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

Tkinter Button Commands are Called Only at Startup?

P: 7
I am trying to use Tkinter to build a simple GUI app which imports data and performs some analysis. The GUI has just four labels and four buttons side by side. When you press the button, you should get a File Dialog prompt. However, whenever I run the script (see below), Python calls all button commands at startup, and then the buttons don't work afterwards. Even if I write the code without a class, the same thing happens. How do I get it to stop doing this? Thanks!

Expand|Select|Wrap|Line Numbers
  1. import numpy
  2. import scipy
  3.  
  4. from Tkinter import *
  5. import tkFileDialog as tkf
  6.  
  7. filenames = {}
  8.  
  9. class App:
  10.     def __init__(self, master):
  11.  
  12.             frame = Frame(master)
  13.             frame.pack()
  14.  
  15.             self.Name0 = Label(frame, text = "Initial Data", width=30).grid(row=0, sticky=W,columnspan=2)
  16.             self.Name1 = Label(frame, text = "After Change #1", width=30).grid(row=1, sticky= W,columnspan=2)
  17.             self.Name2 = Label(frame, text = "After Change #2", width=30).grid(row=2,sticky=W,columnspan=2)
  18.             self.Name3 = Label(frame, text = "Current State", width=30).grid(row=3,sticky=W,columnspan=2)
  19.  
  20.             self.Butt0 = Button(frame, text = "Select", command=tkf.askopenfile()).grid(row=0,column=2)
  21.             self.Butt1 = Button(frame, text = "Select", command=tkf.askopenfile()).grid(row=1,column=2)
  22.             self.Butt2 = Button(frame, text = "Select", command=tkf.askopenfile()).grid(row=2,column=2)
  23.             self.Butt3 = Button(frame, text = "Select", command=tkf.askopenfile()).grid(row=3,column=2)
  24.  
  25.  
  26. root = Tk()
  27.  
  28. app = App(root)
  29.  
  30. root.mainloop()
  31.  
Feb 15 '12 #1
Share this Question
Share on Google+
4 Replies

Expert 100+
P: 626
Loose the parens in the command statement. Tkinter assumes that it is a function and so adds the parens itself.
Expand|Select|Wrap|Line Numbers
  1.              self.Butt0 = Button(frame, text = "Select", command=tkf.askopenfile).grid(row=0,column=2)
  2.              self.Butt1 = Button(frame, text = "Select", command=tkf.askopenfile).grid(row=1,column=2)
  3.              self.Butt2 = Button(frame, text = "Select", command=tkf.askopenfile).grid(row=2,column=2)
  4.              self.Butt3 = Button(frame, text = "Select", command=tkf.askopenfile).grid(row=3,column=2) 
But then, how do you store the file name selected? You should call a function, which calls askopenfile[name?] and stores the name selected. You can use the same function for all buttons and just send it the button number. Also, grid() returns None so there is no reason to save the button id's.
Expand|Select|Wrap|Line Numbers
  1. from Tkinter import *
  2. import tkFileDialog as tkf
  3. from functools import partial
  4.  
  5. class App:
  6.     def __init__(self, master):
  7.  
  8.              frame = Frame(master)
  9.              frame.pack()
  10.  
  11.              self.Name0 = Label(frame, text = "Initial Data", width=30).grid(row=0, sticky=W,columnspan=2)
  12.              self.Name1 = Label(frame, text = "After Change #1", width=30).grid(row=1, sticky= W,columnspan=2)
  13.              self.Name2 = Label(frame, text = "After Change #2", width=30).grid(row=2,sticky=W,columnspan=2)
  14.              self.Name3 = Label(frame, text = "Current State", width=30).grid(row=3,sticky=W,columnspan=2)
  15.  
  16.              self.Butt0 = Button(frame, text = "Select", command=partial(self.get_file_name, 0)).grid(row=0,column=2)
  17.              print self.Butt0
  18.              Button(frame, text = "Select", command=partial(self.get_file_name, 1)).grid(row=1,column=2)
  19.              Button(frame, text = "Select", command=partial(self.get_file_name, 2)).grid(row=2,column=2)
  20.              Button(frame, text = "Select", command=partial(self.get_file_name, 3)).grid(row=3,column=2)
  21.  
  22.     def get_file_name(self, button_num):
  23.         fname=tkf.askopenfilename()
  24.         print "name for button %d is %s" % (button_num, fname)
  25.  
  26. root = Tk()
  27.  
  28. app = App(root)
  29.  
  30. root.mainloop() 
Feb 15 '12 #2

P: 7
Oh, wow, that totally worked. Yeah, I plan to store the file names, but I was just testing it. I still don't understand why the parenthesis would cause the call to the button commands immediately and then never again. Anyways, thanks a lot!
Feb 15 '12 #3

Expert 100+
P: 626
I still don't understand why the parenthesis would cause the call to the button commands
That executes a call to the function and sets the command to the return value of the function, which you could do if you wanted, but I can't think of any reason why anyone would want to.
Feb 18 '12 #4

bvdet
Expert Mod 2.5K+
P: 2,851
You might want to pass a value to the function when the button is pushed. In that case you could use a lambda or closure. Lambda example:
Expand|Select|Wrap|Line Numbers
  1. command=lambda: tkf.askopenfile(file_name_variable1)
Feb 18 '12 #5

Post your reply

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