效果:
其实,在这里之前看了许多自定义颜色控件,有的是采用继承QPushButton。点击后,直接弹出 QColorDialog,然后重写 paintEvent()函数,绘制背景为选中的颜色。但是,没有下拉选择颜色的感觉。
也有的继承 QCombox。在 item 项中添加颜色和文本。通过下拉数据项来选择。
如下所示,
但是,如果通过下拉数据项来选择的话,如果颜色较多,则不适用。
因此我采用继承QCombox。点击后,弹出一个 Popup 的窗体(通过 setWindowFlags(flags) 设置)。
这样的话,点击窗体外面的部分,会自动关闭该窗体。
我们知道,继承 QCombox。如果重写 paintEvent()函数的话,则不会执行QCombox 中的 paintEvent,(子类重写父类的方法,调用子类方法时父类方法则不执行)。也就是原有QCombox 的样式会没有,需要我们在重新绘制。(类似此时就是一个QWidget样式)。
而我们的需求只是需要改变 QCombox 中 LineEdit 中的背景颜色。其余的样式不变(下拉样式等)。
因此我们需要了解QCombox的构成。
Qt—自定义界面之QStyle 这里推荐这位老哥的文章,描述的很清楚,我这里也只是做一些用法上的引用。
这里我们重写了paintEvent()。为了保持原有的样式结构,我们可以查看QCombox 的源码,发现样式的绘制采用的是 QStyle。在这篇文章里我描述了一下 Qt QStyle。
this->initStyleOption(&butOpt);
style->drawComplexControl(QStyle::CC_ComboBox,&butOpt,&painter,this);
其实,上面这些代码,就可以通过QStyle 绘制 QCombox 原有的样式了。
我们可以将该部分代码拷贝出来,复制到重写的 paintEvent()中,使它保持原有的样式,在原有样式的基础上在改造它。
代码如下:
void CustomCombox::initStyleOption(QStyleOptionComboBox *option) const
{
option->initFrom(this);
option->editable = isEditable();
if (hasFocus() && !option->editable)
option->state |= QStyle::State_Selected;
option->subControls = QStyle::SC_All;
if (this->m_barrowState == QStyle::State_Sunken) {
option->activeSubControls = QStyle::SC_ComboBoxArrow;
option->state |= this->m_barrowState;
} else {
option->activeSubControls = this->hoverControl;
}
}
void CustomCombox::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
QPainter painter(this);
//获取QStyle样式
QStyle *style = QWidget::style();
//QCombox样式
QStyleOptionComboBox butOpt;
this->initStyleOption(&butOpt);
// 绘制文本
style->drawControl(QStyle::CE_ComboBoxLabel, &butOpt, &painter, this);
//绘制复杂Combox样式
style->drawComplexControl(QStyle::CC_ComboBox,&butOpt,&painter,this);
//获得子元素矩形范围
QRect labelRect = style->subControlRect(QStyle::CC_ComboBox,&butOpt,QStyle::SC_ComboBoxEditField, this);
QColor fillCol = backgroundColor;
painter.fillRect(labelRect, fillCol);
//返回指定像素值指标的值
// style->pixelMetric(QStyle::PM_ComboBoxFrameWidth)
// qDebug()<<"paintEvent";
}
上面,我们获取了 子元素(SC_ComboBoxEditField)矩形的范围:
QRect labelRect = style->subControlRect(QStyle::CC_ComboBox,&butOpt,QStyle::SC_ComboBoxEditField, this);
在通过绘制矩形区域修改颜色。