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

目录

    • 前言
    • 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 
#include 
#include 

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 
#include 

#include 
#include 

#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,如下图所示:
Qt 自定义控件-支持换行和点击事件的Label_第1张图片
在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());
    }
}

编译运行程序,查看效果

Qt 自定义控件-支持换行和点击事件的Label_第2张图片

点击自定义控件弹出对话框:

4、总结

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

你可能感兴趣的:(C++,qt,开发语言,c++,ui,自定义控件)