style-Parameter tanzt aus der Reihe...

Plattformunabhängige GUIs mit wxWidgets.
Antworten
mutetella
User
Beiträge: 1690
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Donnerstag 23. April 2009, 15:24

Hallo,

ich bastle gerade an einer wx.Frame-Klasse mit folgender Kopfzeile:

Code: Alles auswählen

class Frame(wx.Frame):
    
    def __init__(self, parent=None, id=-1, title='', pos=(), style=0):
        print 'Frame __init__'
        wx.Frame.__init__(self, parent, id, title, pos, style)
Wenn ich die Klasse mit

Code: Alles auswählen

self.frame = Frame(parent=None, id=-1, title='EventUs', pos=(150,150), style=wx.DEFAULT_FRAME_STYLE ^ (wx.CLOSE_BOX))
aufrufen möchte, erscheint folgende Fehlermeldung:
  • Traceback (most recent call last):
    File "wxKalP.py", line 32, in <module>
    app = App(redirect=True, filename='/home/claus/Desktop/err')
    File "wxKalP.py", line 17, in __init__
    wx.App.__init__(self, redirect, filename)
    File "/usr/lib/python2.5/site-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 7912, in __init__
    self._BootstrapApp()
    File "/usr/lib/python2.5/site-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 7487, in _BootstrapApp
    return _core_.PyApp__BootstrapApp(*args, **kwargs)
    File "wxKalP.py", line 21, in OnInit
    self.frame = Frame(parent=None, id=-1, title='EventUs', pos=(150,150), style=wx.DEFAULT_FRAME_STYLE ^ (wx.CLOSE_BOX))
    File "wxKalP.py", line 11, in __init__
    wx.Frame.__init__(self, parent, id, title, pos, style)
    File "/usr/lib/python2.5/site-packages/wx-2.8-gtk2-unicode/wx/_windows.py", line 497, in __init__
    _windows_.Frame_swiginit(self,_windows_.new_Frame(*args, **kwargs))
    TypeError: Expected a 2-tuple of integers or a wxSize object.
Lasse ich den style-Parameter sowohl in der Klasse als auch beim Aufruf derselben weg, funktioniert alles prächtig...

Warum verhält sich der style-Parameter anderst als die anderen???

Danke schon mal für Eure Hilfe!!

Liebe Grüße
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 23. April 2009, 16:06

mutetella hat geschrieben:

Code: Alles auswählen

        wx.Frame.__init__(self, parent, id, title, pos, style)
Hallo mutetella!

Du übergibst die Parameter an die __init__-Methode nicht in der korrekten Reihenfolge. Siehe:

Code: Alles auswählen

>>> import wx
>>> help(wx.Frame.__init__)
Help on method __init__ in module wx._windows:

__init__(self, *args, **kwargs) unbound wx._windows.Frame method
    __init__(self, Window parent, int id=-1, String title=EmptyString, 
        Point pos=DefaultPosition, Size size=DefaultSize, 
        long style=DEFAULT_FRAME_STYLE, String name=FrameNameStr) -> Frame

>>> 
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
pcos
User
Beiträge: 16
Registriert: Dienstag 3. April 2007, 14:21

Donnerstag 23. April 2009, 16:13

Hallo,

die Signatur von wx.Frame.__init__ ist (s. wxPython new docs)

Code: Alles auswählen

 __init__(self, parent, id, title, pos, size, style, name) 
Du übergibst also style, wo die size erwartet wird.

Code: Alles auswählen

wx.Frame.__init__(self, parent, id, title, pos, style=style) 
sollte in Deinem Beispiel funktionieren. Ich habe mir angewöhnt, bei den "langen" Funktionen in wx immer alle Parameter zu benennen (außer parent), das ist auch später hilfreich, wenn man sich den Code ansieht (kommt jetzt zuerst die size oder die pos...)

Der default-style von Frame (wx.DEFAULT_FRAME_STYLE) ist übrigens nicht 0, ich weiß nicht ob Deine Klasse absichtlich einen anderen Wert hat. Ein leeres Tupel für die pos ist auch nicht so gut, das wird von wx.Frame.__init__ nicht akzeptiert (glaube ich, kann's gerade nicht ausprobieren).
mutetella
User
Beiträge: 1690
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Donnerstag 23. April 2009, 19:14

Hallo und vielen Dank für die schnellen Antworten... :D

Der Hinweis auf die Signatur von wx.Frame.__init__ hat mir die Lösung gebracht. Es ist wohl so, dass die falsche Reihenfolge der Parameterliste 'schuld' war...

Allerdings ist die Reihenfolge nur im Konstruktor von wx.Frame(), nicht im Konstruktor der Subklasse Frame(wx.Frame) entscheidend. Dort und auch bei der Instanziierung ist es egal, in welcher Folge die Parameter angegeben sind.

Folgendes funktioniert also:

Code: Alles auswählen

class Frame(wx.Frame):
    
    def __init__(self, pos=(), parent=None, title='', id=-1, style=0, size=()):
        wx.Frame.__init__(self, parent, id, title, pos, size, style)
Instanziierung:

Code: Alles auswählen

self.frame = Frame(parent=None, id=-1, size=(100,100), title='EventUs', pos=(150,150), style=wx.DEFAULT_FRAME_STYLE ^ (wx.CLOSE_BOX))
Ok, ich gebe zu, das ist sehr schlampig und unübersichtlich, mir ging es aber einfach mal wieder ums Prinzip. Ich habe nämlich vor ein paar Tagen in "Objektorientierte Programmierung mit Python" gelesen, dass die Parameterübergabe mittels Schlüsselwortargumenten gegenüber der Übergabe über Positionsargumente den Vorteil hat, dass die Reihenfolge nicht zwingend eingehalten werden muss.

Nun weiß ich, dass das stimmt, sofern die Reihenfolge der Parameter bei der Übergabe an die Hauptklasse eingehalten wird.

@pcos: Deinen Tipp, bei umfangreichen Parameterangaben immer alle Parameter zu benennen finde ich einleuchtend, werde ich künftig auch so machen. style=0 als default hab ich nur gewählt, damit irgend ein gültiger Wert (type(wx.DEFAULT_FRAME_STYLE)='INT') als default-Einstellung steht und ich nicht so viel tippen muss... :-)


Danke nochmals, das hat mir jetzt echt sehr weitergeholfen...

Liebe Grüße
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten