如何使用 QStyle 和指定的 QSS 绘制控件?

Posted

技术标签:

【中文标题】如何使用 QStyle 和指定的 QSS 绘制控件?【英文标题】:How to draw control with QStyle and with specified QSS? 【发布时间】:2013-10-08 21:45:18 【问题描述】:

我正在尝试在QStyledItemDelegate 中绘制一个复选框。我希望不使用原生外观绘制复选框,而是使用qApp->setStyleSheet() 指定的样式。我不知道为什么,但是当我使用 QStyle::drawPrimitive 绘制控件时 - 它不会获取全局 qss。

有没有解决办法,如何手动绘制应用风格的复选框?

以下代码和屏幕截图演示了我的问题:

第一个复选框是用QStyle::drawPrimitive 绘制的,第二个复选框是小部件。

#include <QApplication>
#include <QWidget>
#include <QStyle>
#include <QPainter>
#include <QStyleOptionButton>
#include <QCheckBox>

class TestWindow
    : public QWidget

    Q_OBJECT

public:
    TestWindow() 
    ~TestWindow() 

    void paintEvent( QPaintEvent * event )
    
        QPainter p( this );

        QStyleOptionButton opt;
        opt.state |= QStyle::State_On;
        opt.state |= QStyle::State_Enabled;
        opt.rect = QRect( 10, 10, 20, 20 );

        style()->drawPrimitive( QStyle::PE_IndicatorCheckBox, &opt, &p, this );
    
;

int main( int argc, char *argv[] )

    QApplication a( argc, argv );

    a.setStyleSheet( "QCheckBox::indicator border: 1px solid red; " );

    TestWindow w;
    QCheckBox *cb = new QCheckBox( &w );
    cb->move( 10, 30 );

    w.show();

    return a.exec();


#include "main.moc"

注意:可以创建不可见的复选框并使用QPixmap::grabWidget,但是这种方法太重了。

【问题讨论】:

【参考方案1】:

Qt 目前does not support 的此类绘图:

警告:自定义 QStyle 目前不支持 Qt 样式表 子类。我们计划在未来的某个版本中解决这个问题。

【讨论】:

这是否同时发生了变化(Qt 5 或 Qt 6)? @pasbi - 似乎不是 - doc-snapshots.qt.io/qt6-dev/qapplication.html#setStyle【参考方案2】:
QPainter p( this );

QStyleOptionButton opt;
opt.state |= QStyle::State_On;
opt.state |= QStyle::State_Enabled;
opt.rect = QRect( 10, 10, 20, 20 );

QCheckBox cb(this); // create fake checkbox

style()->drawPrimitive( QStyle::PE_IndicatorCheckBox, &opt, &p, &cb); // pass a pointer to checkbox instead of "this"

【讨论】:

欢迎来到 Stack Overflow!你能否请edit你的答案解释为什么这段代码回答了这个问题?纯代码答案是 discouraged,因为它们不教授解决方案。

以上是关于如何使用 QStyle 和指定的 QSS 绘制控件?的主要内容,如果未能解决你的问题,请参考以下文章

QT常见面试题,基础知识偏多

QT常见面试题,基础知识偏多

QT常见面试题,基础知识偏多

QT常见面试题,基础知识偏多

QSS-qt样式表

继承QWidget后无法使用QSS