使用qt版本5.11.0 window10.
经过试验,qt中的qwidget 的background 可以理解为至少有两个层次。
试验如下:
1、Qpainter 对QPixmap进行画图。
(wb.png)
QPixmap pix("E:/temp1/wb.png");
QPainter painter(&pix);
painter.fillRect(pix.rect(),QColor(0,255,0,100));
pix.save("E:/temp1/wb2.png");
painter.eraseRect(pix.rect());
painter.fillRect(pix.rect(),QColor(0,0,255,100));
pix.save("E:/temp1/wb3.png");
发现eraseRect 会将pixmap完全填充覆盖掉。
2、但是如果在qwidget的paintevent中做同样的操作。
QPainter painter1(this);
painter1.eraseRect(this->rect());
painter1.save();
painter1.fillRect(this->rect(), QColor(255,0,0,100));
Widget::paintEvent(event);
却发现并没有将qwidget上的 控件甚至 初始时通过Qpalette设置的背景图片或颜色抹除掉。这说面 qpainter和qpixmap的行为有差异。另外看到的效果是,在原来的背景上添加了半透的红色(还能看到背景图),并且半透红色没有覆盖上面的组件,而组件是继承自QWidget ,所以组件又都具有相同的结构。
这里就说明底层是有两层buffer的,一层是systembuffer,一层是基于底层添加paintevent所绘制的buffer。然后再在上面有组件层。
setpalette其实并没有调用paintevent,但是却能够修改背景颜色,这是上面猜测之一。
setstylesheet最终会被解释成qstyle,qstyle貌似也是转换成qpalette起作用。最终都是更新systembuffer。setstylesheet 与setpalette 的区别是后者需要设置QWidget 或其子组件的setAutoFillBackground(true),前者如果是在qwidget中,需要在paintevent中 添加对应的代码,可以参考我前面的博文查看具体使用差异。