使用Qt开发实现字幕滚动效果

 更新时间:2023年11月30日 08:54:11   作者:Qt程序员  
我们经常能够在外面看到那种滚动字幕,那么就拿qt来做一个吧,文章通过代码示例给大家介绍的非常详细,对大家的学习或工作有有一定的参考价值,需要的朋友可以参考下

1、效果展示

我们经常能够在外面看到那种滚动字幕,那么就拿qt来做一个吧。

2、实现思路

实现一个窗口部件,这个窗口部件显示了一串文本标语,它会每t毫秒向左移动一个像素。如果窗口部件比文本宽,那么文本将会被多次重复,直到能够填满整个窗口部件的宽度为止。

3、滚动窗口部件

创建一个滚动窗口类,将其命名为ticker。

3.1、成员变量

我们需要提供几个成员变量。

  • myText用来表示要显示的文本内容。
  • offset表示当前偏移量。
  • myTimerId表示定时器的ID编号。
    QString myText;
    int offset;
    int myTimerId;

3.2、事件重写

需要重新实现了Ticker中的4个事件处理器,分别为paintEvent()、timerEvent()、showEvent()和 hideEvent();关于每个事件的职责后面再说。

    virtual void paintEvent(QPaintEvent* event) override; // 绘制事件
    virtual void timerEvent(QTimerEvent* event) override; // 定时器事件
    virtual void showEvent(QShowEvent* event) override; // 显示事件
    virtual void hideEvent(QHideEvent* event) override; // 隐藏事件

3.3、成员方法

还需要提供几个成员方法。关于每个方法的职责后面再说。

    void setText(const QString& newText);
    QString text() const { return myText; }
    QSize sizeHint() const;

3.4、方法实现

1.构造函数

构造函数把 offset变量初始化为0。用来绘制文本的x坐标值就取自于这个offset 值。

定时器的ID通常是非零的,所以可以使用0来表示定时器还没有启动。

Ticker::Ticker(QWidget *parent)
    : QWidget{parent}
{
    offset = 0;
    myTimerId = 0;
}

2.setText函数

setText()函数用来设置要显示的文本。它调用update()强制执行一个重绘操作,并且调用updateGeometry()通知对Ticker窗口部件负责的布局管理器,提示该窗口部件的大小发生了变化。

void Ticker::setText(const QString &newText)
{
    myText = newText;
    update();
    updateGeometry();
}

3.sizeHint函数

sizeHint()函数返回文本所需的空间大小,并以此作为窗口部件的理想尺寸。QWidget::fontMetrics()函数返回一个QFontMetrics对象;可以用这个对象查询并获得与这个窗口部件字体相关的信息。

QSize Ticker::sizeHint() const
{
    return fontMetrics().size(0, text());
}

4.paintEvent事件

paintEvent()函数使用QPainter::drawText()绘制文本。它使用fontMetrics()确定文本在水平方向上所需要的空间,并且在考虑offset值的同时,多次绘制文本,直到能够填充整个窗口部件的宽度为止。

void Ticker::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    int textWidth = fontMetrics().width(text());
    if(textWidth < 1)
    {
        return;
    }
    int x = -offset;
    while(x < width())
    {
        painter.drawText(x, 0, textWidth, height(), Qt::AlignLeft | Qt::AlignVCenter, text());
        x += textWidth;
    }
}

5.timerEvent定时器事件

系统每隔一定时间,都会调用一次timerEvent()函数。

通过在offset上加1来模拟移动,从而形成文本宽度的连续滚动。然后,它使用QWidget::scroll()把窗口部件的内容向左滚动一个像素。

如果这个定时器事件不是我们所关注的那个定时器,就可以把它传递给基类。

这里也可以调用update()代替scrol(),但使用scroll()会更有效率,因为它只是简单地移动屏幕上已经存在的像素并且只对这个窗口部件的新显示区域(此时,只是一个1像素乘以宽度的像素条)产生一个绘制事件。

void Ticker::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == myTimerId)
    {
        ++offset;
        if(offset >= fontMetrics().width(text()))
        {
            offset = 0;
        }
        scroll(-1, 0);
    }
    else
    {
        QWidget::timerEvent(event);
    }
}

6.showEvent显示事件

showEvent()函数用来启动个定时器。QObject::startTimer()调用会返回一个ID数字,用这个数字识别该定时器。QObject支持多个独立的定时器,每一个都可以有自己的时间间隔。

在startTimer()调用之后,大约每30毫秒Qt都会产生一个定时器事件。至于具体的时间精度,则取决于所在的操作系统。

我们也可以在Ticker的构造函数中完成startTimer()的调用,但是只有在窗口部件实际可见的时候,才有必要保存由Qt产生的定时器事件的那些资源。让资源合理利用。

void Ticker::showEvent(QShowEvent *event)
{
    Q_UNUSED(event);
    myTimerId = startTimer(30);
}

7.hideEvent隐藏事件

hideEvent()函数调用QObject::killTimer()来停止该定时器。

void Ticker::hideEvent(QHideEvent *event)
{
    killTimer(myTimerId);
    myTimerId = 0;
}

定时器事件是一种低级事件,而且如果需要多个定时器时,保持对所有定时器ID的跟踪将会变得很麻烦。

在这种情况下,通常更为简单的方式是为每一个定时器分别创建一个QTimer对象。QTimer会在每个时间间隔发射timeout()信号。当然QTimer也提供了一个非常方便的接口,可用于单触发定时器(只触发一次的定时器)QTimer::singleShot(t, this, &Ticker::onTimer)。

以上就是使用Qt开发实现字幕滚动效果的详细内容,更多关于Qt字幕滚动的资料请关注脚本之家其它相关文章!

相关文章

  • c++ STL set_difference set_intersection set_union 操作

    c++ STL set_difference set_intersection set_union 操作

    这篇文章主要介绍了c++ STL set_difference set_intersection set_union 操作,需要的朋友可以参考下
    2017-03-03
  • 基于C++ bitset常用函数及运算符(详解)

    基于C++ bitset常用函数及运算符(详解)

    下面小编就为大家带来一篇基于C++ bitset常用函数及运算符(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • C++运算符重载详情介绍

    C++运算符重载详情介绍

    这篇文章主要介绍了C++运算符重载,C++当中除了函数可以重载之外,其实运算符也是可以重载的,C++根据操作数的数目和类型来决定要使用哪一种操作,下面一起进入文章里哦阿姐更多详情吧
    2022-01-01
  • 如何利用Matlab绘制出好看的火山图

    如何利用Matlab绘制出好看的火山图

    火山图是散点图的一种,它将统计测试中的统计显著性量度和变化幅度相结合,从而能够帮助快速直观地识别那些变化幅度较大且具有统计学意义的数据点。本文将通过Matlab绘制好看的火山图,需要的可以参考一下
    2022-03-03
  • C语言中#define在多行宏定义出错的原因及分析

    C语言中#define在多行宏定义出错的原因及分析

    这篇文章主要介绍了C语言中#define在多行宏定义出错的原因及分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C语言实现多项式的相加

    C语言实现多项式的相加

    这篇文章主要为大家介绍了C语言实现多项式的相加,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 华为云CodeArts IDE Online快速入门和使用

    华为云CodeArts IDE Online快速入门和使用

    华为云CodeArts IDE Online服务,提供了可随时随地编码的云上开发环境,同时具备开放的生态和独立插件市场,本文主要介绍了华为云CodeArts IDE Online快速入门和使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • C语言非递归算法解决快速排序与归并排序产生的栈溢出

    C语言非递归算法解决快速排序与归并排序产生的栈溢出

    上期我们讲完了排序算法下,不知道小伙伴们有没有发现一个问题,快速排序和归并排序我们都是用递归来实现的,可能有小伙伴会问,如果说数据量很多话,栈区空间会不会不够用呢?这期我们就来解决使用递归实现的排序导致栈溢出如何解决
    2022-04-04
  • 一篇文章带你掌握C++虚函数的来龙去脉

    一篇文章带你掌握C++虚函数的来龙去脉

    虚函数主要通过V-Table虚函数表来实现,该表主要包含一个类的虚函数的地址表,可解决继承、覆盖的问题,下面这篇文章主要给大家介绍了如何通过一篇文章带你掌握C++虚函数的来龙去脉,需要的朋友可以参考下
    2022-10-10
  • C++定时器Timer在项目中的使用方法

    C++定时器Timer在项目中的使用方法

    这篇文章主要给大家介绍了关于C++定时器Timer在项目中的基本使用方法,文中通过示例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05

最新评论