gmonz gmonz - 9 months ago 55
Python Question

How to restart tkinter/python program on click of a button?

The Incorrect-Dimiss button erases on click and when Return key is pressed, but if I enter anything afterwards, nothing happens. The issue is that if I enter it correct, the login button pops up and it works. If I enter it incorrect, the dismiss button pops up, and clicking or pressing enter erases it. Now, anything I enter after an incorrect attempt whether correct or incorrect does nothing.

(1) In order to avoid this, I was wondering if the program could just restart on clicking/pressing enter the dismiss button, without the window closing, or another reopening, but I do not know how to do this.

(2)Also is there a max login attempts code that ends/restarts the program and if so how would I place it in this code? (something like if >3 incorrect then quit)

Here is the code (python3)- try it for yourself if you would like:

from tkinter import *

class Application(object):
def __init__(self, event=None):
self.root = Tk()

self.root.configure(bg="darkorchid1", padx=10, pady=10)
self.root.title("WELCOME")

self.username = "Bob"

self.welcome = Label(self.root, text="WELCOME TO MY PROGRAM", bg="lightgrey", fg="darkorchid1")
self.welcome.pack()

self.label0 = Label(self.root, text="ENTER NAME:", bg="purple", fg="white", height=5, width=50)
self.label0.pack()

self.entry = Entry(self.root, width=25)
self.entry.configure(fg= "white",bg="grey20")
self.entry.pack()
self.entry.bind("<Return>", self.submit)

self.button = Button(self.root, text="SUBMIT", highlightbackground="green", width=48, command=self.submit)
self.button.pack()

def submit(self, event=None):
username = self.entry.get()
if username == self.username:
self.button1 = Button(self.root, text='LOGIN', highlightbackground="green", width=28, command=self.root.destroy)
self.button1.pack()
self.entry.bind("<Return>", self.login)

else:
self.button2 = Button(self.root, text="INCORRECT- CLICK TO DIMISS THIS MESSAGE", highlightbackground="red", width=48, command=self.incorrect)
self.button2.pack()
self.entry.bind("<Return>", self.incorrect)

def incorrect(self, event=None):
self.button2.destroy()

def login(self, event=None):
self.root.destroy()


app=Application()

mainloop()


Instead of destroying the button I want this to restart the program but cannot find the correct command. This would destroy the button since it doesn't exist at the beginning of the program, as well as allow for incorrect or correct input to actually work after the first try.

def incorrect(self, event=None):
self.button2.destroy()


I am a beginner so the more simple, the better at this point. Thank you.

Answer Source

First of all I would change the bind to return to the root window instead of the entry (otherwise you have to click on the entry field for the return to have an effect)

Next you need 3 state variables for your class.

self.button1 = None
self.button2 = None
self.attempts = 0

Then by checking the state of each you can accomplish (what I think) you want

Here’s the whole code modified

from tkinter import *

class Application(object):

    def __init__(self, event=None):

        self.root = Tk()

        self.root.configure(bg="darkorchid1", padx=10, pady=10)
        self.root.title("WELCOME")

        self.username = "Bob"

        self.welcome = Label(self.root, text="WELCOME TO MY PROGRAM", bg="lightgrey", fg="darkorchid1")
        self.welcome.pack()

        self.label0 = Label(self.root, text="ENTER NAME:", bg="purple", fg="white", height=5, width=50)
        self.label0.pack()

        self.entry = Entry(self.root, width=25)
        self.entry.configure(fg= "white",bg="grey20")
        self.entry.pack()
        self.root.bind("<Return>", self.submit)

        self.button = Button(self.root, text="SUBMIT", highlightbackground="green", width=48, command=self.submit)
        self.button.pack()

        self.button1 = None
        self.button2 = None
        self.attempts = 0

    def submit(self, event=None):
        username = self.entry.get()
        if username == self.username:
            if (self.button2 != None): # after I added disabling the submit button this check might not be necessary
                return
            if (self.button1 == None):
                self.button1 = Button(self.root, text='LOGIN', highlightbackground="green", width=28, command=self.root.destroy)
                self.button1.pack()
                self.root.bind("<Return>", self.login)
                self.button.config(state="disabled")
        else:
            if (self.button2 == None):
                self.button2 = Button(self.root, text="INCORRECT- CLICK TO DIMISS THIS MESSAGE", highlightbackground="red", width=48, command=self.incorrect)
                self.button2.pack()
                self.root.bind("<Return>", self.incorrect)
                self.button.config(state="disabled")

    def incorrect(self, event=None):
        self.attempts += 1
        if (self.attempts > 2):
            self.root.destroy()
        else:
            self.root.bind("<Return>", self.submit)
            self.button.config(state="normal")
            self.button2.destroy()
            self.button2 = None

    def login(self, event=None):
        self.root.destroy()

app=Application()

mainloop()