解析Qt自带的Style示例

Qt——自定义界面之QStyle 1. Qt控件结构简介 阅读详情

本文转自chenlong12580的专栏    点击打开链接


在之前的QStyle类参考一文中我们介绍到实现自定义样式有两种方法:静态方法和动态方法。我们先介绍静态方法:也就是继承已经存在的类,不是QStyle,通常是QCommonStyle或者是QWindowsStyle等等。然后实现其中的虚函数,重写自己需要修改的部分代码。至于选择哪个基类来继承完全取决用户,通常选择和自己所期望的最相近的类来继承。这里贴一个图,主要是继承层次的图:


        其中的QGtkStyle就是通常GNOME环境下的,而QPlastiqueStyle则是和KDE环境最为接近的。注意QMacStyle只有在Mac OS上才有效果,因为它的实现依赖相应的平台。

       接下来解析一下Qt自带的Style示例,示例程序是Qt十分好的学习资源,不可不看哦!

首先上效果图:


                  图一:自定义样式效果图


                              图二:支持的样式

         大家可以看到该程序在我的系统(Win7)上支持很多样式,这里就不一一截图了,大家可以自己编译示例程序体验一下。

         接下来是源代码,首先看一下工程的目录结构:


        大家可以看到,实现该自定义样式的类为:NorwegianWoodStyle,而类WidgetGallery主要是用代码实现整个界面布局,并没有什么好介绍的。主要介绍一下NorwegianWoodStyle类。

1、首先是头文件:

  1. class NorwegianWoodStyle : public QMotifStyle  
  2. {  
  3.     Q_OBJECT  
  4.   
  5. public:  
  6.     NorwegianWoodStyle() {}  
  7.   
  8.     void polish(QPalette &palette);  
  9.     void polish(QWidget *widget);  
  10.     void unpolish(QWidget *widget);  
  11.     int pixelMetric(PixelMetric metric, const QStyleOption *option,  
  12.                     const QWidget *widget) const;  
  13.     int styleHint(StyleHint hint, const QStyleOption *option,  
  14.                   const QWidget *widget, QStyleHintReturn *returnData) const;  
  15.     void drawPrimitive(PrimitiveElement element, const QStyleOption *option,  
  16.                        QPainter *painter, const QWidget *widget) const;  
  17.     void drawControl(ControlElement control, const QStyleOption *option,  
  18.                      QPainter *painter, const QWidget *widget) const;  
  19.   
  20. private:  
  21.     static void setTexture(QPalette &palette, QPalette::ColorRole role,  
  22.                            const QPixmap &pixmap);  
  23.     static QPainterPath roundRectPath(const QRect &rect);  
  24. };  
class NorwegianWoodStyle : public QMotifStyle
{
    Q_OBJECT

public:
    NorwegianWoodStyle() {}

    void polish(QPalette &palette);
    void polish(QWidget *widget);
    void unpolish(QWidget *widget);
    int pixelMetric(PixelMetric metric, const QStyleOption *option,
                    const QWidget *widget) const;
    int styleHint(StyleHint hint, const QStyleOption *option,
                  const QWidget *widget, QStyleHintReturn *returnData) const;
    void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                       QPainter *painter, const QWidget *widget) const;
    void drawControl(ControlElement control, const QStyleOption *option,
                     QPainter *painter, const QWidget *widget) const;

private:
    static void setTexture(QPalette &palette, QPalette::ColorRole role,
                           const QPixmap &pixmap);
    static QPainterPath roundRectPath(const QRect &rect);
};
        主要就是显示了QMotifStyle类中的虚函数,而这些函数最初是QStyle类中的虚函数。下面介绍这几个函数的功能:
(1)void polish(QPalette &palette)

     这是一个重载函数,功能就是改变调色板为样式指定的颜色调色板。

     该处具体实现为:

  1. //! [0]  
  2. void NorwegianWoodStyle::polish(QPalette &palette)  
  3. {  
  4.     QColor brown(212, 140, 95);  
  5.     QColor beige(236, 182, 120);  
  6.     QColor slightlyOpaqueBlack(0, 0, 0, 63);  
  7.   
  8.     QPixmap backgroundImage(":/images/woodbackground.png");  
  9.     QPixmap buttonImage(":/images/woodbutton.png");  
  10.     QPixmap midImage = buttonImage;  
  11.   
  12.     QPainter painter;  
  13.     painter.begin(&midImage);  
  14.     painter.setPen(Qt::NoPen);  
  15.     painter.fillRect(midImage.rect(), slightlyOpaqueBlack);  
  16.     painter.end();  
  17. //! [0]  
  18.   
  19. //! [1]  
  20.     palette = QPalette(brown);  
  21.   
  22.     palette.setBrush(QPalette::BrightText, Qt::white);  
  23.     palette.setBrush(QPalette::Base, beige);  
  24.     palette.setBrush(QPalette::Highlight, Qt::darkGreen);  
  25.     setTexture(palette, QPalette::Button, buttonImage);  
  26.     setTexture(palette, QPalette::Mid, midImage);  
  27.     setTexture(palette, QPalette::Window, backgroundImage);  
  28.   
  29.     QBrush brush = palette.background();  
  30.     brush.setColor(brush.color().dark());  
  31.   
  32.     palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush);  
  33.     palette.setBrush(QPalette::Disabled, QPalette::Text, brush);  
  34.     palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush);  
  35.     palette.setBrush(QPalette::Disabled, QPalette::Base, brush);  
  36.     palette.setBrush(QPalette::Disabled, QPalette::Button, brush);  
  37.     palette.setBrush(QPalette::Disabled, QPalette::Mid, brush);  
  38. }  
  39. //! [1]  
//! [0]
void NorwegianWoodStyle::polish(QPalette &palette)
{
    QColor brown(212, 140, 95);
    QColor beige(236, 182, 120);
    QColor slightlyOpaqueBlack(0, 0, 0, 63);

    QPixmap backgroundImage(":/images/woodbackground.png");
    QPixmap buttonImage(":/images/woodbutton.png");
    QPixmap midImage = buttonImage;

    QPainter painter;
    painter.begin(&midImage);
    painter.setPen(Qt::NoPen);
    painter.fillRect(midImage.rect(), slightlyOpaqueBlack);
    painter.end();
//! [0]

//! [1]
    palette = QPalette(brown);

    palette.setBrush(QPalette::BrightText, Qt::white);
    palette.setBrush(QPalette::Base, beige);
    palette.setBrush(QPalette::Highlight, Qt::darkGreen);
    setTexture(palette, QPalette::Button, buttonImage);
    setTexture(palette, QPalette::Mid, midImage);
    setTexture(palette, QPalette::Window, backgroundImage);

    QBrush brush = palette.background();
    brush.setColor(brush.color().dark());

    palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush);
    palette.setBrush(QPalette::Disabled, QPalette::Text, brush);
    palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush);
    palette.setBrush(QPalette::Disabled, QPalette::Base, brush);
    palette.setBrush(QPalette::Disabled, QPalette::Button, brush);
    palette.setBrush(QPalette::Disabled, QPalette::Mid, brush);
}
//! [1]

(2)void polish(QWidget *widget)

       这是一个重载函数,功能是:初始化给定窗口部件的外观,该函数在每一个窗口完全创建之后的某个时刻并且是该窗口部件每一次创建后首次显示之前调用。注意,默认的实现是不做任何事情。该函数可能的动作就是调用QWidget::setBackgroundMode()。不要调用该函数来设置例如窗口部件显示位置之类的信息。重现实现这个函数使得我们获得课改变窗口部件显示方式的后门,但是Qt的样式引擎很少需要实现这个函数,而是重新实现 drawItemPixmap(), drawItemText(),drawPrimitive(),等等函数来代替。

       此处的实现为:

  1. //! [3]  
  2. void NorwegianWoodStyle::polish(QWidget *widget)  
  3. //! [3] //! [4]  
  4. {  
  5.     if (qobject_cast<QPushButton *>(widget)  
  6.             || qobject_cast<QComboBox *>(widget))  
  7.         widget->setAttribute(Qt::WA_Hover, true);  
  8. }  
  9. //! [4]  
//! [3]
void NorwegianWoodStyle::polish(QWidget *widget)
//! [3] //! [4]
{
    if (qobject_cast<QPushButton *>(widget)
            || qobject_cast<QComboBox *>(widget))
        widget->setAttribute(Qt::WA_Hover, true);
}
//! [4]


(3)int pixelMetric(PixelMetric metric, const QStyleOption *option,
                    const QWidget *widget) const

       功能:返回给定像素的公制值。指定的option和widget可以被用来计算公制值。一般情况下,widget参数都不会使用到。option参数可以通过qstyleoption_cast()函数转换为合适的类型。注意,option可能会为0,即使是PixelMetrics可以利用它。查看下面的表来获取合适的option转换:



            一些像素公制是从widgets中调用的,而一些则仅仅是style在内部调用的。如果像素公制不是从widget调用的,那么样式的制作者就应该谨慎使用它。对于一些样式而言,这也许是不适用的。

       看看该函数的具体实现:

  1. //! [7]  
  2. int NorwegianWoodStyle::pixelMetric(PixelMetric metric,  
  3. //! [7] //! [8]  
  4.                                     const QStyleOption *option,  
  5.                                     const QWidget *widget) const  
  6. {  
  7.     switch (metric) {  
  8.     case PM_ComboBoxFrameWidth:  
  9.         return 8;  
  10.     case PM_ScrollBarExtent:  
  11.         return QMotifStyle::pixelMetric(metric, option, widget) + 4;  
  12.     default:  
  13.         return QMotifStyle::pixelMetric(metric, option, widget);  
  14.     }  
  15. }  
  16. //! [8]  
//! [7]
int NorwegianWoodStyle::pixelMetric(PixelMetric metric,
//! [7] //! [8]
                                    const QStyleOption *option,
                                    const QWidget *widget) const
{
    switch (metric) {
    case PM_ComboBoxFrameWidth:
        return 8;
    case PM_ScrollBarExtent:
        return QMotifStyle::pixelMetric(metric, option, widget) + 4;
    default:
        return QMotifStyle::pixelMetric(metric, option, widget);
    }
}
//! [8]

         这里附带说一下PixelMetric,这是一个枚举类型,主要是描述了像素公制可取的一些值,一个像素公制值是单个像素在在样式中表现的尺寸。

        在本例中我们对默认值做出了一些修改,然后就实现了自定义的样式,例如:

PM_ComboBoxFrameWidth默认值在Qt帮助文档中如下定义:

QStyle::PM_ComboBoxFrameWidth 7 Frame width of a combo box, defaults to PM_DefaultFrameWidth.

也就是说默认值是7,而在本例中我们改为8了,这就是之前说的实现虚函数,修改相应的部分实现就创建了自定义样式。


(3)int styleHint(StyleHint hint, const QStyleOption *option,
                  const QWidget *widget, QStyleHintReturn *returnData) const

        功能:对指定的widget返回由option指定的样式的hint,返回值为整型。当查询的widget需要返回更多的信息,而不仅仅是由styleHint()返回的整型值时,我们就可以使用returnData来返回这些额外的信息。

       这里的具体实现为:

  1. //! [9]  
  2. int NorwegianWoodStyle::styleHint(StyleHint hint, const QStyleOption *option,  
  3. //! [9] //! [10]  
  4.                                   const QWidget *widget,  
  5.                                   QStyleHintReturn *returnData) const  
  6. {  
  7.     switch (hint) {  
  8.     case SH_DitherDisabledText:  
  9.         return int(false);  
  10.     case SH_EtchDisabledText:  
  11.         return int(true);  
  12.     default:  
  13.         return QMotifStyle::styleHint(hint, option, widget, returnData);  
  14.     }  
  15. }  
  16. //! [10]  
//! [9]
int NorwegianWoodStyle::styleHint(StyleHint hint, const QStyleOption *option,
//! [9] //! [10]
                                  const QWidget *widget,
                                  QStyleHintReturn *returnData) const
{
    switch (hint) {
    case SH_DitherDisabledText:
        return int(false);
    case SH_EtchDisabledText:
        return int(true);
    default:
        return QMotifStyle::styleHint(hint, option, widget, returnData);
    }
}
//! [10]
        这里也附带介绍一下StyleHint的内容,这是一个枚举类型,指定了style hints可以选取的值,一种style hint是一般的外观和/或感到提示。


       由上面的代码和这里的图片可以看到这里也做了一些修改。

(5)void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                       QPainter *painter, const QWidget *widget) const

      功能:用给定的option核painter来绘制element。关于原始元素以及它们相关的option可以参见Qt帮组文档。

       这里的实现为:

  1. //! [11]  
  2. void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element,  
  3. //! [11] //! [12]  
  4.                                        const QStyleOption *option,  
  5.                                        QPainter *painter,  
  6.                                        const QWidget *widget) const  
  7. {  
  8.     switch (element) {  
  9.     case PE_PanelButtonCommand:  
  10.         {  
  11.             int delta = (option->state & State_MouseOver) ? 64 : 0;  
  12.             QColor slightlyOpaqueBlack(0, 0, 0, 63);  
  13.             QColor semiTransparentWhite(255, 255, 255, 127 + delta);  
  14.             QColor semiTransparentBlack(0, 0, 0, 127 - delta);  
  15.   
  16.             int x, y, width, height;  
  17.             option->rect.getRect(&x, &y, &width, &height);  
  18. //! [12]  
  19.   
  20. //! [13]  
  21.             QPainterPath roundRect = roundRectPath(option->rect);  
  22. //! [13] //! [14]  
  23.             int radius = qMin(width, height) / 2;  
  24. //! [14]  
  25.   
  26. //! [15]  
  27.             QBrush brush;  
  28. //! [15] //! [16]  
  29.             bool darker;  
  30.   
  31.             const QStyleOptionButton *buttonOption =  
  32.                     qstyleoption_cast<const QStyleOptionButton *>(option);  
  33.             if (buttonOption  
  34.                     && (buttonOption->features & QStyleOptionButton::Flat)) {  
  35.                 brush = option->palette.background();  
  36.                 darker = (option->state & (State_Sunken | State_On));  
  37.             } else {  
  38.                 if (option->state & (State_Sunken | State_On)) {  
  39.                     brush = option->palette.mid();  
  40.                     darker = !(option->state & State_Sunken);  
  41.                 } else {  
  42.                     brush = option->palette.button();  
  43.                     darker = false;  
  44. //! [16] //! [17]  
  45.                 }  
  46. //! [17] //! [18]  
  47.             }  
  48. //! [18]  
  49.   
  50. //! [19]  
  51.             painter->save();  
  52. //! [19] //! [20]  
  53.             painter->setRenderHint(QPainter::Antialiasing, true);  
  54. //! [20] //! [21]  
  55.             painter->fillPath(roundRect, brush);  
  56. //! [21] //! [22]  
  57.             if (darker)  
  58. //! [22] //! [23]  
  59.                 painter->fillPath(roundRect, slightlyOpaqueBlack);  
  60. //! [23]  
  61.   
  62. //! [24]  
  63.             int penWidth;  
  64. //! [24] //! [25]  
  65.             if (radius < 10)  
  66.                 penWidth = 3;  
  67.             else if (radius < 20)  
  68.                 penWidth = 5;  
  69.             else  
  70.                 penWidth = 7;  
  71.   
  72.             QPen topPen(semiTransparentWhite, penWidth);  
  73.             QPen bottomPen(semiTransparentBlack, penWidth);  
  74.   
  75.             if (option->state & (State_Sunken | State_On))  
  76.                 qSwap(topPen, bottomPen);  
  77. //! [25]  
  78.   
  79. //! [26]  
  80.             int x1 = x;  
  81.             int x2 = x + radius;  
  82.             int x3 = x + width - radius;  
  83.             int x4 = x + width;  
  84.   
  85.             if (option->direction == Qt::RightToLeft) {  
  86.                 qSwap(x1, x4);  
  87.                 qSwap(x2, x3);  
  88.             }  
  89.   
  90.             QPolygon topHalf;  
  91.             topHalf << QPoint(x1, y)  
  92.                     << QPoint(x4, y)  
  93.                     << QPoint(x3, y + radius)  
  94.                     << QPoint(x2, y + height - radius)  
  95.                     << QPoint(x1, y + height);  
  96.   
  97.             painter->setClipPath(roundRect);  
  98.             painter->setClipRegion(topHalf, Qt::IntersectClip);  
  99.             painter->setPen(topPen);  
  100.             painter->drawPath(roundRect);  
  101. //! [26] //! [32]  
  102.   
  103.             QPolygon bottomHalf = topHalf;  
  104.             bottomHalf[0] = QPoint(x4, y + height);  
  105.   
  106.             painter->setClipPath(roundRect);  
  107.             painter->setClipRegion(bottomHalf, Qt::IntersectClip);  
  108.             painter->setPen(bottomPen);  
  109.             painter->drawPath(roundRect);  
  110.   
  111.             painter->setPen(option->palette.foreground().color());  
  112.             painter->setClipping(false);  
  113.             painter->drawPath(roundRect);  
  114.   
  115.             painter->restore();  
  116.         }  
  117.         break;  
  118. //! [32] //! [33]  
  119.     default:  
  120. //! [33] //! [34]  
  121.         QMotifStyle::drawPrimitive(element, option, painter, widget);  
  122.     }  
  123. }  
  124. //! [34]  
//! [11]
void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element,
//! [11] //! [12]
                                       const QStyleOption *option,
                                       QPainter *painter,
                                       const QWidget *widget) const
{
    switch (element) {
    case PE_PanelButtonCommand:
        {
            int delta = (option->state & State_MouseOver) ? 64 : 0;
            QColor slightlyOpaqueBlack(0, 0, 0, 63);
            QColor semiTransparentWhite(255, 255, 255, 127 + delta);
            QColor semiTransparentBlack(0, 0, 0, 127 - delta);

            int x, y, width, height;
            option->rect.getRect(&x, &y, &width, &height);
//! [12]

//! [13]
            QPainterPath roundRect = roundRectPath(option->rect);
//! [13] //! [14]
            int radius = qMin(width, height) / 2;
//! [14]

//! [15]
            QBrush brush;
//! [15] //! [16]
            bool darker;

            const QStyleOptionButton *buttonOption =
                    qstyleoption_cast<const QStyleOptionButton *>(option);
            if (buttonOption
                    && (buttonOption->features & QStyleOptionButton::Flat)) {
                brush = option->palette.background();
                darker = (option->state & (State_Sunken | State_On));
            } else {
                if (option->state & (State_Sunken | State_On)) {
                    brush = option->palette.mid();
                    darker = !(option->state & State_Sunken);
                } else {
                    brush = option->palette.button();
                    darker = false;
//! [16] //! [17]
                }
//! [17] //! [18]
            }
//! [18]

//! [19]
            painter->save();
//! [19] //! [20]
            painter->setRenderHint(QPainter::Antialiasing, true);
//! [20] //! [21]
            painter->fillPath(roundRect, brush);
//! [21] //! [22]
            if (darker)
//! [22] //! [23]
                painter->fillPath(roundRect, slightlyOpaqueBlack);
//! [23]

//! [24]
            int penWidth;
//! [24] //! [25]
            if (radius < 10)
                penWidth = 3;
            else if (radius < 20)
                penWidth = 5;
            else
                penWidth = 7;

            QPen topPen(semiTransparentWhite, penWidth);
            QPen bottomPen(semiTransparentBlack, penWidth);

            if (option->state & (State_Sunken | State_On))
                qSwap(topPen, bottomPen);
//! [25]

//! [26]
            int x1 = x;
            int x2 = x + radius;
            int x3 = x + width - radius;
            int x4 = x + width;

            if (option->direction == Qt::RightToLeft) {
                qSwap(x1, x4);
                qSwap(x2, x3);
            }

            QPolygon topHalf;
            topHalf << QPoint(x1, y)
                    << QPoint(x4, y)
                    << QPoint(x3, y + radius)
                    << QPoint(x2, y + height - radius)
                    << QPoint(x1, y + height);

            painter->setClipPath(roundRect);
            painter->setClipRegion(topHalf, Qt::IntersectClip);
            painter->setPen(topPen);
            painter->drawPath(roundRect);
//! [26] //! [32]

            QPolygon bottomHalf = topHalf;
            bottomHalf[0] = QPoint(x4, y + height);

            painter->setClipPath(roundRect);
            painter->setClipRegion(bottomHalf, Qt::IntersectClip);
            painter->setPen(bottomPen);
            painter->drawPath(roundRect);

            painter->setPen(option->palette.foreground().color());
            painter->setClipping(false);
            painter->drawPath(roundRect);

            painter->restore();
        }
        break;
//! [32] //! [33]
    default:
//! [33] //! [34]
        QMotifStyle::drawPrimitive(element, option, painter, widget);
    }
}
//! [34]

(6)void drawControl(ControlElement control, const QStyleOption *option,
                     QPainter *painter, const QWidget *widget) const

      功能:和上个函数类似。具体参见Qt帮组文档。

      具体实现:

  1. //! [35]  
  2. void NorwegianWoodStyle::drawControl(ControlElement element,  
  3. //! [35] //! [36]  
  4.                                      const QStyleOption *option,  
  5.                                      QPainter *painter,  
  6.                                      const QWidget *widget) const  
  7. {  
  8.     switch (element) {  
  9.     case CE_PushButtonLabel:  
  10.         {  
  11.             QStyleOptionButton myButtonOption;  
  12.             const QStyleOptionButton *buttonOption =  
  13.                     qstyleoption_cast<const QStyleOptionButton *>(option);  
  14.             if (buttonOption) {  
  15.                 myButtonOption = *buttonOption;  
  16.                 if (myButtonOption.palette.currentColorGroup()  
  17.                         != QPalette::Disabled) {  
  18.                     if (myButtonOption.state & (State_Sunken | State_On)) {  
  19.                         myButtonOption.palette.setBrush(QPalette::ButtonText,  
  20.                                 myButtonOption.palette.brightText());  
  21.                     }  
  22.                 }  
  23.             }  
  24.             QMotifStyle::drawControl(element, &myButtonOption, painter, widget);  
  25.         }  
  26.         break;  
  27.     default:  
  28.         QMotifStyle::drawControl(element, option, painter, widget);  
  29.     }  
  30. }  
  31. //! [36]  
//! [35]
void NorwegianWoodStyle::drawControl(ControlElement element,
//! [35] //! [36]
                                     const QStyleOption *option,
                                     QPainter *painter,
                                     const QWidget *widget) const
{
    switch (element) {
    case CE_PushButtonLabel:
        {
            QStyleOptionButton myButtonOption;
            const QStyleOptionButton *buttonOption =
                    qstyleoption_cast<const QStyleOptionButton *>(option);
            if (buttonOption) {
                myButtonOption = *buttonOption;
                if (myButtonOption.palette.currentColorGroup()
                        != QPalette::Disabled) {
                    if (myButtonOption.state & (State_Sunken | State_On)) {
                        myButtonOption.palette.setBrush(QPalette::ButtonText,
                                myButtonOption.palette.brightText());
                    }
                }
            }
            QMotifStyle::drawControl(element, &myButtonOption, painter, widget);
        }
        break;
    default:
        QMotifStyle::drawControl(element, option, painter, widget);
    }
}
//! [36]

(7)两个辅助函数,这里代码比较好懂,直接贴代码了:

  1. //! [37]  
  2. void NorwegianWoodStyle::setTexture(QPalette &palette, QPalette::ColorRole role,  
  3. //! [37] //! [38]  
  4.                                     const QPixmap &pixmap)  
  5. {  
  6.     for (int i = 0; i < QPalette::NColorGroups; ++i) {  
  7.         QColor color = palette.brush(QPalette::ColorGroup(i), role).color();  
  8.         palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap));  
  9.     }  
  10. }  
  11. //! [38]  
  12.   
  13. //! [39]  
  14. QPainterPath NorwegianWoodStyle::roundRectPath(const QRect &rect)  
  15. //! [39] //! [40]  
  16. {  
  17.     int radius = qMin(rect.width(), rect.height()) / 2;  
  18.     int diam = 2 * radius;  
  19.   
  20.     int x1, y1, x2, y2;  
  21.     rect.getCoords(&x1, &y1, &x2, &y2);  
  22.   
  23.     QPainterPath path;  
  24.     path.moveTo(x2, y1 + radius);  
  25.     path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0);  
  26.     path.lineTo(x1 + radius, y1);  
  27.     path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0);  
  28.     path.lineTo(x1, y2 - radius);  
  29.     path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0);  
  30.     path.lineTo(x1 + radius, y2);  
  31.     path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0);  
  32.     path.closeSubpath();  
  33.     return path;  
  34. }  
  35. //! [40] 

QT学习(21):QStyle类自定义样式实现 开发自定义控件并且希望在所有平台上表现一致,可以使用QStyle函数(如drawItemText()、drawItemPixmap()、drawPrimitive()、drawControl()和drawComplexControl())来执行控件绘制的一部分。QStyle函数大部分包含4个参数:枚举值:指定要绘制的图形元素的类型QStyleOption:指定渲染元素的方式和位置QPainter:用于绘制元素QWidget:执行绘图的控件。 阅读详情

相关推荐

「QT」QSS样式表 之 QSS(Qt Style Sheets)样式表介绍

Qt样式表(QSS)作为一种强大的工具,允许开发者定制和美化Qt应用程序的界面。QSS类似于网页开发中的CSS(层叠样式表),通过定义样式规则来控制Qt控件的外观。QSS为Qt应用程序提供了强大的样式定制功能,能够显著提高用户界面的美观性和一致性。通过灵活的样式定义和动态调整能力,QSS帮助开发者快速实现各种设计需求,提高了开发效率和用户体验。它允许开发者通过选择器指定不同类型的控件,并设置属性值,如颜色、字体、边框、间距等。QSS的语法类似于CSS,使用选择器和属性来定义控件的样式。

何曾参静谧的博客 1310

Qt QStyle

QStyle Class QStyle类是一个抽象基类,它封装了GUI的外观。 Qt 包含一组 QStyle 子类,这些子类可以模拟Qt支持不同的平台样式(QWindowsStyle,QMacStyle等)。默认情况下,这些样式内置在 Qt GUI 模块中,样式也可以作为插件使用。 Qt 的内置小窗口部件使用 QStyle 来执行几乎所有的绘图,从而确保它们看起来完全等同于等效的本级窗口小部件。下图展示了九中不同样式的 QCombox。 Setting a Style (设定风格) 可以使用 QAppli

暖暖_的_纠结的博客 6270

Qt Style Sheets-样式表语法

样式表语法Qt 样式表术语和语法规则几乎与 HTML CSS 的相同。如果您已经了解 CSS,您可能可以快速浏览此部分。

qq_42815643的博客 1590

Qt QStyle详解

QStyle类是 Qt 框架中用于控制应用程序界面元素外观的一个抽象基类。这个类提供了一种方式来定制窗口部件(widgets)的绘制和行为,可以通过改变主题或风格来更改应用程序的外观,而无需修改窗口部件本身的代码。Qt包含一组QStyle子类,这些子类模仿Qt支持的不同平台的样式(QWindowsStyle、QMacStyle等)。默认情况下,这些样式内置在Qt GUI模块中。样式也可以作为插件提供。Qt的内置widget使用QStyle来执行几乎所有的绘制,确保它们看起来与等效的本地小部件完全相同。

希望能帮助大家,希望大家多多支持,你们的支持是我前进的动力。 4853

Qt4-GUI-Style:探索Qt4的界面特效与定制

在开发图形用户界面(GUI)应用时,Qt4框架提供了一套丰富而灵活的设计工具,以实现美观和功能兼备的界面。界面设计不仅仅是关于“美”,更重要的是它影响着用户交互的直观性和软件的整体可用性。在Qt4中,开发者可以利用多种技术手段来构建应用程序的外观和行为。QStyle类在Qt框架中扮演着重要的角色,它是Qt为用户提供的一种机制,用于改变界面组件的外观。通过QStyle类,开发者可以统一地自定义界面元素的绘制风格,而不是直接修改底层的绘图代码。

weixin_42230607的博客 1083

电子发票二维码背后的秘密:10分钟看懂校验码、加密字符含义与防伪设计

本文深入解析电子发票二维码的结构与防伪设计,揭示校验码和加密字符的生成原理及验证方法。通过实际案例和技术细节,帮助财务人员理解电子发票的安全机制,提升防伪识别能力,确保税务合规。

weixin_29248611的博客 530

Qt文档阅读笔记-对Style Plugin Example实例的解析

目录   前言 Style Plugin Example SimpleStylePlugin Class 定义 SimpleStylePlugin Class 实现 main()函数 The Simple Style Plugin Profile   前言 文档中给的现象图是这样的: 但在本人Qt5.8 Windows 7端 MinGW编译器中 没有官方实例的现象,这里修...

IT1995的博客 4430

翻倍密码系统主图指标-行情买卖以及持股-翻倍密码买点-获利了结,通达信炒股软件指标公式

华森制药,上图案例走势,低位出现“开始潜伏”信号,进场红色K线持股待涨,进入“翻倍密码买点”,开启紫色K线的持续上涨,目前也达到了翻倍行情,还没出现“获利了结”的出场信号。这套操盘系统,即便出现信号没走出翻倍行情,也都是可以全身而退,获利出局,或者微微止损出场,并不代表每一个波段都能翻倍,但是走翻倍行情,你按照信号参与或持仓是不会错过的。用这个操盘系统操作,你也不需要天天的盘中看盘,不需要担心盘中的震荡,只要趋势不变,哪怕是偶尔出现跌停,也不影响行情的继续上涨,这都是上涨途中的正常调整。

weixin_69760830的博客 3681

Qt Style And Style Sheet

Qt Style Sheets--简介 解析Qt自带的Style示例 Qt stylesheet 源码学习

Liuqz2009的专栏 1060

深入解析STM32F103R6的USB OTG_FS双重角色设备(DRD)设计与应用

本文深入解析了STM32F103R6的USB OTG_FS双重角色设备(DRD)设计与应用。详细阐述了其作为USB主机和设备双重角色的硬件设计要点,包括VBUS电源管理与ID引脚配置,并提供了设备模式(如虚拟串口CDC)与主机模式(如读取U盘文件)的软件实现实战指南,帮助开发者充分发挥该芯片的OTG潜力。

weixin_29195615的博客 268

QUIC 协议域名封堵:核心原理、关键技术与实现路径(C/C++代码实现)

随着 QUIC 协议在互联网领域的广泛应用,其基于 UDP 的传输特性与加密设计,打破了传统 TCP 协议下的域名封堵逻辑,给网络合规管理与安全防护带来新的技术难题。本文将脱离具体代码实现,聚焦 QUIC 协议域名封堵的核心原理、关键技术环节与实际落地路径,从协议特性本质出发,解析如何在遵循 RFC 9000、RFC 9001 等规范的前提下,实现对 QUIC 流量的精准域名封堵。

chen1415886044的博客 1467

Qt style

主要介绍了qt提供的三种customize style的方法,包括QStyle、QSS、QGraphicsView/Item框架,并分别阐述如何来实现customize style

zhaoli_1956的专栏 3438

Altium Designer20 PCB板子绘制

版层 top layer 顶层 bottom layer 底层 设置板子大小 布局 过孔 top layer层连到bottom layer层。通过via连接。 设置线宽 在design rules里可以设置线宽。 右键new rule 可以新增线宽,电源设置成20mil 还可以设置很多其他的线宽 修改安全距离 安全距离太短容易出现毛刺,然后短路,一般设置成20mil 修改元器件旋转角度 修改rotation step,每次旋转45°。 修改光标大小 下面的cursor type是修改光标

及时总结 2582

Qt Style Sheets

Qt设置界面方式 1.继承QStyle,实现自定义子类 2.Qt Style Sheets(类似与HTML CSS)配置 概览 QApplication::setStyleSheet设置应用程序的全部样式; QWidget::setStyleSheet设置特定QWidget或者其子类的样式。 Qt Style Sheets支持级联设置,比...

不知方向的行走 718

《S32系列芯片——Boot & HSE详解》持续更新中...

专栏总目录,将详细介绍S32系列芯片的Boot功能,最终给出HSE基于IVT的Secure Boot方案!!!

车载系统攻城狮 4387

SAP RAP学习系列合集介绍

《SAP RAP学习系列合集:从入门到部署的完整指南》摘要: 本文介绍了作者创建的SAP RAP学习系列合集,涵盖RAP开发从基础概念到实战部署的全流程。系列目前包含17篇文章,系统讲解了RAP核心开发技术:从数据建模、UI构建到行为定义(包括并发控制、草稿功能、授权验证等),最后详细演示了应用部署到Fiori Launchpad的两种方案(OP版和ES版)。

DeveloperMrMeng的博客 1492

QT源码解析笔记

   1. QT如何绘制控件的  QT的绘制控件在QStyleSheetStyle::DrawControl里面,这里会调用默认的QSS来绘制效果 2. 在设置一次QSS以后,将会触发polish事件,里面将会一次设置大小,pallte和property等属性,在QWidget::event里面的polish事件的处理可以看出来 (在QWidget::Event里面会调用QStyle...

440

RFC 字符码转换深度解析:Unicode、非 Unicode 与 MDMP 系统的协奏

老版本 MDMP 系统不上传自定义映射时,Unicode 端会落回“预配置列表”。列表里可见西欧 1100、日文 8000、中文 8400 等经典编号。若需强制覆写映射,可在 SM59 ➡Unicode页签启用,或直接勾选作为兜底。字符编码问题常“潜伏”多年,一旦旧系统升级或新增语种便集中爆发。掌握 RFC code page 转换机理、灵活运用 SM59 选项、在早期对 LANG 字段和字段长度进行治理,是根治乱码与 short dump 的关键。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 225

【Qt】QSS(Qt Style Sheets)选择器介绍

QSS(Qt Style Sheets)是 Qt 框架中用于定制界面样式的工具,其语法类似 CSS,但针对 Qt 部件进行了扩展。QSS 提供了多种选择器来精确控制部件样式,包括类型选择器、类选择器、ID 选择器、属性选择器和后代选择器。此外,QSS 支持伪状态和子控件选择器,用于处理部件的交互状态和子控件样式。优先级和继承机制确保样式应用的顺序和范围。高级技巧如动态属性绑定、盒模型和复杂部件定制进一步增强了样式灵活性。QSS 还支持资源管理和调试工具,以优化样式设计。常见问题如样式不生效通常由选择器优先级

weixin_43510208的博客 1688

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

探索代码美学:Qt Creator与Artistic Style的完美结合

探索代码美学:Qt Creator与Artistic Style的完美结合 去发现同类优质开源项目:https://gitcode.com/ 在当今快速迭代的软件开发环境中,代码的质量直接关乎项目的健壮性和团队协作的效率。Qt Creator 自动缩进功能配置指南(Artistic Style版) 正是为了解决这一痛点而生,它犹如一位幕后英雄,默默提升着代码的可读性和一致性。今天,让我们一起深入了...

gitblog_06530的博客 426

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: how to use style sheets in Qt-----Style Sheet Example instruction
下一篇: QWT 在VS2010下安装与使用
lujunql
博客等级 码龄19年 156粉丝 124原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值