Hand hat geschrieben:Hey Super, danke!
Genauso hatte ich mir das vorgestellt, jetzt nur noch meine Frage wo
ist denn eigentlich dann der Unterschid zu einem AuiMDI?
Optisch sehen beide ja gleich aus.
Der GUI Teil von wx besteht aus zwei verschiedenen Basen:
http://wxpython.wxcommunity.com/docs/ap ... class.html
1. Das eine ist das sogenannte Frame und seht an "oberster"[1] Hierarchie. Etwas was ein Frame ist, wird grundsätzlich als eigenständiges Fenster angezeigt, und lässt sich nicht in andere Fenster einbetten wie z.B. ein ``wx.Panel``, ``wx.TextCtrl``, etc...
[1]
``wx.Frame`` hat als Base ``TopLevelWindow`` (Das wiederum ``Window`` als Base hat, das bei den GUI Teile an der oberster Hierarchie ist.). So weit ich das verstanden habe ist das ``TopLevelWindow`` dafür zuständig um ein Widget als eigenständiges Fenster zu definieren. Ein widget wie z.B. ``wxFrame`` das von ``TopLevelWindow`` erbt und dann einen Konstruktor definiert (``TopLevelWindow`` hat keinen), wird dann als eigenständiges Fenster angezeigt.
Wenn wir es ganz genau nehmen, dann ist ``TopLevelWindow`` (wenn es einen Konstruktor (__init__) und eine Create-Methode defineiren würde) ausreichend
Hier mal ein Beispiel, was für einen primitiven Frame reichen würde:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import wx._windows
from wx._windows import _windows_
wx.SetDefaultPyEncoding("utf-8")
class PrimitiveFrame(wx.TopLevelWindow):
def __init__(self, *args, **kwargs):
_windows_.Frame_swiginit(self,_windows_.new_Frame(*args, **kwargs))
self._setOORInfo(self)
def Create(*args, **kwargs):
return _windows_.Frame_Create(*args, **kwargs)
def main():
app = wx.PySimpleApp()
mf = PrimitiveFrame(None)
mf.Show()
app.MainLoop()
if __name__ == "__main__":
main()
Wie man sehen kann ist das ``TopLevelWindow`` tatsächlich dafür zuständig, um ein Widget als eigenständiges Fenster zu definieren.
Es ist nicht empfohlen sich eigene Frame-Typen zu definieren, da man da auf private Interna (ebene Namen die mit _ oder __ beginnen) zurückgreifen muss, die sich in späteren Versionen von wx wider ändern können! Das obere Beispiel dient nur der Veranschaulichung und damit ich denn zweck von ``TopLevelWindow`` darstellen kann!
2. Ein Panel (Etwas das ``wx.Window in seiner Hierarchie hat aber
kein ``TopLevelWindow``) ist nicht als eigenständiges Fenster geeignet und wird nur verwendet um es in einem Frame "einzubetten".
http://wxpython.wxcommunity.com/docs/ap ... class.html
Das es nicht geht kann man daran sehen:
Code: Alles auswählen
# ...
class TestPanel(wx.Panel):
def __init__(self, *args, **kwargs):
wx.Panel.__init__(self, *args, **kwargs)
def main():
app = wx.PySimpleApp()
mf = TestPanel(None)
mf.Show()
app.MainLoop()
if __name__ == "__main__":
main()
# can't create wxWindow without parent
Ein einbetbares Widget erwartet immer einen Parent, das entweder ein Frame sein kann oder ein anderes Widget das die oberste Base ``wx.Window`` hat.
So, wie bereits erwähnt hat ``wxPanel`` ``wx.Window`` als Base und kein ``TopLevelWindow``.
Schauen wir mal wie wir aus ``wx.Window`` ein eigenen Paneltyp definieren:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import wx._windows
from wx._windows import _windows_
wx.SetDefaultPyEncoding("utf-8")
class PrimitivePanel(wx.Window):
def __init__(self, *args, **kwargs):
wx.Window.__init__(self, *args, **kwargs)
class PrimitiveFrame(wx.TopLevelWindow):
def __init__(self, *args, **kwargs):
_windows_.Frame_swiginit(self,_windows_.new_Frame(*args, **kwargs))
self._setOORInfo(self)
my_panel = PrimitivePanel(parent=self, id=-1, name='PrimitivePanel')
my_panel.SetBackgroundColour((150,150,100))
def Create(*args, **kwargs):
return _windows_.Frame_Create(*args, **kwargs)
def main():
app = wx.PySimpleApp()
mf = PrimitiveFrame(None)
mf.Show()
app.MainLoop()
if __name__ == "__main__":
main()
Wie man sieht funktioniert es.
Auch hier empfehle ich nicht von ``wxWindow`` zu erben sondern direkt von ``wx.Panel`` aus dem Grund, das `wx.Panel`` par nützliche Methoden mitbringt.
Nun sollte der unterschied zwischen einen "Frame" und "Panel" klar geworden sein. -- Als Frame bezeichnen wir(?) ein eigenständiges Fenster, und als Panel(?) etwas das man in einem Fenster einbetten kann, wie z.B. ein
``wxTextCtrl``. das eben auch `wx.Window`` als Base und kein ``TopLevelWindow`` dazwischen hat.
€: Auf Events (z.B. Keyevents) gehe ich mal hier nicht ein, das es den Rahmen sprengen würde.
Zusammengefast:
1. Jedes Widget das in der Hierarchie ein ``wx.Window``
und ein``TopLevelWindow`` dazwischen hat, wird automatisch zu einem eigenständigen Fenster definiert, und lässt sich somit nicht in einem anderen Fenster einbetten.
2. Jedes Widget das ein ``wx.Window``
und kein ``TopLevelWindow`` hat, ist etwas das man nur in einem Fenster oder einem anderen "Panel" einbetten kann.
3. Mit wx.aui wird das ganz ein wenig konfus, da man "Panels" abdocken kann und sie dann wie Frames wirken. Davon bitte nicht irritieren lassen.
Nach der ganzen Theorie die Antwort zu deiner frage:
Der unterschied zwischen ``wx.aui.AuiMDIParentFrame`` und ``wx.aui.AuiNotebook`` ist der, das ``wx.aui.AuiNotebook`` kein ``TopLevelWindow`` in seiner Hierarchie dazwischen hat und somit zu etwas einbettbaren wird. Das ``wx.aui.AuiMDIParentFrame`` hat (denke ich mal da keine Doku dazu vorhanden) ein ``TopLevelWindow`` dazwischen (oder etwas äquivalentes) und kann nur als eigenständiges Fenster fungieren!
Aber, man kann in einer Instanz von ``wx.aui.AuiManager`` auch Frames hinzufügen,
aber sie werden nicht eingebettet und schweben frei rum, daher Sinnfrei...Davon wird aber strengstens abgeraten, da es (im Fall von ``wx.aui.AuiMDIParentFrame``) zum Absturz der Applikation kommen kann!
lg