How can I spawn a window, and halt the execution of the GUI until this window is closed by the user?
That's exactly what functions from the tkinter.messagebox submodule will do.
These will spawn a dialog, and halt the execution until closed.
For instance, the showinfo function will spawn a window with the first parameter as title and the second as message.
Until the window is closed, the remaining of the GUI will not be interactable.
Here is an example demonstrating this.
import tkinter as tk
import tkinter.messagebox as tkmb
root = tk.Tk()
button = tk.Button(
root,
text="Spawn a dialog",
command=lambda: tkmb.showinfo(
"Information",
"Please close this window or press OK to continue"))
button.pack()
root.mainloop()
When the button is clicked, a window spawns.
As long as this window is open, the button will not be clickable once again.
Related
So im very new to python and I'm basically trying to make a program were the user inputs a targets IP and then presses a button below to Execute the command (start the pinging process) and this I've done successfully but now I wanted to add an exit button below to stop the pinging process but I've got a problem. The button works fine before you press execute (works as intended it closes the application window) but when the script is running the button doesn't work at all and just kinda crashes the window but keeps the command running. How can I make the button work att all times (make it work when the script is running).
import tkinter as tk #import tkinter and tkinter library
from tkinter import ttk #package to style widget
import subprocess
def window(): #runs the window ??? i think
#address = input("Enter Ip Here:")
subprocess.call(f"ping {text.get()} -t -l 65500")
# root window
root = tk.Tk() # root?
root.geometry('200x200') #window size
root.resizable(False, False) # makes window non rezisable
root.title('Ping Of Death') #window title
var = tk.StringVar #variable tkinter = StringVar
text = tk.Entry(root,textvariable=var, width = 25)
text.pack()
# execute button
execute_button = ttk.Button( #defines the execute button
root,
text='Execute', #defines the text on the button
command=window
)
execute_button.pack( #package for button
ipadx=5, #x size
ipady=5, #y size
expand=True # ???
)
exit_button = ttk.Button(
root, text="Exit" ,
command=root.quit
)
exit_button.pack(pady=20)
root.mainloop() #to keep everything in a loop
I'm pretty sure that subprocess.call is blocking, so search on "subprocess.call non-blocking" and asyncio as an alternative.
I'm using tkinter to create a window with a button, the button's command is to destroy the window and create a similar new one on click, but the moment you run the program it automatically executes the button command which leads to a spam of windows creation and destruction
from tkinter import *
import random
import tkinter as tk
j=0
def func(j):
f=Tk()
f.title("game")
f.geometry("400x350")
f["bg"]="black"
#message
Label(f,bg="black",fg="white",height=2,width=20,text=" ").pack()
Label(f,bg="black",fg="white",height=3,width=20,text="click continue to proceed\n to main menu",font=("Arial",13)).pack()
#frame
global d
d=Frame(f,bg="white",bd=1)
d.pack(fill="both",expand=True,side="bottom")
print(d.__format__)
#cancel button
def canccel():
f.destroy()
c=Canvas(d,bg="white")
b1=Button(c,bg="white",text="cancel",command=canccel)
b1.pack()
c.pack(padx=90, pady=22,side=tk.LEFT)
#play button
if j==0:
k=Canvas(d,bg="white")
b2=Button(k,bg="red",text="continue!",command= [print("hehe"),func(-1)])
b2.pack()
k.pack(padx=15,pady=0,side=LEFT)
else:
j=random.randrange(0,400)
i=random.randrange(0,300)
k=Canvas(d,bg="white")
b2=Button(k,bg="white",text="continue!",command= [print("hehe"),func(j)])
b2.pack()
k.pack(padx=i,pady=j,side=LEFT)
f.mainloop()
func(j)
My Code opens a window with a button. When the button gets clicked a toplevel window is created and the root window gets destroyed. When the button on the toplevel window gets clicked a messagebox opens. I want the the Toplevel Window to be closed when the user presses the ok button of the messagebox.
Pressing Ok causes the TypeError: destroy() missing 1 required positional argument: 'self'
I really don't understand why it dosn't work since the toplevel window gets passed as an argument to the destroy method.
import tkinter as tk
from tkinter import messagebox
def main():
root = tk.Tk()
root.title("Hauptmenü")
mainmenue(root)
root.mainloop()
def mainmenue(root):
button_rennen = tk.Button(root, text="New Window", width=20,
command=lambda: call_window(root))
button_rennen.pack()
def call_window(root):
root.destroy()
rframe = tk.Toplevel
button = tk.Button(text="Wette platzieren",
command=lambda: question(rframe))
button.pack()
def question(rframe):
dialog = tk.messagebox.askokcancel(message="Destroy Window?")
if dialog is True:
rframe.destroy()
main()
def call_window(root):
root.destroy()
rframe = tk.Tk()
button = tk.Button(rframe, text="Wette platzieren",
command=lambda: question(rframe))
button.pack()
replace toplevel with Tk window and it works fine.
I want to close two windows at the same time when user click the Start button, the new window will pop-up and when the user clicks the Exit button on the Second pop-up window than both the window should Close at a time.
I know that for a different window I have to create a separate function to exit windows But I want to close more than one window with a single click.
I'm using python 3.7!
import tkinter
def NewWindow():
def qExit():
root.destroy()
root = tkinter.Tk()
root.title("New Window")
newButton = tkinter.Button(root, text=" Click here to Exit:",
command=qExit)
newButton.pack()
root.geometry("300x200")
root.mainloop()
Window = tkinter.Tk()
Window.title("hello")
eButton = tkinter.Button(Window, text="Start", command=NewWindow)
eButton.pack()
Window.geometry("200x200")
Window.mainloop()
You shouldn't call tkinter.Tk() more than once in a tkinter application. Call Toplevel() if you want to create a new window.
You also generally don't need to call mainloop() more than once.
To close both the new window and the main window, you can pass the latter to the former when you create it, and then destroy() that in your qExit() function (as well as the new window itself).
Note I changed some of the function and variable names to conform more to the PEP 8 - Style Guide for Python Code guidelines.
import tkinter
def makeWindow(parent):
def qExit():
newWindow.destroy()
parent.destroy()
newWindow = tkinter.Toplevel()
newWindow.geometry("300x200")
newWindow.title("New Window")
newButton = tkinter.Button(newWindow, text=" Click here to Exit",
command=qExit)
newButton.pack()
root = tkinter.Tk()
root.title("hello")
eButton = tkinter.Button(root, text="Start", command=lambda: makeWindow(root))
eButton.pack()
root.geometry("200x200")
root.mainloop()
A simple solution would be to just do exit() to stop the program, which will close all windows. alternatively you can make a list of all open window objects and call destroy on all of them.
No need description
def qExit():
root.destroy()
Window.destroy()
I created a tkinter Toplevel window for my application and later in the program destroyed it but after destroying the window the program doesnt get executed further and get struck there itself doing nothing . Here is the code that I used :-
#login.py
from tkinter import *
class gui:
def __init__(self):
#does something
def login(self):
self.winLogin.destroy()
def guilogin(self):
self.winLogin = Toplevel()
btn = Button(self.winLogin,command=self.login,text='asd')
btn.pack()
self.winLogin.mainloop()
#main.py
import login
from tkinter import *
main = Tk()
a = login.gui()
a.guilogin()
if True:
#some code and this part doesnot get executed
main.mainloop()
else:
main.destroy()
I run main.py file and the code get struck and do nothing before the if part . I tottaly have no idea whats wrong . Pls. Help!
As furas said in the comments, you should not call mainloop on the toplevel, instead use grab_set to disable the main window and wait_window to wait for the toplevel to be closed:
from tkinter import Tk, Toplevel, Button
def login():
top = Toplevel(root)
Button(top, text="Quit", command=top.destroy).pack()
top.grab_set() # deactivate the main GUI while top is opened
root.wait_window(top) # wait for top to be closed before doing the rest
print("logged in")
root = Tk()
Button(root, text="login", command=login).pack()
root.mainloop()