Tkinter:代码停止并且窗口不显示

时间:2018-03-29 15:25:09

标签: python tkinter

我正在使用Tkinter在Python上创建一个非常基本的界面,它显示两个输入框和一个登录按钮。我尝试通过创建不同的帧来做到这一点,并在用户登录时更改帧。它工作得很好,但后来代码开始执行自己不是完全有时和完全,但没有Tkinter窗口。我看着它,没有看到任何令人震惊但我不是专家所以我正在寻求帮助。 这是运行我的类实现Tkinter窗口的代码:

print 1
app = Skeleton("HomePage")
print 2
app.mainloop()
print 3

实现Tkinter窗口的骨架类:

class Skeleton(Tk):
def __init__(self, f,*args, **kwags):
    Tk.__init__(self,*args, **kwags)
    self.title(f)
    container = Frame(self, width=512, height=512)
    container.pack(side="top", fill="both", expand=True)
    container.grid_rowconfigure(0, weight=1)
    container.grid_columnconfigure(0, weight=1)   
    self.frames = {}
    frameName = {"home","upload","retrieve","deconnected"}
    self.frames["HomePage"] = HomePage(parent= container, controller=self)
    self.frames["HomePage"].grid(row=0, column=0, sticky="nsew")
    print 321
    self.show_frame("HomePage")

def show_frame(self, page_name):
    '''Show a frame for the given page name'''
    print "Je vais te montrer mon frame" 
    frame = self.frames[page_name]
    frame.tkraise()

主页框架的代码:

class HomePage(Frame):
def __init__(self, parent, controller):
    Frame.__init__(self, parent)
    self.parent = parent
    self.controller = controller
    #print ("Construction de la page dáccueil")
    #LABEL
    self.username = Label(self, text="Username:")
    self.username.grid(row =0,column =0)
    self.username.pack()

    #ENTRY
    self.username_txb = Entry( self)
    self.username_txb.focus_set() 
    self.username_txb.grid(row =0,column =1)
    self.username_txb.pack(side=LEFT)

    #LABEL
    self.pass_lbl = Label(self, text="Password:")
    self.pass_lbl.grid(row =0,column =2)

    #ENTRY 
    self.password_txb = Entry( self, text="Password", show = "*")
    self.password_txb.grid(row =0,column =3)
    self.password_txb.pack(side=LEFT)

    #LOGIN BUTTON
    self.login_btn = Button(self, text="Login", command=lambda: controller.show_frame("UploadPage"))
    self.login_btn.grid(row =0,column =4)
    self.login_btn.pack(side=LEFT)


    self.info_pane = PanedWindow()
    self.info_pane.grid(row =1,column =0)
    self.info_pane.pack(fill="none", expand=True, side=BOTTOM)
    self.info_lbl = Label(self, text="More information about access:", fg="blue", cursor="hand2")
    self.contact_lbl = Label(self, text="Contact us", fg="blue", cursor="hand2")
    self.contact_lbl.grid(row =2,column =0)
    self.contact_lbl.pack()
    self.contact_lbl.bind("<Button-1>", self.callback)
    print ("123Construction de la page dáccueil")
    #self.parent.update()


def callback(self, event):
    pass 

def connect(self,controller ):
    login = self.username_txb.get()
    pwd = self.password_txb.get()
    if(login == "a" and pwd == "a"):
        print "Valid account"  
        self.controller.show_frame("UploadPage")
        #UploadPage frame is implemented

每次执行代码时的输出如下:

  

1   123Construction de lapagedáccueil

提前感谢您的帮助。希望这会有助于其他人。

1 个答案:

答案 0 :(得分:1)

首先,让我们解决您对pack()grid()的使用问题。 由于tkinter的设置方式,您不能同时在框架或窗口中的同一个窗口小部件上同时使用pack()grid()

您可以使用例如pack()将主框架和grid()打包到该框架内的小部件上,但不能在框架的侧面使用它们。

如果您的某个问题出现在每个窗口小部件的位置,并且是否随窗口扩展,您可以管理grid()内的所有内容,因此我们可以在此处使用grid()作为我喜欢的内容在编写GUI时。

接下来,我们需要查看您对show_frame的来电,因为您试图在您向我们提供的代码中显示self.frames中不存在的框架。

我创建了一个新类,因此可以使用以下代码行测试您的程序: self.controller.show_frame("UploadPage")

新类只是制作一个带有标签的基本框架,显示框架在tkrise()处正确显示。

我做了一些常规清理,因为你的show_frame方法正在采取不必要的步骤来提升框架,导入tkinter的方法不是最佳选择和其他一些质量修正。

而不是使用:

frame = self.frames[page_name]
    frame.tkraise()

我们可以用这样的一行来简化这个方法:

self.frames[page_name].tkraise()

我还更改了导入tkinter的方式,因为如果你无意中覆盖了build in方法,导入时有时会导致问题。最好的选择是导入tkinter,如下所示:

import tkinter as tk

请查看以下代码,如果您有任何疑问,请与我们联系。它应该提供您需要的信息,以使HomePage框架和UploadPage框架按预期工作。

import tkinter as tk


class Skeleton(tk.Tk):
    def __init__(self, f,*args, **kwags):
        tk.Tk.__init__(self,*args, **kwags)
        self.title(f)
        self.container = tk.Frame(self, width=512, height=512)
        self.container.grid(row=0, column=0, sticky="nsew")
        self.container.grid_rowconfigure(0, weight=1)
        self.container.grid_columnconfigure(0, weight=1) 

        self.frames = {}
        self.frames["HomePage"] = HomePage(parent=self.container, controller=self)
        self.frames["HomePage"].grid(row=0, column=0, sticky="nsew")
        self.frames["UploadPage"] = UploadPage(parent=self.container)
        self.frames["UploadPage"].grid(row=0, column=0, sticky="nsew")

        self.show_frame("HomePage")

    def show_frame(self, page_name):
        self.frames[page_name].tkraise()

class HomePage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.controller = controller

        self.username = tk.Label(self, text="Username:")
        self.username.grid(row =0,column =0)
        self.username_txb = tk.Entry(self)
        self.username_txb.focus_set() 
        self.username_txb.grid(row=0, column=1)

        self.pass_lbl = tk.Label(self, text="Password:")
        self.pass_lbl.grid(row =0,column =2)
        self.password_txb = tk.Entry(self, text="Password", show="*")
        self.password_txb.grid(row =0,column =3)

        self.login_btn = tk.Button(self, text="Login", command=self.connect)
        self.login_btn.grid(row=0, column=4)

        self.info_pane = tk.PanedWindow()
        self.info_pane.grid(row=1, column=0)
        self.info_lbl = tk.Label(self, text="More information about access:", fg="blue", cursor="hand2")
        self.contact_lbl = tk.Label(self, text="Contact us", fg="blue", cursor="hand2")
        self.contact_lbl.grid(row=2, column=0)
        self.contact_lbl.bind("<Button-1>", self.callback)

    def callback(self, event):
        pass 
        # webbrowser.open_new("https://www.tno.nl/nl/")
        # I do not have the import for this webbrowser so I disabled it for testing.    

    def connect(self):
        login = self.username_txb.get()
        pwd = self.password_txb.get()
        if(login == "a" and pwd == "a"):
            self.controller.show_frame("UploadPage")

class UploadPage(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        tk.Label(self, text="This upload frame is a test to see if your code is working").grid(row=0, column=0)

if __name__ == "__main__":
    app = Skeleton("HomePage")
    app.mainloop()