使用 PyQt5 和 Windows API 创建文件删除确认对话框

在这篇博客文章中,我们将介绍如何使用 PyQt5 显示删除文件的确认对话框。我们将结合 ctypes 模块调用 Windows 的 SHFileOperation 函数来实现这一功能。

说明

本文中的代码示例仅适用于 Windows 操作系统,因为 SHFileOperation 函数是 Windows 特有的。

依赖库

  • PyQt5
  • ctypes

环境准备

首先,确保你已经安装了 PyQt5 和 ctypes 模块。如果还没有安装,可以使用以下命令进行安装:

pip install pyqt5

步骤

  1. 导入必要的模块:导入 sysctypeswintypes 和 PyQt5 的相关模块。
  2. 定义 SHFileOperation 函数:使用 ctypes.windll.shell32.SHFileOperationW 调用 Windows 的 SHFileOperation 函数。
  3. 定义 SHFILEOPSTRUCT 结构体:定义一个结构体来传递给 SHFileOperation 函数。
  4. 定义常量:定义删除操作和相关标志的常量。
  5. 创建 SHFILEOPSTRUCT 实例:创建并初始化 SHFILEOPSTRUCT 实例。
  6. 调用 SHFileOperation 函数:调用 SHFileOperation 函数并检查操作结果。
  7. 创建 PyQt5 窗口:创建一个 PyQt5 窗口,并添加一个按钮用于显示删除文件对话框。
  8. 显示删除文件对话框:实现按钮点击事件,显示文件选择对话框和删除确认对话框。

代码解析

导入模块

import sys
import ctypes
from ctypes import wintypes
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFileDialog, QMessageBox

  • sys: 提供对 Python 解释器的访问。
  • ctypes: 用于调用 Windows API 函数。
  • wintypes: 包含 Windows 数据类型。
  • PyQt5.QtWidgets: 包含 PyQt5 的 GUI 组件。
定义 SHFileOperation 函数

SHFileOperation = ctypes.windll.shell32.SHFileOperationW

  • 使用 ctypes.windll.shell32.SHFileOperationW 调用 Windows 的 SHFileOperation 函数。
定义 SHFILEOPSTRUCT 结构体

class SHFILEOPSTRUCT(ctypes.Structure):
    _fields_ = [
        ("hwnd", wintypes.HWND),
        ("wFunc", wintypes.UINT),
        ("pFrom", wintypes.LPCWSTR),
        ("pTo", wintypes.LPCWSTR),
        ("fFlags", ctypes.c_uint),
        ("fAnyOperationsAborted", wintypes.BOOL),
        ("hNameMappings", wintypes.LPVOID),
        ("lpszProgressTitle", wintypes.LPCWSTR),
    ]

  • 定义一个结构体来传递给 SHFileOperation 函数。
定义常量

FO_DELETE = 3
FOF_ALLOWUNDO = 0x40
FOF_NOCONFIRMATION = 0x10

  • FO_DELETE: 表示删除操作。
  • FOF_ALLOWUNDO: 允许撤销删除操作。
  • FOF_NOCONFIRMATION: 不显示确认对话框。
创建 SHFILEOPSTRUCT 实例

file_op = SHFILEOPSTRUCT()
file_op.hwnd = None
file_op.wFunc = FO_DELETE
file_op.pFrom = file_path + '\0'
file_op.pTo = None
file_op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION

  • 创建并初始化 SHFILEOPSTRUCT 实例。
调用 SHFileOperation 函数

result = SHFileOperation(ctypes.byref(file_op))

if result == 0:
    print("文件删除成功")
else:
    print("文件删除失败")

  • 调用 SHFileOperation 函数并检查操作结果。
创建 PyQt5 窗口

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQt5 删除文件对话框示例")
        self.setGeometry(100, 100, 400, 300)

        self.button = QPushButton("显示删除文件对话框", self)
        self.button.clicked.connect(self.show_delete_dialog)
        self.button.setGeometry(100, 100, 200, 50)

  • 创建一个 PyQt5 窗口,并添加一个按钮用于显示删除文件对话框。
显示删除文件对话框

def show_delete_dialog(self):
    file_path, _ = QFileDialog.getOpenFileName(self, "选择要删除的文件")
    if file_path:
        reply = QMessageBox.question(self, '确认删除', f"你确定要删除文件吗?\n{file_path}",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            show_delete_file_dialog(file_path)

  • 实现按钮点击事件,显示文件选择对话框和删除确认对话框。

完整代码

import sys
import ctypes
from ctypes import wintypes
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFileDialog, QMessageBox

def show_delete_file_dialog(file_path):
    # 定义 SHFileOperation 函数
    SHFileOperation = ctypes.windll.shell32.SHFileOperationW

    # 定义 SHFILEOPSTRUCT 结构体
    class SHFILEOPSTRUCT(ctypes.Structure):
        _fields_ = [
            ("hwnd", wintypes.HWND),
            ("wFunc", wintypes.UINT),
            ("pFrom", wintypes.LPCWSTR),
            ("pTo", wintypes.LPCWSTR),
            ("fFlags", ctypes.c_uint),
            ("fAnyOperationsAborted", wintypes.BOOL),
            ("hNameMappings", wintypes.LPVOID),
            ("lpszProgressTitle", wintypes.LPCWSTR),
        ]

    # 定义常量
    FO_DELETE = 3
    FOF_ALLOWUNDO = 0x40
    FOF_NOCONFIRMATION = 0x10

    # 创建 SHFILEOPSTRUCT 实例
    file_op = SHFILEOPSTRUCT()
    file_op.hwnd = None
    file_op.wFunc = FO_DELETE
    file_op.pFrom = file_path + '\0'
    file_op.pTo = None
    file_op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION

    # 调用 SHFileOperation 函数
    result = SHFileOperation(ctypes.byref(file_op))

    # 检查操作结果
    if result == 0:
        print("文件删除成功")
    else:
        print("文件删除失败")

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQt5 删除文件对话框示例")
        self.setGeometry(100, 100, 400, 300)

        # 创建一个按钮用于显示删除文件对话框
        self.button = QPushButton("显示删除文件对话框", self)
        self.button.clicked.connect(self.show_delete_dialog)
        self.button.setGeometry(100, 100, 200, 50)

    def show_delete_dialog(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "选择要删除的文件")
        if file_path:
            reply = QMessageBox.question(self, '确认删除', f"你确定要删除文件吗?\n{file_path}",
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                show_delete_file_dialog(file_path)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

运行结果:

相关类型推荐

  • PyQt5 官方文档
  • ctypes 官方文档
  • Windows SHFileOperation 函数文档

其他文章推荐

扩展

1. 添加文件删除日志

你可以在删除文件后记录删除操作的日志,以便将来参考。可以使用 Python 的 logging 模块来实现这一功能。例如:

import logging

# 配置日志记录
logging.basicConfig(filename='delete_log.txt', level=logging.INFO, format='%(asctime)s - %(message)s')

def show_delete_file_dialog(file_path):
    # ... 现有代码 ...

    if result == 0:
        logging.info(f"文件删除成功: {file_path}")
        print("文件删除成功")
    else:
        logging.error(f"文件删除失败: {file_path}")
        print("文件删除失败")
2. 添加多文件删除功能

你可以扩展代码以支持一次删除多个文件。可以使用 QFileDialog.getOpenFileNames 方法来选择多个文件。例如:

def show_delete_dialog(self):
    file_paths, _ = QFileDialog.getOpenFileNames(self, "选择要删除的文件")
    if file_paths:
        reply = QMessageBox.question(self, '确认删除', f"你确定要删除这些文件吗?\n{', '.join(file_paths)}",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            for file_path in file_paths:
                show_delete_file_dialog(file_path)

 

 

3. 添加进度条

你可以在删除文件时显示进度条,以便用户了解删除操作的进度。可以使用 PyQt5 的 QProgressBar 组件。例如:

 

 

from PyQt5.QtWidgets import QProgressBar

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQt5 删除文件对话框示例")
        self.setGeometry(100, 100, 400, 300)

        self.button = QPushButton("显示删除文件对话框", self)
        self.button.clicked.connect(self.show_delete_dialog)
        self.button.setGeometry(100, 100, 200, 50)

        self.progress_bar = QProgressBar(self)
        self.progress_bar.setGeometry(100, 200, 200, 25)
        self.progress_bar.setValue(0)

    def show_delete_dialog(self):
        file_paths, _ = QFileDialog.getOpenFileNames(self, "选择要删除的文件")
        if file_paths:
            reply = QMessageBox.question(self, '确认删除', f"你确定要删除这些文件吗?\n{', '.join(file_paths)}",
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                for i, file_path in enumerate(file_paths):
                    show_delete_file_dialog(file_path)
                    self.progress_bar.setValue((i + 1) / len(file_paths) * 100)
4. 跨平台支持

目前的代码仅适用于 Windows 操作系统。如果你希望代码在其他操作系统(如 macOS 和 Linux)上运行,可以使用 Python 的 os 模块和 shutil 模块来实现文件删除功能。例如:

 

import os
import shutil

def delete_file(file_path):
    try:
        if os.path.isfile(file_path):
            os.remove(file_path)
        elif os.path.isdir(file_path):
            shutil.rmtree(file_path)
        print("文件删除成功")
    except Exception as e:
        print(f"文件删除失败: {e}")

总结

本文介绍了如何使用 PyQt5 显示删除文件的确认对话框,并结合 ctypes 模块调用 Windows 的 SHFileOperation 函数来实现这一功能。希望这篇文章对你有所帮助!

结论

通过结合 PyQt5 和 ctypes 模块,我们可以轻松实现一个带有删除确认对话框的文件删除功能。这种方法不仅简单易用,而且可以提供更好的用户体验,如果你有任何问题或建议,欢迎在评论区留言。继续探索和学习,祝你在深度学习的旅程中取得更多的成果!🚀


希望这个结论对你有所帮助!如果你有任何其他问题或需要进一步的帮助,请随时告诉我。😊

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LIY若依

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值