如何创建不占用主线程的pyqt5gui

2024-10-03 21:32:50 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有可能让Python使用执行的主线程启动pyqt5gui应用程序,然后让线程打开来做其他事情?在

下面是我能想到的最简单的例子:

from PyQt5.QtWidgets import *

def infinite_useless_loop():
    while True:
        pass

app = QApplication([])
doodad = QMainWindow()
doodad.show()
infinite_useless_loop()

如果运行此代码,它将冻结,因为“mainloop”没有像通常那样被激活,如果我没有调用无用的无限循环,而是调用app.exec_()。对infinite_useless_loop的调用是为了在GUI正常运行的情况下,替换用于执行其他有用工作的主线程。在

为了正确地做到这一点,我不得不设想一个单独的线程并使用它来运行GUI,同时用主线程启动该线程,然后从那里继续;如果将来需要,可以进行通信。在

编辑

我写了一些代码,使主事件循环在一个单独的线程中工作,但是我仍然不能与在另一个线程中创建的GUI对象完全交互。这段代码有效地解决了我的一半问题:

^{pr2}$

此代码生成空白窗口,可以单击并正确调整大小(因为事件循环正在工作),但它自己。我是否必须恢复到信号和插槽来与对象通信,或者我可以以某种方式将GUI对象恢复到主线程中并从那里使用它的方法?在

编辑2

我不想在GUI线程之外进行任何实际的GUI操作,只需调用我生成的GUI对象上的方法。整个GUI结构将由GUI对象生成。在

编辑3

这个新代码现在使它能够与通信,但只能与原始信息位通信,而不能由一个线程访问另一个线程的GUI对象的方法。虽然很接近,但还是不是我想要的。调用GUI对象的方法必须通过队列传递原始信息,然后在另一端进行处理。然后必须调用exec()函数。这是不可接受的。代码如下:

from PyQt5.QtWidgets import *

import multiprocessing
import threading
import sys
import time
import queue

class Application(QMainWindow):
    def __init__(self, comms):
        super(Application, self).__init__()
        self.comms = comms
        self.fetchingThread = threading.Thread(target=self.fetchingLoop)

        self.labelOne = QLabel(self)
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.labelOne)
        self.setLayout(self.layout)

        self.fetchingThread.start()

    def fetchingLoop(self):
        while True:
            try:
                obj = self.comms.get()
                self.processItem(obj)
            except queue.Empty:
                pass

    def processItem(self, item):
        self.labelOne.setText(str(item))
        print(self.labelOne.text())

class Launcher(multiprocessing.Process):
    def __init__(self, Application):
        super(Launcher, self).__init__()
        self.comms = multiprocessing.Queue()
        self.Application = Application

    def get_comms(self):
        return self.comms

    def run(self):
        app = QApplication([])
        window = self.Application(self.comms)
        window.show()
        sys.exit(app.exec_())

def no_thread():
    app = QApplication([])
    window = Application(False)
    window.show()
    sys.exit(app.exec_())



if __name__ == '__main__':
    thread = Launcher(Application)
    comms = thread.get_comms()
    thread.start()

    c = 0
    while True:
        c += 1
        time.sleep(1)
        comms.put(c)

Tags: 对象方法代码importselfappapplicationinit