Qt自定义下拉列表-可为选项设置标题、可禁用选项
立即下载
资源介绍:
项目开发中,很可能简单的QComboBox满足不了需求,就需要自定义QComboBox。本示例创建一个自定义的下拉列表,并为选项设置标题、可禁用选项
#include "CustomCombo.h"
#include
#include
CustomCombo::CustomCombo(QWidget *parent) :QComboBox(parent), list_(nullptr)
{
list_ = new QListWidget;
list_->setItemDelegate(new CustomComboDelegate(this));
setModel(list_->model());
setView(list_);
}
void CustomCombo::addTitle(const QString &text)
{
list_->addItem(new CustomComboTitle(this, text));
resetCurrentInd();
}
void CustomCombo::addItem(const QString &text)
{
list_->addItem(new CustomComboItem(this, text));
resetCurrentInd();
}
void CustomCombo::setIsTitle(int ind, bool b)
{
auto *item = dynamic_cast(list_->item(ind));
item->setIsTitle(b);
resetCurrentInd();
}
void CustomCombo::setSelectable(int ind, bool b)
{
auto *item = dynamic_cast(list_->item(ind));
item->setSelectable(b);
resetCurrentInd();
}
void CustomCombo::resetCurrentInd()
{
auto *item = static_cast(list()->item(currentIndex()));
if (item->isSelectable())
return;
for (int i = 0; i < count(); ++i) {
auto *item = static_cast(list()->item(i));
if (item->isSelectable()) {
setCurrentIndex(i);
break;
}
}
}
//CustomComboItem
//------------------------------------------------------------------------------------------------------------
CustomComboItem::CustomComboItem(CustomCombo *combo, const QString &str) :
QListWidgetItem(str), combo_(combo), isTitle_(false), selectable_(true){
}
void CustomComboItem::setIsTitle(bool b) {
isTitle_ = b;
if (isTitle_)
setSelectable(false);
}
void CustomComboItem::setSelectable(bool selectable) {
selectable_ = selectable;
if (selectable_)
setFlags(flags() | (Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled));
else
setFlags(flags() & ~(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled));
}
//CustomComboDelegate
//------------------------------------------------------------------------------------------------------------
CustomComboDelegate::CustomComboDelegate(CustomCombo *combo) :combo_(combo) {
}
void CustomComboDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const {
auto *item = static_cast(combo_->list()->item(index.row()));
QStyleOptionMenuItem opt = getStyleOption(option, index, item);
painter->fillRect(opt.rect, opt.palette.window());
combo_->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, combo_);
}
QSize CustomComboDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
auto *item = static_cast(combo_->list()->item(index.row()));
QStyleOptionMenuItem opt = getStyleOption(option, index, item);
return combo_->style()->sizeFromContents(QStyle::CT_MenuItem, &opt, option.rect.size(), combo_);
}
QStyleOptionMenuItem CustomComboDelegate::getStyleOption(const QStyleOptionViewItem &option,
const QModelIndex &index, CustomComboItem *item) const {
QStyleOptionMenuItem menuOption;
QPalette resolvedpalette = option.palette.resolve(QApplication::palette("QMenu"));
QBrush textBrush = resolvedpalette.brush(QPalette::Active, QPalette::Text);
QVariant value = index.data(Qt::ForegroundRole);
if (value.canConvert())
textBrush = qvariant_cast(value);
if (! item->isSelectable())
textBrush = resolvedpalette.brush(QPalette::Disabled, QPalette::Text);
if (item->isTitle())
textBrush = resolvedpalette.brush(QPalette::Active, QPalette::HighlightedText);
resolvedpalette.setBrush(QPalette::WindowText, textBrush);
resolvedpalette.setBrush(QPalette::ButtonText, textBrush);
resolvedpalette.setBrush(QPalette::Text , textBrush);
menuOption.palette = resolvedpalette;
menuOption.state = QStyle::State_None;
if (combo_->window()->isActiveWindow())
menuOption.state = QStyle::State_Active;
if ((option.state & QStyle::State_Enabled) && (index.model()->flags(index) & Qt::ItemIsEnabled))
menuOption.state |= QStyle::State_Enabled;
else
menuOption.palette.setCurrentColorGroup(QPalette::Disabled);
if (option.state & QStyle::State_Selected)
menuOption.state |= QStyle::State_Selected;
menuOption.checkType = QStyleOptionMenuItem::NonExclusive;
menuOption.checked = (combo_->currentIndex() == index.row());
if (isSeparator(index))
menuOption.menuItemType = QStyleOptionMenuItem::Separator;
else
menuOption.menuItemType = QStyleOptionMenuItem::Normal;
QBrush bgBrush = menuOption.palette.brush(QPalette::Window);
if (index.data(Qt::BackgroundRole).canConvert())
bgBrush = qvariant_cast(index.data(Qt::BackgroundRole));
if (item->isTitle())
bgBrush = resolvedpalette.brush(QPalette::Active, QPalette::Highlight);
menuOption.palette.setBrush(QPalette::All, QPalette::Window, bgBrush);
menuOption.text = index.model()->data(index, Qt::DisplayRole).toString();
menuOption.tabWidth = 0;
menuOption.maxIconWidth = option.decorationSize.width() + 4;
menuOption.menuRect = option.rect;
menuOption.rect = option.rect;
menuOption.font = combo_->font();
menuOption.fontMetrics = QFontMetrics(menuOption.font);
if (item->isTitle())
menuOption.font.setBold(true);
return menuOption;
}