【问题标题】:wxwidgets custom event won't propagate to the parent windowwxwidgets 自定义事件不会传播到父窗口
【发布时间】:2014-02-12 12:53:30
【问题描述】:

我尝试实现以实现我自己的自定义事件。如果我从我从(a wxFrame)连接它的类发布它确实有效,但如果它是从子 wxFrame 发布的,它不会被捕获。

自定义事件:

**cFrameFocus.h**
#pragma once
#include <wx\event.h>
class cFrameFocusEvent;
const wxEventTypeTag<cFrameFocusEvent> evtFRAME_FOCUS( wxNewEventType() );
//eventhandler macro
#if _MSC_VER <= 1600
typedef void (wxEvtHandler::*MyFrameFocusEventFunction)(cFrameFocusEvent&);
#define FrameFocusEventHandler(func) wxEVENT_HANDLER_CAST(MyFrameFocusEventFunction,func)
#else
#define FrameFocusEventHandler(func) (&func)
#endif
class cFrameFocusEvent :
    public wxEvent
{
    wxWindow* m_frame;
public:
    cFrameFocusEvent(wxEventType pEventType,int pWinId = wxID_ANY,const wxWindow* pWin = 0);
    ~cFrameFocusEvent(void);
    //impement base class pure virtual
    virtual wxEvent* Clone(void)const;
    //accessor
    wxWindow* GetWindow(void)const;
};

**cFrameFocus.cpp**
#include "cFrameFocus.h"
cFrameFocusEvent::cFrameFocusEvent(wxEventType pEventType,int pWinId,const wxWindow* pWin):
wxEvent(pWinId,pEventType)
{
    m_frame = const_cast<wxWindow*>(pWin);
}
cFrameFocusEvent::~cFrameFocusEvent(void)
{
}
wxEvent* cFrameFocusEvent::Clone(void)const{
    return new cFrameFocusEvent(*this);
}
wxWindow* cFrameFocusEvent::GetWindow(void)const{
    return m_frame;
}

子 Frame 尝试发送偶数:

cFrameFocusEvent* pevent = new cFrameFocusEvent(evtFRAME_FOCUS,GetId(),this);
wxQueueEvent(GetParent(),pevent);

注意:我确实已经偶然发现了这个问题wxWidgets 2.9 custom events,但这对我没有帮助。

【问题讨论】:

  • 我认为您需要从wxCommandEvent 派生。

标签: c++ visual-c++ wxwidgets


【解决方案1】:

在对 wxWidgets 代码进行了深入的调试和研究之后,我想通了。 问题是每次包含文件“cFrameFocus.h”时,wxEventTypeTag 都会改变(它的 id),这意味着当它被包含在文件中以连接到此事件类型时,id 的 id 为“x”并且在用于发布此事件的另一个文件,事件类型的 ID 为“y”。 解决这个问题的不是传播问题(因为它无论如何都被发送到了应该处理的级别 0),而是一个“编程错误”。

**cFrameFocus.h**
extern const wxEventTypeTag<cFrameFocusEvent> evtFRAME_FOCUS;

**cFrameFocus.cpp**
const wxEventTypeTag<cFrameFocusEvent> evtFRAME_FOCUS(wxNewEventType());

此代码更改修复了错误

编辑

正如VZ在cmets中提到的那样,使用宏而不是直接访问函数更合适。

正确的解决方案:

***cFrameFocus.h***

wxDECLARE_EVENT(evtFRAME_FOCUS,cFrameFocusEvent);

***cFrameFocus.cpp***
 wxDEFINE_EVENT(evtFRAME_FOCUS,cFrameFocusEvent);

【讨论】:

  • 这就是为什么您应该使用 wxDECLARE_EVENT(evtFRAME_FOCUS, cFrameFocusEvent)wxDEFINE_EVENT(evtFRAME_FOCUS, cFrameFocusEvent) 宏而不是手动执行。它们不仅将您与事件类型内部的任何可能的未来更改隔离开来,而且它们还清楚地表明一个可以/应该只在标题中使用(它是一个声明)和另一个在源文件中(它是一个定义)。
  • 我也尝试过使用宏,但并没有改变这种情况。就像在文档中说明的那样。到目前为止唯一的区别是示例实现在一个文件中(所有文件,从 wxApp 到其他所有文件),而我的不是。如果文件被多次包含,似乎没有“extern”声明它将无法工作
  • 但是extern 在宏里面,这就是重点。
  • 我明白了。感谢您的耐心等待,感谢您始终出色的回答。
  • 这很有帮助! wxWidgets 编程指南没有解释在其自定义事件类型示例中使用 wxDECLARE_EVENT。
【解决方案2】:

您需要阅读event propagation overview 以了解事件在 wxWidgets 中的工作方式。特别是,它会告诉您只有源自wxCommandEvent 的事件默认向上传播,对于其他事件,您需要调用ResumePropagation(N) 以使它们向上传播N 级别(并且可能是INT_MAX 到当然,让它们无限制地传播)。

【讨论】:

  • 感谢您的快速响应。我现在通过从 wxCommandEvent 派生它来尝试它(因为它在你悲伤时默认向上传播)。可惜还是不行
  • 您没有显示处理事件的代码,所以我的猜测是问题就在那里。我建议您查看 wxWidgets 发行版中包含的事件示例,它显示了如何定义、发送和捕获一个简单的自定义命令事件,您上面的代码对我来说看起来很奇怪。
  • 实际上错误在于我提供的代码。我会把答案贴在你的下面
猜你喜欢
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
  • 2014-03-20
  • 1970-01-01
  • 2014-09-21
  • 1970-01-01
相关资源
最近更新 更多