C ++ wxWidgets大小调整器中的巨大差距初学者

问题描述

我正在使用水平和垂直Boxsizer来构建我的GUI,到目前为止,我已经成功地完成了所有工作,只需在每个sizer上使用expand将所有内容添加到sizer中,然后调整diff元素的最小或最大宽度/高度以得到什么我想要。不过我遇到了一个奇怪的问题。

我不明白我GUI的内容有2个空白。这是一张图片

enter image description here

差距#1

我不了解差距#1,因为它似乎是不必要的。整个GUI以带有2个元素的垂直装箱器开始。红色的StaticText上方的所有内容都位于顶部,红色的StaticText包含在第二个元素中。

在最上面的子大小调整器中,所需的最大高度是TextCtrls的“ Castables”和“ Lands”列。这导致我进入奇怪的缺口#2 ...

差距#2

直到我为它上面的4个按钮设置了最大高度,这个间隙才出现。我在油漆上绘制了紫色轮廓,以便您可以看到尺寸调整器如何配合在一起(或者应该如何配合在一起,除非我弄错了)。间隙是在垂直尺寸调整器的开头,然后包含其他尺寸调整器...在设置这四个按钮的最大高度之前,这四个按钮的高度正好填充了该间隙区域。当我为它们设置最大高度时,我希望下面的所有内容向上滑动而不是向下滑动。

这是构建整个GUI的构造函数中的所有代码

// 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,其中包含另外两个调整器optsInstructSizerneedsWrapSizer。这些大小调整器都按比例1添加到optsSizer中。这意味着optsInstructSizerneedsWrapSizer的大小将被调整为相同的大小。由于needsWrapSizer的内容要大得多,这意味着在生成图像的代码中将包含gap2。

要解决此问题,只需将optsInstructSizeroptsSizer的比例设为0,如下所示:

optsSizer->Add(optsInstructSizer,wxSizerFlags(0).Expand());

或者因为0是比例参数的默认值,所以您可以使用

optsSizer->Add(optsInstructSizer,wxSizerFlags().Expand());

(即使不必明确提醒我所添加的项目的比例为0,我也始终使用0。)将某项添加到比例为0的尺寸调整器中时,这意味着应该进行尺寸调整(通常以垂直尺寸调整器或水平尺寸调整器中的水平尺寸)调整为最小尺寸。


摆脱gap2时,出于类似原因,gap1被删除。您有progSizer,其中包含handSizeroptsSizer。两者都添加了比例1,这意味着它们将具有相同的大小。删除gap2后,垂直尺寸optsSizer会缩小,因为handSizer的垂直尺寸相同,因此也会删除gap1。