QLabel绘制滚动文本

实现思路

绘制滚动文本是个很简单的事,只需要用定时器累计一个文本坐标偏移量,然后 update ,在 paintEvent 里把文本画出来。

Qt 定时刷新可以用(可能还有其他方式):

  • QObject的startTimer配合paintEvent;
  • QBasicTimer配合paintEvent;(源码中很多都用的这个类,我也就用的这个类了)
  • QTimer;
  • QTimeLine;
  • QAnimation;(如果除了滚动还有颜色等动画,建议用动画组实现)

paintEvent 里 QPainter 的设置默认是被样式表影响的,所以我在样式表里设置的颜色和字体。

获取文本高度的时候还有个坑,就是 Qt 文本的 height() 包含基线往上和往下两部分,但是不一定代表字体的真实信息:

我绘制的时候减去了基线底部距离 descent 才显示正常了,不然就没上下居中对齐(直接用 ascent 感觉有点偏),也可以用 Qt5.8 引入的 capHeight:

    /*const int text_height = painter.fontMetrics().capHeight();
    const int text_y = (height()+text_height) / 2;*/
    const int text_height = painter.fontMetrics().height();
    const int text_y = (height()+text_height) / 2-painter.fontMetrics().descent();

实现基本功能之后也可以进行扩展,如颜色变换,在某一位置暂留,多条文本滚动等。 

最终实现

实现效果:

代码链接:

github链接:https://github.com/gongjianbo/MyTestCode/tree/master/Qt/ScrollLabel

主要代码:

#ifndef SCROLLLABEL_H
#define SCROLLLABEL_H

#include <QLabel>
#include <QBasicTimer>

//滚动文字的label
class ScrollLabel : public QLabel
{
    Q_OBJECT
public:
    enum ScrollDirection{ //滚动方向
        RightToLeft=1,
        LeftToRight=2
    };
public:
    explicit ScrollLabel(QWidget *parent = nullptr);

    //滚动方向
    ScrollLabel::ScrollDirection getDirection() const;
    void setDirection(ScrollLabel::ScrollDirection direction);

    //刷新间隔
    int getInterval() const;
    void setInterval(int interval);

protected:
    //basictimer定时器触发
    void timerEvent(QTimerEvent *event) override;
    //绘制
    void paintEvent(QPaintEvent *event) override;
    //大小变化时重新计算
    void resizeEvent(QResizeEvent *event) override;

private:
    //滚动定时器
    //也可以使用QTimer QTimeLine QAnimation等实现
    QBasicTimer scrollTimer;
    int interval=20;
    //偏移量
    int offset=0;
    int textWidth=0;
    int labelWidth=0;
    //默认右往左
    ScrollDirection direction=RightToLeft;
};

#endif // SCROLLLABEL_H
#include "ScrollLabel.h"

#include <QTimerEvent>
#include <QPaintEvent>
#include <QResizeEvent>
#include <QPainter>

#include <QDebug>

ScrollLabel::ScrollLabel(QWidget *parent)
    : QLabel(parent)
{
    //启动定时器,触发this的timerevent
    scrollTimer.start(interval,this);
}

ScrollLabel::ScrollDirection ScrollLabel::getDirection() const
{
    return direction;
}

void ScrollLabel::setDirection(ScrollLabel::ScrollDirection direction)
{
    if(this->direction!=direction){
        this->direction=direction;
        offset=0;
    }
}

int ScrollLabel::getInterval() const
{
    return interval;
}

void ScrollLabel::setInterval(int interval)
{
    if(this->interval!=interval){
        this->interval=interval;
        scrollTimer.start(interval,this);
    }
}

void ScrollLabel::timerEvent(QTimerEvent *event)
{
    //定时器timeout
    if(event->timerId()==scrollTimer.timerId()){
        event->accept();
        ++offset;
        if(offset>textWidth+labelWidth){
            offset=0;
        }
        update();
    }else{
        QLabel::timerEvent(event);
    }
}

void ScrollLabel::paintEvent(QPaintEvent *event)
{
    event->accept();

    QPainter painter(this);
    const int text_width = painter.fontMetrics().width(text());
    //字体绘制坐标为左下角,y值就是 labelheight-(labelheight-textheight)/2
    //因为取的字体高度还受基线影响,height=descent+ascent,这里去掉descent
    //也可以用Qt5.8提供的capHeight
    /*const int text_height = painter.fontMetrics().capHeight();
    const int text_y = (height()+text_height) / 2;*/
    const int text_height = painter.fontMetrics().height();
    const int text_y = (height()+text_height) / 2-painter.fontMetrics().descent();
    if (textWidth != text_width && text_width > 0) {
        textWidth = text_width;
        offset = 0;
    }else {
        if(direction==RightToLeft){
            //从右往左
            painter.drawText(labelWidth - offset, text_y, text());
        }else{
            //从左往右
            painter.drawText(offset - textWidth, text_y, text());
        }
    }
}

void ScrollLabel::resizeEvent(QResizeEvent *event)
{
    const int old_width = event->oldSize().width();
    const int new_width = event->size().width();
    if (new_width > 10) {
        labelWidth = new_width;
        //新宽度更小,就重置偏移
        if (new_width < old_width) {
            offset = 0;
        }
    }
    QLabel::resizeEvent(event);
}

 

 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: QLabel是Qt中的一个基础控件类,用于显示文字、图像和HTML等内容。要实现QLabel滚动显示文字,可以使用QScrollBar来实现。 首先,我们需要创建一个QLabel对象,并设置其显示的文本。然后,为该QLabel对象添加一个QScrollBar控件,用于控制文本滚动。可以使用QScrollArea类来实现这个功能。 QScrollArea类提供了一个可滚动的窗口,将QLabel控件放置在该窗口中,然后通过设置QScrollBar的相关属性,实现文本滚动。 可以通过调节QScrollBar的valueChanged信号来控制文本的位置(即QLabel的setText)和滚动条的位置(即QScrollBar的setValue),从而实现滚动显示文字的效果。 总之,使用QLabel滚动显示文字,需要结合QScrollBar和QScrollArea来实现,通过设置和调节其相关属性和信号,实现文本滚动滚动条的位置调节。 ### 回答2: QLabel是Qt中的一种控件,用于显示静态文本或图片。它可以被用来显示各种内容,如标签、标题、描述、图片注释等。而滚动显示文字则是在QLabel中的一种功能。 在Qt中,可以使用QScrollArea控件来实现文本滚动显示。以QLabel为例,可以通过以下步骤实现滚动显示文字: 1. 创建一个QScrollArea控件,并将它设置为QLabel的父级控件。 2. 将QLabel放置在QScrollArea控件中。 3. 设置QLabel的大小并将其文本放置在QLabel中。 4. 使用QTimer定时器来移动QScrollArea控件的垂直滚动条,以实现文本滚动显示。 下面是一段示例代码,演示如何在QLabel中实现滚动显示文字: ``` QLabel *label = new QLabel; QScrollArea *scrollArea = new QScrollArea; scrollArea->setWidget(label); scrollArea->setWidgetResizable(true); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); scrollArea->setAlignment(Qt::AlignCenter); QString text = "Hello, World!"; QFont font("Arial", 20); QFontMetrics fontMetrics(font); int textHeight = fontMetrics.height(); int textWidth = fontMetrics.width(text); label->setFont(font); label->setText(text); label->setFixedSize(textWidth, textHeight); QTimer *timer = new QTimer; QObject::connect(timer, &QTimer::timeout, [=]() { scrollArea->verticalScrollBar()->setValue(scrollArea->verticalScrollBar()->value() + 1); }); timer->start(50); scrollArea->show(); ``` 在这个例子中,我们首先创建了一个QLabel控件和一个QScrollArea控件,并将QLabel放置在QScrollArea中。接着,我们使用QFontMetrics类来计算文本的宽度和高度,并设置QLabel的大小。最后,我们创建了一个QTimer定时器,每50毫秒触发一次滚动,将QScrollArea的垂直滚动条往下移动1个像素。这样就可以实现文本滚动显示了。 综上所述,滚动显示文字是在QLabel中的一种功能,通过QScrollArea控件和定时器来实现。在实际开发中,可以根据具体需求对文本滚动的速度、方向等属性进行调整。 ### 回答3: QLable是Qt GUI框架提供的一种用于显示文本或图像的部件,它可以用于显示各种类型的文本内容,包括计数器、计时器、进度条、提示信息等。当文本内容超出QLobel的大小或者需要通过滚动的方式来显示时,Qt提供了一种简单的滚动方式,可以让文本内容在QLabel滚动QLabel滚动显示功能通常通过QScrollArea来实现,这个类继承自QWidget,提供了可滚动的视窗部件,我们可以将QLabel对象置于此部件中,然后通过设置QLable对象的大小和内容,再选择滚动模式,就可以实现滚动显示文本内容了。 为了实现滚动显示文本内容,我们需要完成以下步骤: 1. 建立一个QScrollArea对象,用于容纳需要滚动的QLable对象。 2. 建立一个QLable对象,该对象用于展示需要滚动文本内容。 3. 将QLable对象作为QScrollArea的子部件,使用setWidget()函数来进行设置。 4. 设置QLable对象的大小和内容,如setText()函数和setFixedSize()函数。 5. 选择滚动模式,使用setAlignment()函数设置对齐模式,并使用setStyleSheet()函数设置背景颜色和边框样式。 6. 如果需要在QLabel中显示多行文本,需要设置word-wrap属性,并使用setMinimumHeight()函数设置最小高度。 7. 最后,需要使用QTimer类来实现滚动的动画效果,每一次滚动都需要重置QLable对象的位置。 通过以上步骤,我们就可以实现QLabel滚动显示文本内容的功能了。值得一提的是,QT Framework还提供了更加灵活和高级的滚动显示方式,如QTextBrowser和QPlainTextEdit等,这些部件可以方便地展示多行文本内容,并且提供了更加丰富和高级的格式化和滚动方式,可以满足更加复杂的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龚建波

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

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

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

打赏作者

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

抵扣说明:

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

余额充值