【问题标题】:PySide / Python GUI freezesPySide / Python GUI 冻结
【发布时间】:2015-03-05 16:03:43
【问题描述】:

我目前正在为 rvplayer 编写一个 GUI,它将使艺术家能够自动渲染带有 slate 和老化信息的样片。 GUI 使用 PySide 编写并使用 Python 2.7 编写脚本。我的问题是,在调用我的进程并使用标准输出更新我的QProgressBar 时,GUI 会冻结。我知道这是一个常见问题,它可能可以通过 processEvents() 以某种方式解决,但我对线程和进程循环知之甚少,无法解决这个问题。由于我的代码已经有点长了,这是导致问题的部分:

def rv(self, args):
    p = subprocess.Popen(["C:/Program Files/Tweak/RV-4.0.10-64/bin/rvio_hw.exe"]+[x for x in args], stdout=subprocess.PIPE)
    while True:
        line = p.stdout.readline()
        if line != "":
            progressStr=re.search(r"([0-9]+.[0-9]+%)", line.rstrip())
            if progressStr == None:
                print line.rstrip()
            else:
                progressInt=int(float(re.sub("[^0123456789\.]", "", progressStr.group())))
                self.prog_QProgressBar.setValue(progressInt)
                print progressStr.group()
        else:       
            break

这是开始我的QApplication的部分:

if __name__ == "__main__":

    app = QtGui.QApplication(sys.argv)
    finalForm = MainWindow()
    finalForm.show()
    sys.exit(app.exec_())

我在按下按钮时调用了函数 rv,虽然进度条一直在正常更新,但一段时间后窗口开始变得无响应。我不明白什么时候可以使用 app.processEvents() 告诉我的 QApplication 在单独的线程或后台运行进程。

【问题讨论】:

标签: python user-interface pyside freeze


【解决方案1】:

由于您似乎没有使用线程,因此可能只需要在更新进度条后调用processEvents,如下所示:

    self.prog_QProgressBar.setValue(progressInt)
    QtGui.qApp.processEvents()

但是,这样做的有效性可能取决于该过程需要多长时间才能产生输出。 processEvents 调用所做的只是立即处理当前在应用程序事件队列中的任何未决事件(例如小部件绘制、鼠标点击等)。在这些调用之间,GUI 将继续冻结(即,执行代码不会按照您的建议在单独的线程或后台运行)。因此,这种技术可以保持 GUI 响应的程度取决于在 rv() 方法中调用 processEvents 的频率。

【讨论】:

    【解决方案2】:

    问题在于,并不是您的应用程序被冻结,而是 Windows 认为该应用程序被冻结是因为它忽略了事件(鼠标悬停、单击等),因此 Windows 在其智慧中为您提供了这种对话。

    您需要在 show() 之后启动线程,然后运行 ​​processEvents 函数,显然只有在线程完成后才调用 sys.exit。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-16
      • 2020-08-06
      • 2015-04-08
      • 2015-05-09
      • 1970-01-01
      相关资源
      最近更新 更多