Tkinter - Update All Widgets - python

Hello I am trying to change background by button on tkinter. I have a button that changes background of mainWindow but when button pressed it doesn't change immediately. I think tk.update() command is useless because I made too much test with it and nothing happened.
Here's my code:
import tkinter as tk
def ChangeBg():
global bgColor
bgColor = 'white'
mainWindow.update()
bgColor = 'black'
root = tk.Tk()
mainWindow = tkToplevel()
mainWindow.geometry('500x500')
mainWindow.config(bg=bgColor)
btn = tk.Button(mainWindow, text='change background', command=ChangeBg)
btn.pack()
tk.mainloop()
I guess you will say "Why don't you just use mainWindow.config(bg=bgColor)?". Because in my main code I have to store color in variables and there will be a lot more widgets. Like generalBtnColor, generalForeground, generalTextColor. I can write a lot of codes for update all widgets itself but this is Python and I believe there is a short way.

I added mainWindow.config(bg='white'). Also changed in line 11 and 14.
import tkinter as tk
def ChangeBg():
global bgColor
mainWindow.config(bg='white')
mainWindow.update()
root = tk.Tk()
mainWindow = tk.Toplevel()
mainWindow.geometry('500x500')
mainWindow.config(bg = 'black')
btn = tk.Button(mainWindow, text='change background', command=ChangeBg)
btn.pack()
tk.mainloop()
Output:
Current black:
After changing to white:

Related

Trying to create a red-translucent , flashing gui with tkinter

from tkinter import *
parent = Tk()
parent.geometry('500x500')
parent.title('Test in progress...')
parent.attributes('-alpha',0.5)
#parent.attributes('-fullscreen', True)
button1 = Button(parent, text = 'FOUND!',fg='red', command=parent.destroy)
button1.pack()
parent.mainloop()
I want this to flash translucent-red on fullscreen without effecting the user abilty to select things.
Using some help from this answer I think I have something to help you. You need to have a function that will control the changes to color utilizing .after. It shifts from white transparent to red in a "flashing" like manner. I hope this is in the ballpark for what you want.
from tkinter import *
def change_color():
current_color = parent.cget("bg")
next_color = "white" if current_color == "red" else "red"
parent.config(background=next_color)
parent.after(1000, change_color)
parent = Tk()
parent.config(bg="red")
parent.attributes('-alpha', 0.5)
parent.geometry('500x500')
parent.title('Test in progress...')
button1 = Button(parent, text='FOUND!', fg='red', command=parent.destroy)
button1.pack()
change_color()
parent.mainloop()

Changing the color of Tkinter canvas after set period of time

I'm trying to set a Tkinter canvas to red/green for one second, then back to white afterward. However, despite the fact that the code setting the canvas to red/green precedes the code reverting back to white, the window doesn't reflect the initial color change. I understand that by calling .after, the program freezes until the specified duration is over, but I don't understand why it doesn't change to red or green before freezing.
if is_correct:
self.canvas.config(bg="green")
else:
self.canvas.config(bg="red")
self.window.after(1000, self.canvas.config(bg="white"))
Refer to this simple program.
from tkinter import *
root=Tk()
def change_bg():
canvas.config(bg="red")
root.after(1000,lambda: canvas.config(bg="white"))
canvas=Canvas(root,bg="white")
canvas.pack()
root.after(1000,change_bg)
root.mainloop()
from tkinter import *
import time
def change_color():
can.config(bg="red")
can.update()
change_color2()
def change_color2():
time.sleep(1)
can.config(bg="white")
root = Tk()
root.geometry("500x500")
can = Canvas(root, bg="white", height=450, width=500)
can.pack()
Button(root, text="Change color for 1 sec", command=change_color).pack()
root.mainloop()
You can refer to this code

How to destroy widgets?

I want in my if statement for it to destroy the buttons on my tkinter. I have tried a couple of methods and looked up a few and some i don't understand/too complicated. I have tried making the function create a new window but it isn't displaying.
def greenwin():
global tkinter
global Tk
root = Tk()
root.title("GAME OVER")
root.geometry('387x387')
gamelabel=Label(root,text="GAME OVER!GREENS
WIN!",width=33,height=15).place(x=150,y=150)
root.mainloop
return
I want a clear method of destroying widgets.I would like a function that destroys all these buttons for my tic tac toe.
but1=Button(root,text="",bg="white",width=11,height=5,command=colour1).place(x=0,y=0)
but2=Button(root,text="",bg="white",width=11,height=5,command=colour2).place(x=0,y=150)
but3=Button(root,text="",bg="white",width=11,height=5,command=colour3).place(x=0,y=300)
but4=Button(root,text="",bg="white",width=11,height=5,command=colour4).place(x=150,y=0)
but5=Button(root,text="",bg="white",width=11,height=5,command=colour5).place(x=150,y=150)
but6=Button(root,text="",bg="white",width=11,height=5,command=colour6).place(x=150,y=300)
but7=Button(root,text="",bg="white",width=11,height=5,command=colour7).place(x=300,y=0)
but8=Button(root,text="",bg="white",width=11,height=5,command=colour8).place(x=300,y=150)
but9=Button(root,text="",bg="white",width=11,height=5,command=colour9).place(x=300,y=300)
root.mainloop
import tkinter as tk
root = tk.Tk()
any_widget = tk.Button(root, text="Press to destroy!")
any_widget['command'] = any_widget.destroy # pay special attention to the lack of ()
# call any_widget.destroy(), button widget's command option specifically needs a
# reference to the method instead of an actual call
any_widget.pack()
root.mainloop()
Try this:
import tkinter as tk
root = tk.Tk()
root.geometry("500x300+10+13")
root.title("Test")
b = tk.Button(root, text="click me")
def onclick(evt):
w = evt.widget
w.destroy()
b.bind("<Button-1>", onclick)
b.pack()
root.mainloop()

How to change the colour of everything in a tkinter GUI at once

I have some code (as shown below) which prompts the user to select which colour to change the GUI to. But my problem is that it only changes the background. I'd like to know if there's a way to change the background of every label and button at once or do I have to change each label/button individually.
import tkinter
window = tkinter.Tk()
colour_frame = tkinter.Frame(window)
options_frame = tkinter.Frame(window)
def colours():
options_frame.pack_forget()
red.pack()
orange.pack()
back_button.pack()
colour_frame.pack()
def back():
options_frame.pack()
colour_frame.pack_forget()
def make_red():
window.configure(background="red")
def make_orange():
window.configure(background="orange")
colour_button = tkinter.Button(options_frame, text="Appearance", command=colours)
red = tkinter.Button(colour_frame, text="RED", command=make_red)
red.configure(bg = "red")
orange = tkinter.Button(colour_frame, text="ORANGE", command=make_orange)
orange.configure(bg = "orange")
back_button = tkinter.Button(colour_frame, text="Back", command=back)
window.mainloop()
You can make a list containing all your widgets you want to change
myWidgets = [button1, label1, ... ] # List of widgets to change colour
for wid in myWidgets:
wid.configure(bg = newColour)
Here's an example code of changing the background colour of multiple labels at once.
import tkinter as tk
# Change all label backgrounds
def change_colour():
c = user.get() #Get the entered text of the Entry widget
for wid in widget_list:
wid.configure(bg = c)
# Create GUI
root = tk.Tk()
tk.Label(root, text='Enter a colour').pack()
user = tk.Entry(root)
user.pack()
label_frame = tk.Frame(root)
label_frame.pack()
btn = tk.Button(root, text='Change Colour', command = change_colour)
btn.pack()
widget_list = [user, btn] # Add defined widgets to list
#Dynamicly create labels for example
for x in range(10):
lbl = tk.Label(label_frame, text='Label '+str(x))
lbl.pack(side = tk.LEFT)
widget_list.append(lbl) #Add widget object to list
root.mainloop()
Or if you have a Frame already containing all the widgets you want to change, then you can use this instead.
parent_widget.winfo_children() will return a list containing all the widgets stored inside the parent widget
def change_colour():
c = user.get()
for wid in label_frame.winfo_children():
wid.configure(bg = c)
Try using ttk for some of your GUI elements. ttk allows you to create styles for widgets and update the style to all widgets at once (at least for those that have the same style). You may need to mix the usage of ttk and tkinter, but it should make things a bit easier in the long run. Here is an example I made:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
# Creating a style for the buttons
color_style_button = ttk.Style()
color_style_button.configure("color.TButton", foreground="red")
def change_color(color):
# This function changes the style to all buttons using the "color.Button style"
if color == "red":
color_style_button.configure("color.TButton", foreground="red")
elif color == "blue":
color_style_button.configure("color.TButton", foreground="blue")
elif color == "green":
color_style_button.configure("color.TButton", foreground="green")
frame_a = ttk.Frame(root)
frame_a.pack()
red_button = ttk.Button(frame_a, text="Red", command=lambda: change_color("red"), style="color.TButton")
red_button.pack()
blue_button = ttk.Button(frame_a, text="Blue", command=lambda: change_color("blue"), style="color.TButton")
blue_button.pack()
green_button = ttk.Button(frame_a, text="Blue", command=lambda: change_color("green"), style="color.TButton")
green_button.pack()
root.mainloop()
I recommend checking out this site to learn more about ttk and styles.

How do you refresh a window in Tkinter

If I created Tkinter window with some text that filled the whole window and now wanted to replace the window with a new text, is there a way to refresh the window?
For Example:
a= 100
win= Tk()
win.geometry("500x300")
while a > 0:
if a%2 == 0:
lbl = Label (win, bg = "purple")
lbl.pack()
else:
lbl = Label (win, bg = "blue")
lbl.pack()
a= x-1
The problem with this code is that the Tkinter window does not refresh and just provides the end result instead of showing the windows changing colors.
Thanks for the help!
That is not the way to change UI states, because even if you refreshed the window it would be so quick you won't notice, instead change the state, wait some time and change the state again e.g. here I show how to animate color
from Tkinter import *
index = 0
def changeColor():
global index
if index%2==0:
label.configure(bg = "purple")
else:
label.configure(bg = "blue")
index+=1
label.after(1000, changeColor)
root = Tk()
mainContainer = Frame(root)
label = Label(mainContainer, text="")
label.configure(text="msg will change every sec")
label.pack(side=LEFT, ipadx=5, ipady=5)
mainContainer.pack()
label.after(1000, changeColor)
root.title("Timed event")
root.mainloop()
This Is How I Do To Update Data From Sql Server in tkinter GUI python3
from tkinter import *
import os
window=Tk()
window.geometry('300x300')
def update():
window.destroy()
os.system('test.py')
Button(window,text="Refresh",command=update)
window.mainloop()

Categories