QT学习(20):QStyle类

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

Qt的内置widgets使用QStyle来执行几乎所有的绘图,确保其看起来与等效的原生widgets完全相同。下面展示了九种不同样式的QComboBox。
请添加图片描述

设置样式

使用QApplication::setStyle()函数设置整个应用程序的样式,也可以使用命令行选项指定。使用QWidget::setStyle()设置单个控件的样式。如果没有指定样式,Qt会根据平台或桌面环境选择最合适的样式。

自定义风格控件开发

开发自定义控件并且希望在所有平台上表现一致,可以使用QStyle函数(如drawItemText()、drawItemPixmap()、drawPrimitive()、drawControl()和drawComplexControl())来执行控件绘制的一部分。

QStyle函数大部分包含4个参数:
枚举值:指定要绘制的图形元素的类型
QStyleOption:指定渲染元素的方式和位置
QPainter:用于绘制元素
QWidget:执行绘图的控件

例如,如果要在小部件上绘制一个焦点矩形,可以编写:

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);
}

控件从QStyleOption中获取呈现图形元素所需的所有信息。QStyleOption有多个子类,表示可以用于绘制的图形元素的类型。

为了方便,Qt提供了QStylePainter类,结合了QStyl、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提供的样式之一来构建自定义样式,最常用的基类是QCommonStyle(而不是QStyle)。

根据要更改的基本样式的部分,重新实现用于绘制界面的对应部分的函数。以修改QWindowStyle绘制的QSpinBox箭头为例,箭头是由drawPrimitive()函数绘制的基元元素,因此需要实现该函数。

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

QSpinBox使用PE_IndicatorSpinUp和PE_IndicatorSpinDown基元元素去绘制向上和向下箭头。

void CustomStyle::drawPrimitive(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;x += (option->rect.width() - w) / 2;y += (option->rect.height() - h) / 2;if (element == PE_IndicatorSpinUp) {points[0] = QPoint(x, y + h);points[1] = QPoint(x + w, y + h);points[2] = QPoint(x + w / 2, y);} else { // PE_SpinBoxDownpoints[0] = QPoint(x, y);points[1] = QPoint(x + w, y);points[2] = QPoint(x + w / 2, 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);}
}

需要注意的是,不会使用参数widget,只是将其传递给QWindowStyle::drawPrimitive()函数。要绘制的内容和如何绘制的信息是由QStyleOption对象指定的,与参数widget无关。如果需要使用参数widget来获取其它信息,要在使用之前确保其不为0,并且类型是正确的。在实现自定义样式时,不能仅仅因为枚举值为PE_IndicatorSpinUp或PE_IndicatorSpinDown而假定控件类型是QSpinBox。

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

使用自定义样式

在Qt应用程序中使用自定义样式有几种方法。最简单的方法是在创建QApplication之前将自定义样式传递给静态函数QApplication::setStyle()。该函数可以随时被调用,但在构造函数之前调用,可以确保遵守使用命令行选项(-style)设置的用户首选项。

#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插件系统支持创建样式作为插件,在运行时加载为共享对象。从而将自定义样式用于其它应用程序,而无需重新编译。

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

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

相关文章

美光EMMC芯片丝印型号查询 8LK17/D9PSK, OXA17/JY997

问题说明 最近在使用美光EMMC的时候&#xff0c;发现通过芯片丝印查询不到 芯片的规格说明书&#xff1b; 经过查阅资料&#xff0c;发现美光的EMMC芯片 “由于空间限制&#xff0c;FBGA 封装组件具有与部件号不同的缩写部件标记”&#xff0c;需要通过官网查询丝印的FBGA cod…

如何用分立器件设计一个过流保护电路

过流保护电路是指当后级负载电流过大或者发生短路时&#xff0c;自动切断电源与后级负载&#xff0c;从而防止大电流损害电源电路&#xff0c;过流保护又叫OCP。 常见的过流保护电路有保险丝过流保护&#xff0c;集成的过流保护芯片&#xff0c;还有这种分立器件搭建的过流保护…

SQL 语言:数据控制

文章目录 概述授权&#xff08;GRANT)销权&#xff08;REVOKE&#xff09;总结 概述 SQL语言中的数据控制权限分配是数据库管理的重要组成部分&#xff0c;它涉及到如何合理地为用户分配对数据库资源的访问和使用权限。 权限类型&#xff1a;在SQL中&#xff0c;权限主要分为…

Python条件分支与循环

大家好&#xff0c;当涉及到编写高效和灵活的程序时&#xff0c;条件分支和循环是 Python 中至关重要的概念。它们允许我们根据不同的条件执行不同的代码块&#xff0c;或者重复执行一组语句。条件分支和循环是测试开发工程师在日常工作中经常使用的工具&#xff0c;无论是编写…

易备数据备份软件:从 .VMDK 文件中对虚拟机进行文件级别的恢复

VMDK 是 VMware 创建的开放式的文件格式&#xff0c;主要用于云计算和虚拟化服务。从基本上讲&#xff0c;.vmdk 文件是虚拟磁盘&#xff0c;其中包含 VMware 虚拟机的所有信息。 可以使用多种应用&#xff08;Winzip、7zip 等&#xff0c;当然也可以使用易备数据备份软件&…

clickhouse——ck目录介绍

一、ck目录 1、/etc/clickhouse-server: 服务端的配置文件目录&#xff0c;包括全局配置config.xml和用户配置users.xml等。 2、/var/lib/clickhouse 默认的数据存储目录&#xff08;通常会修改默认路径配置&#xff0c;将数据保存到大容量磁盘挂载的路径&#xff09; 3、/var…

同时安装python2 和python3

最近的项目因为工具的原因 需要同时安装python2 和python3 我又想学着使用python 写东西 导致遇到了很多问题 记录下来 1 同时安装 python2 和python 1.1 安装完把/确认 Path 环境变量里 同时有python2,python2\Scripts和python3 ,python3\Scripts四个环境变量 修改python3…

利用预测大模型完成办公室饮水机剩余热水量

背景 在每天上班的时候&#xff0c;很多同事都有喝热水的习惯&#xff0c;但是饮水机内的热水量总是比较少的&#xff0c;如何避免等待&#xff0c;高效的接到热水是我接下来要做的事情的动机。 理论基础 在大量真实数据的情况下&#xff0c;可以分析出用水紧张的时间段和用水…

扔掉 MacBook,挑战带OrangePi出差!

背景 由于工作需要&#xff0c;博主经常会到各大企业的自建机房中私有化部署公司的软件产品。 在某些企业自建机房中&#xff0c;有时给到全新的机器&#xff0c;没有基础环境&#xff0c;甚至有的还无法互联网&#xff0c;而且因为近几年CentOS的停止更新&#xff0c;服务器…

【UE C++】 虚幻引擎C++开发需要掌握的C++和U++的基础知识有哪些?

目录 0 引言1 关键的 C 知识2 Unreal Engine 相关知识3 学习建议 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;UE虚幻引擎专栏&#x1f4a5; 标题&#xff1a;【UE C】 虚幻引擎C开发需要掌握的C和U的基础知识有哪些&#xff1f;❣️ 寄语&…

01 一文理解,Prometheus详细介绍

01 一文理解&#xff0c;Prometheus详细介绍 介绍 大家好&#xff0c;我是秋意零。 Prometheus 是一个开源的系统监控和报警工具包&#xff0c;最初由SoundCloud开发&#xff0c;并在2012年作为开源项目发布。Prometheus 目前由Cloud Native Computing Foundation&#xff08…

58. UE5 RPG AI行为树的装饰器

书接56. UE5 RPG 给敌人添加AI实现跟随玩家&#xff0c;我们实现了AI一些基础设置&#xff0c;并实现了获取敌人附近的玩家实现了跟随功能 接下来&#xff0c;我们将实现区分职业&#xff0c;并根据职业不同设置不同的攻击距离&#xff0c;并且根据职业实现不同的技能施放。 …

VSCODE中F12无法跳转,快捷键设置F12和insert混淆了

异常现象 最近用新电脑&#xff08;华为&#xff09;的时候&#xff0c;发现VSCODE经常按F12无法跳转&#xff0c;在快捷键设置当中&#xff0c;也是设置成功的&#xff1b; 此时重新去快捷键设置&#xff0c;会发现按 F12变为了Insert 解决方法 华为笔记本的Fx按键&#x…

Euler 欧拉系统介绍

Euler 欧拉系统介绍 1 简介重要节点与版本EulerOS 特色EulerOS 与 openEuler 区别联系Euler 与 HarmonyOS 区别联系 2 openEuler特色支持 ARM&#xff0c;x86&#xff0c;RISC-V 等全部主流通用计算架构融入 AI 生态嵌入式实时能力提升引入 OpenHarmony 一些突出功能 参考 1 简…

23-LINUX--TCP连接状态

一.TCP服务的特点 传输层协议主要有两个&#xff1a;TCP 协议和 UDP协议。TCP 协议相对于UDP协议的特点是&#xff1a;面向连接、字节流和可靠传输。 使用TCP协议通信的双方必须先建立连接&#xff0c;然后才能开始数据的读写。双方都必须为该连接分配必要的内核资源&a…

OpenHarmony 适配HDMI接口声卡

高清多媒体接口&#xff08;High Definition Multimedia Interface&#xff0c;HDMI &#xff09;是一种全数字化视频和声音发送接口&#xff0c;可以发送未压缩的音频及视频信号。HDMI可用于机顶盒、DVD播放机、个人计算机、电视、游戏主机、综合扩大机、数字音响与电视机等设…

windows中每日定时执行python脚本,解决问题

由于需要一个每天定时执行的任务&#xff0c;所以需要定时启动&#xff0c;网上看了很多方法&#xff0c;感觉不能在python脚本种写个while true 定时执行&#xff0c;占资源不说还不可靠。 最后考虑通过系统工具定时启动&#xff0c;发现linux中有crontab&#xff0c;windows…

OpenHarmony实战开发——宿舍全屋智能开发指南

项目说明 基于OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;、数字管家开发宿舍全屋智能&#xff0c;实现碰一碰开门、碰一碰开灯、碰一碰开风扇以及烟感检测。因为各项目开发流程大体相似&#xff0c;本文主要以碰一碰开门为例介绍如何在现有OpenHar…

海信集团携纷享销客启动LTC数字化落地 推动ToB业务再升级

日前&#xff0c;海信集团携手连接型CRM纷享销客正式启动LTC&#xff08;Leads to Cash&#xff09;数字化平台实施落地项目。作为海信集团数字化的重要里程碑&#xff0c;该项目将通过统一规划、统一投资、统一平台、资源共享和数据赋能&#xff0c;构建ToB业务数字化经营管理…

Python代码:十八、生成数字列表

1、描述 牛牛在牛客网系统录入了一连串数字&#xff0c;数字之间依靠逗号隔开&#xff0c;你能帮助他将这些数字存储在列表中吗&#xff0c;列表元素以int的形式。 输入描述&#xff1a; 输入一行整数&#xff0c;数字之间以空格间隔。 输出描述&#xff1a; 输出这些数字…