Welchen Sizer verwenden?

Plattformunabhängige GUIs mit wxWidgets.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Mittwoch 10. Oktober 2007, 16:15

So geht's mit dem GridBagSizer (aber ich mag ihn nicht besonders):

Bild

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import wx

wx.SetDefaultPyEncoding("iso-8859-15")


class MyFrame(wx.Frame):
    
    def __init__(
        self, parent = None, title = "Example", size = wx.Size(550, 420)
    ):
        wx.Frame.__init__(self, parent, -1, title, size = size)
        
        panel = wx.Panel(self)
        
        vbox_main = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox_main)
        
        # GridBagSizer erstellen und einstellen
        grid_sizer = wx.GridBagSizer(vgap = 5, hgap = 5)
        grid_sizer.AddGrowableCol(1) # zweite Spalte
        grid_sizer.AddGrowableRow(1) # zweite Zeile
        vbox_main.Add(grid_sizer, 1, wx.EXPAND | wx.ALL, 5)
        
        left_txt = wx.TextCtrl(panel, size = (100, -1), style = wx.TE_MULTILINE)
        grid_sizer.Add(left_txt, (0, 0), (2, 1), wx.EXPAND)
        
        top_txt = wx.TextCtrl(panel, size = (-1, 100), style = wx.TE_MULTILINE)
        grid_sizer.Add(top_txt, (0, 1), (1, 1), wx.EXPAND)
        
        bottom_txt = wx.TextCtrl(panel, style = wx.TE_MULTILINE)
        grid_sizer.Add(bottom_txt, (1, 1), (1, 1), wx.EXPAND)


def main():
    """Testing"""
    app = wx.PySimpleApp()
    f = MyFrame()
    f.Center()
    f.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Mittwoch 10. Oktober 2007, 16:21

gerold hat geschrieben:So geht's mit dem GridBagSizer (aber ich mag ihn nicht besonders)
Und so funktioniert es, nur mit BoxSizer:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import wx

wx.SetDefaultPyEncoding("iso-8859-15")


class MyFrame(wx.Frame):
    
    def __init__(
        self, parent = None, title = "Example", size = wx.Size(550, 420)
    ):
        wx.Frame.__init__(self, parent, -1, title, size = size)
        
        panel = wx.Panel(self)
        
        vbox_main = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox_main)
        
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        vbox_main.Add(hbox, 1, wx.EXPAND | wx.ALL, 3)
        
        left_txt = wx.TextCtrl(panel, size = (100, -1), style = wx.TE_MULTILINE)
        hbox.Add(left_txt, 0, wx.EXPAND | wx.ALL, 3)
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox.Add(vbox, 1, wx.EXPAND)
        
        top_txt = wx.TextCtrl(panel, size = (-1, 100), style = wx.TE_MULTILINE)
        vbox.Add(top_txt, 0, wx.EXPAND | wx.ALL, 3)
        
        bottom_txt = wx.TextCtrl(panel, style = wx.TE_MULTILINE)
        vbox.Add(bottom_txt, 1, wx.EXPAND | wx.ALL, 3)


def main():
    """Testing"""
    app = wx.PySimpleApp()
    f = MyFrame()
    f.Center()
    f.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()
mfg
Gerold
:-)
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Mittwoch 10. Oktober 2007, 21:58

Danke lieber Gerold!
Das sieht für meinen Wissensstand schon verträglicher aus. ;)

Aber irgendwie kommen doch mit jeder Antwort wieder neue Fragen. :(

Zum letzten Code:
Also: ein Panel und ne Vbox. Darin dann ne HBox mit wieder einer Vbox drin?

Und was mich an der Sache am meisten verwirrt und mir gleichzeitig auch vor Augen führt, dass ich das Konzept nicht verstanden habe:

Code: Alles auswählen

top_txt = wx.TextCtrl(panel, size = (-1, 100), style = wx.TE_MULTILINE)
vbox.Add(top_txt, 0, wx.EXPAND | wx.ALL, 3)
Ein Textcontrol, das als Parent das Panel hat und in der nächsten Zeile wird aber genau diese Objekt an die Vbox übergeben. Das verstehe icht nicht. Wie hängen dies zusammen? Sorgt die Box nicht dafür, dass das Panel vergrößert/verkleinert wird und mit ihm auch sein Inhalt?

Wo ist da mein Denkfehler? Ich begreife es (im Moment) einfach noch nicht. Und selbst wxP in Action, wxPython in one Page und die wxDemo helfen mir da irgendwie nicht weiter. Irgendwas lässt micht nicht dahinter kommen. *gleich rasend werd*

Danke für eure Mühen und Geduld.
Gruß!
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Mittwoch 10. Oktober 2007, 22:47

C4S3 hat geschrieben:Ein Textcontrol, das als Parent das Panel hat und in der nächsten Zeile wird aber genau diese Objekt an die Vbox übergeben. Das verstehe icht nicht. Wie hängen dies zusammen? Sorgt die Box nicht dafür, dass das Panel vergrößert/verkleinert wird und mit ihm auch sein Inhalt?
Hallo C4S3!

Also, die Sache ist eigentlich ganz einfach. :twisted:

Ein Widget muss auf einem Container liegen. Frames, Dialogs, Panels und noch so ein paar Objekte sind solche Container.

Sizer sind keine Container. Sizer sind unsichtbare "Helfer", die sich **nur** darum kümmern, dass die Widgets auf dem Container korrekt angeordnet werden.

Man kann einem Container einen Sizer zuweisen. Dieser Sizer ist dann nur für die Anordnung der Widgets auf diesem Container zuständig.

Code: Alles auswählen

panel = wx.Panel(parent = self)
vbox = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(vbox)
Wenn ich jetzt ein neues Widget erstelle, dann lege ich es schon beim Erstellen auf einen Container.

Code: Alles auswählen

txt = wx.TextCtrl(parent = panel)
Damit liegt das Widget schon auf dem Container, aber es ist noch nicht korrekt angeordnet. Dafür binde ich das neue Widget zusätzlich an einen Sizer.

Jetzt könntest du fragen, warum macht das wxPython nicht automatisch? Es wurde dem Container ja schon ein Sizer zugeordnet. -- Die Antwort ist: Man kann an so einen unsichtbaren Sizer, nicht nur Widgets, sondern auch Sizer zuordnen. Dadurch, dass an einen Sizer auch noch andere Sizer gebunden werden können, kann man die vielfältigsten Layouts generieren. Aber wxPython kann nicht automatisch wissen, welcher Sizer jetzt für das neue, soeben in den Container gelegte, Widget zuständig ist. Deshalb machen wir das selbst. Wir binden das neue Widget selbst an einen Sizer und geben dabei auch noch an, wie und wo und mit welchem Abstand usw. das neue Widget vom Sizer angeordnet werden soll.

Code: Alles auswählen

vbox.Add(txt, proportion = 0, flag = wx.EXPAND | wx.ALL, border = 10)
Damit wird jetzt das neue TextCtrl, an den Sizer ``vbox`` gebunden. ``proportion`` gibt an, wie viel Teile des Gesamtplatzes von diesem Widget ausgefüllt werden soll. Bei einem vertikalen BoxSizer ist damit der Platz nach unten gemeint. Eine 0 gibt an, dass das Widget nur so viel Platz bekommt, wie viel es gerade mal benötigt.
Zahlen > 0 geben die Teile an. Gibt es im gesamten Sizer nur ein Widget und ist die Proportion dieses Widgets 1, dann wird es die gesamte Größe des Sizers ausfüllen.
Kommt noch ein zweites Widget dazu und ist dessen Proportion 2, dann wird das erste Widget ein Drittel und das zweite Widget zwei Drittel des Platzes von oben nach unten ausfüllen.

Mit dem Flag wx.EXPAND gibt man an, dass das Widget den gesamten Bereich innerhalb des Sizers, von links nach rechts ausfüllen soll. Bei einer vertikalen Box ist die Proportion immer auf den vertikalen Bereich bezogen. wx.EXPAND bezieht sich damit bei einer vertikalen Box auf den horizontalen Bereich.

Bei einer horizontalen Box ist die Proportion immer auf den horizontalen Bereich innerhalb dieses Sizers bezogen. wx.EXPAND bezieht sich damit bei einer horizontalen Box auf den vertikalen Bereich.

Aber ich glaube, in wxPython in Action wird das viel schöner erklärt.

EDIT:

Nachzulesen in "wxPython in Action" auf den Seiten 323 bis 355.

mfg
Gerold
:-)
Zuletzt geändert von gerold am Donnerstag 11. Oktober 2007, 08:28, insgesamt 1-mal geändert.
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
C4S3
User
Beiträge: 292
Registriert: Donnerstag 21. September 2006, 10:07
Wohnort: Oberösterreich

Donnerstag 11. Oktober 2007, 07:26

gerold hat geschrieben:Aber ich glaube, in wxPython in Action wird das viel schöner erklärt.
Nein, wird es IMHO nicht.

Danke für die Erklärung. Das hilft jetzt echt enorm! *verbeug*
Gruß!
Antworten