Re: Problem with threads
Robert Roebling <[email protected]> Fri, 29 Apr 2005 00:34:45 +0200
| Newsgroups | gmane.comp.lib.wxwindows.wxnet |
|---|---|
| Message-ID | <[email protected]> |
> Consider the following case:
> I create a window with a button inside.
> I create a thread that contains an endless loop which updates the button's
> caption periodically.
> When I close the window, I get an exception (null pointer in wx-native code)
> which is 100% correct because by the time I call the button.text (or
> whatever), the button does not exist.
>
> I know I have to stop the thread first but the problem is that I don't know
> how to do it (WHERE to do it). I've tried the wx.Window.Closing event and it
> didn't help. No luck with wx.Window.Dispose or destructor either. What is the
> preffered way of postponing the window deletion until I'm finished with my
> stuff?
What I do in C++
a) Define a new event which the thread sends to the
owning frame. Or just notify the window somehow
that the thread has ended just so that it doesn't
get deleted twice
DEFINE_EVENT_TYPE( wxEVT_THREAD_HAS_ENDED )
b) Here is your wxFrame. Note that the thread
will send wxEVT_THREAD_HAS_ENDED either
because it simply has finished doing something
or after the thread has been stopped by the
frame's close handler. In the later case,
m_deleteOnExit will be true and the frame
will then be destroyed.
IMPLEMENT_CLASS(MyRecallFrame,wxFrame)
BEGIN_EVENT_TABLE(MyRecallFrame,wxFrame)
EVT_COMMAND( -1, wxEVT_THREAD_HAS_ENDED,
MyRecallFrame::OnThreadHasEnded )
END_EVENT_TABLE()
MyRecallFrame::MyRecallFrame( wxWindow *parent, wxWindowID id, const
wxString &title,
const wxPoint &position, const wxSize& size, long style ) :
wxFrame( parent, id, title, position, size, style )
{
m_thread = NULL;
m_deleteOnThreadExit = false;
StartThread();
}
void MyRecallFrame::StartThread()
{
m_thread = new MyRecallThread( this );
m_thread->Create();
m_thread->Run();
}
void MyRecallFrame::InterruptThread()
{
if (m_thread)
m_thread->Interrupt();
}
void MyRecallFrame::OnThreadHasEnded( wxCommandEvent &event )
{
m_thread = NULL;
if (m_deleteOnThreadExit)
Destroy();
}
void MyRecallFrame::OnCloseWindow( wxCloseEvent &event )
{
if (event.CanVeto())
{
if (m_thread)
{
m_thread->Interrupt();
event.Veto();
m_deleteOnThreadExit = true;
return;
}
}
Destroy();
}
-------------------------------------------------------
SF.Net email is sponsored by: Tell us your software development plans!
Take this survey and enter to win a one-year sub to SourceForge.net
Plus IDC's 2005 look-ahead and a copy of this survey
Click here to start! http://www.idcswdc.com/cgi-bin/survey?id=105hix