原文: http://zetcode.com/gui/wxwidgets/layoutmanagement/

典型的应用由各种小部件组成。 这些小部件放置在容器小部件内。 程序员必须管理应用的布局。 这不是一件容易的事。

在 wxWidgets 中,我们有两个选择:

  • 绝对定位。
  • 大小调整器。

绝对定位

程序员以像素为单位指定每个小部件的位置和大小。 使用绝对定位时,我们必须了解以下几点:

  • 如果我们调整窗口大小,则小部件的大小和位置不会改变。
  • 在各种平台上,应用看起来有所不同(通常很差)。
  • 在我们的应用中更改字体可能会破坏布局。
  • 如果我们决定更改布局,则必须完全重做您的布局,这既繁琐又耗时。

在某些情况下,例如在简单的教程中,我们可能会使用绝对定位。 我们不想让示例太难,所以我们经常使用绝对定位来解释某个主题。 但是大多数情况下,在现实世界的程序中,程序员使用大小调整器。

在我们的示例中,我们有一个简单的文本编辑器框架。 如果我们调整窗口大小,则wxTextCtrl的大小不会像我们期望的那样改变。

absolute.h

  1. #include <wx/wx.h>
  2. #include <wx/menu.h>
  3. class Absolute : public wxFrame {
  4. public:
  5. Absolute(const wxString& title);
  6. wxMenuBar *menubar;
  7. wxMenu *file;
  8. wxMenu *edit;
  9. wxMenu *help;
  10. wxTextCtrl *textctrl;
  11. };

absolute.cpp

  1. #include "absolute.h"
  2. Absolute::Absolute(const wxString& title)
  3. : wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(350, 250)) {
  4. wxPanel *panel = new wxPanel(this, -1);
  5. menubar = new wxMenuBar;
  6. file = new wxMenu;
  7. edit = new wxMenu;
  8. help = new wxMenu;
  9. menubar->Append(file, wxT("&File"));
  10. menubar->Append(edit, wxT("&Edit"));
  11. menubar->Append(help, wxT("&Help"));
  12. SetMenuBar(menubar);
  13. textctrl = new wxTextCtrl(panel, -1, wxT(""), wxDefaultPosition,
  14. wxSize(250, 150), wxTE_MULTILINE);
  15. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp {
  3. public:
  4. virtual bool OnInit();
  5. };

main.cpp

  1. #include "main.h"
  2. #include "absolute.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit() {
  5. Absolute *absolute = new Absolute(wxT("Absolute"));
  6. absolute->Show(true);
  7. return true;
  8. }

本示例使用绝对定位。 我们将wxTextCtrl小部件放置在面板小部件上。

  1. textctrl = new wxTextCtrl(panel, -1, wxT(""), wxDefaultPosition,
  2. wxSize(250, 150), wxTE_MULTILINE);

我们在wxTextCtrl小部件的构造器中进行绝对定位。 在我们的情况下,我们为小部件提供默认位置。 宽度为 250 像素,高度为 150 像素。

wxWidgets 中的布局管理 - 图1

图:调整大小之前

wxWidgets 中的布局管理 - 图2

图:调整大小之后

调整窗口大小时,文本控件的大小不会更改。

使用大小调整器

wxWidgets 中的大小调整器确实解决了所有这些问题,我们通过绝对定位提到了这些问题。 我们可以在这些大小调整器中进行选择。

  • wxBoxSizer
  • wxStaticBoxSizer
  • wxGridSizer
  • wxFlexGridSizer
  • wxGridBagSizer

wxWidgets 中的布局管理 - 图3

图:调整大小之前

wxWidgets 中的布局管理 - 图4

图:调整大小之后

sizer.h

  1. #include <wx/wx.h>
  2. class Sizer : public wxFrame
  3. {
  4. public:
  5. Sizer(const wxString& title);
  6. wxMenuBar *menubar;
  7. wxMenu *file;
  8. wxMenu *edit;
  9. wxMenu *help;
  10. wxTextCtrl *textctrl;
  11. };

sizer.cpp

  1. #include "sizer.h"
  2. Sizer::Sizer(const wxString& title)
  3. : wxFrame(NULL, -1, title, wxPoint(-1, -1), wxSize(250, 180))
  4. {
  5. menubar = new wxMenuBar;
  6. file = new wxMenu;
  7. edit = new wxMenu;
  8. help = new wxMenu;
  9. menubar->Append(file, wxT("&File"));
  10. menubar->Append(edit, wxT("&Edit"));
  11. menubar->Append(help, wxT("&Help"));
  12. SetMenuBar(menubar);
  13. textctrl = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1),
  14. wxSize(250, 150));
  15. Centre();
  16. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "sizer.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. Sizer *sizer = new Sizer(wxT("Sizer"));
  7. sizer->Show(true);
  8. return true;
  9. }

wxTextCtrl放置在wxFrame小部件内。 wxFrame小部件具有特殊的内置大小调整器。 我们只能在wxFrame容器中放入一个小部件。 子窗口小部件占据了所有空间,边框,菜单,工具栏和状态栏未分配该空间。

wxBoxSizer

这个 sizer 使我们能够将几个小部件放在一行或一列中。 我们可以将另一个调整器放到现有的调整器中。 这样,我们可以创建非常复杂的布局。

  1. wxBoxSizer(int orient)
  2. wxSizerItem* Add(wxWindow* window, int proportion = 0, int flag = 0, int border = 0)

方向可以是wxVERTICALwxHORIZONTAL。 通过Add()方法将小部件添加到wxBoxSizer中。 为了理解它,我们需要查看它的参数。

比例参数定义控件在定义的方向上如何变化的比例。 假设我们有比例为 0、1 和 2 的树按钮。它们被添加到水平wxBoxSizer中。 比例为 0 的按钮完全不会改变。 在水平方向上比例为 2 的按钮的变化比比例为 1 的按钮大两倍。

使用flag参数,您可以进一步在wxBoxSizer中配置小部件的行为。 我们可以控制小部件之间的边界。 我们在小部件之间添加一些像素间距。 为了应用边框,我们需要定义要使用边框的边。 我们可以将它们与|运算符,例如wxLEFT | wxBOTTOM结合使用。 我们可以在这些标志之间进行选择:

  • wxLEFT
  • wxRIGHT
  • wxBOTTOM
  • wxTOP
  • wxALL

wxWidgets 中的布局管理 - 图5

图:面板周围的边框

border.h

  1. #include <wx/wx.h>
  2. class Border : public wxFrame
  3. {
  4. public:
  5. Border(const wxString& title);
  6. };

border.cpp

  1. #include "border.h"
  2. Border::Border(const wxString& title)
  3. : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 200))
  4. {
  5. wxColour col1, col2;
  6. col1.Set(wxT("#4f5049"));
  7. col2.Set(wxT("#ededed"));
  8. wxPanel *panel = new wxPanel(this, -1);
  9. panel->SetBackgroundColour(col1);
  10. wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
  11. wxPanel *midPan = new wxPanel(panel, wxID_ANY);
  12. midPan->SetBackgroundColour(col2);
  13. vbox->Add(midPan, 1, wxEXPAND | wxALL, 20);
  14. panel->SetSizer(vbox);
  15. Centre();
  16. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "border.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. Border *border = new Border(wxT("Border"));
  7. border->Show(true);
  8. return true;
  9. }

在此示例中,我们创建两个面板。 第二个面板周围有一些空间。

  1. vbox->Add(midPan, 1, wxEXPAND | wxALL, 20);

我们在midPan面板周围放置了 20 像素的边框。 wxALL标志将边框大小应用于所有四个侧面。 如果我们使用wxEXPAND标志,则该小部件将使用分配给它的所有空间。

最后,我们还可以定义小部件的对齐方式。 我们使用以下标志来实现:

  • wxALIGN_LEFT
  • wxALIGN_RIGHT
  • wxALIGN_TOP
  • wxALIGN_BOTTOM
  • wxALIGN_CENTER_VERTICAL
  • wxALIGN_CENTER_HORIZONTAL
  • wxALIGN_CENTER

假设我们要在窗口的右下方放置两个按钮。

align.h

  1. #include <wx/wx.h>
  2. class Align : public wxFrame
  3. {
  4. public:
  5. Align(const wxString& title);
  6. };

align.cpp

  1. #include "align.h"
  2. Align::Align(const wxString& title)
  3. : wxFrame(NULL, -1, title, wxPoint(-1, -1), wxSize(300, 200))
  4. {
  5. wxPanel *panel = new wxPanel(this, -1);
  6. wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
  7. wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL);
  8. wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL);
  9. wxButton *ok = new wxButton(panel, -1, wxT("Ok"));
  10. wxButton *cancel = new wxButton(panel, -1, wxT("Cancel"));
  11. hbox1->Add(new wxPanel(panel, -1));
  12. vbox->Add(hbox1, 1, wxEXPAND);
  13. hbox2->Add(ok);
  14. hbox2->Add(cancel);
  15. vbox->Add(hbox2, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 10);
  16. panel->SetSizer(vbox);
  17. Centre();
  18. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "align.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. Align *align = new Align(wxT("Align"));
  7. align->Show(true);
  8. return true;
  9. }

我们创建三个大小调整器。 一台垂直分级机和两台水平分级机。 我们将这两个水平大小调整器放到垂直大小调整器中。

  1. hbox1->Add(new wxPanel(panel, -1));
  2. vbox->Add(hbox1, 1, wxEXPAND);

我们将wxPanel放入第一个水平缩放器中。 我们将比例设置为1并设置一个wxEXPAND标志。 这样,大小调整器将占据hbox2以外的所有空间。

  1. vbox->Add(hbox2, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 10);

我们已将按钮放入hbox2大小调整器中。 hbox2右对齐,我们还在按钮的底部和右侧留了一些空间。

wxWidgets 中的布局管理 - 图6

图:对齐按钮

GotoClass

在下面的示例中,我们介绍了几个重要的想法。

gotoclass.h

  1. #include <wx/wx.h>
  2. class GotoClass : public wxFrame
  3. {
  4. public:
  5. GotoClass(const wxString& title);
  6. };

gotoclass.cpp

  1. #include "gotoclass.h"
  2. GotoClass::GotoClass(const wxString& title)
  3. : wxFrame(NULL, -1, title, wxPoint(-1, -1), wxSize(450, 400))
  4. {
  5. wxPanel *panel = new wxPanel(this, -1);
  6. wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
  7. wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL);
  8. wxStaticText *st1 = new wxStaticText(panel, wxID_ANY,
  9. wxT("Class Name"));
  10. hbox1->Add(st1, 0, wxRIGHT, 8);
  11. wxTextCtrl *tc = new wxTextCtrl(panel, wxID_ANY);
  12. hbox1->Add(tc, 1);
  13. vbox->Add(hbox1, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 10);
  14. vbox->Add(-1, 10);
  15. wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL);
  16. wxStaticText *st2 = new wxStaticText(panel, wxID_ANY,
  17. wxT("Matching Classes"));
  18. hbox2->Add(st2, 0);
  19. vbox->Add(hbox2, 0, wxLEFT | wxTOP, 10);
  20. vbox->Add(-1, 10);
  21. wxBoxSizer *hbox3 = new wxBoxSizer(wxHORIZONTAL);
  22. wxTextCtrl *tc2 = new wxTextCtrl(panel, wxID_ANY, wxT(""),
  23. wxPoint(-1, -1), wxSize(-1, -1), wxTE_MULTILINE);
  24. hbox3->Add(tc2, 1, wxEXPAND);
  25. vbox->Add(hbox3, 1, wxLEFT | wxRIGHT | wxEXPAND, 10);
  26. vbox->Add(-1, 25);
  27. wxBoxSizer *hbox4 = new wxBoxSizer(wxHORIZONTAL);
  28. wxCheckBox *cb1 = new wxCheckBox(panel, wxID_ANY,
  29. wxT("Case Sensitive"));
  30. hbox4->Add(cb1);
  31. wxCheckBox *cb2 = new wxCheckBox(panel, wxID_ANY,
  32. wxT("Nested Classes"));
  33. hbox4->Add(cb2, 0, wxLEFT, 10);
  34. wxCheckBox *cb3 = new wxCheckBox(panel, wxID_ANY,
  35. wxT("Non-Project Classes"));
  36. hbox4->Add(cb3, 0, wxLEFT, 10);
  37. vbox->Add(hbox4, 0, wxLEFT, 10);
  38. vbox->Add(-1, 25);
  39. wxBoxSizer *hbox5 = new wxBoxSizer(wxHORIZONTAL);
  40. wxButton *btn1 = new wxButton(panel, wxID_ANY, wxT("Ok"));
  41. hbox5->Add(btn1, 0);
  42. wxButton *btn2 = new wxButton(panel, wxID_ANY, wxT("Close"));
  43. hbox5->Add(btn2, 0, wxLEFT | wxBOTTOM , 5);
  44. vbox->Add(hbox5, 0, wxALIGN_RIGHT | wxRIGHT, 10);
  45. panel->SetSizer(vbox);
  46. Centre();
  47. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "gotoclass.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. GotoClass *gotoclass = new GotoClass(wxT("GotoClass"));
  7. gotoclass->Show(true);
  8. return true;
  9. }

这是使用wxBoxSizer的复杂示例。 布局僵硬。 我们创建一个垂直大小调整器。 然后,我们将五个水平大小调整器放入其中。

  1. vbox->Add(hbox3, 1, wxLEFT | wxRIGHT | wxEXPAND, 10);
  2. vbox->Add(-1, 25);

我们已经知道可以通过组合flag参数和border参数来控制小部件之间的距离。 但是有一个真正的约束。 在Add()方法中,我们只能为所有给定的边指定一个边框。 在我们的示例中,我们在右侧和左侧分别设置了 10 像素。 但是我们不能给底部 25 像素。 我们可以做的是在底部加上 10 像素或 0 像素。 如果我们省略wxBOTTOM。 因此,如果我们需要不同的值,则可以添加一些额外的空间。 使用Add()方法,我们也可以插入小部件和空间。

  1. vbox->Add(hbox5, 0, wxALIGN_RIGHT | wxRIGHT, 10);

我们将两个按钮放在窗口的右侧。 我们该怎么做呢? 实现这一点很重要的三件事:比例,对齐标志和wxEXPAND标志。 比例必须为零。 调整窗口大小时,按钮不应更改其大小。 我们一定不要指定wxEXPAND标志。 按钮仅占用已分配给它的区域。 最后,我们必须指定wxALIGN_RIGHT标志。 水平大小调整器从窗口的左侧扩展到右侧。 因此,如果我们指定wxALIGN_RIGHT标志,则按钮将放置在右侧。 正是我们想要的。

wxWidgets 中的布局管理 - 图7

图:GotoClass

wxGridSizer

wxGridSizer在二维表中布置小部件。 表格中的每个单元格都具有相同的大小。

  1. wxGridSizer(int rows, int cols, int vgap, int hgap)

在构造器中,我们指定表中的行数和列数。 以及我们细胞之间的垂直和水平空间。

在我们的示例中,我们创建了计算器的骨架。 这是wxGridSizer的完美示例。

gridsizer.h

  1. #include <wx/wx.h>
  2. class GridSizer : public wxFrame
  3. {
  4. public:
  5. GridSizer(const wxString& title);
  6. wxMenuBar *menubar;
  7. wxMenu *file;
  8. wxBoxSizer *sizer;
  9. wxGridSizer *gs;
  10. wxTextCtrl *display;
  11. };

gridsizer.cpp

  1. #include "gridsizer.h"
  2. GridSizer::GridSizer(const wxString& title)
  3. : wxFrame(NULL, -1, title, wxPoint(-1, -1), wxSize(270, 220))
  4. {
  5. menubar = new wxMenuBar;
  6. file = new wxMenu;
  7. SetMenuBar(menubar);
  8. sizer = new wxBoxSizer(wxVERTICAL);
  9. display = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1),
  10. wxSize(-1, -1), wxTE_RIGHT);
  11. sizer->Add(display, 0, wxEXPAND | wxTOP | wxBOTTOM, 4);
  12. gs = new wxGridSizer(4, 4, 3, 3);
  13. gs->Add(new wxButton(this, -1, wxT("Cls")), 0, wxEXPAND);
  14. gs->Add(new wxButton(this, -1, wxT("Bck")), 0, wxEXPAND);
  15. gs->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND);
  16. gs->Add(new wxButton(this, -1, wxT("Close")), 0, wxEXPAND);
  17. gs->Add(new wxButton(this, -1, wxT("7")), 0, wxEXPAND);
  18. gs->Add(new wxButton(this, -1, wxT("8")), 0, wxEXPAND);
  19. gs->Add(new wxButton(this, -1, wxT("9")), 0, wxEXPAND);
  20. gs->Add(new wxButton(this, -1, wxT("/")), 0, wxEXPAND);
  21. gs->Add(new wxButton(this, -1, wxT("4")), 0, wxEXPAND);
  22. gs->Add(new wxButton(this, -1, wxT("5")), 0, wxEXPAND);
  23. gs->Add(new wxButton(this, -1, wxT("6")), 0, wxEXPAND);
  24. gs->Add(new wxButton(this, -1, wxT("*")), 0, wxEXPAND);
  25. gs->Add(new wxButton(this, -1, wxT("1")), 0, wxEXPAND);
  26. gs->Add(new wxButton(this, -1, wxT("2")), 0, wxEXPAND);
  27. gs->Add(new wxButton(this, -1, wxT("3")), 0, wxEXPAND);
  28. gs->Add(new wxButton(this, -1, wxT("-")), 0, wxEXPAND);
  29. gs->Add(new wxButton(this, -1, wxT("0")), 0, wxEXPAND);
  30. gs->Add(new wxButton(this, -1, wxT(".")), 0, wxEXPAND);
  31. gs->Add(new wxButton(this, -1, wxT("=")), 0, wxEXPAND);
  32. gs->Add(new wxButton(this, -1, wxT("+")), 0, wxEXPAND);
  33. sizer->Add(gs, 1, wxEXPAND);
  34. SetSizer(sizer);
  35. SetMinSize(wxSize(270, 220));
  36. Centre();
  37. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "gridsizer.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. GridSizer *gs = new GridSizer(wxT("GridSizer"));
  7. gs->Show(true);
  8. return true;
  9. }

在我们的示例中,我们为wxFrame设置了垂直大小调整器。 我们将静态文本和网格大小调整器放入垂直大小调整器中。

注意我们如何在BckClose按钮之间放置空格。 我们只是在其中放一个空的wxStaticText

  1. gs->Add(new wxButton(this, -1, wxT("Cls")), 0, wxEXPAND);

我们多次调用Add()方法。 将小部件按顺序放置在表中,然后将它们添加。 第一行先填充,然后第二行等。

wxWidgets 中的布局管理 - 图8

图:GridSizer

wxFlexGridSizer

该大小调整器类似于wxGridSizer。 它还确实将其小部件布置在二维表中。 它增加了一些灵活性。 wxGridSizer细胞大小相同。 wxFlexGridSizer中的所有单元格都具有相同的高度。 一列中所有单元格的宽度均相同。 但是,所有行和列不一定都具有相同的高度或宽度。

  1. wxFlexGridSizer(int rows, int cols, int vgap, int hgap)

rowscols指定大小调整器中的行数和列数。 vgaphgap在两个方向的小部件之间添加了一些空间。

很多时候,开发者必须开发用于数据输入和修改的对话框。 我发现wxFlexGridSizer适用于此类任务。 开发者可以使用此大小调整器轻松设置对话框窗口。 也可以使用wxGridSizer完成此操作,但由于每个单元格的大小相同,因此看起来不太好。

flexgridsizer.h

  1. #include <wx/wx.h>
  2. class FlexGridSizer : public wxFrame
  3. {
  4. public:
  5. FlexGridSizer(const wxString& title);
  6. };

flexgridsizer.cpp

  1. #include "flexgridsizer.h"
  2. FlexGridSizer::FlexGridSizer(const wxString& title)
  3. : wxFrame(NULL, -1, title, wxPoint(-1, -1), wxSize(270, 220))
  4. {
  5. wxPanel *panel = new wxPanel(this, -1);
  6. wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
  7. wxFlexGridSizer *fgs = new wxFlexGridSizer(3, 2, 9, 25);
  8. wxStaticText *thetitle = new wxStaticText(panel, -1, wxT("Title"));
  9. wxStaticText *author = new wxStaticText(panel, -1, wxT("Author"));
  10. wxStaticText *review = new wxStaticText(panel, -1, wxT("Review"));
  11. wxTextCtrl *tc1 = new wxTextCtrl(panel, -1);
  12. wxTextCtrl *tc2 = new wxTextCtrl(panel, -1);
  13. wxTextCtrl *tc3 = new wxTextCtrl(panel, -1, wxT(""),
  14. wxPoint(-1, -1), wxSize(-1, -1), wxTE_MULTILINE);
  15. fgs->Add(thetitle);
  16. fgs->Add(tc1, 1, wxEXPAND);
  17. fgs->Add(author);
  18. fgs->Add(tc2, 1, wxEXPAND);
  19. fgs->Add(review, 1, wxEXPAND);
  20. fgs->Add(tc3, 1, wxEXPAND);
  21. fgs->AddGrowableRow(2, 1);
  22. fgs->AddGrowableCol(1, 1);
  23. hbox->Add(fgs, 1, wxALL | wxEXPAND, 15);
  24. panel->SetSizer(hbox);
  25. Centre();
  26. }

main.h

  1. #include <wx/wx.h>
  2. class MyApp : public wxApp
  3. {
  4. public:
  5. virtual bool OnInit();
  6. };

main.cpp

  1. #include "main.h"
  2. #include "flexgridsizer.h"
  3. IMPLEMENT_APP(MyApp)
  4. bool MyApp::OnInit()
  5. {
  6. FlexGridSizer *fgs = new FlexGridSizer(wxT("FlexGridSizer"));
  7. fgs->Show(true);
  8. return true;
  9. }

在我们的示例中,我们创建一个简单的对话框。 它可以用于将数据插入数据库。

  1. wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
  2. ...
  3. hbox->Add(fgs, 1, wxALL | wxEXPAND, 15);

我们创建一个水平框大小调整器,以便在小部件表周围放置一些空间(15 像素)。

  1. fgs->Add(thetitle);

完全与GridSizer一样,将小部件添加到大小调整器中。

  1. fgs->AddGrowableRow(2, 1);
  2. fgs->AddGrowableCol(1, 1);

我们使第三行和第二列可增长。 这样,当调整窗口大小时,我们使文本控件变大。 前两个文本控件将在水平方向上增长,第三个文本控件将在两个方向上增长。 我们一定不要忘记使小部件可扩展(wxEXPAND)以使其真正起作用。

wxWidgets 中的布局管理 - 图9

图:FlexGridSizer

wxWidgets 教程的这一部分专门用于布局管理。