我是wxWidgets的先生。通过调用Destroy()
事件处理程序中的MyFrame::OnClose()
,我遇到了终止应用程序的标准方法的问题:
在MyApp::OnInit()
我正在使用从配置文件加载的构造函数参数创建MyFrame
(使用依赖注入)。此参数存储在MyFrame
内,并且可以在MyFrame
的生命周期内更改。
当应用程序退出时,我需要MyApp::OnExit()
从MyFrame
获取此参数并保存。因此MyFrame
中必须仍然存在MyApp::OnExit()
。
我不想在MyFrame::OnClose()
中保存此参数,因为我不希望MyFrame
依赖于配置文件函数 - 这是更高级别的应用程序类的工作。
我认为如果我正在制作某些内容,例如MyFrame
中OnInit()
,那么完美的地方可以摧毁它OnExit()
对吗?那么,是否存在一些正确的方法来延迟销毁MyFrame
到MyApp::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();
}
答案 0 :(得分:1)
也许在MyFrame :: OnClose()中你可以让它发出一个boost :: signal通知订阅者它即将被销毁?当然,您将在发出此信号时在MyApp中设置一个方法,并使用此方法保存该参数。
在一个稍微相关的说明中,每当wxFrame派生的对象被销毁时,我总是做类似的事情。也就是说,我会在它被销毁之前将它保存到持久存储中。我处理这个问题的方法是简单地使用wxConfig。我将在wxEVT_CLOSE_WINDOW处理程序方法中获取全局wxConfig对象的句柄,然后保存我需要保存的内容。
对我来说,这是一个更清洁的设计。对象应该负责将自己保存到持久存储。让另一个对象A(在您的情况下,您的MyApp对象)负责保存对象B的状态意味着对象A将始终需要保持最新,以确定对象B的哪些内容需要保存。 IMO,对象A对对象B说“嘿,保存自己”然后让对象B处理细节要好得多。
答案 1 :(得分:0)
以下是ExitMainLoop的解决方案:
void MyFrame::OnClose( wxCloseEvent &event )
{
wxTheApp->ExitMainLoop();
}