Martin
Martin

Reputation: 459

Tkinter newly created button does not execute command

A script should open an application with two buttons visible. When Hello button is pressed a new button is gridded into the row number 1 and Hello button to be deactivated. When this new button is pressed it should delete itself off the grid and reactivate hello button but it does not do it.

Please check the video to see it in action.

Code edited to comment suggestion

from tkinter import *

class Application(Frame):
    def __init__(self, master=None):
        self.master = master
        self.master.geometry('300x100+10+10')
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def new_button(self):
        print("enable_b")
        self.hi_there.config(state=ACTIVE)
        self.new_button.grid_remove()

    def say_hi(self):
        print("hi there, everyone!")
        self.new_button = Button(self)
        self.new_button.config(text = "New BTN", command=self.new_button)
        self.new_button.grid(row=1,column=0)
        self.hi_there.config(state=DISABLED)

    def createWidgets(self):
        self.QUIT = Button(self)
        self.QUIT.config(text="QUIT",fg="red",command=self.quit)
        self.QUIT.grid(row=0,column=1)
        self.hi_there = Button(self)
        self.hi_there["text"] = "Hello",
        self.hi_there["command"] = self.say_hi
        self.hi_there.grid(row=0,column=0)

    def quit(self):
        self.master.destroy()

def testit(): 
    root = Tk()
    app = Application(master=root)
    app.mainloop()

if __name__ == '__main__':
    testit()

Upvotes: 0

Views: 71

Answers (2)

Mike - SMT
Mike - SMT

Reputation: 15226

Where your program will technically work just fine with the 2 correction mentioned in Bryan's answer I am not sure why you are taking all the extra effort configuring the widgets for each individual field. All your configs can be done when you create the widget.

That said you can also change a few things for a cleaner code and 1 change I think that really needs to be made is how you are removing the new_button from the grid. When you do grid_remove() this only takes the widget off the screen but does not get rid of the widget. Then next time you press the say_hi button you will end up creating a new button and the old button will still exist. Instead I think I would use destroy() on the button and then let say_hi recreate it.

See this revised version of your code. You will see what I mean about configuring everything when creating the widget and also you do not need to write your own function for quit you can simply do self.master.destroy in the quit button command.

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.master = master
        self.master.geometry('300x100+10+10')
        self.create_widgets()

    def new_btn(self):
        print("enable_b")
        self.hi_there.config(state="active")
        self.new_button.destroy()

    def say_hi(self):
        print("hi there, everyone!")
        self.new_button = tk.Button(self, text="New BTN", command=self.new_btn)
        self.new_button.grid(row=1, column=0)
        self.hi_there.config(state="disabled")

    def create_widgets(self):
        tk.Button(self, text="QUIT", fg="red", command=self.master.destroy).grid(row=0,column=1)
        self.hi_there = tk.Button(self, text="Hello", command=self.say_hi)
        self.hi_there.grid(row=0, column=0)

if __name__ == '__main__':
    root = tk.Tk()
    app = Application(master=root).pack()
    root.mainloop()

Upvotes: 1

Bryan Oakley
Bryan Oakley

Reputation: 385830

Initially, self.new_button refers to a method. Then, you do this:

self.new_button = Button(self)

That effecting removes the method and replaces it with the button widget itself.

Also, you never assign a command to the new button, so clicking it doesn't cause anything to be called.

Upvotes: 2

Related Questions