2010-06-01 3 views
4

wxWidgets를 사용하여 진행하는 데 오랜 시간이 걸리는 함수를 호출합니다. 나는 그것을 백그라운드에서하고 싶다.wxWidgets의 스레드

어떻게하면됩니까? 도움을

감사

+0

이 도움이 될 수 http://docs.wxwidgets.org/trunk/classwx_thread_helper.html – Aif

+0

그리고 이것 ... http://wiki.wxwidgets.org/Inter-Thread_and_Inter-Process_communication – laher

답변

2

단순히이 완료 될 때까지 백그라운드에서 뭔가 작업을해야하는 경우 -이 같은 화재와 당신이 경우 잊지 :

// warning: off the top of my head ;-) 
class MyThread 
    : public wxThread 
{ 
public: 
    MyThread() : wxThread(wxTHREAD_DETACHED) 
    { 
    if(wxTHREAD_NO_ERROR == Create()) { 
     Run(); 
    } 
    } 
protected: 
    virtual ExitCode Entry() 
    { 
    // do something here that takes a long time 
    // it's a good idea to periodically check TestDestroy() 
    while(!TestDestroy() && MoreWorkToDo()) { 
     DoSaidWork(); 
    } 
    return static_cast<ExitCode>(NULL); 
    } 
}; 

MyThread* thd = new MyThread(); // auto runs & deletes itself when finished 
6

내가 함께 작업 한을 거의 모든 방법에서 wxWidgets의 스레드는 here으로 설명되어 있습니다. 처음에는 좀 더 복잡한 반면 사용자 정의 이벤트를 사용하면 장기간에 두통을 피할 수 있습니다. 합니다 (wxMessageQueue 클래스는 매우 좋은,하지만 난 그것을 사용 때 나는 누출을 발견, 그래도 약 1 년을 확인하지 않았습니다.)

기본 예 :

MyFrm.cpp을

#include "MyThread.h" 

BEGIN_EVENT_TABLE(MyFrm,wxFrame) 
    EVT_COMMAND(wxID_ANY, wxEVT_MYTHREAD, MyFrm::OnMyThread) 
END_EVENT_TABLE() 
void MyFrm::PerformCalculation(int someParameter){ 
    //create the thread 
    MyThread *thread = new Mythread(this, someParameter); 
    thread->Create(); 
    thread->Run(); 
    //Don't worry about deleting the thread, there are two types of wxThreads 
    //and this kind deletes itself when it's finished. 
} 
void MyFrm::OnMyThread(wxCommandEvent& event) 
{ 
    unsigned char* temp = (unsigned char*)event.GetClientData(); 
    //do something with temp, which holds unsigned char* data from the thread 
    //GetClientData() can return any kind of data you want, but you have to cast it. 
    delete[] temp; 
}  

MyThread.h

#ifndef MYTHREAD_H 
#define MYTHREAD_H 

#include <wx/thread.h> 
#include <wx/event.h> 

BEGIN_DECLARE_EVENT_TYPES() 
    DECLARE_EVENT_TYPE(wxEVT_MYTHREAD, -1) 
END_DECLARE_EVENT_TYPES() 

class MyThread : public wxThread 
{ 
    public: 
     MyThread(wxEvtHandler* pParent, int param); 
    private: 
     int m_param; 
     void* Entry(); 
    protected: 
     wxEvtHandler* m_pParent; 
}; 
#endif 

MyThread.cpp

#include "MyThread.h" 
DEFINE_EVENT_TYPE(wxEVT_MYTHREAD) 
MyThread::MyThread(wxEvtHandler* pParent, int param) : wxThread(wxTHREAD_DETACHED), m_pParent(pParent) 
{ 
    //pass parameters into the thread 
m_param = param; 
} 
void* MyThread::Entry() 
{ 
    wxCommandEvent evt(wxEVT_MYTHREAD, GetId()); 
    //can be used to set some identifier for the data 
    evt.SetInt(r); 
    //whatever data your thread calculated, to be returned to GUI 
    evt.SetClientData(data); 
    wxPostEvent(m_pParent, evt); 
    return 0; 
} 
,536,

위키가 제공하는 것보다 훨씬 명확하고 간결한 예가 있습니다. 분명히 나는 ​​실제로 응용 프로그램을 시작하는 것에 관한 코드를 생략했다. (wx 규칙은 MyApp.cpp를 만들 것이다.) 그리고 다른 비 스레드 관련 코드.

0

프로그램이 간단하고 스레드를 망치고 싶지 않은 경우 long 함수에서을 주기적으로 wxWindow :: Update()로 호출하는 것이 좋습니다.

2

몇 위를 구현에서 팁 : MingW32 및 Codeblocks를 사용

  1. 가 나는 warning: EVENT redeclared without dllimport attribute: previous dllimport ignored 다음 했어. 이벤트를 내보낼 필요가 없다면 DEFINE_EVENT_TYPEDECLARE_EVENT_TYPE 대신 DEFINE_LOCAL_EVENT_TYPEDECLARE_LOCAL_EVENT_TYPE을 사용하십시오.

  2. SetClientData()을 통해 개체를 전달하려면 분리형 스레드에 new 연산자를 사용하여 데이터를 만들어야합니다. 호출 된 응용 프로그램은 복사 된 후에 데이터를 delete으로 가져야합니다.

    BEGIN_DECLARE_EVENT_TYPES() 
        DECLARE_LOCAL_EVENT_TYPE(wxEVT_CALC_THREAD, -1) 
    END_DECLARE_EVENT_TYPES() 
    
    void* MyThread::Entry() 
    { 
        wxCommandEvent evt(wxEVT_CALC_THREAD, GetId()); 
        // do some work 
        vector<map<int, int> > *vm = new vector<map<int, int> >(); 
        // perform operations with the object vm ... 
        evt.SetClientData((void*)vm); 
        wxPostEvent(m_pParent, evt); 
    } 
    

    및 호출 응용 프로그램에서

    이 : 예를 들어

DEFINE_LOCAL_EVENT_TYPE(wxEVT_CALC_THREAD) 

// change this to your event table 
BEGIN_EVENT_TABLE(..., ...) 
    EVT_COMMAND(wxID_ANY, wxEVT_CALC_THREAD, ThreadDone) 
END_EVENT_TABLE() 

void ThreadDone(wxCommandEvent& event) 
{ 

    vector<map<int, int> > *temp = (vector<map<int, int> > *)event.GetClientData(); 
    // store the data in *temp 
    delete temp; 
}