关于Qt使用QPalette设置Qwidget背景色无效的解决办法及分析

摘要:
标题栏是通过QWidget实现的,但当使用QPallette设置窗口的背景色时,它没有效果。如果bool为true,该属性将导致Qt在小部件触发PaintEvent之前填充QWidget的背景色。填充颜色由小部件的QPalette::window颜色角色决定。调色板的背景角色用于填充小部件的背景色。类似地,前景角色用于初始化笔颜色,即前景颜色。由于setPalette可以设置窗口的背景色,并且当小部件没有父窗口时,它可以成功设置背景色。

因需要,需要重绘窗口的标题栏。

标题栏通过QWidget实现,可是当使用QPalette设置窗口的背景色后没有效果。

代码如下:

    //QWidget类构造函数内
    QPalette p;
    p.setBrush(this->backgroundRole(),QBrush(QColor(51,51,51)));
    this->setPalette(p);

如果这个QWidget直接show,是有背景色的,但是如果把它放到一个父Widget中时,它就没有了效果。
后来通过网上搜索,发现添加如下代码后就可以了:

    //QWidget类构造函数内
   this->setAutoFillBackground(true);

于是翻看帮助文档的autoFillBackground属性,我翻译如下:

  QWidget的autoFillBackground属性  bool类型

  这个属性决定widget的背景色是否自动填充。

  如果bool为真,这个属性会在widget触发PaintEvent之前引起Qt填充QWidget的背景色。

  填充的颜色是由widget的QPalette::window颜色角色所决定的。

  如果该widget没有设置WA_OpaquePaintEvent属性或者WA_NoSystemBackground属性,windows总是会使用QPalette::window颜色角色。

  注意:如果widget的父窗口有渐变的背景色填充,那么这个属性是不能被关闭的(也就是不能设置为false)。

  警告:混合使用此属性和Qt style sheet的时候需要注意,当一个widget拥有一个style sheet设置的背景色或者border-image,那么autoFillBackground属性自动关闭。

  该属性默认是关闭状态。

查看QPalette::window,它为一个窗口的标准的背景色。

然后查看QPalette的说明,发现有下面一句说明:

When you assign a new palette to a widget, the color roles from this palette are combined with the widget's default palette to form the 
widget
's final palette. The palette entry for the widget's background role is used to fill the widget's
background (see QWidget::autoFillBackground), and the foreground role initializes QPainter's pen.

我的翻译就是:

When you assign a new palette to a widget, the color roles from this palette are combined with the widget's default palette to 
form the widget
's final palette. The palette entry for the widget's background role is used to fill the widget's
background (see QWidget::autoFillBackground), and the foreground role initializes QPainter's pen. 当为widget设置一个新的palette的时候,那么设置的palette和widget的默认palette组合成最终的palette。这个palette调色板的背景角色用于填充widget 的背景色(autoFillBackground),同样,前景角色用来初始化笔的颜色,也就是前景色。

既然setPalette是能够设置窗口的背景色,而且当widget没有父窗口是能够成功设置背景色的。
于是我感觉问题可能是出在这句话:

如果该widget没有设置WA_OpaquePaintEvent属性或者WA_NoSystemBackground属性,windows总是会使用QPalette::window颜色角色。

于是在构造函数和paintEvent中都qDebug输出this->Palette().background();
发现结果是一样的,这就证明问题不是出在这个位置。

仔细观看setPalette的说明发现:

QWidget propagates explicit palette roles from parent to child. 
If you assign a brush or color to a specific role on a palette and 
assign that palette to a widget, that role will propagate to all the 
widget's children, overriding any system defaults for that role. 
也就是说widget会清晰的传递自己的palette到孩子类。

于是我把父窗口的背景色设置为红色,发现widget的背景色也是红色了(通过qDebug输出widget的background根本不是红色)。
这也就是说明,如果没有设置autoFillBackground,那么子窗口的setPalette是不生效的。也就是会是使用从父类传递来的"默认"背景色。

我说大牛门把setAutoFillBackground函数的释义为不从父窗口继承背景色,当初我还有点怀疑,现在算是理解了,虽然不知道对不对。  新手,学习ing...

免责声明:文章转载自《关于Qt使用QPalette设置Qwidget背景色无效的解决办法及分析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇java根据图片路径下载图片并保存到本地目录ubuntu root 登录下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

如何 Graphics 对象设置背景色

用 Clear 方法可以轻松地给 Graphics 对象设置背景色。 using (Bitmap bmp = new Bitmap(width, height)){    using (Graphics graphics = Graphics.FromImage(bmp))    {        graphics.Clear(Color.White);...

【three.js详解之二】渲染器篇

【three.js详解之二】渲染器篇 本篇文章将详细讲解three.js中渲染器(renderer)的设置方法。 three.js文档中渲染器的分支如下: Renderers CanvasRenderer DOMRenderer SVGRenderer WebGLRenderer WebGLRenderTarget WebGLRenderTargetCu...

VUE:如何设置当前页面的背景色

给当前页面的最外层div  class 加样式 /deep/ html, .home {   position: fixed;   height: 100%;    100%;   background-color: #658ea9 !important; } 这是效果...

JavaScript网页全屏API

在大多数的浏览器中都有实现网页全屏显示的功能,并且大部分浏览器实现全屏显示和退出全屏显示的快捷键通常是F11和Esc两个按键。如今,W3C已经制定了关于网页全屏显示的API,利用这个API 可以实现网页的全屏显示,并且还能将某个特定的元素设置为全屏显示,在各浏览器的兼容性:google chrome 15 +, safri5.1+,firfox10+,IE...

cocostudio札记(一)

透明度和背景色透明度(cocostudio UI编辑器); 透明度作用于控件本身,例如图片对象,按钮对象,及层容器特性文件(图片);      颜色混合,随透明度的大小对控件整体混合特定颜色值 背景色透明度只作用于层容器的背景色,该值并不影响层容器的特性文件;      填充颜色,背景色,浓度随背景色透明度变化...

Qt之设置QWidget背景色(QStyleOption->drawPrimitive(QStyle::PE_Widget)方法比较有趣)

QWidget是所有用户界面对象的基类,这意味着可以用同样的方法为其它子类控件改变背景颜色。 Qt中窗口背景的设置,下面介绍三种方法。 1.使用QPalette2.使用Style Sheet3.绘图事件 一般我不用QSS设置窗口背景,也不建议使用。(这里是对于窗口而,如果是子部件当然可以)。因为窗口使用QSS设置背景之后,若子部件不使用同样的方式来设置,默...