Sehr einfaches Layout

Plattformunabhängige GUIs mit wxWidgets.
Antworten
enrico
User
Beiträge: 7
Registriert: Montag 30. Januar 2006, 17:00

Hallo,

ich bin neu bei wxPython und habe ein Problem, wo ich einfach nicht weiterkomme. Ich hab vorher mit FLTK programmiert und dort kann man die Positionen der Widgets mittels Pixelkoordinaten setzen. Hier brauch ich nun einen Sizer, was neu für mich ist. Ich benötige solch ein Layout

Code: Alles auswählen

___________
|     |           |
|     |           |
|     |           |
---------------
Ich hoffe, man kann es erkennt. Das Fenster soll in zwei Bereiche eingeteilt werden: In den linken soll eine TreeView, in den rechten ein Panel mit weiterem Inhalt (der hängt von der Auswahl im Baum ab).
Ich hab jetzt mit wxGlade rumexperimentiert und das einzigste, was halbwegs funktioniert: Ich setze eine feste Größe für den Baum und das Panel. Nun wird aber beim Maximieren des Fensters die Widgets nicht maximiert (ist klar).
Ich hab jetzt noch die beiden GridSizer funktioniert, aber da wird mein Baum immer 1x1 Feld groß, obwohl ich beim Hinzufügen eine Größe von (10x10) Feldern angegeben habe. Bei dem Panel das gleiche.

Hat jemand einen Tip für mich, wie ich das angehen könnte? Oder was ich falsch mache? :oops:

Danke schön, Enrico
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

(Nein, ich denke sizer brauchst du nicht unbedingt, bin mir aber nicht sicher).

Ich glaube, am besten, du verwendest ein Splitter window,
und plazierst dort das panel und das treectrl hinein.

Wie es gemacht wird, kannst du eventuell im Demo finden.
Ich meine, das Demo selbst (main.py).

Links ist das TreeControl mit allen verfügbaren Demo Beispielen.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

ich habe das wypython demo Frame mal so zusammengekürzt, damit
du es einmal ausprobieren kannst.

Code: Alles auswählen

import wx                  # This module uses the new wx namespace


_treeList = [
    # new stuff
    ('Recent Additions/Updates', [
        'FoldPanelBar',
        'GIFAnimationCtrl',
        'HyperLinkCtrl',
        'MultiSplitterWindow',
        'Throbber',
        'GetMouseState',
        'FloatCanvas',
        ]),

    # managed windows == things with a (optional) caption you can close
    ('Frames and Dialogs', [
        'Dialog',
        'Frame',
        'MDIWindows',
        'MiniFrame',
        'Wizard',
        ]),
]


#---------------------------------------------------------------------------
class wxPythonDemo(wx.Frame):
    overviewText = "wxPython Overview"

    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, size = (950, 720),
                          style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)

        self.SetMinSize((640,480))

        splitter = wx.SplitterWindow(self, -1, style=wx.CLIP_CHILDREN | wx.SP_LIVE_UPDATE | wx.SP_3D)

        def EmptyHandler(evt): pass
        splitter.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)

        self.treeMap = {}
        self.tree = wx.TreeCtrl(splitter, -1, style =
                                wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
                               )

        root = self.tree.AddRoot("wxPython Overview")
        firstChild = None
        for item in _treeList:
            child = self.tree.AppendItem(root, item[0])
            if not firstChild: firstChild = child
            for childItem in item[1]:
                theDemo = self.tree.AppendItem(child, childItem)
                self.treeMap[childItem] = theDemo

        self.panel = wx.Panel(splitter)
        # add the windows to the splitter and split it.
        splitter.SplitVertically(self.tree, self.panel, 200)

        splitter.SetMinimumPaneSize(120)

        self.tree.SelectItem(root)

class MyApp(wx.App):
    def OnInit(self):
        frame = wxPythonDemo(None, "wxPython: (A Demonstration)")
        frame.Show()
        return True

app = MyApp(False)
app.MainLoop()
enrico
User
Beiträge: 7
Registriert: Montag 30. Januar 2006, 17:00

Wow, danke :shock:
Ein Verweis auf SplitterWindow hätte mir ja auch gereicht... aber das find ich super. Danke :)
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

enrico hat geschrieben:Wow, danke :shock:
Ein Verweis auf SplitterWindow hätte mir ja auch gereicht... aber das find ich super. Danke :)
Bitte :wink:

Das sind die Stärken von wxPython:
Das Demo selbst (da kann man schon viel lernen und die Beispiele auch modifizieren)
Pycrust (!) zum interaktiven probieren
Die mailing Liste
die Wiki Pages
enrico
User
Beiträge: 7
Registriert: Montag 30. Januar 2006, 17:00

Ich hab gleich noch ein Problem: Ich erstelle im ctor zwei panels mit Inhalt, die ich aber gleich verstecke mit Hide(). Stattdessen kommt mein dummy panel zum Einsatz für den Splitter. Wird jetzt in dem Baum was ausgewählt, wird das alte Panel versteckt, das entsprechende Panel ausgewählt (wurde ja im ctor erstellt) und gezeigt. Das sollte funktionieren, zumindest wird das in einem Thread etwas weiter unten ja auch so gemacht. Aber das tut es nicht: Der Inhalt von dem dummy panel (StaticText) ist weiterhin sichtbar; also zusätlich zu dem ausgewählten Panel.
Für Tips und Hinweise wär ich sehr dankbar, sitze da schon eine Weile dran :(

Etwas Code dazu:

Code: Alles auswählen

def OnSelChanged(self, event):
    item = event.GetItem()
    text = self.CAIFTree.GetItemText(item)
    #print "OnSelChanged: ", text

    if self.selectionPanel is not None:
        self.selectionPanel.Hide()
    if text == "Identification":
        self.selectionPanel = self.idPanel
        
    self.selectionPanel.Show()
    self.selectionPanel.Refresh()
Danke, Enrico
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo,

kannst du das einmal in das obrige Beispiel
(möglichst einfach) einbauen?
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Du brauchst da ReplaceWindow (Funktion von SplitterWindow).
Da dann das alte auch noch durchschien, ist der (komplizierte)
Show und Hide Mechanismus erforderlich.

Vielleicht geht es aber auch einfacher.

Ich hoffe, deine Frage richtig verstanden zu haben und
poste nochmals das geänderte Sample.

BTW: Auch für mich sehr lehrreich. :)

Code: Alles auswählen

import wx                  # This module uses the new wx namespace


_treeList = [
    # new stuff
    ('Recent Additions/Updates', [
        'FoldPanelBar',
        'GIFAnimationCtrl',
        'HyperLinkCtrl',
        'MultiSplitterWindow',
        'Throbber',
        'GetMouseState',
        'FloatCanvas',
        ]),

    # managed windows == things with a (optional) caption you can close
    ('Frames and Dialogs', [
        'Dialog',
        'Frame',
        'MDIWindows',
        'MiniFrame',
        'Wizard',
        ]),
]


#---------------------------------------------------------------------------
class wxPythonDemo(wx.Frame):
    overviewText = "wxPython Overview"

    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, size = (950, 720),
                          style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)

        self.SetMinSize((640,480))

        self.splitter = splitter = wx.SplitterWindow(self, -1, style=wx.CLIP_CHILDREN | wx.SP_LIVE_UPDATE | wx.SP_3D)

        def EmptyHandler(evt): pass
        splitter.Bind(wx.EVT_ERASE_BACKGROUND, EmptyHandler)

        self.treeMap = {}
        self.tree = wx.TreeCtrl(splitter, -1, style =
                                wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
                               )

        self.toggle = 0
        root = self.tree.AddRoot("wxPython Overview")
        firstChild = None
        for item in _treeList:
            child = self.tree.AppendItem(root, item[0])
            if not firstChild: firstChild = child
            for childItem in item[1]:
                theDemo = self.tree.AppendItem(child, childItem)
                self.treeMap[childItem] = theDemo

        self.idPanel = wx.Panel(splitter)
        self.idPStatic = wx.StaticText(self.idPanel, label = "idPanel", pos = ((100, 100)))
        self.selectionPanel = wx.Panel(splitter)
        self.idPselection = wx.StaticText(self.selectionPanel, label = "idSelection", pos = ((100, 200)))
        self.idPanel.Hide()
        self.tree.Bind (wx.EVT_TREE_SEL_CHANGING, self.OnSelChanged)
        # add the windows to the splitter and split it.
        splitter.SplitVertically(self.tree, self.idPanel, 200)
        splitter.SplitVertically(self.tree, self.selectionPanel, 200)

        splitter.SetMinimumPaneSize(120)

        self.tree.SelectItem(root)
        
    def OnSelChanged(self, event):
        item = event.GetItem()
        text = self.tree.GetItemText(item)
        print "OnSelChanged: ", text
    
        if self.toggle:
            print "id"
            self.toggle = 0
            #self.splitter.ReplaceWindow (self.idPanel, self.selectionPanel)
            old = self.splitter.GetWindow2()
            self.splitter.ReplaceWindow (self.splitter.GetWindow2(), self.selectionPanel)
            old.Hide()
            self.splitter.GetWindow2().Show()
            #self.selectionPanel.Hide()
            #self.idPanel.Show()
        else:
            print "selection"
            self.toggle = 1
            #self.splitter.ReplaceWindow (self.selectionPanel, self.idPanel)
            old = self.splitter.GetWindow2()
            self.splitter.ReplaceWindow (self.splitter.GetWindow2(), self.idPanel)
            old.Hide()
            self.splitter.GetWindow2().Show()
            
            #self.idPanel.Hide()
            #self.selectionPanel.Show()
            
        #self.selectionPanel.Show()
        #self.selectionPanel.Refresh()
        

class MyApp(wx.App):
    def OnInit(self):
        frame = wxPythonDemo(None, "wxPython: (A Demonstration)")
        frame.Show()
        return True

app = MyApp(False)
app.MainLoop()
enrico
User
Beiträge: 7
Registriert: Montag 30. Januar 2006, 17:00

Bis auf das ReplaceWindow() hab ich genau das selbe :(

Auf jeden Fall vielen, vielen Dank :beer:
tomate
User
Beiträge: 48
Registriert: Sonntag 5. August 2007, 12:07

Code: Alles auswählen

        self.treeMap = {}
        self.tree = wx.TreeCtrl(splitter, -1, style =
                                wx.TR_DEFAULT_STYLE #| wx.TR_HAS_VARIABLE_ROW_HEIGHT
                               )

        root = self.tree.AddRoot("wxPython Overview")
        firstChild = None
        for item in _treeList:
            child = self.tree.AppendItem(root, item[0])
            if not firstChild: firstChild = child
            for childItem in item[1]:
                theDemo = self.tree.AppendItem(child, childItem)
                self.treeMap[childItem] = theDemo

        self.panel = wx.Panel(splitter)
        # add the windows to the splitter and split it.
        splitter.SplitVertically(self.tree, self.panel, 200)

        splitter.SetMinimumPaneSize(120)

        self.tree.SelectItem(root) 
Was müsste ich machen, wenn ich die Treeliste irgendwo updaten möchte? Also eine neue Liste im Baum darstellen möchte? Muss ich erst alle Elemente löschen?

Edit:
Hab mit

Code: Alles auswählen

self.tree.DeleteAllItems()
alles gelöscht? Spricht was dagegen?
Antworten