Seite 1 von 1

Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 13:08
von B-Baer
Hallo,

ich habe gerade Folgendes Problem.
Ich habe die Klasse MyFrame und MyPanel.
In MyFrame lege ich ein Objekt von MyPanel an.

Nun möchte ich von diesem Objekt xPanel (MyPanel) auf
die Funktion "something" von MyFrame zugreifen.
Kann mir jemand sagen wie ich das bewerkstelligen kann, bzw. wie der Konstruktor von MyPanel abzuwandeln ist?
(Irgendwie bekomme ich das mit wx nicht hin :cry: )

Code: Alles auswählen

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):        
        xPanel = MyPanel(self.notebook)
        
    def something(self):
        pass
    
class MyPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        pass
    
    def callsomething(self):
        ???
Danke !

Re: Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 13:16
von Dav1d
Das ist kein wxPython-Problem ;)

Code: Alles auswählen

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):       
        xPanel = MyPanel(self.notebook, self)
       
    def something(self):
        pass
   
class MyPanel(wx.Panel):
    def __init__(self, parent_frame, *args, **kwds):
        self.parent_frame = parent_frame
   
    def callsomething(self):
        self.parent_frame.something()
Dir ist aber klar, dass dein Panel nicht initialisiert wurde?

Re: Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 13:18
von cofi
Das hoert sich nach einer Reichlichlich Schlechten Idee™ an.

Was ist denn dein eigentliches Ziel?

Der Vollstaendigkeit halber: Im Prinzip reicht, wenn du das Objekt `self.something` uebergibt, sollte das nicht reichen, muss eben ein `lambda: return self.something()` herhalten.

Aber: Erzaehl uns mal was du eigtl vorhast.

Re: Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 13:58
von B-Baer
Dav1d hat geschrieben:Das ist kein wxPython-Problem ;)

Code: Alles auswählen

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):       
        xPanel = MyPanel(self.notebook, self)
       
    def something(self):
        pass
   
class MyPanel(wx.Panel):
    def __init__(self, parent_frame, *args, **kwds):
        self.parent_frame = parent_frame
   
    def callsomething(self):
        self.parent_frame.something()
Dir ist aber klar, dass dein Panel nicht initialisiert wurde?

So hatte ich mir das auch erst gedacht...
mein Panel ist wie folgt initialisiert.

Code: Alles auswählen

    def __init__(self, parent_frame, *args, **kwds):
        kwds["style"] = wx.TAB_TRAVERSAL
        wx.Panel.__init__(self, *args, **kwds)
        self.parent_frame = parent_frame
leider bekomme ich aber folgenden Fehler:
return _controls_.BookCtrlBase_AddPage(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "pPage->GetParent() == this" failed at ..\..\src\msw\notebook.cpp(771) in wxNotebook::InsertPage(): notebook pages must have notebook as parent
14:53:29: Debug: ..\..\include\wx/msw/private.h(697): 'UnregisterClass' failed with error 0x00000584 (diese Klasse hat noch geöffnete Fenster.).

Re: Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 14:03
von BlackJack
@B-Baer: Ist denn in `args` als erstes *auch* das Elternwidget enthalten!? Denn das möchte die `wx.Panel.__init__()` da ja gerne haben.

Re: Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 14:05
von ntrunk
@B-Baer: Du übergibst deinem Panel als Parent den Frame. In ein Notebook kannst du allerdings nur Panels einhängen, die das Notebook als Parent haben. (Das hat Dav1d wohl übersehen)
Du müßtest dem Panel zusätzlich zum Frame auch noch das Notebook übergeben und das Panel dann mit diesem Notebook initialisieren?!

Ich kann allerdings cofi (auch aus der Erfahrung mit eigenen Projekten :oops:) nur zustimmen:
sowas deutet auf einen, vorsichtig ausgedrückt, suboptimalen Entwurf hin und sollte höchstens bei klitzekleinen Quick-and-Dirty - Sachen eingesetzt werden. Ansonsten läuft man schnell in Gefahr, verworrenen Code zu produzieren, den kein Mensch (man selber eingeschlossen) jemals wieder versteht, sobald er das erste Mal vergessen wurde...
Wenn du dein Programm aus dem Grund schreibst, um Python und wxPython zu lernen, solltest du deshalb dein Programmdesign überdenken.

Eine mögliche Ausnahme ist allerdings, wenn du ein Control entwickelst und möchtest der großen, weiten Welt Mitteilungen machen. Dafür nimmt man dann aber keine durchgereichten Objektverweise oder Callbacks, sondern Events. Dann ist die Frage hier sogar OnTopic :wink:
Deshalb hier ein Minimalbeispiel (basiert auf einem Tutorial, Quelle habe ich nicht mehr, das ich gekürzt habe):

Code: Alles auswählen

#!/usr/bin/env python

import wx
import wx.lib.newevent

# Eventklasse und Eventbinder erzeugen
MyEvent,EVT_MYEVENT = wx.lib.newevent.NewEvent()

class MyPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        wx.Panel.__init__(self, *args, **kwargs)
        self.Bind(wx.EVT_LEFT_DOWN, self. on_left_down)
    def on_left_down(self, e):
        # Event erzeugen, das Panel als Ausloeser setzen und abschicken
        evt = MyEvent()
        evt.SetEventObject(self)
        self.ProcessEvent(evt)

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.wnd = MyPanel(self)
        self.wnd.Bind(EVT_MYEVENT, self.on_myevent)
    def on_myevent(self, e):
        wx.MessageBox('MyEvent angekommen!')

app = wx.App()
frm = MyFrame(None)
frm.Show()
app.MainLoop()

Re: Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 14:21
von B-Baer
@ntrunk vielen Dank für deine Antwort :D
Es geht in der Tat um eine Art Controler.
Um das Ganze runter zu brechen. Der Frame besitzt eine Notebook mit x Pages,
über die Erste Page möchte ich das "Erscheinen" der weiteren Pages verändern... (ein / ausblenden, etc..)
Zudem sind daran DB Opperationen angekoppelt, die auch noch gesteuert werden müssen.
Ich werde die Event Geschichte mal aufgreifen :-)

Re: Zugriff auf Klassenfunktionen

Verfasst: Freitag 13. August 2010, 16:35
von Dav1d
wx.lib.pubsub ist auch einen Blick wert