Qt处理耗时任务,显示等待界面的两种方式,并防止界面假死与用户误操作

目录

一、弹出对话框,对话框显示gif动图

二、弹出进度条


一、弹出对话框,对话框显示gif动图

效果如下:

1 新建一个QWidget,类名为QWaiting,里面放两个QLabel ,一个用于显示动图,一个显示文字,设定栅格布局,如下

被忘了把动图先加载到资源里,动图的话这里提供两个网址:

http://www.lanrentuku.com/gif/a/loading_2.html

http://blog.sina.com.cn/s/blog_4ad042e50102ek2v.html

2  在QWaiting里面加载动图

#include "qwaiting.h"
#include <QMovie>

QWaiting::QWaiting(QWidget *parent)
	: QDialog(parent)
	, m_Move(NULL)
{
	ui.setupUi(this);

	//设置透明度
	this->setWindowOpacity(0.8);

	/* Qt::Dialog
	Indicates that the widget is a window that should be decorated as a dialog (i.e., typically no maximize or minimize buttons in the title bar). This is the default type for QDialog. If you want to use it as a modal dialog, it should be launched from another window, or have a parent and used with the QWidget::windowModality property. If you make it modal, the dialog will prevent other top-level windows in the application from getting any input. We refer to a top-level window that has a parent as a secondary window.
	*/

	/*Qt::FramelessWindowHint
	Produces a borderless window. The user cannot move or resize a borderless window via the window system. On X11, the result of the flag is dependent on the window manager and its ability to understand Motif and/or NETWM hints. Most existing modern window managers can handle this.
	*/

	/*Qt::WindowModal
	The window is modal to a single window hierarchy and blocks input to its parent window, all grandparent windows, and all siblings of its parent and grandparent windows.
	*/
	//取消对话框标题
	setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);//设置为对话框风格,并且去掉边框
	setWindowModality(Qt::WindowModal);//设置为模式对话框,同时在构造该对话框时要设置父窗口
	ui.label->setStyleSheet("background-color: transparent;");
	m_Move = new QMovie(":/fileMove/wait.gif");
	ui.label->setMovie(m_Move);
	ui.label->setScaledContents(true);
	m_Move->start();
}

QWaiting::~QWaiting()
{
	m_Move->stop();
}

3 调用

	QWaiting *pQwait = new QWaiting(this);
	pQwait->show();

	for (int i = 0; i < m_fileList.size(); i++)
	{
		srcFileName = m_Src + "/" + m_fileList.at(i);
		destFileName = m_Dest + "/" + m_fileList.at(i);

		if (QFile::copy(srcFileName.simplified(), destFileName.simplified()))
		{
			iSucceed = iSucceed + 1;
		}

		QCoreApplication::processEvents();
	}

	pQwait->close();

这里注意使用QCoreApplication::processEvents()是防止界面假死,该函数的作用是让程序处理那些还没有处理的事件,然后再把使用权返回给调用者。

因为弹出的等待对话框是模式的,因此在他运行期间鼠标是无法点击父窗口的。这样防止了用户在任务没有处理完时误点击关闭了主窗口。

但如果此时就有在处理任务期间点击主界面的需求该怎么办?

此时因把QWaiting中的

setWindowModality(Qt::WindowModal);//设置为模式对话框,同时在构造该对话框时要设置父窗口

这样对话框就变成了非阻塞的。 

去掉,并且把

QCoreApplication::processEvents();

修改成

QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);

这样的话用户的鼠标和键盘操作都将被留在消息队列里而不被处理。实际测试发现,它只屏蔽了关闭事件,但可以最大最小化主窗口。

4 总结

要想防止用户点击关闭主窗口有两种方式。

一是将QWaiting设为模态对话框

二是QWaiting设为非模式,但在处理任务时屏蔽用户鼠标操作。

但是这里的动图不是透明的,可能不太美观,可以找美工做背景透明的动图。也可以用几张图片循环显示,可参考:

https://blog.csdn.net/liang19890820/article/details/51029355

二、弹出进度条

效果如下

1 关键代码如下


	QApplication::setOverrideCursor(Qt::WaitCursor);//设置鼠标为等待状态
	QProgressDialog progress;
	progress.setWindowTitle(QString::fromLocal8Bit("提示"));
	progress.setLabelText(QString::fromLocal8Bit("正在移动中..."));
	progress.setCancelButtonText(QString::fromLocal8Bit("取消"));
	progress.setRange(0, m_fileList.size());//设置范围
	progress.setModal(true);//设置为模态对话框
	progress.show();
	for (int i = 0; i < m_fileList.size(); i++)
	{
		srcFileName = m_Src + "/" + m_fileList.at(i);
		destFileName = m_Dest + "/" + m_fileList.at(i);

		if (QFile::copy(srcFileName.simplified(), destFileName.simplified()))
		{
			progress.setValue(i);
			iSucceed = iSucceed + 1;
		}

		//用户取消的话则中止
		if (progress.wasCanceled())
		{
			break;
		}

		//QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
		QCoreApplication::processEvents();
	}
	QApplication::restoreOverrideCursor();
	progress.close();
	QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("共移动%1个文件!").arg(iSucceed));

这里的

	progress.setModal(true);//设置为模态对话框

的作用与QWaiting里的

setWindowModality(Qt::WindowModal);//设置为模式对话框,同时在构造该对话框时要设置父窗口

作用一致。 

你也可以不设为模态,而在任务里屏蔽用户鼠标操作,这里不再赘述。

例子下载:

https://download.csdn.net/download/qq_24282081/11344372

  • 36
    点赞
  • 242
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值