简体   繁体   中英

Can a signal get the return value of a slot in PySide/PyQt

Can I change the return type of a slot (such as class type or str or int)? And if that is possible, can I return two value like a normal function (such as (bool, str) or (int, str) )?

Code:

class SignalSlotTest(QObject):

    get_str = QtCore.Signal(str)
    get_bool_and_str = QtCore.Signal(str)

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

    def start(self):
        msg = self.get_str.emit('start1')
        print(f"start1 return : {msg}")
        (is_valid, msg) = self.get_bool_and_str.emit('start2')
        print(is_valid, msg)


class MainTest(QObject):

    @QtCore.Slot(str, result = str)         #   question 1
    def get_str_func(msg):
        return ""
    
    @QtCore.Slot(str, result=(bool, str))   #   question 2
    def get_bool_and_str_func(msg, msg2):
        return (False,"return_message")

if  __name__ == "__main__":
    main_test = MainTest()
    signal_slot_test = SignalSlotTest()
    signal_slot_test.get_str.connect(main_test.get_str_func)
    signal_slot_test.get_bool_and_str.connect(get_bool_and_str_func)
    signal_slot_test.start()

When I tested the first question, return type is 'bool' type. (It prints True ).

And when I tested the second question, an error occurs:

TypeError: 'bool' object is not iterable

I don't know if my method is wrong...

In PyQt and PySide, emit() will never return the return-value of any connected slot. PyQt always returns None , whilst PySide always returns True . (I don't exactly know why PySide returns this value, or whether it could ever return False , as it doesn't seem to be documented anywhere).

The signal-slot mechanism provides loosely-coupled notfications between unrelated objects. Signals are broadcast entirely passively. It does not matter whether they are connected to one slot, a dozen slots, or no slots at all. The slots simply react to the signals without needing to know anything about the object that emitted them. Likewise, the behaviour of the slots is irrelevant to the signals that are connected to them.

As for Qt itself, the docs state that:

Signals are automatically generated by the moc and must not be implemented in the.cpp file. They can never have return types (ie use void).

However, there are several questions on SO that prove that this is not entirely true. For example:

And indeed, when I tested the example given in this answer , I found it still works as expected with the latest versions of both Qt5 and Qt6. However, this kind of hackery has never been possible in PyQt/PySide. Presumably, this is simply because there's no obvious use-case for it (ie nothing that can't be achieved by other means).

As for slots: of course it is possible to declare them to have any kind of return value in PyQt, PySide and also Qt itself. Slots aren't only made for connections to signals. They can also be invoked directly, or by the meta object system , so there's no reason to limit their return values in any way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM