一 主程序事件循环函数崩溃 :

a.exec()处崩溃

该处崩溃一般调试的时候显示的堆栈信息停止的位置都是QT的dll库。我们的代码中只给出了a.exec()崩溃。

原因一:
子线程中更改界面上控件。在Qt事件循环中一般只有主线程可以用来改变某一个显示控件的状态。子线程想要改变界面时可以给主程序发信号。

原因二:
在事件循环中,有部分控件访问的地址越界
例如:

QPixmap q_pixmap;
	//my_frame.data 是一块连续的内存空间,存放自定义图像数据。该类型创建的QImage数据为浅拷贝
	QImage q_image(static_cast<uchar*>(my_frame.data), width, height, QImage::Format_Grayscale8);
	//pix_image 内部数据指针指向my_frame.data 所在地址。pix_image 只要不对图片进行更改就不会进行真正的深拷贝复制。
	pix_image = pix_image.fromImage(img_image, Qt::ImageConversionFlag::NoFormatConversion);
	QLabel label;
	label.setPixmap(pix_image);

当自定义的分配的那一块图像缓冲区被释放时,QT程序因为label上的图片数据指针被释放,指向了无效数据空间。该控件可能有权限访问也可能没有,就会造成随机崩溃。提现在代码上就是主程序事件循环上崩溃。

二、窗口关闭后程序未正常退出

qt最简单的事件循环启动方式,创建一个可以启动Qt事件循环的类,之后调用exec(),即可启动事件循环
常见可启动事件循环的Qt类有:QApplication, QCoreApplication, QGuiApplication, QEventLoop, QDialog, QMessageBox, QThread

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	app.exec();
	return 0;
}

一般我们程序退出是点击主窗口的关闭按钮,按钮会触发closeEvent()函数,在closeEvent函数内,当我们接受了关闭事件时后,app的事件循环就会退出,即app.exec()函数会有返回,此时程序就退出了。

为何窗口的关闭事件接受后会触发app退出事件循环:
因为Qt默认带有Qt::Window属性的窗口会自动被设置上另外一个属性Qt::WA_QuitOnClose。包含Qt::WA_QuitOnClose属性的最后一个窗口在接受closeEvent()事件后,QApplication 就会自动退出事件循环。所以当我们关闭了所有包含Qt::Window的窗口后我们的程序就退出了。

注意通常带有窗口系统框架和标题栏的部件(窗口或小部件)都会有Qt::Window属性。

未正常退出原因:
  1. 主窗口重新写了closeEvent()函数,函数内没有接受closeEvent事件。即使窗口被隐藏甚至被删除,事件循环也不会退出,程序不会节数
  2. 子窗口未正常关闭
解决办法
  1. 在closeEvent()函数中调用event->accept()。接受关闭事件
  2. 如果上面的不好使可以改成调用qApp->quit(),显示退出事件循环