无论项数如何,如何设置QComboBox的标题文本

7

我有一个使用QStandardModel的QComboBox,我是通过以下方式添加项目的:

QStandardItem * item = new QStandardItem();
item->setText("someText");
item->setCheckable(true);

item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
item->setData(Qt::Checked, Qt::CheckStateRole);

m_model->appendRow(item);
m_ComboBox->setModel(m_model);

我想要一个带有复选框的组合框,这正是我想要的。现在,当用户取消选择所有项目时,下拉菜单应该显示“无”。如果用户选择一些项目,则应该显示“多个”。

我还没有找到设置 QComboBox 的标题文本的方法。除了子类化并自行完成之外,是否没有方便的方法?

2个回答

6

没有方便的方法可以不使用子类实现。事实上,子类是最方便的方法。

即使您可以运行QComboBox模型并检查哪些项目已选中或未选中,您也无法告诉组合框在所有项目(或部分项目)被选中后更新自己。没有信号或特定函数允许您这样做。

但是,将您的QComboBox子类化以具有此行为并不是非常复杂:您需要重新实现paintEvent()。

//return a list with all the checked indexes
QModelIndexList MyComboBox::checkedIndexes()const
{
    return model()->match(model()->index(0, 0), Qt::CheckStateRole, Qt::Checked, -1, Qt::MatchRecursive);
}

// returns a list with all the unchecked indexes
QModelIndexList MyComboBox::uncheckedIndexes()const
{
    return model()->match(model()->index(0, 0), Qt::CheckStateRole, Qt::Unchecked, -1, Qt::MatchRecursive);
}

//return true if all the items are checked
bool MyComboBox::allChecked()const
{
    return (uncheckedIndexes().count() == 0);
}

//return true if all the items are unchecked
bool MyComboBox::noneChecked()const
{
    return (checkedIndexes().count() == 0);
}

void MyComboBox::paintEvent(QPaintEvent *)
{
    QStylePainter painter(this);

    // draw the combobox frame, focusrect and selected etc.
    QStyleOptionComboBox opt;
    this->initStyleOption(&opt);

    // all items are checked
    if (allChecked())
        opt.currentText = "All";
    // none are checked
    else if (noneChecked())
        opt.currentText = "None";
    //some are checked, some are not
    else
        opt.currentText = "Multiple";

    painter.drawComplexControl(QStyle::CC_ComboBox, opt);

    // draw the icon and text
    painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
}

1
如果有人希望在Python中实现,使用以下代码:
class CheckableComboBox(QtGui.QComboBox):
    def __init__(self, parent=None):
        super(CheckableComboBox, self).__init__(parent)
        self.view().pressed.connect(self.handleItemPressed)
        self._changed = False

    def handleItemPressed(self, index):
        item = self.model().itemFromIndex(index)
        if item.checkState() == QtCore.Qt.Checked:
            item.setCheckState(QtCore.Qt.Unchecked)
        else:
            item.setCheckState(QtCore.Qt.Checked)
        self._changed = True

    def hidePopup(self):
        if not self._changed:
            super(CheckableComboBox, self).hidePopup()
        self._changed = False

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

    def setItemChecked(self, index, checked=True):
        item = self.model().item(index, self.modelColumn())
        if checked:
            item.setCheckState(QtCore.Qt.Checked)
        else:
            item.setCheckState(QtCore.Qt.Unchecked)

    def checkedIndexes(self):
        return self.model().match(self.model().index(0,0), QtCore.Qt.CheckStateRole, QtCore.Qt.Checked, -1, QtCore.Qt.MatchRecursive)

    def uncheckedIndexes(self):
        return self.model().match(self.model().index(0,0), QtCore.Qt.CheckStateRole, QtCore.Qt.Unchecked, -1, QtCore.Qt.MatchRecursive)

    def allChecked(self):
        return len(self.uncheckedIndexes()) == 0

    def noneChecked(self):
        return len(self.checkedIndexes()) == 0

    def paintEvent(self, event):

        painter = QtGui.QStylePainter(self)
        opt = QtGui.QStyleOptionComboBox()
        self.initStyleOption(opt)

        if self.allChecked():
            opt.currentText = "All"
        elif self.noneChecked():
            opt.currentText = "None"
        else:
            opt.currentText = "Multiple"

        painter.drawComplexControl(QtGui.QStyle.CC_ComboBox, opt)
        painter.drawControl(QtGui.QStyle.CE_ComboBoxLabel, opt)

似乎在PySide2 5.13.1中不再起作用(仅限于“currentText”的设置)。没有文本显示。 - bariod

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