使用 PyQt 的组合框中的复选框

发布于 2024-10-20 21:17:50 字数 245 浏览 3 评论 0原文

我需要实现一个包含复选框的下拉列表,就像将组合框中的条目作为复选框一样。但 QComboBox 不接受 QCheckBox 作为其成员,我找不到任何替代解决方案。我在 Qt Wiki 上 在 C++ 中找到了实现,但不知道如何移植它到蟒蛇。

I need to implement a drop down list that contains CheckBoxes, much like having the entries in a ComboBox being CheckBoxes. But QComboBox doesn't accept QCheckBox as its member and I couldn't find any alternate solution. I found an implementation in C++ on the Qt Wiki, but don't know how to port it to python.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花期渐远 2024-10-27 21:17:50

当我需要这个时,我想出了一个更简单的解决方案(至少不需要子类化 QCombobox)。这对我有用。
即创建一个包含可检查操作的菜单并将其设置为一个按钮。然后将菜单或操作连接到插槽。

Qt 中的代码(还没有使用 PyQt,抱歉,我希望你可以移植那个,对我来说似乎更容易)是这样的:

QMenu *menu = new QMenu;
QAction *Act1 = new QAction("Action 1", menu);
Act1->setCheckable(true);
QAction *Act2 = new QAction("Action 2", menu);
Act2->setCheckable(true);
menu->addAction(Act1);
menu->addAction(Act2);

QPushButton *btn = new QPushButton("Btn");    
btn->setMenu(menu);

希望这有帮助

When i needed this, I come up with an easier solution (at least it is not necessary to subclass QCombobox). It worked for me.
That is create a menu with checkable actions and set it to a button. Then connect either the menu or the actions to a slot.

The code in Qt(haven't use PyQt yet, sorry, i hope you can port that one, seems easier to me) was something like that:

QMenu *menu = new QMenu;
QAction *Act1 = new QAction("Action 1", menu);
Act1->setCheckable(true);
QAction *Act2 = new QAction("Action 2", menu);
Act2->setCheckable(true);
menu->addAction(Act1);
menu->addAction(Act2);

QPushButton *btn = new QPushButton("Btn");    
btn->setMenu(menu);

Hope this helps

メ斷腸人バ 2024-10-27 21:17:50

使用组合框项目模型,因为项目支持复选框
您只需要将该项目标记为可由用户检查,并设置一个初始 checkState 以使复选框出现(它仅显示是否存在有效状态)

item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)  # causes checkBox to show

这是一个最小的子类示例:

from PyQt5 import QtGui, QtCore, QtWidgets
import sys, os

# subclass
class CheckableComboBox(QtWidgets.QComboBox):
    # once there is a checkState set, it is rendered
    # here we assume default Unchecked
    def addItem(self, item):
        super(CheckableComboBox, self).addItem(item)
        item = self.model().item(self.count()-1,0)
        item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
        item.setCheckState(QtCore.Qt.Unchecked)

    def itemChecked(self, index):
        item = self.model().item(i,0)
        return item.checkState() == QtCore.Qt.Checked

# the basic main()
app = QtWidgets.QApplication(sys.argv)
dialog = QtWidgets.QMainWindow()
mainWidget = QtWidgets.QWidget()
dialog.setCentralWidget(mainWidget)
ComboBox = CheckableComboBox(mainWidget)
for i in range(6):
    ComboBox.addItem("Combobox Item " + str(i))

dialog.show()
sys.exit(app.exec_())

Use the Combobox item model, since items support checkBoxes
you just need to mark the item to be checkable by the user, and set an initial checkState to make the checkBox appear (it does only show if there is a valid state)

item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)  # causes checkBox to show

Here is a minimal subclass example:

from PyQt5 import QtGui, QtCore, QtWidgets
import sys, os

# subclass
class CheckableComboBox(QtWidgets.QComboBox):
    # once there is a checkState set, it is rendered
    # here we assume default Unchecked
    def addItem(self, item):
        super(CheckableComboBox, self).addItem(item)
        item = self.model().item(self.count()-1,0)
        item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
        item.setCheckState(QtCore.Qt.Unchecked)

    def itemChecked(self, index):
        item = self.model().item(i,0)
        return item.checkState() == QtCore.Qt.Checked

# the basic main()
app = QtWidgets.QApplication(sys.argv)
dialog = QtWidgets.QMainWindow()
mainWidget = QtWidgets.QWidget()
dialog.setCentralWidget(mainWidget)
ComboBox = CheckableComboBox(mainWidget)
for i in range(6):
    ComboBox.addItem("Combobox Item " + str(i))

dialog.show()
sys.exit(app.exec_())
只涨不跌 2024-10-27 21:17:50

我在 如何在组合框内创建树视图(带有复选框)-PyQt,但无论如何,为了回复的完整性,我将您粘贴到此处:

您应该创建一个支持 Qt 的模型data 和 SetData 方法中的 .CheckStateRole 以及 flags 方法中的标志 Qt.ItemIsUserCheckable。

我在这里粘贴一个我在项目中使用的示例,这是一个可在任何模型中使用的 QSortFilterProxyModel 通用实现,但您可以在模型实现中使用相同的想法,显然我在这个子类中使用您没有直接使用的内部结构PyQt 和 附加到我的内部实现(self.booleanSet 和 self.readOnlySet)。

def flags(self, index):
    if not index.isValid():
        return Qt.ItemIsEnabled

    if index.column() in self.booleanSet:
        return Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsEnabled
    elif index.column() in self.readOnlySet:
        return Qt.ItemIsSelectable | Qt.ItemIsEnabled
    else:
        return QSortFilterProxyModel.flags(self, index)

def data(self, index, role):
    if not index.isValid():
        return QVariant()

    if index.column() in self.booleanSet and role in (Qt.CheckStateRole, Qt.DisplayRole):
        if role == Qt.CheckStateRole:
            value = QVariant(Qt.Checked) if index.data(Qt.EditRole).toBool() else QVariant(Qt.Unchecked)
            return value
        else: #if role == Qt.DisplayRole:
            return QVariant()
    else:
        return QSortFilterProxyModel.data(self, index, role)

def setData(self, index, data, role):
    if not index.isValid():
        return False

    if index.column() in self.booleanSet and role == Qt.CheckStateRole:
        value = QVariant(True) if data.toInt()[0] == Qt.Checked else QVariant(False)
        return QSortFilterProxyModel.setData(self, index, value, Qt.EditRole)
    else:
        return QSortFilterProxyModel.setData(self, index, data, role)

I have replied a similar question at How do I create a tree view (with checkbox) inside a combo box - PyQt, but anyway and for completeness in the reply i paste you here:

You should create a model that support Qt.CheckStateRole in data and SetData methods and the flag Qt.ItemIsUserCheckable in the flags method.

I Paste you here an example i am using in a project, this is a QSortFilterProxyModel generic implementation to use in any model but you can use the same ideas in your model implementation, obviously i am using internal structures in this subclass you have not directly in PyQt and are attached to my internal implementation (self.booleanSet and self.readOnlySet).

def flags(self, index):
    if not index.isValid():
        return Qt.ItemIsEnabled

    if index.column() in self.booleanSet:
        return Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsEnabled
    elif index.column() in self.readOnlySet:
        return Qt.ItemIsSelectable | Qt.ItemIsEnabled
    else:
        return QSortFilterProxyModel.flags(self, index)

def data(self, index, role):
    if not index.isValid():
        return QVariant()

    if index.column() in self.booleanSet and role in (Qt.CheckStateRole, Qt.DisplayRole):
        if role == Qt.CheckStateRole:
            value = QVariant(Qt.Checked) if index.data(Qt.EditRole).toBool() else QVariant(Qt.Unchecked)
            return value
        else: #if role == Qt.DisplayRole:
            return QVariant()
    else:
        return QSortFilterProxyModel.data(self, index, role)

def setData(self, index, data, role):
    if not index.isValid():
        return False

    if index.column() in self.booleanSet and role == Qt.CheckStateRole:
        value = QVariant(True) if data.toInt()[0] == Qt.Checked else QVariant(False)
        return QSortFilterProxyModel.setData(self, index, value, Qt.EditRole)
    else:
        return QSortFilterProxyModel.setData(self, index, data, role)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文