如何解决替换 wxWidgets 中 wxFrame 的 sizer
我正在编写一个小型扫雷游戏,只是为了熟悉 wxWidgets(Windows,wxWidgets 3.1.4)。该应用程序可以很好地处理一款游戏,现在我想添加“新游戏”功能。对于布局,我使用的是 wxGridSizer
。
我的第一种方法是创建一个包含新字段的新 wxGridSizer
,然后将当前的 sizer 替换为新的。尽管我想出了如何重用旧的 sizer(通常它也可能是一个更好的解决方案),但我还是很好奇如何正确更换 sizer。
我能够将我的问题简化为:
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
class MyApp : public wxApp {
public:
virtual bool OnInit();
};
class MyFrame : public wxFrame {
public:
MyFrame(const wxString &title,const wxPoint &pos,const wxSize &size);
private:
void OnExit(wxCommandEvent &event);
void OnRefill(wxCommandEvent &event);
wxDECLARE_EVENT_TABLE();
};
enum { ID_Refill = 1 };
wxBEGIN_EVENT_TABLE(MyFrame,wxFrame)
EVT_MENU(ID_Refill,MyFrame::OnRefill)
EVT_MENU(wxID_EXIT,MyFrame::OnExit)
wxEND_EVENT_TABLE() wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit() {
MyFrame *frame = new MyFrame("Hello World",wxPoint(50,50),wxSize(300,200));
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString &title,const wxSize &size)
: wxFrame(NULL,wxID_ANY,title,pos,size) {
wxMenu *menu = new wxMenu;
menu->Append(ID_Refill,"&Refill...\tCtrl-R","Creates new layout");
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menu,"&Menu");
SetMenuBar(menuBar);
wxGridSizer *sizer = new wxGridSizer(2,2,1,1);
SetSizer(sizer);
for (auto i = 0; i < 4; i++) {
wxButton *button = new wxButton(this,std::to_string(i),wxDefaultPosition,wxDefaultSize,0);
sizer->Add(button,wxALL,0);
}
}
void MyFrame::OnExit(wxCommandEvent &) {
Close(true);
}
void MyFrame::OnRefill(wxCommandEvent &) {
Freeze();
GetSizer()->Clear(true);
wxGridSizer *sizer = new wxGridSizer(3,3,1);
SetSizer(sizer);
for (auto i = 0; i < 9; i++) {
wxButton *button = new wxButton(this,std::string("Refilled") + std::to_string(i),0);
}
sizer->Layout();
Thaw();
Refresh();
}
问题是在 OnRefill
函数之后,应用只显示第一个按钮 (Refilled0
),而不显示其余按钮。
在OnRefill
之前:
OnRefill
之后:
我的问题是如何正确替换 MyFrame
的 sizer?根据我从示例和文档中的理解,这应该可行,但我想我遗漏了一些东西。
解决方法
要替换 sizer,您只需对 MyFrame::OnRefill
方法进行一个小改动。
无需调用 sizer->Layout();
,只需调用 Layout();
。我不完全确定为什么为 sizer 调用 Layout 不起作用。
完整的方法如下所示:
void MyFrame::OnRefill(wxCommandEvent &) {
Freeze();
GetSizer()->Clear(true);
wxGridSizer *sizer = new wxGridSizer(3,3,1,1);
SetSizer(sizer);
for (auto i = 0; i < 9; i++) {
wxButton *button = new wxButton(this,wxID_ANY,std::string("Refilled") + std::to_string(i),wxDefaultPosition,wxDefaultSize,0);
sizer->Add(button,wxALL,0);
}
Layout();
Thaw();
Refresh();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。