Qt虽然提供了 style sheet 方式设置控件样式,但Qt并没有将对应的QStyleSheetStyle公开。Qt的基础控件都是使用了QStyle接口绘制的,在使用 style sheet 时,大部分样式,如颜色、字体、边框等,在绘制时会从样式表中读取并覆盖QStyleOption,用户代码无法感知到该过程,特别是当设置了 hover、pressed 动作下的样式时。所以绘制的过程只能交给QStyle去绘制控件。
不过,QStyle接口并不关心QPainter参数的绘制目标,例如可以通过
QWidget::render
来截取控件内容。Qt也没有限制在A控件上绘制B控件。
另外,尽管Qt文档里说明了不同控件的style sheet应用范围,但实际样式定义了就会存在,即使样式对某些控件本身无效。
所幸,QComboBox和QPushButton的绘制事件比较简单,不涉及私有接口,可以借用一些源码里的绘制逻辑,所以重写
QComboBox::paintEvent
QStylePainter painter(this);
painter.setPen(palette().color(QPalette::Text));
QStyleOptionComboBox opt;
initStyleOption(&opt);
painter.drawComplexControl(QStyle::CC_ComboBox, opt);
if (currentIndex() < 0)
opt.palette.setBrush(QPalette::ButtonText, opt.palette.brush(QPalette::ButtonText).color().lighter());
painter.end();
QPainter painter2(this);
QStyleOptionButton buttonOpt;
buttonOpt.initFrom(this);
QRect editRect = this->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this);
buttonOpt.rect = editRect;
buttonOpt.text = opt.currentText;
this->style()->drawControl(QStyle::CE_PushButtonLabel, &buttonOpt, &painter2, this);
需要注意的是:
- 最后通过 QStyle::drawControl 仅绘制 QStyle::CE_PushButtonLabel ,是由于 QStyle::CE_PushButton 会绘制边框等样式,如果QComboBox设置了边框,会重复画一遍。
- QStyle::drawControl 最后一个参数必须传QComboBox对象,样式需要通过窗口来获取。
- 可以在QComboBox的样式中设置 text-align 来控制文本的对齐,虽然对QComboBox本身无效,但对QPushButton有效
- 通过设置按钮文本绘制区域来控制位置,但可能会存在某些特殊的样式没有计算在内。
hover状态下的样式同样能够保留,由于未增加其他子控件,交互逻辑也没有变化。
一开始考虑使用组合的方式,在QComboBox上覆盖QLabel来实现居中,但QStyle在应用的过程中,针对QComboBox子控件的样式做了过滤,样式并不会生效。Qt有个私有的属性 Qt::WA_StyleSheet 可以跳过过滤,但在重设 style sheet 时可能引起异常。
还有一种比较麻烦的方案是,默认实现里,painter.drawControl(QStyle::CE_ComboBoxLabel, opt) 这段执行前,通过字体信息计算当前文本宽度,修改opt的rect属性,使默认的文本绘制刚好显示在中间。
QComboBox *combox = new QComboBox;static_cast<QStandardItemModel*>(combox->view()->model())->item(positon)->setTextAlignment(Qt::AlignCenter);每次只能修改一个item的文字位置...
一. 设置背景颜色+取消边框+取消容器内距离
setStyleSheet("background-color:rgb(63,63,63);padding:0px;border:0px");
setStyleSheet("gridline-color: rgb(255, 0, 0);\nbackgroun...
不知道你有没有遇到过这样的需求,将一个QComboBox的文字居中显示。我最近遇到了这样的需要,主要是要和其他的控件显示进行匹配,这也就要求我们必须将下拉列表的文字居中显示。这种需求可能实现的方式会有好多种,但我一直坚信,能用原生的就用原生的,或者在原生的控件之上进行一些特例化的改动,让其满足我们的需求是最简单的方式,并且不会过多的影响样式表设置。所以这儿我还是选择了QComboBox,而我们要做的事情就是怎样将他的文字居中显示。...
Qt QComboBox内容居中Qt-QComboBox内容居中设置1. 显示内容居中2 .下拉菜单内容居中
Qt-QComboBox内容居中设置
1. 显示内容居中
QComboBox *comboBox = new QComboBox;
QLineEdit *lineEdit = new QLineEdit;
lineEdit->setReadOnly(true);
lineEdit->setAlignment(Qt::AlignCenter);
// 监听lineEdit事件
QLineEdit*lineEdit=newQLineEdit;
lineEdit->setReadOnly(true);
lineEdit->setAlignment(Qt::AlignCenter);
comboBox->setLineEdit(lineEdit);
由https://blog.csdn.net/qq_18286031/article/details/85113931处转载。
void comboBoxInit(QComboBox*box,int widthScroll,int height,bool bClolor)
box->setStyle(QStyleFactory::create("windowsvista"));
QLineEdit*lineEdit = box->lineEdit();
if(lineEdit == 0)
lineEdit = new QL.
字体属性:(font)
大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX、PD
样式 {font-style: oblique;}(偏斜体) italic;(斜体) normal;(正常)
行高 {line-height: normal;}(正常) 单位:PX、PD、EM
解决方案:
首先从网上找了一下,网上主流方法是通过setLineEdit(QLineEdit *edit)来设置edit的文本居中来完成文本居中显示,这样相当于改变了QComboBox显示框的属性了。但是这样点击edit框会无法弹出下拉框,又需要对edit框进行点击事件处理才可以完成。
我需要正常的label进行显示,尽量不改变它原有的属性,并且可以