PyQt4在线程中等待来自GUI的用户输入

发布于 2021-01-29 15:02:06

我有一个线程类“ MyThread”和主应用程序,简称为“
Gui”。我想从线程类创建一些对象,但在本示例中,我仅创建了一个对象。线程类完成一些工作,然后向Gui类发出信号,指示需要用户输入(此指示目前仅是更改按钮的文本)。然后,线程应等待用户输入(在这种情况下为单击按钮),然后继续执行其操作…

from PyQt4 import QtGui, QtCore
class MyTrhead(QtCore.QThread):
    trigger = QtCore.pyqtSignal(str)

    def run(self):
        print(self.currentThreadId())
        for i in range(0,10):
            print("working ")
            self.trigger.emit("3 + {} = ?".format(i))
            #### WAIT FOR RESULT
            time.sleep(1)


class Gui(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(Gui, self).__init__(parent)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.btn)

        self.t1 = MyTrhead()
        self.t1.trigger.connect(self.dispaly_message)
        self.t1.start()
        print("thread: {}".format(self.t1.isRunning()))


    @QtCore.pyqtSlot(str)
    def dispaly_message(self, mystr):
        self.pushButton.setText(mystr)

    def btn(self):
        print("Return result to corresponding thread")



if "__main__" == __name__:
    import sys
    app = QtGui.QApplication(sys.argv)
    m = Gui()
    m.show()
    sys.exit(app.exec_())

如何在(多个)线程中等待用户输入?

关注者
0
被浏览
94
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    默认情况下,QThread具有事件循环,可以处理信号和插槽。在当前的实现中,很遗憾,您已通过重写删除了此行为QThread.run。如果还原它,则可以得到所需的行为。

    因此,如果您不能覆盖QThread.run(),如何在Qt中进行线程处理?线程的另一种方法是将代码放在的子类中,QObject然后将该对象移至标准QThread实例。然后,您可以将信号和插槽连接在主线程和线程之间,QThread以双向通信。这将使您能够实现所需的行为。

    在下面的示例中,我启动了一个工作线程,该工作线程将打印到终端,等待2秒钟,再次打印,然后等待用户输入。单击该按钮时,工作线程中的第二个单独的函数运行,并以与第一次相同的模式打印到终端。请注意我使用moveToThread()和连接信号的顺序(按照顺序)。

    码:

    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    import time
    
    class MyWorker(QObject):
    
        wait_for_input = pyqtSignal()
        done = pyqtSignal()
    
    
        @pyqtSlot()
        def firstWork(self):
            print 'doing first work'
            time.sleep(2)
            print 'first work done'
            self.wait_for_input.emit()
    
        @pyqtSlot()
        def secondWork(self):
            print 'doing second work'
            time.sleep(2)
            print 'second work done'
            self.done.emit()
    
    
    class Window(QWidget):
        def __init__(self, parent = None):
            super(Window, self).__init__()
    
            self.initUi()
            self.setupThread()
    
        def initUi(self):
            layout = QVBoxLayout()
            self.button = QPushButton('User input')
            self.button.setEnabled(False)
            layout.addWidget(self.button)
            self.setLayout(layout)
            self.show()
    
        @pyqtSlot()
        def enableButton(self):
            self.button.setEnabled(True)
    
        @pyqtSlot()    
        def done(self):
            self.button.setEnabled(False)
    
        def setupThread(self):
            self.thread = QThread()
            self.worker = MyWorker()
    
            self.worker.moveToThread(self.thread)
    
            self.thread.started.connect(self.worker.firstWork)
            self.button.clicked.connect(self.worker.secondWork)
            self.worker.wait_for_input.connect(self.enableButton)
            self.worker.done.connect(self.done)
    
            # Start thread
            self.thread.start()
    
    if __name__ == "__main__":
        app = QApplication([])
        w = Window()
        app.exec_()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看