pyqt: 文件打开对话框中长时间处理
我对图形用户界面(GUI)编程经验不多,但我正在用PyQt写一个GUI应用程序。这个应用程序可以让用户打开一个二进制文件并对其进行一些编辑。
当文件被打开时,我需要进行一些处理,这个过程会花费一些时间(大约15秒)。所以当用户选择文件并在文件打开对话框中点击“打开”按钮时,界面就会卡住。有什么好的方法可以让用户体验更好呢?
谢谢
3 个回答
你想找一种方法,让某个任务在不同于主界面的线程中运行。
你可以先看看这里。
像wxpython和pyQt这样的主要图形界面框架都有一些方法,可以让长时间运行的程序不让界面卡住。个人来说,我更喜欢直接使用Python的线程模块。
你需要定期让应用程序处理事件队列中的待处理事件。你可以通过调用QApplication实例的processEvents()方法来做到这一点。如果你在进行计算的时候,偶尔调用一下processEvents(),那么图形界面和进度条就会自动更新。需要注意的是,这并不意味着图形界面会变得响应更快。
如果你想在加载数据的时候让图形界面保持响应,你需要把加载操作放到一个后台线程中。不过,后台线程不能直接进行图形界面的操作,但它可以发送信号,让其他线程接收到这些信号。这里有一篇关于多线程PyQt编程的文章。
在后台加载时,通过状态栏中的进度条显示进度。
要做到这一点,你可以使用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的主线程中进行的。