Qt中QProxyStyle::drawControl函数4个参数的意义

我们来详细解释一下 Qt 中 QProxyStyle::drawControl 函数的四个参数。

这个函数是 Qt 样式系统中的一个核心方法,用于绘制标准 UI 元素(如按钮、复选框、菜单栏等)。当你继承 QProxyStyle 并重写此函数时,你是在告诉 Qt 如何绘制这些控件。

void QProxyStyle::drawControl(ControlElement element,const QStyleOption *option,QPainter *painter,const QWidget *widget) const

1. ControlElement element

  • 类型QStyle::ControlElement (一个枚举类型)
  • 意义指定要绘制的控件类型
    这个参数告诉 drawControl 函数当前需要绘制的是什么具体的 GUI 元素。Qt 定义了大量的标准控件元素,例如:
    • CE_PushButton: 绘制一个按钮(如 QPushButton)。
    • CE_CheckBox: 绘制复选框的指示器部分。
    • CE_RadioButton: 绘制单选框的指示器部分。
    • CE_ComboBoxLabel: 绘制组合框(QComboBox)的文本标签。
    • CE_MenuItem: 绘制菜单中的一项。
    • CE_ProgressBar: 绘制进度条。
    • CE_TabBarTab: 绘制标签栏(QTabBar)中的一个标签。
    • … 以及很多其他元素(完整列表请参阅 Qt 文档中的 QStyle::ControlElement)。
  • 用法: 在你的重写函数中,你通常会使用一个 switch 语句来根据不同的 element 值进行不同的绘制操作。对于你不想自定义的元素,你应该调用基类(即 QProxyStyleQCommonStyle)的实现,让它们来处理。
void MyCustomStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{switch (element) {case CE_PushButton:// 我的自定义按钮绘制代码drawMyCustomButton(option, painter, widget);break;case CE_CheckBox:// 我的自定义复选框绘制代码drawMyCustomCheckbox(option, painter, widget);break;default:// 对于所有其他我不关心的控件,交给父类(代理的样式或默认样式)处理QProxyStyle::drawControl(element, option, painter, widget);break;}
}

2. const QStyleOption *option

  • 类型const QStyleOption*

  • 意义包含绘制控件所需的所有状态和信息
    这是一个非常重要的参数,它是一个基类指针,通常指向某个 QStyleOption 的子类。你需要将其转换(qstyleoption_cast)为正确的子类来获取具体的绘制信息。

    不同控件元素(element)对应不同的 QStyleOption 子类:

    • 绘制 CE_PushButton 时,option 通常指向 QStyleOptionButton
    • 绘制 CE_ProgressBar 时,option 通常指向 QStyleOptionProgressBar
    • … 以此类推。

    这些 QStyleOption 子类包含了诸如:

    • rect: 控件需要被绘制的矩形区域。
    • palette: 控件应该使用的调色板(颜色组)。
    • state: 控件的状态标志(如 State_Enabled, State_HasFocus, State_MouseOver, State_Sunken 等)。
    • 以及子类特有的信息,如按钮的文本(text)、图标(icon),进度条的进度(progress)等。
  • 用法: 在绘制代码中,你需要先进行安全的类型转换,然后从转换后的对象中读取信息。

case CE_PushButton: {// 安全地将基类指针转换为 QStyleOptionButton*const QStyleOptionButton *buttonOption = qstyleoption_cast<const QStyleOptionButton*>(option);if (buttonOption) {// 现在可以使用 buttonOption->text, buttonOption->rect 等信息QString text = buttonOption->text;QRect rect = buttonOption->rect;bool isPressed = (buttonOption->state & State_Sunken); // 检查按钮是否被按下// ... 绘制逻辑}break;
}

3. QPainter *painter

  • 类型QPainter*
  • 意义执行实际绘制操作的“画笔”
    这个 QPainter 对象已经设置好了,目标设备(通常是 QWidget 的绘图表面)和坐标系统也已经配置完成。你所有的绘制命令(如 drawRect, drawText, drawPixmap)都通过这个对象来完成。
  • 用法: 你直接使用这个 painteroption->rect 指定的区域内进行绘制。你可以设置它的画笔(pen)、画刷(brush)、字体(font)等属性。
painter->save(); // 保存当前状态
painter->setRenderHint(QPainter::Antialiasing); // 设置抗锯齿if (isPressed) {painter->setBrush(pressedBrush); // 设置按下状态的画刷
} else {painter->setBrush(normalBrush); // 设置正常状态的画刷
}
painter->setPen(outlinePen); // 设置轮廓画笔
painter->drawRoundedRect(buttonRect, 5, 5); // 绘制一个圆角矩形painter->setFont(buttonFont);
painter->setPen(textColor);
painter->drawText(buttonRect, Qt::AlignCenter, text); // 绘制文本painter->restore(); // 恢复保存的状态

4. const QWidget *widget

  • 类型const QWidget*
  • 意义(可选)与绘制操作相关联的控件
    这个参数可能是一个 nullptr,也可能是指向正在被绘制的实际 QWidget 的指针。它主要用于获取控件特有的额外信息,这些信息可能没有包含在通用的 QStyleOption 结构中。
  • 用法: 当你需要获取控件的一些特定属性或调用其方法时(尽管在 const 方法中很有限),这个参数就很有用。例如,你可以检查控件是否具有某些自定义属性。
if (widget) {// 例如,检查控件是否有一个自定义属性来决定是否要特殊绘制if (widget->property("mySpecialStyle").toBool()) {drawSpecialVariant(option, painter);return;}// 或者,你可以获取控件的对象名称等元信息用于调试// qDebug() << "Drawing for widget:" << widget->objectName();
}

注意: 由于这个函数是 const 的,并且 widgetconst 指针,你不能通过它来修改控件。

总结

参数意义用途
element“画什么?”指定要绘制的控件类型(按钮、复选框等)。
option“用什么状态画?”提供控件的大小、状态、文本等所有必要信息。
painter“用什么工具画?”提供执行实际绘制命令(画矩形、文字等)的工具。
widget“为谁画?”(可选)提供控件本身的引用,用于获取更高级或特定的信息。

通过组合使用这四个参数,你可以完全自定义 Qt 应用程序中几乎所有标准控件的外观。QProxyStyle 的妙处在于,你只需要重写你想改变的部分,对于其他控件,可以轻松地委托给底层的基础样式(如 Fusion, Windows 等)来处理。

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

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

相关文章

idf-esp32 PWM呼吸灯(LEDC头文件)

相关宏和变量#define LED_PIN GPIO_NUM_3 #define LEDC_CHANNEL LEDC_CHANNEL_0 #define LEDC_TIMER LEDC_TIMER_0 #define LEDC_MODE LEDC_LOW_SPEED_MODE #define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 2^13 8192级亮度 #define LEDC_FREQUENCY 50…

PLC_博图系列☞基本指令”S_ODTS:分配保持型接通延时定时器参数并启动“

PLC_博图系列☞基本指令”S_ODTS&#xff1a;分配保持型接通延时定时器参数并启动“ 文章目录PLC_博图系列☞基本指令”S_ODTS&#xff1a;分配保持型接通延时定时器参数并启动“背景介绍S_ODTS&#xff1a; 分配保持型接通延时定时器参数并启动说明参数脉冲时序图示例关键字&a…

OneCode 可视化揭秘系列(三):AI MCP驱动的智能工作流逻辑编排

OneCode 可视化揭秘系列&#xff08;三&#xff09;&#xff1a;AI MCP驱动的智能工作流逻辑编排 引言 在前两篇系列博文中&#xff0c;我们详细探讨了OneCode可视化动作的基础配置与界面设计&#xff0c;以及组件交互与数据流管理。在本篇文章中&#xff0c;我们将深入剖析逻辑…

TypeORM、Sequelize、Hibernate 的优缺点对比:新手常见 SQL 与 ORM 踩坑总结

1. ORM 与关系型数据库&#xff08;MySQL、PostgreSQL&#xff09; 的使用 SQL 语句编写&#xff08;JOIN、GROUP BY、索引使用、事务控制&#xff09;与 ORM 映射&#xff08;如 Sequelize、TypeORM、Hibernate&#xff09;之间的差异会让新手非常纠结&#xff1b;尤其是理解…

JavaScript 创建型设计模式详解

1. 单例模式1.1. 使用场景在前端开发中&#xff0c;全局状态管理、配置信息、数据库连接等往往需要在应用中只存在一个实例&#xff0c;避免多次实例化带来的数据不一致性。例如&#xff0c;在一个前端应用中&#xff0c;全局的 loading 状态通常需要一个单例模式来确保其唯一性…

k8s除了主server服务器可正常使用kubectl命令,其他节点不能使用原因,以及如何在其他k8s节点正常使用kubectl命令??

kubectl 并不是“只能”在主节点&#xff08;Control Plane Node&#xff09;使用&#xff0c;而是因为它需要访问 Kubernetes 的 kube-apiserver&#xff0c;而 kube-apiserver 通常只在主节点上运行并监听内部网络。简单来说kubectl 需要连接 kube-apiserver&#xff01;&…

Custom SRP - Complex Maps

https://catlikecoding.com/unity/tutorials/custom-srp/complex-maps/1 创建材质球我们的材质已经支持光照,并且支持 Albedo 和 Emission 贴图.创建材质球,并应用下面的电路板的图分别作为 albedo emission设置材质球的金属度为 1 , 光滑度为 0.952 Mask Map在 albedo 图上的不…

repo 学习教程

你现在会用 git 了&#xff0c;接下来学 repo&#xff08;Google 推出来的多仓库管理工具&#xff09;&#xff0c;其实就是在 Git 的基础上做了一层封装&#xff0c;方便同时管理很多 Git 仓库。像 Android 源码、Rockchip 全套 SDK 都是靠 repo 来拉取和管理的。 我给你分几个…

[SWERC 2020] Safe Distance题解

[SWERC 2020] Safe Distance 题意 给定 NNN 个点与一个坐标 (X,Y)(X,Y)(X,Y)&#xff0c;求从点 (0,0)(0,0)(0,0) 到点 (X,Y)(X,Y)(X,Y) 规划一条路线&#xff0c;不能走出 (0,0)(0,0)(0,0) 与 (X,Y)(X,Y)(X,Y) 间形成的矩形&#xff0c;使得通过这条路线时距离最近的点的距离…

Rewind-你人生的搜索引擎

本文转载自&#xff1a;Rewind-你人生的搜索引擎 - Hello123工具导航 ** 一、&#x1f50d; Rewind 是什么&#xff1f;你的数字记忆增强神器 Rewind 是一款人工智能驱动的个人记忆助手&#xff0c;就像为你配备了一个「数字第二大脑」。它能自动记录、保存并索引你在电脑和手…

开发小点 - 存

开发小点 1.Req注解 EqualsAndHashCode(callSuper true) Data public class BillSituationReq extends BillQueryReq {/*** Whether to display the ring ratio, default is not displayed*/ApiModelProperty("Whether to Display YoY Comparison")private Boolean …

只会npm install?这5个隐藏技巧让你效率翻倍!

原文链接&#xff1a;https://mp.weixin.qq.com/s/nijxVWj-E5U08DX2fl3vgg最近有个刚学前端的小伙伴问我&#xff1a;“为什么我的node_modules这么大&#xff1f;为什么别人装依赖那么快&#xff1f;npx到底是啥玩意儿&#xff1f;” 相信不少人都跟他一样&#xff0c;对npm的…

(二).net面试(static)

文章目录项目地址一、基础501.1 new keyword1.2 static class vs. static method1. static class2. static method3. static constructor 静态构造函数4. 静态成员的生命周期1.3 LinQ1.what is LinQ2. List<T>、IEnumerable<T>、IQueryable<T>3. 在数据库里用…

docker,本地目录挂载

理解Docker本地目录挂载的基本概念Docker本地目录挂载允许容器与宿主机共享文件或目录&#xff0c;实现数据持久化和实时交互。挂载方式分为bind mount和volume两种&#xff0c;前者直接映射宿主机路径&#xff0c;后者由Docker管理存储路径。本地目录挂载的核心方法bind mount…

IO多路复用相关知识

select、poll、epoll 在传入的性能差异是不是体现在&#xff0c;当有新的连接过来&#xff0c;此时需要将新的fd传入到内核中&#xff0c;但是poll/select需要出入整个数组&#xff0c;而epoll方式只需要出入单个fd&#xff1f; 1. select/poll 的情况它们没有内核中“长期保存…

【CF】Day139——杂题 (绝对值变换 | 异或 + 二分 | 随机数据 + 图论)

B. Meeting on the Line题目&#xff1a;思路&#xff1a;数形结合首先考虑如果没有 t 的影响该怎么写显然我们就是让最大时间最小化&#xff0c;那么显然选择最左端点和最右端点的中间值即可&#xff0c;即 (mi mx) / 2&#xff0c;那么现在有了 t 该怎么办我们不妨考虑拆开绝…

在 Ubuntu 上安装和配置 PostgreSQL 实录

一、查看ubuntu版本 lsb_release -a postgresq尽量安装在新的稳定版本的ubuntu上 二、安装postgresql 2.1 直接安装 sudo apt install postgresql 结果如下 2.2 使用PPA源安装 Ubuntu官方源提供了PostgreSQL的PPA(Personal Package Archive),通过PPA源安装可以确保获取…

WebGIS三维可视化 + 数据驱动:智慧煤仓监控系统如何破解煤炭仓储行业痛点

目录 一、项目背景&#xff1a;煤炭仓储管理的痛点与转型需求 二、建设意义&#xff1a;从 “被动管理” 到 “主动掌控” 的价值跃迁 三、项目核心&#xff1a;技术架构与核心目标的深度融合 四、数据与技术&#xff1a;系统稳定运行的 “双支柱” &#xff08;一&#x…

使用 Spring Security 实现 OAuth2:一步一步的操作指南

前言 OAuth 是一种授权框架&#xff0c;用于创建权限策略&#xff0c;并允许应用程序对用户在 HTTP 服务&#xff08;如 GitHub 和 Google&#xff09;上的账户进行有限访问。它的工作原理是允许用户授权第三方应用访问他们的数据&#xff0c;而无需分享他们的凭证。本文将指导…

VMware共享文件夹设置

启用共享文件夹 编辑虚拟机设置-选项-共享文件夹&#xff0c;上面的选项选择启用下面点击添加一个路径&#xff0c;跟着向导走 设置共享文件夹在主机的路径&#xff0c;和文件夹名称添加完成后可以点击这个共享文件夹条目&#xff0c;查看属性虚拟机里安装vm-tools sudo apt up…