如何在不破坏主框架的情况下终止wxWidgets消息循环

How to terminate wxWidgets message loop without destroying main frame?

本文关键字:情况下 终止 wxWidgets 循环 消息 框架      更新时间:2023-10-16

我是wxWidgets的初学者。通过在MyFrame::OnClose()事件处理程序中调用Destroy()来终止应用程序的标准方式有问题:

MyApp::OnInit()中,我正在创建MyFrame与从配置文件加载的构造函数参数(使用依赖注入)。该参数存储在MyFrame中,并且可以在MyFrame的生存期内更改。

当应用程序退出时,我需要MyApp::OnExit()MyFrame获取此参数并保存它。所以MyFrame一定仍然存在于MyApp::OnExit()中。

我不喜欢在MyFrame::OnClose()中保存这个参数,因为我不希望MyFrame依赖于配置文件函数-这是应用程序类在更高级别的工作。

我想如果我正在创建一些东西,例如OnInit()中的MyFrame,那么摧毁它的完美地方是OnExit(),对吧?因此,是否存在延迟MyFrameMyApp::OnExit()销毁的正确方法?

myapp.cpp :

#include <wx/wx.h>
#include "myframe.h"
class MyApp : public wxApp {
public:
    virtual bool OnInit() override;
    virtual int  OnExit() override;
    MyFrame* m_myframe;
};

IMPLEMENT_APP( MyApp );
extern int  LoadSettings();
extern void SaveSettings( int param );
bool MyApp::OnInit()
{
    const int param = LoadSettings();
    m_myframe = new MyFrame( "MyFrame title", param );
    m_myframe->SetIcon( wxICON(aaaa) );
    m_myframe->Show();
    return true;
}
int MyApp::OnExit()
{
    const int param = m_myframe->GetParameter();
    SaveSettings( param );
    m_myframe->Destroy();
    return 0;
}

myframe.h :

#include <wx/wx.h>
class MyFrame: public wxFrame {
public:
    MyFrame( const wxString& title, int param );
    int GetParameter() const { return m_param; }
    /* ... */
private:
    void OnClose( wxCloseEvent& event );
    int m_param;
};

myframe.cpp :

#include "myframe.h"
MyFrame::MyFrame( const wxString& title, int param )
:   wxFrame( nullptr, -1, title ),
    m_param( param )
{
    Bind( wxEVT_CLOSE_WINDOW, &MyFrame::OnClose, this );
}
void MyFrame::OnClose( wxCloseEvent &event )
{
    // Want to terminate message loop but without destroying this
    // Destroy();
}

也许在MyFrame::OnClose()中你可以让它发出一个boost::信号,通知订阅者它即将被销毁?然后,当然,您将在MyApp中设置一个方法,以便在发出该信号时调用该方法,并让该方法保存该参数。

在一个稍微相关的注意事项上,我过去总是在销毁wxframe派生的对象时做类似的事情。也就是说,我会让它在销毁之前将一些信息保存到持久存储中。我处理这个问题的方法是简单地使用wxConfig。我将在wxEVT_CLOSE_WINDOW处理程序方法中获得全局wxConfig对象的句柄,然后保存我需要从那里保存的内容。

对我来说,这是一个更简洁的设计。对象应该负责将自己保存到持久存储中。有另一个对象A(在你的情况下,你的MyApp对象)负责保存对象B的状态意味着对象A将始终需要保持最新的对象B的东西需要保存。在我看来,对象A最好对对象B说"嘿,救救你自己",然后让对象B处理细节。

ExitMainLoop的解决方案:

void MyFrame::OnClose( wxCloseEvent &event )
{
    wxTheApp->ExitMainLoop();
}