wx.Dialog: TypeError

Plattformunabhängige GUIs mit wxWidgets.
Antworten
BaseBallBatBoy
User
Beiträge: 15
Registriert: Mittwoch 18. April 2007, 13:21

ich will über ein menu einen eigenen dialog öffnen und da per button und textfeld eingaben machen.
so wies im moment ist, kommt auch der dialog, aber sobald ich den button drücke oder beim textfeld enter kommt die meldung:

TypeError: unbound method OnAddName() must be called with MyFrame instance as first argument (got CommandEvent instance instead)

könnt ihr mir sagen, wo ich da den fehler mache?

Code: Alles auswählen

class MyDialog(wx.Dialog):
    def __init__(self, parent, id, title, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE):

        wx.Dialog.__init__(self, parent, id, title = title, style = style) 

        pre = wx.PreDialog()
        pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
        pre.Create(parent, id, title, pos, size, style)
        self.PostCreate(pre)
        
        self.lbl_name = wx.StaticText(self, 1, "Name")
        self.txt_name = wx.TextCtrl(self, 2, '', style=wx.TE_PROCESS_ENTER)

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        comSizer = wx.GridBagSizer(vgap=5, hgap=5)
        
        
        comSizer.Add(self.lbl_name, pos=(0,0), flag=wx.EXPAND)
        comSizer.Add(self.txt_name, pos=(0,1), flag=wx.EXPAND)

        mainSizer.Add(comSizer, 0, wx.EXPAND|wx.ALL, 5)
        self.SetSizer(mainSizer)
        self.SetAutoLayout(True)
        mainSizer.Fit(self)

        self.txt_name.Bind(wx.EVT_TEXT_ENTER, MyFrame.OnAddName, id=2)


class MyFrame(wx.Frame):
    #main function
    def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=(500, 400)):
        self.name = ""
        
        #create a simple windows frame
        wx.Frame.__init__(self, parent, id, title, pos, size)
        
        #crate a menumar at the top of the frame ----------------------------
        menubar = wx.MenuBar()
        #create menus
        file = wx.Menu()
        
        #add an menuitem with an icon to a menu
        m_name = wx.MenuItem(file, 100, "&Enter Name", "Dialog to enter a Name")
        file.AppendItem(m_name)
        #bind the menu event to an event handler
        self.Bind(wx.EVT_MENU, self.OnOpenDialog, id=100)

        menubar.Append(file, '&File')
        self.SetMenuBar(menubar)


    def OnOpenDialog(self, event):
        dlg = MyDialog(self, -1, "Enter Settings", size=(500, 500), style = wx.DEFAULT_DIALOG_STYLE)
        dlg.CenterOnScreen()

        # this does not return until the dialog is closed.
        val = dlg.ShowModal()
    
        if val == wx.ID_OK:
            print "You pressed OK\n"
        else:
            print "You pressed Cancel\n"

        dlg.Destroy()


    def OnAddName(self, event):
        self.name = self.txt_name.GetValue()
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi BBBB!

Bitte versuche beim nächsten Mal, funktionierenden/ausführbaren Beispielcode hier ins Forum zu stellen, der dein Problem demonstriert. Das erleichtert die Fehlersuche erheblich. Dann muss man nicht selber ein funktionierendes Gerüst bauen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BaseBallBatBoy
User
Beiträge: 15
Registriert: Mittwoch 18. April 2007, 13:21

gerold hat geschrieben:Hi BBBB!
funktionierenden/ausführbaren Beispielcode

Code: Alles auswählen

import wx, re, os, time, thread, stat, base64, logging, logging.config, xml.etree.ElementTree as ET

wx.SetDefaultPyEncoding("UTF-8")

class MyDialog(wx.Dialog): 
    def __init__(self, parent, id, title, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE): 

        wx.Dialog.__init__(self, parent, id, title = title, style = style) 

        pre = wx.PreDialog() 
        pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) 
        pre.Create(parent, id, title, pos, size, style) 
        self.PostCreate(pre) 
        
        self.lbl_name = wx.StaticText(self, 1, "Name") 
        self.txt_name = wx.TextCtrl(self, 2, '', style=wx.TE_PROCESS_ENTER) 

        mainSizer = wx.BoxSizer(wx.VERTICAL) 
        comSizer = wx.GridBagSizer(vgap=5, hgap=5) 
        
        
        comSizer.Add(self.lbl_name, pos=(0,0), flag=wx.EXPAND) 
        comSizer.Add(self.txt_name, pos=(0,1), flag=wx.EXPAND) 

        mainSizer.Add(comSizer, 0, wx.EXPAND|wx.ALL, 5) 
        self.SetSizer(mainSizer) 
        self.SetAutoLayout(True) 
        mainSizer.Fit(self) 

        self.txt_name.Bind(wx.EVT_TEXT_ENTER, MyFrame.OnAddName, id=2) 


class MyFrame(wx.Frame): 
    #main function 
    def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=(500, 400)): 
        self.name = "" 
        
        #create a simple windows frame 
        wx.Frame.__init__(self, parent, id, title, pos, size) 
        
        #crate a menumar at the top of the frame ---------------------------- 
        menubar = wx.MenuBar() 
        #create menus 
        file = wx.Menu() 
        
        #add an menuitem with an icon to a menu 
        m_name = wx.MenuItem(file, 100, "&Enter Name", "Dialog to enter a Name") 
        file.AppendItem(m_name) 
        #bind the menu event to an event handler 
        self.Bind(wx.EVT_MENU, self.OnOpenDialog, id=100) 

        menubar.Append(file, '&File') 
        self.SetMenuBar(menubar) 


    def OnOpenDialog(self, event): 
        dlg = MyDialog(self, -1, "Enter Name", size=(200, 200), style = wx.DEFAULT_DIALOG_STYLE) 
        dlg.CenterOnScreen() 

        # this does not return until the dialog is closed. 
        val = dlg.ShowModal() 
    
        if val == wx.ID_OK: 
            print "You pressed OK\n" 
        else: 
            print "You pressed Cancel\n" 

        dlg.Destroy() 


    def OnAddName(self, event): 
        self.name = self.txt_name.GetValue() 
        
        

#application class
class MyApp(wx.App):
    def OnInit(self):
        #create a new frame
        frame = MyFrame(None, -1, "wxpython")
        self.SetTopWindow(frame)
        frame.Show(True)
        return True


#start the application
if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi BBBB!

Kurze Antwort:

Damit

Code: Alles auswählen

self.txt_name.Bind(wx.EVT_TEXT_ENTER, MyFrame.OnAddName, id=2)
versuchst du auf eine Methode einer anderen Klasse (nicht Instanz) zuzugreifen. Dann versuchst du auch noch in der Methode auf ein Feld einer anderen Klasseninstanz zuzugreifen. Alles in Allem --> Kann nicht funktionieren und es lässt sich auch nicht in einem Satz erklären, was alles nicht so funktioniert.

Fazit: Greife innerhalb einer Klasseninstanz nur auf Methoden dieser Klasseninstanz zu. Dann machst du nichts falsch. Wenn du schon auf andere Klasseninstanzen zugreifen möchtest, dann solltest du das über eigene Funktionen machen, die du dann auf irgendeine Form übergeben kannst.

Ich habe jetzt keine Zeit mehr für eine bessere Erklärung oder ein funktionierendes Beispiel.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten