0

I wasn't sure how best to word this, but I have an external class which is used to load a "module" into a main application. What I found was that signals/slots from the "module" application did not work unless at least one of them used lambda, even if it didn't have a real reason to otherwise. It didn't matter which one, and it didn't matter what order. I made this simple example to illustrate the point. Running this and pressing the f-key prints 'Foo', pressing the b-key prints 'Bar'. Any ideas why it has to be this way? Thanks.

# GUI
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

# Utility
import sys

class Module(QWidget):

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

        printfoo = QShortcut(QKeySequence('f'), parent)
        printbar = QShortcut(QKeySequence('b'), parent)


        # One of these have to use lambda for either to work
        # It doesn't matter which, and it doesn't matter the order
        printfoo.activated.connect(self.foo)
        printbar.activated.connect(lambda: self.bar())

    def foo(self):
        print('Foo')

    def bar(self):
        print('Bar')

class App(QMainWindow):

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

        self.content = QWidget()
        self.setCentralWidget(self.content)

        Module(self)

        layout = QHBoxLayout()
        self.content.setLayout(layout)

        self.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    window = App()

    sys.exit(app.exec_())
  • 1
    You're not creating a persistent reference to the `Module` ​instance, you're just creating it without assigning it to anything. The lambda creates a closure, so PyQt "chooses" to not garbage collect the object as it would with a direct connection. Either use `super.__init__(parent)` in `Module` or, better, use `self.module = Module(self)`. – musicamante Aug 24 '21 at 14:32
  • Makes sense. Thanks! – somethingvague Aug 24 '21 at 15:23

0 Answers0