C++ 事件wxWidgets

C++ 事件wxWidgets,c++,user-interface,wxwidgets,C++,User Interface,Wxwidgets,我想了解如何做一项具体的任务。我试图在wxWidgets中设置事件表,但在它们的行为方面遇到了问题 我在一个类中设置了一些代码: void TopRightPanel::OnSelChanged(wxTreeEvent& event) { wxTreeItemId item = event.GetItem(); TreeItemData* data = (TreeItemData *) GetItemData(item); if(data != NULL)

我想了解如何做一项具体的任务。我试图在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在标题中声明表。

您没有说明如何连接此事件处理程序,但问题几乎肯定存在,而不是在您显示的代码中。如果您使用的是
Connect()
,请确保将指向
Window
对象的指针作为其最后一个参数传递,否则将调用
TopRightPanel
对象上的
Window
类的方法,并带来意想不到的灾难性后果


如果您确定确实在right对象上调用了该方法,那么我看到的唯一其他解释是,在生成此类型的第一个事件之前,您没有初始化
topRightPanel
。如果是这种情况,最简单的解决方案是初始化指向
NULL
的指针,并在初始化代码末尾正确设置它。当然,还要检查事件处理程序中的指针是否为非空。

您没有显示如何连接此事件处理程序,但问题几乎肯定存在,而不是显示在代码中。如果您使用的是
Connect()
,请确保将指向
Window
对象的指针作为其最后一个参数传递,否则将调用
TopRightPanel
对象上的
Window
类的方法,并带来意想不到的灾难性后果


如果您确定确实在right对象上调用了该方法,那么我看到的唯一其他解释是,在生成此类型的第一个事件之前,您没有初始化
topRightPanel
。如果是这种情况,最简单的解决方案是初始化指向
NULL
的指针,并在初始化代码末尾正确设置它。当然,还要检查事件处理程序中的指针是否非空。

您必须在事件表宏中使用与您在
开始事件表中使用的类名相同的类名。注意,您的处理程序必须在
窗口
事件表中定义,而不是在
TopRightPanel
事件表中定义。由于树事件是
wxCommandEvents
,它们会向上传播到父级,因此如果
Window
包含树控件,这将起作用。否则,例如,如果他们是兄弟姐妹,则必须使用另一个答案中所示的
Connect()


(再次)强烈建议阅读。

您必须在事件表宏中使用与您在
开始事件表中使用的类名相同的类名。注意,您的处理程序必须在
窗口
事件表中定义,而不是在
TopRightPanel
事件表中定义。由于树事件是
wxCommandEvents
,它们会向上传播到父级,因此如果
Window
包含树控件,这将起作用。否则,例如,如果他们是兄弟姐妹,则必须使用另一个答案中所示的
Connect()


(RE)将被强烈推荐。

此代码看起来应该是可行的,从你描述的听起来好像问题可能是C++对象构造顺序或ToprTePosit指针的初始化(我假设它是窗口成员)。我还假设您在其他地方也以类似的方式使用了topRightPanel,但没有发生崩溃?@jstine是的,它在其他任何地方都能正常工作。如果我在窗口类的“更新”中设置了一个断点,topRightPanel中的值指示它已正确初始化,如果我在OnSelChanged方法中检查断点,则该值完全不同……好的,我认为这里的问题可能是wxWidgets在创建事件句柄时强制强制转换对象的方式。我曾经遇到过wx调用(例如)Window::OnSelChanged()处理程序的问题,但实际的对象(例如,this->pointer)是TopRightPanel实例。因为两个对象共享同一个基本窗口对象,所以很多东西仍然是这样工作的。几乎唯一会出错的事情是特定于您的窗口定义的事情。我会给出一个更好的答案,说明如何确保避免这种情况(这与一些简洁的手动事件注册术语有关)。。。但我已经有一段时间没有使用wx了,我觉得自己没有资格写一篇超出我已经说过的内容的文章。好运气。这个代码看起来应该工作,从你描述的听起来好像问题可能在C++对象构造顺序或初始化TopryPosit指针(我假设它是窗口成员)。我还假设您在其他地方也以类似的方式使用了topRightPanel,但没有发生崩溃?@jstine是的,它在其他任何地方都能正常工作。如果我在窗口类的“更新”中设置了一个断点,topRightPanel中的值指示它已正确初始化,如果我在OnSelChanged方法中检查断点,则该值完全不同……好的,我认为这里的问题可能是wxWidgets在创建事件句柄时强制强制转换对象的方式。我曾经遇到过wx调用(例如)Window::OnSelChanged()处理程序的问题,但实际的对象(例如,this->pointer)是TopRightPanel实例。因为两个对象共享同一个基本窗口对象,所以很多东西仍然是这样工作的。几乎所有这些