Флажки в Combobox с использованием PyQt - PullRequest
5 голосов
/ 08 марта 2011

Мне нужно реализовать выпадающий список, который содержит CheckBoxes, очень похоже на наличие записей в ComboBox, являющихся CheckBoxes. Но QComboBox не принимает QCheckBox в качестве своего члена, и я не смог найти альтернативного решения. Я нашел реализацию в C ++ на Qt Wiki, но не знаю, как перенести ее на python.

Ответы [ 3 ]

5 голосов
/ 08 марта 2011

Когда мне это нужно, я придумываю более простое решение (по крайней мере, нет необходимости создавать подкласс 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);

Надеюсь, это поможет

2 голосов
/ 24 сентября 2017

Используйте модель элемента Combobox, так как элементы поддерживают флажки, вам просто нужно пометить элемент для проверки пользователем и установить начальное состояние checkState, чтобы появился флажок (он отображается только при наличии действительного состояния)1001 *

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_())
2 голосов
/ 13 марта 2011

Я ответил на аналогичный вопрос на Как создать древовидное представление (с флажком) внутри поля со списком - PyQt , но в любом случае и для полноты ответа я вставлю вас сюда:

Вы должны создать модель, которая поддерживает Qt.CheckStateRole в методах data и SetData и флаг Qt.ItemIsUserCheckable в методе flags.

Вставьте вам пример, который я использую в проекте, этоуниверсальная реализация 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)
...