Wie mehrer Fenster erzeugen außerhalb vom `Frame`?

Plattformunabhängige GUIs mit wxWidgets.
Antworten
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Ich suche eine gute Lösung wie ich mehrer Fenster erzeugen kann in einer Anwendung. So was in der Art wie man bei Gimp2 sehen kann. Dort sind ja zwei Leisten mit Tools die anscheinend 2 unterschiedliche Frames auf den Desktop sind.

Hab mir das so vorgestellt das ich ein Hauptfenster habe. Wenn ich dann z.B. auf "Logwindow" Klicke, wird ein zweites Fenster erzeugt.

Ich denke mit 2 Frames (wobei das zweite erst Später erzeugt wird) lässt sich das bewerkstelligen. Nun weiß ich aber nicht wie man zwischen zwei Frames Daten austauscht, da die ja von einander Quasi unabhängig sind.

Bin für jede Vorschläge offen wie ich 2 Fenster mit oder ohne Frames erzeugen kann.

Ich hab schon 2 Ansätze die ich gleich mal fertig machen und dann hier poste. Dan seht ihr was ich meine und wo das Problem liegt.

bis später...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Code: Alles auswählen

import os 
import sys


import wx
wx.SetDefaultPyEncoding("utf-8")

class SecFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.panel = wx.Panel(self)
        self.text_ctrl = wx.StaticText(self.panel, label="SecFrame", 
                                       pos=(10, 10))


class MainFrame(wx.Frame):
    def __init__(self, parent=None, id=-1, title = "MyApp"):
         wx.Frame.__init__(self, parent, id, title)
         self.Centre()
         self.panel = wx.Panel(self)
         self.text_ctrl = wx.StaticText(self.panel, label="MainFrame", 
                                        pos=(10, 10))
         
         self.btn = wx.Button(self.panel, -1, "SecFrame", pos=(10,30))
         self.btn.Bind(wx.EVT_BUTTON, self.OnBtn)
         
    def OnBtn(self, event):
        app = wx.PySimpleApp()
        sf = SecFrame(None, id=-1, title = "SecFrame")
        sf.Show()
        app.MainLoop()
   
def main():
    app = wx.PySimpleApp()
    mf =  MainFrame()
    mf.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()
Das scheint mir die schlechteste Lösung zu sein um zwei Fenster zu erzeugen.

Was für saubere Möglichkeiten gibt es? Gibt es vielleicht eine Möglichkeit mit der ich ein `wxPanel` als Child-Window von `MainFrame` erzeugen kann? Mit der Mdthode `AddChild` von `wx.Window` habe ich schon ein wenig versucht aber es nicht zum laufen gekriegt.

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

sape hat geschrieben:Ich suche eine gute Lösung wie ich mehrer Fenster erzeugen kann in einer Anwendung. So was in der Art wie man bei Gimp2 sehen kann.
Hi sape!

Ob sie gut ist, die Lösung -- in den Sternen steht. :-)

Code: Alles auswählen

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

import wx

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


class Frames(object):
    pass


class MyMainFrame(wx.Frame):
   
    def __init__(
        self, parent = None, id = -1, title = "Main Frame", name = "main_frame"
    ):
       
        wx.Frame.__init__(self, parent, id, title, name = name)
        self.app = wx.GetApp()
       
        panel = wx.Panel(self)
       
        vbox = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox)
       
        lab = wx.StaticText(panel)
        vbox.Add(lab, 1, wx.EXPAND | wx.ALL, 5)
        self.lab = lab
       
        cmd = wx.Button(panel, -1, "Klick mich...")
        vbox.Add(cmd, 0, wx.ALL, 10)
        cmd.Bind(wx.EVT_BUTTON, self.set_tool_frame_lab_label)
   
    def set_lab_label(self, text):
        lab = self.lab
        lab.SetLabel(text)
   
    def set_tool_frame_lab_label(self, event):
        try:
            tool_frame = self.app.frames.tool_frame
        except AttributeError:
            return
        assert(isinstance(tool_frame, MyToolFrame))
        tool_frame.set_lab_label("Hallo Tool")


class MyToolFrame(wx.Frame):
   
    def __init__(
        self, parent = None, id = -1, title = "Tool Frame", name = "tool_frame"
    ):
       
        wx.Frame.__init__(self, parent, id, title, name = name)
        self.app = wx.GetApp()
       
        panel = wx.Panel(self)
       
        vbox = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox)
       
        lab = wx.StaticText(panel)
        vbox.Add(lab, 1, wx.EXPAND | wx.ALL, 5)
        self.lab = lab
       
        cmd = wx.Button(panel, -1, "Klick mich...")
        vbox.Add(cmd, 0, wx.ALL, 10)
        cmd.Bind(wx.EVT_BUTTON, self.set_main_frame_lab_label)
       
        self.Bind(wx.EVT_CLOSE, self.on_close)
   
    def on_close(self, event):
        del self.app.frames.tool_frame
        event.Skip()
   
    def set_lab_label(self, text):
        lab = self.lab
        lab.SetLabel(text)

    def set_main_frame_lab_label(self, event):
        main_frame = self.app.frames.main_frame
        assert(isinstance(main_frame, MyMainFrame))
        main_frame.set_lab_label("Hallo Welt")


class MyApp(wx.PySimpleApp):
   
    def __init__(self):
        wx.App.__init__(
            self, redirect = False, filename = None,
            useBestVisual=False, clearSigInt=True
        )
       
        # Alle Frames werden hier drin abgelegt
        frames = Frames()
        self.frames = frames
       
        # Main-Frame
        frames.main_frame = MyMainFrame(None, name = "main_frame")
        frames.main_frame.Show()
       
        # Tool-Frame
        frames.tool_frame = MyToolFrame(frames.main_frame, name = "tool_frame")
        frames.tool_frame.Show()


def main():
    app = MyApp()
    app.MainLoop()


if __name__ == "__main__":
    main()
EDIT: Codebeispiel verbessert.
Zuletzt geändert von gerold am Montag 18. Juni 2007, 05:47, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Hallo Gerold! Genial!

Vielen, vielen dank. Genau das was ich suchte :)

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

sape hat geschrieben:Vielen, vielen dank. Genau das was ich suchte :)
Hi sape!

Das freut mich! Ich habe das Beispiel noch ein wenig ausgebaut -- aber jetzt muss ich wieder an die Arbeit. :roll:

Quellcode: http://paste.pocoo.org/show/481/

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

WOW! Saubere Arbeit Gerold. Nochmals vielen dank :)

lg
sape
ashurial
User
Beiträge: 5
Registriert: Montag 23. April 2007, 13:18

dieses mal sollte ich richtig den richtigen thread erwischt haben.

Wie sind oben genannte Panel in ein modul auszulagern? Habe es probiert kriege aber folgende Fehlermeldung:

global name 'MyApp' is not defined.

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

Hallo ashurial!

Der Code hat sich geändert. Es gibt keine direkte Abhängigkeit mehr zu MyApp.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
ashurial
User
Beiträge: 5
Registriert: Montag 23. April 2007, 13:18

ok soweit verstanden. wie würde der korrekte Code lauten, wenn man die Panels auslagert. durchschaue das ganze irgendwie nicht.
ich möchte einige Toolframes in ein Modul auslagern und möchte dass sie mit einem Mainframe, welches in einem eigenen Script definiert ist, kommunizieren.
Weiss nicht wie ich das anstellen soll.

ashurial
Antworten