c++ - 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 初始化)会改变结果?
解决方案
来自wx 文档:
A
frame
是一个窗口,其大小和位置(通常)可以由用户更改。
它通常有粗边框和标题栏,并且可以选择包含菜单栏、工具栏和状态栏。A
panel
是放置控件的窗口。
它通常放置在一个框架内。其父类 wxWindow 的主要特性是处理子窗口和 TAB 遍历的代码。
wxWindow
是任何类型的窗口使用的泛型类。wxDialog
主要用作用户输入数据的表单。
通常应用程序会显示一个框架作为应用程序的主窗口。
==> 虽然您可以将控件直接放置在 wxFrame 中,但由于“TAB 遍历”和操作系统的典型背景功能,您最好使用 wxPanel。
此面板是主 wxFrame 的子面板,您可以在 wxFrame 的 ctor 处构建它。因为在 wxWidgets 中,如果一个 wxFrame 有一个唯一的子级,那么这个子级将被扩展以适应 wxFrame 的整个客户端大小,那么您就不要使用 wxsizers 来进行面板到框架的匹配。
当您创建控件时(例如在 wxPanel ctor 处),您将此wxPanel 设置为控件的父级。并使用 sizers 将它们布局到面板中。
所以每个控件都有你的面板作为父级;您的面板将框架作为父级。不要忘记“this”指针可以用作父级,或者将父级作为参数传递给创建窗口(面板、控件)的函数。
最后,指向任何 wxWindow 派生类的指针都是用“new”创建的,但您不需要删除它们,wxWigets 内部会处理它们的删除。
推荐阅读
- python - 光学字符识别多行检测
- onedrive - 共享链接的 OneDrive API 过期
- javascript - 如何在 React Native 中进行搜索?
- batch-file - 使用 wmic 仅查找以太网 MAC 地址
- scala - 如何在apache spark中对两个数据集进行基于时间的连接?
- java - 链式规划实体中的 CustomChangeMove 引发 IllegalStateException (Optaplanner)
- c++ - Qt 样式表的用途是什么以及它们是如何工作的?
- r - 无法在 WRDS Interactive R 会话中安装 R 包
- java - java,如果超类使用try/catch,为什么扩展类不能用方法定义中的抛出和检查异常覆盖超类方法
- mysql - 如何在vs17中使用mysql在剃须刀中显示下拉列表