PyQt4 Wait in the stream for user input from the GUI

I have a MyThread thread class and my main application, which is simply called "Gui". I want to create several objects from a thread class, but for this example, I created only one object. The thread class does some work, then emits a signal to the Gui class, indicating the need for user input (this indication at the moment just changes the button text). Then the thread should wait for the user to enter (in this case, click the button), and then continue with what it does ...

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_())

How can I wait in (multiple) threads for user input?

+3
source share
1 answer

a 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_()
+6

Source: https://habr.com/ru/post/1693250/


All Articles