我有一个带有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的标题文本的方法。除了子类化和自己做之外没有方便的方法吗?
没有子类化就没有方便的方法。实际上,子类化是最方便的方法。
即使你可以运行你的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);
}
万一有人在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)