英文:
How should I change my code so that I can call the Bind() function instead of using the event table?
问题
I am using WxWidgets 3.2 for my C++ Windows application.
I need to pass data (eg login) from one class to another. To do this, I create a custom event and use the event table to bind the event to the handler.
For example, I have a LoginPanel class and I want to pass the login entered by the user to another class - MainFrame.
LoginPanel.h
DECLARE_EVENT_TYPE(LOGIN_ENTERED, wxCommandEvent)
enum class Buttons_ID {
ID_CONNECT_BUTTON = wxID_HIGHEST + 1,
};
class LoginPanel : public wxPanel {
public:
LoginPanel(wxWindow* parent, wxWindowID id = wxID_ANY);
private:
void OnConnectButton(wxCommandEvent& event);
wxTextCtrl* usernameInput;
};
LoginPanel.cpp
DEFINE_EVENT_TYPE(LOGIN_ENTERED)
LoginPanel::LoginPanel(wxWindow* parent, wxWindowID id)
: wxPanel(parent, id) {
wxButton* connectButton = new wxButton(loginTab, wxID_ANY, "Connect");
connectButton->Bind(wxEVT_BUTTON, &LoginPanel::OnConnectButton, this);
}
void LoginPanel::OnConnectButton(wxCommandEvent& event) {
wxString username = usernameInput->GetValue();
wxCommandEvent loginEvent(LOGIN_ENTERED, GetId());
loginEvent.SetString(username);
GetParent()->GetEventHandler()->ProcessEvent(loginEvent);
}
MainFrame.h
class MainFrame : public wxFrame {
public:
MainFrame(const wxString& title);
~MainFrame();
private:
LoginPanel * loginPanel;
public:
void ShowLoginPanel();
void OnLoginEntered(wxCommandEvent& event);
wxDECLARE_EVENT_TABLE();
};
MainFrame.cpp
wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
EVT_COMMAND(wxID_ANY, LOGIN_ENTERED, MainFrame::OnLoginEntered)
wxEND_EVENT_TABLE()
MainFrame::MainFrame(const wxString& title)
: wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~wxRESIZE_BORDER) {
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
loginPanel = new LoginPanel(this, wxID_ANY);
mainSizer->Add(loginPanel, 1, wxEXPAND);
SetSizer(mainSizer);
ShowLoginPanel();
}
void MainFrame::OnLoginEntered(wxCommandEvent& event) {
auto login = event.GetString();
}
This is how the code works and the LOGIN_ENTERED event is normally passed from the LoginPanel class to the OnConnectButton() handler of the MainFrame class.
Since using the event table is not very modern now, I want to use the Bind() function. I call the Bind() function in the constructor of the MainFrame class:
loginPanel->Bind(LOGIN_ENTERED, &MainFrame::OnLoginEntered, this);
However, the problem is that an error occurs:
C2664: 'void wxEventFunctorMethod<EventTag,MainFrame,EventArg,EventHandler>::CheckHandlerArgument(EventArg *)': cannot convert argument 1 from 'wxEvent *' to 'EventArg *'
How should I change my code so that I can call the Bind() function instead of using the event table?
英文:
I am using WxWidgets 3.2 for my C++ Windows application.
I need to pass data (eg login) from one class to another. To do this, I create a custom event and use the event table to bind the event to the handler.
For example, I have a LoginPanel class and I want to pass the login entered by the user to another class - MainFrame.
LoginPanel.h
DECLARE_EVENT_TYPE(LOGIN_ENTERED, wxCommandEvent)
enum class Buttons_ID {
ID_CONNECT_BUTTON = wxID_HIGHEST + 1,
};
class LoginPanel : public wxPanel {
public:
LoginPanel(wxWindow* parent, wxWindowID id = wxID_ANY);
private:
void OnConnectButton(wxCommandEvent& event);
wxTextCtrl* usernameInput;
};
LoginPanel.cpp
DEFINE_EVENT_TYPE(LOGIN_ENTERED)
LoginPanel::LoginPanel(wxWindow* parent, wxWindowID id)
: wxPanel(parent, id) {
wxButton* connectButton = new wxButton(loginTab, wxID_ANY, "Connect");
connectButton->Bind(wxEVT_BUTTON, &LoginPanel::OnConnectButton, this);
}
void LoginPanel::OnConnectButton(wxCommandEvent& event) {
wxString username = usernameInput->GetValue();
wxCommandEvent loginEvent(LOGIN_ENTERED, GetId());
loginEvent.SetString(username);
GetParent()->GetEventHandler()->ProcessEvent(loginEvent);
}
MainFrame.h
class MainFrame : public wxFrame {
public:
MainFrame(const wxString& title);
~MainFrame();
private:
LoginPanel * loginPanel;
public:
void ShowLoginPanel();
void OnLoginEntered(wxCommandEvent& event);
wxDECLARE_EVENT_TABLE();
};
MainFrame.cpp
wxBEGIN_EVENT_TABLE(ChessFrame, wxFrame)
EVT_COMMAND(wxID_ANY, LOGIN_ENTERED, ChessFrame::OnLoginEntered)
wxEND_EVENT_TABLE()
MainFrameFrame::MainFrameFrame(const wxString& title)
: wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~wxRESIZE_BORDER) {
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
loginPanel = new LoginPanel(this, wxID_ANY);
mainSizer->Add(loginPanel, 1, wxEXPAND);
SetSizer(mainSizer);
ShowLoginPanel();
}
void MainFrameFrame::OnLoginEntered(wxCommandEvent& event) {
auto login = event.GetString();
}
This is how the code works and the LOGIN_ENTERED event is normally passed from the LoginPanel class to the OnConnectButton() handler of the MainFrame class.
Since using the event table is not very modern now, I want to use the Bind() function. I call the Bind() function in the constructor of the MainFrame class:
loginPanel->Bind(LOGIN_ENTERED, &ChessFrame::OnLoginEntered, this);
However, the problem is that an error occurs:
C2664: 'void wxEventFunctorMethod<EventTag,ChessFrame,EventArg,EventHandler>::CheckHandlerArgument(EventArg *)': cannot convert argument 1 from 'wxEvent *' to 'EventArg *'
How should I change my code so that I can call the Bind() function instead of using the event table?
答案1
得分: 1
我认为主要问题是您用于声明/定义新事件的宏。您应该使用 wxDECLARE_EVENT 和 wxDEFINE_EVENT。
简而言之,将以下代码更改为:
wxDECLARE_EVENT(LOGIN_ENTERED, wxCommandEvent);
和
wxDEFINE_EVENT(LOGIN_ENTERED, wxCommandEvent);
此外,我建议将以下代码更改为:
ProcessWindowEvent(loginEvent);
如果窗口本身未处理命令事件,这些事件将向上过滤到父窗口。
英文:
I think the main issue is the macro you're using to declare/define your new events. You should use wxDECLARE_EVENT and wxDEFINE_EVENT instead.
In short, change
DECLARE_EVENT_TYPE(LOGIN_ENTERED, wxCommandEvent)
to
wxDECLARE_EVENT(LOGIN_ENTERED, wxCommandEvent);
and
DEFINE_EVENT_TYPE(LOGIN_ENTERED)
to
wxDEFINE_EVENT(LOGIN_ENTERED, wxCommandEvent);
Also, I would suggest changing
GetParent()->GetEventHandler()->ProcessEvent(loginEvent);
to simply
ProcessWindowEvent(loginEvent);
Command events will filter up to the parent windows if not handled by the window itself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论