子类化 QGroupBox 以便它可以成为 QButtonGroup 的成员 [英] subclassing QGroupBox so that it can be member of QButtonGroup

查看:35
本文介绍了子类化 QGroupBox 以便它可以成为 QButtonGroup 的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

QButtonGroups 可以有复选框.但是您不能将它们添加到 QButtonGroup 中,因为它们不继承 QAbstractButton.

QButtonGroups can have checkboxes. But you cannot add them to a QButtonGroup because they do not inherit QAbstractButton.

对于一些 UI 来说,如果能够拥有一些带有独占复选框的 QGroupBox,那就太好了.也就是说,您选中一个,其他 QGroupBoxes 将自动取消选中.

It would be really nice for some UIs to be able to have a few QGroupBoxes with exclusive checkboxes. That is, you check one and the other QGroupBoxes are automatically unchecked.

在理想的世界中,我可以这样做:

In an ideal world, I could do something like this:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QGroupBox, QWidget, QApplication, 
                             QAbstractButton, QButtonGroup)

class SuperGroup(QGroupBox, QAbstractButton):
    def __init__(self, title, parent=None):
        super(SuperGroup, self).__init__(title, parent)
        self.setCheckable(True)
        self.setChecked(False)

class Example(QWidget):

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

        sg1 = SuperGroup(title = 'Super Group 1', parent = self)
        sg1.resize(200,200)
        sg1.move(20,20)

        sg2 = SuperGroup(title = 'Super Group 2', parent = self)
        sg2.resize(200,200)
        sg2.move(300,20)

        self.bgrp = QButtonGroup()
        self.bgrp.addButton(sg1)
        self.bgrp.addButton(sg2)


        self.setGeometry(300, 300, 650, 500)
        self.setWindowTitle('SuperGroups!')
        self.show()



if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

一旦您尝试将 SuperGroup 添加到按钮组,此代码就会失败.PyQt5 明确不支持多重继承.但是有一些野外的例子,比如来自这个博客.

This code fails as soon as you try to add a SuperGroup to the button group. PyQt5 explicitly does not support multiple inheritance. But there are some examples out in the wild, like from this blog.

在这个简单的示例中,以编程方式管理点击会很容易.但是随着您添加更多的分组框,它会变得更加混乱.或者如果你想要一个带有按钮、复选框和分组框的 QButtonGroup 怎么办?啊.

In this simple example, it would be easy to manage the clicks programmatically. But as you add more group boxes, it gets more messy. Or what if you want a QButtonGroup with buttons, check boxes, and group boxes? Ugh.

推荐答案

没有必要创建一个继承自 QGroupBox 和 QAbstractButton 的类(而且在 pyqt 或 Qt/C++ 中是不可能的).解决方案是创建一个 QObject 来在检查任何 QGroupBox 时处理另一个 QGroupBox 的状态,并且我为 旧答案实现了它 用于 Qt/C++ 所以这个答案只是一个翻译:

It is not necessary to create a class that inherits from QGroupBox and QAbstractButton (plus it is not possible in pyqt or Qt/C++). The solution is to create a QObject that handles the states of the other QGroupBox when any QGroupBox is checked, and I implemented that for an old answer for Qt/C++ so this answer is just a translation:

import sys
from PyQt5.QtCore import pyqtSlot, QObject, Qt
from PyQt5.QtWidgets import QGroupBox, QWidget, QApplication, QButtonGroup


class GroupBoxManager(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._groups = []

    @property
    def groups(self):
        return self._groups

    def add_group(self, group):
        if isinstance(group, QGroupBox):
            group.toggled.connect(self.on_toggled)
            self.groups.append(group)

    @pyqtSlot(bool)
    def on_toggled(self, state):
        group = self.sender()
        if state:
            for g in self.groups:
                if g != group and g.isChecked():
                    g.blockSignals(True)
                    g.setChecked(False)
                    g.blockSignals(False)

        else:
            group.blockSignals(True)
            group.setChecked(False)
            group.blockSignals(False)


class Example(QWidget):
    def __init__(self):
        super().__init__()

        sg1 = QGroupBox(
            title="Super Group 1", parent=self, checkable=True, checked=False
        )
        sg1.resize(200, 200)
        sg1.move(20, 20)

        sg2 = QGroupBox(
            title="Super Group 2", parent=self, checkable=True, checked=False
        )
        sg2.resize(200, 200)
        sg2.move(300, 20)

        self.bgrp = GroupBoxManager()
        self.bgrp.add_group(sg1)
        self.bgrp.add_group(sg2)

        self.setGeometry(300, 300, 650, 500)
        self.setWindowTitle("SuperGroups!")
        self.show()


if __name__ == "__main__":

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

这篇关于子类化 QGroupBox 以便它可以成为 QButtonGroup 的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆