如何创建不占用主线程的

时间:2016-08-12 23:44:20

标签: python multithreading pyqt5

是否有可能让Python使用主要执行线程启动PyQt5 GUI应用程序,然后让线程处于打开状态以执行其他操作?

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

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的调用意味着用正在运行的其他有用工作 WHILE 替换正在运行的GUI。

为了正确地做到这一点,我不得不想象一个人会创建一个单独的线程并使用它来运行GUI,同时用主线程启动该线程,然后从那里继续;能够在将来必要时进行沟通。

修改

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

from PyQt5.QtWidgets import *
from threading import Thread
import sys

def makeGUI():
    app = QApplication([])
    doodad = QMainWindow()
    doodad.show()
    sys.exit(app.exec_())

def infinite_useless_loop():
    while True:
        pass


if __name__ == '__main__':
    thread = Thread(target=makeGUI)
    thread.start()
    infinite_useless_loop()

此代码生成空白窗口,可以单击并正确调整大小(因为事件循环正在运行),但它是独立的。我是否必须恢复信号和插槽以与对象通信,或者我可以以某种方式将GUI对象重新放回主线程并使用它的方法吗?

编辑2

我不希望在GUI的线程之外进行任何实际的GUI操作,只需在GUI对象上调用 I HAVE MADE 的方法。整个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)

0 个答案:

没有答案