在我的应用程序中,我有以下行打开文件对话框窗口。获得文件名后,我会进行一系列处理,这需要花费很长时间,一旦完成,工作区就会为用户做好准备。
filename, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', os.curdir, "*.cws")
文件对话框是一个模态窗口(默认情况下),这很棒,因为它阻止用户在工作空间尚未准备好使用时做蠢事。我想在某处放置一个进度条,以了解处理的数量。我创建了另一个对话窗口,显示进度条和其他一些信息。
现在,由于文件对话框窗口是模态的,它只是在我的工作区处理时冻结在那里,并且只在完成所有操作后弹出进度对话框。
我已经研究过将文件对话框窗口设置为非模态,但我不认为这是可能的。我想也许强迫它关闭,并立即弹出我的进度对话框窗口并接管模态。如何以编程方式关闭文件对话框窗口?我不知道如何获得表格的参考。
或许您对如何解决这个问题有更好的建议?
答案 0 :(得分:1)
正如thuga所说,您的应用程序事件循环因您的繁重处理而停滞不前。 因此,在处理运行时不会处理事件(特别是绘制事件),导致GUI冻结。
在我看来,你有两个选择:
强制要处理的事件(不是非常优雅但可能有效):
这取决于你的“繁重处理”是如何完成的。 假设挂起循环的代码是“在你手中”(不在第三方lib中)。 您可以尽可能多地添加QApplication.processEvents来电话。
如果处理是基于循环的,它可能看起来像:
for item in itemList:
...processitem...
QtGui.QApplication.processEvents()
这是在不应该注意的部分代码中向GUI添加依赖关系的主要缺点。 如果您的代码不是基于循环的,那么您将不得不添加几个对processEvents的调用,这些调用将污染处理代码。
停止挂起事件循环(更复杂但更易于维护)
这意味着你将不得不像thuga建议的那样处理线程和/或子进程。 该解决方案假定GUI代码和业务代码分离得足够好。
您可以查看this article from Qt Quarterly,其中提供了有关此问题的一些重点。 由于python全局解释器锁(GIL),您可能看不到更好的线程结果。 考虑使用multiprocessing库。