If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
dhana
Earned a small fee
Posts: 15 Joined: Tue Dec 02, 2014 7:25 am
Post
by dhana » Thu Dec 04, 2014 6:23 am
Hi,
wxBusyInfo displaying properly when button event is triggered (check below code).
Issue is, if I shift to other application and come back to MyFrame, wxBusyInfo disappears (although the main thread still waits for process thread to complete).
Code: Select all
//// Above function called to start a task
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
wxBusyInfo busy("Executing Process Thread",this);
try
{
if (wxThreadHelper::Create(wxTHREAD_JOINABLE) != wxTHREAD_NO_ERROR)
{
wxLogError("Could not create the worker thread!");
return;
}
if (GetThread()->Run() != wxTHREAD_NO_ERROR)
{
wxLogError("Could not run the worker thread!");
return;
}
GetThread()->Wait();
}
catch(exception& e)
{
}
}
Last edited by
dhana on Thu Dec 04, 2014 1:15 pm, edited 2 times in total.
doublemax
Moderator
Posts: 19160 Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2
Post
by doublemax » Thu Dec 04, 2014 11:59 am
This is normal. wxBusyInfo doesn't have its own event loop, so it can't repaint itself when the application is busy.
Use the source, Luke!
dhana
Earned a small fee
Posts: 15 Joined: Tue Dec 02, 2014 7:25 am
Post
by dhana » Thu Dec 04, 2014 1:17 pm
doublemax wrote: This is normal. wxBusyInfo doesn't have its own event loop, so it can't repaint itself when the application is busy.
I've updated the question now it should be clear to you , that main thread is not busy but the process thread is.
doublemax
Moderator
Posts: 19160 Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2
Post
by doublemax » Thu Dec 04, 2014 1:55 pm
I understood the question, but during this call...
... the main thread is locked and can't respond to any events, like the paint event of the busyinfo window.
You could try this:
Code: Select all
GetThread()->Wait( wxTHREAD_WAIT_YIELD );
But it has its risks.
http://docs.wxwidgets.org/trunk/interfa ... 0194371a87
Use the source, Luke!
dhana
Earned a small fee
Posts: 15 Joined: Tue Dec 02, 2014 7:25 am
Post
by dhana » Fri Dec 05, 2014 10:01 am
Now I removed wxThread->Wait()[check update code below]
I am deleting wxBusyInfo in Pending Event.But Still it disappears(while thread is processing), if I shift to other application and come back to my frame.
CODE:
Code: Select all
//// Above function called to start a task
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
busy = new wxBusyInfo("Executing Process Thread", this);
try
{
if (wxThreadHelper::Create(wxTHREAD_JOINABLE) != wxTHREAD_NO_ERROR)
{
wxLogError("Could not create the worker thread!");
return;
}
if (GetThread()->Run() != wxTHREAD_NO_ERROR)
{
wxLogError("Could not run the worker thread!");
return;
}
}
catch(exception& e)
{
}
}
wxThread::ExitCode MyFrame::Entry()
{
try
{
}
catch(exception& e)
{
}
wxCommandEvent updateEvent(wxEVT_COMMAND_BUTTON_CLICKED,MW_FIX_THREAD_UPDATE);
this->AddPendingEvent(updateEvent );
return (wxThread::ExitCode)0;
}
void MyFrame::OnThreadUpdate(wxCommandEvent& event)
{
if(busy){ delete busy; busy = NULL;}
}
Last edited by
dhana on Tue Dec 09, 2014 8:57 am, edited 2 times in total.
doublemax
Moderator
Posts: 19160 Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2
Post
by doublemax » Fri Dec 05, 2014 11:25 am
If the main thread is not blocked and the event loop running, the wxBusyInfo should update properly. Maybe there is something else going on that can't be seen in the code you posted.
Try this code using wxProgressDialog, in any case it will look better than the plain wxBusyInfo window.
Code: Select all
class demoThread : public wxThread
{
public:
enum
{
IDLE = 0,
BUSY,
FINISHED_OK,
FINISHED_ERROR
};
demoThread(int *status)
{
mp_status = status;
*mp_status = IDLE;
};
~demoThread() {};
virtual void *Entry()
{
*mp_status = BUSY;
for(int i=0; i<100; i++)
{
Sleep(100);
}
*mp_status = FINISHED_OK;
return NULL;
};
virtual void OnExit()
{
};
protected:
int *mp_status;
};
// event handlers
void MyFrame::StartThread(wxCommandEvent& WXUNUSED(event))
{
int status = demoThread::IDLE;
demoThread *thread = new demoThread( &status );
if( thread->Create()==wxTHREAD_NO_ERROR )
{
thread->Run();
wxProgressDialog dlg("Caption", "Processing", 100, this);
dlg.CenterOnScreen();
while( status!=demoThread::FINISHED_OK && status!=demoThread::FINISHED_ERROR )
{
dlg.Pulse();
::wxMilliSleep(100);
}
}
}
Use the source, Luke!
dhana
Earned a small fee
Posts: 15 Joined: Tue Dec 02, 2014 7:25 am
Post
by dhana » Fri Dec 12, 2014 11:16 am
Please Check Below Updated Code.But Still it disappears on top of the frame I can to able to see once I minimize the frame(while thread is processing), if I shift to other application and come back to my frame.
Code: Select all
/////////////////////////////////////////////////////////MyFrame.h///////////////////////////////////////////////////////////////////////////////////////
class MyFrame:public wxDialog, public wxThreadHelper
{
public:
MyFrame();
MyFrame( wxWindow *parent , wxWindowID id , const wxString& title ,const wxPoint& pos = wxDefaultPosition , const wxSize& size = wxDefaultSize , long style = wxDEFAULT_DIALOG_STYLE );
~MyFrame();
bool Create();
virtual void CreateWidgets( void );
void OnButtonClick(wxCommandEvent& event);
void OnThreadUpdate(wxCommandEvent& event);
protected:
virtual wxThread::ExitCode Entry();
wxWindow *m_Parent;
wxButton *m_BtnEvent;
wxBusyInfo *busy;
DECLARE_DYNAMIC_CLASS(MyFrame);
DECLARE_EVENT_TABLE();
};
////////////////////////////////MyFrame.cpp///////////////////////////////////////////
enum
{
ID_BUTTON_EVENT,
MW_FIX_THREAD_UPDATE
};
IMPLEMENT_DYNAMIC_CLASS( MyFrame , wxDialog )
BEGIN_EVENT_TABLE( MyFrame , wxDialog )
EVT_BUTTON(ID_BUTTON_EVENT,MyFrame::OnButtonClick)
EVT_BUTTON(MW_FIX_THREAD_UPDATE, MyFrame::OnThreadUpdate)
END_EVENT_TABLE()
MyFrame::MyFrame()
{
}
MyFrame::~MyFrame()
{
}
MyFrame::MyFrame( wxWindow* parent , wxWindowID id , const wxString& title, const wxPoint& pos , const wxSize& size , long style )
:wxDialog( parent , id , title , pos , size , style )
{
m_Parent = parent;
busy = NULL;
Create();
}
bool MyFrame::Create()
{
CreateWidgets();
return true;
}
void MyFrame::CreateWidgets( void )
{
wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
m_BtnEvent = new wxButton(this,ID_BUTTON_EVENT,"THREAD",wxDefaultPosition,wxDefaultSize);
sizer->Add(m_BtnEvent);
this->SetSizer(sizer);
}
void MyFrame::OnButtonClick(wxCommandEvent& event)
{
this->Enable(false);
busy = new wxBusyInfo("Executing Process Thread", this);
try
{
if (wxThreadHelper::Create(wxTHREAD_JOINABLE) != wxTHREAD_NO_ERROR)
{
wxLogError("Could not run the worker thread!");
return;
}
if (GetThread()->Run() != wxTHREAD_NO_ERROR)
{
wxLogError("Could not run the worker thread!");
return;
}
}
catch(exception& e)
{
}
this->Enable(true);
}
wxThread::ExitCode MyFrame::Entry()
{
try
{
for(int i=0; i<100; i++)
{
wxThread::Sleep(100);
}
}
catch(exception& e)
{
}
wxCommandEvent updateEvent(wxEVT_COMMAND_BUTTON_CLICKED,MW_FIX_THREAD_UPDATE);
this->AddPendingEvent(updateEvent );
return (wxThread::ExitCode)0;
}
void MyFrame::OnThreadUpdate(wxCommandEvent& event)
{
if(busy){ delete busy; busy = NULL;}
}
Last edited by
doublemax on Fri Dec 12, 2014 12:36 pm, edited 1 time in total.
Reason: Added code tags.