C ++ wxWidgets Sizer问题初学者

问题描述

我是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);

这是它的样子:

enter image description here

我想用蓝色的StaticText填充整个大小,因此它占据了窗口的右1/3,在垂直和水平方向上都拉伸。此外,每个TextCtrl都已垂直拉伸以填充其大小调整器,但没有水平拉伸。调整帧大小时,我不需要任何未使用的空间,因此每个textctrl都在垂直和水平方向上扩展。我在做什么错了?

谢谢

解决方法

@GeoffL,

首先-仅blue Static TextRed

第二个-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);

产生此输出。

enter image description here

这是一个开始,但它将所有内容捆绑在一起而没有分隔。要在项目之间添加一些分隔,可以将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);

这将产生如下布局:

enter image description here

有许多种方法可以重新排列“边框”选项以防止出现双边框,而上面的示例只是一种可能性。

最后,使用面板将框架中的所有项目分组通常是一个好主意。它提供了更好看的背景,并允许您使用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();

这将产生以下布局:

enter image description here

无需在面板上使用大小调整器,因为当框架只有一个孩子时,该孩子会自动展开以填充框架的所有空间。