Qt模仿实现文字浮动字母的效果

目录
  • 前沿
  • 功能实现
    • 定时器操作
    • 文本偏移实现
    • 控件自绘
  • 总结

前沿

最近可能是小视频着魔了,尤其是动画字幕效果的,身为一名技术开发人员,当然是想试一试了,哪怕只是简单的移动也是可以的~

这不,说干就干拿起来我的C++语言就要尝试,还好使用的Qt框架,这样是使用MFC框架写小demo,真的好困难呀!

先来看一看我实现的效果吧~

效果很简单就是文本向上移动,在移动过程中文字整体变大或缩小。

那么,我就来讲解下我是如何实现的吧!

功能实现

在实现这个文本移动的效果过程中,用到了以下几个功能:

1:定时器

2:QLabel控件自绘

定时器操作

在QWidget中提供了一个定时器操作函数,我们只需要继承就可以实现了

virtual void timerEvent(QTimerEvent *event);

使用QWidget自带的定时器操作时,就不需要new QTiemr的方式了,只需要使用int值记录当前开启定时器编号,等达到触发时间后进行处理即可。

文本偏移实现

首先在实现之前,先来讲解下主要流程是怎么回事吧!

1:定义文本移动定时器

2:每一秒触发一次,每次触发都需要创建一个新的控件用于展示内容。

3:触发后将已经展示的文本遍历方式向上整体偏移,偏移过程中会根据随机数,随机更改文本字体的大小。

4:字体变化,导致文本的宽度高度变更,用新的宽度、高度计算偏移后的位置。

在这里,我们可以对QLabel控件进行重绘,假设叫做QCustomLabel,父类是QLabel。那么我来一步一步地讲解我是如何实现定时器偏移的吧~

第一步

定义容器用于存储需要展示的文本内容,这里可以用一个简单的容器vector来记录,std::vector< std::string >m_vetContent;

第二步

定义容器用于存储已经展示过的文本控件,使用QVector来记录,QVector<QCustomLabel*> m_vetControls;

为什么第一步和第二步都是用vector记录,但是一个使用C++的,另一个使用Qt的呢?

其实在第一步与第二步存储过程中,都可以使用QVector来进行记录,有一点需要注意的是,第二步存储必须使用QVector。

为什么?因为vector与QVector存储都是先入先出的形式,我们在记录控件指针时,最先拿出的控件指针应该是后插入的数据。在QVector中从前端插入数据更为方便些,索性这两个步骤用的容器就稍微有一些差别了,你get到了吗?

第三步

触发定时器后,临时创建显示文本的控件数据,并及时存储到容器m_vetControls中,以防销毁窗口时不及时销毁指针导致的内存泄漏问题。

QCustomLabel *lab = new QCustomLabel(this);
QSize size = lab->SetTextData(m_vetContent[m_nTimerTriggerNumber], 1);
int nTop = (height() - size.height()) / 2;
lab->setGeometry(DistanceLeft, nTop, size.width(), size.height());
lab->show();
m_vetControls.push_font(lab);

使用QVector的push_font()方法,每次存储的数据都最先展示,也就是将数据存储到下标为0的位置下。

第四步

数据存储后,更新所有展示的文本控件位置,这里使用:UpdateShowRectStyle()函数进行实现哦~

for (int i = 0; i < m_vetControls.size(); i++)
{
	QCustomLabel *lab = m_vetControls[i];
	QSize size = lab->UpdateZoomStyle(bFontZoom);
	QRectF rectF = lab->geometry();
	if (nTop == 0)
	{
		nTop = lab->geometry().top();
	}
	else
	{
		nTop = nTop - size.height();
	}
	lab->move(DistanceLeft, nTop);
}
this->update();

循环遍历整个存储控件指针的数据内容,在更新位置的同时更改文本缩放大小(也就是变化字体大小),获取最新的变更位置,重新获取宽度、高度。

假设当前的高度是0时,说明是第一条数据需要变更,偏移的位置,直接是控件的高度; 假设当前的高度非0时,说明是偏移过程中的某一条数据,因为是向上偏移,所有每次计算偏移后的高度时,都需要做减法,如果是向下偏移,每次计算偏移后的高度就是做加法了。

第五步

当读写完所有的显示内容时,停止定时器操作

if (m_nTimerTriggerNumber == m_vetContent.size())
{
	killTimer(m_nTimerId);
	m_nTimerId = 0;
}

到这里,文字自动偏移的功能就实现了,接下来我们来讲一讲是如何自绘QLabel控件吧~

控件自绘

首先我们需要定义QLabel的自绘类,这里我给除了简单的框架,以后需要什么功能直接追加就可以啦~

.h 使用

#pragma once

#include <QLabel>

class QCustomLabel : public QLabel
{
	Q_OBJECT

public:
	QCustomLabel(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
	~QCustomLabel();
};

.cpp 使用

#include "QCustomLabel.h"
QCustomLabel::QCustomLabel(QWidget *parent, Qt::WindowFlags f)
	: QLabel(parent, f)
{
}

QCustomLabel::~QCustomLabel()
{
}

想要实现什么功能,就只需要在这个基础上扩充就可以了。

在自绘QLabel中有两个重点

1:如何根据字体的大小固定文本区域?

2:文字闪烁效果实现

根据这两个重点来绘制QLable控件吧!

功能1:

字体的大小可以使用随机数qrand()来实现。

使用方法:

QTime time = QTime::currentTime();
qsrand(time.msec() + time.second() * 1000);
int nFontSize = qrand() % 30 + 20;

这种方式生成的随机数保证了唯一性。

根据字体大小,设置QFont的属性

QFont fontContent =this->font();
//设置:字体样式:微软雅黑
fontContent.setFamily("Microsoft YaHei");
//设置:字体大小:22
fontContent.setPixelSize(nFontSize);
//字体绑定
this->setFont(fontContent);

重点来啦!!!

设置了字体风格之后,这时候我们是可以获取到字体的高度的,但是整体的宽度是获取不到的需要动态获取。

QFontMetrics metrics(font());
int nheight = metrics.height();
//设置内容并存储文本内容
m_qsTextContent = QString::fromLocal8Bit(sText.c_str());
setFixedHeight(nheight);
this->setText(m_qsTextContent);
this->adjustSize();
int nwidth = this->width();
//设置自定义QLable控件的宽度以及高度
QSize size(nwidth , nheight);

//开启定时器
m_nTimerId = startTimer(100);
return size;

功能2:

文字颜色渐变展示。

这个功能很简单,核心就是实时的更新QColor值,这里我使用了随机数使每次生成的颜色值都不相同

QFontMetrics metrics(font());
int x = 0;
int y = (height() + metrics.ascent() - metrics.descent()) / 2;
QColor color;
for (int i = 0; i < m_qsTextContent.size(); i++)
{
	//设置:色调(H)、饱和度(S)、亮度(Y)
	int nIndex = (m_nStep + i) % 16;
	color.setHsv((15 - nIndex) * 16, 255, 191);
	painter->setPen(color);
	//单个字符绘制
	painter->drawText(x, y, QString(m_qsTextContent[i]));
	//计算下一个字符的x坐标起始点
	x += metrics.width(m_qsTextContent[i]);
}

总结

到这里,文字移动效果就已经实现了,功能比较简单,唯一的难点就在于文字风格变动时,区域的变化,只要我们了解了变化规律,位置展示还不是小菜一碟吗?

以上就是Qt模仿实现文字浮动字母的效果的详细内容,更多关于Qt文字浮动的资料请关注我们其它相关文章!

(0)

相关推荐

  • 如何为Qt视图中的文字实现彩虹渐变效果

    前言 将view中的文本内容用自定义的颜色显示是一种十分常见的需求.今天我们稍微改变些"花样".下面话不多说了,来一起看看详细的介绍吧 需求定义 我们的需求很简单,现在有一些在view中的text内容需要使用彩色显示,而且不使用单一的一种颜色,而是多种颜色渐变实现的彩虹效果. 文字描述可能比较抽象,所以我们先给出预想的效果图: 现在让我们想办法实现图中的效果. 需求分析 好在Qt的Model/View机制对于用户自定义的外观控制提供了极为丰富的支持,因此我们可以轻松地实现许多独特的显示

  • Qt实现字符串生成二维码功能

    目录 前言 开发环境 实现步骤 资源包数据 配置属性 二维码操作 总结 前言 最近在整理开发项目中遇到的知识点,发现了一个特别有意思的功能:使用字符串生成二维码操作. 下面是实现的效果图 开发环境 WIN10环境 + VS2017 + Qt 5.14.2 64位开发环境 实现步骤 资源包数据 说实话我的开发环境还真是挺麻烦的~ 想要使用Qt使用二维码功能,必须要外加 "qrencode"库.针对我目前用的环境使用cmake编译了一个dll库 编译出来的文件包含了两个:lib和src,如

  • Qt实现樱花飞舞效果

    本文实例为大家分享了Qt实现樱花飞舞效果的具体代码,供大家参考,具体内容如下 应女友要求,使用Qt做了一个在电脑桌面樱花飞舞的小程序.这里面用到了Qt动画效果QPropertyAnimation类来控制飞舞效果.使用label加载樱花图案.大概的核心代码如下: Widget::Widget(QWidget *parent) : QWidget(parent), timer(new QTimer(this)), pixmap(new QPixmap(":/cherry.png")), u

  • Qt基于定时器实现动图展示效果

    本文实例为大家分享了Qt基于定时器实现动图展示的具体代码,供大家参考,具体内容如下 总体概述 (1)总体介绍 动图展示主要是将已有的动图逐帧图片连续输出,达到视觉上的动态图效果,本次介绍两例,分别为单一动图和分组动图. 主要原理是设置一个定时器,然后随设置的秒数将资源中的逐帧图片输出,让图片连续变化. (2)素材获得途径 关于素材来源,可以到网站下载现成的逐帧图片素材包,也可以找到自己喜欢的动态图,通过软件(如:爱奇艺万能播放器)将动图逐帧保存得到素材. (注意:不论通过哪种方式获得素材,都需要

  • QT实现年会抽奖小软件的示例代码

    目录 一.效果展示: 二.软件代码介绍 1.工程目录 2.核心代码之主类代码部分 3.核心代码之线程类代码部分 一.效果展示: 1.操作说明 下拉选择主题,点击开始按钮,开始滚动,再次点击停止,显示幸运之星及名称.中选人员不参与接下来的抽取,除非软件重启或点击复位按钮. 二.软件代码介绍 1.工程目录 2.核心代码之主类代码部分 main.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include &l

  • Qt模仿实现文字浮动字母的效果

    目录 前沿 功能实现 定时器操作 文本偏移实现 控件自绘 总结 前沿 最近可能是小视频着魔了,尤其是动画字幕效果的,身为一名技术开发人员,当然是想试一试了,哪怕只是简单的移动也是可以的~ 这不,说干就干拿起来我的C++语言就要尝试,还好使用的Qt框架,这样是使用MFC框架写小demo,真的好困难呀! 先来看一看我实现的效果吧~ 效果很简单就是文本向上移动,在移动过程中文字整体变大或缩小. 那么,我就来讲解下我是如何实现的吧! 功能实现 在实现这个文本移动的效果过程中,用到了以下几个功能: 1:定

  • Qt模仿Visual Studio停靠窗口效果

    前言 众所周知,停靠窗口可以实现任意拖动效果,本文重点在于如何利用Qt制作与Visual Studio相似的带有停靠方向标及停靠区域预览的的停靠窗口框架. 效果图 功能 1.鼠标在中间方向标:叠加窗口2.鼠标在上下左右方向标:分割目标窗口,并紧挨着目标窗口周边位置添加新窗口3.鼠标在内部最上下左右方向标:目标窗口所在的最上下左右位置添加新窗口4.鼠标在外部最上下左右方向标:程序主窗口的最上下左右位置添加新窗口5.鼠标在Tab位置上:在当前所在tab页位置插入新窗口6.鼠标在Tab最右侧位置上:在

  • js仿黑客帝国字母掉落效果代码分享

    看过黑客帝国的朋友或许都对开头的字幕效果很熟悉,自从影片播放以来,网页设计者有不少都在模仿这种字母掉落的效果,而且最后还有文字显现效果"I love you",你可以稍加修改,在情人节,用来对你的恋人表白哦~ 运行效果图: 大家也动手运行一下,                                      ----------------效果演示---------------- 为大家分享js仿黑客帝国字母掉落效果代码如下 <head> <meta htt

  • JavaScript实现的圆形浮动标签云效果实例

    本文实例讲述了JavaScript实现的圆形浮动标签云效果.分享给大家供大家参考.具体如下: 这里介绍的JS标签云效果,在鼠标的作用下会自动转动,整体上围绕成一个圆形,各个标签之间无需Div代码,直接文字+链接的形式,有多少就显示多少,JavaScript会自动调整显示数量,让视觉效果最佳. 运行效果如下图所示: 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://

  • JS实现slide文字框缩放伸展效果代码

    本文实例讲述了JS实现slide文字框缩放伸展效果代码.分享给大家供大家参考,具体如下: 这里介绍的slide文字框缩放伸展效果,自己闲来无事写的,不是太好,可能在兼容性方面还需努力,展开速度方面,IE8和火狐的展开速度不一样,火狐下更快一些,至今没找到原因,也请JS高人指点江山. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-slide-txt-dlg-show-codes/ 具体代码如下: <!DOCTYPE html> <h

  • Android开发之自定义view实现通讯录列表A~Z字母提示效果【附demo源码下载】

    本文实例讲述了Android开发之自定义view实现通讯录列表A~Z字母提示效果.分享给大家供大家参考,具体如下: 开发工具:eclipse 运行环境:htc G9 android2.3.3 话不多说,先看效果图 其实左右边的A~Z是一个自定义的View,它直接覆盖在ListView上. MyLetterListView: public class MyLetterListView extends View { OnTouchingLetterChangedListener onTouching

  • 基于Jquery制作图片文字排版预览效果附源码下载

    基于jQuery图文排版图片预览特效.这是一款基于jQuery+CSS3实现的鼠标点击图片弹出画廊切换特效. 效果图如下所示,怎么样感兴趣吗,感兴趣的朋友继续往下学习哦. 效果演示    源码下载 html代码: <div id="fullscreen"> <div id="fullscreen-inner"> <div id="fullscreen-inner-left" class="fullscree

  • 利用JS实现文字的聚合动画效果

    前言 所谓文字聚合效果,原理就是将容器分为若干的小块,然后每个小块设置 background-poisition ,最后添加css3动画就可以了,去掉注释,也就仅仅20行的代码. 先来看看效果图: js代码如下: //c为列数,r为行数,把box划分成多少个小块 var box = document.querySelector('.boxWrap1'),c=4,r=8; //每个小块的宽高 var w = box.offsetWidth/c,h = box.offsetHeight/r; //循

  • jQuery插件实现文字无缝向上滚动效果代码

    本文实例讲述了jQuery插件实现文字无缝向上滚动效果代码.分享给大家供大家参考,具体如下: 此插件旨在实现目前较为流行的无缝向上滚动特效,当鼠标移动到文字上时,向上滚动会停止,当鼠标离开时,向上滚动继续.整体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&

  • 基于JS模仿windows文件按名称排序效果

    作个记录,主要是对数字的处理,如果数字的前面字符是相同的,则数字以值比较,而不是单个字符之间的比较. function SortLikeWin(v1, v2) { var a = v1.name; var b = v2.name; var reg = /[0-9]+/g; var lista = a.match(reg); var listb = b.match(reg); if (!lista || !listb) { return a.localeCompare(b); } for (var

随机推荐