1 #pragma once
2 #include <QToolButton>
3 #include <QBoxLayout>
4 #include <QLabel>
5
6 /* 基于QToolButton封装,解决Icon不能设置hover和press态的问题
7 QSS使用方法:
8 qproperty-dpiAdaptionImage: url(:/img/res/imgmainframe/icon_exit_presentation.png);
9 qproperty-iconSize: 18px 18px;
10 qproperty-buttonStyle:3; 对应ToolButtonStyle的枚举值,默认为2(左右)
11 qproperty-space:16; icon和文字的间隔,默认是8
12 */
13 class CenteredToolButtonStyle;
14 class IconTextButton : public QToolButton {
15 Q_OBJECT
16 Q_PROPERTY(QString dpiAdaptionImage READ getDpiAdaptionImage WRITE setDpiAdaptionImage)
17 Q_PROPERTY(QString buttonType READ getButtonTypeFromQss WRITE setButtonTypeFromQss)
18 Q_PROPERTY(QString buttonStyle READ getToolButtonStyleFromQss WRITE setToolButtonStyleFromQss)
19 Q_PROPERTY(QString space READ getSpaceFromQss WRITE setSpaceFromQss)
20
21 enum class ImageType
22 {
23 THREE_STATUS = 3, //三态图片
24 FOUR_STATUS = 4, //四态图片
25 };
26
27 enum class ButtonStatus
28 {
29 NORMAL = 0, //正常
30 HOVER = 1, //悬浮
31 PRESS = 2, //按下
32 DISABLE = 3, //禁用态
33 };
34
35 public:
36 IconTextButton(QWidget* parent = nullptr, ImageType type = ImageType::THREE_STATUS);
37 IconTextButton(const QString& text, QWidget* parent = nullptr, ImageType type = ImageType::THREE_STATUS);
38
39 protected:
40 QString getDpiAdaptionImage();
41 void setDpiAdaptionImage(const QString& strIconPath);
42 void setButtonTypeFromQss(const QString& strType);
43 QString getButtonTypeFromQss();
44 void setToolButtonStyleFromQss(const QString& strStyle);
45 QString getToolButtonStyleFromQss();
46 void setSpaceFromQss(const QString& strStyle);
47 QString getSpaceFromQss();
48
49 virtual void leaveEvent(QEvent* event) override;
50 virtual void enterEvent(QEvent* event) override;
51 virtual void mousePressEvent(QMouseEvent* event) override;
52 virtual void mouseReleaseEvent(QMouseEvent* event) override;
53 virtual void paintEvent(QPaintEvent* event) override;
54 virtual void showEvent(QShowEvent* event) override;
55
56 private:
57 bool m_bLeftPress = false;
58 ButtonStatus m_btnStatus = ButtonStatus::NORMAL;
59 ImageType m_ImageType = ImageType::THREE_STATUS;
60 int m_nImageWidth = 0;
61 int m_nImageHeight = 0;
62 QString m_strImagePath;
63 QPixmap m_pixmap;
64 Qt::ToolButtonStyle m_ToolButtonStyle = Qt::ToolButtonTextBesideIcon;
65 CenteredToolButtonStyle* m_pCenteredToolButtonStyle = nullptr;
66 int m_nSpace = 8;
67 };

.cpp

#include "IconTextButton.h"
#include "qevent.h"
#include "CenteredToolButtonStyle.h" IconTextButton::IconTextButton(QWidget* parent /*= nullptr*/, ImageType type /*= IconPicType::THREE_STATUS*/)
: IconTextButton("", parent, type) {
} IconTextButton::IconTextButton(const QString& text, QWidget* parent /*= nullptr*/,
ImageType type /*= IconPicType::THREE_STATUS*/)
: QToolButton(parent)
, m_ImageType(type) {
setText(text);
setToolButtonStyle(m_ToolButtonStyle);
} void IconTextButton::setDpiAdaptionImage(const QString& strIconPath)
{
if (0 == strIconPath.compare(m_strImagePath)) {
return;
} m_strImagePath = strIconPath;
m_pixmap.load(m_strImagePath);
m_nImageWidth = m_pixmap.width() / static_cast<int>(m_ImageType);
m_nImageHeight = m_pixmap.height(); int nSub = static_cast<int>(m_btnStatus);
QPixmap iconPixmap = m_pixmap.copy(m_nImageWidth * nSub, 0, m_nImageWidth, m_nImageHeight)
.scaled(iconSize().width(), iconSize().height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
setIcon(iconPixmap);
} void IconTextButton::setButtonTypeFromQss(const QString& strType)
{
m_ImageType = static_cast<ImageType>(strType.toInt());
} QString IconTextButton::getDpiAdaptionImage()
{
return m_strImagePath;
} QString IconTextButton::getButtonTypeFromQss()
{
return QString("%1").arg(static_cast<int>(m_ImageType));
} void IconTextButton::setToolButtonStyleFromQss(const QString& strStyle) {
m_ToolButtonStyle = static_cast<Qt::ToolButtonStyle>(strStyle.toInt());
setToolButtonStyle(m_ToolButtonStyle);
} QString IconTextButton::getToolButtonStyleFromQss() {
return QString("%1").arg(static_cast<int>(m_ToolButtonStyle));
} void IconTextButton::setSpaceFromQss(const QString& strStyle) {
m_nSpace = strStyle.toInt();
} QString IconTextButton::getSpaceFromQss() {
return QString("%1").arg(static_cast<int>(m_nSpace));
} void IconTextButton::leaveEvent(QEvent* event)
{
__super::leaveEvent(event);
m_btnStatus = ButtonStatus::NORMAL;
} void IconTextButton::enterEvent(QEvent* event)
{
__super::enterEvent(event);
m_btnStatus = ButtonStatus::HOVER;
} void IconTextButton::mousePressEvent(QMouseEvent* event)
{
__super::mousePressEvent(event);
if (event->button() == Qt::LeftButton)
{
m_bLeftPress = true;
m_btnStatus = ButtonStatus::PRESS;
}
} void IconTextButton::mouseReleaseEvent(QMouseEvent* event)
{
__super::mouseReleaseEvent(event);
if (m_bLeftPress)
{
m_bLeftPress = false;
m_btnStatus = ButtonStatus::NORMAL;
}
} void IconTextButton::paintEvent(QPaintEvent* event) {
__super::paintEvent(event); ButtonStatus status = m_btnStatus;
if (isChecked()) {
status = ButtonStatus::PRESS;
} if (!isEnabled()) {
status = ButtonStatus::DISABLE;
} int nSub = static_cast<int>(status);
QPixmap iconPixmap =
m_pixmap.copy(m_nImageWidth * nSub, 0, m_nImageWidth, m_nImageHeight)
.scaled(iconSize().width(), iconSize().height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
setIcon(iconPixmap); // 自定义样式用于居中
if (m_ToolButtonStyle == Qt::ToolButtonTextBesideIcon || m_ToolButtonStyle == Qt::ToolButtonTextUnderIcon) {
if (m_pCenteredToolButtonStyle == nullptr) {
m_pCenteredToolButtonStyle = new CenteredToolButtonStyle(this, m_ToolButtonStyle, iconSize(), m_nSpace);
setStyle(m_pCenteredToolButtonStyle);
}
}
} void IconTextButton::showEvent(QShowEvent* event)
{
QToolButton::showEvent(event);
m_btnStatus = ButtonStatus::NORMAL;
update();
}

自定义居中样式:

.h

#pragma once

#include <QProxyStyle>
#include <QToolButton> class CenteredToolButtonStyle : public QProxyStyle
{
Q_OBJECT public:
CenteredToolButtonStyle(QToolButton* parent, Qt::ToolButtonStyle buttonStyle, const QSize& sIcon, const int& space); virtual void drawItemPixmap(QPainter* painter, const QRect& rect, int, const QPixmap& pixmap) const override;
virtual void drawItemText(QPainter* painter, const QRect& rect, int flags, const QPalette& pal, bool enabled,
const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const override;
void Draw(QPainter* painter) const; private:
const QToolButton* m_pParent = nullptr;
const QSize m_iconSize;
mutable QString m_text;
mutable QPixmap m_pixMap;
mutable QRect m_rect;
mutable int m_nFlag = 0;
mutable int m_ny = -1;
mutable int m_nx = 1;
mutable bool m_bEnabled = true;
mutable QPalette m_palette;
mutable QPalette::ColorRole m_textRole = QPalette::NoRole;
bool m_bDrawFinished = false;
Qt::ToolButtonStyle m_buttonStyle = Qt::ToolButtonTextBesideIcon;
int m_nSpace = 8;
};

.cpp

#include "CenteredToolButtonStyle.h"
namespace {
constexpr auto SPACE = 6;
} CenteredToolButtonStyle::CenteredToolButtonStyle(QToolButton* parent, Qt::ToolButtonStyle buttonStyle,
const QSize& sIcon, const int& space)
: QProxyStyle(),
m_pParent(parent),
m_iconSize(sIcon),
m_buttonStyle(buttonStyle),
m_nSpace(space)
{
if (parent != nullptr) {
setParent(parent);
}
} void CenteredToolButtonStyle::drawItemPixmap(QPainter* painter, const QRect& rect, int, const QPixmap& pixmap) const {
m_pixMap = pixmap;
m_ny = rect.y();
m_nx = rect.x();
Draw(painter);
} void CenteredToolButtonStyle::drawItemText(QPainter* painter, const QRect& rect, int flags, const QPalette& pal,
bool enabled, const QString& text,
QPalette::ColorRole textRole /* = QPalette::NoRole*/) const {
m_text = text;
m_rect = rect;
m_nFlag = flags | Qt::AlignCenter;
m_bEnabled = enabled;
m_palette = pal;
m_textRole = textRole;
Draw(painter);
} void CenteredToolButtonStyle::Draw(QPainter* painter) const {
if (m_pParent == nullptr) {
return;
} if (m_buttonStyle == Qt::ToolButtonTextUnderIcon) {
if (m_nx >= 0) {
if (m_rect.x() != m_nx)
return;
auto iconRect = m_rect;
m_nx = 0;
iconRect.adjust(0, -m_iconSize.height() - m_nSpace, 0,
-itemTextRect(m_pParent->fontMetrics(), m_rect, m_nFlag, m_bEnabled, m_text).height());
QProxyStyle::drawItemPixmap(painter, iconRect, Qt::AlignCenter, m_pixMap);
}
} else if (m_buttonStyle == Qt::ToolButtonTextBesideIcon) {
if (m_ny >= 0) {
if (m_rect.y() != m_ny)
return;
auto iconRect = m_rect;
m_ny = 0;
iconRect.adjust(-m_iconSize.width() - m_nSpace, 0,
-itemTextRect(m_pParent->fontMetrics(), m_rect, m_nFlag, m_bEnabled, m_text).width(), 0);
QProxyStyle::drawItemPixmap(painter, iconRect, Qt::AlignCenter, m_pixMap);
}
} QProxyStyle::drawItemText(painter, m_rect, m_nFlag, m_palette, m_bEnabled, m_text, m_textRole);
}

基于QToolButton封装,解决Icon不能设置hover和press态的问题的更多相关文章

  1. 未能将基于用户的Visual C++项目设置保存到user文件错误的解决

    作者:朱金灿 来源:http://blog.csdn.net/clever101 最近遇见一个诡异错误,将Win7家庭版升级到Win7旗舰版.然后使用原来安装的VS2008开发,保存工程时总是出现未能 ...

  2. 基于jQuery封装的分页组件

    前言: 由于项目需要实现分页效果,上jQuery插件库找了下,但是木有找到自己想要的效果,于是自己封装了个分页组件. 思路: 主要是初始化时基于原型建立的分页模板然后绑定动态事件并实现刷新DOM的分页 ...

  3. iOS lanchImage 和icon的设置

    1 icon的设置 打开项目中的Assets.xcassets   这里边有一个icon 首先需要有icon 的尺寸 尺寸如下: 29*29   2x 29*29   3x 40*40  2x 40* ...

  4. 基于AFN封装的带缓存的网络请求

    给大家分享一个基于AFN封装的网络请求 git: https://github.com/zhouxihi/NVNetworking #带缓存机制的网络请求 各类请求有分带缓存 , 不带缓存, 可自定义 ...

  5. 基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件

    目录 1. 前言 2. 关于vue-simple-uploader 3. 基于vue-simple-uploader封装全局上传组件 4. 文件上传流程概览 5. 文件分片 6. MD5的计算过程 7 ...

  6. 基于epoll封装的事件回调miniserver

    epoll技术前两节已经阐述过了,目前主要做一下封装,很多epoll的服务器都是采用事件回调方式处理, 其实并没有什么复杂的,我慢慢给大家阐述下原理. 在networking.h和networking ...

  7. vue可视化图表 基于Echarts封装好的v-charts简介

    **vue可视化图表 基于Echarts封装好的v-charts** 近期公司又一个新的需求,要做一个订单和销售额统计的项目,需要用到可视化图表来更直观的展示数据.首先我想到的是Echarts,众所周 ...

  8. 基于better-scroll封装一个上拉加载下拉刷新组件

    1.起因 上拉加载和下拉刷新在移动端项目中是很常见的需求,遂自己便基于better-scroll封装了一个下拉刷新上拉加载组件. 2.过程 better-scroll是目前比较好用的开源滚动库,提供很 ...

  9. 基于layui,Jquery 表格动态编辑 设置 编辑值为 int 或者 double 类型及默认值

    首先先推荐大家在看这篇笔记时,阅读过我写的这篇 Layui表格编辑[不依赖Layui的动态table加载] 阅读过上面那篇笔记之后呢,才能更好的理解我现在所要说的这个东西 接下来废话不多说,上代码. ...

  10. 基于 React 封装的高德地图组件,帮助你轻松的接入地图到 React 项目中。

    react-amap 这是一个基于 React 封装的高德地图组件,帮助你轻松的接入地图到 React 项目中. 文档实例预览: Github Web | Gitee Web 特性 ️ 自动加载高德地 ...

随机推荐

  1. 如何实现nvidia显卡的cuda的多kernel并发执行???

    相关: CPU端多进程/多线程调用CUDA是否可以加速??? 参考: <CUDA C 编程指南>导读 https://developer.nvidia.com/blog/gpu-pro-t ...

  2. 前端黑科技:使用 JavaScript 实现网页扫码功能

    在数字化时代,二维码已经渗透到我们生活的方方面面.从移动支付到产品溯源,二维码凭借其便捷性和高效性,成为了信息传递的重要载体.而随着前端技术的不断发展,我们甚至可以使用 JavaScript 在网页端 ...

  3. Linux内核如何判断地址是否位于用户空间?

    一. 问题描述 access_ok函数是什么原理? 二.问题分析 我们在内核空间和用户空间进行数据拷贝的时候必须判断用户空间地址是否合法. 主要通过偶函数access_ok来判断. 1. Linux用 ...

  4. Fluent Editor:一个基于 Quill 2.0 的富文本编辑器,功能强大、开箱即用!

    你好,我是 Kagol,个人公众号:前端开源星球. 今年4月份,听到 Quill 2.0 正式发布的消息,我心情非常激动,立马体验了下,并写了一篇文章. 重回铁王座!时隔5年!Quill 2.0 终于 ...

  5. Linux离线安装Tomcat

    系统环境: centos7.3.1611 openjdk version "1.8.0_102" apache-tomcat-9.0.36.tar.gz tomcat 安装 #链接 ...

  6. zabbix4.0配置短信报警

    1.准备工作 #访问短信网址:172.16.98.1,网线插LAN口 #账号&密码:admin 安装ubuntu系统模拟http请求工具(命令行模式) # apt-get install ht ...

  7. java_父类子类

    private 只有自身能访问自身 自身 同包子 不同包子类 同包类 其他类 可以访问 不能继承 不能继承 不能访问 不能访问 package/friendly/default == 不写 自身 同包 ...

  8. 配置 Windows Boot Manager

    配置 Windows Boot Manager 通常需要使用 bcdedit 命令,这是一个命令行工具,用于管理 Boot Configuration Data (BCD) 存储.BCD 存储包含了启 ...

  9. WebShell流量特征检测_蚁剑篇

    80后用菜刀,90后用蚁剑,95后用冰蝎和哥斯拉,以phpshell连接为例,本文主要是对这四款经典的webshell管理工具进行流量分析和检测. 什么是一句话木马? 1.定义 顾名思义就是执行恶意指 ...

  10. Redis 高可用方案原理初探

    redis 参考目录: 生产级Redis 高并发分布式锁实战1:高并发分布式锁如何实现 https://www.cnblogs.com/yizhiamumu/p/16556153.html 生产级Re ...