2012-12-28 25 views
1

我想了解如何執行特定任務。我試圖在wxWidgets中設置事件表,並遇到了與他們的行爲有關的問題。活動wxWidgets

我建立在一個類中的一些代碼:

void TopRightPanel::OnSelChanged(wxTreeEvent& event) 
{ 
    wxTreeItemId item = event.GetItem(); 
    TreeItemData* data = (TreeItemData *) GetItemData(item); 

    if(data != NULL) 
    { 

     particleSystemManager->SetSelectedParticleSystem(data->particleSystem); 
    } 

} 

這工作得很好,並預期有正確的價值觀。但是我的問題在於它是自包含的,我希望層次結構上方的類讀取treeCtrl的操作並更改U.I的所有方面。所以,我想這一點:

void Window::OnSelChanged(wxTreeEvent& event) 
{ 
    wxTreeItemId item = event.GetItem(); 
    TreeItemData* data = (TreeItemData *) topRightPanel->GetItemData(item);//item.m_pItem.//m_MyTreeCtrl->GetItemData(itemId);*/ 

    if(data != NULL) 
    { 
     particleSystemManager.SetSelectedParticleSystem(data->particleSystem); 

    } 
} 

現在,我得到的時候topRightPanel-> GetItemData(數據)被稱爲未處理的異常。它使用的topRightPanel似乎並沒有被更新,並且似乎在數據在類的構造函數中陷入困境之前指向數據。無論如何,我可以繞過這個嗎?

編輯:

我聲明事件表如下所示:

#if USE_GENERIC_TREECTRL 
BEGIN_EVENT_TABLE(TopRightPanel, wxGenericTreeCtrl) 
#else 
BEGIN_EVENT_TABLE(TopRightPanel, wxTreeCtrl) 
#endif 
EVT_TREE_SEL_CHANGED(TopRightPanel_Ctrl, Window::OnSelChanged) 
END_EVENT_TABLE() 

和我然後使用DECLARE_EVENT_TABLE聲明該表中的標題。

+0

這段代碼看起來應該起作用,並且從你描述的內容看來,這聽起來像是C++對象構造順序或topRightPanel指針的初始化(我認爲它是Window的成員)的問題。我還假設你在其他地方以類似的方式使用了topRightPanel而沒有崩潰? – jstine

+0

@jstine是的,它在其他地方絕對行得通。如果我在Window類的更新中放置了一個斷點,那麼topRightPanel的值就表明它已經正確初始化了,如果我在OnSelChanged方法中檢查斷點的值是完全不同的... – Bushes

+0

好吧,我認爲這裏的問題可能是方式wxWidgets在創建事件句柄時強制轉換對象。我曾經遇到過wx會調用(例如)Window :: OnSelChanged()處理程序的問題,但實際的對象(例如this-> pointer)是TopRightPanel實例。由於兩個對象共享相同的基本窗口對象,所以許多東西仍然以這種方式工作。絕大多數唯一會出錯的是你的Window Definituon特有的東西。 – jstine

回答

1

必須在您在BEGIN_EVENT_TABLE中使用的事件表宏中使用相同的類名。 IOW,您的處理程序必須在Window事件表中定義,而不是在TopRightPanel事件表中定義。由於樹事件是wxCommandEvents,它們向上傳播給父代,所以如果Window包含樹控件,這將起作用。否則,例如如果他們是兄弟姐妹,則必須使用Connect(),如另一個答案中所示。

(Re)reading the event handling overview將被強烈推薦。

+0

我最終用Connect()解決了這個問題。這似乎是一個更清潔的方法謝謝您的幫助。 – Bushes

0

您不會顯示如何連接此事件處理程序,但問題幾乎肯定存在,而不是您顯示的代碼中。如果您使用的是Connect(),請確保您將指針指向Window對象作爲其最後一個參數,否則最終會以不可預料的災難性後果調用Window類的方法。

如果您確定您確實在正確的對象上調用方法,那麼我看到的唯一的其他解釋是,在生成此類型的第一個事件之前,您不會初始化topRightPanel。如果是這種情況,最簡單的解決方案是將指針初始化爲NULL,並在初始化代碼結束時將其正確設置。當然,在事件處理程序中檢查指針是否爲非NULL。

+0

我在使用事件表,我會修改這個問題。 – Bushes

+0

現在已修改的問題。我根本不使用Connect ...我應該嗎? – Bushes

+0

不,如果你使用的是事件表,那應該沒問題。它是否可以讓你有兩個或更多具有相同窗口ID的樹形控件?如果使用event.GetEventObject()並將其轉換爲wxTreeCtrl *,然後將該指針用於獲取數據的wxTreeCtrl,會發生什麼?你能否確認由GetEventObject()返回的指針和指向你的topRightPanel的指針是一樣的? –