按下 wxYES_NO 中的按钮时如何执行该功能?

How can I execute the function when button in wxYES_NO is pressed?

可能我的标题不清楚,所以我在这里告诉一个更准确的解释:

刚开始学习WxWidgets,现在正在尝试制作两个文件:main.cpp和Quit.h。 Main.cpp 将具有应用程序的核心,Quit.h 将具有用于退出对话框的 class:您真的要退出此应用程序吗(是/否)。

现在这是我的 Quit.h 文件(没有 include 部分):

class Quit : public wxFrame
{
public:
    Quit(const wxString& tekst);
};
Quit::Quit(const wxString& tekst)
{
    wxMessageDialog* dial = new wxMessageDialog(NULL, _("Do you really want to quit?"), _("Quit"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
    dial->ShowModal();
}

我卡在这里了。我尝试使用 wxDECLARE_EVENT_TABLE(),但我不知道哪个事件代表这个:"on the press of yes button (in wxYES_NO system of buttons)"。我不能说:按下 wxYES_NO 因为这是两个按钮(是和否)。

那么当按下 YES 按钮时,如何执行该功能?

谢谢!

P.S。 对于这个不清楚的问题,我深表歉意,但我希望您能理解。请注意,我只是一个初学者,所以请不要在答案中使用这么多 "technical" 个单词和表达方式。我阅读了文档,但它使用了很多技术表达和解释。另外,我读了this本书。

P.P.S。 您是否注意到现在有很多关于 SE 的问题,而 COVID-19 即将到来?

编辑: 当我打开程序时,我遇到了另一个错误。最小代码:

Quit.h

class Quit : public wxFrame
{
public:
    Quit(const wxWindow* parent, const wxString& text);
};

Quit::Quit(const wxWindow* parent, const wxString& text)
{
    int dialog_return_value = wxNO;
    wxMessageDialog* dial = new wxMessageDialog(NULL, text, _("Exit"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
    dialog_return_value = dial->ShowModal();

    switch (dialog_return_value)
    {
    case wxYES:
        Close(true);
        break;
    case wxNO:
        Close(false);
        break;
    default:
        Close(false);
    };
}

然后我在 main.cpp 中有这一行:

void MyFrame::CloseWindow(wxCommandEvent& event)
{
    Quit* quit = new Quit(this, _("Do you really want to close the App?"));
}

然后就不行了。我找不到解决办法,所以,如果你有时间,请帮忙。

再次感谢!

我建议使用 wxEvtHandler::Bind<>() 函数,详见 https://docs.wxwidgets.org/3.0/overview_events.html 的 wxWidgets 文档。 Bind() 函数允许动态绑定事件,与将表设置为 link 事件到对象相比,语法是一行代码。

另外请参阅此 wxWidgets 用户论坛线程,其中详细说明了调用成员和非成员方法 https://forums.wxwidgets.org/viewtopic.php?t=39817

wxYES_NO 是一个样式标志,它告诉 wxWidgets 框架你想要在你的对话框中同时使用是和否按钮。检查 ShowModal() 的 return 值是否等于定义为 wxYESwxNO.

的内置宏之一

宏定义见此处https://docs.wxwidgets.org/trunk/defs_8h.html

你应该阅读 wxDiaglog。从这里开始 https://docs.wxwidgets.org/trunk/classwx_dialog.html

是否要将 return 的值传递给 Quit::Quit() 的调用者?构造函数没有 return 值,您可以将成员变量设置为该值,但请记住,如果对象被销毁,那么您的成员变量也会消失。您还没有提供足够的信息来了解您 Quit() 时需要做哪些清理工作,所以我会为您提供检查 return 值的代码,只需在案例正文中填写您需要的内容.

检查 return 值的方法如下:

class Quit : public wxFrame
{
public:
    Quit(const wxString& tekst);
};
Quit::Quit(const wxString& tekst)
{
    int dialog_return_value = wxNO; // initialize to a sane default value
    wxMessageDialog* dial = new wxMessageDialog(NULL, _("Do you really want to quit?"), _("Quit"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
    dialog_return_value = dial->ShowModal();
    // You do not have cancel button so only check wxYES and wxNO
    switch( dialog_return_value) // Use switch, scales to more buttons later
    {
        case wxYES :
        /* do something */
        break;
        case wxNO :
        /* do something */
        break;
        default : /* ignore or handle error */ ;
    };
}

您正在做一项技术任务,预计会涉及学习 "technical" 个单词。

我试图坚持尽可能多地使用您的代码,但使用普通 class 关闭应用程序对我来说毫无意义。在那种情况下,使用 wxWidgets 你仍然需要引用你的主框架来完成关闭。有更简单的方法,如下例所示。 以下是一个应用程序的完整工作示例,它在框架上只有一个退出按钮。您单击该按钮并获得退出消息对话框。 wxWidgets 允许在堆栈而不是堆上创建对话框,这就是你在这里需要的,因为对话框是微不足道的,不会被重用。

只要你使用的是 wxWidgets 3+,你就可以 copy/paste/compile/run 下面的代码(我很确定 Bind() 是那时添加的,可能稍微早一点)

#include <wx/wx.h>
// toolkit requires defining a wxApp class, OnInit() will be called automatically
// when the wxIMPLEMENT_APP macro is invoked below
class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
    MyFrame();
    ~MyFrame();
private:
    void OnExit( wxCommandEvent& event );
    // these pointer are owned by the wxWidgets toolkit, do not delete them
    // but you need them in a "real" app to add items to the sizer or change
    // button properties
    wxSizer* m_frame_sizer;
    wxButton* m_quit_button;
};
// toolkit requires calling this macro with a wxApp object to bootstrap the GUI framework
wxIMPLEMENT_APP( MyApp );
// OnInit is loosely synonymous with main(), it is where the GUI thread is started
bool MyApp::OnInit()
{
    // Create a frame with button
    MyFrame* frame = new MyFrame();
    // Show the frame with its button
    frame->Show( true );
    // If return value is false, the wxWidgets framework will kill the app
    return true;
}
MyFrame::MyFrame() : wxFrame( NULL, wxID_ANY, "Test Exit" )
{
    // wxWidgets requires all controls to be placed in a sizer
    m_frame_sizer = new wxBoxSizer( wxVERTICAL );
    // Assign the sizer to the frame
    this->SetSizer( m_frame_sizer );
    m_quit_button = new wxButton( this, wxID_EXIT, "Quit" );
    // Put the button into the sizer
    m_frame_sizer->Add( m_quit_button, wxSizerFlags().Center() );
    // Here we bind the button click event to the OnExit method of MyFrame
    // keep in mind that this technique will bind all buttons with id wxID_EXIT to the method
    // m_quit_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::OnExit, this) will also work
    // to handle the event for just the m_quit_button (notice the lack of wxID_EXIT, it is not needed in this case)
    Bind( wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::OnExit, this, wxID_EXIT );
}
MyFrame::~MyFrame()
{
    // for illustration, not strictly needed here becasue the entire app is shutting down
    Unbind( wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::OnExit, this, wxID_EXIT );
    // OR m_quit_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &MyFrame::OnExit, this) for the alternative form
}
void MyFrame::OnExit( wxCommandEvent& event )
{
    // Setup a message box with (in order below) the user query text, a title, and style which puts yes/no button and a question mark icon
    // Create the message box on the stack as opposed to the heap becasue we only need it here
    int answer = wxMessageBox( "Do you rally want to quit?", "Exit App", wxYES_NO | wxICON_QUESTION );
    if( answer == wxYES )
    {
        this->Close( true );
    }
    // else just return
}

wxYES 与 wxID_YES 的值不同(代码是 2 与 5103)。 wxMessageDialog::ShowModal returns “wxID_OK、wxID_CANCEL、wxID_YES、wxID_NO 或 wxID_HELP 之一”。因此所写的 switch 语句将始终触发 default case。这适用于 wx3.1 - 希望这些变量在未来会被合并,因为冗余值确实会导致错误。

为了完整起见,提供的 switch 语句应该是:

switch (dialog_return_value)
{
case wxID_YES: //Subtly different from wxYES
    Close(true);
    break;
case wxID_NO: //Not wxNO
    Close(false);
    break;
default:
    Close(false);
};

我检查了代码 return 值与输入样式值不一样,我们需要用 wxID_YES[=14 检查 return 值=] 而不是 wxYES!