How to Read Data From Grid Cells in Wxwidgets
Layout management in wxWidgets
terminal modified January half dozen, 2022
A typical awarding consists of diverse widgets. Those widgets are placed inside container widgets. A developer must manage the layout of the application. This is non an easy task.
In wxWidgets we have 2 options:
- Accented positioning.
- Sizers.
Absolute Positioning
The programmer specifies the position and the size of each widget in pixels. When nosotros use absolute positioning, we have to understand several things:
- The size and the position of a widget exercise not change if we resize a window.
- Applications expect different (frequently poorly) on various platforms.
- Changing fonts in our awarding might spoil the layout.
- If we decide to change our layout, we must completely redo your layout, which is tedious and time consuming.
There might be situations, where we tin possibly use absolute positioning, for case, in simple tutorials. Nosotros do not want to brand the examples too difficult, so we often use absolute positioning to explain a certain topic. But mostly, in real world programs, programmers use sizers.
In our instance we have a simple skeleton of a text editor. If we resize the window, the size of out wxTextCtrl does not change as we would look.
absolute.h
#include <wx/wx.h> #include <wx/carte du jour.h> class Accented : public wxFrame { public: Accented(const wxString& championship); wxMenuBar *menubar; wxMenu *file; wxMenu *edit; wxMenu *assistance; wxTextCtrl *textctrl; }; accented.cpp
#include "absolute.h" Absolute::Absolute(const wxString& title) : wxFrame(NULL, -1, title, wxDefaultPosition, wxSize(350, 250)) { wxPanel *console = new wxPanel(this, -1); menubar = new wxMenuBar; file = new wxMenu; edit = new wxMenu; help = new wxMenu; menubar->Append(file, wxT("&File")); menubar->Append(edit, wxT("&Edit")); menubar->Suspend(help, wxT("&Aid")); SetMenuBar(menubar); textctrl = new wxTextCtrl(panel, -i, wxT(""), wxDefaultPosition, wxSize(250, 150), wxTE_MULTILINE); } principal.h
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; primary.cpp
#include "main.h" #include "absolute.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Accented *accented = new Absolute(wxT("Absolute")); absolute->Show(true); return truthful; } This instance uses absolute positioning. Nosotros position a wxTextCtrl widget on a panel widget.
textctrl = new wxTextCtrl(panel, -i, wxT(""), wxDefaultPosition, wxSize(250, 150), wxTE_MULTILINE); We do the accented positioning in the constructor of the wxTextCtrl widget. In our case, we provide the default position for the widget. The width is 250px and the pinnacle 150px.
The size of the text command does not modify when the window is resized.
Using sizers
Sizers in wxWidgets do address all those issues, we mentioned by absolute positioning. We tin choose amongst these sizers.
-
wxBoxSizer -
wxStaticBoxSizer -
wxGridSizer -
wxFlexGridSizer -
wxGridBagSizer
sizer.h
#include <wx/wx.h> grade Sizer : public wxFrame { public: Sizer(const wxString& championship); wxMenuBar *menubar; wxMenu *file; wxMenu *edit; wxMenu *assist; wxTextCtrl *textctrl; }; sizer.cpp
#include "sizer.h" Sizer::Sizer(const wxString& championship) : wxFrame(NULL, -1, title, wxPoint(-one, -1), wxSize(250, 180)) { menubar = new wxMenuBar; file = new wxMenu; edit = new wxMenu; help = new wxMenu; menubar->Suspend(file, wxT("&File")); menubar->Suspend(edit, wxT("&Edit")); menubar->Append(help, wxT("&Assistance")); SetMenuBar(menubar); textctrl = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1), wxSize(250, 150)); Heart(); } main.h
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; principal.cpp
#include "main.h" #include "sizer.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Sizer *sizer = new Sizer(wxT("Sizer")); sizer->Show(truthful); return true; } The wxTextCtrl is placed inside the wxFrame widget. The wxFrame widget has a special built-in sizer. Nosotros can put merely one widget inside the wxFrame container. The child widget occupies all the infinite, which is not given to the borders, carte du jour, toolbar, and the statusbar.
wxBoxSizer
This sizer enables us to put several widgets into a row or a column. We can put another sizer into an existing sizer. This fashion we can create very circuitous layouts.
wxBoxSizer(int orient) wxSizerItem* Add(wxWindow* window, int proportion = 0, int flag = 0, int border = 0)
The orientation tin exist wxVERTICAL or wxHORIZONTAL. Calculation widgets into the wxBoxSizer is washed via the Add method. In lodge to understand it, we need to look at its parameters.
The proportion parameter defines the ratio of how volition the widgets change in the defined orientation. Let's assume we have tree buttons with the proportions 0, 1, and two. They are added into a horizontal wxBoxSizer. Button with proportion 0 will not change at all. Button with proportion 2 will change twice more than the 1 with proportion 1 in the horizontal dimension.
With the flag parameter y'all can further configure the behaviour of the widgets within a wxBoxSizer. We can command the border betwixt the widgets. We add together some space between widgets in pixels. In order to utilise edge we need to define sides, where the edge will be used. We can combine them with the | operator, east.k wxLEFT | wxBOTTOM. Nosotros can choose between these flags:
-
wxLEFT -
wxRIGHT -
wxBOTTOM -
wxTOP -
wxALL
border.h
#include <wx/wx.h> class Border : public wxFrame { public: Border(const wxString& title); }; border.cpp
#include "border.h" Border::Border(const wxString& championship) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 200)) { wxColour col1, col2; col1.Set(wxT("#4f5049")); col2.Set(wxT("#ededed")); wxPanel *panel = new wxPanel(this, -ane); panel->SetBackgroundColour(col1); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxPanel *midPan = new wxPanel(panel, wxID_ANY); midPan->SetBackgroundColour(col2); vbox->Add(midPan, 1, wxEXPAND | wxALL, 20); console->SetSizer(vbox); Heart(); } chief.h
#include <wx/wx.h> course MyApp : public wxApp { public: virtual bool OnInit(); }; main.cpp
#include "main.h" #include "border.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Border *border = new Border(wxT("Edge")); edge->Show(true); render truthful; } In this case, nosotros create two panels. The second panel has some space around itself.
vbox->Add together(midPan, i, wxEXPAND | wxALL, 20);
We take placed a xx px border around a midPan panel. The wxALL flag applies the edge size to all 4 sides. If nosotros employ wxEXPAND flag, the widget will use all the space that has been allotted to it.
Lastly, nosotros can also ascertain the alignment of our widgets. Nosotros do it with the post-obit flags:
-
wxALIGN_LEFT -
wxALIGN_RIGHT -
wxALIGN_TOP -
wxALIGN_BOTTOM -
wxALIGN_CENTER_VERTICAL -
wxALIGN_CENTER_HORIZONTAL -
wxALIGN_CENTER
Say nosotros wanted to identify two buttons into the right lesser of the window.
align.h
#include <wx/wx.h> class Align : public wxFrame { public: Align(const wxString& title); }; align.cpp
#include "align.h" Align::Align(const wxString& title) : wxFrame(Nix, -1, title, wxPoint(-ane, -1), wxSize(300, 200)) { wxPanel *console = new wxPanel(this, -1); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL); wxButton *ok = new wxButton(panel, -1, wxT("Ok")); wxButton *abolish = new wxButton(panel, -1, wxT("Cancel")); hbox1->Add(new wxPanel(console, -1)); vbox->Add(hbox1, 1, wxEXPAND); hbox2->Add together(ok); hbox2->Add(cancel); vbox->Add(hbox2, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 10); panel->SetSizer(vbox); Eye(); } main.h
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; master.cpp
#include "main.h" #include "align.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Align *align = new Align(wxT("Align")); align->Bear witness(true); render truthful; } We create iii sizers. 1 vertical sizer and two horizontal sizers. We put those two horizontal sizers into the vertical 1.
hbox1->Add(new wxPanel(panel, -1)); vbox->Add(hbox1, 1, wxEXPAND);
Nosotros put a wxPanel into the start horizontal sizer. We set the proportion to 1 and set a wxEXPAND flag. This fashion the sizer volition occupy all the space except the hbox2.
vbox->Add(hbox2, 0, wxALIGN_RIGHT | wxRIGHT | wxBOTTOM, 10);
We have placed the buttons into the hbox2 sizer. The hbox2 is right aligned and we too put some space to the lesser and to the correct of the buttons.
Go To Course
In the following instance we innovate several important ideas.
gotoclass.h
#include <wx/wx.h> class GotoClass : public wxFrame { public: GotoClass(const wxString& championship); }; gotoclass.cpp
#include "gotoclass.h" GotoClass::GotoClass(const wxString& championship) : wxFrame(Zip, -ane, title, wxPoint(-ane, -one), wxSize(450, 400)) { wxPanel *panel = new wxPanel(this, -ane); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL); wxStaticText *st1 = new wxStaticText(panel, wxID_ANY, wxT("Class Name")); hbox1->Add together(st1, 0, wxRIGHT, 8); wxTextCtrl *tc = new wxTextCtrl(panel, wxID_ANY); hbox1->Add(tc, ane); vbox->Add(hbox1, 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 10); vbox->Add(-i, 10); wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL); wxStaticText *st2 = new wxStaticText(console, wxID_ANY, wxT("Matching Classes")); hbox2->Add(st2, 0); vbox->Add(hbox2, 0, wxLEFT | wxTOP, 10); vbox->Add together(-ane, 10); wxBoxSizer *hbox3 = new wxBoxSizer(wxHORIZONTAL); wxTextCtrl *tc2 = new wxTextCtrl(panel, wxID_ANY, wxT(""), wxPoint(-i, -ane), wxSize(-i, -1), wxTE_MULTILINE); hbox3->Add(tc2, 1, wxEXPAND); vbox->Add together(hbox3, 1, wxLEFT | wxRIGHT | wxEXPAND, 10); vbox->Add together(-one, 25); wxBoxSizer *hbox4 = new wxBoxSizer(wxHORIZONTAL); wxCheckBox *cb1 = new wxCheckBox(panel, wxID_ANY, wxT("Case Sensitive")); hbox4->Add(cb1); wxCheckBox *cb2 = new wxCheckBox(panel, wxID_ANY, wxT("Nested Classes")); hbox4->Add(cb2, 0, wxLEFT, ten); wxCheckBox *cb3 = new wxCheckBox(panel, wxID_ANY, wxT("Not-Project Classes")); hbox4->Add(cb3, 0, wxLEFT, 10); vbox->Add(hbox4, 0, wxLEFT, ten); vbox->Add(-1, 25); wxBoxSizer *hbox5 = new wxBoxSizer(wxHORIZONTAL); wxButton *btn1 = new wxButton(panel, wxID_ANY, wxT("Ok")); hbox5->Add together(btn1, 0); wxButton *btn2 = new wxButton(panel, wxID_ANY, wxT("Close")); hbox5->Add(btn2, 0, wxLEFT | wxBOTTOM , v); vbox->Add together(hbox5, 0, wxALIGN_RIGHT | wxRIGHT, 10); panel->SetSizer(vbox); Centre(); } main.h
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; main.cpp
#include "chief.h" #include "gotoclass.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { GotoClass *gotoclass = new GotoClass(wxT("GotoClass")); gotoclass->Show(true); return truthful; } This is a circuitous example using wxBoxSizer. The layout is straitforward. We create one vertical sizer. We put and so five horizontal sizers into information technology.
vbox->Add together(hbox3, 1, wxLEFT | wxRIGHT | wxEXPAND, ten); vbox->Add(-1, 25);
We already know that we tin can control the distance amongst widgets by combining the flag parameter with the edge parameter. But there is one real constraint. In the Add method we tin can specify only one border for all given sides. In our case, we give 10 px to the right and to the left. Just we cannot give 25 px to the bottom. What we can do is to give ten px to the bottom, or 0 px. If nosotros omit wxBOTTOM. And then if nosotros need different values, nosotros can add some actress infinite. With the Add together method, we tin insert widgets and space every bit well.
vbox->Add together(hbox5, 0, wxALIGN_RIGHT | wxRIGHT, ten);
We place the two buttons on the right side of the window. How do nosotros do it? Iii things are important to reach this: the proportion, the align flag, and the wxEXPAND flag. The proportion must be naught. The buttons should non alter their size, when nosotros resize our window. We must not specify wxEXPAND flag. The buttons occopy just the surface area that has been alotted to it. And finally, we must specify the wxALIGN_RIGHT flag. The horizontal sizer spreads from the left side of the window to the right side. So if we specify wxALIGN_RIGHT flag, the buttons are placed to the correct side. Exactly, equally we wanted.
wxGridSizer
wxGridSizer lays out widgets in two dimensional table. Each prison cell within the tabular array has the same size.
wxGridSizer(int rows, int cols, int vgap, int hgap)
In the constructor we specify the number of rows and columns in the tabular array. And the vertical and horizontal space between our cells.
In our example we create a skeleton of a figurer. It is a perfect example for a wxGridSizer.
gridsizer.h
#include <wx/wx.h> class GridSizer : public wxFrame { public: GridSizer(const wxString& title); wxMenuBar *menubar; wxMenu *file; wxBoxSizer *sizer; wxGridSizer *gs; wxTextCtrl *display; }; gridsizer.cpp
#include "gridsizer.h" GridSizer::GridSizer(const wxString& championship) : wxFrame(Nix, -1, title, wxPoint(-1, -ane), wxSize(270, 220)) { menubar = new wxMenuBar; file = new wxMenu; SetMenuBar(menubar); sizer = new wxBoxSizer(wxVERTICAL); display = new wxTextCtrl(this, -i, wxT(""), wxPoint(-1, -i), wxSize(-ane, -1), wxTE_RIGHT); sizer->Add(display, 0, wxEXPAND | wxTOP | wxBOTTOM, 4); gs = new wxGridSizer(four, 4, 3, 3); gs->Add(new wxButton(this, -i, wxT("Cls")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("Bck")), 0, wxEXPAND); gs->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("Shut")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("7")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("8")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("nine")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("/")), 0, wxEXPAND); gs->Add together(new wxButton(this, -1, wxT("4")), 0, wxEXPAND); gs->Add(new wxButton(this, -one, wxT("v")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("vi")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("*")), 0, wxEXPAND); gs->Add together(new wxButton(this, -1, wxT("1")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("2")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("3")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("-")), 0, wxEXPAND); gs->Add together(new wxButton(this, -i, wxT("0")), 0, wxEXPAND); gs->Add together(new wxButton(this, -1, wxT(".")), 0, wxEXPAND); gs->Add together(new wxButton(this, -1, wxT("=")), 0, wxEXPAND); gs->Add(new wxButton(this, -1, wxT("+")), 0, wxEXPAND); sizer->Add(gs, 1, wxEXPAND); SetSizer(sizer); SetMinSize(wxSize(270, 220)); Middle(); } main.h
#include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; main.cpp
#include "main.h" #include "gridsizer.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { GridSizer *gs = new GridSizer(wxT("GridSizer")); gs->Show(true); render true; } In our example, we set a vertical sizer for a wxFrame. Nosotros put a static text and a filigree sizer into the vertical sizer.
Notice how we managed to put a space between the Bck and the Close buttons. We simply put an empty wxStaticText there.
gs->Add(new wxButton(this, -1, wxT("Cls")), 0, wxEXPAND); We call the Add method multiple times. Widgets are placed inside the table in the order, they are added. The outset row is filled first, then the second row etc.
wxFlexGridSizer
This sizer is like to wxGridSizer. Information technology does as well lay out its widgets in a two dimensional table. It adds some flexibility to it. wxGridSizer cells are of the same size. All cells in wxFlexGridSizer have the same height in a row. All cells accept the same width in a column. But all rows and columns are not necessarily the aforementioned top or width.
wxFlexGridSizer(int rows, int cols, int vgap, int hgap)
rows and cols specify the number of rows and columns in a sizer. vgap and hgap add some space between widgets in both directions.
Many times developers have to develop dialogs for data input and modification. I find wxFlexGridSizer suitable for such a chore. A developer tin easily set up a dialog window with this sizer. It is also possible to attain this with wxGridSizer, but it would not look nice, because of the constraint that each cell has the same size.
flexgridsizer.h
#include <wx/wx.h> class FlexGridSizer : public wxFrame { public: FlexGridSizer(const wxString& title); }; flexgridsizer.cpp
#include "flexgridsizer.h" FlexGridSizer::FlexGridSizer(const wxString& title) : wxFrame(NULL, -1, title, wxPoint(-1, -1), wxSize(270, 220)) { wxPanel *panel = new wxPanel(this, -one); wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); wxFlexGridSizer *fgs = new wxFlexGridSizer(iii, 2, ix, 25); wxStaticText *thetitle = new wxStaticText(console, -ane, wxT("Title")); wxStaticText *author = new wxStaticText(panel, -1, wxT("Author")); wxStaticText *review = new wxStaticText(console, -i, wxT("Review")); wxTextCtrl *tc1 = new wxTextCtrl(panel, -1); wxTextCtrl *tc2 = new wxTextCtrl(panel, -1); wxTextCtrl *tc3 = new wxTextCtrl(panel, -1, wxT(""), wxPoint(-i, -1), wxSize(-1, -one), wxTE_MULTILINE); fgs->Add(thetitle); fgs->Add(tc1, 1, wxEXPAND); fgs->Add together(author); fgs->Add(tc2, 1, wxEXPAND); fgs->Add(review, ane, wxEXPAND); fgs->Add(tc3, i, wxEXPAND); fgs->AddGrowableRow(2, ane); fgs->AddGrowableCol(ane, 1); hbox->Add(fgs, ane, wxALL | wxEXPAND, xv); console->SetSizer(hbox); Middle(); } main.h
#include <wx/wx.h> grade MyApp : public wxApp { public: virtual bool OnInit(); }; main.cpp
#include "main.h" #include "flexgridsizer.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { FlexGridSizer *fgs = new FlexGridSizer(wxT("FlexGridSizer")); fgs->Prove(true); return true; } In our example we create a simple dialog. It could be used to insert information into the database.
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); ... hbox->Add(fgs, one, wxALL | wxEXPAND, 15);
Nosotros create a horizontal box sizer in order to put some space (15px) effectually the table of widgets.
fgs->Add(thetitle);
We add widgets to the sizer exactly as with the gridsizer.
fgs->AddGrowableRow(2, ane); fgs->AddGrowableCol(1, ane);
We make the third row and the 2nd column growable. This fashion nosotros brand the text controls grow, when the window is resized. The first two text controls will grow in horizontal direction, the third i will abound in both direction. We must not forget to make the widgets expandable (wxEXPAND) in club to arrive really work.
This part of the wxWidgets tutorial was dedicated to layout direction.
Source: https://zetcode.com/gui/wxwidgets/layoutmanagement/
Post a Comment for "How to Read Data From Grid Cells in Wxwidgets"