0

I have an application using QThreads. I am adding different methods to a queued connection and they are run in that sequence. This has been working very well. But the depending on the order of the tests (sequence can be in any order) my application will just stop (It won't freeze, but it won't finish calling the rest of the tests in the queue). For example if running the sequence [test1, test2, test3]. I will be able to run and finish (finish signal is emitted) test1 and test2, but test3 will not be called. However, this only happens sometimes, not all the time. I think the thread is quitting before all the tasks are complete. Is there something I should be clearing?

Relevant code below:

    # Initialize QThread
    self.obj = signalTest.Worker()
    self.thread = QThread()
    self.obj.moveToThread(self.thread)
    self.obj.finished.connect(self.signalFinished)

def runTests(self) # This is triggered by clicking a button
    self.thread.start()
    for index in range(0, len(sequence)):
        if self.queue[index] == 'test1'
            QMetaObject.invokeMethod(self.obj, 'run_test1', Qt.QueuedConnection,
                                     Q_ARG(int, index)
        elif self.queue[index] == 'test2'
            QMetaObject.invokeMethod(self.obj, 'run_test2', Qt.QueuedConnection)
        elif self.queue[index] == 'test3'
            QMetaObject.invokeMethod(self.obj, 'run_test3', Qt.QueuedConnection)

@pyqtSlot(int)
def signalFinished(self, row)
    # Do something here

Worker thread:

class Worker(QObject):
    finished = pyqtSignal(int)

    @pyqtSlot(int)
    def test1(self):
        """
        Runs test1
        """
        if self.abort is False:
            # Run test1 here
        self.finished.emit(row)
....
climbx5
  • 85
  • 1
  • 8
  • I'm wondering why you are using `QMetaObject` to call the slot in the worker? You can achieve the same thing with the usual signal/slot connection assuming it is done in the correct order (see [here](http://stackoverflow.com/q/20752154/1994235)). Anyway, wondering if the issue is because of the use of the `QMetaObject` and if you have tried defining signals in the main thread which are connected to slots in the worker, and triggering those via calling `emit()` on the signals? – three_pineapples Dec 08 '16 at 22:59
  • I do have something connected to the slots in the worker that are triggered by the emit() signal (updated code above) – climbx5 Dec 08 '16 at 23:13
  • Would I just do something like self.obj.run_test1(index)? – climbx5 Dec 08 '16 at 23:37
  • No, that would run the method in the main thread. You still need to create a `QueuedConnection` but Qt will automatically do that if you connect a signal (or rather three) from the main thread, to a slot in an object in a worker thread. You need to define a new signal in the class that houses the `runTests` method and connect it to the worker slot. Then emit that new signal (basically the reverse direction of what you are doing now). I don't know if it will make any difference, but I haven't seen someone directly use `QMetaObject` directly before which makes me suspicious. – three_pineapples Dec 09 '16 at 00:40

0 Answers0