By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,772 Members | 906 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,772 IT Pros & Developers. It's quick & easy.

Combined event handling on Tkinkter

P: 26
Hey

I am making a GUI Program in Tkinter and am running into problems.What I want to do is draw 2 checkboxes and a button. According to the user input next steps should take place. A part of my code has been shown below :-
Expand|Select|Wrap|Line Numbers
  1. CheckVar1 = IntVar()
  2. CheckVar2 = IntVar()
  3. self.C1 = Checkbutton(root, text = "C Classifier", variable = CheckVar1, onvalue = 1, offvalue = 0, height=5,width = 20).grid(row=4)
  4.  
  5. self.C2 = Checkbutton(root, text = "GClassifier", variable = CheckVar2, onvalue = 1,    offvalue = 0, height=5, width = 20).grid(row=5)
  6.  
  7. self.proceed1 = Button(root,text = "\n Proceed",command =       self.proceed(CheckVar1.get(),CheckVar2.get())).grid(row=6)
  8.  
  9. # where proceed prints the combined values of 2 checkboxes
  10.  
  11.  
The error that I am getting is typical ie a default value of both the selected checkboxes gets printed up and then there is no further input. The error that I get is NullType Object is not callable.

I searched on the net and I think the answer is related to lambda events or curry.

Please help ..
Nov 13 '10 #1
Share this Question
Share on Google+
16 Replies


Expert 100+
P: 621
You just call the function without the args. You can access self.* variable anywhere in the program so passing them is not necessary, but I can't tell much else from this snippet. Note also the difference between the output of these two lines (why are they different?).
Expand|Select|Wrap|Line Numbers
  1. self.proceed1 = Button(root,text = "\n Proceed",command =self.proceed).grid(row=6)
  2. #
  3. self.proceed2 = Button(root,text = "\n Proceed",command =self.proceed)
  4. self.proceed2.grid(row=6)
  5. #
  6. print self.proceed1
  7. print self.proceed2 
Nov 13 '10 #2

Expert 100+
P: 621
Sorry, I left out that you want to make the variables members of the class so they can be accessed anywhere.
Expand|Select|Wrap|Line Numbers
  1. self.CheckVar1 = IntVar()
  2. self.CheckVar2 = IntVar() 
Nov 13 '10 #3

P: 26
Expand|Select|Wrap|Line Numbers
  1. class NextScreen():
  2.  
  3.         def __init__(self,root,val):
  4.                 self.CheckVar1 = IntVar()
  5.                 self.CheckVar2 = IntVar()
  6.                 self.label = Label(root,text = " \n Click on what do you wish to do \n ").grid(row = 0)
  7.                 self.calculate = Button(root,text = "CALCULATE THE THRESHOLDS").grid(row = 1,column = 0)
  8.                 self.printed = Button(root,text = "PRINT THE RESULTS").grid(row = 1,column = 1)
  9.                 self.space = Label(root , text = "\n Also select the classifier").grid(row = 3)
  10.                 self.C1 = Checkbutton(root, text = "C Classifier", variable = CheckVar1, onvalue = 1, offvalue = 0, height=5,width = 20).grid(row=4)
  11.                 self.C2 = Checkbutton(root, text = "GClassifier", variable = CheckVar2, onvalue = 1, offvalue = 0, height=5, width = 20).grid(row=5)
  12.                 self.proceed1 = Button(root,text = "\n Proceed",command = self.proceed()).grid(row=6)
  13.                 self.menu = self.makeMenuBar(root)
  14.         def proceed(self):
  15.                 val1 = self.CheckVar1.get()
  16.                 val2 = self.CheckVar2.get()
  17.  
  18.  
Here I get the error that CheckVar1 needs to be global.
I am nt understanding what is wrong in here.....
Nov 14 '10 #4

Expert 100+
P: 621
No way to tell without the complete error message and line number. A quick check shows that you did not change this line or the following line
self.C1 = Checkbutton(root, text = "C Classifier", variable = CheckVar1, onvalue = 1, offvalue = 0, height=5,width = 20).grid(row=4)
also it should be
Button(root,text = "\n Proceed",command = self.proceed) <-- no parens
to call the function when the mouse is released.
Nov 14 '10 #5

P: 26
Hey , I got my mistake which was that in checkbox command the variable should be self.CheckVar1. But I have ran into problems. I wanted 2 checkboxes and a button which would print individual boxes values. The code is shown below but I can't figure out what I am doing wrong.

Expand|Select|Wrap|Line Numbers
  1.  def __init__(self,root):
  2.                 self.CheckVar1 = IntVar()
  3.                 self.CheckVar2 = IntVar()
  4.                 self.C1 = Checkbutton(root, text = "C Classifier", variable = self.CheckVar1, height=5,width = 20)
  5.                 self.C1.grid(row=4)
  6.                 self.C2 = Checkbutton(root, text = "GClassifier", variable = self.CheckVar2, height=5, width = 20)
  7.                 self.C2.grid(row=5)
  8.                 self.proceed1 = Button(root,text = "\n Proceed",command = self.proceed)
  9.                 self.proceed1.grid(row=6)
  10. def proceed(self):
  11.                 val1 = self.CheckVar1.get()
  12.                 val2 = self.CheckVar2.get()
  13.                 print val1,val2
  14.  
I thought that I would get mixtures of 0 and 1 corresponding to whether they are selected or not . But all I am getting is 0 and 0.
Nov 14 '10 #6

bvdet
Expert Mod 2.5K+
P: 2,851
It seems to work properly. In the following test script, Checkbutton 1 is initially set to on. When the Button is clicked, the output is "1 0" as expected.
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2.  
  3. class Test:
  4.     def __init__(self,root):
  5.         self.CheckVar1 = IntVar()
  6.         self.CheckVar2 = IntVar()
  7.         self.C1 = Checkbutton(root, text="C Classifier", variable=self.CheckVar1, height=5,width=20)
  8.         self.C1.grid(row=4)
  9.         self.C2 = Checkbutton(root, text="G Classifier", variable=self.CheckVar2, height=5, width=20)
  10.         self.C2.grid(row=5)
  11.         self.proceed1 = Button(root,text="\n Proceed",command=self.proceed)
  12.         self.proceed1.grid(row=6)
  13.         self.C1.invoke()
  14.     def proceed(self):
  15.         val1 = self.CheckVar1.get()
  16.         val2 = self.CheckVar2.get()
  17.         print val1,val2
  18.  
  19. if __name__ == "__main__":
  20.     root = Tk()
  21.     app = Test(root)
  22.     root.mainloop()
Nov 14 '10 #7

P: 26
Hey I am not understanding what is wrong with my code.
What I do I am telling you in comments and not code.

I copy the above Test class as it is
Expand|Select|Wrap|Line Numbers
  1. class Test:
  2.     ....
  3.     ....
  4. class test:
  5.     def __init__(self,root):
  6.            ....
  7.     def change(self):
  8.            if(a==1): # any checking condition
  9.                root.destroy()
  10.                t1 = Tk()
  11.                App = Test(t1)
  12.                t1.mainloop()
  13. start = Tk()
  14. New = test(start)
  15. start.mainloop()
  16.  
The above code for Test class written by bvdet works fine but when I add this into my class as shown the checkboxes only show 0. I don't understand why??
Nov 16 '10 #8

bvdet
Expert Mod 2.5K+
P: 2,851
It would help us help you if you would post complete code, or at least enough code to run without external dependencies, so we can test it without having to complete the code for testing ourselves.
Nov 18 '10 #9

P: 26
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2.  
  3. class NextScreen():
  4.         def __init__(self,root):
  5.                 self.Check1 = IntVar()
  6.                 self.Check2 = IntVar()
  7.                 self.space = Label(root , text = "\n Also select the classifier").grid(row = 0)
  8.                 self.C1 = Checkbutton(root, text = "C", variable = self.Check1,offvalue=5,onvalue = 1, height=5,width = 20)
  9.                 self.C1.grid(row=1)
  10.                 self.C2 = Checkbutton(root, text = "G", variable = self.Check2,offvalue=0,onvalue =1, height=5, width = 20)
  11.                 self.C2.grid(row=2)
  12.                 self.C1.invoke()
  13.                 self.button = Button(root,text = "Proceed",command = self.proceed)
  14.                 self.button.grid(row=3)
  15.                 #print self.Check1.get(),self.Check2.get()
  16.  
  17.         def proceed(self):
  18.                 print self.Check1.get(),self.Check2.get()
  19.  
  20.  
  21.  
  22.  
  23. class Screen():
  24.  
  25.         def __init__(self,root):
  26.                 var = IntVar()
  27.                 self.label = Label(root,text = " \n Welcome \n ").pack()
  28.                 self.radio1 = Radiobutton(root, value=1,indicatoron=False,text="Face",variable=var,command= lambda : self.select(root,var.get())).pack()
  29.  
  30.                 self.radio3 = Radiobutton(root, value=2,indicatoron=False,text="FFinger",variable=var,command=lambda : self.select(root,var.get())).pack()
  31.  
  32.         def select(self,root,value):
  33.                 root.withdraw()
  34.                 if(value==1):
  35.  
  36.                         Face = Tk()
  37.                         Face.title("Face and Face NIST Database ")
  38.                         App = NextScreen(Face)
  39.                         Face.geometry("400x400")
  40.                         Face.resizable(1,1)
  41.                         Face.mainloop()
  42.                 else:
  43.                         if(value==2):
  44.  
  45.                                 Face_Fin = Tk()
  46.                                 Face_Fin.title("Face and Finger NIST Database ")
  47.                                 App = NextScreen(Face_Fin)
  48.                                 Face_Fin.geometry("400x400")
  49.                                 Face_Fin.resizable(1,1)
  50.                                 Face_Fin.mainloop()
  51.  
  52. if __name__ == "__main__":
  53.         root = Tk()
  54.         root.title('Fusion in Multibiometrics')
  55.         App = Screen(root)
  56.         root.geometry("260x220")
  57.         root.resizable(1,1)
  58.         root.mainloop()
  59.  
  60.  
Here I want that different combination of 1 and 0 should be printed for different selection of checkboxes
Nov 18 '10 #10

Expert 100+
P: 621
There are two possible problems. You'll have to test for yourself to see if either or both are the problem. One is using both pack() and grid(), which every tutorial AFAIK says you can't do. The second is multiple instances of Tk, which no one does so the outcome is not known, since no one does it. Part of the offending code follows, modified so as to use better techniques.
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2.  
  3. class NextScreen():
  4.         def __init__(self,root2, title_in):
  5.                 root2.title(title_in)
  6.                 root.geometry("250x300")
  7.                 self.Check1 = IntVar()
  8.                 self.Check2 = IntVar()
  9.                 self.screen_frame = Frame(root)
  10.                 self.screen_frame.pack()
  11.                 self.space = Label(self.screen_frame , text = "\n Also select the classifier").pack()
  12.                 self.C1 = Checkbutton(self.screen_frame, text = "C", variable = self.Check1, height=5,width = 20)
  13.                 self.C1.pack()
  14.                 self.C2 = Checkbutton(self.screen_frame, text = "G", variable = self.Check2, height=5, width = 20)
  15.                 self.C2.pack()
  16.                 self.C1.invoke()
  17.                 self.button = Button(self.screen_frame,text = "Proceed",command = self.proceed)
  18.                 self.button.pack()
  19.                 self.exit = Button(self.screen_frame, text="Exit", command=root.quit)
  20.                 self.exit.pack()
  21.  
  22.         def proceed(self):
  23.                 print self.Check1.get(),self.Check2.get()
  24.  
  25.  
  26. class Screen():
  27.  
  28.     def __init__(self,root):
  29.         self.root = root
  30.         self.screen_frame = Frame(self.root)
  31.         self.screen_frame.pack()
  32.         var = IntVar()
  33.         self.label = Label(self.screen_frame,text = " \n Welcome \n ")
  34.         self.radio1 = Radiobutton(self.screen_frame, value=1,indicatoron=False,text="Face",variable=var,command= lambda : self.select(var.get()))
  35.         self.radio3 = Radiobutton(self.screen_frame, value=2,indicatoron=False,text="FFinger",variable=var,command=lambda : self.select(var.get()))
  36.         self.label.pack()
  37.         self.radio1.pack()
  38.         self.radio3.pack()
  39.  
  40.     def select(self,value):
  41.         self.screen_frame.destroy()
  42.         if(value==1):
  43.             App = NextScreen(self.root, "Face and Face NIST Database ")
  44.  
  45. if __name__ == "__main__":
  46.         root = Tk()
  47.         root.title('Fusion in Multibiometrics')
  48.         App = Screen(root)
  49.         root.resizable(1,1)
  50.         root.mainloop() 
Nov 21 '10 #11

P: 26
Hey ,

Thanks for replying ....

I understood what you are saying but unfortunately the code that you modified isn't working. The value in select always gets 0 . I don't know that also why is it happening...

Thanks a lot for answering though...
Nov 21 '10 #12

Expert 100+
P: 621
You have to click the "Proceed" button. The values will then print in the terminal window. Zero for off and one for on, depending on whether the checkbox is checked. Although I have no idea if you are running from a terminal or IDE, or which version of Python you are using, but it works fine on my Slackware system running in xterm, and getting it to work properly on my computer is all that I can do. You had this same problem in the previous post, so the problem is possibly your Python installation or OS which we obviously can not help with.
Nov 21 '10 #13

P: 26
I am sorry but I can't get it how you are getting the output.

The value in select is always 0 and never turns 1 .
Also when I write (value == 0 ) in place of 1 and click on proceed subsequently the only output is 0, 0
Nov 21 '10 #14

bvdet
Expert Mod 2.5K+
P: 2,851
The value in select() can only be 1 or 2 because the method is called by pushing one of the buttons. IntVar object var is initially set to 0, but becomes 1 or 2 on a button invocation.
Nov 22 '10 #15

Expert 100+
P: 621
Changing the code Again (mock sigh). It must be in the way you are running the program, so two labels have been added which show the button's IntVar on the left hand side and will show zero or one depending on whether it is checked, and will change as the button's state changes. Why you can not get them to print is a mystery.
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2.  
  3. class NextScreen():
  4.         def __init__(self,root2, title_in):
  5.                 root2.title(title_in)
  6.                 root.geometry("250x300")
  7.                 self.Check1 = IntVar()
  8.                 self.Check2 = IntVar()
  9.                 self.screen_frame = Frame(root)
  10.                 self.screen_frame.pack()
  11.                 self.space = Label(self.screen_frame , text = "\n Also select the classifier").pack()
  12.                 label_1 = Label(self.screen_frame, textvariable=self.Check1)
  13.                 label_1.pack(side="left")
  14.                 self.C1 = Checkbutton(self.screen_frame, text = "C", variable = self.Check1, height=5,width = 20)
  15.                 self.C1.pack(side="right")
  16.  
  17.                 screen_frame_2 = Frame(root)
  18.                 screen_frame_2.pack()
  19.                 label_2 = Label(screen_frame_2, textvariable=self.Check2)
  20.                 label_2.pack(side="left")
  21.                 self.C2 = Checkbutton(screen_frame_2, text = "G", variable = self.Check2, height=5, width = 20)
  22.                 self.C2.pack(side="right")
  23.                 self.C1.invoke()
  24.  
  25.                 button_frame = Frame(root)
  26.                 self.button = Button(button_frame,text = "Proceed",command = self.proceed)
  27.                 self.button.pack()
  28.                 self.exit = Button(button_frame, text="Exit", command=root.quit)
  29.                 self.exit.pack(side="right")
  30.                 button_frame.pack()
  31.  
  32.         def proceed(self):
  33.                 print self.Check1.get(),self.Check2.get()
  34.  
  35.  
  36. class Screen():
  37.  
  38.     def __init__(self,root):
  39.         self.root = root
  40.         self.screen_frame = Frame(self.root)
  41.         self.screen_frame.pack()
  42.         var = IntVar()
  43.         self.label = Label(self.screen_frame,text = " \n Welcome \n ")
  44.         self.radio1 = Radiobutton(self.screen_frame, value=1,indicatoron=False,text="Face",variable=var,command= lambda : self.select(var.get()))
  45.         self.radio3 = Radiobutton(self.screen_frame, value=2,indicatoron=False,text="FFinger",variable=var,command=lambda : self.select(var.get()))
  46.         self.label.pack()
  47.         self.radio1.pack()
  48.         self.radio3.pack()
  49.  
  50.     def select(self,value):
  51.         self.screen_frame.destroy()
  52.         App = NextScreen(self.root, "Face and Face NIST Database ")
  53.  
  54. if __name__ == "__main__":
  55.         root = Tk()
  56.         root.title('Fusion in Multibiometrics')
  57.         App = Screen(root)
  58.         root.resizable(1,1)
  59.         root.mainloop() 
Nov 23 '10 #16

Expert 100+
P: 621
So does the label at least work correctly now?
Nov 24 '10 #17

Post your reply

Sign in to post your reply or Sign up for a free account.