PDA

View Full Version : Window not closing or destroying



spraff
10th December 2008, 20:57
Hello. I have a QMainWindow with a few layers of subwidgets. One of the deeper ones needs to know when the application is closed.

Its destructor isn't called. Its closeEvent isn't called. I've tried setting WA_DestroyOnClose. (The main window is being closed by clicking the X, but I need to capture all reasons of closing/destroying, which is why I wanted to use the destructor.)

What's going on?

Thanks for reading.

rexi
10th December 2008, 21:51
According to the documentation of QWidget::closeEvent() it is only called for top-level widgets. So you have to reimplement closeEvent() in your main window if you want to do something when the window is closed.

spraff
10th December 2008, 22:05
Are you sure?

"This event handler is called with the given event when Qt receives a window close request for a top-level widget from the window system."

I read that to mean close events would only be triggered by requesting top-level windows to close, I don't see how that implies only the top-level window receives it.

Reimplementing the close event all the way down the layers to pass it on won't work in my case, and it's a crappy tactic anyway.

Qt normally doesn't prevent you from doing intuitive things -- I must be missing something obvious here. At the moment is looks like Qt is breaking RAII by design, which would be the first truly awful feature I've come across if it's true...

rexi
10th December 2008, 23:21
I read that to mean close events would only be triggered by requesting top-level windows to close, I don't see how that implies only the top-level window receives it.

That's how I understand that part, though I haven't tried it. As your event handler isn't called, this might be the reason. But I might be wrong on this.


Reimplementing the close event all the way down the layers to pass it on won't work in my case, and it's a crappy tactic anyway.

I agree that this wouldn't be elegant, but do you have to do so? Can't you just initiate from the mainwindow's handler whatever it is your widget does when it is closed?

rexi
10th December 2008, 23:45
Ok, if have tried it now. It really looks like only the top level window receives the close event, so either my understanding of that part of the documentation is correct or there is something else about the way how widget closing works that I missed. If the latter is the case, I too would be grateful for an explanation.

BTW, if you explicitly call QWidget::close() on a subwidget, then the closeEvent() of that widget is called. Otherwise it doesn't. So, in the closeEvent() handler of the main window you could close your subwidget explicitly and it should solve your problem.

spraff
13th December 2008, 15:10
I just tried to get around it with this static object:

struct Temp{~Temp();}Temp temp;Temp::~Temp(){
// Find and explicitly destroy all relevant non-top-level windows
}

Funnily enough, this destructor never got called! I did an strace and found out that Qt ends with an exit_group call. I'm guessing this kills the threads/process without bothering with any clean-up code.

Easier than being strict about one's resource handling, I suppose, but not exactly kosher.