问题描述
我有以下GUI,该GUI是在当前位置使用空的sizer创建的。大小调整器可能是折叠的,因为它的比例为0,但是我这样画了它,所以您可以看到它。
当您单击“ + Need”按钮时,程序将创建带有一堆按钮和控件的新的定尺寸器,然后将其添加到该定尺寸器中。但是,它们没有出现在应有的位置。实际上,新的sizer及其内容已折叠,并且位于您的左上角。
显然不是我想要的。但是,当我仅通过单击并拖动边缘之一来调整窗口大小时,所有内容都会弹出到位置:
我尝试调用我可以想到的-> Layout()和-> Fit()的每种组合,但我无法使其正常工作。这是在程序加载时创建GUI的代码,由框架构造函数调用。它创建“ needs_sizer_wrap”,它是BoxSizer,开始为空,单击按钮时将新的动态尺寸调整器添加到其中。注意,在图像中它显示为“ needsSizerWrap”,但代码实际上是“ needs_sizer_wrap”
// creates the basic GUI
void MullSimple_2Frame::createGUI()
{
// mainPanel
main_panel = new wxPanel(this,wxID_ANY);
// mainPanelSizer (vertical)
wxBoxSizer *main_panel_sizer = new wxBoxSizer(wxVERTICAL);
// deckInfo (horizontal)
// deck data along top like deck name,deck id,deck set
wxBoxSizer *deck_info_sizer = new wxBoxSizer(wxHORIZONTAL);
main_panel_sizer->Add(deck_info_sizer,wxSizerFlags(0).Expand());
// DECK ID
// label
wxStaticText *label1 = new wxStaticText(main_panel,wxID_ANY,"DECK ID: ");
deck_info_sizer->Add(label1,wxSizerFlags(0).Expand());
// value
deck_info_id = new wxStaticText(main_panel,"-1");
deck_info_sizer->Add(deck_info_id,wxSizerFlags(0).Expand());
// DECK NAME
// label
wxStaticText *label2 = new wxStaticText(main_panel,",NAME: ");
deck_info_sizer->Add(label2,wxSizerFlags(0).Expand());
// value
deck_info_name = new wxTextCtrl(main_panel,"");
deck_info_name->Bind(wxEVT_TEXT,&MullSimple_2Frame::ChangeDeckValue,this);
deck_info_sizer->Add(deck_info_name,wxSizerFlags(0).Expand());
// DECK SET
// label
wxStaticText *label3 = new wxStaticText(main_panel,SET: ");
deck_info_sizer->Add(label3,wxSizerFlags(0).Expand());
// value
deck_info_set = new wxTextCtrl(main_panel,"");
deck_info_set->Bind(wxEVT_TEXT,this);
deck_info_sizer->Add(deck_info_set,wxSizerFlags(0).Expand());
// DECK SAVED
// can't do stuff unless the deck is saved. saving allows us to set data_vars.
// label
wxStaticText *label4 = new wxStaticText(main_panel,SAVED: ");
deck_info_sizer->Add(label4,wxSizerFlags(0).Expand());
// value
deck_info_if_saved = new wxStaticText(main_panel,"FALSE");
deck_info_sizer->Add(deck_info_if_saved,wxSizerFlags(0).Expand());
// progSizer (horizontal)
// program contains 3 "columns"
wxBoxSizer *prog_sizer = new wxBoxSizer(wxHORIZONTAL);
main_panel_sizer->Add(prog_sizer,wxSizerFlags(1).Expand());
// PROGRAM COLUMN 1: DECK CASTABLES
// castables column
wxBoxSizer *deck_casts_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(deck_casts_sizer,wxSizerFlags(1).Expand());
// castables title
wxStaticText *deck_casts_title = new wxStaticText(main_panel,"Castables",wxDefaultPosition,wxSize(-1,30),wxALIGN_CENTER_HORIZONTAL);
deck_casts_title->SetBackgroundColour(*wxYELLOW);
deck_casts_sizer->Add(deck_casts_title,wxSizerFlags(0).Expand());
// castables content
for ( int i = 0; i < 25; i++ )
{
// need to set a size so that they're small enough to all fit on my crappy laptio
wxTextCtrl *text_ctrl = new wxTextCtrl(main_panel,wxEmptyString,20));
text_ctrl->Bind(wxEVT_TEXT,this);
deck_castable_inputs.push_back(text_ctrl);
deck_casts_sizer->Add(text_ctrl,wxSizerFlags(0).Expand());
}
// PROGRAM COLUMN 2: DECK LANDS
wxBoxSizer *deck_lands_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(deck_lands_sizer,wxSizerFlags(1).Expand());
// lands title
wxStaticText *deck_lands_title = new wxStaticText(main_panel,"Lands",wxALIGN_CENTER_HORIZONTAL);
deck_lands_title->SetBackgroundColour(*wxGREEN);
deck_lands_sizer->Add(deck_lands_title,wxSizerFlags(0).Expand());
// lands content
for ( int i = 0; i < 25; i++ )
{
wxTextCtrl *text_ctrl = new wxTextCtrl(main_panel,this);
deck_land_inputs.push_back(text_ctrl);
deck_lands_sizer->Add(text_ctrl,wxSizerFlags(0).Expand());
}
// PROGRAM COLUMN 3: HAND
wxBoxSizer *hand_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(hand_sizer,wxSizerFlags(1).Expand());
// hand title
wxStaticText *hand_title = new wxStaticText(main_panel,"Hand",wxALIGN_CENTER_HORIZONTAL);
hand_title->SetBackgroundColour(*wxBLUE);
hand_sizer->Add(hand_title,wxSizerFlags(0).Expand());
// hand content
for ( int i = 0; i < 7; i++ )
{
wxTextCtrl *text_ctrl = new wxTextCtrl(main_panel,20));
hand_inputs.push_back(text_ctrl);
hand_sizer->Add(text_ctrl,wxSizerFlags(0).Expand());
}
// PROGRAM COLUMN 4: MULL OPTS
wxBoxSizer *mull_opts_sizer = new wxBoxSizer(wxVERTICAL);
prog_sizer->Add(mull_opts_sizer,wxSizerFlags(3).Expand());
// MULL OPTS HORIZONTAL 1: MULL_OPTS_BUTTONS
wxBoxSizer *mull_opts_but_sizer = new wxBoxSizer(wxHORIZONTAL);
mull_opts_sizer->Add(mull_opts_but_sizer,wxSizerFlags(0).Expand());
// add need button
mull_opts_but_add_need = new wxButton(main_panel,"+ Need");
mull_opts_but_add_need->SetMinSize(wxSize(-1,50));
mull_opts_but_add_need->Bind(wxEVT_BUTTON,&MullSimple_2Frame::addNeedGlobal,this);
mull_opts_but_sizer->Add(mull_opts_but_add_need,wxSizerFlags(1).Expand());
// remove need button
mull_opts_but_remove_need = new wxButton(main_panel,"- Need");
mull_opts_but_remove_need->SetMinSize(wxSize(-1,50));
mull_opts_but_remove_need->Bind(wxEVT_BUTTON,&MullSimple_2Frame::removeNeedGlobal,this);
mull_opts_but_sizer->Add(mull_opts_but_remove_need,wxSizerFlags(1).Expand());
// reset all button
mull_opts_but_reset_needs = new wxButton(main_panel,"Reset All");
mull_opts_but_reset_needs->SetMinSize(wxSize(-1,50));
mull_opts_but_reset_needs->Bind(wxEVT_BUTTON,&MullSimple_2Frame::resetNeedsGlobal,this);
mull_opts_but_sizer->Add(mull_opts_but_reset_needs,wxSizerFlags(1).Expand());
// calculate button
mull_opts_but_calculate = new wxButton(main_panel,"Calculate");
mull_opts_but_calculate->SetMinSize(wxSize(-1,50));
mull_opts_but_calculate->Bind(wxEVT_BUTTON,&MullSimple_2Frame::calcNeedsGlobal,this);
mull_opts_but_sizer->Add(mull_opts_but_calculate,wxSizerFlags(1).Expand());
// needs sizer wrap,contains the needs,starts out empty
needs_sizer_wrap = new wxBoxSizer(wxVERTICAL);
mull_opts_sizer->Add(needs_sizer_wrap,wxSizerFlags(0).Expand());
// MULL OPTS HORIZONTAL 2: NEEDS (in a stack)
// Make on base need we can use as a model
// at the bottom of the main panel stretches the log output
// fixed height so set proportion 0
wxBoxSizer *output_sizer = new wxBoxSizer(wxHORIZONTAL);
main_panel_sizer ->Add(output_sizer,wxSizerFlags(0).Expand());
log_output = new wxTextCtrl(main_panel,100),wxTE_MULTILINE);
log_output->SetBackgroundColour(*wxYELLOW);
output_sizer ->Add(log_output,wxSizerFlags(1).Expand());
main_panel->SetSizerAndFit(main_panel_sizer);
this->Fit();
}
这是单击+需求按钮时插入附加的sizer的代码
void MullSimple_2Frame::addNeedGUI()
{
wxBoxSizer *need_sizer = new wxBoxSizer(wxVERTICAL);
// NEED ITEM HORIZONTAL 1: grid of filters,4 columns
// we'll put the same filters for every deck (for Now),// and no custom filter ability
std::vector<std::string> filters_in_deck;
filters_in_deck.push_back("Land");
...
// fixed 2 rows with 4 cols in each row
wxGridSizer *base_need_filters_sizer = new wxGridSizer(2,4,0);
need_sizer->Add(base_need_filters_sizer,wxSizerFlags(0).Expand());
for ( unsigned int i = 0; i < filters_in_deck.size(); i++ )
{
wxCheckBox *filter_check = new wxCheckBox(this->main_panel,myHelpFxns::ToWxString(filters_in_deck[i]));
base_need_filters_sizer->Add(filter_check,wxSizerFlags(1).Expand());
}
// NEED ITEM HORIZONTAL 2: line options
wxBoxSizer *base_need_line_sizer = new wxBoxSizer(wxHORIZONTAL);
need_sizer->Add(base_need_line_sizer,wxSizerFlags(0).Expand());
// line item -> "("
wxButton *need_line_open_brack_but = new wxButton(this->main_panel,"(",wxSize(50,-1));
base_need_line_sizer->Add(need_line_open_brack_but,wxSizerFlags(0).Expand());
// line item -> apply filters logic (any/all)
wxComboBox *need_line_apply_filters_combo = new wxComboBox(this->main_panel,wxID_ANY);
need_line_apply_filters_combo->Append("Any");
need_line_apply_filters_combo->Append("All");
base_need_line_sizer->Add(need_line_apply_filters_combo,wxSizerFlags(1).Expand());
// line item -> cards to draw combo Box
wxComboBox *need_line_cards_draw_combo = new wxComboBox(this->main_panel,wxID_ANY);
need_line_cards_draw_combo->Append("1 to Draw");
...
base_need_line_sizer->Add(need_line_cards_draw_combo,wxSizerFlags(1).Expand());
// line item -> source colors combo
wxComboBox *need_line_source_colors_combo = new wxComboBox(this->main_panel,wxID_ANY);
need_line_source_colors_combo->Append("Any");
...
base_need_line_sizer->Add(need_line_source_colors_combo,wxSizerFlags(1).Expand());
// line item -> cost colors combo
wxComboBox *need_line_cost_colors_combo = new wxComboBox(this->main_panel,wxID_ANY);
need_line_cost_colors_combo->Append("Any");
...
base_need_line_sizer->Add(need_line_cost_colors_combo,wxSizerFlags(1).Expand());
// line item -> cost amount combo
wxComboBox *need_line_cost_amount_combo = new wxComboBox(this->main_panel,wxID_ANY);
need_line_cost_amount_combo->Append("Any");
...
base_need_line_sizer->Add(need_line_cost_amount_combo,wxSizerFlags(1).Expand());
// line item -> specific card input
wxTextCtrl *need_line_specific_card_input = new wxTextCtrl(this->main_panel,wxEmptyString);
base_need_line_sizer->Add(need_line_specific_card_input,wxSizerFlags(1).Expand());
// line item -> ")"
wxButton *need_line_close_brack_but = new wxButton(this->main_panel,")",-1));
base_need_line_sizer->Add(need_line_close_brack_but,wxSizerFlags(0).Expand());
// line item -> "AND"
wxButton *need_line_and_but = new wxButton(this->main_panel,"AND",-1));
base_need_line_sizer->Add(need_line_and_but,wxSizerFlags(0).Expand());
// line item -> "OR"
wxButton *need_line_or_but = new wxButton(this->main_panel,"OR",-1));
base_need_line_sizer->Add(need_line_or_but,wxSizerFlags(0).Expand());
// NEED ITEM HORIZONTAL 3: NEED INLINE BUTTONS
wxBoxSizer *base_need_buts_sizer = new wxBoxSizer(wxHORIZONTAL);
need_sizer->Add(base_need_buts_sizer,wxSizerFlags(0).Expand());
wxButton *need_but_add_need_after_but = new wxButton(this->main_panel,"+");
base_need_buts_sizer->Add(need_but_add_need_after_but,wxSizerFlags(0).Expand());
wxButton *need_but_remove_this_but = new wxButton(this->main_panel,"-");
base_need_buts_sizer->Add(need_but_remove_this_but,wxSizerFlags(0).Expand());
needs_sizer_wrap->Add(need_sizer,wxSizerFlags(0).Expand().Border(wxALL,10));
//needs_sizer_wrap->Layout();
//needs_sizer_wrap->Fit(need_sizer);
}
解决方法
直到现在我才意识到这一点,但是根据文档,当您在top level window上调用Layout
时,使用窗口大小调整器布置子项或调整唯一子项的大小 覆盖整个窗口的面积。
此类重写基类Layout()方法以检查是否 窗口中恰好包含一个孩子-通常是这样, wxPanel通常被创建为wxTopLevelWindow的唯一子项– 如果是这种情况,请调整此子窗口的大小以覆盖 整个客户区。
所以我猜想在只有1个子窗口的框架上调用Layout是行不通的,因为该调用只会尝试调整面板的大小,但是面板不会更改尺寸,因此不会尝试重新布局其新的子窗口
似乎起作用的是添加类似的内容
this->main_panel->Layout();
到MullSimple_2Frame::addNeedGUI()
的末尾。这样会在面板上而不是框架上重新布局。
或者,根据文档,您可以仅使用调整大小的框架,并仅向其添加main_panel
。但是,正如我在另一个答案中所说的那样,通常只有一个窗口的尺寸调整器没有多大意义。