当前位置: 首页 > news >正文

类模板实现实现Qt click/hover自定义操作

一、场景

常常会需要实现点击/hover时修改图片,可能是一个QPushButtonQLabelQToolButton……

由于Qt bug,QIcon/QSS只能实现常规态、按下态的图标切换,hover态的图片设置无效。
解决思路无非是安装事件过滤器、自定义类并重实现事件。

然而,总要为这些鸡毛蒜皮的操作“小动干戈”会让人不爽。
这里选择更通用的类模板来简化操作。

二、实现说明

  1. Q_OBJECT不能在类模板中使用,导致我们不能在模板类中设置信号。不过也不是刚需,上面的场景回调函数足够用了。

  2. 如果一定要使用信号,那么就要用一个类来代理信号的发送。
    比如下面定义了InteractiveSignalSender,只用于发送信号。
    绑定时信号发送者需要调getSignalSender()

    注意,只能通过组合的方式。如果通过多继承的方式,例如让模板类继承QObject,会出现重复继承QObject(因为WidgetType也继承自QObject),QObject不支持多重继承,会有问题。

  3. 如果需要在Qt Deigner中使用,需要提升,那么可以单独写个头文件来放入模板实例,例如:

    // InteractivePushButton.h
    #pragma once
    #include "interactiveTemplate.h"using InteractivePushButton = Interactive<QPushButton>;
    

    然后添加该头文件,选择提升为InteractivePushButton即可。

三、实现

使用例子:

ui.btnFeedback->setEnterCallback([&] { ui.btnFeedback->setIcon(QIcon(":/img/hover.png")); });
ui.btnFeedback->setLeaveCallback([&] { ui.btnFeedback->setIcon(QIcon(":/img/simple.png")); });
ui.btnFeedback->setClickCallback([&] { ui.btnFeedback->setIcon(QIcon(":/imgpressed.png")); });connect(ui.btnFeedback->signalSender(), &InteractiveSignalSender::signalEnter, this, [] {});

模板实现如下:
InteractiveTemplate.h

#pragma once#include <QWidget>class InteractiveSignalSender : public QObject {Q_OBJECT
public:explicit InteractiveSignalSender(QObject *parent) : QObject(parent){}Q_SIGNALS:void signalEnter();
Q_SIGNALS:void signalLeave();
};template <typename WidgetType>
class Interactive : public WidgetType {
public:explicit Interactive(QWidget *parent = nullptr);void setEnterCallback(std::function<void()> callback);void setLeaveCallback(std::function<void()> callback);void setClickCallback(std::function<void()> callback);InteractiveSignalSender *signalSender();protected:void mousePressEvent(QMouseEvent *event) override;void enterEvent(QEvent *event) override;void leaveEvent(QEvent *event) override;
private:std::function<void()> m_enterCallback	= nullptr;std::function<void()> m_leaveCallback	= nullptr;std::function<void()> m_clickCallback	= nullptr;InteractiveSignalSender *m_signalSender = new InteractiveSignalSender(this);static_assert(std::is_base_of<QWidget, WidgetType>::value, "WidgetType must be a QWidget");
};template <typename WidgetType>
Interactive<WidgetType>::Interactive(QWidget *parent) : WidgetType(parent)
{
}template <typename WidgetType>
InteractiveSignalSender *
Interactive<WidgetType>::signalSender()
{return m_signalSender;
}template <typename WidgetType>
void
Interactive<WidgetType>::setEnterCallback(std::function<void()> callback)
{m_enterCallback = callback;
}template <typename WidgetType>
void
Interactive<WidgetType>::setLeaveCallback(std::function<void()> callback)
{m_leaveCallback = callback;
}template <typename WidgetType>
void
Interactive<WidgetType>::setClickCallback(std::function<void()> callback)
{m_clickCallback = callback;
}template <typename WidgetType>
void
Interactive<WidgetType>::mousePressEvent(QMouseEvent *event)
{if (m_clickCallback) {m_clickCallback();}WidgetType::mousePressEvent(event);
}template <typename WidgetType>
void
Interactive<WidgetType>::enterEvent(QEvent *event)
{emit m_signalSender->signalEnter();if (m_enterCallback) {m_enterCallback();}WidgetType::enterEvent(event);
}template <typename WidgetType>
void
Interactive<WidgetType>::leaveEvent(QEvent *event)
{emit m_signalSender->signalLeave();if (m_leaveCallback) {m_leaveCallback();}WidgetType::leaveEvent(event);
}

相关文章:

类模板实现实现Qt click/hover自定义操作

一、场景 常常会需要实现点击/hover时修改图片&#xff0c;可能是一个QPushButton、QLabel、QToolButton…… 由于Qt bug&#xff0c;QIcon/QSS只能实现常规态、按下态的图标切换&#xff0c;hover态的图片设置无效。 解决思路无非是安装事件过滤器、自定义类并重实现事件。 …...

Arco Design:引领未来的Vue 3创意先锋,一键开启高效与美感并重的Web开发之旅!

Arco Design 是一个基于 Vue 3 的 UI 框架&#xff0c;它提供了丰富的组件和样式&#xff0c;可以帮助开发者快速构建高质量的 Web 应用程序。以下是 Arco Design 的一些详细特点&#xff1a; 完整的设计系统&#xff1a;Arco Design 提供了一套完整的设计系统&#xff0c;包括…...

【MySQL】Linux下用C/C++链接MySQL数据库

文章目录 一、准备工作二、验证库和接口的使用三、链接数据库四、对数据库进行增删查改增删改查 五、结尾 一、准备工作 要使用C链接数据库, 首先要去MySQL官网下载官网提供的库, MySQL 社区下载. 如图所示: 接着选择: 按需选择版本: 如果用的是云服务器, 那么在安装mysql时…...

Python金融量化专栏简介

量化分析实战 - 专栏大纲 👉👉👉 《玩转Python金融量化专栏》👈👈👈 订阅本专栏的可以下载对应的代码和数据集 专栏目标 本专栏旨在帮助读者全面掌握使用Python进行金融技术指标的计算与应用,从基础到高级,涵盖各种技术指标的实现、策略开发与回测等内容。通过…...

出行365:依托分布式数据库,让出行无忧 | OceanBase案例

*本文首发自“新华社环球”杂志&#xff0c;作者张海鑫 每年的暑期旅游旺季&#xff0c;都会触发一轮轮的文旅消费的热潮&#xff0c;对于互联网出行服务行业而言&#xff0c;这既是一场盛大的狂欢&#xff0c;也是对其综合实力的严峻考验。 然而&#xff0c;自去年暑假起&…...

【C语言】位段详解

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:https://blog.csdn.net/huangcancan666/category_12718530.html &#x1f381;代码托管:黄灿灿 (huang-cancan-xbc) - Gitee.com ⚙️操作环境:Visual Studio 2022 目录 一、什么是位段&#xff1f; 二、…...

LVS集群实验

NAT模式 本质是多目标IP的DNAT&#xff0c;通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发RIP和DIP应在同一个IP网络&#xff0c;且应使用私网地址:RS的网关要指向DIP请求报文和响应报文都必须经由Direclor转发&#xff0c;Direclor易于成为系统瓶…...

在 Spring Boot 中使用适配器模式实现支付网关的统一接口

引言 在许多电子商务系统中&#xff0c;集成多个支付网关是常见的需求。不同的支付网关有着不同的接口和实现细节。适配器模式可以帮助我们以一种灵活的方式实现这些不同的支付网关接口。 适配器模式简介 适配器模式将一个类的接口转换为客户期望的另一个接口。适配器模式使…...

【书生·浦语大模型实战营】第三期 入门岛作业

入门岛作业 Linux闯关任务&#xff1a;完成 SSH 连接与端口映射并运行 hello_world.py。配置vscode作业内容 可选任务1&#xff1a;将Linux基础命令在开发机上完成一遍作业内容 可选任务 2&#xff1a;使用 VSCODE 远程连接开发机并创建一个conda环境作业内容 可选任务 3&#…...

Redis的String类型常用命令总结

1. set 设置一个键的值。 set key value示例&#xff1a; set username "alice"2. get 获取一个键的值。 get key示例&#xff1a; get username3. getset 设置键的值&#xff0c;并返回键的旧值。 getset key value示例&#xff1a; getset username "…...

河南萌新联赛2024第(四)场:河南理工大学

A 思路&#xff1a; B 思路&#xff1a;有一种贪心的写法&#xff0c;将整个数组排序以后比较两个相邻数的同或值&#xff0c;取 m a x max max&#xff0c;不会证明 int th(int x, int y, int z) {int res 0;for (int i z - 1; i > 0; i --) {int dx (x >> i &…...

Linux中临时使用账号提权进行业务操作

普通账号提权 su&#xff1a;永久提权 Switching users with su sudo&#xff1a;临时提权 Running commands as root with sudo 1&#xff09;su切换账号 需要对方的密码 示例&#xff1a;切换到超级管理员 su - root 建议用-这个 su root 普通用户需要执行特殊指令&…...

lwip 3. 网线拔掉后 lwip_recvfrom不能返回

当网线被拔掉后&#xff0c;‌LWIP的lwip_recvfrom函数无法返回&#xff0c;‌这通常意味着网络连接已经断开&#xff0c;‌而LWIP没有自动检测到这种断开并进行相应的处理。具体卡在这个地方&#xff1a; ret xQueueReceive(mbox->mbx, &(*msg), portMAX_DELAY); //具…...

Linux环境安装Docker Engine

Docker是一个开源的应用容器引擎&#xff0c;由Go语言开发&#xff0c;基于Linux内核技术。Docker通过将应用及其依赖打包到可移植的容器中&#xff0c;实现了应用的快速部署和高效管理。Docker容器具有轻量级、快速启动、可移植性强等特点&#xff0c;能够显著提升资源利用率和…...

大厂面试题分享

大厂面试题分享 Redis持久化方式AOF优缺点RDB优缺点 如何保证Redis和Myql的一致性索引下推输入url到浏览器发生了什么ReentranLock底层原理SpringBoot 的启动流程 Redis持久化方式 Redis提供了两种主要的持久化机制&#xff0c;分别是AOF&#xff08;Append-Only File&#xf…...

FPGA面试问题整理

1. 逻辑设计中竞争与冒险概念&#xff0c;如何识别和消除&#xff1f; 竞争&#xff1a;在组合逻辑电路中&#xff0c;信号经过多条路径到达输出端&#xff0c;每条路径经过的逻辑门不同存在时差&#xff0c;在信号变化的瞬间存在先后顺序。这种现象叫竞争。 冒险&#xff1a;由…...

3Done学习笔记

一、基本操作 1、旋转视角 使用左下角立方体选择&#xff1b; 右键可以拖动视角&#xff1b; 中间滑轮按住拖动整个舞台界面。 2、平移和旋转 右键选择移动&#xff0c;有两种方式。 第一种选择起始点&#xff0c;按照起始点位置移动到终止点&#xff08;边、角、中心点…...

AI学习指南深度学习篇-卷积层详解

AI学习指南深度学习篇-卷积层详解 一、引言 随着人工智能技术的不断发展&#xff0c;深度学习作为人工智能领域的热门分支之一&#xff0c;正在逐渐成为各个领域的核心技术。而在深度学习中&#xff0c;卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN…...

2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第二弹 手搓机械臂

第一弹赛题的选择与前期方案的准备 opencv调用摄像头bug的解决 机械臂的组装 采用三个舵机&#xff0c;组成一个三自由度的机械臂。 并且利用电磁吸盘的方式&#xff0c;完成对棋子的抓取工作&#xff0c;后面的事实证明&#xff0c;在预算不足的情况下&#xff0c;队友手搓…...

如何在Java、C、Ruby语言中使用Newscatcher API

Newscatcher 世界实时新闻聚合API 一款强大的数据服务工具&#xff0c;它通过先进的网络爬虫技术&#xff0c;实时从全球超过70,000个新闻源聚合新闻内容。这个API能够提供全面、多角度的新闻报道&#xff0c;包括但不限于标题、作者、发布日期、全文内容以及媒体资源链接。它使…...

保姆级教程:在ROS2 Humble/Foxy的Gazebo中配置RGB-D相机(附解决点云颜色/坐标问题)

ROS2 Humble/Foxy中Gazebo深度相机仿真全攻略&#xff1a;从配置到点云问题解决在机器人仿真开发中&#xff0c;深度相机&#xff08;RGB-D&#xff09;是不可或缺的传感器之一。它能够同时提供彩色图像和深度信息&#xff0c;为SLAM、物体识别、避障等任务提供关键数据支持。本…...

【DeepSeek-R1代码相似度引擎解密】:3层语义比对机制、Token归一化偏差修正与Jaccard阈值黄金分割点

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;DeepSeek代码重复检测 DeepSeek-R1 模型在训练过程中引入了严格的代码去重机制&#xff0c;其核心目标是消除训练语料中语义等价或高度相似的代码片段&#xff0c;从而提升模型对真实编程模式的学习能力与泛化…...

Simulink中Repeating Sequence锯齿波显示恒为0解决方案

锯齿波设置如图1时&#xff0c;其示波器显示恒为0&#xff08;如图2&#xff09;。图1图2于是新建模型&#xff0c;只添加Repeating Sequence模块&#xff0c;采用原始设置发现可以正常输出锯齿波&#xff0c;于是调整时间参数&#xff0c;发现当时间设置为≥[0 0.06]时可以正常…...

新能源车轻量化为什么开始盯上高强镁合金?

续航&#xff0c;是悬在每一台纯电动汽车头上的达摩克利斯之剑。多充一度电、多堆一些正极材料&#xff0c;是一条路&#xff1b;但还有另一条路——把车造得更轻。 SAE&#xff08;美国汽车工程师学会&#xff09;的测算已经被反复引用&#xff1a;整车每减重100千克&#xff…...

FT231XQ USB串口桥接板设计解析与实战应用指南

1. 项目概述&#xff1a;从FT232R到FT231XQ的USB串口桥接板演进在嵌入式开发和硬件调试的日常工作中&#xff0c;一个可靠、小巧且功能清晰的USB转串口&#xff08;UART&#xff09;桥接板&#xff08;Breakout Board&#xff0c; 简称BoB&#xff09;几乎是工程师手边的标配工…...

电子商务设计师软考备战:特别篇 - 综合模拟与备考策略

1. 考试形式与内容结构1.1 考试基本信息考试科目与时间基础知识考试&#xff1a;上午9:00-11:30&#xff08;150分钟&#xff09;应用技术考试&#xff1a;下午2:00-4:30&#xff08;150分钟&#xff09;题型与分值分布上午考试&#xff08;基础知识&#xff09;&#xff1a; -…...

长期使用Token Plan套餐在项目开发中的成本观察

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 长期使用Token Plan套餐在项目开发中的成本观察 在AI驱动的项目开发中&#xff0c;成本控制与预算管理是团队负责人必须面对的现实…...

3分钟解锁网易云音乐NCM文件:ncmdumpGUI小白也能懂的完整教程

3分钟解锁网易云音乐NCM文件&#xff1a;ncmdumpGUI小白也能懂的完整教程 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换&#xff0c;Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经下载了网易云音乐的歌曲&a…...

1688运营培训/询盘成本从500元降到63.9!1688运营培训还原1688真实玩法

1688运营培训/询盘成本从500元降到63.9&#xff01;1688运营培训还原1688真实玩法500块钱一个询盘&#xff0c;你敢信&#xff1f;做1688运营培训这么多年&#xff0c;这个数字我都觉得离谱。前阵子遇到一个老板&#xff0c;一上来就开始吐槽1688&#xff0c;说1688就是个垃圾平…...

Adobe-GenP 3.0:轻松激活Adobe全家桶的完整指南

Adobe-GenP 3.0&#xff1a;轻松激活Adobe全家桶的完整指南 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP Adobe-GenP 3.0是一款专为Adobe Creative Cloud系列软件…...