简体   繁体   English

保持 PyQt5 GUI 运行,同时等待另一个线程完成

[英]Keep PyQt5 GUI Running while wating for another thread to finish

I am trying keep a PyQt5 GUI running after a starting a function from a different file in a different thread, which works fine, and then wait for that thread to finsish to update some text on the GUI, which does not work fine.我试图让 PyQt5 GUI 在从不同线程中的不同文件启动 function 后运行,这工作正常,然后等待该线程完成以更新 GUI 上的一些文本,这不能正常工作。

File 1 (main.py):文件 1(main.py):

from PyQt5.QtWidgets import  QMainWindow, QApplication,  QPushButton, QTextEdit
from PyQt5.QtGui import QFont
import sys
from threading import Thread

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
  
        self.setWindowTitle("test")
        self.initWidgets()
        self.initWindow()

    def initWindow(self):
        self.setGeometry(0, 0, 300, 300)
        self.show()
    
    def initWidgets(self):
        self.goButton = QPushButton("go", self)
        self.goButton.resize(100, 50)
        self.goButton.move(30, 30)
        self.goButton.setFont(QFont("Calibri", 11))
        self.goButton.clicked.connect(self.goButtonClicked)

        self.textBox = QTextEdit(self)
        self.textBox.resize(200, 40)
        self.textBox.move(30, 100)

        self.outBox = QTextEdit(self)
        self.outBox.resize(200, 40)
        self.outBox.move(30, 150)

       
    def goButtonClicked(self):
        self.var = self.textBox.toPlainText()
        from filewithfunc import testfunc
        self.thread1 = Thread(target=testfunc, args=(self.var,), daemon=False)
        self.thread1.start()
        self.thread2 = Thread(target=self.updateText)
        self.thread2.start()

    def updateText(self):
        self.thread1.join()
        from filewithfunc import capVar
        self.outBox.setText(capVar)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    sys.exit(app.exec())

File 2 (filewithfunc.py):文件 2 (filewithfunc.py):

from time import sleep

def testfunc(var):
    sleep(5)
    global capVar
    capVar = var.capitalize()
   

Basically after pushing the button, the testfunc() function is called with variable from the textbox, and is then later displayed in the other textbox once the function finishes.基本上在按下按钮后,testfunc() function 会从文本框中使用变量调用,然后在 function 完成后显示在另一个文本框中。 I create a different thread for the both the testfunc() and updateText() function in hopes that it will keep the GUI from freezing, but I get this error:我为 testfunc() 和 updateText() function 创建了一个不同的线程,希望它可以防止 GUI 冻结,但我收到此错误:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x1cb0c9aeff0), parent's thread is QThread(0x1cb0ca13cd0), current thread is QThread(0x1cb109b8310)

What can I do to remedy this.我能做些什么来解决这个问题。 I read about using QThread, but I feel like that is slightly overkill and could just be done with threading, I might be wrong though.我读过有关使用 QThread 的信息,但我觉得这有点过头了,可以通过线程来完成,不过我可能错了。

Figured it out on my own, looks like QThread was definitely the way to go, quite easy to implement.我自己想通了,看起来 QThread 绝对是通往 go 的方式,很容易实现。 Final code looks like this.最终代码如下所示。

from PyQt5.QtWidgets import  QMainWindow, QApplication,  QPushButton, QTextEdit
from PyQt5.QtCore import QThread
from PyQt5.QtGui import QFont

import sys
from threading import Thread

class Window(QMainWindow):
    def __init__(self):

        Window.var = "t"

        super().__init__()
  
        self.setWindowTitle("test")
        self.initWidgets()
        self.initWindow()

    def initWindow(self):
        self.setGeometry(0, 0, 300, 300)
        self.show()
    
    def initWidgets(self):
        self.goButton = QPushButton("go", self)
        self.goButton.resize(100, 50)
        self.goButton.move(30, 30)
        self.goButton.setFont(QFont("Calibri", 11))
        self.goButton.clicked.connect(self.goButtonClicked)

        self.textBox = QTextEdit(self)
        self.textBox.resize(200, 40)
        self.textBox.move(30, 100)

        self.outBox = QTextEdit(self)
        self.outBox.resize(200, 40)
        self.outBox.move(30, 150)

       
    def goButtonClicked(self):
        Window.var = self.textBox.toPlainText()
        self.worker = workerThread()
        self.worker.start()
        self.worker.finished.connect(self.updateText)
        

    def updateText(self):
        from filewithfunc import capVar
        self.outBox.setText(capVar)


class workerThread(QThread):
    def run(self):
        from filewithfunc import testfunc
        self.funcThread = Thread(target=testfunc, args=(Window.var,), daemon=True)
        self.funcThread.start()
        print("sat")
        self.funcThread.join()


app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())

Basically when goButton is clicked, a worked thread is started which imports and calls the function from the other file, then waits for it to finish before updating the text on the screen.基本上,当单击 goButton 时,会启动一个工作线程,该线程会从另一个文件导入并调用 function,然后等待它完成,然后再更新屏幕上的文本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM