如何在退出Qt应用程序时做一些事情



我的理解是,当所有相关的窗口关闭时,下面的代码将执行一个应用程序,该应用程序将退出。

int main(int argc, char *argv[])
{
    QApplication cal(argc, argv); //Application instance
    MainWindow window; //Create window in the stack
    window.show(); //Show the window
    return cal.exec(); //Execute event loop
}

这也将退出该应用程序。

quitButton = new QPushButton("Quit", this);
connect(quitButton, SIGNAL(clicked()), QApplication::instance(), SLOT(quit()));

我应该如何去清理(关闭硬件连接和库等),这样我就可以确保所有需要发生的事情都发生了,无论应用程序如何退出,也不是在执行的什么时候退出?

我将在整个应用程序中打开一个库,并在大多数时候连接到USB设备。如果进程运行正常,我可以很容易地关闭此连接,但如果有人决定在完成之前点击退出或关闭所有窗口,我希望安全关闭此连接。

QWidget有一个名为closeEvent的虚函数(请参阅文档),当调用widget的close()操作时调用该虚函数。

或者,如果您不想拥有自己的Base小部件,您可以将自己挂钩到信号QApplication::lastWindowClosed(见这里)。当应用程序的最后一个可见窗口关闭时,它将被触发。

您可以这样做:

int main(int argc, char *argv[])
{
    QApplication cal(argc, argv);
    // Allocate resources
    int ret = cal.exec(); // start the event loop and wait until it quits
    // Free the resources
    return ret;
}

正确的c++方法是:

  1. 确保你所有的对象实例被销毁

  2. 确保您持有的任何资源都是通过RAII持有的

那么你不需要做任何特别的事情。当main返回时,对象被破坏,事情就被清理了。

例如:

int main(int argc, char ** argv) {
  QApplication app(argc, argv);
  QObject foo;
  QObject * bar = new QObject(&app);
  Widget w;
  w.show();
  return app.exec();
}

这里,foobarmain返回之前都被正确地析构了。现在假设您持有一些非内存资源,如文件:

class Worker : public QObject {
  QFile m_file;
  ...
  void doSomething() {
    if (m_file.open()) {
      ...
    }
    // No file closing!
  }
};
int main(int argc, char ** argv) {
  QApplication app(argc, argv);
  Worker foo;
  Widget w;
  w.show();
  return app.exec();
}

再次,在main返回之前文件被关闭。

简而言之,这就是RAII的工作原理。如果您有自己的类来包装操作系统或其他资源,只需确保在类被销毁时释放这些资源—并且类总是可销毁(销毁它们总是安全的)。我最讨厌的是QThread——它打破了这个期望,你必须实现一个包装器来修复它。

对于需要在堆上分配的资源,应该使用智能指针或QObject内存管理。

您可以使用QApplication信号在应用程序退出之前进行清理:

QObject::connect(&app, SIGNAL(aboutToQuit()), &MyCleaner, SLOT(cleanUp()));

玩得开心!

最新更新