pyqt: 文件打开对话框中长时间处理

0 投票
3 回答
2367 浏览
提问于 2025-04-17 03:26

我对图形用户界面(GUI)编程经验不多,但我正在用PyQt写一个GUI应用程序。这个应用程序可以让用户打开一个二进制文件并对其进行一些编辑。

当文件被打开时,我需要进行一些处理,这个过程会花费一些时间(大约15秒)。所以当用户选择文件并在文件打开对话框中点击“打开”按钮时,界面就会卡住。有什么好的方法可以让用户体验更好呢?

谢谢

3 个回答

1

你想找一种方法,让某个任务在不同于主界面的线程中运行。
你可以先看看这里

像wxpython和pyQt这样的主要图形界面框架都有一些方法,可以让长时间运行的程序不让界面卡住。个人来说,我更喜欢直接使用Python的线程模块。

2

你需要定期让应用程序处理事件队列中的待处理事件。你可以通过调用QApplication实例的processEvents()方法来做到这一点。如果你在进行计算的时候,偶尔调用一下processEvents(),那么图形界面和进度条就会自动更新。需要注意的是,这并不意味着图形界面会变得响应更快。

如果你想在加载数据的时候让图形界面保持响应,你需要把加载操作放到一个后台线程中。不过,后台线程不能直接进行图形界面的操作,但它可以发送信号,让其他线程接收到这些信号。这里有一篇关于多线程PyQt编程的文章

2

在后台加载时,通过状态栏中的进度条显示进度。

要做到这一点,你可以使用QThread来启动加载。你的线程类可以像下面这样写(假设parent会有一个属性progress):

QtFileLoader(QtCore.QThread):
    def __init__(self,parent=None, filepath=None):
        QtCore.QThread.__init__(self,parent)
        self.data = None
        self.filepath = filepath

    def run(self):
        """ load data in parts and update the progess par """
        chunksize = 1000
        filesize = ... # TODO: get length of file
        n_parts = int(filesize/chunksize) + 1
        with open(self.filepath, 'rb') as f:
            for i in range(n_parts):
                self.data += f.read(chunksize)
                self.parent.progress = i 

关于使用QThread还是threading.Thread的问题,可以在这里找到讨论。

编辑(根据@Nathan的提示):在parent中,应该有一个定时器函数,每隔100毫秒检查一次self.parent.progress的值,并相应地设置进度条。这样,进度条的设置是在GUI的主线程中进行的。

撰写回答