本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、前言
做一个简单的展示界面,所以继承了QWidget,然后在ui里撸了一通样式表之后,运行起来一看,样式啥也没有,内心很崩溃,这个时候不用慌,以下三种办法可供使用
二、解决方案
void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const
{
Q_Q(const QWidget);
#if QT_CONFIG(scrollarea)
bool resetBrushOrigin = false;
QPointF oldBrushOrigin;
//If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture
QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent);
if (scrollArea && scrollArea->viewport() == q) {
QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
oldBrushOrigin = painter->brushOrigin();
resetBrushOrigin = true;
painter->setBrushOrigin(-priv->contentsOffset());
}
#endif // QT_CONFIG(scrollarea)
const QBrush autoFillBrush = q->palette().brush(q->backgroundRole());
if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) {
const QBrush bg = q->palette().brush(QPalette::Window);
if (!(flags & DontSetCompositionMode)) {
//copy alpha straight in
QPainter::CompositionMode oldMode = painter->compositionMode();
painter->setCompositionMode(QPainter::CompositionMode_Source);
fillRegion(painter, rgn, bg);
painter->setCompositionMode(oldMode);
} else {
fillRegion(painter, rgn, bg);
}
}
if (q->autoFillBackground())
fillRegion(painter, rgn, autoFillBrush);
if (q->testAttribute(Qt::WA_StyledBackground)) {
painter->setClipRegion(rgn);
QStyleOption opt;
opt.initFrom(q);
q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
}
#if QT_CONFIG(scrollarea)
if (resetBrushOrigin)
painter->setBrushOrigin(oldBrushOrigin);
#endif // QT_CONFIG(scrollarea)
}
-
在QWidget中绘制背景的源码中,判断了一个WA_StyledBackground属性,只有为true时,才会去绘制背景样式,但是这个属性默认是false,也就是不绘制背景样式了,所以要解决问题,只需要将该属性设置为true就好了。
-
继承QFrame,因为QFrame就是专门用来承载样式的,所以本身已经对样式做了支持
void QFrame::paintEvent(QPaintEvent *)
{
QPainter paint(this);
drawFrame(&paint);
}
/*!
\internal
Used by QLabel and QLCDNumber
*/
void QFrame::drawFrame(QPainter *p)
{
QStyleOptionFrame opt;
initStyleOption(&opt);
style()->drawControl(QStyle::CE_ShapedFrame, &opt, p, this);
}
- 重写paintEvent,手动处理 从刚刚的源码中可以看到判断了WA_StyledBackground属性之后做了这段处理
if (q->testAttribute(Qt::WA_StyledBackground)) {
painter->setClipRegion(rgn);
QStyleOption opt;
opt.initFrom(q);
q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q);
}
所以,我们只需要把这段绘制背景样式的代码手动写出来,也能解决问题
void ChildWidget::paintEvent(QPaintEvent*)
{
QStyleOption option;
option.init(this);
QPainter painter(this);
style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this);
}
三、结言
如果在没设置样式的情况下,建议还是将WA_StyledBackground属性关掉,毕竟加载动作也是消耗很大的。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!