Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make a function that wait a parameter to change triggered by button

Tags:

python

tkinter

The following is a program that does not make sense, but I want to do something similar in a larger code. One function is called and I want it to wait for a change in a parameter, where the change is triggered by a button. Running this code, when the OK button is pressed it doesn't allow for another button to be pressed and it freezes. Also before anything, I get the error: name 'boton' is assigned to before global declaration. Thanks for reading. Saludos.

from Tkinter import *
import time
master = Tk()

def callback():
    w1['text']="this"
    while boton==0:
        time.sleep(1)
    w1['text']="and then this"

def switch():
    if boton==0:
        global boton
        boton=1
    if boton==1:
        global boton
        boton=0

boton=0
w1 = Label(master, text="")
w1.grid(row=0, column=0)
e1 = Entry(master)
e1.grid(row=0, column=1)
b = Button(master, text="OK", command=callback)
b.grid(row=1, column=0)
b2 = Button(master, text="switch", command=switch)
b2.grid(row=1, column=1)

mainloop()
like image 540
Jorge Avatar asked Nov 29 '25 19:11

Jorge


1 Answers

You have a few problems and the two big ones are interrupting the Tkinter mainloop().

When you press OK your program gets stuck in a while loop that can never be broken. Keep in mind Tkinter runs on a single thread and any time you create a loop then it blocks the mainloop() form working until that loop is broken. To get around something like this we can use the after() method to schedule and event to happen as part of the mainloop() instead. The second problem that is blocking the mainloop() is the sleep() method. This will have the same affect until the time is up.

We also need to make sure you are using if/else statements because your Switch() your if statements will always result in the 2nd text.

With that taken care of all we need to do now is a little cleanup.

Instead of doing from Tkinter import * we should do import Tkinter as Tk. This will keep us from overriding any methods from other imports or from variables we create.

You do not need to do global in each if statement. You just need it at the top of your function.

take a look at the below code.

import Tkinter as tk


master = tk.Tk()

def callback():
    global boton, w1
    w1.config(text="this")
    if boton == 0:
        master.after(1000, callback)
    else:
        w1.config(text="and then this")

def switch():
    global boton
    if boton==0:
        boton=1
    else:
        boton=0

boton=0
w1 = tk.Label(master, text="")
w1.grid(row=0, column=0)
e1 = tk.Entry(master)
e1.grid(row=0, column=1)
tk.Button(master, text="OK", command=callback).grid(row=1, column=0)
tk.Button(master, text="switch", command=switch).grid(row=1, column=1)

master.mainloop()
like image 192
Mike - SMT Avatar answered Dec 02 '25 10:12

Mike - SMT