目录
1、一个字符一个字符地滚动(效果简陋些)
2、像素级别地移动(效果丝滑些)
1、一个字符一个字符地滚动(效果简陋些)
可以通过使用QTimer和QLabel的setText()方法实现文字循环滚动效果。
效果就是比较简陋些,一个字符一个字符地滚动;
以下是一个示例代码:
#include <QLabel>
#include <QTimer>
class RollingLabel : public QLabel
{
Q_OBJECT
public:
RollingLabel(QWidget *parent = nullptr) : QLabel(parent)
{
m_timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, &RollingLabel::scrollText);
m_timer->start(50); // 每50毫秒滚动一次
}
void setText(const QString &text) override
{
m_originalText = text;
m_scrolledText = text;
QLabel::setText(text);
}
private:
QString m_originalText;
QString m_scrolledText;
QTimer *m_timer;
void scrollText()
{
m_scrolledText = m_scrolledText.mid(1) + m_scrolledText.at(0);
QLabel::setText(m_scrolledText);
}
};
在使用时,只需要将QLabel替换为RollingLabel即可:
RollingLabel *label = new RollingLabel(parent);
label->setText("Hello, World!");
2、像素级别地移动(效果丝滑些)
用法:
(1)继承于QLabel,之后在qt设计师内右键选择"提升" 使得这个继承类即可;
(2)直接在代码中new 该类使用即可;
头文件:
#pragma once
#include <QDebug>
#include <QLabel>
#include <QTimerEvent>
#include <QPaintEvent>
#include <QTextDocument> //判断富文本用的
#include <QPainter>
// 继承于标签,之后在qt设计师内右键选择"提升" 使得这个继承类控制对应需要滚动的标签
class RollingLabel :public QLabel
{
Q_OBJECT
public:
explicit RollingLabel(QWidget *parent = nullptr);
~RollingLabel();
//自适应函数,判断label文本是否需要滚动起来
void upateLabelRollingState();
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真
};
源文件:
#include "rolling_label.h"
RollingLabel::RollingLabel(QWidget *parent):QLabel(parent)
{
timerId = -1;// 定时器的ID
text_wpixel = 0; //文本的像素长度
speedt = 50;// 多久触发一次滚动
spixel = 2;// 一次滚动多少像素
//start_scroll = this->width();//保存了窗体最初的宽度,避免窗体变动就不滚动
flag = 0;//默认不处理
}
RollingLabel::~RollingLabel()
{
if(timerId >= 0)
killTimer(timerId);
}
//在设置文本、缩放事件两次调用自适应的函数
void RollingLabel::setText(const QString &txt)
{
if(Qt::mightBeRichText(txt))//判断是否为富文本
flag = 0; //0不处理,直接用原本的绘画事件显示,当属于富文本时使用这个 1左到右 2上到下
else
flag = 1;
QLabel::setText(txt);
upateLabelRollingState();
}
//设置图片,主要把lt设回0,使其恢复正常的图片显示
void RollingLabel::setPixmap(const QPixmap &pix)
{
flag=0;
QLabel::setPixmap(pix);
}
//窗口变化事件
void RollingLabel::resizeEvent(QResizeEvent *e)
{
QLabel::resizeEvent(e);
upateLabelRollingState();
}
// 根据给定的数值,修改滚动速度 sp是一次滚动多少像素,st是多少秒触发一次滚动
void RollingLabel::setspeed(int sp,int st)
{
spixel = sp;
speedt = st;
upateLabelRollingState(); // 刷新一次滚动量
}
//用来判断label文本是否需要滚动起来,是这块功能的核心
void RollingLabel::upateLabelRollingState()
{
//获取文本大小,小于文本框长度,则无需滚动
QFont ft = font();// 获取当前字体的格式,里面有文本大小和文本像素大小
QFontMetrics fm(ft); // 以当前的字体格式为基础
#if QT_VERSION > QT_VERSION_CHECK(5,11,0)//根据官方文档说明,5.11后使用新的函数
text_wpixel = (text() ); //以当前的字体格式为基础,计算字体的像素宽度
#else
text_wpixel = (text() ); //以当前的字体格式为基础,计算字体的像素宽度
#endif
if( (text_wpixel > this->width() ) && flag == 1 )// **长度或高度超出本身label的像素大小,则开启滚动***关键判断
{
left = 0; // 标志当前的像素滚动量
#if QT_VERSION > QT_VERSION_CHECK(5,11,0)//根据官方文档说明,5.11后使用新的函数
blank = " ";//空格
blank_wp = (blank );//空格的像素宽度,方便后面计算是否到达末尾
#else
blank = " ";//空格
blank_wp = (blank );//空格的像素宽度
#endif
qDebug()<< "OK!";
//开启定时器,定时器定时触发滚动效果
timerId = startTimer(speedt);
}
else//关闭文本框滚动
{
qDebug()<< "no OK!";
flag = 0; //关闭
if(timerId >= 0){
killTimer(timerId);
timerId = -1;
}
}
}
//定时改位移量,到末尾时改为开头 负责修改当前像素位移值
void RollingLabel::timerEvent(QTimerEvent *e)
{
if(e->timerId() == timerId && isVisible())
{
left += spixel;// (0,0)在左上角,每次增加对应像素
// 判断是否已经完成一遍循环,完成则恢复起始位置,重新开始循环
if (left > (text_wpixel + blank_wp))
left = 0;
//repaint();//立即触发一次刷新,不会产生冗余,但是耗性能
update();//不会立马刷新,有可能产生事件冗余,但是节省性能
}
QLabel::timerEvent(e);
}
//重绘事件,根据位移量left显示文本
void RollingLabel::paintEvent(QPaintEvent *e)
{
if(flag == 0){ // 不处理,直接调用标签的默认函数
QLabel::paintEvent(e);
return;
}
QPainter pen(this);
// 获取当前label的矩形大小
QRect rc = rect();
(() /*- 2*/);
(() /*- 2*/);
QString strText = text();
strText += blank + text();
(() - left); //修改矩形 x轴, 由于left在不断变大,setLeft就在不断变小,(0,0)在左上角,固左移
(rc,Qt::AlignVCenter, strText);//根据给定的矩形坐标,绘制标签
}