Seite 1 von 1

wx.Frame und mehrere Panels

Verfasst: Samstag 8. Juli 2006, 19:45
von DatenMetzgerX
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

Re: wx.Frame und mehrere Panels

Verfasst: Samstag 8. Juli 2006, 20:17
von gerold
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
:-)

Verfasst: Samstag 8. Juli 2006, 20:32
von gerold
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
:-)

Verfasst: Samstag 8. Juli 2006, 20:59
von DatenMetzgerX
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?)

Verfasst: Samstag 8. Juli 2006, 21:52
von gerold
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
:-)

Verfasst: Samstag 8. Juli 2006, 22:02
von DatenMetzgerX
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 :)

Verfasst: Sonntag 9. Juli 2006, 11:19
von DatenMetzgerX
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()

Verfasst: Sonntag 9. Juli 2006, 13:27
von gerold
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
:-)

Verfasst: Montag 11. September 2006, 09:18
von DatenMetzgerX
Das Ganze funktioniert allerdings nur unter Linux...

Unter Windows überblendet diese Funktion die Toolbar...

IMAGE

Verfasst: Montag 11. September 2006, 11:00
von CM
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

Verfasst: Montag 11. September 2006, 11:22
von DatenMetzgerX
:) 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.