Reputation: 1227
I have been learning wxWidgets for the last week, both by using IDEs and writing C++ code. I'm starting to despair at ever getting something that looks nice, as the ability to position items seems very limited.
I'm porting a large-ish project from C++Builder to VStudio, for cost reasons. I've got quite a few dialogs to recreate. They generally contain varying combinations of a 'blocks' of input - for lack of a better word. I chose wxWidgets for my GUI because I thought I could build up the dialogs in code from functions that produce a row of the form. For example in the dialog shown below I might have functions CreateLabelEdit, CreateLabelCombo, CreateBoldLabel, etc. I'm actually having some success at that part but failing miserably in styling the dialog.
Here are some of the design criteria from this particular form:
All of the inputs are left aligned and different widths appropriate to their contents.
The input labels are all right aligned.
The alignment point (ie. the width of the column containing the input labels is the same across all dialogs, and the widths of the various inputs is as well. Of course there are exceptions!
Other types of labels are aligned at a different spot. BoldLabels in this case.
Basically I want to control the size, location and alignment of my objects. Is this a case of having the wrong mindset for the tool I have chosen? Or can these types of things be accomplished with this tool?
PARTIAL SOLUTION I've tried using absolute positions mixed with sizers and that doesn't work at all.
Then I tried using a flexgrid sizer to do a part of the example, If I can make one of the blocks then I can stitch together multiple blocks. It's all good except when I set the width of the first column using SetItemMinSize, as @VZ suggested, that item loses it's sizerflag settings:
form4::form4() :wxDialog(nullptr, wxID_ANY, "title")
{
wxSizerFlags flagT1(1);
flagT1.Align(wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT).Border(wxTOP | wxLEFT, 10);
wxSizerFlags flagT2(1);
flagT2.Align(wxALIGN_CENTER_VERTICAL ).Border(wxTOP | wxLEFT, 10);
wxSizerFlags flagT3(1);
flagT3.Align(wxALIGN_CENTER_VERTICAL).Border(wxTOP | wxLEFT| wxRIGHT, 10);
wxBoxSizer* bSize = new wxBoxSizer(wxVERTICAL);
wxStaticText* _Text = new wxStaticText(this, wxID_ANY, "this should be bold");
wxFont _Font = _Text->GetFont();
_Font.MakeBold();
_Font.SetPixelSize(_Font.GetPixelSize()*1.1);
_Text->SetFont(_Font);
bSize->Add(_Text, wxSizerFlags().Border(wxTOP, 10).Center());
bSize->Add(new wxStaticText(this, wxID_ANY, "this should be bold"),
wxSizerFlags().Border(wxTOP, 10).Center());
wxFlexGridSizer* bSizer = new wxFlexGridSizer(3,0,0);
_Text = new wxStaticText(this, wxID_ANY, "bob");
// bSizer->SetItemMinSize(_Text, wxSize(150, -1)); //this has no effect here
bSizer->Add(_Text, flagT1);
bSizer->SetItemMinSize(_Text, wxSize(150, -1));// loses styling of flagT1
bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value", wxDefaultPosition, wxSize(150, -1)), flagT2);
bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);
bSizer->Add(new wxStaticText(this, wxID_ANY, " longer"), flagT1);
bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value2", wxPoint(-1, -1), wxSize(150, -1)), flagT2);
bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);
bSizer->Add(new wxStaticText(this, wxID_ANY, "bob"), flagT1);
bSizer->Add(new wxTextCtrl(this, wxID_ANY, "default_value3", wxPoint(-1, -1), wxSize(150, -1)), flagT2);
bSizer->Add(new wxStaticText(this, wxID_ANY, "cm", wxPoint(200, 20)), flagT3);
bSize->Add(bSizer);
bSize->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags(0).Border(wxALL, 10));
this->SetSizerAndFit(bSize);
// this->Layout();
this->Centre(wxBOTH);
}
produces this:
Upvotes: 1
Views: 694
Reputation: 22678
This particular dialog is not especially simply to create in wxWidgets because it can't be done with a simple wxFlexGridSizer
. You have several choices:
wxFlexGridSizer
and creating it should be very easy in either the code or a dialog editor.wxFlexGridSizer
, you need to have several of them and manually align their first columns. The way to do is to find the width of the longest label (use GetTextExtent()
) and set the minimal item size (SetItemMinSize()
) to it for all sizers.wxGridBagSizer
. Personally, I don't recommend using it because it's messier (you have to manually track columns/rows), but it does allow to do exactly what you want.Upvotes: 2