QT学习(20):QStyle和自定义样式

QStyle
样式(继承自QStyle类)代表控件的绘制并封装GUI的外观。QStyle是一个封装了GUI外观的抽象基类。Qt使用QStyle去执行几乎所有的内置控件的绘制,确保控件外观和原生控件风格风格相同。

class Q_WIDGETS_EXPORT QStyle : public QObject{};

QProxyStyle
为了自定义现有样式,需要继承QProxyStyle并重新实现所需的虚函数。QProxyStyle允许指定某个基本样式,当基本样式未指定时,将自动使用应用程序样式。前者提供对基本样式的完全控制,并且在自定义需要特定样式行为时效果最佳,而后者提供一种与平台无关的方式来自定义默认为本机平台样式的应用程序样式。

class Q_WIDGETS_EXPORT QProxyStyle : public QCommonStyle{};

QCommonStyle
QCommonStyle为完全自定义样式实现提供了一个方便的基类。这种方式与使用QProxyStyle相同,但是继承自QCommonStyle并重新实现相应的虚函数。

class Q_WIDGETS_EXPORT QCommonStyle: public QStyle{};

QStyle实现
QStyle的API包含绘制控件的函数,用于执行常见和困难任务的静态函数以及用于执行绘制时所需的各种计算的函数。该样式也辅助控件内容的布局,此外还创建一个包含QBrush的QPalette对象。

QStyle绘制图形元素,一个元素是一个控件,或者是一个控件部分(如按钮斜角、窗口框架或滚动条等等)。大多数绘制函数采用四个函数:

  • 枚举值指定绘制元素的类型;
  • QStyleOption对象指定呈现该元素的方式和位置;
  • QPainter对象表示执行绘图的画笔;
  • QWidget对象表示执行绘图的控件。

当控件要求样式绘制元素时,控件会为样式提供QStyleOption对象(包含绘制所需信息的类)。QStyleOption类使得可以在不链接控件代码的情况下绘制控件,从而在任何绘画设备上使用QStyle的绘制函数成为可能。在Qt中,Item Views的items由委托绘制。Item Views的标题任由样式绘制。

样式元素
样式元素是GUI的图形部分。一个控件由样式元素的层次结构(或树)组成。比如,当样式收到绘制按钮的请求时(例如,从QPushButton),样式会绘制一个标签(文本和图标)、一个按钮斜角和一个焦点框。而按钮斜角由斜角周围的框架和另外两个元素组成。

请添加图片描述
绘制控件不一定是通过要求样式只绘制一个元素来完成,控件可以多次调用来绘制不同元素。比如QTabWidget单独绘制选项卡和框架。

元素类型分三种:基本元素、控制元素和复杂控制元素,元素由枚举类型ComplexControl、ControlElement和PrimitiveElement enums定义。

  • 基本元素:

基本元素是常见的GUI元素。例如,框架frame、按钮斜角button bavels以及用于输入框spin boxes、滑动条scroll bars和下拉框combo boxes的箭头。基本元素不能独立存在,而是整体结构的一部分,不参与用户交互,而是GUI中的被动装饰。

  • 控制元素:

控制元素执行操作或者向用户显示信息。控制元素包括表和树视图中的按钮、勾选框和标题部分。控制元素不一定是完整的小部件,也可以是控件的部分结构,比如滑动条滑块和选项卡。控制元素与基本元素的不同之处在于其不是被动的,而是在交互中填充功能。有多个元素组成的控件通常使用样式来计算元素的边界矩形,可用的子元素由枚举类型SubElement定义。此枚举仅用于计算边界矩形,子元素不是像基本元素、控制元素和复杂元素那样需要绘制的图形元素。

  • 复杂的控制元素:

复杂的控制元素包含子控件。复杂控件的行为会有所不同,具体取决于用户使用鼠标的位置和按下的键盘键。这取决于鼠标处于或按键按下的子控件(如果有)。复杂控件元素有滚动条和组合框。可以通过鼠标移动滑动块或者按向上和向下按钮来使用滑动条。可用的子控件由枚举SubControl枚举类型定义。

除了绘图之外,样式还需要为控件提供有关鼠标在哪个子控件上进行操作的信息。例如,互动条需要知道用户是否按下滑块、滑块凹槽或向上、向下按钮。

和控制元素不同,不能使用样式绘制子控件,样式仅计算应在其中绘制子控件的边界矩形。然而,复杂元素通常使用控制元素和基本元素来绘制子控件。

样式选项
QStyleOption的子类包含设置各个元素样式所需的所有信息。样式选项通常在栈上被实例化,并由QStyle函数的调用方填写。根据绘制的内容,样式期望不同的样式选项类。例如,QStyle::PE_FrameFocusRect元素需要一个QStyleOptionFocusRect参数,并且可以创建一个自定义样式可以使用的自定义子类。出于性能原因,样式选项保留公共变量

控件可以处于许多不同的状态,这些状态由State枚举类型定义。根据控件的不同,状态标志具有不同的含义,但像State_Disabled这样的状态标志对所有控件都是通用的。

最值得注意的是,样式选项包含要绘制的控件的调色板和边界矩形,大多数控件都有专门的样式选项,例如QPushButton和QCheckBox使用QStyleOptionButton用作样式选项,其中包含文本、图标及其图标的大小。

在重新实现带有QStyleOption参数的QStyle函数时,通常需要将QStyleOption对象类型转换为子类(如QStyleFocusRect)。为了安全起见,可以使用qstyleoption_cast()确保指针类型时正确的。如果类型指针不正确,qstyleoption_cast会返回nullptr。

QStyle函数
定义了三个虚函数,用来绘制基本元素、控制元素和复杂控制元素。

  • 绘制基本元素drawPrimitive
  • 绘制复杂控制元素drawComplexControl
  • 绘制控制元素drawControl

QStyle类还提供绘制元素时使用的辅助函数,drawItemText函数在指定的矩形内绘制文本,将调色板对象作为参数。drawItemPixmap函数在指定的边界矩形内对齐像素图。

其它QStyle函数为执行绘制的函数进行各种计算。如果控件绘制多个样式元素,也使用这些函数来计算大小提示和边界矩形。和绘制元素的函数一样,辅助函数通常采用相同的参数。

  • subElementRect函数采用SubElement枚举值并计算子元素的边界矩形,样式使用此函数来得到绘制元素不同部分的位置。
  • subControlRect函数用来计算复杂控制元素中的子控件的边界矩形,实现新样式时需要重新实现该函数并计算矩形。
  • pixelMetric函数返回像素度量,该指标是以屏幕像素为单位给出的与样式相关的大小。采用PixelMetric枚举值并返回正确的测量值。
  • hitTestComplexControl函数返回鼠标指针在复杂控制元素中的子控件上。

QStyle还定义了函数polish和unpolish函数,所有控件在显示之前都会被发送到polish函数,在隐藏时会被发送到unpolish。可以使用这些函数在设置控件上的属性,或者执行样式所需的其它工作。例如,如果需要知道鼠标何时悬停在控件上,需要设置WA_Hover属性,然后控件中的样式选项中的State_MouseOver状态位被设置。

QStyle也定义了一些静态辅助函数,执行一些常见但困难的任务。例如,根据滑块的值计算滑块手柄的位置,并转换矩形并绘制文本,考虑反向布局。

调色板
QPalette提供调色板,存储不同控件状态和颜色角色的颜色。每种样式都提供调色板应用于控件的绘制。有一组颜色集合对应于不同的控件状态:活动状态(具有焦点)、非活动状态和禁用状态。可以通过查询State_Enabled和State_Actived状态标志得到当前的状态。每一个颜色集合包含由枚举类型QPalette::ColorRole确定的颜色职责。这些职责描述了在一种情况(绘制控件背景、文本和按钮)下应该使用对应的颜色。

如何使用颜色职责取决于样式,例如,如果样式使用渐变,则可以使用使用QColor::darked或QColor::lighter使其更暗或更亮从而创建渐变。如果需要调色板没有提供的画布,通常应该继承。

Java风格
实现一种类似于Java默认外观的样式。

设计与实现
设计样式的第一步是选择基类,通常选择继承QCommonStyle,该类实现了需要的大多数功能,而不是执行实际的绘图。

改样式在一个类中实现。

尝试实现一个控件

公共的控件属性和变量

某些状态和变量对于所有控件来说是通用的,这些属性通过QStyleOption::initFrom函数设置。并非所有元素都使用该函数。

状态状态设置条件
State_Enabled控件没有禁用时
State_Focus控件有焦点
State_KeyboardFocusChange键盘焦点更改
State_MouseOver鼠标在控件上
State_Active控件是活动窗口的子窗口
State_HasEditFocus控件具有编辑焦点
变量内容
rect绘制元素的边界矩形
direction布局方向
palette绘制元素使用的调色板
fontMetrics绘制文本的字体计量

QPushButton

按钮的样式结构图下所示,通过对树进行自上而下的遍历,可以获得绘制元素的顺序。
请添加图片描述
按钮的布局(和元素边界相关)因样式而异。元素可能有相同的边界。例如,PE_PushButtonBevel被用于在QCommonStyle中绘制三个元素:PE_FrameDefaultButton、PE_FrameButtonBevel和PE_PanelButtonCommand,这些元素在公共样式中具有相同的边界。

下面给出了一个按钮图像,该图像显示了元素的边界矩形。颜色用于分隔图像中的边界矩形。
请添加图片描述
QPushButton的样式选项是QStyleOptionButton,QPushButton可以在样式选项上设置的状态表如下。

状态状态设置条件
State_Sunken按钮按下或按下菜单显示
State_On按钮被选中
State_Raised按钮没按下也没升起
成员变量内容
features描述各种按钮属性
icon按钮图标
iconSizeicon的大小
text按钮文本

QCheckBox和QRadioButton

QCheckBox和QRadioButton的结构是相同的。
请添加图片描述

状态状态设置条件
State_Sunken框被按下
State_NoChange框被部分选中
State_On框被选中
State_Off按钮没按下也没升起

Tabs选项卡

在Qt中,QTabBar使用样式来绘制选项卡。选项卡要么存在于包含QTabBar的QTabWidget,要么作为单独的选项卡栏存在。

QTabBar和QTabWidget的样式结构如下。
请添加图片描述
tab bar形状和标签具有与CE_TabBarTab相同的边界矩形。请注意,tabs和tab widget框架重叠,tab bar的底部是重叠的区域。

tabs的样式QStyleOptionTab包含绘制tabs必须的信息。该样式选项包含tab在tab bar中的位置,选择tab的位置,tab的形状,文本,图标和图标的大小。
请添加图片描述
tab bar可以在tabs上设置的状态表如下。

状态状态设置条件
State_Sunken选项卡被鼠标选中
State_Selected是当前选项卡
State_HasFocus选项卡栏具有焦点且选项卡处于选中状态

QStyleOptionTab的成员表如下。

成员变量内容
cornerWidgets指示tab bar是否具有角控件以及具有哪些角控件
icontab图标
iconSizeicon的大小
texttab文本
positiontab在tab bar上相对于其它tab的位置
rowtab所在的行
selectedPosition指示所选tab和tab相邻还是tab
shape指示tab是圆角还是三角以及tab的方向

tab widget的外框使用QStyleOptionTabWidgetFrame作为样式选项,除了通用的标志外,没有其它状态标志。

成员变量内容
cornerWidgets指示tab bar是否具有角控件以及具有哪些角控件
icontab图标
iconSizeicon的大小
texttab文本
positiontab在tab bar上相对于其它tab的位置
rowtab所在的行
selectedPosition指示所选tab和tab相邻还是tab
shape指示tab是圆角还是三角以及tab的方向

Scroll Bars
请添加图片描述
QScrollBar只需创建样式选项,然后绘制控件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/18074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【OpenCV】图像通道合并与分离,ROI

介绍可以实现图像通道合并与分离的API,这只是一种方式,后续还会介绍其他的合并与分离方法,以及ROI区域截取的方法。相关API: split() merge() Mat对象() 代码: #include "iostream" #include "ope…

MySQL进阶之(九)数据库的设计规范

九、数据库的设计规范 9.1 范式的概念9.1.1 范式概述9.1.2 键和相关属性 9.2 常见的范式9.2.1 第一范式9.2.2 第二范式9.2.3 第三范式9.2.4 第四范式9.2.5 第五范式(域键范式) 9.3 反范式化9.3.1 概述9.3.2 举例9.3.3 反范式化新问题9.3.4 通用场景 9.4 …

18 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 地表水储量变化Glads水文数据处理

18 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 地表水储量变化 0 引言1 Grace陆地水储量过程整合0 引言 由水量平衡方程可以将地下水储量的计算过程分解为3个部分,第一部分计算陆地水储量变化、第二部分计算地表水储量变化、第三部分计算地下水储量变化。本篇简单介绍…

2024.05.28学习记录

1. 小林coding 计网复习 2.代码随想录刷题. 图论.和复习数组.链表 3.rosebush完成select组件

景源畅信电商:做抖音运营怎么开始第一步?

在数字化时代的浪潮中,抖音作为一款短视频平台迅速崛起,成为许多人表达自我、分享生活的重要舞台。随着用户量的激增,如何做好抖音运营,尤其是迈出成功的第一步,成为了众多内容创作者和品牌主们关注的焦点。接下来&…

Web应用开发学习笔记————Vue框架

Vue框架快速入门 Vue入门 实现代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>vue入门</title><!--引入vue.js文件--><script src"../js/vue.js"><…

就说说Java初学者求职准备项目的正确方式

当下不少Java初学者也知道求职时项目的重要程度&#xff0c;但在简历上写项目和准备面试项目时&#xff0c;真有可能走弯路&#xff0c;这样的话&#xff0c;加重学习负担还是小事&#xff0c;还真有可能导致无法入职。 1 对于在校生和应届生来说&#xff0c;你去跑通个学习项…

2024年4月—马克思主义基本原理概论真题及答案解析(上海自考)

目录 1.选择题 2.简答题 3.论述题 1.选择题 2.简答题

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(九)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 继续接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 现在&#xff0c;我们…

STM32——定时器

一、简介 *定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断 *16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时 *不仅具备基本的定时中断功能&#xff0c;而且还包含内外时钟源选择、输入…

基于SpringBoot的本科生考研率统计系统

基于SpringBoot的本科生考研率统计系统 一、开发技术二、功能模块三、代码结构四、数据库设计五、运行截图六、源码获取 一、开发技术 技术&#xff1a;SpringBoot、MyBatis-Plus、Redis、MySQL、Thymeleaf、Html、Vue、Element-ui。 框架&#xff1a;基于开源框架easy-admin开…

景源畅信:抖音小店新手小白如何做好运营?

在数字时代的浪潮中&#xff0c;抖音小店成为了众多创业者和商家的新宠。但面对激烈的市场竞争和不断变化的平台规则&#xff0c;新手小白如何才能在抖音小店的海洋里稳健航行&#xff0c;捕捉到属于自己的商机呢?接下来的内容将为你揭晓答案。 一、精准定位&#xff0c;明确目…

视频监控平台AS-V1000 的场景管理,一键查看多画面视频的场景配置、调用、管理(一键浏览多路视频)

目录 一、场景管理的定义 二、场景管理的功能和特点 1、功能 &#xff08;1&#xff09;场景配置 &#xff08;2&#xff09;实时监控 &#xff08;3&#xff09;权限管理 2、特点 三、AS-V1000的场景配置和调用 1、场景配置 &#xff08;1&#xff09;实时视频预览 …

React@16.x(12)ref 转发-forwardRef

目录 1&#xff0c;介绍2&#xff0c;类组件如何使用4&#xff0c;应用场景-高阶组件HOC 1&#xff0c;介绍 上篇文章中提到&#xff0c;ref 只能对类组件使用&#xff0c;不能对函数组件使用。 而 ref 转发可以对函数组件实现类似的功能。 使用举例&#xff1a; import Re…

为什么选择CleanMyMac软件呢?推荐理由

你是否曾经遇到过这样的问题&#xff1a;电脑运行缓慢&#xff0c;存储空间不足&#xff0c;不知道如何清理垃圾文件&#xff1f;别担心&#xff0c;我们为你找到了解决方案——CleanMyMac软件。这款强大的工具可以帮助你轻松解决这些问题&#xff0c;让你的电脑焕然一新&#…

深入理解Python中的包与模块

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、包的概述与功能 代码案例&#xff1a;包的结构 二、模块的划分与组合 划分模块的方法…

开源内网穿透神器:中微子代理(neutrino-proxy)实现内网穿刺

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

dubbo复习:(10)使用tripple协议进行通信

一、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.…

场景文本检测识别学习 day10(MMdetection)

配置文件(config) 由于在大型项目中&#xff0c;一种模型需要分&#xff1a;tiny、small、big等很多种&#xff0c;而它们的区别主要在网络结构&#xff0c;数据的加载&#xff0c;训练策略等&#xff0c;且差别很多都很小&#xff0c;所以如果每个模型都手动从头写一份&#…

ChatGPT原创指令大全(持续更新)

随着ChatGPT在互联网上的使用越来越多&#xff0c;但很多人在使用ChatGPT的过程中会觉得得到的答案并不是很精准。究其原因其实是你给它的命令不够准确、不够到位。实际现在网上已经很多关于ChatGPT的网站&#xff0c;可以快速生成带有快捷键的ChatGPT指令。但是对于不熟悉Chat…