Взаимодействие между wxPanel и wxFrame - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь понять, как 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, только если они определены в области действия функции. Если я определю wxPanel в области видимости конструктора производного класса wxFrame, он не будет работать.

Например, при этом не будет сгенерирована форма, как предполагалось:

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) может изменить результат?

1 Ответ

2 голосов
/ 25 апреля 2020

Из wx документов :

A frame - это окно, размер и положение которого (обычно) могут быть изменены пользователем.
Обычно он имеет толстые границы и строку заголовка и может дополнительно содержать строку меню, панель инструментов и строку состояния.

A panel - это окно, в которое помещаются элементы управления.
Обычно он помещается в рамку. Его основной особенностью по сравнению с родительским классом wxWindow является код для обработки дочернего windows и обхода TAB.

wxWindow - это обобщенный c класс, используемый в любом типе окон. wxDialog в основном используется как форма, в которую пользователь вводит данные.

Обычно приложение отображает фрейм в качестве основного окна приложения.

==> Хотя вы можете размещать элементы управления напрямую в wxFrame из-за 'TAB traversal' и типичных фоновых функций операционной системы вам лучше использовать wxPanel.

Эта панель является дочерней по отношению к основному wxFrame , и вы можете создать ее на wxFrame's т е р. Поскольку в wxWidgets, если у wxFrame есть уникальный дочерний элемент, этот дочерний элемент расширяется, чтобы соответствовать всему клиентскому размеру wxFrame, тогда вы не используете wxsizers для этой подгонки панели к кадру.

При создании элементы управления (например, в wxPanel ctor) вы устанавливаете этот wxPanel как родительский элемент управления . И используйте sizer для размещения их на панели.

Таким образом, каждый элемент управления имеет вашу панель в качестве родителя; Ваша панель имеет рамку в качестве родителя. Не забывайте, что указатели «this» могут использоваться в качестве родителей или передавать родительский элемент в качестве параметра в функции, которая создает windows (панель, элементы управления).

Наконец, указатели на любое wxWindow -приобретенный класс создается с "новым", но вам не нужно удалять его, внутреннее устройство wxWigets позаботится об их удалении.

...