问题描述
我是wxWidgets和sizer的新手。我已经在框架构造器中创建了以下结构
wxBoxSizer *frameSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *deckListLeftSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *deckListRightSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *logoutputSizer = new wxBoxSizer(wxVERTICAL);
// 10 inputs on left
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(this,-1,wxT(""),wxPoint(-1,-1),wxSize(-1,-1));
deckInputCastables.push_back(textCtrl);
deckListLeftSizer->Add(textCtrl,wxEXPAND );
}
// 10 inputs on right
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(this,-1));
deckInputLands.push_back(textCtrl);
deckListRightSizer->Add(textCtrl,wxEXPAND );
}
logoutput = new wxStaticText(this,wxID_ANY,"Output Terminal",-1));
logoutput->SetBackgroundColour(*wxRED);
logoutputSizer->Add(logoutput);
frameSizer->Add(deckListLeftSizer,1,wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND,5);
frameSizer->Add(deckListRightSizer,5);
frameSizer->Add(logoutputSizer,5);
frameSizer->Fit(this);
SetSizer(frameSizer);
这是它的样子:
我想用蓝色的StaticText填充整个大小,因此它占据了窗口的右1/3,在垂直和水平方向上都拉伸。此外,每个TextCtrl都已垂直拉伸以填充其大小调整器,但没有水平拉伸。调整帧大小时,我不需要任何未使用的空间,因此每个textctrl都在垂直和水平方向上扩展。我在做什么错了?
谢谢
解决方法
@GeoffL,
首先-仅blue Static Text
个Red
。
第二个-wxALIGN_ *选项只能看到主要方向,即传递给wxBoxSizer()构造函数的那个方向。
您可能想要的是(未经测试的):
logOutput = new wxStaticText(this,wxID_ANY,"Output Terminal",wxPoint(-1,-1),wxSize(-1,-1));
logOutput->SetBackgroundColour(*wxRED);
logOutputSizer->Add(logOutput,wxEXPAND | wxALIGN_CENTER_VERTICAL,0 );
wxEXPAND | wxALIGN_CENTER_VERTICAL将扩展大小调整器并将控件垂直居中。
您还到处都省略了wxALL选项,因为它与现有的wxALIGN选项一起使用并没有用。
您还可以在控件构造函数中省略wxPoint()和wxSize()参数,因为(-1,-1)是默认值
,除了以上Igor所说的之外,我还要补充两点。首先,我将wxSizerFlags添加到尺寸调整器中时使用。我认为这确实有助于弄清用于添加项目的所有数字和选项在做什么。其次,通常只有一个项(例如logOutputSizer
)的上胶机没有任何作用。我会摆脱它。
请牢记这两点,要回答您的问题,有必要对sizer标志使用比例参数和Expand
方法,以获取所需的布局。例如:
wxBoxSizer *frameSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *deckListLeftSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *deckListRightSizer = new wxBoxSizer(wxVERTICAL);
// 10 inputs on left
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(this,wxEmptyString);
deckInputCastables.push_back(textCtrl);
deckListLeftSizer->Add(textCtrl,wxSizerFlags(1).Expand());
}
// 10 inputs on right
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(this,wxEmptyString);
deckInputLands.push_back(textCtrl);
deckListRightSizer->Add(textCtrl,wxSizerFlags(1).Expand());
}
logOutput = new wxStaticText(this,"Output Terminal");
logOutput->SetBackgroundColour(*wxRED);
frameSizer->Add(deckListLeftSizer,wxSizerFlags(1).Expand());
frameSizer->Add(deckListRightSizer,wxSizerFlags(1).Expand());
frameSizer->Add(logOutput,wxSizerFlags(1).Expand());
frameSizer->Fit(this);
SetSizer(frameSizer);
产生此输出。
这是一个开始,但它将所有内容捆绑在一起而没有分隔。要在项目之间添加一些分隔,可以将Border方法用于sizer标志。但是,如果仅使用wxALL
为每个项目添加所有边框,则会得到多个双边框。例如,如果一个项目同时具有底部边框,而其下方的项目同时具有顶部边框,则项目之间将有一个双边框。考虑到这一点,以下代码将在每个项目周围放置一个边框:
wxBoxSizer *frameSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *deckListLeftSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *deckListRightSizer = new wxBoxSizer(wxVERTICAL);
// 10 inputs on left
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(this,wxSizerFlags(1).Expand().Border(wxBOTTOM));
}
// 10 inputs on right
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(this,wxSizerFlags(1).Expand().Border(wxBOTTOM));
}
logOutput = new wxStaticText(this,wxSizerFlags(1).Expand().Border(wxTOP|wxLEFT|wxRIGHT));
frameSizer->Add(deckListRightSizer,wxSizerFlags(1).Expand().Border(wxTOP|wxRIGHT));
frameSizer->Add(logOutput,wxSizerFlags(1).Expand().Border(wxTOP|wxBOTTOM|wxRIGHT));
frameSizer->Fit(this);
SetSizer(frameSizer);
这将产生如下布局:
有许多种方法可以重新排列“边框”选项以防止出现双边框,而上面的示例只是一种可能性。
最后,使用面板将框架中的所有项目分组通常是一个好主意。它提供了更好看的背景,并允许您使用Tab键在控件之间切换。这是展示此想法的最终示例:
wxPanel* panel = new wxPanel(this,wxID_ANY);
wxBoxSizer *panelSizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *deckListLeftSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *deckListRightSizer = new wxBoxSizer(wxVERTICAL);
// 10 inputs on left
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(panel,wxSizerFlags(1).Expand().Border(wxBOTTOM));
}
// 10 inputs on right
for ( int i = 0; i < 10; i++ )
{
wxTextCtrl *textCtrl = new wxTextCtrl(panel,wxSizerFlags(1).Expand().Border(wxBOTTOM));
}
logOutput = new wxStaticText(panel,"Output Terminal");
logOutput->SetBackgroundColour(*wxRED);
panelSizer->Add(deckListLeftSizer,wxSizerFlags(1).Expand().Border(wxTOP|wxLEFT|wxRIGHT));
panelSizer->Add(deckListRightSizer,wxSizerFlags(1).Expand().Border(wxTOP|wxRIGHT));
panelSizer->Add(logOutput,wxSizerFlags(1).Expand().Border(wxTOP|wxBOTTOM|wxRIGHT));
panel->SetSizerAndFit(panelSizer);
this->Fit();
这将产生以下布局:
无需在面板上使用大小调整器,因为当框架只有一个孩子时,该孩子会自动展开以填充框架的所有空间。