Wxwidgets callback

Wxwidgets callback

本文关键字:callback Wxwidgets      更新时间:2023-10-16

我想在不冻结主应用程序的情况下为线程函数添加回调函数。

例:当我点击一个按钮,它启动一个线程函数。我想在工作完成时通知用户。

Thx

    cs functions;
    pthread_t thread;
    pthread_create(&thread, NULL, maFonction, (void*)&functions);
    //pthread_join(thread, NULL);
pthread_join在等待线程完成时阻塞主应用程序。我该怎么做呢?非常感谢

通过在派生线程中调用pthread_detach()使线程处于分离状态,或者在主线程中创建线程时,将该线程的pthread属性设置为分离状态。既然线程已经分离,您就不需要在主线程中调用pthread_join()了。接下来,在派生线程本身中,在退出线程之前,将一个事件推送到派生线程的WxWidgets对象的事件队列中,以"宣布"派生线程已经完成。最后,将线程结束事件的事件处理程序添加到WxWidget对象中,以处理生成的线程将放置在其事件队列中的偶数。

例如,你可以创建一个像THREAD_FINISHED_EVENT这样的事件,你的线程将把它推送到将产生线程的对象的事件队列中。你的代码看起来像这样:

wxCommandEvent event(THREAD_FINISHED_EVENT, GetId());
//"this" points to the parent WxWidgets object spawning the threads
//and allows you to access the "this" pointer in the handler
event.SetEventObject(this); 
//Send the event
this->AddPendingEvent(event);
事件本身将在安装事件处理程序的WxWidget的主事件线程中处理。您只需要为WxWidget对象提供一个处理程序,并定义事件本身。这可以使用宏DEFINE_EVENT_TYPE完成,然后将以下行添加到将生成线程本身的WxWidget对象的构造函数中:
//myWxWidget::thread_handler is the handler for your thread ending events
Connect(widgetID, THREAD_FINISHED_EVENT, wxCommandEventHandler(myWxWidget::thread_handler))

总结一下,下面是一些理论上的WxWidgets对象类的样子:

//myWindowThreadClass.hpp
#include <wx/wx.h>
#include <wx/event.h>
extern expdecl const wxEventType THREAD_FINISHED_EVENT;
class myWindowThreadClass: public wxWindow
{
    public:
        myWindowThreadClass(wxWindow* parent, int id);
        //handler for the thread-ending event
        void thread_handler(wxCommandEvent& event);
        //pushes a thread event on the wxWidgets event-queue 
        //for myWindowThreadClass
        void send_thread_event();
};

//myWindowThreadClass.cpp
#include <myWindowthreadClass.h>
#include <pthread.h>
const wxEventType THREAD_FINISHED_EVENT = wxNewEventType();
void* thread_func(void* data)
{
    myWindowThreadClass* window_ptr = static_cast<myWindowThreadClass*>(data);
    //detach thread
    pthread_detatch(pthread_self());
    //... rest of thread function
    window_ptr->send_thread_event();
    return (void*)0;
}
myWindowThreadClass::myWindowThreadClass(wxWindow* parent, int id):
              wxWindow(parent, id)
{
    //enable the event handler
    Connect(id, THREAD_FINISHED_EVENT, wxCommandEventHandler(myWindowThreadClass::thread_handler));
    //create your threads
    pthread_t tid;
    for (int i=0; i < NUM_THREADS; i++)
    {
        pthread_create(&tid, NULL, thread_func, this);
    }
    //...do anything else needed to initialize object
}
void myWindowThreadClass::thread_handler(wxCommandEvent& event)
{
    //handle the event
}
void myWindowThreadClass::send_thread_event()
{
    wxCommandEvent event(THREAD_FINISHED_EVENT, GetId());
    event.SetEventObject(this); 
    //Send the event ... import to use this function, as it will cause
    //the event to be processed in main-thread, not spawned child threads
    this->AddPendingEvent(event);
}

设置一个变量,例如:在启动线程之前,将xxx_is_done设置为false。当线程完成时,它所做的最后一件事是将xxx_is_done设置为true。然后只需检查主事件循环中的变量,并在变量为true时在线程上调用pthread_join,并将变量设置回false,这样您就不会再次在线程上调用pthread_join