问题描述
我正在使用水平和垂直Boxsizer来构建我的GUI,到目前为止,我已经成功地完成了所有工作,只需在每个sizer上使用expand将所有内容添加到sizer中,然后调整diff元素的最小或最大宽度/高度以得到什么我想要。不过我遇到了一个奇怪的问题。
差距#1
我不了解差距#1,因为它似乎是不必要的。整个GUI以带有2个元素的垂直装箱器开始。红色的StaticText上方的所有内容都位于顶部,红色的StaticText包含在第二个元素中。
在最上面的子大小调整器中,所需的最大高度是TextCtrls的“ Castables”和“ Lands”列。这导致我进入奇怪的缺口#2 ...
差距#2
直到我为它上面的4个按钮设置了最大高度,这个间隙才出现。我在油漆上绘制了紫色轮廓,以便您可以看到尺寸调整器如何配合在一起(或者应该如何配合在一起,除非我弄错了)。间隙是在垂直尺寸调整器的开头,然后包含其他尺寸调整器...在设置这四个按钮的最大高度之前,这四个按钮的高度正好填充了该间隙区域。当我为它们设置最大高度时,我希望下面的所有内容向上滑动而不是向下滑动。
// mainPanel
wxPanel *mainPanel = new wxPanel(this,wxID_ANY);
// mainPanelSizer (vertical)
wxBoxSizer *mainPanelSizer = new wxBoxSizer(wxVERTICAL);
// progSizer (horizontal)
// contains program along top,and log window is along the bottom
// program contains 3 "columns"
wxBoxSizer *progSizer = new wxBoxSizer(wxHORIZONTAL);
mainPanelSizer->Add(progSizer,wxSizerFlags(1).Expand());
// 1. DECK
// deckSizer (horizontal)
wxBoxSizer *deckSizer = new wxBoxSizer(wxHORIZONTAL);
progSizer->Add(deckSizer,wxSizerFlags(1).Expand());
// castables column
wxBoxSizer *deckSizerCasts = new wxBoxSizer(wxVERTICAL);
deckSizer->Add(deckSizerCasts,wxSizerFlags(1).Expand());
// castables title
wxStaticText *deckCastsTitle = new wxStaticText(mainPanel,wxID_ANY,"Castables",wxDefaultPosition,wxDefaultSize,wxALIGN_CENTER_HORIZONTAL);
deckCastsTitle->SetBackgroundColour(*wxYELLOW);
deckCastsTitle->SetMaxSize(wxSize(-1,25));
deckSizerCasts->Add(deckCastsTitle,wxSizerFlags(1).Expand());
// castables content
for ( int i = 0; i < 25; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(mainPanel,wxEmptyString);
textCtrl->SetMinSize(wxSize(200,-1));
textCtrl->SetMaxSize(wxSize(-1,25));
deckInputCastables.push_back(textCtrl);
deckSizerCasts->Add(textCtrl,wxSizerFlags(1).Expand());
}
// lands column
wxBoxSizer *deckSizerLands = new wxBoxSizer(wxVERTICAL);
deckSizer->Add(deckSizerLands,wxSizerFlags(1).Expand());
// lands title
wxStaticText *deckLandsTitle = new wxStaticText(mainPanel,"Lands",wxALIGN_CENTER_HORIZONTAL);
deckLandsTitle->SetBackgroundColour(*wxGREEN);
deckLandsTitle->SetMaxSize(wxSize(-1,25));
deckSizerLands->Add(deckLandsTitle,wxSizerFlags(1).Expand());
// lands content
for ( int i = 0; i < 25; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(mainPanel,25));
deckInputLands.push_back(textCtrl);
deckSizerLands->Add(textCtrl,wxSizerFlags(1).Expand());
}
// 2. HAND
// handSizer (vertical)
wxBoxSizer *handSizer = new wxBoxSizer(wxVERTICAL);
progSizer->Add(handSizer,wxSizerFlags(1).Expand());
// hand title
wxStaticText *deckHandTitle = new wxStaticText(mainPanel,"Hand",wxALIGN_CENTER_HORIZONTAL);
deckHandTitle->SetBackgroundColour(*wxCYAN);
deckHandTitle->SetMaxSize(wxSize(-1,25));
handSizer->Add(deckHandTitle,wxSizerFlags(1).Expand());
// hand content
for ( int i = 0; i < 7; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(mainPanel,25));
handInputs.push_back(textCtrl);
handSizer->Add(textCtrl,wxSizerFlags(1).Expand());
}
// 3. OPTS
wxBoxSizer *optsSizer = new wxBoxSizer(wxVERTICAL);
progSizer->Add(optsSizer,wxSizerFlags(1).Expand());
// a. OPTS INSTRUCTIONS (horizontal)
// contains buttons for things can do,// add or remove needs,reset all,or calculate
wxBoxSizer *optsInstructSizer = new wxBoxSizer(wxHORIZONTAL);
optsSizer->Add(optsInstructSizer,wxSizerFlags(1).Expand());
wxButton *addNeedButton = new wxButton(mainPanel,"+ Need");
//addNeedButton->SetMaxSize(wxSize(-1,50));
optsInstructSizer->Add(addNeedButton,wxSizerFlags(1).Expand());
wxButton *removeNeedButton = new wxButton(mainPanel,"- Need");
//removeNeedButton->SetMaxSize(wxSize(-1,50));
optsInstructSizer->Add(removeNeedButton,wxSizerFlags(1).Expand());
wxButton *resetAllButton = new wxButton(mainPanel,"Reset All");
//resetAllButton->SetMaxSize(wxSize(-1,50));
optsInstructSizer->Add(resetAllButton,wxSizerFlags(1).Expand());
wxButton *calculateButton = new wxButton(mainPanel,"Calculate");
//calculateButton->SetMaxSize(wxSize(-1,50));
optsInstructSizer->Add(calculateButton,wxSizerFlags(1).Expand());
// b. NEEDS WRAP SIZER
// contains all the needs
wxBoxSizer *needsWrapSizer = new wxBoxSizer(wxVERTICAL);
optsSizer->Add(needsWrapSizer,wxSizerFlags(1).Expand());
// b1. a single need we can copy to make more needs
wxBoxSizer *needsItemSizer = new wxBoxSizer(wxVERTICAL);
needsWrapSizer->Add(needsItemSizer,wxSizerFlags(1).Expand());
// each need has 3 horrizontal components
// i. filters check area
// we'll do 3 columns of filters so 12 possible.
// this is
wxBoxSizer *needsItemFilteRSSizer = new wxBoxSizer(wxHORIZONTAL);
needsItemSizer->Add(needsItemFilteRSSizer,wxSizerFlags(1).Expand());
// 4 filters per column: col 1
wxBoxSizer *needsItemFiltersCol1Sizer = new wxBoxSizer(wxVERTICAL);
needsItemFilteRSSizer->Add(needsItemFiltersCol1Sizer,wxSizerFlags(1).Expand());
for ( int i = 0; i < 4; i++ )
{
wxCheckBox *filterCheck = new wxCheckBox(mainPanel,"filter " + wxString::Format(wxT("%d"),(int)(i + 1)));
filterCheck->SetBackgroundColour(*wxGREEN);
needsItemFiltersCol1Sizer->Add(filterCheck,wxSizerFlags(1).Expand());
}
// 4 filters per column: col 2
wxBoxSizer *needsItemFiltersCol2Sizer = new wxBoxSizer(wxVERTICAL);
needsItemFilteRSSizer->Add(needsItemFiltersCol2Sizer,wxSizerFlags(1).Expand());
for ( int i = 4; i < 8; i++ )
{
wxCheckBox *filterCheck = new wxCheckBox(mainPanel,(int)(i + 1)));
needsItemFiltersCol2Sizer->Add(filterCheck,wxSizerFlags(1).Expand());
}
// 4 filters per column: col 3
wxBoxSizer *needsItemFiltersCol3Sizer = new wxBoxSizer(wxVERTICAL);
needsItemFilteRSSizer->Add(needsItemFiltersCol3Sizer,wxSizerFlags(1).Expand());
for ( int i = 8; i < 12; i++ )
{
wxCheckBox *filterCheck = new wxCheckBox(mainPanel,(int)(i + 1)));
needsItemFiltersCol3Sizer->Add(filterCheck,wxSizerFlags(1).Expand());
}
// ii. build line (3 variations: land/land+fixing,specific card,and other
// should put in a ramp,but for Now just do "land"
wxBoxSizer *needsItemBuildLinesizer = new wxBoxSizer(wxHORIZONTAL);
needsItemSizer->Add(needsItemBuildLinesizer,wxSizerFlags(1).Expand());
// line item -> "("
wxButton *needsItemOpenBrackButton = new wxButton(mainPanel,"(");
needsItemBuildLinesizer->Add(needsItemOpenBrackButton,wxSizerFlags(1).Expand());
// line item -> cards to draw combo Box
wxComboBox *cardsToDrawCombo = new wxComboBox(mainPanel,wxID_ANY);
cardsToDrawCombo->Append("1 to Draw");
cardsToDrawCombo->Append("2 to Draw");
cardsToDrawCombo->Append("3 to Draw");
cardsToDrawCombo->Append("4 to Draw");
cardsToDrawCombo->Append("5 to Draw");
cardsToDrawCombo->Append("6 to Draw");
cardsToDrawCombo->Append("7 to Draw");
cardsToDrawCombo->Append("8 to Draw");
cardsToDrawCombo->Append("9 to Draw");
cardsToDrawCombo->Append("10 to Draw");
needsItemBuildLinesizer->Add(cardsToDrawCombo,wxSizerFlags(1).Expand());
// line item -> filters to apply (any/all)
wxComboBox *filtersApplyTypeCombo = new wxComboBox(mainPanel,wxID_ANY);
filtersApplyTypeCombo->Append("Any");
filtersApplyTypeCombo->Append("All");
needsItemBuildLinesizer->Add(filtersApplyTypeCombo,wxSizerFlags(1).Expand());
// line item -> cost colors combo
wxComboBox *filtersCostColorsCombo = new wxComboBox(mainPanel,wxID_ANY);
filtersCostColorsCombo->Append("Any");
filtersCostColorsCombo->Append("Black");
filtersCostColorsCombo->Append("Blue");
filtersCostColorsCombo->Append("Green");
filtersCostColorsCombo->Append("Red");
filtersCostColorsCombo->Append("White");
needsItemBuildLinesizer->Add(filtersCostColorsCombo,wxSizerFlags(1).Expand());
// line item -> cost amount combo
wxComboBox *filtersCostAmountCombo = new wxComboBox(mainPanel,wxID_ANY);
filtersCostAmountCombo->Append("<= 1");
filtersCostAmountCombo->Append("<= 2");
filtersCostAmountCombo->Append("<= 3");
filtersCostAmountCombo->Append("<= 4");
filtersCostAmountCombo->Append("<= 5");
filtersCostAmountCombo->Append("<= 6");
needsItemBuildLinesizer->Add(filtersCostAmountCombo,wxSizerFlags(1).Expand());
// line item -> ")"
wxButton *needsItemCloseBrackButton = new wxButton(mainPanel,")");
needsItemBuildLinesizer->Add(needsItemCloseBrackButton,wxSizerFlags(1).Expand());
// line item -> "AND"
wxButton *needsItemAndButton = new wxButton(mainPanel,"AND");
needsItemBuildLinesizer->Add(needsItemAndButton,wxSizerFlags(1).Expand());
// line item -> "OR"
wxButton *needsItemOrButton = new wxButton(mainPanel,"OR");
needsItemBuildLinesizer->Add(needsItemOrButton,wxSizerFlags(1).Expand());
// iii. line buttons (reset,+ row below,- this row
wxBoxSizer *needsItemButtonSizer = new wxBoxSizer(wxHORIZONTAL);
needsItemSizer->Add(needsItemButtonSizer,wxSizerFlags(1).Expand());
// buttons
wxButton *needsItemInlineAddButton = new wxButton(mainPanel,"+");
needsItemButtonSizer->Add(needsItemInlineAddButton,wxSizerFlags(1).Expand());
wxButton *needsItemInlineRemoveButton = new wxButton(mainPanel,"-");
needsItemButtonSizer->Add(needsItemInlineRemoveButton,wxSizerFlags(1).Expand());
wxButton *needsItemInlineResetButton = new wxButton(mainPanel,"R");
needsItemButtonSizer->Add(needsItemInlineResetButton,wxSizerFlags(1).Expand());
// b2. At the bottom of all needs is a
// test control that has the build string
wxBoxSizer *needsBuilddisplaySizer = new wxBoxSizer(wxVERTICAL);
needsWrapSizer->Add(needsBuilddisplaySizer,wxSizerFlags(1).Expand());
// outputSizer (horizontal)
wxStaticText *builddisplay = new wxStaticText(mainPanel,"Build display");
builddisplay->SetBackgroundColour(*wxBLUE);
needsBuilddisplaySizer->Add(builddisplay,wxSizerFlags(1).Expand());
// at the bottom of the main panel stretches the log output
wxBoxSizer *outputSizer = new wxBoxSizer(wxHORIZONTAL);
mainPanelSizer ->Add(outputSizer,wxSizerFlags(1).Expand());
// logoutput StaticText
logoutput = new wxStaticText(mainPanel,"Output Terminal");
logoutput->SetBackgroundColour(*wxRED);
outputSizer ->Add(logoutput,wxSizerFlags(1).Expand());
mainPanel->SetSizerAndFit(mainPanelSizer);
this->Fit();
感谢您的帮助。
解决方法
使用您发布的代码,我看不到gap2。取而代之的是,我看到的按钮被放大以填充整个空间。我猜您在创建图像后稍稍更改了代码。但是按钮的增大和gap2的起因相同。
您有optsSizer
,其中包含另外两个调整器optsInstructSizer
和needsWrapSizer
。这些大小调整器都按比例1添加到optsSizer
中。这意味着optsInstructSizer
和needsWrapSizer
的大小将被调整为相同的大小。由于needsWrapSizer
的内容要大得多,这意味着在生成图像的代码中将包含gap2。
要解决此问题,只需将optsInstructSizer
与optsSizer
的比例设为0,如下所示:
optsSizer->Add(optsInstructSizer,wxSizerFlags(0).Expand());
或者因为0是比例参数的默认值,所以您可以使用
optsSizer->Add(optsInstructSizer,wxSizerFlags().Expand());
(即使不必明确提醒我所添加的项目的比例为0,我也始终使用0。)将某项添加到比例为0的尺寸调整器中时,这意味着应该进行尺寸调整(通常以垂直尺寸调整器或水平尺寸调整器中的水平尺寸)调整为最小尺寸。
摆脱gap2时,出于类似原因,gap1被删除。您有progSizer
,其中包含handSizer
和optsSizer
。两者都添加了比例1,这意味着它们将具有相同的大小。删除gap2后,垂直尺寸optsSizer
会缩小,因为handSizer
的垂直尺寸相同,因此也会删除gap1。