Как выполнить функцию, когда нажата кнопка в wxYES_NO? - PullRequest
0 голосов
/ 26 марта 2020

Возможно, мой заголовок неясен, поэтому я приведу более точное объяснение:

Я просто изучаю WxWidgets и сейчас пытаюсь создать два файла: main. cpp и Quit.h. , Main. cpp будет иметь ядро ​​приложения, а Quit.h будет иметь класс для диалога выхода: вы действительно хотите выйти из этого приложения (Да / Нет).

Теперь это мой Файл quit.h (без 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();
}

И вот я застрял. Я пробовал с wxDECLARE_EVENT_TABLE(), но я не знаю, какое событие означает это: «при нажатии кнопки yes (в системе кнопок wxYES_NO)». Я не могу сказать: по нажатию кнопки wxYES_NO, потому что это две кнопки (и ДА, и НЕТ).

Так как я могу выполнить функцию, когда нажата кнопка ДА?

Спасибо Вы!

PS Я действительно извиняюсь за этот неясный вопрос, но я надеюсь, что вы поймете. Обратите внимание, что я только начинающий, поэтому, пожалуйста, не используйте так много «технических» слов и выражений в ответе. Я прочитал документацию, но она использует так много технических выражений и объяснений. Кроме того, я прочитал эту книгу.

PPS. Вы заметили, что сейчас много вопросов по 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);
    };
}

, и тогда у меня есть эта строка в основном. cpp:

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

И тогда это не работает , Я не могу найти решение, поэтому, если у вас есть время, пожалуйста, помогите.

Еще раз спасибо!

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

Я бы предложил использовать функцию wxEvtHandler::Bind<>(), как подробно описано в документе wxWidgets на https://docs.wxwidgets.org/3.0/overview_events.html. Функция Bind () позволяет динамически связывать события c, а синтаксис занимает одну строку кода по сравнению с настройкой таблиц для привязки событий к объектам.

Дополнительно см. Эту ветку форума пользователя wxWidgets с подробным объяснением. для вызова методов-членов и не-членов https://forums.wxwidgets.org/viewtopic.php?t=39817

wxYES_NO - это флаг стиля, который сообщает платформе wxWidgets о том, что в вашем диалоговом окне вам нужны кнопки да и нет. Убедитесь, что возвращаемое значение ShowModal() равно одному из встроенных макросов, определенных как wxYES и wxNO.

См. Здесь определения макросов 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 */ ;
    };
}

Вы выполняете техническое задание, разумно ожидать, что изучение «технических» слов будет задействовано.

1 голос
/ 26 марта 2020

Я пытался использовать как можно больше вашего кода, но нет смысла использовать простой класс для закрытия приложения. В этом случае с wxWidgets вам все равно нужно сослаться на ваш основной фрейм, чтобы выполнить sh закрытие. Есть более простые способы, как показано в примере ниже. Ниже приводится полный рабочий пример приложения, в котором просто есть кнопка выхода на рамке. Вы нажимаете кнопку и получаете диалог сообщения о выходе. 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
}
...