Qt 使用自己的方式绘制组件。然而我们也看到,在不同的平台上,Qt 的组件表现也不相同。这和 Swing 有些类似:Swing 使用 look and feel 表现组件的外观,Qt 也是类似的。用来绘制组件外观的类就是 QStyle。多数情况是没有必要实现的!
第一,重写 widget 的 paintEvent() 函数;
第二,使用 QStyle 类。两种方式的侧重点不同:重写组件的 paintEvent() 函数,可以简单地实现某一类组件的样式,而继承 QStyle 类,则可以实现对全部组件一致性处理。
void mystyleButton::paintEvent(QPaintEvent *event)
{QStyleOptionButton option;
option.initFrom(this);
option.state = isDown() ? QStyle::State_Sunken : QStyle::State_Raised;
if (1)
option.features |= QStyleOptionButton::AutoDefaultButton;
option.text = text();
option.icon = icon();
QPainter painter(this);
//参数一用于指定要绘制哪个元素 ,//保存了 painter 绘制时所需要的所有数据信息//画家,对象style()->drawControl(QStyle::CE_PushButton, &option, &painter, this);
}
第二种,QStyle 的实现。
其实在上面,我们已经使用了 QStyle。想必也能够想到,
这里我们依旧要用到 QStyle 的各个 draw 函数,只不过这里我们不是简单的去调用它们,
而是通过继承,将这些 draw 函数替换成我们自己的版本,达到自定义样式的目的。
虽然我们可以直接继承 QStyle 来实现,但是这并不是一个好主意。因为 QStyle 这个类很复杂,
几乎所有的函数都是纯虚函数,这要求我们必须一个个实现它们。有时候,我们并不需要自己实现所有功能,
仅仅是做简单的修改。于是,从 4.6 版本开始,Qt 提供了一个专门的类,QProxyStyle。我们要做的就是继承 QProxyStyle,覆盖我们感兴趣的函数即可。看下面一个简单的实例:
class MyProxyStyle : public QProxyStyle
{ public:
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const;
}; void MyProxyStyle::drawControl(
element,
QStyleOption *option,
QPainter *painter,
QWidget *widget
const
{ if(element == QStyle::CE_PushButtonLabel) {
painter->drawText(option->rect, "button");
} else {
QProxyStyle::drawControl(element, option, painter, widget);
}
} MyProxyStyle 覆盖了 drawControl() 函数,然后判断,如果是 button label 的话,绘制文本 “button”。
int main(int argc, char **argv)
{ QApplication app(argc, argv);
app.setStyle(new MyProxyStyle);
MainWindow w;
w.show();
return app.exec();
} 这样,我们就可以用我们自己的 style 显示组件了。
通过学习这个可以窥探到自定义控件的方法实现细节!
文章来源: Qt---定义控件实现细节