Working with signal sender in Qt bindings

I tried to create dialog box with several controls of same type and use same signal handler for all of them. But self.sender() returned None.

class Test_Dialog(pya.QDialog):

    def __init__(self, parent, current_view, names):
        super(Test_Dialog, self).__init__(parent)
        self.current_view = current_view

        self.setWindowTitle('Test')
        self.resize(200, 400)

        layout = pya.QVBoxLayout(self)
        self.setLayout(layout)

        for name in names:
            check_box = pya.QCheckBox(name, self)
            check_box.tristate = False
            check_box.checkState = pya.Qt_CheckState('Checked')
            check_box.stateChanged = self.check_box_stateChanged
            layout.addWidget(check_box)

    def check_box_stateChanged(self, state):
        print(self.sender())

def test():
    app = pya.Application.instance()
    current_view = app.main_window().current_view()

    window = Test_Dialog(app.main_window(), current_view, ['1', '2', '3'])
    window.show()

I used 0.26.4 Ubuntu build from KLayout site.

Couple of more questions:

  • In C++ Qt sender() is cast to proper type with qobject_cast. Is there equivalent in Qt bindings? If not, how sender() should be used (for example, custom properties)?
  • Is my understanding of Qt constant (pya.Qt_CheckState('Checked') in code above) correct? If so, I think it'll be reasonable to make them enum classes.

Comments

  • edited April 2020

    Hi,

    currently, "sender()" isn't available in KLayout Qt binding flavour.

    The reason is that unlike in C++ Qt, the receiver can be any method of any class. In fact the binding is not built upon an emulation of the Qt signal/slot mechanism. You can actually add any callable to a Qt signal.

    This means you can use a lambda to add the sender parameter in case you want the same method to handle two events from different signals:

    check_box.stateChanged = lambda checked : self.check_box_stateChanged(checked, check_box)
    

    When the actions you want to take on a signal are not complex, you can even only use a lambda and you don't need a method for handling the signal.

    Regards,

    Matthias

  • Hi, Matthias!

    Thank you for explanations! It may be reasonable to add this to documentation.

Sign In or Register to comment.