Was machen diese Sizer?

Einer der schwierigsten Bereiche von wxWidgets ist es, herauszufinden, wie Sizer funktionieren. Sie sind sehr mächtig, aber manchmal nicht sehr intuitiv. Dieses Tutorial ist gedacht bei dem Verständnis aller verschiedenen Parameter und Möglichkeiten zu helfen.

Dieses Tutorial bezieht sich auf BoxSizer, weil sie die flexibelsten und am meisten genutzten Sizer sind. Die Informationen können aber genauso für andere Sizer-Typen verwendet werden. Unscoped methods like SetSizer() belong to wxWindow, but really make most sense in a wxFrame, wxDialog, wxPanel, or similar types.

Ein einfacher BoxSizer

Das folgende Beispiel ist der simpelste BoxSizer-Typ. Wir erstellen einen vertikalen Sizer (Kindelemente werden übereinander angeordnet) und platzieren darin zwei Button. Alle "Extra"-Parameter werden auf 0 gesetzt; darum kümmern wir uns später.

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, 0, 0)
SetSizer(sizer)
Default Screenshot

Dir werden zwei Dinge aufgefallen sein:

Wir kümmern und erst einmal um das zweite Problem. Um die Fenstergröße passender zu machen, können wir dem Fenster mitteilen, dass es auf die Größe des Sizers gebracht werden soll:

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, 0, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with size hints

Das ist vor allem nützlich, wenn das Fenster zu groß oder zu klein ist, um das Layout in einer ästhetisch ansprechenden Weise anzuzeigen.

Parameter 2: Proportion

Der erste Parameter von Add() ist augenscheinlich das Element (wxWindow oder wxSizer - letzteres im Falle von AddSizer()), welches du hinzufügen möchtest. Das zweite Argument beschreibt, wie groß die Kindelemente in Relation zu den anderen sind. In einem vertikalen Sizer verändert das die Höhe, in einem horizontalen Sizer die Breite. Hier sind ein paar Beispiele:

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
' Der zweite Button ist drei mal so groß, wie der erste
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 1, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 3, 0, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with 3:1 proportion

Gleicher Code wie oben, nur die Fenstergröße wurde geändert. Beachte, dass der untere Button immer noch drei mal größer ist, als der obere Button.

Screenshot with 3:1 proportion in bigger window
Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
' Der erste Button hat die 1,5-fache Größe des zweiten Buttons.
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 3, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 2, 0, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with 3:2 proportion
Gleicher Code wie oben, nur die Fenstergröße wurde geändert. Die Button behalten ihre Proportionen. Screenshot with 3:2 proportion in bigger window

Wenn einer der Proportions-Parameter 0 ist, hat das Kindelement die minimale Größe und alle anderen vergrößern/verkleinern sich proportional:

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
' Dritter Button hat die doppelte Größe, wie der zweite Button
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 1, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Another Button"), 2, 0, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot of three proportional buttons
Gleicher Code wie oben, nur die Fenstergröße wurde geändert. Der obere Button hat immer noch die minimale Größe und der untere ist immer noch doppelt so groß, wie der mittlere. Screenshot of three proportional buttons in bigger window

Das ist vor allem nützlich, wenn du zum Beispiel einen Button haben möchtest, welcher nur so groß ist, wie nötig und ein Element, welches den restlichen Platz einnimmt. Um das zu machen musst du dem Button die Proportion 0 und dem anderen Element eine Proportion größer 0 geben. Speziell Mac-Benutzer werden es dir danken, wenn du keine riesigen Button erstellst.

Parameter 3 und 4: Flags und Rahmen

Lass uns mit dem einfachsten anfangen: Den Ausrichtungs-Flags, welche sich eigentlich selbst erklären.

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
' Zweiter Button ist rechts ausgerichtet
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, wxALIGN_RIGHT, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot of right-aligned button
Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
' Zweiter Button ist zentriert
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, wxALIGN_CENTER, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot of centered button

Das Nächste ist wxEXPAND, welches ein Synonym von wxGROW ist.

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
' Zweiter Button nimmt den ganzen Platz
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, wxEXPAND, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot of expanded button

Wie du sehen kannst, nimmt der erste Button die minimale Größe und der zweite Button wächst auf die selbe Größe an. Das beeinflusst Elemente genau in die andere Richtung, wie der zweite Parameter; wxEXPAND in einem vertikalen Sizer lässt ein Element horizontal wachsen, und in einem horizontalen Sizer lässt es das Element vertikal wachsen.

Das nächste ist wxSHAPED. Dieser Flag garantiert, dass die Breite und Höhe eines Elements proportional bleiben. Das macht bei Button wenig Sinn, ist jedoch nützlich für Grafiken, welche sonst verzerrt oder abgeschnitten würden.

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
' Zweiter Button wird proportional die Größe ändern
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 1, wxSHAPED, 0)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot of shaped button
Gleicher Code wie oben, nur die Fenstergröße wurde geändert. Die Breite wuchs beträchtlich mit der Höhe. In Wirklichkeit ist es nicht vertikal nicht komplett gleich gewachsen, weil das Verhältnis nicht eingehalten werden konnte. Screenshot of shaped button

Zum Schluss haben wir noch die Rahmen-Flags. Die beschreiben die Seiten, an denen ein Rahmen sein soll und machen nur Sinn, wenn der Rahmen größer als 0 ist. Um das am besten zu zeigen, behalten wir den wxEXPAND-Flag.

Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, wxEXPAND | wxLEFT, 20)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with left border
Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, wxEXPAND | wxLEFT | wxRIGHT, 20)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with left and right borders
Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
sizer.Add(New wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(New wxButton.Create(Self, -1, "Tiny Button"), 0, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 20)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with left, right, and top borders
Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
sizer.Add(new wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(new wxButton.Create(Self, -1, "Tiny Button"), 0, wxEXPAND | wxALL, 20)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with borders on all sides
Local sizer:wxBoxSizer = New wxBoxSizer.Create(wxVERTICAL)
sizer.Add(new wxButton.Create(Self, -1, "A Really Really Big Button"), 0, 0, 0)
sizer.Add(new wxButton.Create(Self, -1, "Tiny Button"), 0, wxEXPAND | wxALL, 5)
sizer.SetSizeHints(Self)
SetSizer(sizer)
Screenshot with smaller borders

Du kannst sehen, dass der Button an den entsprechenden Seiten so viele Pixel von den anderen Elementen bzw. vom Sizer-Rand entfernt ist, wie im letzten Parameter angegeben.

Abschluss

Ich hoffe, dass dieses Dokument es die einfacher macht die verschiedenen Sizer-Parameter machen. Sizer sind sehr mächtig und ihre Benutzung wird dir helfen sicherzustellen, dass deine Programme auf allen Plattformen korrekt.

Autor

Originial-Tutorial von Brian Victor (brianhv@users.sourceforge.net)
Adaptiert für BlitzMax von Bruce A Henderson.
Übersetzung von Jonas Cleve.