PyQt: 为什么方法中的QButtonGroup需要使用'self.'前缀来发射buttonClicked信号?

6

我创建了一个QMainWindow GUI,使用一组单选按钮的工具栏来选择主显示(即显示QStackedWidget的哪个小部件)。最终,我成功地检测到了QButtonGroup的信号,但我并不完全理解为什么我的修复方法有效。

这里是一个最小化的工作示例; 重点是modelButtonGroup方法。

class myGui(QMainWindow):

    def __init__(self, parent=None):

        super(myGui, self).__init__(parent)
        self.setupCentral()
        self.setupButtonToolBar()

    def setupCentral(self):

        self.stackedWidget = QStackedWidget()
        self.setCentralWidget(self.stackedWidget)

        windowA = QWidget()
        windowALayout = QGridLayout()
        windowALayout.addWidget(QLabel('Window A'))

        windowB = QWidget()
        windowBLayout = QGridLayout()
        windowBLayout.addWidget(QLabel('Window B'))

        windowA.setLayout(windowALayout)
        windowB.setLayout(windowBLayout)

        self.stackedWidget.addWidget(windowA)
        self.stackedWidget.addWidget(windowB)
        self.stackedWidget.setCurrentIndex(0)

    def setupButtonToolBar(self):

        buttonBar = QToolBar()
        buttonBar.addWidget(self.modelButtonGroup())
        self.addToolBar(buttonBar)

    def modelButtonGroup(self):

        modelsWidget = QWidget()
        modelsLayout = QVBoxLayout()
        self.ButtonGroup = QButtonGroup()

        windowA_Button = QRadioButton('Window A')
        windowA_Button.setChecked(True)
        self.ButtonGroup.addButton(windowA_Button, 0)

        windowB_Button = QRadioButton('Window B')
        self.ButtonGroup.addButton(windowB_Button, 1)

        self.ButtonGroup.buttonClicked[int].connect(self.switchdisplay)

        modelsLayout.addWidget(windowA_Button)
        modelsLayout.addWidget(windowB_Button)
        modelsWidget.setLayout(modelsLayout)

        return modelsWidget

    def switchdisplay(self, id):
        print('button %d has been pressed' % id)
        self.stackedWidget.setCurrentIndex(id)

我的理解是,如果一个方法中的名称仅在该方法中引用,并且在类中没有其他地方引用,则不需要将self.作为前缀。但是,如果使用ButtonGroup而不是self.ButtonGroup,则其.buttonClicked信号不会被switchdisplay处理。

在撰写此问题时,我认为已经确定了原因,但仍需要确认。 modelButtonGroup仅返回按钮小部件,并且仅在设置GUI时调用。 ButtonGroup未传递出函数并被垃圾回收。即使它没有直接按名称引用,也需要使用'self.'前缀才能“存活下来”。

我的理解正确吗?


1
ButtonGroup must be a member of the class, if you do not want to use self.ButtonGroup, you can use ButtonGroup = QButtonGroup(self) - eyllanesc
这是一般的Python特性/效果,不是吗? - Trilarion
2个回答

6
我看到你已经自己解决了问题:

ButtonGroup没有传递出函数并被垃圾回收。即使没有直接引用,也需要使用“self.”前缀来保留它的存在。

我理解得对吗?

是的,这正是此处发生的情况。如果您不保留对ButtonGroup的引用,则会在超出范围时(在函数退出时)将其删除。它将永远不会发出任何信号。
我认为@eyllanesc的答案也可能起作用。在这种情况下,对ButtonGroup对象的引用将被隐式保留为parent类中的子项。
顺便说一句,我通常在处理QMenu对象时遇到此类错误。

3

ButtonGroup 必须是该类的成员,如果您不想使用 self.ButtonGroup,可以使用 ButtonGroup = QButtonGroup(self)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接