Qt开发实现字幕滚动效果

news2024/11/19 5:54:27

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)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/886397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式之原型模式Prototype的C++实现

1、原型模式提出 在软件功能设计中&#xff0c;经常面临着“某些结构复杂的对象”的创建工作&#xff0c;且创建的对象想拥有其他对象在某一刻的状态&#xff0c;则可以使用原型模型。原型模型是通过拷贝构造函数来创建对象&#xff0c;并且该对象拥有其他对象在某一刻的状态。…

嵌入式设备应用开发(linux应用的几个场景)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 linux内核是可以裁剪的,所以除了pc电脑可以用linux之外,小的嵌入式设备其实也可以用linux。前面我们讨论了soc的各个驱动,本质上还是要把这些外设用起来。操作系统帮助我们把这些…

go语言恶意代码检测系统--对接前端可视化与算法检测部分

Malware Detect System 1 产品介绍 恶意代码检测系统。 2 产品描述 2.1 产品功能 功能点详细描述注册账号未注册用户注册成为产品用户&#xff0c;从而具备享有产品各项服务的资格登录账号用户登录产品&#xff0c;获得产品提供的各项服务上传恶意样本用户可以将上传自己的…

虹科分享 | 使用工业无线方案的包装机械运输轨道系统将会是什么样子的?

背景 包装机械制造商正面临着大规模定制和客户动态需求的新挑战。随着包装机械设计向工业4.0迈进&#xff0c;灵活性、更高的吞吐量和减少停机时间成为关键要求。柔性制造系统需要具备快速更换新产品类型、重新安排操作以及根据产量和产能的重大变化进行调整的能力。因此&…

北京开发者社区简介

标题 北京城市开发者社区简介导语简介技术交流与分享创新与创业平台城市发展与科技应用线上线下活动获益和奖励 展望未来加入我们往期活动照片 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1f466;&#x1f3fb; 《java 面试题大全》 &#x1f369;惟余…

【ARM】Day4 点亮LED灯

1. 思维导图 2. 自己编写代码实现三盏灯点亮 .text .global _start _start: /**********LED1&#xff0c;LED2,LED3点灯:PE10,PF10,PE8**************/ RCC_INIT:使能GPIOE组/GPIOF组控制器,通过RXCC_MP_AHB4ENSETR设置第[5:4]位写1,地址:0x50000A28[5:4]1ldr r0,0x50000A28 …

c#设计模式-结构型模式 之 桥接模式

前言 桥接模式是一种设计模式&#xff0c;它将抽象与实现分离&#xff0c;使它们可以独立变化。这种模式涉及到一个接口作为桥梁&#xff0c;使实体类的功能独立于接口实现类。这两种类型的类可以结构化改变而互不影响。 桥接模式的主要目的是通过将实现和抽象分离&#xff0c;…

kafka线上问题优化

如何防止消息丢失 生产者&#xff1a; 使用同步发送把ack设成1或者all&#xff08;非0&#xff0c;0可能会出现消息丢失的情况&#xff09;&#xff0c;并且设置同步的分区数>2 消费者&#xff1a;把自动提交改成手动提交 如何防止重复消费 在防止消息丢失的方案中&#…

软件测试人员每天的工作日常

我现在每天9点左右从家里出发&#xff0c;9点半左右到公司&#xff0c;到公司之后王豆豆首先用养生壶煮一壶好茶&#xff0c;工作忙碌时也要记得多喝水&#xff0c;然后一边听着煮茶声一边写着当天的工作计划&#xff0c;工作计划主要包括当天工作内容、学习计划和总结。 计划…

Mysql之 optimizer_trace 相关总结

Mysql之 optimizer_trace 相关总结 MySQL官网介绍&#xff1a;https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_OPT_TRACE.html 1. 简介 MySQL优化器可以生成Explain执行计划&#xff0c;通过执行计划查看sql是否使用了索引&#xff0c;使用了哪种索&#xff1b; 但…

饿了么大数据开发凉经

1 一个mapreduce进程会启动多少map进程多少reduce进程* 1&#xff09;map数量由处理的数据分成的block数量决定default_num total_size / split_size; 2&#xff09;reduce数量为job.setNumReduceTasks(x)中x 的大小。不设置的话默认为 1。 2 讲下shuffle的过程 shuffle分为…

【Python dxfgrabber+matplotlib】显示AutoCAD导出的.dxf格式文件

代码&#xff1a; import dxfgrabber,matplotlib import matplotlib.pyplot as plt from matplotlib.patches import Polygonmatplotlib.use(TkAgg)# 使用 dxfgrabber 库加载 DXF 文件 drawing dxfgrabber.readfile(files/Main board0.DXF)# 创建 Matplotlib 图形 fig, ax p…

【无线点对点网络时延分析和可视化】模拟无线点对点网络中的延迟以及物理层和数据链路层之间的相互作用(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Stimulsoft Reports 2023Crack

Stimulsoft Reports 2023Crack Stimulsoft Reports.BLAZOR是一个跨平台的报告工具&#xff0c;用于集成应用程序&#xff0c;使用BLAZOR框架工作。我们的组件支持Blazor的所有主要功能。通过使用WebAssembly技术&#xff0c;它们既可以在.NET服务器端工作&#xff0c;也可以在…

Linux学习之firewallD

systemctl status firewalld.service查看一下firewalld服务的状态&#xff0c;发现状态是inactive (dead)。 systemctl start firewalld.service启动firewalld&#xff0c;systemctl status firewalld.service查看一下firewalld服务的状态&#xff0c;发现状态是active (runni…

贪心(一)

一、区间问题 1.1区间选点 #include<iostream> #include<algorithm>using namespace std;const int N 100010;int n; struct Range {int l,r;bool operator < (const Range &w)const{return r < w.r;} }range[N];int main() {scanf("%d",&a…

JVM元空间溢出的排除思路

背景&#xff1a; java的应用我们为了防止元空间的无限扩展&#xff0c;一般都会设置MaxMetaSpace参数&#xff0c;一般来说只要这个值是512M或者1G左右就足够了&#xff0c;不过今天遇到一个meta空间溢出问题&#xff0c;简单记录下排除的思路 meta元空间溢出 最开始的现象…

【Vue3.0 ——指令学习】

v-text 期望值是string v-html 期望值&#xff1a;string 注意&#xff1a;在你的站点上动态渲染任意的HTML是非常危险的&#xff0c;因为他很容易导致XSS攻击。请只对可信内容使用HTML差值&#xff0c;绝不要将用户提供的内容作为插值 scoped将不会作用于v-html&#xff0…

【悬挂绝缘子的串效模型】测量每个绝缘子盘之间的电压并测量串效研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

解析错误:‘import‘和‘export‘可能只出现在顶层

1、import引入文件时&#xff0c;提示Parsing error: ‘import’ and ‘export’ may only appear at the top leveleslint 中文含义&#xff1a;解析错误:import和export可能只出现在顶层&#xff0c;如下提示&#xff1a; 2、下载包npm i babel/eslint-parser -D 在此配置中…