wx.Frame und mehrere Panels

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Samstag 8. Juli 2006, 19:45

Hallo

Das mit den Mehreren Panels ist so gemeint....

Ich will ein MainFrame erstellen und je nach dem was der User gerade will (Per Menübar / Toolbar auswählen) soll in diesem MainFrame ein anderer Inhalt sein.

Mit MDIParentFrame möchte ich es nicht machen! Wieso? DA wird automatisch einen nicht übersetzten Text erstellt.

Da dachte ich, ich mache je nach dem ein anderes Panel. Und setze dieses in das MainFrame. Nur, Wenn ich eins gemacht habe, lässt es sich nicht überschreiben. Habe dann immer 2, sehe aber nur das Älteste :(

Wie könnte man das lösen?

Gruess DM
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Samstag 8. Juli 2006, 20:17

DatenMetzgerX hat geschrieben:Ich will ein MainFrame erstellen und je nach dem was der User gerade will (Per Menübar / Toolbar auswählen) soll in diesem MainFrame ein anderer Inhalt sein.
Hi DM!

So vielleicht:

Code: Alles auswählen

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

import wx

class FirstPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("green")
        
        lab = wx.StaticText(self, -1, "First Panel")

class SecondPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("red")
        
        lab = wx.StaticText(self, -1, "Second Panel")

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "More Panels")
        
        mnu_file = wx.Menu()
        
        mnu_f_panel1 = mnu_file.Append(-1, "Panel1")
        self.Bind(
            wx.EVT_MENU, 
            lambda event: self.OnPanel(event, "Panel1"),
            mnu_f_panel1
        )
        
        mnu_f_panel2 = mnu_file.Append(-1, "Panel2")
        self.Bind(
            wx.EVT_MENU, 
            lambda event: self.OnPanel(event, "Panel2"),
            mnu_f_panel2
        )
        
        menubar = wx.MenuBar()
        menubar.Append(mnu_file, "&Datei")
        self.SetMenuBar(menubar)
        
        self.panel = FirstPanel(self)

    def OnPanel(self, event, panelname):
        self.Freeze()
        self.panel.Destroy()
        del self.panel
        if panelname == "Panel1":
            self.panel = FirstPanel(self)
        else:
            self.panel = SecondPanel(self)
        self.panel.SetSize(self.GetVirtualSize()) # ein wenig nachhelfen
        self.Thaw()

def main():
    app = wx.PySimpleApp()
    frame = MyFrame()
    frame.Center()
    frame.Show()
    app.MainLoop()
    
if __name__ == "__main__":
    main()
Bei diesem Beispiel wird das aktuelle Panel vorher gelöscht und ein neu erstelltes Panel wird eingefügt.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Samstag 8. Juli 2006, 20:32

Hi DM!

In diesem Beispiel werden zwei Panels erstellt und bleiben erhalten. Beim Umschalten wird jeweils das andere Panel versteckt.

Code: Alles auswählen

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

import wx

class FirstPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("green")
        
        lab = wx.StaticText(self, -1, "First Panel")

class SecondPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("red")
        
        lab = wx.StaticText(self, -1, "Second Panel")

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "More Panels")
        
        mnu_file = wx.Menu()
        
        mnu_f_panel1 = mnu_file.Append(-1, "Panel1")
        self.Bind(
            wx.EVT_MENU, 
            lambda event: self.OnPanel(event, "Panel1"),
            mnu_f_panel1
        )
        
        mnu_f_panel2 = mnu_file.Append(-1, "Panel2")
        self.Bind(
            wx.EVT_MENU, 
            lambda event: self.OnPanel(event, "Panel2"),
            mnu_f_panel2
        )
        
        menubar = wx.MenuBar()
        menubar.Append(mnu_file, "&Datei")
        self.SetMenuBar(menubar)
        
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.vbox)
        
        self.first_panel = FirstPanel(self)
        self.vbox.Add(self.first_panel, 1, wx.EXPAND)
        
        self.second_panel = SecondPanel(self)
        self.second_panel.Hide()

    def OnPanel(self, event, panelname):
        self.Freeze()
        
        try:
            self.vbox.Detach(self.first_panel)
        except:
            pass
        try:
            self.vbox.Detach(self.second_panel)
        except:
            pass
            
        if panelname == "Panel1":
            self.second_panel.Hide()
            self.first_panel.Show()
            self.vbox.Add(self.first_panel, 1, wx.EXPAND)
        else:
            self.first_panel.Hide()
            self.second_panel.Show()
            self.vbox.Add(self.second_panel, 1, wx.EXPAND)
        self.Layout()
        self.Thaw()

def main():
    app = wx.PySimpleApp()
    frame = MyFrame()
    frame.Center()
    frame.Show()
    app.MainLoop()
    
if __name__ == "__main__":
    main()
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Samstag 8. Juli 2006, 20:59

Was mir an diesem Beispiel nicfht so gefällt ist, das ich so die alten panels zwischenspeichern muss und so z.T das ram unnötig gebraucht wird.

Gibts da keine schönere lösung (ohne Panels?)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Samstag 8. Juli 2006, 21:52

DatenMetzgerX hat geschrieben:Gibts da keine schönere lösung (ohne Panels?)
Hi DM!

Das erste Beispiel ist ja so gemacht, dass es das alte Panel komplett aus dem Speicher löscht und das Panel, das angezeigt werden soll, frisch erstellt.

Was willst du erreichen? Wahrscheinlich habe ich deine Frage nicht richtig verstanden.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Samstag 8. Juli 2006, 22:02

OK, dann könnte es gehen.

Mein Ziel wäre es...

Ich habe ein Frame frmMain. Mainfenster ;).

Hier habe ich Statusbar + Menübar + Toolbar

dann z.B. zwei weitere "Fenster"

frmSub1 und frmSub2. Beide mit Unterschiedlichen Inhalt

wenn der User nun im frmMain im Menü auf Sub1 klickt, soll im frmMain der Inhalt des frmSub1 angezeigt werden...

Wenn der User auf Sub2 klickt, der Inhalt des frmSub2.

Sollte mit Panels allerdings gehen :)
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Sonntag 9. Juli 2006, 11:19

Noch ein Problem :(

Wenn ich in diesem Panel einen Splitter Erstelle, hat der immer eine grösse von ~5x5

Code: Alles auswählen

#Mainsplitter erstellen
        #Splitter zwischen dem Tree und den beiden Tabellen rechts
        self.splitter = wx.SplitterWindow(self)
        self.pnlTree = wx.Panel(self.splitter, style=wx.SUNKEN_BORDER)
        self.pnlBuchungen = wx.Panel(self.splitter, style=wx.SUNKEN_BORDER)
        #self.splitter.Initialize(self.pnlTree)
        self.splitter.SplitHorizontally(self.pnlTree, self.pnlBuchungen, 100)
        self.splitter.SetMinimumPaneSize(100)
self ist ein wx.Panel()
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Sonntag 9. Juli 2006, 13:27

DatenMetzgerX hat geschrieben:

Code: Alles auswählen

#Mainsplitter erstellen
        #Splitter zwischen dem Tree und den beiden Tabellen rechts
        self.splitter = wx.SplitterWindow(self)
        self.pnlTree = wx.Panel(self.splitter, style=wx.SUNKEN_BORDER)
        self.pnlBuchungen = wx.Panel(self.splitter, style=wx.SUNKEN_BORDER)
        #self.splitter.Initialize(self.pnlTree)
        self.splitter.SplitHorizontally(self.pnlTree, self.pnlBuchungen, 100)
        self.splitter.SetMinimumPaneSize(100)
Hi DM!

Sizer an Panel binden. Dann Splitter an Sizer übergeben.

Code: Alles auswählen

...
vbox = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(vbox)
self.splitter = wx.SplitterWindow(self)
vbox.Add(self.Splitter, 1, wx.EXPAND)
...
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Montag 11. September 2006, 09:18

Das Ganze funktioniert allerdings nur unter Linux...

Unter Windows überblendet diese Funktion die Toolbar...

IMAGE
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Montag 11. September 2006, 11:00

Hoi,

vielleicht hilft Dir dieses Snippet aus den matplotlib-Beispielen (mußt Du natürlich anpassen):

Code: Alles auswählen

    def add_toolbar(self):
        """
            toolbar initialization function
        """
        self.toolbar = NavigationToolbar(self.canvas)
        self.toolbar.Realize()
        #The divide for different platforms is taken from the matplotlib examples:
        if wx.Platform == '__WXMAC__':
            self.SetToolBar(self.toolbar)
        else:
            # On Windows the default size is incorrect, so these settings are required
            tw, th = self.toolbar.GetSizeTuple()
            fw, fh = self.canvas.GetSizeTuple()
            # to get closer to the GTK version on Linux (doesn't work for the Mac)
            self.toolbar.SetSize(wx.Size(fw, th))
            self.canvas_sizer.Add(self.toolbar, 0, wx.ALL| wx.EXPAND,2)
        # update the axes menu on the toolbar
        self.toolbar.update()
Wäre schön, wenn Du den relevanten Teil einer Lösung kurz posten könntest - würde mich interessieren.

Gruß,
Christian
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Montag 11. September 2006, 11:22

:) eine relativ einfache Methode gefunden...

Code: Alles auswählen

def _change_panel(self, new, name):
        self.Freeze()
        self.panel.OnDestroy()
        self.panel.Destroy()
        del self.panel
        self.panel = new
        self.panelname = name
        self.panel.SetSize(self.GetVirtualSize()) # ein wenig nachhelfen
        self.panel.SetPosition(wx.Point(0, 0))
        self.Thaw()
    
SetPosition() setzt das Panel irgend wie an den richtigen ort ;) wieso dass das windows nicht selber machen kann k.A. Evtl muess man noch eine Prüfung für Linux / Mac machen aber die habe ich Momentan gerade nicht zur verfügeung.
Antworten