首页 > 解决方案 > wxPanel 和 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,它就不起作用。

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

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 初始化)会改变结果?

标签: c++wxwidgets

解决方案


来自wx 文档

Aframe是一个窗口,其大小和位置(通常)可以由用户更改。
它通常有粗边框和标题栏,并且可以选择包含菜单栏、工具栏和状态栏。

Apanel是放置控件的窗口。
它通常放置在一个框架内。其父类 wxWindow 的主要特性是处理子窗口和 TAB 遍历的代码。

wxWindow是任何类型的窗口使用的泛型类。wxDialog主要用作用户输入数据的表单。

通常应用程序会显示一个框架作为应用程序的主窗口。

==> 虽然您可以将控件直接放置在 wxFrame 中,但由于“TAB 遍历”和操作系统的典型背景功能,您最好使用 wxPanel。

此面板是主 wxFrame 的子面板,您可以在 wxFrame 的 ctor 处构建它。因为在 wxWidgets 中,如果一个 wxFrame 有一个唯一的子级,那么这个子级将被扩展以适应 wxFrame 的整个客户端大小,那么您就不要使用 wxsizers 来进行面板到框架的匹配。

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

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

最后,指向任何 wxWindow 派生类的指针都是用“new”创建的,但您不需要删除它们,wxWigets 内部会处理它们的删除。


推荐阅读