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);
}
}