当前位置:网站首页>QLabel 跑马灯文字显示

QLabel 跑马灯文字显示

2022-07-06 11:01:00 HL_风神

效果展示:

在这里插入图片描述

整个功能的实现是在前人的基础上进行了优化和修改

有一个比较重要的点是:
当windows系统设置文本显示比例不是100%的时候,这里设置字体大小号数并不意味着文字的像素大小就是这个号数

重点是这3个函数:

//自适应函数,判断label文本是否需要滚动起来
void upateLabelRollingState();
//设置文本字体格式
void setScrollLabelFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);
// 强制开启跑马灯,所有文本均滚动显示
void setFixedScrollShow(bool isOn);

源程序呈上
头文件:

#ifndef SCROLL_LABEL_H
#define SCROLL_LABEL_H


#include <QDebug>
#include <QLabel>
#include <QTimerEvent>
#include <QPaintEvent>
#include <QTextDocument> //判断富文本用的
#include <QPainter>

// 继承于标签,之后在qt设计师内右键选择"提升" 使得这个继承类控制对应需要滚动的标签
class ScrollLabel :public QLabel
{
    
    Q_OBJECT
public:
    explicit ScrollLabel(QWidget *parent = nullptr);
    ~ScrollLabel();

    //自适应函数,判断label文本是否需要滚动起来
    void upateLabelRollingState();
    //设置文本字体格式
    void setScrollLabelFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);
    // 强制开启跑马灯,所有文本均滚动显示
    void setFixedScrollShow(bool isOn);
public slots:
    //定时改位移量,到末尾时改为开头 负责修改当前像素位移值left startTimer开始,killTimer结束
    void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE;

    //重绘事件,根据位移量left显示文本
    void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE;

    //在设置文本、缩放事件两次调用自适应的函数
    void setText(const QString &txt);

    //设置图片,主要把lt设回0,使其恢复正常的图片显示
    void setPixmap(const QPixmap &pix);

    //窗口变化事件
    void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;

    // 根据给定的数值,修改滚动速度 sp是一次滚动多少像素,st是多少秒触发一次滚动
    void setspeed(int sp=10,int st=300);

private:
    int timerId; //定时器id
    int text_wpixel; //储存的当前label内字符串的像素水平长度

    int speedt;// 多久触发一次滚动
    int spixel;// 一次滚动多少像素

    int left;// 标明当前的像素滚动量

    QString blank;//空格
    int blank_wp;//空格的像素宽度

    int start_scroll;

    uint8_t flag; //判断是否应该开启滚动 0否 1真

    bool isFixedScroll;
};

#endif // SCROLL_LABEL_H

cpp文件:
#include “scrolllabel.h”

ScrollLabel::ScrollLabel(QWidget *parent):QLabel(parent)
{
    
    timerId = -1;// 定时器的ID
    text_wpixel = 0; //文本的像素长度

    speedt = 80;// 多久触发一次滚动
    spixel = 10;// 一次滚动多少像素

    //start_scroll = this->width();//保存了窗体最初的宽度,避免窗体变动就不滚动

    flag = 0;//默认不处理

    isFixedScroll = false; //默认当文本过长时才滚动显示
}

ScrollLabel::~ScrollLabel()
{
    
    if(timerId >= 0)
        killTimer(timerId);
}

//在设置文本、缩放事件两次调用自适应的函数
void ScrollLabel::setText(const QString &txt)
{
    
    if(Qt::mightBeRichText(txt))//判断是否为富文本
        flag = 0;  //0不处理,直接用原本的绘画事件显示,当属于富文本时使用这个 1左到右 2上到下
    else
        flag = 1;

    QLabel::setText(txt);
    upateLabelRollingState();
}

//设置图片,主要把lt设回0,使其恢复正常的图片显示
void ScrollLabel::setPixmap(const QPixmap &pix)
{
    
    flag=0;
    QLabel::setPixmap(pix);
}

//窗口变化事件
void ScrollLabel::resizeEvent(QResizeEvent *e)
{
    
    QLabel::resizeEvent(e);
    upateLabelRollingState();
}

// 根据给定的数值,修改滚动速度 sp是一次滚动多少像素,st是多少秒触发一次滚动
void ScrollLabel::setspeed(int sp,int st)
{
    
    spixel = sp;
    speedt = st;

    upateLabelRollingState(); // 刷新一次滚动量
}

//用来判断label文本是否需要滚动起来,是这块功能的核心
void ScrollLabel::upateLabelRollingState()
{
    
    //获取文本大小,小于文本框长度,则无需滚动
    QFont ft = font();// 获取当前字体的格式,里面有文本大小和文本像素大小
    QFontMetrics fm(ft); // 以当前的字体格式为基础

    #if QT_VERSION > QT_VERSION_CHECK(5,11,0)//根据官方文档说明,5.11后使用新的函数
    text_wpixel = fm.horizontalAdvance(text() ); //以当前的字体格式为基础,计算字体的像素宽度
    #else
    text_wpixel = fm.width(text() ); //以当前的字体格式为基础,计算字体的像素宽度
    #endif

    if((flag == 1 && isFixedScroll) || ((text_wpixel > this->width() ) && flag == 1) )// **长度或高度超出本身label的像素大小,则开启滚动***关键判断
    {
    
        left = 0; // 标志当前的像素滚动量

        #if QT_VERSION > QT_VERSION_CHECK(5,11,0)//根据官方文档说明,5.11后使用新的函数
        blank = " ";//空格
        blank_wp = fm.horizontalAdvance(blank );//空格的像素宽度,方便后面计算是否到达末尾
        #else
        blank = " ";//空格
        blank_wp = fm.width(blank );//空格的像素宽度
        #endif

        qDebug()<< "OK!";

        //开启定时器,定时器定时触发滚动效果
        timerId = startTimer(speedt);

    }
    else//关闭文本框滚动
    {
    
        qDebug()<< "no OK!";
        flag = 0; //关闭
        if(timerId >= 0){
    
            killTimer(timerId);
            timerId = -1;
        }
    }

}

void ScrollLabel::setScrollLabelFont(const QString &family, int pointSize, int weight, bool italic)
{
    
    QFont f(family,pointSize,weight,italic); //当windows系统设置文本显示比例不是100%的时候,这里设置字体大小号数并不意味着文字的像素大小就是这个号数
    f.setPixelSize(pointSize);
    setFont(f);
}

void ScrollLabel::setFixedScrollShow(bool isOn)
{
    
    isFixedScroll = isOn;
}

//定时改位移量,到末尾时改为开头 负责修改当前像素位移值
void ScrollLabel::timerEvent(QTimerEvent *e)
{
    
    if(e->timerId() == timerId && isVisible())
    {
    
        left += spixel;// (0,0)在左上角,每次增加对应像素
        if((left + 20) > (text_wpixel + blank_wp) )// 表示到末尾了
        {
    
            left = 1-( this->width() ); //重新添加,负数代表从最右边开始
        }

        //repaint();//立即触发一次刷新,不会产生冗余,但是耗性能
        update();//不会立马刷新,有可能产生事件冗余,但是节省性能
        //update和repaint的区别,请看QT文档说明
    }

    QLabel::timerEvent(e);
}

//重绘事件,根据位移量left显示文本
void ScrollLabel::paintEvent(QPaintEvent *e)
{
    
    if(flag == 0){
     // 不处理,直接调用标签的默认函数
        QLabel::paintEvent(e);
        return;
    }

    QPainter pen(this);
    // 获取当前label的矩形大小
    QRect rc = rect();
    rc.setHeight(rc.height() /*- 2*/);
    rc.setWidth(rc.width() /*- 2*/);

    QString strText = blank + text();
    rc.setLeft(rc.left() - left); //修改矩形 x轴, 由于left在不断变大,setLeft就在不断变小,(0,0)在左上角,固左移
    pen.drawText(rc,Qt::AlignVCenter, strText);//根据给定的矩形坐标,绘制标签
}
原网站

版权声明
本文为[HL_风神]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_43154850/article/details/125559443