QT 实现字幕滚动(上下滚动)


// 我们假设有一个QLabel 用来显示某某信息,但是信息有时候过长,高度超过了QLabel的高度
// 这时候最好的方法是让其滚动,那么我们就来实现以下上下滚动。

// 要用到的QT 事件 
void showEvent(QShowEvent *);
void paintEvent(QPaintEvent *);
void timerEvent(QTimerEvent *);
void hideEvent(QHideEvent *);

// paintEvent 这个事件是重绘事件
// timerEvent 既然是滚动肯定有个定时器,这是定时器事件
// showEvent  显示事件 例如 label->show() 时候触发
// hideEvent  隐藏事件 例如 label->hide() 时候触发

// 下面就附上代码进行详细说明 这里我们定义 VScrollLabel 类

------------------------------ Vscrolllabel.h-------------------------


#ifndef VSCROLLLABEL_H
#define VSCROLLLABEL_H


#include <QLabel>


class VScrollLabel : public QLabel    // 继承 QLabel类
{
    Q_OBJECT
public:
    explicit VScrollLabel(QWidget *parent = 0, Qt::WindowFlags f=0);
    virtual ~VScrollLabel(){}

public slots:
    void setText(const QString &);

protected:
    void showEvent(QShowEvent *);
    void paintEvent(QPaintEvent *);
    void timerEvent(QTimerEvent *);
    void hideEvent(QHideEvent *);

private slots:
    void metrics();
    void startScroll();

signals:
    void currentTextChanged();

private:
    int getHeight();

private:
    int offset;
    int timerID;
    int textHeight;

};

#endif // VSCROLLLABEL_H


------------------------------ Vscrolllabel.cpp-------------------------

#include "vscrolllabel.h"
#include <QPainter>
#include <QTimerEvent>
#include <QTimer>

VScrollLabel::VScrollLabel(QWidget *parent, Qt::WindowFlags f) :
    QLabel(parent,f)
{
offset = timerID = textHeight = 0;
connect(this, SIGNAL(currentTextChanged()), SLOT(metrics()));
}

void VScrollLabel::setText(const QString &curText)
{
if (text() != curText) {
QLabel::setText(curText);
emit currentTextChanged();
}
}

// 开始启动定时器 设为 50
void VScrollLabel::startScroll()
{
  timerID = startTimer(50);
}


void VScrollLabel::metrics()
{
offset = 0;

// getHeight + QLabel高度是为了 一段过长的文字显示完后再重新开始滚动显示
// 不然的话第一行会紧接着末尾显示出来。
textHeight = getHeight() +height() ;   
QTimer::singleShot(500, this, SLOT(startScroll()));
this->update();
}

// 这里是重点,我们得到的一段信息有没有换行符号,要自动换行
// 这就要得到字体的高度和宽度来处理这一段文字,处理完后调用
// setText() 设置到Qlabel 上面去。
int VScrollLabel::getHeight()
{
#define MARGIN  5

char newMsg[1024] ={0};
char *message = text().toLatin1().data();
int len = strlen(message);
char mss[len];  
memcpy(mss,text().toLatin1().data(),len);

int i;
int row =1;
int line_width =0;
int font_width = 0;
int max_width = 0;
int j=0;

QFontMetrics fm = fontMetrics();
int  h = 18;    // 这里指定我们想要的字体高度

printf("len  = %d\n",len);
for (i=0; i<len; i++) {

font_width = fm.width(mss[i]); 
if (mss[i] == '\n') {       // line feed
line_width = 0;
newMsg[j++] = mss[i];
row++;
continue;
}

if ((line_width+font_width) > width()) {
max_width = line_width;
newMsg[j++] = '\n';
line_width = 0;
row++;
}

line_width += font_width;
newMsg[j++] = mss[i];
//printf("line_width = %d\n",line_width);
if (line_width > max_width) max_width = line_width;

if(j == sizeof(newMsg)-1) break;

}

printf("row = %d\n",row);

// 上面经过处理得到结果,查看下有多少行。
// 设置到QLabel 上去
  setText(newMsg);        
// 返回 行*字体高度 + 这里我们加了10 的预留空间。
  return row*h+(MARGIN<<1);
}

// 显示我们就启动定时器
void VScrollLabel::showEvent(QShowEvent *)
{
    metrics();
}

void VScrollLabel::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
if (textHeight < 1) return;

int y = -offset;
while (y < height()) {
painter.drawText(0, y, width(), textHeight,
Qt::AlignLeft | Qt::AlignVCenter, text());
y += textHeight;
}
}

void VScrollLabel::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timerID) {
++offset;
if (offset >= textHeight) 
offset = 0;
scroll(0, -1);    // X 轴不变,Y 轴 向上偏移 1
} else {
QWidget::timerEvent(event);
}
}

// 隐藏我们就停止掉 定时器
void VScrollLabel::hideEvent(QHideEvent *)
{
     offset = 0;
     if (timerID) killTimer(timerID);

}




Qt中使用QLabel实现文字的上下滚动可以通过以下步骤来实现: 1. 创建一个QLabel对象并设置其文本内容。 2. 设置QLabel的固定大小,以确保文本溢出时可以进行滚动。 3. 创建一个QTimer对象用于触发滚动事件。 4. 在滚动事件中,将QLabel的y坐标减少一个固定值,以实现向上滚动效果。 5. 当QLabel滚动到顶部时,将其y坐标重置为初始值,以实现无限滚动的效果。 下面是示例代码实现: ```cpp #include <QtWidgets> class ScrollLabel : public QLabel { public: ScrollLabel(const QString& text, QWidget* parent = nullptr) : QLabel(parent), m_yPos(0) { setText(text); setAlignment(Qt::AlignTop); setFixedSize(200, 100); // 设置固定大小 QTimer* scrollTimer = new QTimer(this); // 创建定时器 connect(scrollTimer, &QTimer::timeout, this, &ScrollLabel::scrollText); // 连接滚动事件 scrollTimer->start(100); // 设置滚动间隔 } private: void scrollText() { m_yPos -= 1; // 向上滚动一个固定值 move(pos().x(), m_yPos); // 更新QLabel的位置 if (m_yPos <= -height()) // 判断是否滚动到顶部 { m_yPos = 0; move(pos().x(), m_yPos); // 重置位置 } } private: int m_yPos; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); ScrollLabel* scrollLabel = new ScrollLabel("这是一个滚动的文字", nullptr); scrollLabel->show(); return a.exec(); } ``` 在这个例子中,我们创建了一个名为ScrollLabel的自定义QLabel类,并重写了其滚动事件scrollText。在scrollText函数中,我们不断减少QLabel的y坐标来实现文字的上下滚动。当滚动到顶部时,我们将y坐标重置为初始值,以实现无限滚动的效果。最后,在主函数中创建ScrollLabel对象,并显示出来。 这样,我们就成功地利用QLabel实现了文字的上下滚动效果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HarkerYX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值