wxPanel 和 wxFrame 的交互

Interaction between wxPanel and wxFrame

我想了解 wxFrame 和 wxPanel 是如何协同工作的。我很难解释以下代码行为:

我正在尝试为我的应用程序设置 GUI。我有一个创建数据输入表单的函数:

void MyFrame::Initialize_Project_Info() {


//Info_Panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(600, 1000), wxTAB_TRAVERSAL, _T(""));

//Info_Panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T(""));

Info_Box = new wxBoxSizer(wxHORIZONTAL);
Info_Staticbox = new wxStaticBoxSizer(wxHORIZONTAL, Info_Panel, _T("Project Information"));
Info_Grid = new wxFlexGridSizer(4, 2, 0, 0);


//Note wsSize(width,height).
Project_Name = new wxStaticText(Info_Panel, wxID_ANY, _T("Project:"));
Engineer_Name = new wxStaticText(Info_Panel, wxID_ANY, _T("Engineer:"));
CrossSection_Name = new wxStaticText(Info_Panel, wxID_ANY, _T("Cross Section ID:"));
Additional_Notes = new wxStaticText(Info_Panel, wxID_ANY, _T("Additional Notes:"));


Enter_PN = new wxTextCtrl(Info_Panel, ENTER_PN, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB, wxDefaultValidator, _T(""));
Enter_EN = new wxTextCtrl(Info_Panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB, wxDefaultValidator, _T(""));
Enter_CSN = new wxTextCtrl(Info_Panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB, wxDefaultValidator, _T(""));
Enter_AN = new wxTextCtrl(Info_Panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, 100), wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxTE_MULTILINE, wxDefaultValidator, _T(""));

Info_Grid->Add(Project_Name,
    wxSizerFlags().Align(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL)
    .Border(wxTOP | wxBOTTOM | wxLEFT));
Info_Grid->Add(Enter_PN, wxSizerFlags().Expand().Border(wxALL));
Info_Grid->Add(Engineer_Name,
    wxSizerFlags().Align(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL)
    .Border(wxBOTTOM | wxLEFT));
Info_Grid->Add(Enter_EN, wxSizerFlags().Expand().Border(wxBOTTOM | wxLEFT | wxRIGHT));
Info_Grid->Add(CrossSection_Name,
    wxSizerFlags().Align(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL)
    .Border(wxBOTTOM | wxLEFT));
Info_Grid->Add(Enter_CSN,
    wxSizerFlags().Expand().Border(wxBOTTOM | wxLEFT | wxRIGHT));
Info_Grid->Add(Additional_Notes,
    wxSizerFlags().Align(wxALIGN_LEFT).Border(wxBOTTOM | wxLEFT));
Info_Grid->Add(Enter_AN, wxSizerFlags().Expand().Border(wxBOTTOM | wxLEFT | wxRIGHT));

Info_Staticbox->Add(Info_Grid);
Info_Box->Add(Info_Staticbox, wxSizerFlags().Border(wxALL));
Info_Panel->SetSizer(Info_Box);

}

如果我仅在函数范围内定义时将所有对象附加到 wxPanel,则此代码有效。如果我在 wxFrame 派生的构造函数范围内定义 wxPanel class,它不起作用。

例如,这样做不会按预期生成表单:

MyFrame::MyFrame() : wxFrame(NULL,wxID_ANY,"Cross Sectional Beam Properties",wxDefaultPosition,wxSize(1200,600),wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER | wxMAXIMIZE_BOX)) {


Info_Panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T(""));


Initialize_Project_Info();

}

所以,我的问题是 wxPanel 如何与 wxFrame 交互。为什么一个移动一行代码(即wxPanel初始化)会改变结果?

来自wx docs

A frame is a window whose size and position can (usually) be changed by the user.
It usually has thick borders and a title bar, and can optionally contain a menu bar, toolbar and status bar.

A panel is a window on which controls are placed.
It is usually placed within a frame. Its main feature over its parent class wxWindow is code for handling child windows and TAB traversal.

wxWindow 是任何类型的 window 所使用的通用 class。 wxDialog主要用作用户输入数据的表单。

通常一个应用程序显示一个框架作为应用程序的主要 window。

==> 虽然您可以将控件直接放置在 wxFrame 中,但由于 'TAB traversal' 和 OS 的典型背景功能,您最好使用 wxPanel。

此面板是主 wxFrame 的 child,您可以在 wxFrame 的 ctor 中构建它。 因为在 wxWidgets 中,如果 wxFrame 有一个唯一的 child,那么这个 child 会被扩展以适应 wxFrame 的整个客户端大小,那么你就不会为这个 panel-to-frame 拟合使用 wxsizers。

当您创建控件时(例如,在 wxPanel ctor 中),您将此 wxPanel 设置为控件 parent 的 。并使用 sizer 将它们布局到面板中。

所以每个控件都有你的面板parent;您的面板的框架为 parent。不要忘记 'this' 指针可以用作 parent,或者将 parent 作为参数传递给创建 windows(面板、控件)的函数。

最后,指向任何 wxWindow-derived class 的指针是用 "new" 创建的,但你不需要删除它们,wxWigets 内部会处理它们的删除。