Tkinter button not working as expected

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • vagrantbrad@yahoo.com

    #1

    Tkinter button not working as expected

    I've created a short test program that uses tkFileDialog.as kdirectory
    to help the user input a path into a tk entry widget. The problem I'm
    having is that when I run the code as listed below, the getPath
    function is called when the program initially runs, not when the button
    is pressed.

    from Tkinter import *
    import tkFileDialog

    class App:

    def __init__(self, master):

    frame = Frame(master)
    frame.pack()

    t = StringVar()
    self.entry = Entry(frame, textvariable=t)
    self.entry.pack (side=LEFT)

    self.button = Button(frame, text="Select", fg="red")
    self.button["command"] = self.getPath(t)
    self.button.pac k(side=LEFT)

    def getPath(self, t):
    dirPath = tkFileDialog.as kdirectory(init ialdir="c:\\")
    print dirPath
    t.set(dirPath)

    root = Tk()
    app = App(root)
    root.mainloop()


    The problem arises when I try to pass the t variable in the "command"
    option of the button widget. If I set the command to
    "command=self.g etpath" rather than "command=self.g etpath(t)", then I
    don't get this issue. But I would like to be able to pass a variable
    to the the function through the command option. I'm a Tk newbie ....
    what am I doing wrong?

  • bearophileHUGS@lycos.com

    #2
    Re: Tkinter button not working as expected

    vagrantbrad@yah oo.com wrote:
    I've created a short test program that uses tkFileDialog.as kdirectory
    to help the user input a path into a tk entry widget. The problem I'm
    having is that when I run the code as listed below, the getPath
    function is called when the program initially runs, not when the button
    is pressed.
    [...]
    what am I doing wrong?
    Recently I've done a stupid error with a callback (probably I was
    sleeping), so I try again. Note many little changes that I belive
    improve your program:

    import Tkinter as tk
    import tkFileDialog

    class App(tk.Frame):
    def __init__(self, master):
    tk.Frame.__init __(self, master)
    self.pack()

    self.entrytxt = tk.StringVar()
    entry = tk.Entry(self, textvariable=se lf.entrytxt)
    entry.pack(side =tk.LEFT)

    button = tk.Button(self, text="Select", fg="red",
    command=self.ge tPath)
    button.pack(sid e=tk.LEFT)

    def getPath(self):
    dirPath = tkFileDialog.as kdirectory(init ialdir="c:/")
    self.entrytxt.s et(dirPath)
    print dirPath

    root = tk.Tk()
    app = App(root)
    root.mainloop()

    Bye,
    bearophile

    Comment

    • James Stroud

      #3
      Re: Tkinter button not working as expected

      vagrantbrad@yah oo.com wrote:
      I've created a short test program that uses tkFileDialog.as kdirectory
      to help the user input a path into a tk entry widget. The problem I'm
      having is that when I run the code as listed below, the getPath
      function is called when the program initially runs, not when the button
      is pressed.
      >
      from Tkinter import *
      import tkFileDialog
      >
      class App:
      >
      def __init__(self, master):
      >
      frame = Frame(master)
      frame.pack()
      >
      t = StringVar()
      self.entry = Entry(frame, textvariable=t)
      self.entry.pack (side=LEFT)
      >
      self.button = Button(frame, text="Select", fg="red")
      self.button["command"] = self.getPath(t)
      self.button.pac k(side=LEFT)
      >
      def getPath(self, t):
      dirPath = tkFileDialog.as kdirectory(init ialdir="c:\\")
      print dirPath
      t.set(dirPath)
      >
      root = Tk()
      app = App(root)
      root.mainloop()
      >
      >
      The problem arises when I try to pass the t variable in the "command"
      option of the button widget. If I set the command to
      "command=self.g etpath" rather than "command=self.g etpath(t)", then I
      don't get this issue. But I would like to be able to pass a variable
      to the the function through the command option. I'm a Tk newbie ....
      what am I doing wrong?
      >
      Well, in python 2.5, you might consider functools.parti al.

      Other options, including lambda, will be suggested and are the
      traditional way to do this sort of thing.

      Here is the revised code:

      import functools
      from Tkinter import *
      import tkFileDialog

      class App:

      def __init__(self, master):

      frame = Frame(master)
      frame.pack()

      t = StringVar()
      self.entry = Entry(frame, textvariable=t)
      self.entry.pack (side=LEFT)

      self.button = Button(frame, text="Select", fg="red")

      # note change here
      self.button["command"] = functools.parti al(self.getPath , t)
      self.button.pac k(side=LEFT)

      def getPath(self, t):
      dirPath = tkFileDialog.as kdirectory(init ialdir="c:\\")
      print dirPath
      t.set(dirPath)

      root = Tk()
      app = App(root)
      root.mainloop()




      --
      James Stroud
      UCLA-DOE Institute for Genomics and Proteomics
      Box 951570
      Los Angeles, CA 90095


      Comment

      • Fredrik Lundh

        #4
        Re: Tkinter button not working as expected

        vagrantbrad@yah oo.com wrote:
        I've created a short test program that uses tkFileDialog.as kdirectory
        to help the user input a path into a tk entry widget. The problem I'm
        having is that when I run the code as listed below, the getPath
        function is called when the program initially runs, not when the button
        is pressed.
        the right side of an assignment is always evaluated before it is assigned, so

        self.button["command"] = self.getPath(t)

        will call self.getPath(t) and then assign the return value to button["command"].
        quite obvious, if you think about it, right ?

        the easiest way to fix this is to add a local function that calls getPath, and
        use that as the button callback:

        def callback():
        self.getPath(t)
        self.button["command"] = callback

        (if you want, you can inline the getPath code in the callback).

        </F>



        Comment

        • vagrantbrad@yahoo.com

          #5
          Re: Tkinter button not working as expected

          Thank you Fredrik. It makes total sense now that you've explained it
          this way. I frustrated at my ignorance on the assignment issue :)




          Fredrik Lundh wrote:
          vagrantbrad@yah oo.com wrote:
          >
          I've created a short test program that uses tkFileDialog.as kdirectory
          to help the user input a path into a tk entry widget. The problem I'm
          having is that when I run the code as listed below, the getPath
          function is called when the program initially runs, not when the button
          is pressed.
          >
          the right side of an assignment is always evaluated before it is assigned, so
          >
          self.button["command"] = self.getPath(t)
          >
          will call self.getPath(t) and then assign the return value to button["command"].
          quite obvious, if you think about it, right ?
          >
          the easiest way to fix this is to add a local function that calls getPath, and
          use that as the button callback:
          >
          def callback():
          self.getPath(t)
          self.button["command"] = callback
          >
          (if you want, you can inline the getPath code in the callback).
          >
          </F>

          Comment

          • Fredrik Lundh

            #6
            Re: Tkinter button not working as expected

            vagrantbrad@yah oo.com wrote:
            Thank you Fredrik. It makes total sense now that you've explained it
            this way. I frustrated at my ignorance on the assignment issue :)
            well, it's one of those "you'll only do this once" mistakes that
            *everyone* does (mutable default arguments and unexpected integer
            division are two of the others).

            it's the "I'm always doing this" mistakes that are really frustrating
            (for me, "'str' object has no attribute 'startwith'" is at the top of
            that list...)

            </F>

            Comment

            Working...