这是一个老生常谈的问题,在使用Qt进行界面开发时,我们经常会继承自QWidget来实现自定义控件(当然这里说的是非顶级窗口),此时我们发现在该自定义控件上应用QSS样式会无效。

导致这个问题的主要原因是QWidget的paintEvent函数实现为空,未做任何绘制,也没有对样式表进行初始化和绘制,其代码如下:

1
2
3
void QWidget::paintEvent(QPaintEvent *)
{
}

解决这个问题也比较简单,在QWidget子类的paintEvent函数中初始化并绘制样式表:

1
2
3
4
5
6
void CustomWidget::paintEvent(QPaintEvent* e) {
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

当然我们也可以采用变通的方法,改为继承自QFrame,因为QFrame默认初始化和绘制了样式表,其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
}