Calling button-click events from different classes

Thread Solved

Join Date: Sep 2006
Posts: 20
Reputation: dunderhead is an unknown quantity at this point 
Solved Threads: 0
dunderhead's Avatar
dunderhead dunderhead is offline Offline
Newbie Poster

Calling button-click events from different classes

 
0
  #1
Sep 24th, 2006
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 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) '.

  1. #!/usr/bin/python
  2.  
  3.  
  4. import wx
  5. import time
  6.  
  7.  
  8. class MakePanel1(wx.Panel):
  9. def __init__(self, Parent, *args, **kwargs):
  10. wx.Panel.__init__(self, Parent, *args, **kwargs)
  11.  
  12. self.dalabel = wx.StaticText(self, -1, " panel 1 label ")
  13. self.dabutton1 = wx.Button(self, label="button 1")
  14. self.dabutton1.Bind(wx.EVT_BUTTON, self.daclick1 )
  15. self.bs1 = wx.BoxSizer(wx.HORIZONTAL)
  16. self.bs1.Add(self.dabutton1,0)
  17. self.bs1.Add(self.dalabel,0)
  18. self.SetSizer(self.bs1)
  19.  
  20. def daclick1(self, event):
  21. self.dalabel.SetLabel(str(time.time()))
  22.  
  23.  
  24. class MakePanel2(wx.Panel):
  25. def __init__(self, Parent, *args, **kwargs):
  26. wx.Panel.__init__(self, Parent, *args, **kwargs)
  27.  
  28. self.dabutton2 = wx.Button(self, label="button 2")
  29. self.dabutton2.Bind(wx.EVT_BUTTON, self.daclick2 )
  30. self.bs2 = wx.BoxSizer(wx.HORIZONTAL)
  31. self.bs2.Add(self.dabutton2,0,wx.ALL,20)
  32. self.SetSizer(self.bs2)
  33.  
  34. def daclick2(self, event):
  35. MakePanel1.daclick1()
  36.  
  37. class DisFrame(wx.Frame):
  38. def __init__(self, *args, **kwargs):
  39. wx.Frame.__init__(self, *args, **kwargs)
  40.  
  41. self.Panel1 = MakePanel1(self)
  42. self.Panel2 = MakePanel2(self)
  43.  
  44. bs = wx.BoxSizer(wx.VERTICAL)
  45. bs.Add(self.Panel1,1,wx.EXPAND);
  46. bs.Add(self.Panel2,1,wx.EXPAND);
  47.  
  48. self.SetSizer(bs)
  49. self.Fit()
  50.  
  51.  
  52. if __name__ == '__main__':
  53. app = wx.App()
  54. daframe = DisFrame(None)
  55. daframe.Show()
  56. 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.
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Calling button-click events from different classes

 
0
  #2
Sep 24th, 2006
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.
  1. #!/usr/bin/python
  2.  
  3.  
  4. import wx
  5. import time
  6.  
  7.  
  8. class MakePanel1(wx.Panel):
  9. def __init__(self, Parent, *args, **kwargs):
  10. wx.Panel.__init__(self, Parent, *args, **kwargs)
  11.  
  12. self.dalabel = wx.StaticText(self, -1, " panel 1 label ")
  13. self.dabutton1 = wx.Button(self, label="button 1")
  14. self.dabutton1.Bind(wx.EVT_BUTTON, self.daclick1 )
  15. self.bs1 = wx.BoxSizer(wx.HORIZONTAL)
  16. self.bs1.Add(self.dabutton1,0)
  17. self.bs1.Add(self.dalabel,0)
  18. self.SetSizer(self.bs1)
  19.  
  20. def daclick1(self, event):
  21. self.dalabel.SetLabel(str(time.time()))
  22.  
  23.  
  24. class MakePanel2(MakePanel1):
  25. """Note that MakePanel2 inherits MakePanel1"""
  26. def __init__(self, Parent, *args, **kwargs):
  27. wx.Panel.__init__(self, Parent, *args, **kwargs)
  28.  
  29. self.dabutton2 = wx.Button(self, label="button 2")
  30. self.dabutton2.Bind(wx.EVT_BUTTON, self.daclick2 )
  31. self.bs2 = wx.BoxSizer(wx.HORIZONTAL)
  32. self.bs2.Add(self.dabutton2,0,wx.ALL,20)
  33. self.SetSizer(self.bs2)
  34.  
  35. def daclick2(self, event):
  36. #MakePanel1.daclick1() # gives error, need to make instance first
  37. self.Panel1 = MakePanel1(self)
  38. self.Panel1.daclick1(self)
  39.  
  40. class DisFrame(wx.Frame):
  41. def __init__(self, *args, **kwargs):
  42. wx.Frame.__init__(self, *args, **kwargs)
  43.  
  44. self.Panel1 = MakePanel1(self)
  45. self.Panel2 = MakePanel2(self)
  46.  
  47. bs = wx.BoxSizer(wx.VERTICAL)
  48. bs.Add(self.Panel1,1,wx.EXPAND);
  49. bs.Add(self.Panel2,1,wx.EXPAND);
  50.  
  51. self.SetSizer(bs)
  52. self.Fit()
  53.  
  54.  
  55. if __name__ == '__main__':
  56. app = wx.App()
  57. daframe = DisFrame(None)
  58. daframe.Show()
  59. app.MainLoop()
Reply With Quote Quick reply to this message  
Join Date: Sep 2006
Posts: 20
Reputation: dunderhead is an unknown quantity at this point 
Solved Threads: 0
dunderhead's Avatar
dunderhead dunderhead is offline Offline
Newbie Poster

Re: Calling button-click events from different classes

 
0
  #3
Sep 24th, 2006
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.
Last edited by dunderhead; Sep 24th, 2006 at 1:25 pm.
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Calling button-click events from different classes

 
0
  #4
Sep 24th, 2006
Aha, now I see it! All you need to do is reference daclick1() properly! Forget the inherited solution.
  1. #!/usr/bin/python
  2.  
  3.  
  4. import wx
  5. import time
  6.  
  7.  
  8. class MakePanel1(wx.Panel):
  9. def __init__(self, Parent, *args, **kwargs):
  10. wx.Panel.__init__(self, Parent, *args, **kwargs)
  11.  
  12. self.dalabel = wx.StaticText(self, -1, " panel 1 label ")
  13. self.dabutton1 = wx.Button(self, label="button 1")
  14. self.dabutton1.Bind(wx.EVT_BUTTON, self.daclick1 )
  15. self.bs1 = wx.BoxSizer(wx.HORIZONTAL)
  16. self.bs1.Add(self.dabutton1,0)
  17. self.bs1.Add(self.dalabel,0)
  18. self.SetSizer(self.bs1)
  19.  
  20. def daclick1(self, event):
  21. self.dalabel.SetLabel(str(time.time()))
  22.  
  23.  
  24. class MakePanel2(wx.Panel):
  25. """Note that MakePanel2 inherits MakePanel1"""
  26. def __init__(self, Parent, *args, **kwargs):
  27. wx.Panel.__init__(self, Parent, *args, **kwargs)
  28.  
  29. self.dabutton2 = wx.Button(self, label="button 2")
  30. self.dabutton2.Bind(wx.EVT_BUTTON, self.daclick2 )
  31. self.bs2 = wx.BoxSizer(wx.HORIZONTAL)
  32. self.bs2.Add(self.dabutton2,0,wx.ALL,20)
  33. self.SetSizer(self.bs2)
  34.  
  35. def daclick2(self, event):
  36. # reference daclick1() properly!!!!!!!
  37. daframe.Panel1.daclick1(self)
  38.  
  39. class DisFrame(wx.Frame):
  40. def __init__(self, *args, **kwargs):
  41. wx.Frame.__init__(self, *args, **kwargs)
  42.  
  43. self.Panel1 = MakePanel1(self)
  44. self.Panel2 = MakePanel2(self)
  45.  
  46. bs = wx.BoxSizer(wx.VERTICAL)
  47. bs.Add(self.Panel1,1,wx.EXPAND);
  48. bs.Add(self.Panel2,1,wx.EXPAND);
  49.  
  50. self.SetSizer(bs)
  51. self.Fit()
  52.  
  53.  
  54. if __name__ == '__main__':
  55. app = wx.App()
  56. daframe = DisFrame(None)
  57. daframe.Show()
  58. app.MainLoop()
Sorry, was sitting in my favorite internet bistro and got distracted by friends!
Last edited by bumsfeld; Sep 24th, 2006 at 2:16 pm.
Reply With Quote Quick reply to this message  
Join Date: Sep 2006
Posts: 20
Reputation: dunderhead is an unknown quantity at this point 
Solved Threads: 0
dunderhead's Avatar
dunderhead dunderhead is offline Offline
Newbie Poster

Re: Calling button-click events from different classes

 
0
  #5
Sep 25th, 2006
Many thanks Bumsfeld !

Your suggestion is perfect.

I was about to post the following solution before seeing your response:

  1. MakePanel1.daclick1(daframe.Panel1,None)
My proposal is definitely less elegant than your solution.

Thanks again.
Last edited by dunderhead; Sep 25th, 2006 at 10:16 am.
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: Calling button-click events from different classes

 
0
  #6
Sep 27th, 2006
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
Reply With Quote Quick reply to this message  
Join Date: Sep 2006
Posts: 20
Reputation: dunderhead is an unknown quantity at this point 
Solved Threads: 0
dunderhead's Avatar
dunderhead dunderhead is offline Offline
Newbie Poster

Re: Calling button-click events from different classes

 
0
  #7
Sep 28th, 2006
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.
Last edited by dunderhead; Sep 28th, 2006 at 12:44 am.
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 1,514
Reputation: Ene Uran has a spectacular aura about Ene Uran has a spectacular aura about 
Solved Threads: 168
Ene Uran's Avatar
Ene Uran Ene Uran is offline Offline
Posting Virtuoso

Re: Calling button-click events from different classes

 
0
  #8
Sep 28th, 2006
In the case of:
  1. import random
  2. random.randint(5)
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:
  1. import inspect
  2. if inspect.isclass(object_name):
  3. 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:
  1. class Employee:
  2. pass
  3.  
  4.  
  5. john = Employee() # Create an empty employee record/struct
  6. ted = Employee()
  7.  
  8. # fill the fields of the record/struct
  9. john.name = 'John Johnson'
  10. john.dept = 'computer lab'
  11. john.salary = 3000
  12.  
  13. ted.name = 'Ted Tetris'
  14. ted.dept = 'human resources'
  15. ted.salary = 5000
  16.  
  17. print "%s works in the %s and earns $%s/month" % (john.name, john.dept, john.salary)
In other words, you can create new class variables outside the class!
Last edited by Ene Uran; Sep 28th, 2006 at 2:43 pm.
drink her pretty
Reply With Quote Quick reply to this message  
Join Date: Sep 2006
Posts: 20
Reputation: dunderhead is an unknown quantity at this point 
Solved Threads: 0
dunderhead's Avatar
dunderhead dunderhead is offline Offline
Newbie Poster

Re: Calling button-click events from different classes

 
0
  #9
Sep 28th, 2006
Thanks Ene Uran. Your post is very informative.
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: Calling button-click events from different classes

 
0
  #10
Sep 28th, 2006
Originally Posted by dunderhead View Post

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 ?
Indeed it does. Here's an example:

[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
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Other Threads in the Python Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC