Python getOpenFileName上的进度条

Python getOpenFileName上的进度条,python,qt,pyside,Python,Qt,Pyside,在我的应用程序中,我有下面一行代码,它打开了一个文件对话框窗口。一旦我得到了文件名,我会进行一系列的处理,这需要相当长的时间,一旦完成,工作区就为用户准备好了 filename, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', os.curdir, "*.cws") “文件”对话框是一个模式窗口(默认情况下),这很好,因为它可以防止用户在工作区尚未准备好使用时做愚蠢的事情。我想在某个地方放一个进度条,让你知道有多少事情需要处理。

在我的应用程序中,我有下面一行代码,它打开了一个文件对话框窗口。一旦我得到了文件名,我会进行一系列的处理,这需要相当长的时间,一旦完成,工作区就为用户准备好了

filename, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', os.curdir, "*.cws")
“文件”对话框是一个模式窗口(默认情况下),这很好,因为它可以防止用户在工作区尚未准备好使用时做愚蠢的事情。我想在某个地方放一个进度条,让你知道有多少事情需要处理。我制作了另一个对话框窗口,其中显示进度条和一些其他信息

现在,由于文件对话框窗口是模态的,它只是在我的工作区处理时冻结在那里,而进度对话框只有在一切完成后才会弹出

我已经研究过将文件对话框窗口设置为非模态,但我认为这是不可能的。我在想也许可以强制关闭它,然后立即弹出我的进度对话框并接管该设备。如何以编程方式关闭“文件”对话框窗口?我不知道如何获得该表格的推荐人


或者您对如何解决这个问题有更好的建议?

正如thuga提到的,您的应用程序事件循环被繁重的处理卡住了。 因此,在处理运行时不会处理事件(尤其是绘制事件),从而导致GUI冻结

在我看来,您有两种选择:

强制处理事件(不是很经典,但可能有效):

这取决于“繁重的处理”是如何完成的。 假设挂起循环的代码“在您的手中”(不在第三方库中)。 您可以在其中添加尽可能多的调用

如果处理是基于循环的,则它可以如下所示:

for item in itemList:
    ...processitem...
    QtGui.QApplication.processEvents()
这是在不应该知道的代码部分向GUI添加依赖项的主要缺点。 如果您的代码不是基于循环的,那么您必须添加几个对processEvents的调用,这些调用将污染处理代码

停止挂起事件循环(更复杂但更易于维护)

这意味着您必须按照thuga的建议处理线程和/或子进程。 此解决方案假设GUI代码和业务代码分离得足够好

你可以看一看这篇文章,它在这个问题上给出了一些亮点。 由于python全局解释器锁(GIL)的存在,您可能看不到更好的线程结果。
考虑使用库。

问题是关闭文件对话框后会进行一些繁琐的处理,这会阻止事件被处理。您应该考虑在另一个线程中进行这种繁重的处理。文件对话框的模式没有导致问题。从文件对话框窗口收到文件名后,处理立即开始。窗户本身还开着。那么,您的意思是因为我自己的繁重处理而无法执行关闭事件吗?我将按照你的建议在另一个线程中尝试一下。那么,我应该让另一个线程弹出模式进度窗口,以防止用户执行任何其他操作?谢谢是的,在完成繁重的处理之前,不会处理关闭事件。这个
其他线程
应该做繁重的处理,它不应该做任何GUI工作。在主线程中保留与GUI相关的内容,并将繁重的工作转移到新的辅助线程。模态进度窗口应该被创建并显示在你的主线程中。我刚刚做了这个,是的,效果很好!实际上,我想知道是什么原因导致文件对话框关闭,因为它没有在返回文件名时立即关闭。酷。现在,如果我的进度条在主线程中,我将如何从新线程向它传递有关进度状态的信息?让新线程显示进度条是一种糟糕的风格吗?是的,你真的应该把你的GUI内容放在主线程中。要将有关进度状态的信息从工作线程传递到主线程,可以使用信号和插槽。在第一个选项中,可以使用回调机制将GUI与后端分开。后端只是注册一个处理程序,它以调用方可以设置的频率调用该处理程序。这项技术的一个例子是。