QStyleOption类和QStyle类简介

QStyleOption类存储QStyle函数使用的参数。QStyleOption及其子类包含了QStyle函数绘制图形元素所需的所有信息。

由于性能原因,成员函数很少,并且对成员变量的访问是直接的(即。,使用。或- >操作符)。这种低级的感觉使结构易于使用,并强调这些只是样式函数使用的参数。

QStyle函数的调用者通常在堆栈上创建QStyleOption对象。结合Qt对QString、QPalette和QColor等类型的隐式共享的广泛使用,可以确保没有不必要的内存分配。

QStyle类是一个抽象基类,它封装GUI的外观和感觉。

Qt包含一组QStyle子类,它们模拟Qt支持的不同平台的样式(QWindowsStyle、QMacStyle等)。默认情况下,这些样式构建在Qt GUI模块中。样式也可以作为插件提供。

Qt的内置小部件使用QStyle来执行几乎所有的绘图,确保它们看起来与等效的本地小部件完全相同。

QStyle类

设置风格:

可以使用QApplication::setStyle(QStyle *style)函数设置整个应用程序的样式。它也可以由应用程序的用户指定,使用样式命令行选项: 。

./myapplication -style windows

如果没有指定样式,Qt将为用户的平台或桌面环境选择最合适的样式。还可以使用QWidget::setStyle(QStyle *style)函数在单个小部件上设置样式。

QStyle类的简要:

如果您正在开发自定义小部件,并希望它们在所有平台上看起来都很好,那么可以使用QStyle函数来执行小部件绘图的部分,例如drawItemText()、drawItemPixmap()、drawPrimitive()、drawControl()和drawComplexControl()。

大多数QStyle绘制函数有四个参数:

1.枚举值,指定要绘制哪个图形元素

2.QStyleOption,指定如何和在哪里呈现该元素

3.用于绘制元素的QPainter

4.执行绘图的QWidget(可选)

QStyle从QStyleOption中获取呈现图形元素所需的所有信息。如果样式需要小部件执行特殊效果(比如macOS上的动画默认按钮),则将小部件作为最后一个参数传递,但这不是必须的。实际上,通过正确设置QPainter,您可以使用QStyle来绘制任何绘图设备,而不仅仅是控件。QStyleOption为可以绘制的各种图形元素类型有不同的子类。例如,PE_FrameFocusRect需要一个QStyleOptionFocusRect参数。为了确保绘图操作尽可能快,QStyleOption及其子类具有公共数据成员。有关如何使用的详细信息,请参阅QStyleOption类文档。

为了方便,Qt提供了QStylePainter类,它结合了QStyle、QPainter和QWidget。这使得下面写作替换原有的成为可能:

QStylePainter painter(this);
...
painter.drawPrimitive(QStyle::PE_FrameFocusRect, option);

取代下面代码

QPainter painter(this);
...
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter, this);

自定义界面:

通过创建自定义样式,您可以为应用程序创建自定义外观。创建自定义样式有两种方法。在静态方法中,您要么选择一个现有的QStyle类,子类化它,并重新实现虚拟函数来提供自定义行为,或者从头创建一个完整的QStyle类。在动态方法中,您可以在运行时修改系统样式的行为。下面描述静态方法。动态方法描述在QProxyStyle中。

静态方法的第一步是选择Qt提供的一种样式,您将从中构建自定义样式。您对QStyle类的选择将取决于哪个样式与您所期望的样式最相似。您可以使用的最普通的类是QCommonStyle(不是QStyle)。这是因为Qt要求它的样式是QCommonStyles。

根据您想要更改的基本样式的哪些部分,您必须重新实现用于绘制接口部分的函数。为了说明这一点,我们将修改QWindowsStyle绘制的旋转框箭头的外观。箭头是由draw原语()函数绘制的基本元素,因此我们需要重新实现该函数。

我们需要以下类声明:

  class CustomStyle : public QProxyStyle
{
Q_OBJECT public:
CustomStyle();
~CustomStyle() {} void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const;
};

要绘制上下箭头,QSpinBox使用PE_IndicatorSpinUp和PE_IndicatorSpinDown原始元素。下面介绍如何重新实现draw原语()函数,以便以不同的方式绘制它们:

  void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const
{
if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) {
QPolygon points();
int x = option->rect.x();
int y = option->rect.y();
int w = option->rect.width() / ;
int h = option->rect.height() / ;
x += (option->rect.width() - w) / ;
y += (option->rect.height() - h) / ; if (element == PE_IndicatorSpinUp) {
points[] = QPoint(x, y + h);
points[] = QPoint(x + w, y + h);
points[] = QPoint(x + w / , y);
} else { // PE_SpinBoxDown
points[] = QPoint(x, y);
points[] = QPoint(x + w, y);
points[] = QPoint(x + w / , 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 {
QProxyStyle::drawPrimitive(element, option, painter, widget);
}
}

注意:我们不使用小部件参数,除非将其传递给QWindowStyle::drawPrimitive()函数。如前所述,关于要绘制什么以及应该如何绘制的信息是由QStyleOption对象指定的,因此不需要询问小部件。

如果您需要使用小部件参数来获取其他信息,请小心确保它不是0,并且在使用它之前它是正确的类型。例如:

const QSpinBox *spinBox = qobject_cast<const QSpinBox *>(widget);
if (spinBox) {
...
}

**在实现自定义样式时,您不能仅仅因为枚举值被称为PE_IndicatorSpinUp或PE_IndicatorSpinDown就认为小部件是一个QSpinBox。

警告:Qt样式表目前不支持自定义QStyle子类。在将来的某个版本会解决这个问题。

在Qt应用程序中有几种使用自定义样式的方法。最简单的方法是在创建QApplication对象之前将自定义样式传递给QApplication::setStyle()静态函数:

  #include <QtWidgets>

  #include "customstyle.h"

  int main(int argc, char *argv[])
{
QApplication::setStyle(new CustomStyle);
QApplication app(argc, argv);
QSpinBox spinBox;
spinBox.show();
return app.exec();
}

在项视图中使用样式

视图中的项的绘制是由委托执行的。Qt的默认委托QStyledItemDelegate也用于计算项目的边界矩形,以及QStyledItemDelegate支持的各种项目数据角色的子元素。查看QStyledItemDelegate类描述,以找出支持哪些数据类型和角色。您可以在模型/视图编程中阅读更多关于项目数据角色的内容。

当QStyledItemDelegate绘制项时,它会绘制CE_ItemViewItem,并使用CT_ItemViewItem计算它们的大小。还要注意,它使用SE_ItemViewItemText设置编辑器的大小。在实现自定义项目视图绘制样式时,需要检查QCommonStyle的实现(以及样式继承的任何其他子类)。通过这种方式,您可以发现哪些和如何绘制其他样式元素,然后您可以重新实现应该以不同方式绘制的元素的绘制。

下面使用一个小例子来说明:

      switch (element) {
case (PE_PanelItemViewItem): {
painter->save(); QPoint topLeft = option->rect.topLeft();
QPoint bottomRight = option->rect.topRight();
QLinearGradient backgroundGradient(topLeft, bottomRight);
backgroundGradient.setColorAt(0.0, QColor(Qt::yellow).lighter());
backgroundGradient.setColorAt(1.0, Qt::white);
painter->fillRect(option->rect, QBrush(backgroundGradient)); painter->restore();
break;
}
default:
QProxyStyle::drawPrimitive(element, option, painter, widget);
}

原始元素PE_PanelItemViewItem负责绘制项目的背景,它来自QCommonStyle的CE_ItemViewItem实现。

要添加对绘制新数据类型和项数据角色的支持,需要创建一个自定义委托。但是,如果您只需要支持由默认委托实现的数据类型,则自定义样式不需要附带的委托。QStyledItemDelegate类描述提供了关于自定义委托的更多信息。项目视图标题的绘制也由样式完成,对标题项的大小以及行和列的大小进行控制。

QStyleOption子类:

QStyleOptionButton, QStyleOptionComplex, QStyleOptionDockWidget, QStyleOptionFocusRect, QStyleOptionFrame, QStyleOptionGraphicsItem, QStyleOptionHeader, QStyleOptionMenuItem, QStyleOptionProgressBar, QStyleOptionRubberBand, QStyleOptionTab, QStyleOptionTabBarBase, QStyleOptionTabWidgetFrame, QStyleOptionToolBar, QStyleOptionToolBox, and QStyleOptionViewItem

QT界面 理解QStyle和QStyleOption以及QStyleFactory的更多相关文章

  1. 嵌入式Linux学习笔记(六) 上位机QT界面实现和串口通讯实现

    目录 (1).参考资料 (2).QT界面布局实现 (3).数据和操作逻辑 在上一章我们实现了下位机的协议制定,并通过串口通讯工具完成了对设备内外设(LED)的状态修改,下面就要进行上位机软件的实现了( ...

  2. Qt 界面使用自己定义控件 &quot;提升为&quot;

    1.效果图 我做了一个很easy的样例,一个能够显示颜色的QLabel,边上有个button,点击,跳出颜色选取的Dialog,然后选择一个颜色.这个QLabel会变成什么颜色. 2.ColorLab ...

  3. OSG嵌入QT(QT界面使用Qt Designer编辑)

    本文主要内容:使用Qt Designer编辑好QT界面后,将OSG中的ViewerWidget嵌入到QT的Widget中. 在VS中嵌入QT工具,建立QT GUIApplication后,打开自动生成 ...

  4. 在ROS中使用QT界面

    在终端可以直接用catkin_create_qt_pkg命令创建带Qt界面的ROS package,再按照前面说的方法导入到Qt即可 这里参考的是qt_createTutorialsQt App Te ...

  5. Qt界面编程基本操作

    Qt界面编程基本操作 了解基本代码构成 类widget的头文件widget.h如下: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> ...

  6. QT界面绘制学习记录

    1. MVC结构中,model必须作为类的成员变量存在,不可再函数内部申明.否则,会出现函数调用结束,model找不到的错误. 2.QcomboBox可设置为左边空白,右侧一小箭头的形式.代码:com ...

  7. 用QT创建新风格: QStyle

    转贴: http://hi.baidu.com/yjj2008/blog/item/6cd4a1892ef0d4b60f2444a5.html 本文介绍了如何使用qt提供的接口来设计自己的GUI风格( ...

  8. qt 界面去掉系统边框2.0版

    之前的一版存在bug.如果将鼠标放移动到界面内某个可点击的widget上(如:QPushButton)上,按住鼠标左键不放,界面可能会出现界面非预期移动的问题. 那是因为当鼠标移动到可点击的widge ...

  9. 对QT的理解——能在公司里不做Java,不做很偏门的产品,不使用偏门的语言,还有钱挣,要有感恩的心

    我的理解: QT做应用软件可以很强大,界面足够漂亮(最有意思的是QSS,让我刮目相看),应该是足够了.同时QT也提供了源码,不过超级复杂,难以理解,所以还是无法深入底层.另外它提供了一个额外的好处,就 ...

随机推荐

  1. 初入android驱动开发之字符设备(一)

    大学毕业,初入公司,招进去的是android驱动开发工程师的岗位,那时候刚进去,首先学到的就是如何搭建kernel.android的编译环境,然后就是了解如何刷设备以及一些最基本的工具.如adb.fa ...

  2. Linux 服务器环境启动

    1.PHP 关闭php killall php-fpm php重启 /usr/local/php/sbin/php-fpm & 或者 /usr/local/php/sbin/php-fpm { ...

  3. Echarts 获取后台数据 使用后台数据展示 饼装图

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head& ...

  4. cocos2d-x 托付模式的巧妙运用——附源代码(二)

    转载请注明出处:http://blog.csdn.net/hust_superman/article/details/38292265,谢谢. 继上一篇将了托付类的详细实现后.这篇来将一下怎样在游戏中 ...

  5. android回调函数

    在我们进行android开发的时候,常常遇到一些回调函数,当中,我们最常常使用的回调就是,当我们对一个组件设置监听的时候,事实上就相对于设置的回调函数.比如: Button btn = (Button ...

  6. 算法笔记_091:蓝桥杯练习 递推求值(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 已知递推公式: F(n, 1)=F(n-1, 2) + 2F(n-3, 1) + 5, F(n, 2)=F(n-1, 1) + 3F(n- ...

  7. 《The Story of My Life》Introductiom - The Life and Work of Helen Keller

    Helen Keller was born on June 27,1880, in Tuscumabia, Alabama, to Captain Arthur Henry Keller, a Con ...

  8. 如何监控Tomcat服务器

    如何监控Tomcat服务器 发表于:2009-06-25来源:作者:点击数:2651 标签:tomcatTomcat服务器 在进行 性能测试 时,一般都需要对应用服务器进行监控,监控的指标包括应用服务 ...

  9. Android--从零开始开发一款文章阅读APP

    代码地址如下:http://www.demodashi.com/demo/11212.html 前言 本案例已经开源!如果你想免费下载,可以访问我的Github,所有案例均在上面,只求给个star.当 ...

  10. C语言-数据结构(一)

    1.动态创建多维数组 int ** createArray(int rows, int cols) { int **x, i; x = (int **)malloc(rows * sizeof(*x) ...