【问题标题】:How can I execute the function when button in wxYES_NO is pressed?按下 wxYES_NO 中的按钮时如何执行该功能?
【发布时间】:2020-07-07 00:18:55
【问题描述】:

也许我的标题不清楚,所以我在这里说一个更准确的解释:

我只是在学习WxWidgets,我现在正在尝试制作两个文件:main.cpp 和Quit.h。 Main.cpp 将包含应用程序的核心,Quit.h 将包含退出对话框的类:Do you really want to quit this application (Yes / No)。

现在这是我的 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(),但我不知道哪个事件代表这个:“按下 yes 按钮(在 wxYES_NO 按钮系统中)”。我不能说:按下 wxYES_NO 因为这是两个按钮(YES 和 NO)。

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

谢谢!

附: 对于这个不清楚的问题,我真的很抱歉,但我希望你能理解。请注意,我只是一个初学者,所以请不要在答案中使用这么多“技术性”词汇和表达方式。我阅读了文档,但它使用了很多技术表达和解释。另外,我读了this 的书。

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

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

退出.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?"));
}

然后它不起作用。我找不到解决方案,所以,如果你有时间,请帮忙。

再次感谢您!

【问题讨论】:

  • 通过学习C++框架来学习C++并没有多大意义。请先学习语言,然后再回到关于 wxWidgets 的问题。您使用的代码写得不好(设计),正如第二个答案指出的那样 - 没有多大意义。请学习一些 C++ 课程,了解 C++ 的工作原理和方式,然后尝试用它进行一些编程。

标签: c++ events modal-dialog wxwidgets


【解决方案1】:

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

另外查看这个 wxWidgets 用户论坛帖子,其中详细解释了调用成员和非成员方法https://forums.wxwidgets.org/viewtopic.php?t=39817

wxYES_NO 是一个样式标志,它告诉 wxWidgets 框架您需要对话框中的“是”和“否”按钮。检查ShowModal() 的返回值是否等于定义为wxYESwxNO 的内置宏之一。

查看这里的宏定义https://docs.wxwidgets.org/trunk/defs_8h.html

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

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

这是检查返回值的方法:

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

您正在执行一项技术任务,可以预期会涉及到学习“技术”词汇。

【讨论】:

  • 很抱歉在您写完答案后更改了问题,但是如果单击“是”,如何返回值 true,如果单击“否”,如何返回值 false ?谢谢!
【解决方案2】:

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

只要您使用 wxWidgets 3+,您就可以复制/粘贴/编译/运行以下代码(我很确定 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
}

【讨论】:

    【解决方案3】:

    wxYES 是与 wxID_YES 不同的值(代码是 2 与 5103)。 wxMessageDialog::ShowModal 返回“wxID_OK、wxID_CANCEL、wxID_YES、wxID_NO 或 wxID_HELP 之一”。因此,所写的 switch 语句将始终触发默认情况。这适用于 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);
    };
    

    【讨论】:

      【解决方案4】:

      我检查了代码返回值与输入样式值不一样,我们需要用wxID_YES而不是wxYES检查返回值!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-29
        • 1970-01-01
        • 2015-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-31
        相关资源
        最近更新 更多