This simple code is not working.
I mean its running without errors but
is not showing any gui window for text entry.
from Tkinter import *
from tkMessageBox import *
root=Tk()
Label(root,text="first").grid(row=0)
Label(root,text="second").grid(row=2)
e1=Entry(root)
e1.grid(row=0,column=2)
e2=Entry(root)
e2.grid(row=2,column=3)
def info():
s=showinfo(title="wish",message=e1.get()+''+"welcome to python")
Button(root,text="ok",command=info).pack()
root.mainloop()
You can't use grid and pack on two widgets owned by the same parent. This causes the geometry manager to loop forever.
Change your Button positioning to:
Button(root,text="ok",command=info).grid(row=3, column=0)
(or whatever row/column you want it to be in).
Result:
Related
I am trying to show a tkinter Toplevel window, have the script sleep for one second, then continue running. However, the sleep function always occurs before the toplevel window appears. I'm doing this because I want to show an indication to the user that a label text has been copied on click.
I am planning to have the Toplevel show, sleep for one second, then destroy it. However, as it is currently, the sleep occurs first and then the Toplevelshows and is destroyed immediately too fast for the user to perceive.
Is there a way to have these events happen in my desired order? Here is a script demonstrating what I'm dealing with:
from tkinter import *
from tkinter import ttk
import time
root = Tk() # Creating instance of Tk class
def make_new_window(event):
new_window = Toplevel()
clabel = Label(new_window, text = "Copied")
clabel.pack()
time.sleep(1)
l = Label(root, text = "Example text")
l.pack()
l.bind('<1>', make_new_window)
root.mainloop()
In a program I am working on there is a tkinter label/button which starts the card game (the program I am using) and a other window that has a string stating 'Welcome to the card game'.
Here is the tkinter section of the code:
import tkinter
window = tkinter.Tk()
print()
from tkinter import *
def quit():
global root
root.quit()
root = Tk()
while True:
label = tkinter.Label(window, text = "Welcome to the card game! (During name registration only use characters)").pack()
Button(root, text="Start Game", command=quit).pack()
root.mainloop()
However when I run the program they each appear in their own window screens when it would be more convenient for the user to have the options in one single window.
Is there anyway to merge them?
EDIT - (Having the button and text using root has fixed the problem.)
There is a lot going on here that should not be in such a small set of code.
Lets break it down.
First your imports. You are importing from tkinter multiple times. You only need to import once and you can use everything with the proper prefix. The preferred method is import tkinter as tk this way you don't overwrite any other imports or built in methods.
Next we need to get rid of one of your instances of Tk() as tkinter should only ever have one. For other windows use Toplevel().
In your quit function you do not need to define global as you are not assigning values here so the function will look in the global namespace for root.
Next Lets delete the empty print statement.
Next make sure both your label and button have the same container assigned to them. This is the reason why you are seeing them in different windows.
Next rename your function as quit is a built in method and should not be overwritten.
Lastly we remove the while statement as the mainloop() is already looping the Tk instance. You do not need to manage this yourself.
Here is what your code should look like (a 2nd window serves no purpose here):
import tkinter as tk
def root_quit():
root.quit()
root = tk.Tk()
tk.Label(root, text="Welcome to the card game! (During name registration only use characters)").pack()
tk.Button(root, text="Start Game", command=root_quit).pack()
root.mainloop()
Here is an example using Toplevel just so you can get an idea of how it is used.
import tkinter as tk
def root_quit():
root.quit()
def game_window():
top = tk.Toplevel(root)
tk.Button(top, text='exit', command=root_quit).pack()
root = tk.Tk()
tk.Label(root, text="Welcome to the card game! (During name registration only use characters)").pack()
tk.Button(root, text="Start Game", command=game_window).pack()
root.mainloop()
I have created two frames using Tkinter. In one of the frames I am trying to add a button using a grid. When I run the program, there is no output. Instead it just freezes and I have to kill the process.
Here is the code:
from Tkinter import *
window=Tk()
window.title("calculator")
window.geometry("500x500")
window.resizable(0,0)
input_field=StringVar()
display_frame=Frame(window).pack(side="top")
button_frame=Frame(window).pack(side="bottom")
text=Entry(display_frame,font=('arial',20,'bold'),textvariable=input_field,justify="right").pack(fill="x",ipady=10)
clear_button=Button(button_frame,text="C").grid(row=0)
window.mainloop()
However, if I change the clear_button variable as
clear_button=Button(button_frame,text="C").pack()
I get an output. What am I missing here?
You cannot mix grid and pack inside the same container (a Frame/Window).
That said you should realize that your display_frame and button_frame variables are actually None! Why, because Frame(Window) will return a Frame object, but you have applied the pack() function just after that whose return value is None.
So basically the Entry and the Button widgets that you created have master=None and that means they are not inside the Frames that you defined, but actually part of the main Window.
Now you can easily see why clear_button=Button(button_frame,text="C").pack() was working as now the main window has only one geometry manager namely pack.
Here is the working code.
from tkinter import * # "Tkinter" on python 2
window=Tk()
window.title("calculator")
window.geometry("500x500")
window.resizable(0,0)
input_field=StringVar()
display_frame=Frame(window)
display_frame.pack(side="top")
button_frame=Frame(window)
button_frame.pack(side="bottom")
Entry(display_frame,font=('arial',20,'bold'),textvariable=input_field,justify="right").pack(fill="x",ipady=10)
Button(button_frame, text="C").grid(row=0)
window.mainloop()
You cannot use both grid and pack method on widgets having same master.
Here, follow the below thread for a detailed understanding :
python pack() and grid() methods together
I am currently implementing a program that uses many tkinter frames and while subframe is being opened I want the superframe to be locked for the user (otherwise things will not work out). After some research I found the grab_set and grab_release method which worked quite fine.
However once the subframe (instanciated by Toplevel) calls the askstring the grab is "losed" and the user can interact with the superlevel window again. An example would be this (very simplified code):
import tkinter as tk
import tkinter.simpledialog
root = tk.Tk()
def open_sublevel():
tl = tk.Toplevel(root)
def ask():
print(tk.simpledialog.askstring("askstring", "askstring"))
tk.Button(tl, text="ask", command=ask).pack()
tl.grab_set()
root.wait_window(tl)
tl.grab_release()
print("release")
tk.Button(root, text="asdf", command=open_sublevel).pack()
tk.mainloop()
Once the user opens the subframe by clicking "asdf" the frame containing "asdf" will be locked for the duration while the subframe is opened. However once the user selects the "ask"-Button in the subframe this "lock" somehow disappears.
According to the notes in the tkinter library:
A grab directs all events to this and descendant widgets in the application.
I am not able so far to find any documentation that would explain why the grab_set() is falling off after you finish submitting your askstring but I would imaging it is because once the widget is gone the grab_set() falls off. Just like if you were to close out the Toplevel window.
In this case tl.grab_release() does not appear to be needed as grab releases once the window closes.
From what I have tested if you reset the grab_set() after the askstring is done then it will still work properly.
You need to simply add tl.grab_set() just below print(tk.simpledialog.askstring("askstring", "askstring")).
Modified code below:
import tkinter as tk
import tkinter.simpledialog
root = tk.Tk()
def open_sublevel():
tl = tk.Toplevel(root)
tl.grab_set()
def ask():
print(tk.simpledialog.askstring("askstring", "askstring"))
tl.grab_set()
tk.Button(tl, text="ask", command=ask).pack()
print("release")
tk.Button(root, text="asdf", command=open_sublevel).pack()
tk.mainloop()
setting the parent for simpledialog will make simpledialog take focus
x = simpledialog(parent = window_x, title = z etc.)
this will make sure x takes focus and not withdraw
I would like to show a window after I called withdraw.
The following is my current code:
from Tkinter import *
def callback():
global root
root.withdraw()
win2 = Tk()
root = Tk()
Label(root,text='this is a window').pack()
Button(root,text='withdraw',command=self.callback).pack()
mainloop()
As soon as I press the button, the window disappears much as I want it, and another window appears and everything works great. How do I get the first window back, in the same state as it was before?
Use the following commands when you want to show the window:
# root.update() # not required
root.deiconify()
If you want to know more about it, see here.