I am working on a program that requires multiple windows, and the first one to appear is the login window, I used the Toplevel widget in order to make other windows its children, but this code keeps showing two windows instead of one.
from Tkinter import Frame, Toplevel
from ttk import Label, Entry, Button
class loginWindow(Toplevel):
def __init__(self):
Toplevel.__init__(self)
self.title("Title")
self.frame = Frame(self)
self.frame.pack()
self.__make_layout()
self.mainloop()
def __make_layout(self):
self.frame.user_name_label = Label(text="User name:")
self.frame.user_name_text = Entry()
self.frame.user_name_label.grid(row=0, column=0)
self.frame.user_name_text.grid(row=0, column=1)
self.frame.password_label = Label(text="Password:")
self.frame.password_text = Entry()
self.frame.password_label.grid(row=1, column=0)
self.frame.password_text.grid(row=1, column=1)
self.frame.login_button = Button(text="Login")# , command=self.__create_window)
self.frame.login_button.grid(row=2, column=0, columnspan=2)
if __name__ == '__main__':
win1 = loginWindow()
All of the widgets created in _make_layout are created without a parent. This means they're children of the default root. You need to pass a parent to each of them, the same way you do to the Frame. Like this:
self.frame.user_name_label = Label(self.frame, text="User name:")
self.frame.user_name_text = Entry(self.frame)
# etc.
When I run your exact code, I don't get a second window, on any platform I try. The closest I get is on OS X, where an entry for the default root window appears in the Window menu, but the window itself still doesn't appear and the widgets all end up on the Toplevel (although not on the Frame where you wanted them). But it certainly would be legal for Tkinter to show a second window here, and put some or all of your widgets on it.
This must be a platform dependent issue, since abarnert isn't having issues with multiple windows. I use OS X with XQuartz and the following code gives me two windows:
from Tkinter import Toplevel, Tk
Toplevel().mainloop()
However, this code gives me one window:
from Tkinter import Toplevel, Tk
Tk().mainloop()
I believe your first window should be declared Tk() and subsequent windows should be Toplevel().
Related
I've looked at the tkinter documentation but am still confused as to how the -topmost option works when multiple Toplevels are open. A simple example:
from tkinter import Tk,Toplevel
root = Tk()
root.wm_title("Main Window")
root.geometry('1400x900')
top_window = Toplevel(root,bg="lightgray")
top_window.geometry('1400x900')
top_window.attributes('-topmost', 'true')
top_window.wm_title('Top Window 1')
top_window = Toplevel(root,bg="lightgray")
top_window.geometry('1400x900')
top_window.attributes('-topmost','true')
top_window.wm_title('Top Window 2')
root.mainloop()
Both Toplevel windows appear on top of the root, but the one labelled Top Window 1 is on top of the one labelled Top Window 2, which is not what I would expect. (Note: For my actual application, I'll be reusing the Toplevel's name over and over, which is why I used the name top_window twice.)
I have created a tkinter application where the user can make multiple toplevel windows and have the option of closing them from inside the toplevel. I would like to make a button on the main window that closes all toplevel windows. How would I do this? Is there a way to do this without lists? If these toplevels are parts of classes is there also a way to call a function present in all of them?
Here's how to do the first part of your question about making a button in the main window to delete all the Toplevels without making a list of them. This works by using the universal winfo_children() widget method to find all the child widgets of the root (main) window.
It's unclear to me what you meant about calling a function present in all of them — Toplevel widgets are instances of a predefined tkinter class which supports a predefined set of methods — and you can call them the same way the sample code below does with child.destroy().
import tkinter as tk
root = tk.Tk()
root.title('Main')
root.geometry('200x100')
def close_all(master):
for child in master.winfo_children():
if isinstance(child, tk.Toplevel):
child.destroy() # Call method.
button = tk.Button(root, text=f"Close Toplevels",
command=lambda master=root: close_all(master))
button.pack()
for i in reversed(range(4)): # Create them bottom to top.
toplevel = tk.Toplevel()
toplevel.title(f'Toplevel {i+1}')
toplevel.geometry('200x75')
toplevel.lift()
button = tk.Button(toplevel, text="Close me", command=toplevel.destroy)
button.pack()
root.mainloop()
So the code initially begins with a pop up asking you if you are ready, then once you select yes, a pop-up appears and if you try and close it, it will duplicate itself. Right now, it cannot duplicate itself.
Sorry if code is bad and riddled with mistakes (I'm just a beginner.) Thanks for helping.
from tkinter import *
from tkinter import messagebox
def a():
window2 = Tk()
offset = 300 + 1*10
window2.geometry('250x50+'+str(offset)+'+'+str(offset))
window2.title('')
window2.resizable(False, False)
la = Label(window2,text = 'ccmeockeoowpeokv.').pack()
button = Button(window2, text = 'OK', command = a()).pack()
def begining():
window = Tk()
window.eval('tk::PlaceWindow %s center' %window.winfo_toplevel())
window.withdraw()
if messagebox.askyesno("heh", "Ready?.") == True:
a()
window.deiconify()
window.destroy()
window.quit()
begining()
Do NOT ever insert Tk() if there are the absolute root of application, because it's just gonna make a new App, and NOT a new Window
The only method is using Toplevel()
Here, i explain you a bit
What is Toplevel()?
The Toplevel() widget is used to create and display the toplevel windows which are directly managed by the window manager
What is the function of Toplevel()?
The function of Toplevel() is to create a new window, without using Tk(). The Tk() and Toplevel() is almost same, but Toplevel() is to create a new window, without even create new application, if you watch some tutorial, the Tk() function is used to be creating a new application
What is the difference between Toplevel() and Tk()?
Tk() is the absolute root of the application, it is the first widget that needs to be instantiated and the GUI will shut down when it is destroyed. Toplevel() is a window in the application, closing the window will destroy all children widgets placed on that window but will not shut down the program
I suggest you to read more of the docs, or watch some tkinter tutorials on Youtube
Happy coding!
#snakes and ladder
from tkinter import * #pygame is the module that has collections of functions that is used to create a window import everything from tkinter
import time
class window(Frame): #Frame comes from tkinter is what you think as a window
def __init__(self, master = None):#The master widget defines the settings upon initialisation
Frame.__init__(self, master) #This is called the frame class that has been built in python
self.master = master
def __init__window(self): #creation of the init window
self.master.title("Reagan Kambayi") #It changes the title of the title of our widget
self.pack(fill=BOTH, expand=1)#The pack function will pack this in our frame
#placing the button
stop = Button(self, master, message= "Stop")
#intialising the button that will start the stopwatch
stop.place(x=0, y=0)
screen = Tk() #It must be written with capitalised T because there will be an error and it holds the components of the tkinter module
screen.geometry("700x500")
app = window(screen) #The app variable is assigned to the window creation which has the tkinter module
screen.mainloop()
Ok, here we go.
from tkinter import * #pygame is the module that has collections of functions that is used to create a window import everything from tkinter
Pygame has nothing to do with tkinter and you're not importing pygame here, you're importing tkinter.
class window(Frame): #Frame comes from tkinter is what you think as a window
No, it isn't. A Frame widget is just that, a frame inside a window. It doesn't draw a window in and of itself. The parameter Frame in your example isn't even a Frame widget at all, it's value is Tk() which is the function called to draw the first window in tkinter.
def __init__(self, master = None):#The master widget defines the settings upon initialisation
I'm actually at a loss for what you're attempting to do here. master should equal Frame which equals screen which equals Tk() but if I'm correct you're overriding that and telling it to equal None?
Frame.__init__(self, master) #This is called the frame class that has been built in python
I don't think you're doing what you think you're doing here. This answer explains it better than I could.
def __init__window(self): #creation of the init window
If I'm reading your program correctly then window.__init__window() is never called, so none of this function ever actually happens.
self.pack(fill=BOTH, expand=1)#The pack function will pack this in our frame
You're attempting to call .pack() on self which is calling .pack() on Frame. Typically we wouldn't assign a value to self in this way (although this is valid), read this to find out what self should be used for.
#placing the button
stop = Button(self, master, message= "Stop")
This isn't placing the Button widget, this is assigning the Button widget to a variable. Also, Button widgets are declared as Button(parent, *attributes) and there is no message attribute built in. Meaning what you meant to call was Button(self.master, text="Stop").
#intialising the button that will start the stopwatch
stop.place(x=0, y=0)
This is where you're placing the button, but the function that contains this is never called, so it never happens.
app = window(screen) #The app variable is assigned to the window creation which has the tkinter module
What you're actually doing here is calling the class window, all this does in your current program is call window.__init__(), which in itself does essentially nothing.
This is meant with no offence but I think you're lacking a very basic understanding of tkinter and possibly even Pythonic OOP.
I believe what you're trying to do in your program is the below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.root.title("Reagan Kambayi")
self.stop = Button(self.root, text="Stop")
self.stop.place(x=0, y=0)
root = Tk()
App(root)
root.mainloop()
Every time I use this code in my applications:
tkMessageBox.showinfo("Test", "Info goes here!")
a message box pops up (like it is supposed to), but after I click OK, the box disappears along with most of the other widgets on the window. How do I prevent the other widgets from disappearing?
Here Is My Code:
from Tkinter import *
import tkMessageBox
root = Tk()
root.minsize(600,600)
root.maxsize(600,600)
p1 = Label(root, bg='blue')
p1.place(width=600, height=600)
b1 = Button(p1, text="Test Button")
b1.place(x="30", y="50")
tkMessageBox.showinfo("Test", Info")
root.mainloop()
Ok, there are a few things going wrong here. First, your label has no string or image associated with it. Therefore, it's width and height will be very small. Because you use pack, the containing widget (the root window) will "shrink to fit" around this widget and any other widgets you pack in the root window.
Second, you use place for the button which means its size will not affect the size of the parent. Not only that, but you place the button inside the very tiny label. Thus, the only thing controlling the size of the parent is the label so the main window ends up being very small.
You have another problem is that you're showing the dialog before entering the event loop. I'm a bit surprised that it even works, but Tkinter sometimes does unusual things under the covers. You should enter the event loop before calling the dialog.
Try this variation of your code as a starting point:
from Tkinter import *
import tkMessageBox
def showInfo():
tkMessageBox.showinfo("Test","Info")
root = Tk()
p1 = Label(root, bg='blue', text="hello")
p1.pack()
b1 = Button(root, text="Test Button", command=showInfo)
b1.pack()
root.mainloop()