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.mfbz.cn/a/656376.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker 基础使用 (1)

文章目录 Docker 软件安装Docker 镜像仓库Docker 仓库指令Docker 镜像指令Docker 容器指令Docker 使用实例 —— 搭建 nginx 服务nginx 概念nginx 使用用 docker 启动 nginx 侧重对docker基本使用的概览。 Docker 软件安装 Linux Ubuntu 依次执行以下指令即可 # 更新软件包列…

Spring:事务(tx)

1. 简介 spring对jdbc进行封装&#xff0c;简化对数据库的操作 2. HelloWorld 1. 搭建模块 2.加入依赖 <dependencies><!--spring jdbc Spring 持久化层支持jar包--><dependency><groupId>org.springframework</groupId><artifactId>s…

Unity Dotween 定位点的制作

目录 前言 一、动画预览 二、动画拆分 三、素材准备 四、曲线 OutCirc详解 五、速度分类详解 六、代码 七、组件和设置 八、作者的话 前言 我答应我的粉丝接下来更新Dotween系列&#xff0c;但是我一直没想好&#xff0c;从哪里开始讲。 Dotween的安装我就跳过了&…

一款220V降12V恒压芯片电路原理图WT5114

一款220V降12V恒压芯片电路原理图WT5114&#xff0c;电路图简示如下&#xff1a; 一款220V降12V恒压芯片线路图WT5114 WT5114是一款高性能、高精度、低成本的PWM电源开关&#xff0c;适用于非隔离降压和反激式应用。它集成了专用电流模式PWM控制器&#xff08;采用SOP8封装的高…

埃及媒体分发投放-新闻媒体通稿发布

埃及商业新闻 大舍传媒近日宣布将在埃及商业新闻领域展开新的媒体分发投放。作为埃及最具影响力的商业新闻平台之一&#xff0c;埃及商业新闻将为大舍传媒提供广阔的市场和受众群体。这一合作意味着大舍传媒将有机会通过埃及商业新闻的平台向埃及的商业精英和投资者传递最新的…

ACM Proceedings Template 使用方法

模板导入 打开ACM Primary Article Template官网&#xff0c;可以看到自带overleaf模板&#xff0c;接下来我们使用overleaf来自动导入模板。 选择你需要的ACM Conference or Journals模板&#xff0c;然后Open as Template 栏目说明 接下来依次解释一下左边栏目的作用 …

mail发送调用接口如何与三方服务无缝对接?

mail发送调用接口的性能怎么样&#xff1f;调用邮件接口的技巧&#xff1f; 为了提高效率和自动化水平&#xff0c;企业通常会选择使用mail发送调用接口。然而&#xff0c;仅仅使用这些接口还不够&#xff0c;如何与各种第三方服务无缝对接同样至关重要。AokSend将探讨如何有效…

再创佳绩丨达梦数据库一体机荣获2024数字中国创新大赛·信创赛道总决赛一等奖

5月24日&#xff0c;第七届数字中国建设峰会在福州盛大开幕&#xff0c;峰会内容安排包含开幕式、主论坛、分论坛、数字中国创新大赛、现场体验区及成果发布和专业工作会议等。武汉达梦数据库股份有限公司(以下简称达梦数据)受邀参加并在展、会、赛等多个环节深度参与。达梦全栈…

mac M3芯片 goland 2022.1 断点调试失败(frames are not available)问题,亲测有效

遇到如上问题&#xff0c;解法 步骤1&#xff1a;下载dlv文件 执行 go install github.com/go-delve/delve/cmd/dlvlatest 然后在 $GOPATH/bin里发现多了一个dlv文件 (找不到gopath? 执行 go env 可以看到) 步骤2&#xff1a;配置dlv 将这个dlv文件移到 /Applications/G…

vue中在mounted使用$refs获取不到DOM元素

vue中在mounted使用$refs获取不到DOM元素 前言解决方案1、通过使用$nextTick来获取2、updated中获取 前言 在使用ref的时候&#xff0c;在mounted中通过$ref获取节点是获取不到报undefined this.$refs.xx 为 undefined 解决方案 在mounted钩子中加载回来的数据不会在这个阶段更…

webpack5_相关知识点

webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler) &#xff0c;是前端资源模块化管理和打包工具&#xff0c; 它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离&#xff0c;等到实际需要时…

Python 读取.shp文件并生成图幅编号

代码适用于需要处理和分析地理空间数据的场景&#xff0c;如城市规划、环境监测或自然资源管理&#xff0c;其中它可以帮助用户读取特定区域的Shapefile文件&#xff0c;确定其地理边界&#xff0c;并基于这些边界计算出按照经纬度5度间隔的图幅编号&#xff0c;进而用于地图制…

Hive环境搭建

1 安装Hive 下载文件 # wget -P /opt/ https://mirrors.huaweicloud.com/apache/hive/hive-2.3.8/apache-hive-2.3.8-bin.tar.gz 解压缩 # tar -zxvf /opt/apache-hive-2.3.8-bin.tar.gz -C /opt/ 修改hive文件夹名字 # mv /opt/apache-hive-2.3.8-bin /opt/hive 配置环境变量 …

力扣HOT100 - 138. 随机链表的复制

解题思路&#xff1a; class Solution {public Node copyRandomList(Node head) {if(headnull) return null;Node p head;//第一步&#xff0c;在每个原节点后面创建一个新节点//1->1->2->2->3->3while(p!null) {Node newNode new Node(p.val);newNode.next …

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

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

文生图模型演进:AE、VAE、VQ-VAE、VQ-GAN、DALL-E 等 8 模型

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学。 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 合集&#x…

【强训笔记】day24

NO.1 思路&#xff1a;递归。 代码实现&#xff1a; class Solution { public:bool IsBalanced_Solution(TreeNode* pRoot) {return dfs(pRoot)!-1;}int dfs(TreeNode* root){if(rootnullptr) return 0;int leftdfs(root->left);if(left-1) return -1;int rightdfs(root-…

如何使用甘特图来做任务管理?zz-plan甘特图的实践指南

在项目管理和任务调度中&#xff0c;甘特图是一种非常实用的工具&#xff0c;它可以帮助团队成员清晰地规划、执行和跟踪项目进度。然而&#xff0c;如何有效利用甘特图进行任务管理&#xff0c;对于许多团队来说仍然是一个挑战。本文将结合 zz-plan https://zz-plan.com/ 甘特…

jmeter服务器性能监控分析工具ServerAgent教程

ServerAgent介绍&#xff1a;支持监控CPU&#xff0c;memory&#xff0c;磁盘&#xff0c;网络等&#xff0c;和JMeter集成&#xff0c;在JMeter的图形界面中&#xff0c;可以实时看到监控的数据&#xff0c;但是&#xff0c;它只能监控硬件资源使用情况。 不能监控应用服务 S…

天若OCR 识别 (本地文字识别转换工具)

前言 天若OCR文字识别本地版是一款在天若OCR文字识别工具v5.0免费开源版的基础上采用Chinese-lite框架和Paddle-ocr框架本地化识别接口编译而成,无需联网也无需申请密钥&#xff0c;纯本地运算&#xff0c;识别准确度和速度很快&#xff0c;操作和天若OCR免费版一样&#xff0…