【问题标题】:PyQt: QtGui.QFileDialog.getSaveFileName won't close after selectionPyQt:选择后 QtGui.QFileDialog.getSaveFileName 不会关闭
【发布时间】:2013-02-12 06:13:06
【问题描述】:

在我的 PyQt4 应用程序中,有一个功能允许用户保存 avi 文件。 为此,在主窗口中实现了 saveMovie 方法:

def saveMovie(self):
    """ Let the user make a movie out of the current experiment. """
    filename = QtGui.QFileDialog.getSaveFileName(self, "Export Movie", "",
                                                 'AVI Movie File (*.avi)')

    if filename != "":
        dialog = QtGui.QProgressDialog('',
                                       QtCore.QString(),
                                       0, 100,
                                       self,
                                       QtCore.Qt.Dialog |
                                       QtCore.Qt.WindowTitleHint)

        dialog.setWindowModality(QtCore.Qt.WindowModal)
        dialog.setWindowTitle('Exporting Movie')
        dialog.setLabelText('Resampling...')

        dialog.show()

        make_movie(self.appStatus, filename, dialog)

        dialog.close()

我的想法是使用 QProgressDialog 来显示视频编码工作是如何进行的。
然而,在选择文件名后,QFileDialog 不会消失,整个应用程序将保持无响应,直到 ma​​ke_movie 函数完成。

我应该怎么做才能避免这种情况?

【问题讨论】:

  • 尝试添加对processEvents()的呼叫。见this question
  • 我在 if 语句之前添加了对 QApplication.processEvents() 的调用,不幸的是它不起作用。
  • processEvents() 需要去阻塞部分。 make_movie 在这种情况下,我猜。取决于make_movie 的实现,这可能会也可能不会解决问题。或者您可以将该部分移至不同的线程。
  • 是的,最后我将make_movie 移到了另一个线程,以避免阻塞用户界面。很快就会发布代码。

标签: python pyqt pyqt4 qfiledialog


【解决方案1】:

经验教训:如果您有一些长时间运行的操作要做——例如,读取或写入一个文件,请将它们移到另一个线程,否则它们会冻结 UI。

因此,我创建了QThread的子类MovieMaker,其run方法封装了make_movie之前实现的功能:

class MovieMaker(QThread):
    def __init__(self, uAppStatus, uFilename):
        QtCore.QThread.__init__(self, parent=None)
        self.appStatus = uAppStatus
        self.filename = uFilename

    def run(self):
        ## make the movie and save it on file

让我们回到saveMovie 方法。在这里,我将原来对make_movie 的调用替换为以下代码:

self.mm = MovieMaker(self.appStatus,
                     filename)

self.connect(self.mm, QtCore.SIGNAL("Progress(int)"),
             self.updateProgressDialog)

self.mm.start()

注意我是如何定义一个新的信号Progress(int)
此类信号由MovieMaker 线程发出以更新用于向用户显示电影编码工作进展情况的QProgressDialog

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 2015-07-17
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    相关资源
    最近更新 更多