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()
Related
I need to center two buttons, and I may need to center more buttons, but I can't center more than one button, so I need help...
Here's the code:
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
button = Button(root, text="Button 1", command=click, width=25)
button.grid(row=0, column=0)
button2 = Button(root, text="Button 2", command=click2, width=25)
button2.grid(row=1, column=0)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
I did a bit of testing and here is what i have come up with. I have used the .pack() method instead of the .grid() method and i have also used a frame. I am kind of new to Python, but here it is :)
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
frame = Frame(root)
frame.pack(padx = 20, pady = 12)
button = Button(root, text="Button 1", command=click, width=25)
button.pack()
button2 = Button(root, text="Button 2", command=click2, width=25)
button2.pack()
root.mainloop()
Here is what it looks like:
Don't add weight to the first row. It is forcing it to expand. You may want to consider something else, though. You may eventually put something else on that row, and you may need that thing to expand the row. In it's current state this will cause a "catch 22" for you. You may want to consider creating a frame to hold all of the buttons, and put that entire frame on the root.
immediate fix:
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
button = Button(root, text="Button 1", command=click, width=25)
button.grid(row=0, column=0)
button2 = Button(root, text="Button 2", command=click2, width=25)
button2.grid(row=1, column=0)
#this is forcing the top row to expand
#root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
possibly a better way:
from tkinter import *
from tkinter.ttk import *
import os
root = Tk()
root.geometry("325x100")
def click():
pass
def click2():
pass
#by not defining row and column in grid()
#~ row will be the next available one and column will be 0
button_frame = Frame(root)
button_frame.grid(sticky='nswe')
button_frame.grid_columnconfigure(0, weight=1)
#you only need to store a reference if you intend to change/reference/destroy/forget these
#if they are going to always be a button, as initially defined, a reference is dead weight
Button(button_frame, text="Button 1", command=click, width=25).grid()
Button(button_frame, text="Button 2", command=click2, width=25).grid()
#now you can use grid_rowconfigure without it destroying your button layout
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
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.
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()
How do I create a new tkinter root window on top of the main root window that prevents you from accessing the main window until you close the secondary window?
Here is the code that I've written so far (in python 3.6):
from tkinter import *
root = Tk()
root.geometry('600x400+0+0')
def new_page():
rootB = Tk()
btnNP = Button(root, padx=1, pady=2, fg='black',relief='raise',font=
('garamond',10, 'italic', 'bold'),
text='New Page', bg='blue', command=new_page)
btnNP.place(x=100, y=300)
text1 = Text(root, bd=5, height=1, width=14, bg='pink')
text1.place(x=100, y=250)
root.mainloop()
I use Toplevel instead of a new root
def New_page():
popup = Toplevel()
popup.grab_set()
this should do the trick
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.