【问题标题】:What's bad about starting a pyQt thread from a python thread (not main)?从 python 线程(不是主线程)启动 pyQt 线程有什么不好?
【发布时间】:2015-02-03 10:02:25
【问题描述】:

我有一个 python 控制台脚本,我想向其中添加一个基本状态窗口,所以在对 pyqt 了解不多的情况下,我添加了一个窗口。如果我从我的主线程启动 pyqt,它会阻塞其他所有内容,所以我从另一个线程启动它。几个月来它一直运行良好,但我只是注意到一个警告(不知道我之前是怎么错过的): WARNING: QApplication was not created in the main() thread.我想知道这可能会导致什么问题。

这是我正在使用的代码的精简版,只是更新了窗口标题栏:

from PyQt4 import QtGui, QtCore
import threading
import sys
from time import sleep

class MainWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MainWidget, self).__init__(parent)
        self.setWindowTitle(statusLine)
        self.timer = QtCore.QBasicTimer()
        self.timer.start(500, self)


    def updateWindow(self):
        self.setWindowTitle(statusLine)


    def timerEvent(self, event):
        if event.timerId() == self.timer.timerId():
            self.updateWindow()
        else:
            super(MainWidget, self).timerEvent(event)


def startWindow():
    app = QtGui.QApplication(sys.argv)
    mw = MainWidget()
    mw.show()
    app.exec_()


if __name__ == '__main__':
    global statusLine
    statusLine = 'foo'
    threadWindow = threading.Thread(target=startWindow)
    threadWindow.start()
    sleep(2)  # process lots of data
    statusLine = 'bar'
    # keep doing stuff and updating statusLine

编辑:看起来我没有收到这个简化示例的警告;相反,我似乎只有在启动 pyQt 之前启动多个其他 python 线程时才能得到它。但是问题仍然存在:这样做有什么问题?

【问题讨论】:

    标签: python multithreading pyqt


    【解决方案1】:

    我想说,由于用户与 GUI 交互,因此存在一些危险,即人们在没有真正杀死主程序的情况下杀死 GUI,这可能导致:

    1. 由于另一个实例启动导致资源泄漏、冲突等问题。&
    2. 问题是因为__main__ 尝试更新不再存在的 GUI。

    在带有 GUI 的程序(无论是 QT 还是 WX)中,将 GUI 设置为 __main__ 并让子线程执行任何后台、计算密集型处理似乎通常被认为是最佳实践。当然,在 OnExit 方法中显式终止任何子线程仍然是一个非常好的主意。

    【讨论】:

    • 谢谢。因此,对于我的情况,我在事后才使用一个简单的 gui,从线程调用 pyQt 并不会直接破坏任何东西,只是它变得不那么优雅了。为了获得最佳实践(如果我要重新开始),我绝对可以看到不同的做法。现在我已经确保关闭 GUI 也会触发主线程正常关闭,并且 main 不会直接对 gui 做任何事情,而是更新全局变量(这当然是我的糟糕做法当然)gui在计时器上读取的内容。
    • 与其绑定在 GUI 上,不如快速构建前端/包装器。
    • 嗯,这是一个想法。但我知道 pyQt 使用自己的线程风格,所以我担心重新编写我原来的多线程代码以在 Qt 下工作将是一项相当大的工作。或者有什么技巧可以将其插入 Qt 中?
    • 主要的“技巧”是用户交互和计算的分离——如果你将用户交互拆分为收集启动选项、报告进度、更改正在进行的进度并完成所有这些在一个单独的 UI 文件中,那么您只需要一个 GUI 文件来执行这些操作。 pubsub 模型值得一看。
    • 好的,现在我可能会保持原样,因为它听起来不应该给我带来任何问题(这主要是我想知道的)但我会保留它下次我需要添加 UI 时介意。谢谢。
    猜你喜欢
    • 2017-11-02
    • 2014-06-16
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2020-10-15
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多