Alex Gisi
Alex Gisi

Reputation: 93

Error when attempting to call function from button in wxpython

As a beginner in wxpthon, I'm creating a simple login script that creates two buttons: one to open a window for the user to create an account, and one for them to register an account. My relevant code is:

 yesbutton = wx.Button(panel, label="Yes,  I wish to log in", pos=(50,150), size=(150,60))
    self.Bind(wx.EVT_BUTTON, Login.login(Login), yesbutton)


 nobutton = wx.Button(panel, label="No,  I wish to register", pos=(270,150), size=(150,60))
    self.Bind(wx.EVT_BUTTON, Register.register(Register), nobutton)


class Login:


    def login(self):
        print("login")


class Register:

    def register(self):
        print("register")

However when I run this code i get:

TypeError: unbound method login() must be called with Login instance as first argument (got classobj instance instead)

I've looked a lot for this answer, but I can't make any solutions work. Thanks in advance.

Upvotes: 1

Views: 305

Answers (3)

dpdwilson
dpdwilson

Reputation: 1007

Your functions Login.login() and Register.register() take no arguments, but you're passing the Login and Register classes into them. Your second line should instead be:

self.Bind(wx.EVT_BUTTON, Login.login, yesbutton)

You don't need the parentheses after Login.login in this case since it's within the Bind function. Similarly adjust your other binding.

Edit: You also need to instantiate a Login object and a Register object before calling anything from those classes. Unfortunately I don't have access to wxPython at the moment and can't test it, but try this:

Edit 2: This will also pass the event into the function, so make sure the functions you are calling account for this.

yesbutton = wx.Button(panel, label="Yes,  I wish to log in", pos=(50,150), size=(150,60))
log = Login()
self.Bind(wx.EVT_BUTTON, log.login, yesbutton)


nobutton = wx.Button(panel, label="No,  I wish to register", pos=(270,150), size=(150,60))
reg = Register()
self.Bind(wx.EVT_BUTTON, reg.register, nobutton)


class Login:

    def login(self, evt):
        print("login")

class Register:

    def register(self, evt):
        print("register")

Upvotes: 3

sawyermclane
sawyermclane

Reputation: 1086

When you use the bind function, the second parameter where you pass your function is called the "handler". By default, the only thing that is passed to this function is a wx Event. The correct syntax for doing this (using your code) would be

self.Bind(wx.EVT_BUTTON, Login.login, yesbutton)

For future reference, if you want to call a function that does not take an event as a parameter on an Event, do this:

self.Bind(wx.EVT_BUTTON, lambda event: Login.login(), yesbutton)

Upvotes: 0

muddyfish
muddyfish

Reputation: 3660

Have you tried using the lambda function in doing this?

eg: self.Bind(wx.EVT_BUTTON, lambda: <INSTANCE OF LOGIN>.login(), yesbutton)

You would do the same thing for rthe register command

Upvotes: 0

Related Questions