各种尝试
项目开发中遇到了一个问题,想要设置一个蓝色背景的TabWidget,但是不管我怎么设置样式表,都没有生效。
我尝试了置QTabWidget的背景颜色,以及设置backGround-color的属性,在ui文件里看着是正常的,但是运行起来效果不一致
解决方法
我设置了QTabBar的样式表,但是发现默认情况下它只影响那几个Tab,而不会影响整个tab栏,需要设置QTabWidget的document属性为true,才能够正常的显示整个Tab栏的背景颜色
原因
我们直接去查看QTabWidget的源码
void QTabWidget::setDocumentMode(bool enabled)
{
Q_D(QTabWidget);
d->tabs->setDocumentMode(enabled);
d->tabs->setExpanding(!enabled);
d->tabs->setDrawBase(enabled);
setUpLayout();
}
这里的d->tabs实际上就是tabWidget自带的那个tab,可以直接调用QTabBar的样式,发现生效的实际上是tabs->setDocument(true)。
但是查看了tabBar的paintevent,发现并没有哪里绘制了它的背景。猜测是QTabWidget里影响了它,搜索哪里用到了document。
void QTabWidget::setUpLayout(bool onlyCheck) {
QStyleOptionTabWidgetFrame option;
initStyleOption(&option); //init中有给option设置document的值
QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this);
d->tabs->setGeometry(tabRect);
}
void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const {
if (d->tabs->isVisibleTo(const_cast<QTabWidget *>(this))) {
t = d->tabs->sizeHint();
if (documentMode()) {
if (tabPosition() == East || tabPosition() == West) {
t.setHeight(height());
} else {
t.setWidth(width());
}
}
}
可以看到是这里通过document的参数,设置了QTabBar的geometry
背景颜色是在哪里绘制的
现在知道了是根据document设置了QTabBar的geometry,但是又是在哪里绘制的qtabBar的这个背景框呢?rect应该是由painter.fillRect绘制,打断点发现是这里会调用用来。
QWidgetPrivate::paintBackground,根据堆栈查看它和paintEvent的关系。
先绘制了背景,再调用的paintEvent
void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, DrawWidgetFlags flags) const {
if (q->testAttribute(Qt::WA_StyledBackground)) {
painter->setClipRegion(rgn);
QStyleOption opt;
opt.initFrom(q);
q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
}
void QRenderRule::drawBackground(QPainter *p, const QRect& rect, const QPoint& off)
{
QBrush brush = hasBackground() ? background()->brush : QBrush();
/*省略其余代码*/
p->fillRect(originRect(rect, origin), brush); //这里就是目标地点
drawBackgroundImage(p, rect, off); //没有背景图片,这个函数就没实际意义
}