Qt 模仿企业微信图标实现按钮图片文字上下结构

news2024/9/23 13:19:42

 简述

实现类似企业微信左侧导航栏的上下结构的按钮

效果图

可以用2种方案实现,2种最终效果图如下:

方案1 QToolButton 实现

	ui.toolButton->setFixedSize(50, 50);
	ui.toolButton->setCheckable(true);
	ui.toolButton->setAutoExclusive(true);
	ui.toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
	ui.toolButton_2->setFixedSize(50, 50);
	ui.toolButton_2->setCheckable(true);
	ui.toolButton_2->setAutoExclusive(true);
	ui.toolButton_2->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

	connect(ui.toolButton, &QToolButton::toggled, this, [=]() {
		ui.toolButton->setIcon(ui.toolButton->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
	});
	connect(ui.toolButton_2, &QToolButton::toggled, this, [=]() {
		ui.toolButton_2->setIcon(ui.toolButton_2->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
	});

qss

QToolButton
{
	border:none;
	background-color: rgba(255,255,255,0);
	color: #CADFFF;
}
QToolButton:hover
{
	border-radius:5px;
	background-color: rgba(255,255,255,15);
	color: #CADFFF;
}
QToolButton:checked
{
	border-radius:5px;
	background-color: rgba(255,255,255,20);
	color: #FFFFFF;
}
QToolButton:checked:hover
{ 
	background-color: rgba(255,255,255,30);
	color: #FFFFFF; 
}

用 QToolButton 实现有个按下效果,按下之后图标会往右偏一点点。

UI像素眼表示不服,重做!

方案2 继承 QPushButton 重写 paintEvent 实现

新建一个继承自QPushButton的子类 QUpdownButton

QUpdownButton.h 

#pragma once

#include <QPushButton>
#include "ui_QUpdownButton.h"

class QUpdownButton : public QPushButton
{
	Q_OBJECT
public:
	QUpdownButton(const QString &text, QString iconNormal, QString iconSelect, QWidget *parent = Q_NULLPTR);
	~QUpdownButton();
	void paintEvent(QPaintEvent *event);

private:
	Ui::QUpdownButton ui;
	QString m_text;
	QString m_iconNormal;
	QString m_iconSelect;
};

QUpdownButton.cpp

#include "QUpdownButton.h"
#include <QPainter>  
#include <QPixmap>  

QUpdownButton::QUpdownButton(const QString &text, QString iconNormal, QString iconSelect, QWidget *parent)
	: QPushButton(parent),
	m_text(text)
	, m_iconNormal(iconNormal)
	, m_iconSelect(iconSelect)
{
	ui.setupUi(this);
	setFixedSize(50, 50);
	setText(text);
	setStyleSheet(QString::fromLocal8Bit("\
QPushButton{ border-radius:6px; background-color: rgba(255,255,255,0); color: #CADFFF; font: 9pt \"微软雅黑\"; text-align: bottom; padding-bottom: 6px; }\
QPushButton:hover{ background-color: rgba(255,255,255,15); color: #CADFFF; }\
QPushButton:pressed{ background-color: rgba(255,255,255,20); color: #CADFFF; }\
QPushButton:checked{ background-color: rgba(255,255,255,20); color: #FFFFFF; }\
QPushButton:checked:hover{ background-color: rgba(255,255,255,30); color: #FFFFFF; }\
		"));
}

QUpdownButton::~QUpdownButton()
{
}

void QUpdownButton::paintEvent(QPaintEvent *event)
{
	QPushButton::paintEvent(event); // 调用基类的 paintEvent  

	QPainter painter(this);
	QRect buttonRect = this->rect();

	// 加载图片  
	QString btIcon = this->isChecked() ? m_iconSelect : m_iconNormal;
	QPixmap pixmap(btIcon);

	// 图标区域高度占按钮高度的2/3,文字占1/3  
	int iconAreaHeight = buttonRect.height() - (buttonRect.height() / 3); 

	// 按钮图标尺寸20*20 
	int newWidth = 20;
	int newHeight = 20;

	// 计算图标位置  
	int x = (buttonRect.width() - newWidth) / 2;
	int y = (iconAreaHeight - newHeight) / 2;

	// 绘制缩放后的图片  
	QPixmap scaledPixmap = pixmap.scaled(newWidth, newHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	painter.drawPixmap(x, y, scaledPixmap);

	// 绘制文字  
	//QString text = this->text();
	//QRect textRect = QRect(0, scaledHeight-RATIO_X(6), buttonRect.width(), buttonRect.height() - scaledHeight);
	//painter.drawText(textRect, Qt::AlignCenter, m_text);
}

使用:

	ui.toolButton->setFixedSize(50, 50);
	ui.toolButton->setCheckable(true);
	ui.toolButton->setAutoExclusive(true);
	ui.toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
	ui.toolButton_2->setFixedSize(50, 50);
	ui.toolButton_2->setCheckable(true);
	ui.toolButton_2->setAutoExclusive(true);
	ui.toolButton_2->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

	connect(ui.toolButton, &QToolButton::toggled, this, [=]() {
		ui.toolButton->setIcon(ui.toolButton->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
	});
	connect(ui.toolButton_2, &QToolButton::toggled, this, [=]() {
		ui.toolButton_2->setIcon(ui.toolButton_2->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
	});

	m_updownButton = new QUpdownButton(QString::fromLocal8Bit("应用"), QString(":/pafeyDemo/Resources/bar/nav_app_normal.png"), QString(":/pafeyDemo/Resources/bar/nav_app_select.png"));
	m_updownButton2 = new QUpdownButton(QString::fromLocal8Bit("应用2"), QString(":/pafeyDemo/Resources/bar/nav_app_normal.png"), QString(":/pafeyDemo/Resources/bar/nav_app_select.png"));
	ui.verticalLayout_2->insertWidget(2, m_updownButton);
	ui.verticalLayout_2->insertWidget(3, m_updownButton2);
	m_updownButton->setCheckable(true);
	m_updownButton->setAutoExclusive(true);
	m_updownButton2->setCheckable(true);
	m_updownButton2->setAutoExclusive(true);

最终效果如下: 

第1,2图标是QToolButton,第3,4图标是重写 paintEvent 的 QPushButton 子类

第2种方案实现效果,图标的位置不会动了。

完工。

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

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

相关文章

电源测试设备功能篇:测试仪器的灵活兼容与扩展

依托ATECLOUD智能云测试平台打造的电源ate自动测试设备&#xff0c;相较于传统的自动化测试系统&#xff0c;其突出特点在于提供了灵活的系统操作。这种操作灵活性不仅表现在自动化测试的便捷性、报告模板的多样化以及数据分析的灵活性上&#xff0c;还表现在电源测试仪器设备配…

覃嘉仪,艺人经纪人、经纪人、影视经纪人。2002.7.9出生于四川省遂宁市射洪县

覃嘉仪&#xff0c;艺人经纪人、经纪人、影视经纪人。2002.7.9出生于四川省遂宁市射洪县 2020年开始从事宣传工作&#xff0c;2023成为“WP经纪工作室”艺人经纪&#xff0c;现担任孙亦欣、魏逸熙等艺人的经纪人。 2024年涉足于影视行业&#xff0c;并加入嘉林娱乐。2024年在由…

部标JT808标准下的视频汇聚新方案:EasyCVR平台助力推动车辆监管智能化进程

在数字化转型的浪潮中&#xff0c;智慧城市的建设正以前所未有的速度推进&#xff0c;而市政车载设备作为城市运行的重要“神经末梢”&#xff0c;其智能化、联网化水平直接影响着城市管理效率与服务质量。近年来&#xff0c;随着部标协议&#xff08;即国家行业标准协议&#…

Python学习日志(3)—— 运行

通过python文档辅助学习&#xff0c;规范代码 python文档&#xff1a;3.12.5 Documentation (python.org) 1、python版本之间的差异&#xff1a;新的特性和变化、弃用和新增 2、标准库参考&#xff08;宝典&#xff0c;用于查询&#xff09; 3、语法参考 python程序是解释型…

记录工作时的一些错误

1、mobaxterm问题&#xff1a; 解决方案&#xff1a;找不到mottynew.exe 2、虚拟机安装centos7进入不了引导页面 解决方案&#xff1a;检查镜像 虚拟机 192.168.40.128 root/Root yxr/y123x123r123 解决方案&#xff1a; 问题&#xff1a;docker run不起来容器&#xff0c;显…

HTTP 状态码全攻略:快速搞懂服务器的“暗号”

文章目录 HTTP 状态码全攻略&#xff1a;快速搞懂服务器的“暗号”1xx&#xff1a;打个招呼&#xff0c;信息来了 (Informational Responses)2xx&#xff1a;事情办成了&#xff01; (Successful Responses)3xx&#xff1a;走这边&#xff0c;换个地方吧 (Redirection Response…

音视频——RTSP流媒体传输技术介绍及抓包解析

流式传输 流媒体技术&#xff1a;将声音影像向用户计算机 连续、不间断的进行传送&#xff0c;延时小。 抓包 route add 添加到指定网络的路由规则 route add [-net|-host] [网域或主机] netmask [mask] [gw|dev] route del [-net|-host] [网域或主机] netmask [mask] [gw|dev…

第9章 使用ContentProvider实现数据共享

第9章 使用ContentProvider实现数据共享 本章要点 理解ContentProvider的功能与意义ContentProvider类的作用和常用方法Uri 对 ContentProvider的作用理解ContentProvider与ContentResolver的关系实现自己的ContentProvider配置ContentProvider使用ContentResolver操作数据操…

宝藏!《联盟自控基础班筑基题库》(凤凰篇) 1-8章:甄选部分

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;初试《自控基础班筑基题库》(凤凰篇)。 Part1&#xff1a;资料封面&目录 Part2&#xff1a;资料各个章节具体内容 第1章 自动控制的基本概念 第2章 控制系统的数学模型 第3章 控制系统的时域分析 第4章 根轨迹法…

某东东的jdgs算法分析--适合进阶学习

某东东的jdgs算法分析 这个贴主要还是对算法本身结构部分描述会多点&#xff0c;憋问&#xff0c;问就是过去太久了&#xff0c;很多逆向过程不一定能还原&#xff08;主要是懒&#xff0c;不想原路再走一遍&#xff09;&#xff0c;所以可能有部分跳跃的内容&#xff0c;会给具…

【网络安全】IDOR之敏感数据泄露

未经许可,不得转载。 文章目录 正文正文 在测试“添加到收藏夹”功能时,我拦截了发送到服务器的请求,请求体如下: {“uriTemplate”:“asset/{assetId}/favorite”,“version”:“v2”,“type”:“POST”,“req_service”:“pict”,“url”:“asset/VICTIMS_ASS…

【论文阅读】DivTheft: An Ensemble Model Stealing Attack by Divide-and-Conquer(2023)

摘要 Recently, model stealing attacks(模型窃取攻击) are widely studied(广泛研究) but most of them are focused on stealing a single non-discrete model(窃取单个非离散模型), e.g., neural networks(神经网络). For ensemble models(对于集成模型), these …

分钟快速搭建分班查询系统,支持查班级群二维码

新学期已经开始了&#xff0c;老师们又要忙活起来了。但是&#xff0c;别担心&#xff0c;现在有个超方便的工具&#xff0c;能帮大家快速搞定分班的事情&#xff0c;还能让家长们一键加入班级群&#xff0c;省时又省力&#xff01; 以前分班可麻烦了&#xff0c;老师们得一个…

集群的调度和策略

集群的调度&#xff1a; 怎么把pod部署到节点的方法。 调度的过程&#xff1a; scheduler是集群的调度器&#xff0c;主要任务就是把pod部署到节点上。 自动调度&#xff1a; 1、公平&#xff0c;保证每个可用的节点都可以部署pod 2、资源的高效利用&#xff0c;集群当中…

C/C++内存详解

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 C/C内存模型C语言动态内存管理mallocrealloccallocfree C动态内存申请new 操作符delete 操作符注意事项用法示例 operator new和operator delete函数内存泄露 C/C内存模型 让我们先来看看这段代码&a…

四、SPI——2、NOR FLASH

一、NOR FLASH介绍 FLASH是常用的用于储存数据的半导体器件&#xff0c;它具有容量大&#xff0c;可重复擦写、按“扇区/块”擦除、掉电后数据可继续保存的特性。 FLASH是有一个物理特性&#xff1a;只能写0&#xff0c;不能写1&#xff0c;写1靠擦除。 FLASH主要有NOR Flash和…

【JavaEE初阶】JVM内存划分和类加载过程以及垃圾回收

目录 &#x1f332;内存划分 &#x1f6a9;堆&#xff08;线程共享&#xff09; &#x1f6a9;栈 &#x1f6a9;元数据区 &#x1f343;类加载过程 &#x1f6a9;双亲委派模型 &#x1f384;垃圾回收机制&#xff08;GC&#xff09; &#x1f6a9;找到谁是垃圾(不被继续…

纷享销客CRM渠道分销之多维度数据分析介绍

预设渠道报表驾驶舱 基于渠道分销场景&#xff0c;系统预设了一个全面的渠道订货数据驾驶舱&#xff0c;旨在通过直观的数据分析&#xff0c;为企业提供深度的市场洞察和业务决策支持。该驾驶舱提供渠道订货的概览&#xff0c;快速把握整体订货动态。 渠道订货波动分析&#…

Scratch 角色绘制

引言 在Scratch这款强大的可视化编程环境中&#xff0c;不仅可以通过编程来实现各种有趣的互动项目&#xff0c;还能利用内置的绘图编辑器来创造独一无二的角色。本文将引导你如何使用Scratch中的绘图编辑器&#xff0c;绘制出属于你自己的简单图形角色。 准备工作 首先&#…

【数据分享】2000—2023年我国250米分辨率逐月植被覆盖度(FVC)栅格数据

植被覆盖度&#xff08;Fractional Vegetation Cover&#xff0c;简称FVC&#xff09;是指植被&#xff08;包括叶、枝、茎&#xff09;在水平地面的垂直投影面积占研究区总面积的百分比。植被覆盖度是生态学、地理学、气候学等多个学科研究的基础数据&#xff0c;对于理解生态…