Qt 自定义控件-支持换行和点击事件的Label

news2024/12/24 20:45:14

目录

    • 前言
    • 1、功能描述
    • 2、代码实现
      • 2.1 头文件
      • 2.2 源码文件
      • 2.3 设计思路
    • 3、示例
    • 4、总结

前言

本文主要介绍一个自定义控件,支持换行和点击事件的Label。起因是有这样一个需求,在一个复杂系统中有一个页面可以显示该系统中所有设备的名字,并且点击名字可以进入设备详情页。软件最初用QPushButton显示设备名字,但因为大部分设备的名字比较长,可显示的文字又太少,因此产品经理提出希望设备名称可以换行显示。于是有了本文介绍的这个自定义控件。

1、功能描述

QPushButton作为按钮,其基本功能是支持点击事件,支持设置按钮标题,支持设置按钮图标。参照QPushButton的基本功能,本自定义控件也实现了点击事件通知,设置图标,设置文本的功能,除此之外,本控件还支持设置是否换行。

2、代码实现

2.1 头文件

#ifndef ZCLICKABLELABEL_H
#define ZCLICKABLELABEL_H

#include <QLabel>
#include <QIcon>
#include <QHBoxLayout>

class  ZClickableLabel : public QWidget
{
    Q_OBJECT
public:
    explicit ZClickableLabel(QWidget *parent = NULL);

    /**
     * @brief setIcon 设置图标
     * @param icon  图标
     */
    void setIcon(const QIcon &icon);

    /**
     * @brief setText 设置文本
     * @param text  文本内容
     * @param wordWrap 是否换行
     */
    void setText(const QString &text, bool wordWrap = true);

    /**
     * @brief text 获取文本内容
     * @return
     */
    QString text() const;

signals:
    /**
     * @brief clicked 点击事件信号
     */
    void clicked();

protected:
    void mousePressEvent(QMouseEvent *ev) override;
private:
    QLabel *m_pIconLabel;
    QLabel *m_pTextLabel;
    QHBoxLayout *m_pHlayout;
};


#endif // ZCLICKABLELABEL_H

2.2 源码文件

#include <QPaintEvent>
#include <QPainter>

#include <QSpacerItem>
#include <QtDebug>

#include "zclickablelabel.h"

static const int iconWidth = 14;
static const int iconHeight = 14;

ZClickableLabel::ZClickableLabel(QWidget *parent)
    : QWidget(parent)
    , m_pIconLabel(NULL)
    , m_pTextLabel(NULL)
    , m_pHlayout(NULL)
{
    setObjectName("ZClickableLabel");
    m_pTextLabel = new QLabel(this);
    m_pTextLabel->setAlignment(Qt::AlignTop|Qt::AlignLeft);
    m_pHlayout = new QHBoxLayout;
    m_pHlayout->addWidget(m_pTextLabel);
    setLayout(m_pHlayout);
}

void ZClickableLabel::setIcon(const QIcon &icon)
{
    if(!m_pIconLabel)
    {
        m_pIconLabel = new QLabel(this);
    }
    m_pIconLabel->setPixmap(icon.pixmap(iconWidth,iconHeight));
    m_pIconLabel->setMaximumWidth(iconWidth);
    m_pIconLabel->setMaximumHeight(iconHeight);
    m_pIconLabel->setAlignment(Qt::AlignTop);
    m_pHlayout->insertWidget(0, m_pIconLabel);
}

void ZClickableLabel::setText(const QString &text, bool wordWrap)
{
    m_pTextLabel->setWordWrap(wordWrap);
    QFontMetrics fm(m_pTextLabel->font());
    int labelWidth = m_pTextLabel->rect().width();
    if(fm.width(text) > labelWidth)
    {
        double lines = m_pTextLabel->rect().height() / fm.height();
        m_pTextLabel->setText(fm.elidedText(text, Qt::ElideRight, labelWidth * lines, Qt::TextWordWrap));
    }
    else
    {
        m_pTextLabel->setText(text);
    }
}

QString ZClickableLabel::text() const
{
    return m_pTextLabel->text();
}

void ZClickableLabel::mousePressEvent(QMouseEvent *ev)
{
    Q_UNUSED(ev)
    emit clicked();
}

2.3 设计思路

该控件继承自QWidget,在QWidget内部有两个QLabel组件和一个水平布局控件,其中m_pIconLabel为图标显示控件,m_pTextLabel为文本内容显示控件。通过重载void mousePressEvent(QMouseEvent *ev)函数,本控件实现了点击事件的获取,并将点击事件通过信号 clicked() 抛给外界使用者。
为了当文本过长显示不下时在末尾显示省略号,在setText函数中,根据控件尺寸动态计算带省略号的文本长度,代码如下:

	QFontMetrics fm(m_pTextLabel->font());
    int labelWidth = m_pTextLabel->rect().width();
    if(fm.width(text) > labelWidth)
    {
        double lines = m_pTextLabel->rect().height() / fm.height();
        m_pTextLabel->setText(fm.elidedText(text, Qt::ElideRight, labelWidth * lines, Qt::TextWordWrap));
    }
    else
    {
        m_pTextLabel->setText(text);
    }

如果用户设置了icon,就把m_pIconLabel 添加到控件布局m_pHlayout 上,否则不添加。这一点是在函数setIcon中实现的。

	m_pIconLabel->setPixmap(icon.pixmap(iconWidth,iconHeight));
    m_pIconLabel->setMaximumWidth(iconWidth);
    m_pIconLabel->setMaximumHeight(iconHeight);
    m_pIconLabel->setAlignment(Qt::AlignTop);
    m_pHlayout->insertWidget(0, m_pIconLabel);

3、示例

将ZClickableLabel的头文件和源码文件复制到工程目录下,并添加到测试工程中,然后在MainWindow.ui文件中添加测试控件,并将click_lb1和click_lb2两个QWidget提升为ZClickableLabel,如下图所示:
在这里插入图片描述
在MainWindow.cpp中实现测试代码:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
      , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    ui->click_lb1->setText("白日依山尽,");
    ui->click_lb2->setText("黄河入海流!");

    ui->click_lb1->setIcon(QIcon(":/resources/icon_redTip.png"));
    ui->click_lb2->setIcon(QIcon(":/resources/icon_tip.png"));

    connect(ui->click_lb1, SIGNAL(clicked()), this, SLOT(slot_labelClicked()));
    connect(ui->click_lb2, SIGNAL(clicked()), this, SLOT(slot_labelClicked()));
}

void MainWindow::slot_labelClicked()
{
    ZClickableLabel *pLabel = qobject_cast<ZClickableLabel*>(sender());
    if(pLabel)
    {
        QMessageBox::information(this, "提示", pLabel->text());
    }
}

编译运行程序,查看效果

在这里插入图片描述

点击自定义控件弹出对话框:
在这里插入图片描述

4、总结

这种自定义控件不难,你学会了吗?以上就是本文的所有内容了,欢迎留言讨论,下一篇再见!

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

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

相关文章

RSA 2048位算法的主要参数N,E,P,Q,DP,DQ,Qinv,D分别是什么意思 哪个是通常所说的公钥与私钥 -安全行业基础篇5

非对称加密算法RSA 在RSA 2048位算法中&#xff0c;常见的参数N、E、P、Q、DP、DQ、Qinv和D代表以下含义&#xff1a; N&#xff08;Modulus&#xff09;&#xff1a;模数&#xff0c;是两个大素数P和Q的乘积。N的长度决定了RSA算法的安全性。 E&#xff08;Public Exponent&a…

基于SSM的小区物业管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

获取请求IP以及IP解析成省份

某些业务需要获取请求IP以及将IP解析成省份之类的&#xff0c;于是我写了一个工具类&#xff0c;可以直接COPY /*** IP工具类* author xxl* since 2023/11/9*/ Slf4j public class IPUtils {/*** 过滤本地地址*/public static final String LOCAL_ADDRESS "127.0.0.1&quo…

基于SSM的演唱会购票系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue、HTML 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是…

Langchain-Chatchat实践详解

简介 本质上是在Langchain基础上封装的一层聊天服务&#xff0c;可以对接底层多种离线LLM和在线的LLM&#xff08;也可以对接自定义的在线LLM&#xff09;。提供基于知识库聊天功能相关的一系列API。 下载源码 源码地址&#xff1a; https://github.com/chatchat-space/Lang…

Apache Druid连接回收引发的血案

问题 线上执行大批量定时任务&#xff0c;发现SQL执行失败的报错&#xff1a; CommunicationsException, druid version 1.1.10, jdbcUrl : jdbc:mysql://xxx?useUnicodetrue&characterEncodingUTF-8&zeroDateTimeBehaviorconvertToNull,testWhileIdle true, idle …

《向经典致敬》第二届粤港澳大湾区著名歌唱家音乐会完美落幕

百年经典 歌坛盛会 “《向经典致敬》第二届粤港澳大湾区著名歌唱家音乐会暨2023福田人才之夜”完美落幕 2023年11月4日&#xff0c;阳光普照&#xff0c;秋意正浓&#xff0c;由中共深圳市福田区委宣传部、深圳市福田区文学艺术界联合会主办&#xff0c;深圳歌唱家协会承办&…

数据结构与算法C语言版学习笔记(3)-线性表的链式结构:链表

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言&#xff1a;回顾顺序表的优缺点&#xff1a;为什么要引入链式结构的线性表&#xff1f; 一、什么是链表&#xff1f;二、链表的分类①为什么要设置头节点&…

Oracle(15)Managing Users

目录 一、基础知识 1、Users and Security 用户和安全 2、Database Schema 3、Checklist for Creating Users创建用户步骤 二、基础操作 1、创建一个用户 2、OS Authentication 操作系统身份验证 3、Dropping a User 删除用户 4、Getting User Information 获取用户信…

Idea安装使用教程~

在本文中&#xff0c;我们将提供关于如何安装 IntelliJ IDEA 的详细步骤。如果您是初学者或只是想尝试一下 IDEA&#xff0c;我们建议您下载 Community 版。如果您需要更多高级功能&#xff0c;可以选择 Ultimate 版。 步骤一&#xff1a;下载 IntelliJ IDEA 首先&#xff0c;…

第三方商城对接项目(202311)

文章目录 1. 项目背景和目标2. 项目成果3. 项目经验总结4. 展望和建议 1. 项目背景和目标 竞标成功接口对接第三方商城&#xff0c;商品&#xff0c;订单&#xff0c;售后尽快完成对接 2. 项目成果 完成整个项目功能流程对接新业务功能移交项目等业务部门使用 3. 项目经验总…

app自动化测试——capability 配置参数解析

一、Capability 简介 功能&#xff1a;配置 Appium 会话&#xff0c;告诉 Appium 服务器需要自动化的平台的应用程序 形式&#xff1a;键值对的集合&#xff0c;键对应设置的名称&#xff0c;值对应设置的值 主要分为三部分 公共部分 ios 部分 android 部分 二、Session Appi…

【C++】特殊类实现——设计一个类、不能被拷贝、只能在堆上创建对象、只能在栈上创建对象、不能被继承、单例模式、饿汉模式、懒汉模式

文章目录 C特殊类实现1.设计一个类、不能被拷贝2.设计一个类、只能在堆上创建对象3.设计一个类、只能在栈上创建对象4.设计一个类、不能被继承5.设计一个类&#xff0c;只能创建一个对象(单例模式)5.1饿汉模式5.2懒汉模式 C 特殊类实现 1.设计一个类、不能被拷贝 在C中&#x…

11 # 手写 reduce 方法

reduce 使用 reduce() 方法对数组中的每个元素按序执行一个提供的 reducer 函数&#xff0c;每一次运行 reducer 会将先前元素的计算结果作为参数传入&#xff0c;最后将其结果汇总为单个返回值。 第一次执行回调函数时&#xff0c;不存在“上一次的计算结果”。如果需要回调…

短短45分钟,Open AI撼动了整个AI圈?

相信关注AI行业的人没有人不知道ChatGPT&#xff0c;作为人工智能新产品&#xff0c;ChatGPT一经发出就引爆全球&#xff0c;也让一众企业走上了探索AI大模型之路。而就在国内一众企业就AI大模型不断改进创新时&#xff0c;Open AI用一场仅45分钟的发布会&#xff0c;震惊了整个…

【JavaEESpring】Spring IoCDI

Spring IoC& DI 1. IoC2. IoC & DI 使⽤2.1 Bean的存储2.1 DI 注入 Autowired 3. 练习代码自取 1. IoC Spring 是包含了众多⼯具⽅法的 IoC 容器 IoC: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器。 什么是控制反转呢? 也就…

uniapp使用vue

uniapp集成了Vuex&#xff0c;&#xff0c;并不需要安装vuex 定义自己的vuex vuex中独立命名空间&#xff1a; 可以在模块中使用 namespaced 属性&#xff0c;设置为 true&#xff0c;&#xff0c;这样做的好处是&#xff0c;&#xff0c;不同模块之间的state&#xff0c;mut…

电商库存随笔

好多年没有来写东西了&#xff0c;忙成狗&#xff0c;最近闲暇&#xff0c;有点时间&#xff0c;随手写一下之前的项目中的小点&#xff1b; 一方面是做个总结&#xff0c;一方面打发一下时间 出库 库存扣减时机 下单扣减 [生成订单]付款扣减预扣库存(实际使用) 预扣库存 并…

运营商大数据精准获客:我们提供精准客源渠道的最大资源体?

运营商大数据精准营销 谈起精准获客&#xff0c;竞争对手永远是为我们提供精准客源渠道的最大资源体&#xff01; 最新的获客方式&#xff0c;就是从竞争对手的手中把他们的精准客户资源变为自己的。 今年最火的运营商大数据精准营销是拒绝传统营销方式的烧钱推广&#xff0…

Nginx缓存基础

1 nginx缓存的流程 客户端需要访问服务器的数据时&#xff0c;如果都直接向服务器发送请求&#xff0c;服务器接收过多的请求&#xff0c;压力会比较大&#xff0c;也比较耗时&#xff1b;而如果在nginx缓存一定的数据&#xff0c;使客户端向基于nginx的代理服务器发送请求&…