这里使用QPushButton为例,讲解一下具体QPushButton是怎么绘制的
首先看一段代码,这段代码是QPushButton中的绘制事件函数,可以看出来是使用QStylePainter来绘制,
QStylePainter
包装了所有高级控件的绘制, QStyleOptionButton
是按钮的样式参数的分装类,所有有关按钮的绘制样式在QStyleOptionButton
都可找到。
initStyleOption
初始化参数
void QPushButton::paintEvent(QPaintEvent *)
{
QStylePainter p(this);
QStyleOptionButton option;
initStyleOption(&option);
p.drawControl(QStyle::CE_PushButton, option);
}
void QPushButton::initStyleOption(QStyleOptionButton *option) const
{
if (!option)
return;
Q_D(const QPushButton);
option->initFrom(this);
option->features = QStyleOptionButton::None;
if (d->flat)
option->features |= QStyleOptionButton::Flat;
#ifndef QT_NO_MENU
if (d->menu)
option->features |= QStyleOptionButton::HasMenu;
#endif
if (autoDefault())
option->features |= QStyleOptionButton::AutoDefaultButton;
if (d->defaultButton)
option->features |= QStyleOptionButton::DefaultButton;
if (d->down || d->menuOpen)
option->state |= QStyle::State_Sunken;
if (d->checked)
option->state |= QStyle::State_On;
if (!d->flat && !d->down)
option->state |= QStyle::State_Raised;
option->text = d->text;
option->icon = d->icon;
option->iconSize = iconSize();
}
下面看一下QStylePainter 是怎么绘制的
void QStylePainter::drawControl(QStyle::ControlElement ce, const QStyleOption &opt)
{
wstyle->drawControl(ce, &opt, this, widget);
}
wstyle 是QStyle的一个子类,Qt默认使用QCommonStyle,想修改Qt的样式可以继承QCommonStyle,
重写里面的一些虚函数就可以
看一下具体QCommonStyle是怎么绘制控件的
void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
QPainter *p, const QWidget *widget) const
{
Q_D(const QCommonStyle);
switch (element) {
case CE_PushButton:
if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) {
proxy()->drawControl(CE_PushButtonBevel, btn, p, widget);
QStyleOptionButton subopt = *btn;
subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
proxy()->drawControl(CE_PushButtonLabel, &subopt, p, widget);
if (btn->state & State_HasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*btn);
fropt.rect = subElementRect(SE_PushButtonFocusRect, btn, widget);
proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
}
}
break;
case CE_PushButtonBevel:
这里给一个例子,修改Qt的默认空间绘制方式的一个例子
#include "textedit.h"
#include
#include
class MyProxyStyle : public QProxyStyle
{
public:
int styleHint(StyleHint hint, const QStyleOption *option = 0,
const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const
{
if (hint == QStyle::SH_UnderlineShortcut)
return 0;
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
};
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(textedit);
QApplication a(argc, argv);
a.setStyle(new MyProxyStyle);
TextEdit mw;
mw.resize(700, 800);
mw.show();
//...
}