importierten Code überschreiben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
erde9
User
Beiträge: 7
Registriert: Dienstag 1. Juni 2021, 15:57

Hallo,
ich bin neu im Forum, die meine Suche war bisher vergeblich, vielleicht hat jemand einen Tip für mich.

Ich möchte mit Python (3.9) testweise eine Karteikartenanwendung erstellen, die ich unter Windows und Linux laufen lassen kann.

Als GUI habe ich mir den wxFormBuilder ausgekuckt, in den ersten Schritten komme ich damit auch gut zurecht.
An dem dort erzeugten py-Code könnte ich dann beliebig weiter arbeiten.

Damit ich trennen kann zwischen dem generierten Code und meine Ergänzungen habe ich mir folgenden ausgedacht, funktioniert auch:

Ich erstellte mir ein py Skript als Hauptscript, dort importiere ich mir mit

"from xxx (mein generierter Code) import xxxFrame" das generierte Frame

Anschließend enthält das Hauptscript die nötigen Codeergänzungen, damit das ganze Programm läuft.
Soweit funktioniert das auch super. Ändere ich etwas in der GUI, was anfangs häufig vorkommt, dann brauche ich dort nur den Python-Code neu zu generieren (Knopfdruck),
und schon habe ich im Hauptscript alles neu.

Problem dabei:
Im von Formbuilder generierten Code heißt es bei den erzeugten Events:
# Virtual event handlers, overide them in your derived class
Im möchte also im Hauptscript den Pseudohandler aus dem importierten Code ersetzen durch richtigen Code.
Nach 2 Tagen Suche und Ausprobieren habe ich jetzt als letzte Hoffnung das Forum.
Wie müsste konkret der Code im Hauptscript aussehen, der den Pseudo-Code ersetzt, oder geht das gar nicht, da ich ja mit einem importierten Frame arbeite.

Vielen Dank für Tips, wo es evtl. Beispiele gibt

mein Hauptscript:


import sys
import wx
import imp

from mnaBK import FrameMain #nicht den restlichen Rahmen, nur diesen Frame

..hier könnte der zusätzliche Code stehen, z.B. für folgendes Pseudo-Event:

def MenuBeendenOnMenuSelection(self, event):
#event.Skip()

class MainApp(wx.App):
def OnInit(self):
mainFrame = FrameMain(None)
mainFrame.Show(True)
return True

if __name__ == '__main__':
app = MainApp()
app.MainLoop()
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Der Hinweis in dem generierten Code birgt schon die Lösung: Du musst eine Klasse schreiben, die von der generierten Klasse erbt. Und in der überschreibst du die entsprechenden Events.
erde9
User
Beiträge: 7
Registriert: Dienstag 1. Juni 2021, 15:57

Danke für die schnelle Antwort,
ich hab das sicher schon in 10 verschiedenen Ausführungen versucht, es kommt auch keine Fehlermeldung, aber es funktioniert auch nicht, siehe Beispiel:

class Zusatz(FrameMain):
pass
#richtiger Code anstelle des importierten Pseudo-Codes:

def MenuBeendenOnMenuSelection(event):
self.Destroy()
#event.Skip()
pass

Was fehlt hier?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@erde9: Code-Tags im Beitrag damit man sehen kann wie der Quelltext tatsächlich aussieht.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

@erde9: Bitte zeig ein komplettes Beispiel, das zeigt, was nicht geht, und beschreiben, was du für ein Verhalten erwartest.

Und, wie __blackjack__ geschrieben hat: Bitte in Code-Tags, damit die Einrückung erhalten bleibt. Code-Tags erscheinen automatisch, wenn du den </> Button im vollständigen Editor drückst. Dazwischen gehört dein Code.
erde9
User
Beiträge: 7
Registriert: Dienstag 1. Juni 2021, 15:57

erstmal danke für die prompten Antworten.
Ich probiere das mit den Code-Tags:

so sieht der generierte Code aus, bezüglich Events, diese sind meiner Meinung nach Pseudo-Code, damit keine Fehlermeldung kommt:

Code: Alles auswählen

# -*- coding: utf-8 -*-

###########################################################################
## Python code generated with wxFormBuilder (version Dec 21 2016)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################

import wx
import wx.xrc

###########################################################################
## Class FrameMain
###########################################################################

class FrameMain ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"wxFormbuilder Widget Examples", pos = wx.DefaultPosition, size = wx.Size( 734,355 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )

        bSizerFrameMain = wx.BoxSizer( wx.VERTICAL )

        bSizerMainFrame = wx.BoxSizer( wx.VERTICAL )

        self.m_panelMain = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        self.m_panelMain.SetBackgroundColour( wx.Colour( 254, 240, 214 ) )

        bSizer8 = wx.BoxSizer( wx.VERTICAL )

        bSizer9 = wx.BoxSizer( wx.VERTICAL )

        bSizer14 = wx.BoxSizer( wx.VERTICAL )

        self.m_staticText6 = wx.StaticText( self.m_panelMain, wx.ID_ANY, u"       Überschrift", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.m_staticText6.Wrap( -1 )
        self.m_staticText6.SetFont( wx.Font( 16, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, "Arial" ) )

        bSizer14.Add( self.m_staticText6, 0, wx.ALL, 20 )

        self.m_staticline2 = wx.StaticLine( self.m_panelMain, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
        bSizer14.Add( self.m_staticline2, 0, wx.EXPAND |wx.ALL, 5 )


        bSizer9.Add( bSizer14, 0, wx.EXPAND, 0 )

        bSizer10 = wx.BoxSizer( wx.VERTICAL )

        bSizer11 = wx.BoxSizer( wx.HORIZONTAL )

        self.m_staticText3 = wx.StaticText( self.m_panelMain, wx.ID_ANY, u"Nummer", wx.DefaultPosition, wx.Size( 50,-1 ), 0 )
        self.m_staticText3.Wrap( -1 )
        bSizer11.Add( self.m_staticText3, 0, wx.ALL, 5 )

        self.m_Nummer = wx.TextCtrl( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 50,-1 ), 0 )
        bSizer11.Add( self.m_Nummer, 0, wx.ALL, 5 )

        self.m_staticText31 = wx.StaticText( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 150,-1 ), 0 )
        self.m_staticText31.Wrap( -1 )
        bSizer11.Add( self.m_staticText31, 0, wx.ALL, 0 )

        self.m_staticText311 = wx.StaticText( self.m_panelMain, wx.ID_ANY, u"PLZ", wx.DefaultPosition, wx.Size( 50,-1 ), 0 )
        self.m_staticText311.Wrap( -1 )
        bSizer11.Add( self.m_staticText311, 0, wx.ALL, 5 )

        self.m_PLZ = wx.TextCtrl( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer11.Add( self.m_PLZ, 0, wx.ALL, 5 )


        bSizer10.Add( bSizer11, 1, wx.ALL|wx.EXPAND, 0 )

        bSizer101 = wx.BoxSizer( wx.VERTICAL )

        bSizer111 = wx.BoxSizer( wx.HORIZONTAL )

        self.m_staticText32 = wx.StaticText( self.m_panelMain, wx.ID_ANY, u"Name", wx.DefaultPosition, wx.Size( 50,-1 ), 0 )
        self.m_staticText32.Wrap( -1 )
        bSizer111.Add( self.m_staticText32, 0, wx.ALL, 5 )

        self.m_Name = wx.TextCtrl( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 200,-1 ), 0 )
        bSizer111.Add( self.m_Name, 0, wx.ALL, 5 )

        self.m_staticText312 = wx.StaticText( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( -1,-1 ), 0 )
        self.m_staticText312.Wrap( -1 )
        bSizer111.Add( self.m_staticText312, 0, wx.ALL, 0 )

        self.m_staticText3111 = wx.StaticText( self.m_panelMain, wx.ID_ANY, u"Vorname", wx.DefaultPosition, wx.Size( 50,-1 ), 0 )
        self.m_staticText3111.Wrap( -1 )
        bSizer111.Add( self.m_staticText3111, 0, wx.ALL, 5 )

        self.m_Vorname = wx.TextCtrl( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 200,-1 ), 0 )
        bSizer111.Add( self.m_Vorname, 0, wx.ALL, 5 )


        bSizer101.Add( bSizer111, 1, wx.ALL|wx.EXPAND, 0 )


        bSizer10.Add( bSizer101, 1, wx.EXPAND, 5 )

        bSizer12 = wx.BoxSizer( wx.VERTICAL )

        bSizer13 = wx.BoxSizer( wx.HORIZONTAL )

        self.m_staticText4 = wx.StaticText( self.m_panelMain, wx.ID_ANY, u"Strasse", wx.DefaultPosition, wx.Size( 50,-1 ), 0 )
        self.m_staticText4.Wrap( -1 )
        bSizer13.Add( self.m_staticText4, 0, wx.ALL, 5 )

        self.mbutton4 = wx.Button( self.m_panelMain, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.mbutton4.Hide()

        bSizer13.Add( self.mbutton4, 0, wx.ALL, 5 )

        self.m_Strasse = wx.TextCtrl( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 200,-1 ), 0 )
        bSizer13.Add( self.m_Strasse, 0, wx.ALL, 5 )

        self.m_staticText41 = wx.StaticText( self.m_panelMain, wx.ID_ANY, u"Ort", wx.DefaultPosition, wx.Size( 50,-1 ), 0 )
        self.m_staticText41.Wrap( -1 )
        bSizer13.Add( self.m_staticText41, 0, wx.ALL, 5 )

        self.m_Ort = wx.TextCtrl( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 200,-1 ), 0 )
        bSizer13.Add( self.m_Ort, 0, wx.ALL, 5 )


        bSizer12.Add( bSizer13, 1, wx.EXPAND, 0 )

        self.m_staticline21 = wx.StaticLine( self.m_panelMain, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL )
        bSizer12.Add( self.m_staticline21, 0, wx.EXPAND |wx.ALL, 5 )


        bSizer10.Add( bSizer12, 0, wx.ALL|wx.EXPAND, 0 )

        bSizer16 = wx.BoxSizer( wx.HORIZONTAL )

        self.m_staticText20 = wx.StaticText( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 10,-1 ), 0 )
        self.m_staticText20.Wrap( -1 )
        bSizer16.Add( self.m_staticText20, 0, wx.ALL, 5 )

        self.mzurück = wx.Button( self.m_panelMain, wx.ID_ANY, u"zurück", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.mzurück.SetFont( wx.Font( 9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_BOLD, False, "Arial" ) )
        self.mzurück.SetBackgroundColour( wx.Colour( 255, 255, 0 ) )

        bSizer16.Add( self.mzurück, 0, wx.ALL, 5 )

        self.m_staticText201 = wx.StaticText( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 400,-1 ), 0 )
        self.m_staticText201.Wrap( -1 )
        bSizer16.Add( self.m_staticText201, 0, wx.ALL, 5 )

        self.mnext = wx.Button( self.m_panelMain, wx.ID_ANY, u"nächster", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.mnext.SetFont( wx.Font( 9, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_BOLD, False, "Arial" ) )
        self.mnext.SetBackgroundColour( wx.Colour( 255, 255, 0 ) )

        bSizer16.Add( self.mnext, 0, wx.ALL, 5 )


        bSizer10.Add( bSizer16, 1, wx.EXPAND, 5 )

        bSizer15 = wx.BoxSizer( wx.HORIZONTAL )

        self.m_staticText131 = wx.StaticText( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 150,-1 ), 0 )
        self.m_staticText131.Wrap( -1 )
        bSizer15.Add( self.m_staticText131, 0, wx.ALL, 0 )

        self.mSpeichern = wx.Button( self.m_panelMain, wx.ID_ANY, u"Speichern", wx.DefaultPosition, wx.DefaultSize, 0|wx.RAISED_BORDER )
        self.mSpeichern.SetBackgroundColour( wx.Colour( 21, 255, 80 ) )

        bSizer15.Add( self.mSpeichern, 0, wx.ALL, 10 )

        self.m_staticText13 = wx.StaticText( self.m_panelMain, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 100,-1 ), 0 )
        self.m_staticText13.Wrap( -1 )
        bSizer15.Add( self.m_staticText13, 0, wx.ALL, 0 )

        self.mAbbrechen = wx.Button( self.m_panelMain, wx.ID_ANY, u"Abbrechen", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.mAbbrechen.SetBackgroundColour( wx.Colour( 255, 0, 0 ) )

        bSizer15.Add( self.mAbbrechen, 0, wx.ALL, 10 )


        bSizer10.Add( bSizer15, 1, wx.EXPAND, 0 )


        bSizer9.Add( bSizer10, 0, wx.ALL, 0 )


        bSizer8.Add( bSizer9, 1, wx.ALL|wx.EXPAND, 0 )


        self.m_panelMain.SetSizer( bSizer8 )
        self.m_panelMain.Layout()
        bSizer8.Fit( self.m_panelMain )
        bSizerMainFrame.Add( self.m_panelMain, 1, wx.EXPAND |wx.ALL, 0 )


        bSizerFrameMain.Add( bSizerMainFrame, 1, wx.ALL|wx.EXPAND, 0 )


        self.SetSizer( bSizerFrameMain )
        self.Layout()
        self.menubarMain = wx.MenuBar( 0 )
        self.menufile = wx.Menu()
        self.menuItemFileNew = wx.MenuItem( self.menufile, wx.ID_ANY, u"Neu"+ u"\t" + u"Ctrl+N", wx.EmptyString, wx.ITEM_NORMAL )
        self.menufile.AppendItem( self.menuItemFileNew )

        self.menuItemFileOpen = wx.MenuItem( self.menufile, wx.ID_ANY, u"Öffnen"+ u"\t" + u"Ctrl+O", wx.EmptyString, wx.ITEM_NORMAL )
        self.menufile.AppendItem( self.menuItemFileOpen )

        self.menufile.AppendSeparator()

        self.MenuBeenden = wx.MenuItem( self.menufile, wx.ID_ANY, u"Beenden", wx.EmptyString, wx.ITEM_NORMAL )
        self.menufile.AppendItem( self.MenuBeenden )

        self.menubarMain.Append( self.menufile, u"Datei" )

        self.menueEdit = wx.Menu()
        self.m_menuItem13 = wx.MenuItem( self.menueEdit, wx.ID_ANY, u"Bearb Zeile1"+ u"\t" + u"Ctrl+B", wx.EmptyString, wx.ITEM_NORMAL )
        self.menueEdit.AppendItem( self.m_menuItem13 )

        self.menubarMain.Append( self.menueEdit, u"Bearbeiten" )

        self.menueHelp = wx.Menu()
        self.menubarMain.Append( self.menueHelp, u"Hilfe" )

        self.SetMenuBar( self.menubarMain )


        self.Centre( wx.BOTH )

        # Connect Events
        self.mAbbrechen.Bind( wx.EVT_BUTTON, self.m_AbbrechenOnButtonClick )
        self.mAbbrechen.Bind( wx.EVT_ENTER_WINDOW, self.m_AbbrechenOnEnterWindow )
        self.mAbbrechen.Bind( wx.EVT_LEAVE_WINDOW, self.m_AbbrechenOnLeaveWindow )
        self.Bind( wx.EVT_MENU, self.FileNewOnMenuSelection, id = self.menuItemFileNew.GetId() )
        self.Bind( wx.EVT_MENU, self.menuItemFileOpenOnMenuSelection, id = self.menuItemFileOpen.GetId() )
        self.Bind( wx.EVT_MENU, self.MenuBeendenOnMenuSelection, id = self.MenuBeenden.GetId() )

    def __del__( self ):
        pass


    # Virtual event handlers, overide them in your derived class
    def m_AbbrechenOnButtonClick( self, event ):
       event.Skip()

    def m_AbbrechenOnEnterWindow( self, event ):
        event.Skip()

    def m_AbbrechenOnLeaveWindow( self, event ):
        event.Skip()

    def FileNewOnMenuSelection( self, event ):
        event.Skip()

    def menuItemFileOpenOnMenuSelection( self, event ):
        event.Skip()

    def MenuBeendenOnMenuSelection( self, event ):
        event.Skip()



jetzt möchte ich konkret das Programm beenden, wenn im Menü der entsprechende Eintrag angewählt wird,
dazu muss ich den Event überschreiben. Das möchte ich aber in dem Script machen, das den generierten Code importiert,
einer meiner vielen Code-Versuche sieht so aus (neue Klasse "Zusatz"), der hier programmierte Code wird aber nicht ausgeführt,
sprich, das Programm wird nicht beendet. Füge ich das direkt in den generierten Code ein, da funktioniert alles.

mein Haupt-Script mit der neuen Klasse "Zusatz":

Ich habe in der Doku von wxpython bezüglich Event-Handel auch gefunden, dass ein Überschreiben eines Events gar keine neue Klasse braucht, hilft aber auch nicht

Code: Alles auswählen

#

import sys
import wx
import imp


from mnaBK import FrameMain  #nicht den restlichen Rahmen, nur diesen Frame
# Modul neu laden
# imp.reload(mna)

class Zusatz(FrameMain):
    pass
#richtiger Code anstelle des importierten Pseudo-Codes:

    def MenuBeendenOnMenuSelection(event):
        self.Destroy()
        #event.Skip()
        pass


class MainApp(wx.App):
    def OnInit(self):
        mainFrame = FrameMain(None)
        mainFrame.Show(True)
        return True

if __name__ == '__main__':
    app = MainApp()
    app.MainLoop()
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Was denkst du, was "pass" tut? Pass ist ein Platzhalter, den man verwendet, um dem Parser mitzuteilen, dass die Funktion oder Klasse keinen Rumpf hat - also leer ist. Das ist hier aber nirgends so. Alle "pass" können also weg.

Ruf __init__ der Elternklasse auf, wenn du erbst.

Dann vesuchst du eine Methode zu überschreiben. Das ist der richtige Weg, denke ich - ohne in den letzten Jahren mit wx gearbeitet zu habe.
Ich sehe allerdings einen deutlichen Unterschied in der Parameterliste der Methode, die du überschreibst und die in deiner eigenen Klasse.

Dann solltest du vernünfite Namen verwenden. Was ist denn "Zusatz"? Vom Namen her zumindest nicht zu erkennen.
Und: Du vewendest "Zusatz" nicht in deinem Code. Du hast zwar die Klasse "Zusatz", die von "FrameMain" erbt - aber du verwendest "FrameMain" in der GUI - nicht "Zusatz".
erde9
User
Beiträge: 7
Registriert: Dienstag 1. Juni 2021, 15:57

danke, vielleicht komme ich der Sache näher´.

Ich hab die "pass" alle entfernt.
Was in der GUI passiert bzw dort generiert wird, wird einfach importiert.

Die Definition des EventHandlers aus der generierten GUI mit zwei Parametern habe ich kopiert in mein Hauptscript,
allerdings ist mir nicht klar, ob dieParameter "(self, event)" weiterhin so stimmen

Code: Alles auswählen

class Zusatz(FrameMain):

    def MenuBeendenOnMenuSelection(self, event):
        self.Destroy()
        event.Skip()
Für mich bleibt weiterhin die Frage:
Wenn ich zum Überschreiben von Events der Elternklasse im Hauptscript eine abgeleitete Klasse brauche, die vom GUI "FrameMain" erbt,
wie muss diese genau definiert sein, (ob die jetzt "Zusatz" heisst oder irgendwie sei dahingestellt).


sorry - mit Ruf __init__ der Elternklasse kann ich bei meinem derzeitigen Kenntnisstand leider noch nichts konkretes anfangen. Da steckt sicher viel Spezialwissen dahinter.

Schon mal vielen Dank im Voraus
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Du musst dich mit Objektorientierter Programmieren im allgemeinen und mit Klassen in Python im speziellen beschäftigen. Du rätst Code. Das funktioniert nicht.
"Zusatz" bleibt nichtssagend.

Ungetestet

Code: Alles auswählen

class Frame(FrameMain):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def MenuBeendenOnMenuSelection(self, event):
        self.Destroy()
Hier ist noch anzumerken, dass die Namensgebung sich an der Namensgebung von wxPython orientiert.
Das solltest du dir außerhalb von wxPython nicht angewöhnen.
Variablen und Funktionen schreibt man in Python eigentlich klein_mit_unterstrich, Klassenname PascalCase (das ist hier so).
erde9
User
Beiträge: 7
Registriert: Dienstag 1. Juni 2021, 15:57

vielen Dank.

Ich hab es mit deinem Code ausprobiert, aber auch jetzt verhält sich das Programm wie bei meinen Versuchen.

Die Überschreibung funktioniert nicht, d.h. es wird bei der Anwahl des Menüpunktes "Beenden" nichts ausgelöst.

Nur wenn man das "self.Destroy" direkt in den generierten Code einfügt funktioniert das Programm wie gewünscht.

Für mich heißt das, dass für eine Überschreibung von Funktionen noch mehr außenherum nötig ist (z.B. import von ..) usw.
Grundsätzlich sollte wxpython das ganz elegant machen, gemäß Doku wäre hierfür nicht mal eine Klassendefinition nötig.

Bezüglich Schreibweise von Variablen und Funktionen:
Ich sehe das auch so. Da es sich hier aber um generierten Code handelt, ist ist das halt so erzeugt worden.

Ich bedanke mich ganz herzlich für Deine Mühe und breche das Experiment mit dem Import von Code mit Überschreiben von Events an dieser Stelle ab.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Du könntst auch einfach den verwendeten Code zeigen und wir schauen, warum es nicht funktioniert. Denn ohne, dass man weiß, was du tust, kann man den Fehler auch nicht eingrenzen.

Dein Schlussfolgerung ist auf jeden Fall nicht richtig. Man braucht keine zusätzlichen Importe oder ähnliches.

Und wenn du in der Dokumentation gesehen hast, wie es geht (also ohne Klassendefinition), warum machst du es dann nicht wie dort beschrieben?
Wie gesagt, mein letztes mal wxPython ist viele Jahre her. Aber wenn irgendwo steht, dass man etwas in einer abgeleiteteten Klasse überschreiben soll, dann würde ich das genau so tun.
erde9
User
Beiträge: 7
Registriert: Dienstag 1. Juni 2021, 15:57

Code-Beispiel 1: genau so, wie du vorgeschlagen hast
# Versuch, mit Import mny.py zu laden
#

import sys
import wx
import imp


from mnaBK import FrameMain #nicht den restlichen Rahmen, nur diesen Frame
# Modul neu laden
# imp.reload(mna)


class Frame(FrameMain):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def MenuBeendenOnMenuSelection(self, event):
self.Destroy()

class MainApp(wx.App):
def OnInit(self):
mainFrame = FrameMain(None)
mainFrame.Show(True)
return True


if __name__ == '__main__':
app = MainApp()
app.MainLoop()
in der wxpython Doku habe ich bezüglic Dynamic Event-Handling folgendes gefunden:
Let us now look at more examples of how to use different event handlers using the two overloads of Bind() function: first one for the object methods and the other one for arbitrary functors (callable objects, including simple functions).

In addition to using a method of the object generating the event itself, you can use a method from a completely different object as an event handler:

def OnFrameExit(event):
# Do something useful.
pass

class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)

# Other initialization code...

self.Bind(wx.EVT_MENU, OnFrameExit, id=wx.ID_EXIT)

Note that MyFrameHandler doesn’t need to derive from wx.EvtHandler.
Beispiel 2: angelehnt an obiges, habe ich die Event-Definition, die die ursprüngliche überladen soll, einfach in mein Haupt-Script eingefügt,
Ergebnis ist dasselbe - Code wird nicht ausgeführt
# Versuch, mit Import mny.py zu laden
#

import sys
import wx
import imp


from mnaBK import FrameMain #nicht den restlichen Rahmen, nur diesen Frame
# Modul neu laden
# imp.reload(mna)




def MenuBeendenOnMenuSelection(event):
self.Destroy()
event.skip()


class MainApp(wx.App):
def OnInit(self):
mainFrame = FrameMain(None)
mainFrame.Show(True)
return True


if __name__ == '__main__':
app = MainApp()
app.MainLoop()
Das Verhalten ist in beiden Beispielen gleich:
ein Überladen findet nicht statt, das "Destroy" wird nicht ausgeführt
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Aber du _benutzt_ doch in Codebeispiel 1 die Klasse "Frame" gar nicht. Wie soll die denn etwas bewirken?

Wenn alle deine Fahrräder einen Platten haben, du auf das gelbe Luft pumpst und dann mit dem roten los fährst, dann hat das rote noch immer einen Platten.

Du bindest eine Instanz von "FrameMain" an den namen "mainFrame". Aber "Frame" verwendest du nirgends. In "FrameMain" gibt es aber keine "überschriebenen Dinge" - die sind in Frame. es muss also mainFrame=Frame(None) heißen. Auch das habe ich oben erwähnt.

Einen guten Einstieg in die Programmierung mit Python bietet das offizielle Tutorial.
Und wenn es mit der GUI weiter gehen soll, dann musst du dich mit Klassen in Python und mit Objektorientierter Programmierung auseinandersetzen. Aber das habe ich dir bereits gesagt.
erde9
User
Beiträge: 7
Registriert: Dienstag 1. Juni 2021, 15:57

danke nochmal, ich hab inzwischen (auch mit deiner Hilfe) das Problem gelöst:

ganz einfach: in der Definition der MainApp Klasse muss ich natürlich die abgeleitete Klasse aufrufen, und nicht die Ursprungsklasse.

Code:

Code: Alles auswählen

# Versuch, generierten Code zu laden und zu ergänzen
#

import sys
import wx
import imp


from mnaBK import FrameMain  ## aus dem  GUI-Code nur den erzeugten Frame-Code importieren

class OrgFrame(FrameMain):  ##erbt den importieren Code (vom GUI-Generator)
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    #Überschreiben des Codes aus der importieren Klasse:
    def MenuBeendenOnMenuSelection(self, event):
        self.Destroy()


##Grund-Code, damit die GUI läuft:

class MainApp(wx.App):
    def OnInit(self):

        mainFrame = OrgFrame(None) ##Aufruf der abgeleiteten Klasse
        mainFrame.Show(True)
        return True


if __name__ == '__main__':
    app = MainApp()
    app.MainLoop()


Antworten