Как правильно использовать wxID_OK и wxID_CANCEL? - PullRequest
1 голос
/ 04 апреля 2020

Есть окно графика, которое при щелчке правой кнопкой мыши отображает всплывающее меню, а затем при выборе показывает окно:

void CChart::Series_OnPopupMenu(wxCommandEvent& evt)
{
    int evtID = evt.GetId();


if (m_dlgManageSeriesData)
    return;


if(evtID==ID_ADDNEW) 
{
    m_dlgManageSeriesData=new dlgManageSeriesData(this);

    m_dlgManageSeriesData->Bind(wxEVT_CLOSE_WINDOW, &CChart::OnDlgManageSeriesDataClose, this);


    m_dlgManageSeriesData->Show();
}

Чтобы иметь возможность отслеживать, закрыто ли показанное окно:

void CChart::OnDlgManageSeriesDataClose(wxCloseEvent & evt)
{
    m_dlgManageSeriesData->Unbind(wxEVT_CLOSE_WINDOW, &CChart::OnDlgManageSeriesDataClose, this);

    m_dlgManageSeriesData = nullptr;

    evt.Skip();
}

Окно, а именно dlgManageSeriesData, имеет две кнопки:

m_BtnOK = new wxButton(this, wxID_OK, "OK"); 

m_BtnCancel = new wxButton(this, wxID_CANCEL, "Cancel");

Например, когда нажата кнопка Отмена, просто оно должно закрыть окно:

void dlgManageSeriesData::OnBtnCancelClick(wxCommandEvent & event)
{
    Close();
}

Мало что происходит в разных сценариях ios:

1) Если я не пытаюсь вручную закрыть окно с помощью dlgManageSeriesData::OnBtnCancelClick, то сохраняя wxID_CANCEL и нажатие на кнопку Cancel закрывает ее, как и ожидалось, от wxDialog . Однако , похоже, что закрытие окна таким способом не генерирует wxEVT_CLOSE_WINDOW, так как CChart::OnDlgManageSeriesDataClose никогда не вызывается.

2) Если я пытаюсь закрыть окно с Close() при сохранении wxID_CANCEL окно никогда не закрывается.

3) Если я изменил идентификатор кнопки и объявил кнопку отмены как m_BtnCancel = new wxButton(this, wxID_ANY, "Cancel");, все работает как положено, так что кнопка отмены закрывает окно и вызывается CChart::OnDlgManageSeriesDataClose. Аналогичное обоснование следует для кнопки OK.


Возможно, я неправильно понял некоторые концепции, но пара вопросов:

1) Является ли система обработки событий wxWidgets ручками обработки событий эти идентификаторы (wxID_OK или wxID_CANCEL) по-разному, так что это препятствовало закрытию окна?

2) Каков хороший способ использования wxID_OK и wxID_CANCEL, если я все еще хочу предпринять некоторые действия, когда окно закрывается?

Я использую wxWidgets 3.1.3 на Windows 10 с VS 2017.

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

wxWidgets действительно показывает wxID_OK и wxID_CANCEL специально в диалогах по умолчанию и предоставляет встроенные логи c для стандартного поведения.

Однако это не должно иметь никакого значения, если вы не использовать wxDialog вообще, как вы, кажется, говорите, хотя это не совсем ясно. И, на самом деле, если вы не хотите показывать его модально, нет реальной причины использовать wxDialog.

Если вы действительно просто создаете нормальный wxFrame и вызываете Close() из обработчик события для одной из его кнопок, он должен работать независимо от идентификатора, который вы используете для него.

0 голосов
/ 04 апреля 2020

А-а-а, wxWidgets ... хорошие времена:)

wxID_ * в кнопке ctor позволяет реализовывать только обработчики событий во всплывающем окне:

BEGIN_EVENT_TABLE(FooClass, wxDialog)
    EVT_BUTTON(wxID_OK, FooClass::OnButtonOkClick)
END_EVENT_TABLE()

Вы можете использовать идентификаторы для закрытия модальных диалогов:

void FooClass::OnButtonOkClick(wxCommandEvent& event)
{

   EndModal(wxID_OK);

   event.Skip(false);
}

Затем вызывающая сторона получает это значение в качестве возвращаемого значения для вызова ShowModal:

...
FooClass dialog(this);
int result = dialog.ShowModal();
if (result == wxID_OK)
{
    ...
}

Если ваше всплывающее окно имеет тип wxWindow, я думаю, что там не этот механизм для возврата значения. Рассмотрите возможность получения из wxDialog.

...