[PyQt] PyQt5.3 invokeMethod with Qt.BlockingQueuedConnection and return value question

Alan Ezust alan.ezust at gmail.com
Sat Dec 13 17:02:05 GMT 2014


I am attaching a test case that shows how to use invokeMethod on an object
in another thread.
Basically, I want to get the return value of this function, so I set the
connection type to Qt.BlockingQueuedConnection.

For some reason the return value of the invokeMethod is always None.
Is this a bug in PyQt or am I just using invokeMethod in the wrong way?

Thanks! --Alan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20141213/be94a58c/attachment.html>
-------------- next part --------------
from nose.tools import assert_equals
from nose.tools import assert_equal, assert_in, assert_raises
import sys
from PyQt5.Qt import QObject, QApplication, pyqtSlot, QThread, QMetaObject, Qt, Q_ARG, qApp

class SampleQObject(QObject):
    def __init__(self, name = "", parent=None):
        super().__init__(parent)
        self.setObjectName(name)
        self.counter = 0

    @pyqtSlot(str)
    def sample_slot_with_args(self, string: str):
        self.counter += 1
        print ("slot with args called: " + string)
        if self.counter > 5:
            qApp.quit()
        return self.counter

    def __del__(self):
        print ("object " + self.objectName() + " cleaned up properly.")
        assert(True)



# -- Class Definitions: One per test case --

class TestInvokeMethod:
    """
    Test case that shows how to invoke a method of an object in another slot.
    Also shows how to make sure the thread and the heap object in the thread are cleaned up properly.
    """

    @classmethod
    def setup_class(cls):
        """Called once, when this Test Case instantiated"""
        pass
       
    def setup(self):
        """Called before every test method: """
        pass

    def teardown(self):
        """Called after every test method: """
        pass

    def test_invoke_method(self):
        """ Test to show how QMetaObject.invokeMethod() works for communicating with an object in another thread.  """
        self.app = QApplication.instance()
        if self.app is None:
            self.app = QApplication(sys.argv)
        self.other_thread_object = SampleQObject("b")
        # Set the parent of the QThread to ensure the QThread is cleaned up when the QApplication is:
        self.thread = QThread(self.app)
        self.other_thread_object.moveToThread(self.thread)
        self.thread.start()

        # the QThread's finished signal tells us when to clean up object b:
        self.thread.finished.connect(self.other_thread_object.deleteLater)
        # First get the metaobject, you can save this for multiple invocations.
        self.meta = self.other_thread_object.metaObject()
        # invokeMethod runs its slot in the other thread.
        for c in range(0, 10):
            return_val = self.meta.invokeMethod(self.other_thread_object, "sample_slot_with_args",
                                                Qt.BlockingQueuedConnection, Q_ARG(str, "invoke# " + str(c)))
            print (str(return_val))
        self.app.exec()

    @classmethod
    def teardown_class(cls):
        """Called once, when this Test Case has completed"""
        pass
       


More information about the PyQt mailing list