tkinter: почему мое окно входа в систему находится не в том месте?

Я сделал 2 окна: main и login. Я хочу, чтобы кнопка и окно входа были на верхнем уровне, но всегда переходили в главное, почему? Если я пишу код в poplogin(), а не импортирую модуль, он работает правильно.

main.py
#! python3
from tkinter import *
from login import login

def demo():
    root = Tk()
    root.title("demo")
    root.geometry('640x400')  
    Button(root,text='login',width=10,command=poplogin).grid(row=3,column=1,padx=10,pady=5)
    root.mainloop()

def poplogin():
    toplevel = Toplevel()
    toplevel.grid()
    toplevel.title('login')
    login(toplevel)

if __name__ == "__main__":demo()

login.py
#! python3
from tkinter import *

class login(Frame):

    def __init__(self,parent=None):
        Frame.__init__(self,parent)
        self.creat_login()

    def creat_login(self):
        Label(text='email').grid(row=1)
        user_email = Entry()
        user_email.grid(row=1,column=1,padx=10,pady=5)

        Label(text='password').grid(row=2)
        user_password = Entry(show='*')
        user_password.grid(row=2,column=1,padx=10,pady=5)  

        Button(text='login',width=10).grid(row=3,column=1,padx=10,pady=5)


if __name__ == '__main__':
    login().mainloop()

person Python rookie    schedule 21.11.2016    source источник
comment
вы должны использовать parent в виджетах: Entry(parent, ...) и т. д. Если вы не используете родителя, то tkinter используйте главное окно.   -  person furas    schedule 21.11.2016
comment
@furas все в порядке, спасибо !!!   -  person Python rookie    schedule 21.11.2016
comment
@furas Наконец-то я добавил правильный код, но я не знаю, почему self.grid() не выглядит никаким эффектом?   -  person Python rookie    schedule 21.11.2016


Ответы (2)


Вы должны сообщить виджету, кто является его родителем - Widget(parent, ...). Если вы этого не сделаете, то tkinter используйте главное окно.

В вашем коде вы должны использовать self

И вы должны использовать self.pack(), чтобы показать Frame в Toplevel

#! python3

from tkinter import *

class login(Frame):

    def __init__(self, parent=None):
        Frame.__init__(self, parent)
        self.creat_login()

        # show in Toplevel
        self.pack()

    def creat_login(self):
        # self
        Label(self, text='email').grid(row=1)

        # self
        user_email = Entry(self)
        user_email.grid(row=1, column=1, padx=10, pady=5)

        # self    
        Label(self, text='password').grid(row=2)

        # self
        user_password = Entry(self, show='*')
        user_password.grid(row=2, column=1, padx=10, pady=5)  

         # self
        Button(self, text='login', width=10).grid(row=3, column=1, padx=10, pady=5)

if __name__ == '__main__':
    login().mainloop()
person furas    schedule 21.11.2016
comment
спасибо за ваш ответ, я пробую ваш код, поднимаю _tkinter.TclError: не могу использовать пакет менеджера геометрии внутри. у которого уже есть ведомые устройства, управляемые сеткой, поэтому я меняю self.pack() на self.grid(), но результат тот же, всегда в главном окне. - person Python rookie; 21.11.2016
comment
вы не можете использовать одновременно pack(), grid() или place() в одном окне или фрейме. Всегда показывать полное сообщение об ошибке. Возможно, проблема в другом месте, или вам также нужно изменить другой пакет () на сетку (). - person furas; 21.11.2016

правильный код

from tkinter import *

class login(Frame):

    def __init__(self, parent=None):
        Frame.__init__(self, parent)
        self.creat_login(parent)

        # With or without this line the same results,I don't know why 
        self.grid()

    def creat_login(self,parent):

        Label(parent, text='email').grid(row=1)

        user_email = Entry(parent)
        user_email.grid(row=1, column=1, padx=10, pady=5)

        Label(parent, text='password').grid(row=2)

        user_password = Entry(parent, show='*')
        user_password.grid(row=2, column=1, padx=10, pady=5)  

        Button(parent, text='login', width=10).grid(row=3, column=1, padx=10, pady=5)

if __name__ == '__main__':
    login().mainloop()
person Python rookie    schedule 21.11.2016
comment
это место для ответа, а не для вопроса. Добавьте это к своему вопросу. Также добавьте полное сообщение об ошибке (Traceback). - person furas; 21.11.2016
comment
этот код может работать, поэтому я публикую его. никаких сообщений об ошибках. - person Python rookie; 21.11.2016
comment
Я увидел комментарий в коде и подумал, что он не работает. Я вижу, вы используете parent вместо self, поэтому вы ставите прямо на верхний уровень, поэтому у вас могут быть проблемы с pack(). Я использую self, поэтому я вставил Frame, а не непосредственно в Toplevel, чтобы можно было использовать pack(). Вы бы описали разницу. - person furas; 21.11.2016