无法将 wxCommandEvent 绑定到处理程序,从 wxCommandEvent* 到 wxEvent* 的转换无效
我在使用 wxWidgets 3.1.5 时遇到了一个奇怪的问题。尝试将 wxCommandEvent
绑定到处理程序失败,并出现以下编译错误:
/usr/local/include/wx-3.1/wx/event.h:423:29: error: invalid conversion from ‘wxEventFunctorMethod<int, MainWindowPresenter, wxCommandEvent, MainWindowPresenter>::EventClass*’ {aka ‘wxEvent*’} to ‘wxCommandEvent*’ [-fpermissive]
根据 文档,明确提到将wxCommandEvent
绑定到处理程序。这是 Bind 方法的签名,我真的很确定出了什么问题这里:
void MainWindow::addEventHandler(const std::string& windowName, const wxEventType eventType,
void (MainWindowPresenter::*callback)(wxCommandEvent&), MainWindowPresenter &handler) {
auto widget = findWindowByName<wxWindow>(windowName);
widget->Bind(eventType, callback, &handler);
}
void MainWindow::registerEventHandlers(MainWindowPresenter& handler) {
addEventHandler("readersListBox", wxEVT_LISTBOX, &MainWindowPresenter::onReaderSelected, handler);
}
Handler显然是一个接受的成员方法wxCommandEvent
参考:
void onReaderSelected(wxCommandEvent& event);
奇怪的是,它对于其他 wxEvent
子类型工作得很好。为什么这个不能编译?
I ran into a strange issue when using wxWidgets 3.1.5. Trying to bind wxCommandEvent
to a handler fails with the following compiliation error:
/usr/local/include/wx-3.1/wx/event.h:423:29: error: invalid conversion from ‘wxEventFunctorMethod<int, MainWindowPresenter, wxCommandEvent, MainWindowPresenter>::EventClass*’ {aka ‘wxEvent*’} to ‘wxCommandEvent*’ [-fpermissive]
According to the documentation, binding wxCommandEvent
to a handler is explicitly mentioned. Here's the signature of the Bind method, I'm really sure what is wrong here:
void MainWindow::addEventHandler(const std::string& windowName, const wxEventType eventType,
void (MainWindowPresenter::*callback)(wxCommandEvent&), MainWindowPresenter &handler) {
auto widget = findWindowByName<wxWindow>(windowName);
widget->Bind(eventType, callback, &handler);
}
void MainWindow::registerEventHandlers(MainWindowPresenter& handler) {
addEventHandler("readersListBox", wxEVT_LISTBOX, &MainWindowPresenter::onReaderSelected, handler);
}
Handler is obviously a member method accepting wxCommandEvent
reference:
void onReaderSelected(wxCommandEvent& event);
Curiously, it works fine for other wxEvent
subtypes. Why doesn't this compile?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了对列表框中的选择做出反应,您所需要做的就是以下操作:
没有比这更简单的了。
现在您可以选择以非成员身份创建列表框。但是,您需要使用
dynamic_cast<>()
或wxDynamicCast()
确保小部件类型为 wxListBox,然后调用Bind() 在强制转换的指针上。
像这样的事情:
顺便说一句,我希望你有一个合适的
findWindowByName<>
函数,因为所有 wx 调用都在开头使用大写字母。另外,请确保不要使用智能指针来创建控件和主框架。 wxWidgets 是在 1990 年设计的,当时还没有使用智能指针,所以如果你这样做你会崩溃,因为窗口的析构函数会自动销毁它的所有子元素,但不会将指针置空,所以你会得到一个碰撞。
In order to react to the selection in the list box all you need to do is the following:
It can't be simpler than this.
Now you can choose to create the listbox as not a member. Buit then you need to ensure that the widget type is wxListBox by using either
dynamic_cast<>()
orwxDynamicCast()
and then callBind()
on casted pointer.Something like this:
BTW, I hope you have an appropriate
findWindowByName<>
function, as all wx calls are using Capital letters in the beginning.Also, make sure to not to use the smart pointer to create controls and main frame. wxWidgets is designed in 1990 when smart pointers were not used and so if you do you will get a crash, because the destructor of the windows will destroy all of its children automatically, but will not NULL-ify the pointer and so you will get a crash.
bind()
是使用事件类型(其第一个参数)的模板函数,以验证提供的事件处理程序实际上是通过使用wxeventtypetag&lt;&gt; 专业化而与之兼容的。给定的事件类型。在您的情况下,您只是将通用
wxeventType
传递给它,这使此检查失败。最简单的解决方案可能是使您的
addeventHandler()
也使模板功能成为一个模板功能。如果这是不可能的或不希望的,则可以使用不同的bind()
过载,例如,服用任意函数的人应起作用。Bind()
is a template function using the event type (its first argument) to verify that the event handler provided is actually compatible with it by usingwxEventTypeTag<>
specialization for the given event type. In your case you're just passing a genericwxEventType
to it, which makes this check fail.The simplest solution is probably to make your
addEventHandler()
a template function too. If this is impossible or undesirable, you can use a differentBind()
overload, e.g. the one taking the arbitrary functor should work.