Discussion:
Deleting frame while timer is active
Jan Engelhardt
2014-01-27 22:20:53 UTC
Permalink
A small testcase which crashes with wxGTK 3 if the dtor is not
specified. Is this supposed to act as such? Perhaps the wxTimer
documentation should say something about deleting a window in which a
timer is active.

As the timer is (in this case) attached to the wxFrame which itself
is a EvtHandler, would it be possible to scan for all timers in
wxWindow::~wxWindow and destroy the attached timers?


#include <wx/wx.h>
#include <cstdio>
class myFrame : public wxFrame {
public:
void OnTime(wxTimerEvent &) {};
wxTimer *t;
myFrame(wxWindow *p) : wxFrame(p, wxID_ANY, wxEmptyString) {
t = new wxTimer(this);
t->Start(1000, wxTIMER_ONE_SHOT);
};
//~myFrame(void) { delete t; };
};
class myApp : public wxApp {
private: bool OnInit(void) {
wxFrame *a = new myFrame(NULL);
a->Show();
wxFrame *b = new myFrame(a);
b->Destroy();
return true;
};
};
IMPLEMENT_APP(myApp);
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Vadim Zeitlin
2014-01-28 01:58:56 UTC
Permalink
On Mon, 27 Jan 2014 23:20:53 +0100 (CET) Jan Engelhardt wrote:

JE> A small testcase which crashes with wxGTK 3 if the dtor is not
JE> specified. Is this supposed to act as such?

I think it's just an example of a general principle: you can't destroy
windows which have events sent to them. Timers are probably one of the most
common ways in which it can happen, but far from being the only one,
especially when you start using Bind().

JE> As the timer is (in this case) attached to the wxFrame which itself
JE> is a EvtHandler, would it be possible to scan for all timers in
JE> wxWindow::~wxWindow and destroy the attached timers?

It's not, in general, possible to know where is the given wxEvent handled
(it would be very nice if it were...), so I don't think it's worth it.

JE> #include <wx/wx.h>
JE> #include <cstdio>
JE> class myFrame : public wxFrame {
JE> public:
JE> void OnTime(wxTimerEvent &) {};
JE> wxTimer *t;
JE> myFrame(wxWindow *p) : wxFrame(p, wxID_ANY, wxEmptyString) {
JE> t = new wxTimer(this);
JE> t->Start(1000, wxTIMER_ONE_SHOT);
JE> };
JE> //~myFrame(void) { delete t; };
JE> };

FWIW the simplest fix is to just make wxTimer an object and not a pointer,
then there would be no need to delete it explicitly.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Loading...