【问题标题】:Multithreading with pyqt - Can't get the separate threads running at the same time?使用 pyqt 进行多线程 - 不能让单独的线程同时运行?
【发布时间】:2023-03-27 16:16:01
【问题描述】:

我试图让 PyQT GUI 在我的 python 应用程序上运行,我试图将它分成 2 个线程,以便在我的主运行循环运行时 GUI 会响应,但我无法得到它去。也许我误解了它。这是我尝试过的:

我的WindowWorker线程定义如下:

class Window(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.thread = Worker()

        start = QPushButton("Start", self)
        QObject.connect(start, SIGNAL("clicked()"), MAIN_WORLD.begin)

        hbox = QVBoxLayout(self)
        hbox.addStretch(4)

class Worker(QThread):
    def __init__(self, parent = None):
        QThread.__init__(self, parent)

if __name__ == '__main__':
    MAIN_WORLD = World()
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

这似乎与在线示例非常接近。我的World 类正在运行一个循环,一旦用户单击“开始”,该循环就会无限循环,直到再次单击它。这是它的部分定义。

class World(QThread):
    def __init__(self, parent = None):
        QThread.__init__(self, parent)
        self.currentlyRunning = False
        //snip

    def begin(self):
        if self.currentlyRunning:
            self.currentlyRunning = False
        else:
            self.currentlyRunning = True
            self.MethodThatDoesUsefulStuff()

编辑:我注意到我并没有真正“使用”我的工作线程。如何将我的世界线程创建为工作线程?

【问题讨论】:

    标签: python multithreading pyqt


    【解决方案1】:

    仔细查看您的代码后,您在 QApplication 之前启动了 MAIN_WORLD,这不是您想要的。

    你想做这样的事情:

    if __name__ == '__main__':
        app = QApplication(sys.argv)
        sys.exit(app.exec_())
    

    并且,在您的 Window 类中:

    class Window(QWidget):
        def __init__(self, *args):
            self.world_thread = World();
            # ...
    

    以上将允许主线程控制 gui 并允许工作线程在后台工作。

    【讨论】:

    • 在这种情况下,如何在其他代码运行时保持 GUI 始终响应?奇怪..
    • 我编辑了这篇文章以简要描述您设计的结果。你能详细说明你的线程在做什么吗?
    • 我不熟悉生产者/消费者问题,但似乎不是这样。无限循环无限期地运行几代 GA,直到 GUI 停止它。
    • 是的,这与生产者/消费者问题非常不同。我将不得不服从别人。你也许可以在你的无限循环中调用QApplication.processEvents(),但我不确定它是否可以在线程中工作(这真的是一个丑陋的黑客,而不是一个适当的修复)。
    • 这是错误的。 GIL 每 100 个 Python 周期释放一次,无论它是否处于无限循环中。我建议观看您在答案中链接到的视频。 blip.tv/file/2232410
    【解决方案2】:

    当然是 PyQt 而不是 PySide,但是:

    • 不要继承 QThread,继承 QObject(参见 http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/)。
    • 那么基本的工作流程就是创建一个新线程,将你的工作线程移入线程,启动线程和你的工作线程。您的问题可能是您从未真正启动新线程,初始化不会这样做 - 然后您的 GUI 和您的工作人员都在运行同一个线程,正如其他人所评论的那样。 GIL 并没有真正进入画面。查看 QThread 文档:http://doc.qt.io/qt-4.8/qthread.html

    【讨论】:

      猜你喜欢
      • 2018-09-27
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 2023-01-31
      • 1970-01-01
      • 2012-04-05
      • 2018-07-15
      相关资源
      最近更新 更多