I am writing a program with Qt, and I would like it to show a dialog box with a Exit | Restart choice whenever an error is thrown somewhere in the code.
What I did causes a crash and I really can't figure out why it happens, I was hoping you could help me understanding what's going on.
Here's my main.cpp:
#include "my_application.hpp"
int main(int argc, char *argv[])
{
std::cout << std::endl;
My_Application app(argc, argv);
return app.exec();
}
And here's my_application:hpp:
#ifndef MY_APPLICATION_HPP
#define MY_APPLICATION_HPP
#include <QApplication>
class Window;
class My_Application : public QApplication
{
public:
My_Application(int& argc, char ** argv);
virtual ~My_Application();
virtual bool notify(QObject * receiver, QEvent * event);
private:
Window *window_;
void exit();
void restart();
};
#endif // MY_APPLICATION_HPP
Finally, here's my_application.cpp:
#include "my_application.hpp"
#include "window.hpp"
#include <QMessageBox>
My_Application::My_Application(int& argc, char ** argv) : QApplication(argc, argv)
{
window_ = new Window;
window_->setAttribute(Qt::WA_DeleteOnClose, false);
window_->show();
}
My_Application::~My_Application()
{
delete window_;
}
bool My_Application::notify(QObject * receiver, QEvent * event)
{
try
{
return QApplication::notify(receiver, event);
}
catch(QString error_message)
{
window_->setEnabled(false);
QMessageBox message_box;
message_box.setWindowTitle("Error");
message_box.setIcon(QMessageBox::Critical);
message_box.setText("The program caught an unexpected error:");
message_box.setInformativeText("What do you want to do? <br>");
QPushButton *restart_button = message_box.addButton(tr("Restart"), QMessageBox::RejectRole);
QPushButton *exit_button = message_box.addButton(tr("Exit"), QMessageBox::RejectRole);
message_box.setDefaultButton(restart_button);
message_box.exec();
if ((QPushButton *) message_box.clickedButton() == exit_button)
{
exit();
}
else if ((QPushButton *) message_box.clickedButton() == restart_button)
{
restart();
}
}
return false;
}
void My_Application::exit()
{
window_->close();
//delete window_;
return;
}
void My_Application::restart()
{
window_->close();
//delete window_;
window_ = new Window;
window_->show();
return;
}
Note that the line window_->setAttribute(Qt::WA_DeleteOnClose, false); means that window_ (my main window) won't be deleted when it is closed.
The code I've written above works, but as far as I understand, there's a memory leak: I should uncomment the line //delete window_; in My_Application::exit() and My_Application::restart(). But when I do that, the program crashes when I click restart (or exit but who cares).
(I'm not sure this is useful, in fact it might be misleading, but here's what my debugger tells me: a segmentation fault occurs in QWidgetPrivate::PaintOnScreen() const which is called by a function called by a function... called by My_Application::notify())
When I do some std::couts, I notice that the program runs through the entire restart() function and in fact through the entire notify() function before it crashes.
I have no idea why it crashes. Thanks in advance for your insights!
Update:
I've noticed that My_Application::notify() is called very often. For example, it is called a bunch of times while the error dialog box is open, also during the execution of the restart function.
The crash actually occurs in the subfunction QApplication::notify(receiver, event). This is not too surprising in light of the previous remark (the receiver has probably been deleted)
But even if I forbid the function My_Application::notify() to do anything while restart() is executed, it still crashes (after having called My_Application::notify() a bunch of times, like 15 times, isn't that weird)?
How should I proceed? Maybe I should say (to make the question slightly more relevant) that my class My_Application also has a "restore" function, which I've not copied here to try to keep things short. If I just had that restart feature I wouldn't bother too much, but I do want to have that restore feature. I should also say that if I keep the code with the "delete window_" commented, the problem is not only a memory leak, it still crashes sometimes apparently. There must surely be a way to fix this! But I'm clueless, I'd really appreciate some help! Thanks in advance.