QLabelPro 支持滚动显示、发送点击信号

QLabelPro是一个自定义的QLabel控件,它支持当文本超出控件长度时自动滚动显示,并能发送点击信号。通过QFontMetrics判断文本是否超宽,使用定时器实现滚动效果,而点击事件通过覆写mousePressEvent和mouseReleaseEvent来捕获和处理。
摘要由CSDN通过智能技术生成

滚动显示

需求:超出当前控件长度的时候,文字可以滚动显示。
分解一下:

  1. 如何判断当前显示的内容是否超过了控件的长度?
    通过 QFontMetrics 类,可获取当前字体文本的宽度。
    QFont ft = font();
    QFontMetrics fm(font);
    int text_width = fm->width(text());
    
  2. 如何实现滚动?
    通过定时器来将文本的内容滚动起来。我使用的是QObject自带的timerEvent来实现;
    void QLabelPro::timerEvent(QTimerEvent *event)
    {
    	if(event->timerId() == firstTimeId && isVisible()) {
        timerID = startTimer(100);
    	}
    	if(event->timerId() == timerID && isVisible()) {
        if(firstTimeId >= 0) {
            killTimer(firstTimeId);
            firstTimeId = -1;
        }
        left += 5;
        QFont ft = font();
        QFontMetrics fm(ft);
        int txtWidth = fm.width(text());
        int spaceWidth = fm.width(strSpace);
    
        if((txtWidth + spaceWidth) < left)
            left = 0;
    
        repaint();
    }
    QLabel::timerEvent(event);
    }
    

timerEvent 的使用参考

发送点击信号

点击这个动作可以分解为“按下”和“抬起”,所以实现思路是通过重写mousePressEvent和mouseReleaseEvent的方式。

void QLabelPro::mousePressEvent(QMouseEvent *ev)
{
    perss_flag = true;
    QLabel::mousePressEvent(ev);
}
void QLabelPro::mouseReleaseEvent(QMouseEvent *ev)
{
    if(perss_flag) {
        perss_flag = false;
        emit Clicked();
    }
    QLabel::mouseReleaseEvent(ev);
}

其中的perss_flag变量是用来保证”按下“与“抬起”是按照顺序在该控件中发生的。

源码

qlabelpro.cpp

#include "qlabelpro.h"
#include <QTimerEvent>
#include <QMouseEvent>
#include <QPainter>

QLabelPro::QLabelPro(QWidget *parent) : QLabel(parent)
{
    strSpace = "          ";
    firstTimeId = -1;
    timerID = -1;
    perss_flag = false;
}

void QLabelPro::updateLabelRollingState()
{
    QFont ft = font();

    QFontMetrics fm(ft);
    int nW = fm.width(text());

    left = 0;

    if(timerID >= 0) {
        killTimer(timerID);
        timerID = -1;
    }
    if(firstTimeId >= 0) {
        killTimer(firstTimeId);
        firstTimeId = -1;
    }
    if(nW > width()) {
        firstTimeId = startTimer(3000);
    } else {
        if(timerID >= 0) {
            killTimer(timerID);
            timerID = -1;
        }
        if(firstTimeId >= 0) {
            killTimer(firstTimeId);
            firstTimeId = -1;
        }
    }
}

void QLabelPro::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == firstTimeId && isVisible()) {
        timerID = startTimer(100);
    }
    if(event->timerId() == timerID && isVisible()) {
        if(firstTimeId >= 0) {
            killTimer(firstTimeId);
            firstTimeId = -1;
        }
        left += 5;
        QFont ft = font();
        QFontMetrics fm(ft);
        int txtWidth = fm.width(text());
        int spaceWidth = fm.width(strSpace);

        if((txtWidth + spaceWidth) < left)
            left = 0;

        repaint();
    }
    QLabel::timerEvent(event);
}

void QLabelPro::paintEvent(QPaintEvent *e)
{
    QPainter p(this);
    QRect rc = rect();
    rc.setHeight(rc.height()-2);
    rc.setWidth(rc.width()-2);

    QFont ft = font();

    p.setFont(ft);

    rc.setLeft(rc.left() - left);

    QString strText = text();
    if(timerID >= 0) {
        strText += strSpace + text();
    }

    p.drawText(rc, Qt::AlignVCenter, strText);
}

void QLabelPro::resizeEvent(QResizeEvent *event)
{
    QLabel::resizeEvent(event);
    updateLabelRollingState();
}

void QLabelPro::mousePressEvent(QMouseEvent *ev)
{
    perss_flag = true;
    QLabel::mousePressEvent(ev);
}

void QLabelPro::mouseReleaseEvent(QMouseEvent *ev)
{
    if(perss_flag) {
        perss_flag = false;
        emit Clicked();
    }
    QLabel::mouseReleaseEvent(ev);
}

void QLabelPro::setText(const QString & text)
{
    QLabel::setText(text);
    updateLabelRollingState();
}

qlabelpro.h

#ifndef QLABELPRO_H
#define QLABELPRO_H

#include <QLabel>

class QLabelPro : public QLabel
{
    Q_OBJECT
public:
    explicit QLabelPro(QWidget *parent = nullptr);

    void setText(const QString & text);
private :
    int timerID;
    int firstTimeId;
    int left;
    QString strSpace;
    bool perss_flag;
    void updateLabelRollingState();
    void timerEvent(QTimerEvent* event);
    void paintEvent(QPaintEvent* e);
    void resizeEvent(QResizeEvent *event);
    void mousePressEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);
signals:
    void Clicked();

public slots:
};

#endif // QLABELPRO_H

写在后面

要想进步还是需要多分享多总结。
如有问题欢迎留言指正【抱拳】。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值