How can i update a tkinter window with a new defined variable? - python

I want to create two windows with one button in the first one one and one label in the second.
When i press the button the label in the second window should refresh and display the variable plus 1.
I dont want to close the second window and re open it afterwards.
Any ideas how that could be done?
import tkinter as tk
text = 1
root = tk.Tk()
root2 = tk.Tk()
label = tk.Label(root, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
def plus():
global text
text = text + 1
print(text)
button = tk.Button(root2, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()
root2.mainloop()
This code should do the basics but the line to refresh the second window is still missing.
Hopefully anyone can tell me how to that :)

Use Toplevel() window instead of using Tk() as secondary windows. Tkinter is single threaded so using one mainloop() is sufficient for all the windows.
Now as you've asked that you want one button in one window and a label which updates in the second window, and also you can reopen the window without losing any progress if you close the second window.
Here is my way.
import tkinter as tk
text = 1
root = tk.Tk()
root2 = tk.Toplevel()
label = tk.Label(root2, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
def plus():
global text, root2, label
if not root2.winfo_exists(): # checks if the window is closed or not
root2 = tk.Toplevel()
label = tk.Label(root2, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
text += 1
label['text'] = text
button = tk.Button(root, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()
Using IntVar() to update all the label values. Can use StringVar() for sting type:
Sample
import tkinter as tk
root = tk.Tk()
root2 = tk.Toplevel()
# This is a textvariable IntVar can also use StringVar for sting input
text = tk.IntVar()
text.set(1) # Set the initial to 1
# Use 'textvariable' instad of text
label = tk.Label(root2, bg="green", textvariable=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
label2 = tk.Label(root, textvariable=text)
label2.pack()
def plus():
global text, root2, label
if not root2.winfo_exists(): # checks if the window is closed or not
root2 = tk.Toplevel()
label = tk.Label(root2, bg="green", textvariable=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
text.set( text.get()+1 ) # incrementing by 1 ( text.get() will return the value )
button = tk.Button(root, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()
I hope you may find something useful from my answer.

You can't run two mainloops in one thread. Your call to root.mainloop() blocks until you close the window. Once you close the window, it exits that method and runs root2.mainloop() because it's the next line of code.
One root pane can have multiple windows, you don't need to make a root2. You want to make two Toplevel windows

To expand upon the answer already given, you should use Toplevel rather than two root windows.
Also in order to change the text of the label you use label['text'] = str(text) to update the value.
import tkinter as tk
text = 1
root = tk.Tk()
root2 = tk.Toplevel()
def plus():
global text
text = text + 1
label['text'] = str(text)
label = tk.Label(root, bg="green", text=text, fg="blue")
label.place(relx=0.1, rely=0.1, relheight=0.3, relwidth=0.3)
button = tk.Button(root2, bg="blue", text="Button", command=plus)
button.pack()
root.mainloop()

If I've understand, try this, every time you open a window, toplevel, the label in the new window is increment by 1
import tkinter as tk
class Test(tk.Toplevel):
def __init__(self, parent, count):
super().__init__()
self.parent = parent
self.count = tk.IntVar()
self.count.set(count)
self.title("I'm a new toplevel.")
self.init_ui()
def init_ui(self):
self.label = tk.Label(self, textvariable=self.count).pack()
self.close_me = tk.Button(self, text= "Close me", command = self.on_close_me).pack()
self.close_parent = tk.Button(self, text= "Close parent", command = self.on_close_parent).pack()
def on_close_me(self):
self.destroy()
def on_close_parent(self):
self.parent.on_close()
class App(tk.Frame):
def __init__(self,):
super().__init__()
self.master.title("Hello World")
self.count =0
self.init_ui()
def init_ui(self):
self.pack(fill=tk.BOTH, expand=1,)
f = tk.Frame()
w = tk.Frame()
tk.Button(w, text="Open", command=self.callback).pack()
tk.Button(w, text="Close", command=self.on_close).pack()
f.pack(side=tk.LEFT, fill=tk.BOTH, expand=0)
w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=0)
def callback(self):
self.count +=1
obj = Test(self,self.count)
def on_close(self,evt=None):
self.master.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()

Related

Buttons in tkinter - When clicked: reveal something behind it

I am new to python and tkinter. I'm looking to make a simple window with a few buttons. When a button is pressed, I wish for it to disappear and instead reveal something behind it, a number, for instance.
How do I go about doing this? Below is an example code which generates a window with a button. Can I work with a code like this or should it look completely different?
from tkinter import *
class Button:
def __init__(self):
self.root = Tk()
self.root.title("Button program")
self.root.geometry("100x100")
self.frame = Frame(self.root)
self.btn = Button(self.root, width=2)
self.btn.grid(row=1, column=1)
self.root.mainloop()
Button()
How about this? You will have to rearrange it in the class 'cause I couldn't fit it in, but works for me
from tkinter import *
def press_btn():
btn.grid_forget()
lbl = Label(root, text="label", width=15)
lbl.grid(row=1, column=1)
root = Tk()
root.title("Button program")
root.geometry("100x100")
frame = Frame(root)
btn = Button(root, text="button", width=15, command=press_btn)
btn.grid(row=1, column=1)
root.mainloop()

Tkinter StringVar shows random numbers instead of variable on label

The title says it all.
import tkinter as tk
from tkinter import filedialog, Text, StringVar
root = tk.Tk()
root.resizable(False, False)
var1 = StringVar()
topn = ""
print(topn)
def addApp():
global topn
topn = topn + "1"
print(topn)
var1.set(topn)
canvas = tk.Canvas(root, height=500, width=400, bg="#263D42")
canvas.pack()
frame = tk.Frame(root, bg="orange")
frame.place(relwidth=0.8, relheight=0.8, relx=0.1, rely=0.1)
Resultlabel = tk.Label(root,text=var1.get, padx=100, pady=5, fg="white", bg="grey")
Resultlabel.pack()
t
openFile = tk.Button(frame, text="Open File", padx=10, pady=5, fg="white", bg="#263D42", command=addApp)
openFile.pack()
root.mainloop()
[btw, ignore the Open File, i was following a tutorial to learn the basics of tkinter and then edited the code to fit my needs. I forgot to change the text in the button.]
https://i.stack.imgur.com/2FVKG.png
text is not the same thing as textvariable. text is used to associate static text with a widget, textvariable is used to have the text of the widget be synchronized with the value of a variable.
If you want ResultLabel to always show what is in var1 you must define it like this:
Resultlabel = tk.Label(root,textvariable=var1, padx=100, pady=5, fg="white", bg="grey")

Despite not getting any errors, my Tkinter GUI wont run. Why is that?

I'm trying to create a GUI that opens up a new window after pressing a button while destroying the last window. I'm not getting any errors but when I run my program nothing comes up.
from Tkinter import *
def team():
def table():
table = Toplevel(contributers)
contributers.destroy()
def contributers():
contributers = Toplevel(table)
table.destroy()
def firstpage():
firstpage = Toplevel(letsbegin)
letsbegin.destroy()
def secondpage():
secondpage = Toplevel(firstpage)
firstpage.destroy()
def leave():
exit()
root = Tk()
root.title("Team Blue")
label1 = label(menu, text="Team Blue", bg = "Yellow", fg="Black")
button1 = button(menu, text="ENTER", width=15, bg="yellow", fg="Black", command =contributers)
button2 = button(menu, text="Exit", bg="red", fg="white", command=leave)
root.mainloop()
I just want this code to run
You have many mistakes which I mentioned in comments.
If you want to close one window and open new one then destroy first window - root.destroy() - and later use again Tk() to create new window and use again mainloop().
I assign new window to global variable root so I can use almost the same code to close second window and open third one.
I use global root so variable root is not local variable but it is global and I have access (to window assigned to root) in other functions.
from Tkinter import *
# --- functions ---
def open_first_window():
global root
root = Tk()
label1 = Label(root, text="Team Brake 'Em")
label1.pack()
button1 = Button(root, text="Open Second Window", command=open_second_window)
button1.pack()
button2 = Button(root, text="Exit", command=root.destroy)
button2.pack()
root.mainloop()
def open_second_window():
global root
root.destroy()
root = Tk()
label1 = Label(root, text="Second Window")
label1.pack()
button1 = Button(root, text="Open Third Window", command=open_third_window)
button1.pack()
button2 = Button(root, text="Exit", command=root.destroy)
button2.pack()
root.mainloop()
def open_third_window():
global root
root.destroy()
root = Tk()
label1 = Label(root, text="Third Window")
label1.pack()
button2 = Button(root, text="Exit", command=root.destroy)
button2.pack()
root.mainloop()
# --- main ---
open_first_window()
There is other popular method - don't destry window but remove all widgets and put new one. Widget Frame can be usful because you can put all widget in Frame and Frame put in Window and later you have to only remove Frame and put new Frame with new widgets.
from Tkinter import *
# --- function ---
def create_first_frame():
global root
global frame
#frame.destroy()
frame = Frame()
frame.pack()
label1 = Label(frame, text="Team Brake 'Em")
label1.pack()
button1 = Button(frame, text="Open Second Window", command=create_second_frame)
button1.pack()
button2 = Button(frame, text="Exit", command=root.destroy)
button2.pack()
def create_second_frame():
global root
global frame
frame.destroy()
frame = Frame()
frame.pack()
label1 = Label(frame, text="Second Window")
label1.pack()
button1 = Button(frame, text="Open Third Window", command=create_third_frame)
button1.pack()
button2 = Button(frame, text="Exit", command=root.destroy)
button2.pack()
def create_third_frame():
global root
global frame
frame.destroy()
frame = Frame()
frame.pack()
label1 = Label(frame, text="Third Window")
label1.pack()
button2 = Button(frame, text="Exit", command=root.destroy)
button2.pack()
# --- main ---
root = Tk()
create_first_frame()
root.mainloop()
this is because as you wrapped your whole code inside the fuction name team().
so, you have to call that method at appropriate position in order to run the program.
and please make sure the letter case as label fuction is written as Label() so does button() is Button().
and also you have to use root in place of menu, then hopefully you see window.
pack the content according.

iconify in tkinter in python

I have written a code in python 2.7 and i have created a root window with two buttons: submit and cancel when i press submit button, a new window opens and previous parent/root window gets iconify. Now i want that when i cut the child window, parent window should be deiconify, i am in a trouble that where to put the condition so that parent window gets deiconify?
from Tkinter import *
root = Tk()
root.title("test window")
root.geometry('400x220+500+250')
root.configure(background="dark gray")
def submit(*args):
root.iconify()
popup_root_window = Toplevel()
popup_root_window.geometry('300x50+550+300')
popup_root_window.resizable(width=False, height=False)
popup_root_window.focus_force()
popup_root_window.grab_set()
popup_root_window_label = Label(popup_root_window, text="new window open successfully.")
popup_root_window_label.pack(anchor=CENTER, padx=10, pady=20)
frame = Frame(root, bd=4, relief="raise", height=100, width=250)
frame.pack(fill="both", padx=70, pady=35)
frame.pack_propagate(0)
submit_button = Button(frame, text="Submit", command=submit, width=10)
submit_button.grid(row=0, column=0)
cancel_button = Button(frame, text="Cancel", width=10)
cancel_button.grid(row=0, column=1)
root.mainloop()
I wrote the below in 3.6 but it should still work in 2.7.
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.label1 = Label(self.root, text="I'm your main window.")
self.button = Button(self.root, text="Submit", command=self.command)
self.label1.pack()
self.button.pack()
def command(self):
self.root.iconify()
self.top = Toplevel(self.root)
self.label2 = Label(self.top, text="I'm your toplevel window.")
self.label2.pack()
self.top.protocol("WM_DELETE_WINDOW", self.close)
def close(self):
self.top.destroy()
self.root.deiconify()
root = Tk()
App(root)
root.mainloop()
You can use .protocol() on the event WM_DELETE_WINDOW to create a callback whenever the X is selected from the title bar of the designated window.
This is tested and working with Python 3.6 on Windows 10.
You can try this one. i have tested this in python 2.7.13 and it working correctly.
from Tkinter import *
root = Tk()
root.title("test window")
root.geometry('400x220+500+250')
root.configure(background="dark gray")
def submit(*args):
def on_closing(*args):
popup_root_window.destroy()
root.deiconify()
root.iconify()
popup_root_window = Toplevel()
popup_root_window.geometry('300x50+550+300')
popup_root_window.resizable(width=False, height=False)
popup_root_window.focus_force()
popup_root_window.grab_set()
popup_root_window_label = Label(popup_root_window, text="new window open successfully.")
popup_root_window_label.pack(anchor=CENTER, padx=10, pady=20)
popup_root_window.protocol("WM_DELETE_WINDOW", on_closing)
frame = Frame(root, bd=4, relief="raise", height=100, width=250)
frame.pack(fill="both", padx=70, pady=35)
frame.pack_propagate(0)
submit_button = Button(frame, text="Submit", command=submit, width=10)
submit_button.grid(row=0, column=0)
cancel_button = Button(frame, text="Cancel", width=10)
cancel_button.grid(row=0, column=1)
root.mainloop()

How can i make a function make a GUI window empty it`s content?

I am working on a school project and i am very new to programming. I want to know how i can take the GUI i made which contains a set of entries/labels/buttons and make the window "refresh" as you would in a normal browser. My goal is to clear the window of all the entries and buttons during this "refresh".
I thank for any advice in advance and hope my post was specific enough.
Here is a login screen without any functions.
import tkinter
import distutils
from distutils.cmd import Command
import os
from _ast import Delete
window = tkinter. Tk()
window.title("PTF Pydev Eclipse")
window.geometry("500x500")
lbl = tkinter.Label(window, text= "Username")
ent = tkinter.Entry(window)
lbl1 = tkinter.Label(window, text= "Password")
ent1 = tkinter.Entry(window)
lbl2 = tkinter.Label(window, text= "Access")
ent1.bind('<Return>', show) # Not sure if this is needed
btn = tkinter.Button(window, text="Login", command= lambda: validation())
lbl.pack()
ent.pack()
lbl1.pack()
ent1.pack()
lbl2.pack()
btn.pack()
window.mainloop()
You can use pack_forget() to remove widget.
lbl.pack_forget()
ent.pack_forget()
lbl1.pack_forget()
ent1.pack_forget()
lbl2.pack_forget()
btn.pack_forget()
You can also put all widgets in Frame() and then use pack_forget() to remove Frame with all widgets inside.
import tkinter as tk
def validation():
# remove frame
frame.pack_forget()
window = tk.Tk()
window.title("PTF Pydev Eclipse")
window.geometry("500x500")
# create frame
frame = tk.Frame(window)
frame.pack()
# put widgets in frame
lbl = tk.Label(frame, text= "Username")
ent = tk.Entry(frame)
lbl1 = tk.Label(frame, text= "Password")
ent1 = tk.Entry(frame)
lbl2 = tk.Label(frame, text= "Access")
#ent1.bind('<Return>', show) # Not sure if this is needed
btn = tk.Button(frame, text="Login", command=validation)
ent.pack()
lbl1.pack()
ent1.pack()
lbl2.pack()
btn.pack()
window.mainloop()
BTW: it can be useful: "famous" Bryan Oakley's program on how to switch between frames.

Categories

Resources