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

帅比萌擦擦* 提交于 2020-07-08 00:31:10

问题


Maybe my title is unclear, so I will tell here a more precise explanation:

I am just learning WxWidgets, and I am now trying to make two files: main.cpp and Quit.h. Main.cpp will have the core of the application, and Quit.h will have the class for the quit dialog: Do you really want to quit this application (Yes / No).

Now this is my Quit.h file (without include part):

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();
}

And here I am stuck. I tried with wxDECLARE_EVENT_TABLE(), but I don't know which event stands for this: "on the press of yes button (in wxYES_NO system of buttons)". I can't say: on the press of wxYES_NO because these are two buttons (both YES and NO).

So how can I execute the function when the button YES is pressed?

Thank you!

P.S. I really apologize for this unclear question, but I hope, that you'll understand. Note that I am just a beginner, so please don't use so many "technical" words and expressions in the answer. I read the documentation, but it uses so many technical expressions and explanation. Also, I read this book.

P.P.S. Have you noticed that there are a lot of questions on SE now, while there is COVID-19 on its way?

EDIT: When I was making the program on, I came to the other error. Minimal code:

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);
    };
}

and then I have this line in main.cpp:

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

And then it doesn't work. I can't find the solution, so, if you have some time, please help.

Thank you again!


回答1:


I would suggest using the wxEvtHandler::Bind<>() function as detailed in the wxWidgets documentaton at https://docs.wxwidgets.org/3.0/overview_events.html. The Bind() function allows dynamic binding of events and the syntax is one line of code as compared to setting up tables to link events to objects.

Additionally see this wxWidgets user forum thread which has detailed explanation for calling member and nonmember methods https://forums.wxwidgets.org/viewtopic.php?t=39817

wxYES_NO is a style flag that tells wxWidgets framework that you want both yes and no buttons in your dialog. Check if the return value of ShowModal() is equal to one of the builtin macros defined as wxYES and wxNO.

See here for the macro definitions https://docs.wxwidgets.org/trunk/defs_8h.html

And you should read up on wxDiaglog. Start here https://docs.wxwidgets.org/trunk/classwx_dialog.html

Do you want to return the value to the caller of Quit::Quit()? Constructors do not return values, you can set a member variable to the value but remember that if the object is destroyed then your member variable is gone too. You have not provided enough information to know what needs to be done for cleanup when you Quit() so I will provide you with the code to check the return value, just fill in what you need in the case body.

Here is how you would check the return value:

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 */ ;
    };
}

You are doing a technical task, it is reasonable to expect that learning "technical" words will be involved.




回答2:


I was trying to stick to using as much as possible your code but it makes no sense to me using a plain class to close the application. In that case with wxWidgets you still need to reference your main frame to accomplish the closure. There are easier ways as shown in the example below. Following is a full working example of an application which simply has a quit button on a frame. You click the button and get the quit message dialog. wxWidgets allows creating dialogs on the stack as opposed to the heap and that is what you need here because the dialog is trivial and will not be reused.

You can copy/paste/compile/run the following code as long as you are using wxWidgets 3+ (I am pretty sure Bind() was added then, may have been slightly earlier)

#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
}


来源:https://stackoverflow.com/questions/60866025/how-can-i-execute-the-function-when-button-in-wxyes-no-is-pressed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!