Qt防止同步请求界面卡死

1、一念、一瞬、一弹指

古代的梵典《僧祗律》中有这样的记载:一刹那者为一念,二十念为一瞬,二十瞬为一弹指,二十弹指为一罗预,二十罗预为一须臾,一日一夜有三十须臾。根据时间推算,一须臾为48分钟,一弹指为7.2秒,一瞬为0.36秒,一念为0.018秒。
而我们在使用Qt做应用程序中,同步请求是必不可少的操作,但当同步请求耗时比较久呢?
理想状态下,页面之间的跳转需要在瞬间解决,而页面内的操作需要在刹那间完成。实际情况之下呢?似乎都没有那么在意,慢慢的,会给我们造成一种潜意识,软件,慢一点是正常。
是的,慢一点,也无可厚非,但这只是在普通的领域。如果涉及到交易呢?慢一点可能会造成不可估量的损失,毕竟只要涉及到钱的事,都会比较敏感。
为了给用户良好的体验,超过一弹指的请求需要有进度提示,并且能够随时终止或者取消。是的,曾经我也是追求请求的极致,现在,制造业软件中,总是觉得,时间久一点,也会心安理得。

2、解决卡死

同步请求呢,存在的意义就是必须要等这个请求完成才能进行下一步操作,否则那就死等。。。等的不耐烦了或者手贱一下,多点了几次,恐怖的事情就会发生,轻则卡死转圈圈,重则直接崩溃或者闪退。
别着急,经历的多了,也就麻木了。话虽这么说,该解决的问题还是要解决。
手边有一个任务,导入一份比较大的数据,需求呢:文件读取,3个服务器,串行导入,每个服务器都自己的db,并且共用一个SQLserver。
这个请求的耗时就会有点恐怖,为了防止操作人员不耐烦的点击和给他一个显眼的提示,巧妙的使用了Qt的多线程和一个交互,虽然没有提升性能,至少能防止界面卡死,并且能告诉操作人员需要等待。
交互是比较简单的交互,发起该请求之后,界面给一层蒙版,防止点击,再给一个不断循环的圈圈。
首先看下圈圈的实现:

#include <QDialog>
#include <QMovie>

namespace Ui {
class LoadingWidget;
}

class LoadingWidget : public QDialog
{
    Q_OBJECT
public:
	static LoadingWidget*     instance();	    //获取单实例
	static void	        	  release();		//释放单实例;
	
	void start();
	void stop();

private:
	explicit LoadingWidget(QWidget *parent = Q_NULLPTR);
	~LoadingWidget();
	void initPage();
private:
	Ui::LoadingWidget* ui;
	static LoadingWidget* m_pSelf;
	QMovie* m_pMovie{ Q_NULLPTR };
};

实现呢,比较简单,就是找一个动画,做成动画。

void LoadingWidget::initPage()
{
	setWindowOpacity(0.2);
	setWindowFlags(Qt::FramelessWindowHint/* | Qt::WindowStaysOnTopHint */| Qt::WindowSystemMenuHint | Qt::SubWindow);
	m_pMovie = new QMovie(":/LoadingWidget.gif");
	ui->label->setMovie(m_pMovie);
}

void LoadingWidget::start()
{
	m_pMovie->start();
	exec();     // 启动之后阻塞
}

void LoadingWidget::stop()
{
	m_pMovie->stop();
	reject();
}

下面看下实际应用的过程:

一个同步请求,调用完成之后就不再需要占用资源,所以我们现在Qt中临时启动线程的方式来做。

#include <QtConcurrent/QtConcurrent>
#include <QFuture>

实际的调用过程:

QFuture<void> func = QtConcurrent::run(this, &TestWidget::importPointThread, path);
LoadingWidget::instance()->start();

上面我们就完成了防止界面卡死的操作,其中,&TestWidget::importPointThread 是需要执行的函数地址,path是其入参,之后调用LoadingWidget::Instance()->start();实现界面交互。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值