1.简介
QStyle类是 Qt 框架中用于控制应用程序界面元素外观的一个抽象基类。这个类提供了一种方式来定制窗口部件(widgets)的绘制和行为,可以通过改变主题或风格来更改应用程序的外观,而无需修改窗口部件本身的代码。
Qt包含一组QStyle子类,这些子类模仿Qt支持的不同平台的样式(QWindowsStyle、QMacStyle等)。默认情况下,这些样式内置在Qt GUI模块中。样式也可以作为插件提供。
Qt的内置widget使用QStyle来执行几乎所有的绘制,确保它们看起来与等效的本地小部件完全相同。下图显示了九种不同样式的QComboBox。
QStyle 的主要方法:
- drawControl
()
: 绘制控制元素,如复选框、按钮等。 - drawPrimitive
()
: 绘制基本元素,如滚动条的箭头、框架等。 - drawComplexControl
()
: 绘制复杂的控制元素,如组合框或滚动条。 - sizeFromContents
()
: 根据内容计算控件的大小。 - subElementRect
()
: 返回控件子元素的矩形区域。 - styleHint
()
: 提供关于如何绘制或行为的提示。 - pixelMetric
()
: 返回关于控件的一些基本尺寸的信息,如滚动条的宽度等。
2.如何使用QStyle
由于QStyle是一个抽象类,你不能直接实例化它。Qt 提供了一些内置的风格类,如 QWindowsStyle,QMacStyle等,你可以直接使用这些预定义的风格或者继承QStyle创建自定义风格。
QStyleFactory提供了一个静态方法create(),该方法接受一个字符串参数,该参数表示要创建的样式的名称。
#include "mainwindow.h"
#include <QApplication>
#include <QStyleFactory>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug()<<QStyleFactory::keys();
// 设置应用程序的风格
QApplication::setStyle(QStyleFactory::create("Fusion"));
MainWindow w;
w.show();
return a.exec();
}
在这个例子中,我们使用QStyleFactory来创建一个 “Fusion” 风格,并将其设置为应用程序的当前风格。
QStyleFactory还提供了一个静态方法keys(),该方法返回一个字符串列表,包含了工厂知道如何创建的所有样式的名称。这可以用来列出所有可用的样式:
QStringList styles = QStyleFactory::keys();
for (const QString &style : styles) {
qDebug() << "Available style:" << style;
}
除了上面的使用setStyle方法来加载样式以为,还提供以下方式来加载样式。
./myapplication -style windows
3.自定义风格
如果您正在开发自定义widget,并希望它们在所有平台上看起来都很好,则可以使用QStyle函数来执行小部件绘图的部分,如drawItemText()、drawItemPixmap()、drawPrimitive()、drawControl()和drawComplexControl()。
大多数QStyle绘制函数都有四个参数:
- PrimitiveElement:指定要绘制的图形元素的枚举值
- QStyleOption:指定如何以及在何处渲染该元素。
- QPainter:画家
- QWidget:可选,在哪个widget上绘制。
例子:如果你想在你的widget上画一个焦点矩形,你可以写:
void MyWidget::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this);
QStyleOptionFocusRect option;
option.initFrom(this);
option.backgroundColor = palette().color(QPalette::Background);
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter, this);
}
示例:自定义QSpinBox,绘制上下指针。使用PE_IndicatorSpinUp和PE_IndicatorSpinDown。
运行结果前后对比:
源码:自定义CustomStyle。
#ifndef CUSTOMSTYLE_H
#define CUSTOMSTYLE_H
#include <QProxyStyle>
#include <QStyleOption>
#include <QPainter>
class CustomStyle : public QProxyStyle
{
public:
CustomStyle();
void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const;
};
#endif // CUSTOMSTYLE_H
#include "customstyle.h"
CustomStyle::CustomStyle()
{
}
void CustomStyle::drawPrimitive(QStyle::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;