欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-01-23 10:23:58
目录前沿功能实现定时器操作文本偏移实现控件自绘总结前沿最近可能是小视频着魔了,尤其是动画字幕效果的,身为一名技术开发人员,当然是想试一试了,哪怕只是简单的移动也是可以的~这不,说干就干拿起来我的c++...

前沿

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

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

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

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

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

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

功能实现

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

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文字浮动的资料请关注其它相关文章!

相关标签: Qt 文字 浮动