Zugriff auf Klassenfunktionen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
B-Baer
User
Beiträge: 23
Registriert: Donnerstag 5. August 2010, 11:56

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 !
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

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?
the more they change the more they stay the same
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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.
B-Baer
User
Beiträge: 23
Registriert: Donnerstag 5. August 2010, 11:56

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.).
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.
ntrunk
User
Beiträge: 83
Registriert: Sonntag 7. September 2008, 23:09
Wohnort: Buchen (Odenwald)

@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()
B-Baer
User
Beiträge: 23
Registriert: Donnerstag 5. August 2010, 11:56

@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 :-)
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

wx.lib.pubsub ist auch einen Blick wert
the more they change the more they stay the same
Antworten