On 11/20/2014 01:25 PM, Juan Christian wrote:
> **Back to the list
> 
> So, as I said the PyQt doc is using C o.0
> 
> Yes, I read the tutorials, I'll google for some books and things related.

Okay so I took a long look at the example code that was on stackoverflow
and figured it out.  It's not quite as complete as I thought, and it's
only partially functioning.  I rewrote it to function a little better.
Hopefully it will give you an example.  Working with QThread and then
moving the worker object to that thread is apparently the recommended
way of doing it, but it makes signal handling a two-stage affair.
Basically the worker thread has to notify Qthread that it's finished
using a finished signal which has to be connected to the QThread's
quit() method.  That in turn emits its own finished signal which the GUI
can trap.  It seems a bit convoluted to me.

anyway I've attached the working example.
import time, sys
from PyQt4.QtCore  import *
from PyQt4.QtGui import * 

class SimulRunner(QObject):
    'Object managing the simulation'

    stepIncreased = pyqtSignal(int, name = 'stepIncreased')
    finished = pyqtSignal(name = 'finished')

    def __init__(self):
        super(SimulRunner, self).__init__()
        self._step = 0
        self._isRunning = True
        self._maxSteps = 20

    def longRunning(self):
        self._step = 0
        self._isRunning = True
        while self._step  < self._maxSteps  and self._isRunning == True:
            self._step += 1
            self.stepIncreased.emit(self._step)
            time.sleep(1)
        # note since the delay is one second, the thread won't die and the signal
        # won't be emitted for an entire second.
        self.finished.emit()

    def stop(self):
        print ('stopping.')
        self._isRunning = False

class SimulationUi(QDialog):
    'PyQt interface'

    def thread_finished (self):
        print ('The thread is finished. You could now do something to update the GUI')

    def on_stop_button (self):
        # for some reason we can't have the signal call this directly
        # but it works from here. Don't know why.
        self.simulRunner.stop()

    def __init__(self):
        super(SimulationUi, self).__init__()

        self.goButton = QPushButton('Go')
        self.stopButton = QPushButton('Stop')
        self.currentStep = QSpinBox()

        self.layout = QHBoxLayout()
        self.layout.addWidget(self.goButton)
        self.layout.addWidget(self.stopButton)
        self.layout.addWidget(self.currentStep)
        self.setLayout(self.layout)

        self.simulRunner = SimulRunner()
        self.simulThread = QThread()
        self.simulRunner.moveToThread(self.simulThread)
        self.simulRunner.stepIncreased.connect(self.currentStep.setValue)
        self.stopButton.clicked.connect(self.simulRunner.stop)
        self.goButton.clicked.connect(self.simulThread.start)

        # As soon as the QThread object starts, instruct it to run our
        # worker thread's longRunning() method. Can be arbitrarily named
        self.simulThread.started.connect(self.simulRunner.longRunning)

        # Here's the tricky part. You must connect a signal from your
        # thread worker instance that tells the QThread object to
        # terminate.
        self.simulRunner.finished.connect(self.simulThread.quit)

        # now we want to get a signal from the thread so our GUI could
        # do some update.

        self.simulThread.finished.connect(self.thread_finished)
        self.stopButton.clicked.connect(self.on_stop_button)
        self.goButton.clicked.connect(self.simulThread.start)
        #self.connect(self.goButton, SIGNAL('clicked()'), self.simulThread.start)
        self.simulRunner.stepIncreased.connect(self.currentStep.setValue)
        #self.connect(self.simulRunner,SIGNAL('stepIncreased'), self.currentStep.setValue)

       

if __name__ == '__main__':
    app = QApplication(sys.argv)
    simul = SimulationUi()
    simul.show()
    sys.exit(app.exec_())
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to