QStyle QStyleOption 样式选项(四)

QStyleOption的子类包含样式各个元素所需的所有信息。样式选项被实例化-通常在堆栈上-并由QStyle函数的调用者填写。

根据所绘制的内容,样式将期望使用不同的样式选项类。例如,QStyle :: PE_FrameFocusRect元素需要一个QStyleOptionFocusRect参数,

并且可以创建自定义样式可以使用的自定义子类。出于性能原因,样式选项保留公共变量。

这些小部件可以处于多个不同的状态,这些状态由State枚举定义。

某些状态标志根据窗口小部件具有不同的含义,但其他状态标志对于所有窗口小部件(例如State_Disabled)都是通用的。

QStyleOption使用QStyleOption :: initFrom();设置公共状态。其余状态由各个小部件设置。

最值得注意的是,样式选项包含要绘制的小部件的调色板和边界矩形。大多数小部件都有专门的样式选项。

例如,QPushButton和QCheckBox使用QStyleOptionButton作为样式选项,其中包含文本,图标和图标大小。当我们浏览各个小部件时,将描述所有选项的确切内容。

重新实现带有QStyleOption参数的QStyle函数时,通常需要将QStyleOption强制转换为子类(例如QStyleOptionFocusRect)。

为了安全起见,可以使用qstyleoption_cast()来确保指针类型正确。如果对象的类型不正确,则qstyleoption_cast()返回0。

例如:

 const QStyleOptionFocusRect *focusRectOption = qstyleoption_cast<const QStyleOptionFocusRect *>(option);
 if (focusRectOption) {
     ...
}

以下代码段说明了如何使用QStyle从自定义小部件的paintEvent()绘制焦点矩形:

 void MyWidget::paintEvent(QPaintEvent *event)
 {
     QPainter painter(this);
     ...

     QStyleOptionFocusRect option(1);
     option.init(this);
     option.backgroundColor = palette().color(QPalette::Window);

     style().drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter,
                           this);
 }


下一个示例显示如何从现有样式派生以定制图形元素的外观:
class CustomStyle : public QWindowsStyle
 {
     Q_OBJECT

 public:
     CustomStyle()
     ~CustomStyle() {}

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

 void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                 QPainter *painter, const QWidget *widget) const
 {
     if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) {
         QPolygon points(3);
         int x = option->rect.x();
         int y = option->rect.y();
         int w = option->rect.width() / 2;
         int h = option->rect.height() / 2;
         x += (option->rect.width() - w) / 2;
         y += (option->rect.height() - h) / 2;

         if (element == PE_IndicatorSpinUp) {
             points[0] = QPoint(x, y + h);
             points[1] = QPoint(x + w, y + h);
             points[2] = QPoint(x + w / 2, y);
         } else { // PE_SpinBoxDown
             points[0] = QPoint(x, y);
             points[1] = QPoint(x + w, y);
             points[2] = QPoint(x + w / 2, y + h);
         }

         if (option->state & State_Enabled) {
             painter->setPen(option->palette.mid().color());
             painter->setBrush(option->palette.buttonText());
         } else {
             painter->setPen(option->palette.buttonText().color());
             painter->setBrush(option->palette.mid());
         }
         painter->drawPolygon(points);
     } else {
         QWindowsStyle::drawPrimitive(element, option, painter, widget);
     }
 }



posted @ 2020-11-03 21:44  流浪侠客  阅读(2646)  评论(0编辑  收藏  举报