前言
创建Qt App项目的时候,我们总能在main函数里面见到
正文
这里可以看到它继承自QGuiApplication,而QGuiApplication又继承自QCoreApplication
剩下的我就挑一些重要的来说
notify()
它是一个虚函数,重载了QGuiApplication中的notify函数
1. 作用
notify 函数负责将事件(如鼠标点击、键盘输入、窗口大小改变等)分发给对应的接收对象(通常是 QObject 或其子类)。当一个事件发生时,Qt 框架会通过 QApplication::notify 将该事件传递给目标对象。
2. 函数原型
virtual bool notify(QObject *receiver, QEvent *event) override;
receiver:这是指向事件的目标对象的指针,即事件的接收者。event:这是指向要发送的事件的指针。
3. 返回值
- 返回
true 表示事件已被处理。 - 返回
false 表示事件未被处理,通常意味着事件会继续被传递给其他可能的处理者,或者被忽略。
4. 典型用途
-
事件拦截和自定义处理:通过继承 QApplication 并重写 notify 方法,可以在事件分发之前拦截事件,做一些自定义处理。例如,你可以在应用程序中实现全局的事件过滤、日志记录、异常捕获、调试信息输出等。
class MyApplication : public QApplication
{
public:
MyApplication(int &argc, char **argv)
: QApplication(argc, argv) {}
bool notify(QObject *receiver, QEvent *event) override
{
if (event->type() == QEvent::MouseButtonPress) {
qDebug() << "Mouse button pressed!";
}
return QApplication::notify(receiver, event);
}
};
-
全局异常处理:可以在 notify 函数中捕获异常,防止程序因为未捕获的异常而崩溃。这样可以增加程序的稳定性和健壮性。
bool MyApplication::notify(QObject *receiver, QEvent *event) {
try {
return QApplication::notify(receiver, event);
} catch (std::exception &e) {
qCritical() << "Exception caught:" << e.what();
return false;
}
}
5. 注意事项
-
性能影响:因为 notify 是事件处理的核心函数,重写时应谨慎处理,避免引入大量计算或复杂逻辑,这可能会影响整个应用程序的性能。
-
调用基类方法:在重写 notify 函数时,通常需要调用基类的 QApplication::notify 方法,以确保事件能够被正常分发到目标对象,除非你有特殊需要阻止事件的传递。
-
线程安全:notify 可能会在多个线程中被调用,因此在重写 notify 时,确保代码是线程安全的。
exec()
int QApplication::exec() 是 QApplication 类的一个成员函数,它是启动 Qt 事件循环的核心函数。exec() 函数将阻塞,直到应用程序退出为止,因此通常是应用程序的最后一个函数调用。
1. 作用
exec() 函数启动了 Qt 的事件循环。这意味着在调用此函数后,应用程序将开始处理各种事件,如用户输入、窗口事件、定时器事件等。- 事件循环一直运行,直到应用程序调用
QApplication::quit() 或关闭所有窗口。
2. 函数原型
int exec();
3. 返回值
exec() 的返回值是一个整数,通常表示应用程序的退出状态。返回的整数值通常是从 QApplication::quit(int returnCode) 中的 returnCode 参数传递的。如果没有明确指定,通常会返回 0,表示正常退出。
4. 使用示例
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton button("Hello, World!");
button.show();
return app.exec();
}
在这个例子中,app.exec() 会启动事件循环,使按钮能够响应用户的点击事件。当用户关闭窗口或应用程序时,事件循环将结束,并返回一个退出状态码。
5. 内部机制
6. 注意事项
7. 总结
int QApplication::exec() 是启动 Qt 应用程序事件循环的核心函数。通过调用它,应用程序开始处理用户交互、定时器事件和其他系统事件。它是 Qt 应用程序的核心运行机制,确保 GUI 界面能够正常工作和响应。
qApp
qApp竟然是个宏,你敢信?不看帮助文档是真的不知道
用于访问当前正在运行的 QApplication 或 QGuiApplication 唯一对象的全局指针。它相当于 QCoreApplication::instance (),它允许方便地访问应用程序对象而无需显式地传递指针。
#define qApp QCoreApplication::instance()
qApp 的用法和示例
通常在 Qt 应用程序中,你可以使用 qApp 来执行与应用程序全局状态相关的操作。例如:
#include <QApplication>
#include <QMessageBox>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QMessageBox::information(nullptr, "App Info", QString("Application Name: %1").arg(qApp->applicationName()));
return qApp->exec();
}
在这个例子中,qApp 被用来访问 QApplication 对象并获取应用程序的名称。
qApp 的介绍
qApp 是一个宏,它实际上是对 QApplication::instance() 的简写。- 它返回指向当前
QApplication 或 QGuiApplication 对象的指针。在 Qt 应用程序的任何地方,只要需要访问应用程序对象,都可以使用 qApp。 - 由于
qApp 是一个全局宏,因此它可以在应用程序的任何地方使用,而不需要显式地传递 QApplication 对象的指针。
注意事项
- 只有在 GUI 应用程序中创建了
QApplication 或 QGuiApplication 对象后,qApp 才能使用。否则,使用 qApp 可能会导致访问空指针的错误。 - 对于非 GUI 应用程序(如控制台应用程序),应使用
QCoreApplication,此时 qApp 也可以指向 QCoreApplication 对象。
quit()与exit()
我们在 Qt 应用程序中,在关闭程序的时候可以通过 QApplication 提供的 exit() 和 quit() 方法来退出应用程,也经常在别人的代码中看到运用。这两个方法都是QCoreApplication的函数,QApplication 只是继承了这些函数
1. QApplication::exit(int returnCode = 0)
exit() 方法用于终止应用程序的事件循环,并返回一个整数值作为退出代码。默认情况下,返回代码为 0,表示正常退出。
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QPushButton button("Exit Application");
QObject::connect(&button, &QPushButton::clicked, [&]() {
QApplication::exit(0);
});
button.show();
return app.exec();
}
2. QApplication::quit()
quit() 方法相对简单,它实际上调用了 exit(0),即终止事件循环并返回 0 作为退出代码。
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QPushButton button("Quit Application");
QObject::connect(&button, &QPushButton::clicked, &QApplication::quit);
button.show();
return app.exec();
}
区别
exit(int returnCode):允许你指定返回代码,这对于需要传递退出状态的应用程序比较有用。quit():等同于 exit(0),更简洁,当你不需要指定退出代码时可以使用它。
调用时机
无论使用 exit() 还是 quit(),都只能在 QApplication::exec() 已经启动并正在运行事件循环时调用,否则不会有任何效果。
注意事项
quit() 和 exit() 会退出事件循环,但它们不会立即终止应用程序,而是会等待所有的事件处理完毕后再退出。- 在某些情况下,调用
quit() 或 exit() 后,可能需要进行一些清理工作,这时可以连接到 QApplication::aboutToQuit() 信号进行处理。
QObject::connect(&app, &QApplication::aboutToQuit, [](){
qDebug() << "Application is about to quit!";
});
这种方式确保了在应用程序退出之前,有机会执行任何必要的清理工作。
题外话
QApplication 和 QGuiApplication, QCoreApplication
-
QCoreApplication:
- 是所有 Qt 程序的基础类,处理非图形用户界面的应用程序的主控制流和设置。
- 适用于没有图形界面的应用程序。
-
QGuiApplication:
- 继承自
QCoreApplication,用于处理有图形用户界面的应用程序,但不涉及小部件 (widgets)。 - 适用于不使用
QWidget 的 GUI 应用程序。
-
QApplication:
- 继承自
QGuiApplication,是所有涉及 QWidget 的应用程序的主类。 - 适用于需要图形用户界面的小部件应用程序。
注意事项
-
唯一实例:一个应用程序中只能有一个 QApplication 实例。多次创建 QApplication 对象会导致应用程序的异常行为。
-
事件处理:所有用户事件(如按键、鼠标点击等)都通过 QApplication 进行处理。如果没有进入事件循环(即未调用 exec()),用户界面将不会响应用户输入。
-
资源管理:QApplication 负责全局资源(如字体、样式)的管理,这些资源在 QApplication 对象销毁时会被自动清理。
通过 QApplication 的合理使用,可以有效管理 Qt 应用程序的主流程和资源。