2011-04-06 33 views
27

我將Lua的腳本添加到我們的應用程序中,我需要爲GUI工具包實現綁定。我們使用的工具包是wxWidgets。用Luabind處理事件回調

我使用的是Lua 5.1和Luabind 0.9.1,到目前爲止效果很好。但是,我不確定如何最好地處理事件。例如,如果你想創建一個按鈕,單擊時打印一個字符串,你寫在C++這樣的事情

class MyClass : public wxFrame 
{ 
    MyClass (...) 
    { 
     b = new wxButton (this, -1, "Click me"); 
     b->Bind (wxEVT_COMMAND_BUTTON_CLICKED, &MyClass::HandleButtonClick, this); 
    } 

    void HandleButtonClick (wxCommandEvent& ev) 
    { 
     wxMessageBox ("You clicked me"); 
    } 
} 

做同樣的事情在Lua會是這個樣子我的夢想-API:

b = wx.Button (frm, -1, "Click me") 
b.on_click = function (ev) 
    print ("Button clicked") 
end 

或者,允許多個事件處理程序:

b.on_click:add (function (ev) 
    print ("Button clicked again ...") 
end) 

如果沒有可能,像這樣它更類似於C++ API:

b.bind (wx.EVT_COMMAND_BUTTON_CLICKED, function (ev) 
    print ("Yet again") 
end) 

但是,我不知道如何使用Luabind實現這一點,而不用爲我想要使用的wxWidgets庫中的每個類編寫包裝類。

有什麼建議嗎?

也許Luabind會以某種方式自動創建助手類(比如說「wxLuaEventPropagator」)?因此,wxButton類爲每個事件(「on_click」,等等)都有一個嵌套的wxLuaEventPropagator類。再次,我不想爲我使用的wxWidgets中的每個類創建包裝類,因爲有很多。

(是的,我知道wxLua的)

+0

你說你知道wxLua - 那爲什麼不使用它? – 2011-04-10 15:35:48

+1

因爲:1. wx部分不會被腳本使用太多,我認爲這是一個相當重的依賴性(不一定是這樣),2.項目可能會在不久的將來轉移到另一個gui工具包,並且最重要的是:3.還有其他API我也必須包裝,所以我仍然必須爲此找到解決方案。我目前的計劃是放棄Luabind,儘管我非常喜歡它,並使用SWIG代替。 – Jonatan 2011-04-11 10:27:21

+0

你提到過C++。您的主機應用程序是用C++編寫的嗎? – 2011-05-13 02:43:35

回答

2

您可以使用luabind ::對象來做到這一點。

一種爲例類: MyClass類 { 公共: 空隙OnMouseMoved(INT的x,int y)對; void SetEventFunction(const luabind :: object & fn);

private: 
    luabind::object m_eventFunction; 
}; 


void MyClass::SetEventFunction(const luabind::object &fn) 
{ 
    if(luabind::type(fn) == LUA_TFUNCTION) 
    { 
     cout << "A function" << endl; 
     m_eventFunction = fn; 
    } 
    else 
    { 
     cout << "Not a function" << endl; 
    } 
} 

void MyClass::OnMouseMoved(int x, int y) 
{ 
    if(m_eventFunction.is_valid()) 
    { 
     luabind::call_function<void>(m_eventFunction, x, y); 
    } 
} 

在Lua代碼,這將是:

MyClass的= MyClass的()

myClass:SetEventFunction(function (x, y) 
    print ("The new mouse position is", x, y) 
end) 

要擁有一個以上功能的事件,您可以使用std::vectorluabind::object

+0

由於類是第三方庫的一部分,我將不得不使用這種方法來包裝每個類。正如我上面所說的,現在我正在使用SWIG,因爲它允許您以簡單的方式擴展類。 – Jonatan 2011-05-27 07:27:31