PyQt streams and signals - how to get values ​​correctly

Using Python 2.5 and PyQt 4.4.3, I could not find any questions like this in Python, so sorry if I repeat the other questions mentioned below, but I could not easily understand this C code.

I have two classes, a graphical interface and a stream , and I'm trying to get return values from a stream. I used the link here as a base for writing my code , which works just fine. To summarize and illustrate the question in the code here (I don't think this code will work on its own):

#!/usr/bin/python2.5

# this is a testing module, and almost everything in here is just there to make the script work
# the relevant issues for the testing are noted in comments

from PyQt4 import QtCore, QtGui
import sys, time

class MainWindow (QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.buttonDaemon = QtGui.QPushButton(self)
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.buttonDaemon)
        self.setLayout(self.layout)

        self.thread = Worker()
        self.connect(self.thread, QtCore.SIGNAL('finished()'), self.unfreezeUi)
        self.connect(self.thread, QtCore.SIGNAL('terminated()'), self.unfreezeUi)
        #self.thread.stop.connect(self.stopped) # part of proposed solution
        self.connect(self.thread, QtCore.SIGNAL('stopped(int)'), self.stopped) #adapted from proposed solution

        self.connect(self.buttonDaemon, QtCore.SIGNAL('clicked()'), self.pressDaemon)

    def unfreezeUi (self):
        self.buttonDaemon.setEnabled(True)

    # the problem begins below: I'm not using signals, or queue, or whatever, while I believe I should for StopSignal and DaemonRunning
    def pressDaemon (self):
        self.buttonDaemon.setEnabled(False)
        if self.thread.isDaemonRunning():
            self.thread.setDaemonStopSignal(True)
            self.buttonDaemon.setText('Daemon - run code every %s sec'% 1)
        else:
            self.thread.startDaemon()
            self.buttonDaemon.setText('Stop Daemon')
            self.buttonDaemon.setEnabled(True)

    # part of proposed solution
    def stopped (self, val):
        print 'stopped ' + str(val)

class Worker (QtCore.QThread):
    daemonIsRunning = False
    daemonStopSignal = False
    daemonCurrentDelay = 0

    def isDaemonRunning (self): return self.daemonIsRunning
    def setDaemonStopSignal (self, bool): self.daemonStopSignal = bool

    def __init__ (self, parent = None):
        QtCore.QThread.__init__(self, parent)
        self.exiting = False
        self.thread_to_run = None

    def __del__ (self):
        self.exiting = True
        self.thread_to_run = None
        self.wait()

    def run (self):
        if self.thread_to_run != None:
            self.thread_to_run(mode='continue')

    #stop = QtCore.pyqtSignal(int) # part of proposed solution

    def startDaemon (self, mode = 'run'):
        if mode == 'run':
            self.thread_to_run = self.startDaemon # I'd love to be able to just pass this as an argument on start() below
            return self.start() # this will begin the thread

        # this is where the thread actually begins
        self.daemonIsRunning = True
        print 'Daemon started'
        self.daemonStopSignal = False
        sleepStep = 0.1 # don't know how to interrupt while sleeping - so the less sleepStep, the faster StopSignal will work

        # begins the daemon in an "infinite" loop
        while self.daemonStopSignal == False and not self.exiting:
            print 'Daemon running'
            # here, do any kind of daemon service

            delay = 0
            while self.daemonStopSignal == False and not self.exiting and delay < 1:
                print 'Daemon sleeping'
                time.sleep(sleepStep) # delay is actually set by while, but this holds for 'sleepStep' seconds
                delay += sleepStep

        # daemon stopped, reseting everything
        self.daemonIsRunning = False
        print 'Daemon stopped'
        #self.stop.emit(self.daemonIsRunning) # part of proposed solution
        self.emit(QtCore.SIGNAL('stopped(int)'), self.daemonIsRunning) # adapted from proposed solution
        self.emit(QtCore.SIGNAL('terminated'))

def main (args):
    app = QtGui.QApplication(args)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main(sys.argv)

, , . - def pressDaemon. , 3 self.thread. , self.thread.startDaemon() , , . , .

, , . , QtCore.QtThread, , . , return emit.

, . , , , , . , , , Qt, Python. , , , .

edit. . , ! , , , .

+3
1

, .

, , script. "" , , , "" "MainWindow" , .

Qt : Queued, Blocking f.x. (RTM, ), . , ( ) , .

PyQt riverbankcomputing, , , .

from sys import argv, exit
from PyQt4 import QtCore, QtGui, uic
import PyQt4
import time


class MainWindow (QtGui.QWidget):
    # this is just a reference and not really relevant to the question
    def __init__ (self, args):
        self.app = MainApp(args)
        QtGui.QWidget.__init__(self)
        self.buttonDaemon = QtGui.QPushButton(self)
        self.buttonConvert = QtGui.QPushButton(self)
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.buttonDaemon)
        self.layout.addWidget(self.buttonConvert)
        self.setLayout(self.layout)

        self.thread = Worker() # this does not begin a thread - look at "Worker.run" for mor details
        self.connect(self.thread, QtCore.SIGNAL('finished()'), self.unfreezeUi)
        self.connect(self.thread, QtCore.SIGNAL('terminated()'), self.unfreezeUi)
        self.thread.stop.connect(self.stopped)

        self.connect(self.buttonDaemon, QtCore.SIGNAL('clicked()'), self.pressDaemon)

    # the problem begins below: I'm not using signals, or queue, or whatever, while I believe I should
    def pressDaemon (self):
        self.buttonDaemon.setEnabled(False)
        if self.thread.isDaemonRunning():
            self.thread.setDaemonStopSignal(True)
            self.buttonDaemon.setText('Daemon - converts every %s sec'% 1)
        else:
            self.buttonConvert.setEnabled(False)
            self.thread.startDaemon()
            self.buttonDaemon.setText('Stop Daemon')
            self.buttonDaemon.setEnabled(True)

    def unfreezeUi(self):
        print '!!'

    def stopped(self, val):
        print 'stopped ' + str(val)

# this whole class is just another reference
class Worker (QtCore.QThread):
    daemonIsRunning = False
    daemonStopSignal = False
    daemonCurrentDelay = 0

    def isDaemonRunning (self): return self.daemonIsRunning
    def setDaemonStopSignal (self, bool): self.daemonStopSignal = bool

    def __init__ (self, parent = None):
        QtCore.QThread.__init__(self, parent)
        self.exiting = False
        self.thread_to_run = None  # which def will be running

    def __del__ (self):
        self.exiting = True
        self.thread_to_run = None
        self.wait()

    def run (self):
        if self.thread_to_run != None:
            self.thread_to_run(mode='continue')

    stop = QtCore.pyqtSignal(int)

    def startDaemon (self, mode = 'run'):
        if mode == 'run':
            self.thread_to_run = self.startDaemon # I'd love to be able to just pass this as an argument on start() below
            return self.start() # this will begin the thread

        # this is where the thread actually begins
        self.daemonIsRunning = True
        self.daemonStopSignal = False
        sleepStep = 0.1 # don't know how to interrupt while sleeping - so the less sleepStep, the faster StopSignal will work

        # begins the daemon in an "infinite" loop
        while self.daemonStopSignal == False and not self.exiting:
            # here, do any kind of daemon service

            delay = 0
            while self.daemonStopSignal == False and not self.exiting and delay < 1:
                time.sleep(sleepStep) # delay is actually set by while, but this holds for N second
                delay += sleepStep

        # daemon stopped, reseting everything
        self.daemonIsRunning = False
        self.stop.emit(self.daemonIsRunning)
        self.emit(QtCore.SIGNAL('terminated'))

class MainApp(QtGui.QApplication):
    def __init__(self, args):
        QtGui.QApplication.__init__(self, args)

if __name__ == "__main__":
    main = MainWindow(argv)
    main.show()
    exit(main.app.exec_())
+3

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


All Articles