| | |
Calling button-click events from different classes
Thread Solved |
Hi,
I am having a problem with function and class syntax.
I have one class (MakePanel1) that creates a button and label. The button-click event of the button is linked to a function (daclick1) that changes the text of the label. This works well.
I have another class (MakePanel2) that creates a second button. I want this second button to call the button-click function of the first button.
My incorrect call
How do I call the button-click function of button 1 whilst in the button-click function of button 2 ?
Any assistance appreciated. Thanks.
I am having a problem with function and class syntax.
I have one class (MakePanel1) that creates a button and label. The button-click event of the button is linked to a function (daclick1) that changes the text of the label. This works well.
I have another class (MakePanel2) that creates a second button. I want this second button to call the button-click function of the first button.
My incorrect call
MakePanel1.daclick1() whilst in the MakePanel2 class produces the error ' TypeError: unbound method daclick1() must be called with MakePanel1 instance as first argument (got nothing instead) '. Python Syntax (Toggle Plain Text)
#!/usr/bin/python import wx import time class MakePanel1(wx.Panel): def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.dalabel = wx.StaticText(self, -1, " panel 1 label ") self.dabutton1 = wx.Button(self, label="button 1") self.dabutton1.Bind(wx.EVT_BUTTON, self.daclick1 ) self.bs1 = wx.BoxSizer(wx.HORIZONTAL) self.bs1.Add(self.dabutton1,0) self.bs1.Add(self.dalabel,0) self.SetSizer(self.bs1) def daclick1(self, event): self.dalabel.SetLabel(str(time.time())) class MakePanel2(wx.Panel): def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.dabutton2 = wx.Button(self, label="button 2") self.dabutton2.Bind(wx.EVT_BUTTON, self.daclick2 ) self.bs2 = wx.BoxSizer(wx.HORIZONTAL) self.bs2.Add(self.dabutton2,0,wx.ALL,20) self.SetSizer(self.bs2) def daclick2(self, event): MakePanel1.daclick1() class DisFrame(wx.Frame): def __init__(self, *args, **kwargs): wx.Frame.__init__(self, *args, **kwargs) self.Panel1 = MakePanel1(self) self.Panel2 = MakePanel2(self) bs = wx.BoxSizer(wx.VERTICAL) bs.Add(self.Panel1,1,wx.EXPAND); bs.Add(self.Panel2,1,wx.EXPAND); self.SetSizer(bs) self.Fit() if __name__ == '__main__': app = wx.App() daframe = DisFrame(None) daframe.Show() app.MainLoop()
How do I call the button-click function of button 1 whilst in the button-click function of button 2 ?
Any assistance appreciated. Thanks.
Last edited by dunderhead; Sep 24th, 2006 at 12:58 am.
One solution to fix problem is to have MakePanel2 inherit MakePanel1, then you only need to create instance of MakePanel1 in MakePanel2. For some odd reason wx.BoxSizer() gets confused with the label location. Look the code over.
Python Syntax (Toggle Plain Text)
#!/usr/bin/python import wx import time class MakePanel1(wx.Panel): def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.dalabel = wx.StaticText(self, -1, " panel 1 label ") self.dabutton1 = wx.Button(self, label="button 1") self.dabutton1.Bind(wx.EVT_BUTTON, self.daclick1 ) self.bs1 = wx.BoxSizer(wx.HORIZONTAL) self.bs1.Add(self.dabutton1,0) self.bs1.Add(self.dalabel,0) self.SetSizer(self.bs1) def daclick1(self, event): self.dalabel.SetLabel(str(time.time())) class MakePanel2(MakePanel1): """Note that MakePanel2 inherits MakePanel1""" def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.dabutton2 = wx.Button(self, label="button 2") self.dabutton2.Bind(wx.EVT_BUTTON, self.daclick2 ) self.bs2 = wx.BoxSizer(wx.HORIZONTAL) self.bs2.Add(self.dabutton2,0,wx.ALL,20) self.SetSizer(self.bs2) def daclick2(self, event): #MakePanel1.daclick1() # gives error, need to make instance first self.Panel1 = MakePanel1(self) self.Panel1.daclick1(self) class DisFrame(wx.Frame): def __init__(self, *args, **kwargs): wx.Frame.__init__(self, *args, **kwargs) self.Panel1 = MakePanel1(self) self.Panel2 = MakePanel2(self) bs = wx.BoxSizer(wx.VERTICAL) bs.Add(self.Panel1,1,wx.EXPAND); bs.Add(self.Panel2,1,wx.EXPAND); self.SetSizer(bs) self.Fit() if __name__ == '__main__': app = wx.App() daframe = DisFrame(None) daframe.Show() app.MainLoop()
Thanks for the reply Bumsfeld.
Unfortunately your suggestion seems to create another panel on Panel2 (with a button and label), and this modification does not change the text of the label I wish to alter (on the first panel).
Even though I am a novice python user, I feel as though I must be able to call the button-click function of the first button through the button-click event of the second button using a proper syntax call.
I simply don't have a good understanding of how to access python objects and functions between classes.
Unfortunately your suggestion seems to create another panel on Panel2 (with a button and label), and this modification does not change the text of the label I wish to alter (on the first panel).
Even though I am a novice python user, I feel as though I must be able to call the button-click function of the first button through the button-click event of the second button using a proper syntax call.
I simply don't have a good understanding of how to access python objects and functions between classes.
Last edited by dunderhead; Sep 24th, 2006 at 1:25 pm.
Aha, now I see it! All you need to do is reference daclick1() properly! Forget the inherited solution.
Sorry, was sitting in my favorite internet bistro and got distracted by friends!
Python Syntax (Toggle Plain Text)
#!/usr/bin/python import wx import time class MakePanel1(wx.Panel): def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.dalabel = wx.StaticText(self, -1, " panel 1 label ") self.dabutton1 = wx.Button(self, label="button 1") self.dabutton1.Bind(wx.EVT_BUTTON, self.daclick1 ) self.bs1 = wx.BoxSizer(wx.HORIZONTAL) self.bs1.Add(self.dabutton1,0) self.bs1.Add(self.dalabel,0) self.SetSizer(self.bs1) def daclick1(self, event): self.dalabel.SetLabel(str(time.time())) class MakePanel2(wx.Panel): """Note that MakePanel2 inherits MakePanel1""" def __init__(self, Parent, *args, **kwargs): wx.Panel.__init__(self, Parent, *args, **kwargs) self.dabutton2 = wx.Button(self, label="button 2") self.dabutton2.Bind(wx.EVT_BUTTON, self.daclick2 ) self.bs2 = wx.BoxSizer(wx.HORIZONTAL) self.bs2.Add(self.dabutton2,0,wx.ALL,20) self.SetSizer(self.bs2) def daclick2(self, event): # reference daclick1() properly!!!!!!! daframe.Panel1.daclick1(self) class DisFrame(wx.Frame): def __init__(self, *args, **kwargs): wx.Frame.__init__(self, *args, **kwargs) self.Panel1 = MakePanel1(self) self.Panel2 = MakePanel2(self) bs = wx.BoxSizer(wx.VERTICAL) bs.Add(self.Panel1,1,wx.EXPAND); bs.Add(self.Panel2,1,wx.EXPAND); self.SetSizer(bs) self.Fit() if __name__ == '__main__': app = wx.App() daframe = DisFrame(None) daframe.Show() app.MainLoop()
Last edited by bumsfeld; Sep 24th, 2006 at 2:16 pm.
Many thanks Bumsfeld !
Your suggestion is perfect.
I was about to post the following solution before seeing your response:
My proposal is definitely less elegant than your solution.
Thanks again.
Your suggestion is perfect.
I was about to post the following solution before seeing your response:
Python Syntax (Toggle Plain Text)
MakePanel1.daclick1(daframe.Panel1,None)
Thanks again.
Last edited by dunderhead; Sep 25th, 2006 at 10:16 am.
•
•
Join Date: Jul 2006
Posts: 608
Reputation:
Solved Threads: 150
Right. Python does not allow the use of unbound methods like
MyClass.method()
Instead, it always requires
my_inst = MyClass()
my_inst.method()
The reason I got confused by these things is that we can do things like
import random
random.randint(5)
which appears to be an unbound method. However, it's actually just a function residing in the random module.
Jeff
MyClass.method()
Instead, it always requires
my_inst = MyClass()
my_inst.method()
The reason I got confused by these things is that we can do things like
import random
random.randint(5)
which appears to be an unbound method. However, it's actually just a function residing in the random module.
Jeff
Thanks Jeff.
Your explanation has helped to remove some confusion I've had about valid calling conventions.
I understand how your approach is required when accessing widgets created in a class - it seems logical that you need to create the widget first [ my_inst = MyClass() ] before attempting to access the widget in any way [ my_inst.method() ].
But what happens when a class consists only of functions without any creation of widgets ?
Does the call my_inst = MyClass() in such a case mean anything ?
Much appreciate your comments.
Your explanation has helped to remove some confusion I've had about valid calling conventions.
I understand how your approach is required when accessing widgets created in a class - it seems logical that you need to create the widget first [ my_inst = MyClass() ] before attempting to access the widget in any way [ my_inst.method() ].
But what happens when a class consists only of functions without any creation of widgets ?
Does the call my_inst = MyClass() in such a case mean anything ?
Much appreciate your comments.
Last edited by dunderhead; Sep 28th, 2006 at 12:44 am.
In the case of:
random is a module, and you are using the namespace random. Note that random is not a class!
To find out if an object is a class use something like this:
Generally, Python recommends to start class names with a Capital letter. This disinguishes them from module namespaces.
Here is a case where making an instance of an empty class means something:
In other words, you can create new class variables outside the class!
Python Syntax (Toggle Plain Text)
import random random.randint(5)
To find out if an object is a class use something like this:
Python Syntax (Toggle Plain Text)
import inspect if inspect.isclass(object_name): print "object_name is a class"
Generally, Python recommends to start class names with a Capital letter. This disinguishes them from module namespaces.
Here is a case where making an instance of an empty class means something:
Python Syntax (Toggle Plain Text)
class Employee: pass john = Employee() # Create an empty employee record/struct ted = Employee() # fill the fields of the record/struct john.name = 'John Johnson' john.dept = 'computer lab' john.salary = 3000 ted.name = 'Ted Tetris' ted.dept = 'human resources' ted.salary = 5000 print "%s works in the %s and earns $%s/month" % (john.name, john.dept, john.salary)
Last edited by Ene Uran; Sep 28th, 2006 at 2:43 pm.
drink her pretty
•
•
Join Date: Jul 2006
Posts: 608
Reputation:
Solved Threads: 150
•
•
•
•
I understand how your approach is required when accessing widgets created in a class - it seems logical that you need to create the widget first [ my_inst = MyClass() ] before attempting to access the widget in any way [ my_inst.method() ].
But what happens when a class consists only of functions without any creation of widgets ?
Does the call my_inst = MyClass() in such a case mean anything ?
[php]
class Test(object):
def this(self, arg):
print "my arg: ", arg
a = Test()
[/php]
We can now "look" at a as follows:
>>> a
<__main__.Test object at 0x00B83F50>
>>> a.this
<bound method Test.this of <__main__.Test object at 0x00B83F50>>
>>>
So a lives in memory, and a.this does, also. In other words, the object consists of nothing more or less than the 'this' method.
BTW, you can come close to an "unbound" method call like this:
[php]
>>> Test().this(4) # not quite Test.this(4), but close!
my arg: 4
[/php]
which creates an unassigned instance of Test(), calls its this method with arg = 4, and following the result, garbage-collects the Test() object out of existence. It probably runs slowly for large objects and/or many invocations, but it does work.
Jeff
![]() |
Other Threads in the Python Forum
- Previous Thread: Python Stat points...
- Next Thread: Python ISU
| Thread Tools | Search this Thread |
abrupt ansi anti apache approximation array assignment avogadro backend beginner binary bluetooth book builtin calculator character cmd converter countpasswordentry curved customdialog dan08 decimals dictionaries dictionary dynamic error exe file float format function gnu graphics heads homework http ideas import inches input java leftmouse library line lines linux list lists loop module mouse mysqlquery number numbers numeric output parsing path phonebook plugin pointer prime programming progressbar py2exe pygame python random recursion redirect scrolledtext software sqlite statictext statistics string strings sum table terminal text textarea thread threading time tlapse trick tuple tutorial twoup ubuntu unicode urllib urllib2 variable wordgame write wxpython xlib






