My program should destroy btn1 and create it again after one second in loop. I don't no why but my program only destroy btn1 and don't show this again. Anyone have idea why?
from tkinter import *
import random
def hide():
btn1.destroy()
btn1.after(2000,hide)
def show():
btn1 = Button(root, bd=c, text="Hello\nWorld", relief="ridge", cursor="trek")
btn1.grid(row=0,column=0)
btn1.after(3000,show)
root = Tk()
root.geometry("350x150+400+400")
c=random.randint(20,40)
btn1 = Button(root, bd=c, text="Hello\nWorld", relief="ridge", cursor="trek")
btn1.grid(row=0,column=0)
btn1.after(2000,hide)
btn1.after(3000,show)
root.mainloop()
It will work if you use grid_forget instead of creating a new object each time. Note that what happens at multiples of 6 seconds (2000 X 3000) depends on which one is the last one to execute.
def hide():
btn1.grid_forget()
btn1.after(2000,hide)
def show():
btn1.grid(row=0,column=0)
btn1.after(3000,show)
root = Tk()
root.geometry("350x150+400+400")
c=random.randint(20,40)
btn1 = Button(root, bd=c, text="Hello\nWorld",
relief="ridge", cursor="trek")
btn1.grid(row=0,column=0)
btn1.after(2000,hide)
btn1.after(3000,show)
root.mainloop()
Related
How can I make windows show up one at a time with tkinter? For example, if I typed in 6 as an input, and called a function with a button, I need it to show me 6 windows, but one at a time. It will only prompt me the next window after pressing a button from the previous one.
I tried using a for loop to loop through the range of the input, and create new windows with a button based on that range, but the problem is that they all show up at the same time:
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.title("Multiple windows")
def multiplewindows():
for i in range(int(number.get())):
tempwindow = Toplevel()
tempwindow.title(f"Window {i+1}")
tempbutton = Button(tempwindow, text=f"Button {i+1}")
tempbutton.pack(padx=10, pady=10)
number = Entry(root, width=5)
number.pack(padx=10, pady=10)
button = Button(root, text="Show", command=multiplewindows)
button.pack(padx=10, pady=10)
root.mainloop()
Is there any way to pause the for loop and allow it to continue after pressing the button in the newly created window?
I think you don't need for loop to do this
def multiplewindows():
j=int(number.get())
tempwindow = Toplevel()
tempwindow.title(f"Window {j}")
tempbutton = Button(tempwindow, text=f"Button {j}")
tempbutton.pack(padx=10, pady=10)
And if you want to use for loop to do this
def multiplewindows():
j=int(number.get())
for i in range(int(number.get())):
if (i+1)==j:
tempwindow = Toplevel()
tempwindow.title(f"Window {j}")
tempbutton = Button(tempwindow, text=f"Button {j}")
tempbutton.pack(padx=10, pady=10)
The easiest way to do this is like acw1668 was recommanded with the builtin method of tkinter that is calld with wait_window().
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.title("Multiple windows")
def multiplewindows():
for i in range(int(number.get())):
tempwindow = Toplevel()
tempwindow.title(f"Window {i+1}")
tempbutton = Button(tempwindow, text=f"Button {i+1}", command=tempwindow.destroy)
tempbutton.pack(padx=10, pady=10)
tempwindow.wait_window()
number = Entry(root, width=5)
number.pack(padx=10, pady=10)
button = Button(root, text="Show", command=multiplewindows)
button.pack(padx=10, pady=10)
root.mainloop()
Here we have created a function with a forloop that waits until the window is destroyed and added a command to the Button to destroy the window.
This question already has an answer here:
How do I create child windows with Python tkinter?
(1 answer)
Closed 5 years ago.
I am quite new to Python and started learning Tkinter yesterday. I am creating a banking system and I have a Menu made out of the buttons. The problem that I have is that I do not know how to open an additional window when the button is clicked. I have tried with top=Toplevel(), but it only opens two windows on top of each other. What I need is for the additional window to open only when it is activated with a button(event). Can someone help me because I am really stuck as I have about six buttons?
My code so far is:
root.minsize(width=400, height=400)
root.maxsize(width=400, height=400)
root.configure(background='#666666')
label = Frame(root).pack()
Lb = Label(label, text='Welcome to Main Menu',bg='#e6e6e6', width=400).pack()
menu = Frame(root,).pack()
btn_1 = Button(menu, text='Make Deposit', width=15, height=2).pack(pady=5)
btn_2 = Button(menu, text='Withdrawal', width=15, height=2).pack(pady=5)
btn_3 = Button(menu, text='Accounts', width=15, height=2).pack(pady=5)
btn_4 = Button(menu, text='Balance', width=15 ,height=2).pack(pady=5)
btn_5 = Button(menu, text='Exit', width=15, height=2).pack(pady=5)
root.mainloop()
Thank you for the help in advance
Maybe this could work:
from Tkinter import *
class firstwindow:
def __init__(self):
#Variables
self.root= Tk()
self.switchbool=False
#Widgets
self.b = Button(self.root,text="goto second window",command= self.switch)
self.b.grid()
self.b2 = Button(self.root,text="close",command= self.root.quit)
self.b2.grid()
self.root.mainloop()
#Function to chage window
def switch(self):
self.switchbool=True
self.root.quit()
self.root.destroy()
class secondwindow:
def __init__(self):
self.root= Tk()
self.b2 = Button(self.root,text="close",command= self.root.quit)
self.b2.grid()
self.root.mainloop()
one = firstwindow()
if one.switchbool:
two = secondwindow()
Take a look to the Tkinter reference. Check all universal methods and widgets methods. You can do anything you want.
Below is a small example of how you can open a window by clicking on a button. When the user clicks on the button, the function open_window, which was passed to the command option of the button, is called.
import tkinter as tk
def open_window():
top = tk.Toplevel(root)
tk.Button(top, text='Quit', command=top.destroy).pack(side='bottom')
top.geometry('200x200')
root = tk.Tk()
tk.Button(root, text='Open', command=open_window).pack()
tk.Button(root, text='Quit', command=root.destroy).pack()
root.mainloop()
I would like for a cant afford label to appear then after a second disappear when i push a button to buy something. It seems like the time.sleep(1) is making it not work properly. This is done on python tkinter.
def buttonpressed():
Label.place(x = 500, y = 500 #where i want the label to appear
time.sleep(1)
Label.place(x = 10000, y = 10000) #moving it away where i wont be able to see it
You can't use sleep because it stops mainloop
You can use root.after(time_in_milliseconds, function_name) to run function
Example
import tkinter as tk
def button_pressed():
# put text
label['text'] = "Hello World!"
# run clear_label after 2000ms (2s)
root.after(2000, clear_label)
def clear_label():
# remove text
label['text'] = ""
root = tk.Tk()
label = tk.Label(root) # empty label for text
label.pack()
button = tk.Button(root, text="Press Button", command=button_pressed)
button.pack()
root.mainloop()
If you have to create and remove label then use label.destroy()
import tkinter as tk
def button_pressed():
label = tk.Label(root, text="Hello World!")
label.pack()
root.after(2000, destroy_widget, label) # label as argument for destroy_widget
def destroy_widget(widget):
widget.destroy()
root = tk.Tk()
button = tk.Button(root, text="Press Button", command=button_pressed)
button.pack()
root.mainloop()
And shorter version without destroy_widget
import tkinter as tk
def button_pressed():
label = tk.Label(root, text="Hello World!")
label.pack()
root.after(2000, label.destroy)
root = tk.Tk()
button = tk.Button(root, text="Press Button", command=button_pressed)
button.pack()
root.mainloop()
Press button many times to see many labels which disappear after 2s.
You can use after() to set up a callback after a specified interval. In the callback function clear the label with pack_forget() (or grid_forget() if you're using grid). This is better than setting the label's text attribute to an empty string because that causes widgets to be resized, which might not be what you want. Here's an example:
import Tkinter as tk
class App():
def __init__(self):
self.root = tk.Tk()
self.label = tk.Label(text='I am a label')
self.label.place(x=0, y=0)
self.label.after(1000, self.clear_label) # 1000ms
self.root.mainloop()
def clear_label(self):
print "clear_label"
self.label.place_forget()
app=App()
Another option is to use self.label.destroy() to destroy the widget, however, pack_forget() allows you to display the label again by calling pack() on the widget again.
# I made it through calling 2 functions:
from tkinter import *
root = Tk()
root.geometry('400x200') # width by height
def one_text():
label['text'] = "Look around"
root.after(1000, another_text)
def another_text():
label['text'] = "and smile"
root.after(1000, one_text)
label= Label(root ,font=('Helvetica', 14), fg='black', bg='white')
label.pack()
one_text()
root.mainloop()
from tkinter import *
def begin():
root = Tk()
root.title("main window")
root.geometry("1920x1080")
return #How would a button be placed in this window made by this function?
root = Tk()
root.title("Start up page")
root.geometry("1920x1080")
BeginButton = Button(app, text = "Begin", command=begin, bg="green")
BeginButton.grid(column = 2, row = 2, sticky = W)
BeginButton.config(height = 10, width = 30 )
root.mainloop()
How would I create new buttons in the new window, if the new window is being made by, in this case a function known as "begin".
Any response would be much appreciated!
I believe what you want to do is to modify the root window rather than create a new one. Here is a minimal working example:
from tkinter import *
root = Tk()
class App:
def __init__(self):
root.title("Start up page")
root.geometry("1920x1080")
self.beginB = Button(root, text="Begin", command=self.begin,
bg="green", height=10, width=30)
self.beginB.grid(sticky = W)
def begin(self):
root.title("main window")
self.beginB.destroy()
del self.beginB
self.goB = Button(root, text='Go on', command=self.go_on,
bg='red')
self.goB.grid(sticky=E)
def go_on(self):
self.label = Label(root, text="you have continued")
self.label.grid(row=1, sticky=S)
App()
root.mainloop()
An advantage of defining a class is that you can make forward references. In your code, you had to define the begin function before you create the begin button. With a class, I could put it after init, which to me is a more natural order. It is ofter the case that the initialization code calls or binds more than one function.
I have a bit of difficulty with the code below. Basically, I want the code to, when I press the Enter button, to open the window2 but also close window1 simultaneously so that there is only one window and not two of them.
The code is...
from tkinter import *
def window1():
window = Tk()
window.title("Welcome")
f = Frame()
f.pack()
label1 = Label(window, text = "Welcome to the random window")
label1.pack()
button1 = Button(window, text = "Enter...", command = window2)
button1.pack()
def window2():
screen = Tk()
screen.title("Pop-Up!")
fr = Frame()
fr.pack()
label2 = Label(screen, text = "This is a pop-up screen!")
label2.pack()
button2 = Button(screen, text = "Return", command = window1)
button2.pack()
window1()
This is "Bad" because you're using two instances of Tk. Try instead using TopLevels.
import tkinter as tk
def window1():
window = tk.Toplevel(root)
window.title("Welcome")
# etc etc ...
tk.Button(window,text="Enter...",command=lambda: window2(window)).pack()
def window2(old_window):
old_window.destroy()
# window2 stuff
root = tk.Tk()
root.iconify() # to minimize it, since we're just using Toplevels on top of it
window1()
root.mainloop()
When you are using the Tk() function, you are creating a new instance of the Tcl/tkinter interpreter. Instead use Toplevel() which will make a new window in the current interpreter.