简体   繁体   English

wxWindow 中未调用关闭事件

[英]Close event not invoked in wxWindow

I'm creating a program that can have multiple files open simultaneously (using a wxAuiNotebook).我正在创建一个可以同时打开多个文件的程序(使用 wxAuiNotebook)。 I'm trying to create a system that warns the user whenever he tries to close a window with unsaved data, but the close event doesn't seem to get invoked.我正在尝试创建一个系统,每当用户尝试关闭带有未保存数据的 window 时都会发出警告,但关闭事件似乎没有被调用。

TimelineWindow::TimelineWindow(wxWindow* parent, TimelineData* data) 
    : wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxALWAYS_SHOW_SB)
{
    SetData(data);
    Bind(wxEVT_CLOSE_WINDOW, &TimelineWindow::OnClose, this);
}

void TimelineWindow::OnClose(wxCloseEvent& event)
{
    if (event.CanVeto() && data->IsDirty()) // Dunno what this does, but the wiki tells me to use this
    {
        int choice = wxMessageBox("Save changes?",
            "Unsaved changes", wxICON_QUESTION | wxYES_NO | wxCANCEL, this);

        switch (choice)
        {
            // Save changes and close
        case wxYES:

            break;

            // Close without saving changes
        case wxNO:

            break;

            // Don't close
        case wxCANCEL:

            break;
        }

        event.Veto();
    }

    event.Skip();
}

I've also tried binding the event through DECLARE_EVENT_TABLE(), which also didn't work.我也试过通过 DECLARE_EVENT_TABLE() 绑定事件,这也没有用。 I guess this event doesn't work with wxScrolledWindow's or wxWindow's in general?我想这个事件一般不适用于 wxScrolledWindow 或 wxWindow? Is there any way to make it work?有什么办法让它发挥作用吗?

Also, I need to make it so if the user presses wxCANCEL, the window closing process is cancelled.另外,我需要这样做,如果用户按下 wxCANCEL,window 关闭过程将被取消。 Is this possible?这可能吗?

wxEVT_CLOSE_WINDOW is only sent to top level windows, so you need to bind to it there and not in TimelineWindow which looks like a child window. This makes sense, if you think about it, because only top level windows can really be closed by the user -- all the other windows can only be destroyed ("closed" is the word used for TLWs only) by the program itself, so it doesn't need an event to know about when it happens. wxEVT_CLOSE_WINDOW只发送到顶层 windows,所以你需要在那里绑定它,而不是在TimelineWindow中,它看起来像一个孩子 window。如果你考虑一下,这是有道理的,因为只有顶层 windows 才能真正被用户关闭-- 所有其他 windows 只能由程序本身销毁(“关闭”是仅用于 TLW 的词),因此它不需要事件来知道它何时发生。 And if you really need to do something when a window is destroyed, just do it in the usual way, by doing it in its destructor.如果您真的需要在 window 被销毁时执行某些操作,只需按照通常的方式在其析构函数中执行即可。 Of course, you can't veto destroying the window by then, but then you shouldn't have to, because different parts of your program are not supposed to fight with each other!当然,到那时你不能否决销毁 window,但你不应该这样做,因为你的程序的不同部分不应该互相争斗!

You can prevent the window from being closed in your handler by vetoing it, ie calling event.Veto() , as you already do -- except you should only do it if the user answers that they don't want to close, not always.您可以通过否决它来防止 window 在您的处理程序中被关闭,即调用event.Veto() ,就像您已经做的那样——除非您只在用户回答他们不想关闭时才应该这样做,而不是总是.

Finally, consider using wxMessageDialog::SetYesNoCancelLabels() to make the choices in the dialog more clear to the user.最后,考虑使用wxMessageDialog::SetYesNoCancelLabels()使对话框中的选择对用户来说更清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM