Qt程序退出相关资源释放问题

目录

问题背景:

aboutToQuit

代码举例

资源释放函数注意事项

closeEvent事件

代码举例

程序退出方式

quit()

[exit(int returnCode = 0)](#exit(int returnCode = 0))

close()


问题背景:

实际项目中程序退出前往往需要及进行一些资源释放、配置保存、线程中断等操作,避免资源浪费,配置参数丢失等;但是Qt程序默认的退出方式并不能释放主动申请的这些资源,因此在程序关退出前需要主动进行资源回收和记录退出方式等。

aboutToQuit

aboutToQuit信号是QCoreApplication类的一个信号,它在应用程序即将退出时发出。这个信号对于在应用程序关闭前执行一些清理工作非常有用,比如保存设置、释放资源等。 使用场景:通常连接到一个槽函数,用于处理应用程序退出前的清理工作。

代码举例

通过连接 aboutToQuit信号到资源释放槽函数,从而达到在程序退出前进行资源释放操作。

cpp 复制代码
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	THWritterTool w;
	w.show();
	QObject::connect(qApp, &QCoreApplication::aboutToQuit, [&]() {
				cLogger("THWritterTool")->info("THWritterTool程序正常退出!");
				w.Destroy();
				ReleaseResource();
			});
	int ret = a.exec();
	//在事件循环结束后进行一些资源释放 一些非正常退出无aboutToQuit信号
	releaseResource();
	return ret;
}

资源释放函数注意事项

在上面的额代码中releaseResource函数调用了两次是为了防止一些异常退出没有触发aboutToQuit信号,从而导致资源无法释放。但是正常情况下该函数会调用两次,因此releaseResource函数种要确保资源只被释放一次。此处一种解决方案可以用std::call_once和std::once_flag解决此问题。

cpp 复制代码
	void ReleaseResource()
    {
		 std::call_once(m_releaseFlag, []()
		 {
			//...
			 g_pSplashScreen->releaseInstance();
			 
			 cLogger("unInit")->info("vehicleApi::httpServer.stopServer");
			 vehicleApi::httpServer.stopServer();
			 g_CacheHelper->saveCfg();
			 g_CacheHelper->free();
			 cLogger("unInit")->info("PlatformPluginManager::free");
			 //...
			 //...
			 cLogger("unInit")->info("All finished");
		 });
	 }

closeEvent事件

closeEvent是QWidget类的一个事件处理函数,当窗口关闭时,Qt会调用这个函数。通过重写主界面的这个函数可在窗口关闭前执行一些自定义的操作,比如询问用户是否真的要关闭窗口,或者保存未保存的数据。

代码举例

cpp 复制代码
void THWritterTool::closeEvent(QCloseEvent * event)
{
	if (!m_AuthorithyVertify)
	{
		QTHMessageBox::TimerMessage(this, QMessageBox::Critical, QObject::tr("授权未验证通过,程序即将退出!"), 15 * 1000);
		cLogger("THWritterTool")->info("授权未验证通过退出");
	}
	else if (m_switchDB)
	{
		QTHMessageBox::TimerMessage(this, QTHMessageBox::Critical, QObject::tr("数据库已切换,程序即将退出!"), 15 * 1000);
		cLogger("THWritterTool")->info("切换数据库程序退出");
	}
	else
	{
		if (m_savingCfg)
		{
			QTHMessageBox::TimerMessage(this, QTHMessageBox::Warning, QObject::tr("正在保存配置文件,无法退出。"), 15 * 1000);
			event->ignore();//忽略退出事件
			return;
		}

		ret = QTHMessageBox::question(this, tr("是否要退出程序?"), QTHMessageBox::Yes | QTHMessageBox::No);
		if (ret == QTHMessageBox::Yes)
		{
			cLogger("THWritterTool")->info("用户手动确认退出");
		}
	}

	cLogger("THWritterTool")->info("正常退出");
	Destroy();
	event->accept();//接收事件 不在传递
}

程序退出方式

quit()

• quit()是QCoreApplication类(以及继承自它的QApplication类)的一个静态函数,用于退出整个Qt应用程序。

• 当调用quit()时,它会退出主事件循环,触发QApplication::exec()返回,并关闭所有打开的窗口。程序会完全终止。

• quit()通常用于在应用程序中实现"退出"功能,比如在菜单项的"退出"操作上绑定这个函数。

• quit()作为槽函数,也可以连接信号和槽,响应某个信号后关闭应用程序。

• 调用quit后程序在退出前会触发aboutToQuit信号

exit(int returnCode = 0)

• exit()和quit()类似,也是用于退出应用程序。

• exit()可以指定一个返回代码(returnCode),该代码将在应用程序退出时返回给操作系统。

• 它同样会结束主事件循环并关闭所有窗口。

• exit()更适合在需要返回特定退出代码的场景中使用。

• 调用exit后程序在退出前会触发aboutToQuit信号

close()

• close()是QWidget类的成员函数,用于关闭单个窗口或控件。

• 调用close()会尝试关闭该窗口或控件,关闭前会触发closeEvent()事件。如果该窗口是主窗口,且所有子窗口都已关闭,应用程序会退出,退出前会触发和aboutToQuit信号。

• close()适用于关闭单个窗口或控件的场景,比如"关闭"按钮的操作。

• 当用户点击窗口右上角的"X"按钮时,系统也会自动调用该窗口的close()函数。

相关推荐
滴_咕噜咕噜30 分钟前
C#基础总结:常用的数据结构
开发语言·数据结构·c#
martian66530 分钟前
【Java高级篇】——第16篇:高性能Java应用优化与调优
java·开发语言·jvm
许苑向上1 小时前
Java八股文(下)
java·开发语言
菜鸟一枚在这1 小时前
深入解析设计模式之单例模式
开发语言·javascript·单例模式
独孤求败Ace1 小时前
第44天:Web开发-JavaEE应用&反射机制&类加载器&利用链&成员变量&构造方法&抽象方法
java·开发语言
计算机-秋大田2 小时前
基于Spring Boot的农产品智慧物流系统设计与实现(LW+源码+讲解)
java·开发语言·spring boot·后端·spring·课程设计
matlabgoodboy2 小时前
Matlab代编电气仿真电力电子电机控制自动化新能源微电网储能能量
开发语言·matlab·自动化
镰圈量化2 小时前
当电脑上有几个python版本Vscode选择特定版本python
开发语言·vscode·python
背太阳的牧羊人2 小时前
RAG检索中使用一个 长上下文重排序器(Long Context Reorder) 对检索到的文档进行进一步的处理和排序,优化输出顺序
开发语言·人工智能·python·langchain·rag
ITPUB-微风2 小时前
美团MTSQL特性解析:技术深度与应用广度的完美结合
java·服务器·开发语言