theatropos1994
theatropos1994

Reputation: 165

Python Tkinter Toplevel

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()

Upvotes: 1

Views: 3287

Answers (2)

Chris Barker
Chris Barker

Reputation: 2399

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().

Upvotes: 2

abarnert
abarnert

Reputation: 366113

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.

Upvotes: 2

Related Questions