【问题标题】:How to call a new GUI or form inside a GUI or form in python?如何在 python 中的 GUI 或表单中调用新的 GUI 或表单?
【发布时间】:2016-06-18 23:34:54
【问题描述】:

我正在尝试使用 python 中的套接字编程创建一个简单的聊天服务器。我正在使用 Tkinter 构建 GUI。这是我的问题,我有一个 login.py 文件,它让我看到登录的形式。然后我有这个 signup.py 。现在,当我单击按钮注册时,我想从登录表单导航到注册表单。请帮忙!这是我的示例代码。只是为了导航。

login.py

from Tkinter import *
import Signup

class Login():
    def __init__(self):
        self.root = Tk()
        self.root.title("Welcome to Login")
        self.btnSignup = Button(self.root, text="Not a member? Sign up now!", relief=FLAT,
                                borderwidth=1, font=("Century Gothic",11,'normal'),
                                command = self.callSignup, fg="white",bg="#0866c6", 
                                activebackground="#404040",activeforeground="white")
        self.btnSignup.place(width = 250, height = 25, x = 10, y = 10)
        self.root.mainloop()

    def callSignup(self):
        self.root.destroy()
        self.obj = Signup.signup("james")
        self.obj.display()

signup.py

from Tkinter import *

class signup():
    def __init__(self,name):
        self.name = name

    def display(self):
        self.root = Tk()
        self.root.title("Welcome " + self.name)            
        self.root.mainloop()

当我运行代码时,我可以打开注册表格。但是登录时的 self.root.destroy(),py 不起作用!请帮我!谢谢。

【问题讨论】:

  • 您的问题是点击注册按钮时登录窗口没有关闭吗?如果是这样,则移动破坏线以首先调用然后创建注册对象。
  • 谢谢兄弟!这解决了我的问题,我没有想到那个方法,因为我认为它会破坏整个程序,并且它不会执行代码来调用 obj 来显示另一种形式。谢谢! :)
  • 欢迎您。问题是当你创建一个新的 Tk 实例时,它会导致一个无限循环(root.mainloop),所以它永远不会到达销毁线。

标签: python forms python-2.7 user-interface tkinter


【解决方案1】:

我将使用 2 种方法解决您的问题。

所以基本上,你正在寻找这个:

  • 用户点击注册按钮:

  • 点击必须提示注册窗口:

第一种方法:

第一种方法建议重新设计您的应用程序:我的意思是,出于此任务的目的(实际上),您最好将窗口收集在同一个模块中,而不是两个单独的 login.pysignup.py 模块。我更喜欢从方法开始,因为它的第二个优点是简单地解决您的问题。让我们调用我们的模块loginsignup.py

在类的构造函数中,在构造函数中设置Frame小部件:

def __init__(self, parent):
        Tkinter.Frame.__init__(self, parent)
        self.parent = parent

为了更好的设计,最好将 GUI 设计分离到一个单独的函数中,我们称之为 initialize_membership_interface()。当然,这个方法必须在上面的构造函数体中调用:

def __init__(self, parent):
        Tkinter.Frame.__init__(self, parent)
        self.parent = parent
        self.initialize_membership_interface()

initialize_membership_interface() 实例化 2 个按钮和一个标签。使用grid() 方法在框架内组织这3 个小部件:

def initialize_membership_interface(self):
        self.parent.title('Membership Area')
        self.parent.grid_rowconfigure(0, weight = 1)
        self.parent.grid_columnconfigure(0, weight = 1)
        self.parent.config(background = "lavender")    

        self.label_welcome = Tkinter.Label(self.parent,text="Not a member? Please sign up: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_welcome.grid(row = 0, columnspan = 2, stick = Tkinter.E + Tkinter.W)

        self.button_signup = Tkinter.Button(self.parent,font="Helvetica 10 bold", text = "Sign up", command = self.signup)
        self.button_signup.grid(row = 1, column = 0, sticky = Tkinter.E + Tkinter.W)
        self.button_cancel_signup = Tkinter.Button(self.parent,text = "Cancel",font="Helvetica 10 bold", command = self.parent.quit)
        self.button_cancel_signup.grid(row = 1, column = 1, sticky = Tkinter.E + Tkinter.W)

然后我们编写第二个方法,例如,signup() 来绘制第二个 GUI,以正确显示订阅元素。

1.第一个技巧:

但是您的问题是如何将self.button_signup 绑定到signup() 方法。您可以使用command 修饰符解决此问题:

self.button_signup = Tkinter.Button(command = self.signup)

2。第二招:

您面临的第二个问题的解决方案是使用Toplevel() 方法将上面的第二个(最大)窗口显示为第一个(小)窗口的子窗口:

def signup(self):
        self.signup_window = Tkinter.Toplevel(self)
        self.signup_window.wm_title("Sign up Area")
        self.signup_window.grid_rowconfigure(0, weight = 1)
        self.signup_window.grid_columnconfigure(0, weight = 1)
        # Member's first name
        self.label_firstname = Tkinter.Label(self.signup_window,text="First name: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_firstname.grid(row = 0, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_firstname = Tkinter.Entry(self.signup_window)
        self.entry_firstname.grid(row = 0, column = 1)
        # Member's last name
        self.label_lastname = Tkinter.Label(self.signup_window,text="Last name: ", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_lastname.grid(row = 1, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_lastname = Tkinter.Entry(self.signup_window)
        self.entry_lastname.grid(row = 1, column = 1)
        # Member's email
        self.label_email = Tkinter.Label(self.signup_window,text="Email: ", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_email.grid(row = 2, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_email = Tkinter.Entry(self.signup_window)
        self.entry_email.grid(row = 2, column = 1)
        # Member's password
        self.label_password = Tkinter.Label(self.signup_window,text="Password: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_password.grid(row = 3, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_password = Tkinter.Entry(self.signup_window, show = "*")
        self.entry_password.grid(row = 3, column = 1)        
        # Member's repeat password
        self.label_repeat_password = Tkinter.Label(self.signup_window,text="Repeat password: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_repeat_password.grid(row = 4, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_repeat_password = Tkinter.Entry(self.signup_window, show = "*")
        self.entry_repeat_password.grid(row = 4, column = 1)

        self.button_submit = Tkinter.Button(self.signup_window,text="Submit",font="Helvetica 10 bold")
        self.button_submit.grid(row = 5, column = 0, sticky = Tkinter.E + Tkinter.W)
        self.button_cancel_submit = Tkinter.Button(self.signup_window,text = "Cancel",font="Helvetica 10 bold", command = self.parent.quit)
        self.button_cancel_submit.grid(row = 5, column = 2, sticky = Tkinter.E + Tkinter.W)

3.完整应用:

这是在一个模块中编码的完整应用程序:

'''
Created on Mar 6, 2016

@author: Bill Begueradj
'''

import Tkinter

class Begueradj(Tkinter.Frame):
    '''Define a GUI for membership subscription.    
    '''
    def __init__(self, parent):
        '''Set the constructor.
        Set the parent Frame widget.
        Call initialize_membership_interface() to draw the GUI
        '''
        Tkinter.Frame.__init__(self, parent)
        self.parent = parent
        self.initialize_membership_interface()

    def initialize_membership_interface(self):
        ''' Draw a simplistic GUI consisting of 2 buttons.
        The user clicks on the sign up button to land on the second
        window dedicated for the subscription process.
        The user may click on the cancel button to leave 
        the application.
        '''
        self.parent.title('Membership Area')
        self.parent.grid_rowconfigure(0, weight = 1)
        self.parent.grid_columnconfigure(0, weight = 1)
        self.parent.config(background = "lavender")    

        self.label_welcome = Tkinter.Label(self.parent,text="Not a member? Please sign up: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_welcome.grid(row = 0, columnspan = 2, stick = Tkinter.E + Tkinter.W)

        self.button_signup = Tkinter.Button(self.parent,font="Helvetica 10 bold", text = "Sign up", command = self.signup)
        self.button_signup.grid(row = 1, column = 0, sticky = Tkinter.E + Tkinter.W)
        self.button_cancel_signup = Tkinter.Button(self.parent,text = "Cancel",font="Helvetica 10 bold", command = self.parent.quit)
        self.button_cancel_signup.grid(row = 1, column = 1, sticky = Tkinter.E + Tkinter.W)

    def signup(self):
        '''Design the subscription window.
        Bind this child window to the main one using Tkinter.Toplevel()
        '''
        self.signup_window = Tkinter.Toplevel(self)
        self.signup_window.wm_title("Sign up Area")
        self.signup_window.grid_rowconfigure(0, weight = 1)
        self.signup_window.grid_columnconfigure(0, weight = 1)
        # Member's first name
        self.label_firstname = Tkinter.Label(self.signup_window,text="First name: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_firstname.grid(row = 0, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_firstname = Tkinter.Entry(self.signup_window)
        self.entry_firstname.grid(row = 0, column = 1)
        # Member's last name
        self.label_lastname = Tkinter.Label(self.signup_window,text="Last name: ", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_lastname.grid(row = 1, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_lastname = Tkinter.Entry(self.signup_window)
        self.entry_lastname.grid(row = 1, column = 1)
        # Member's email
        self.label_email = Tkinter.Label(self.signup_window,text="Email: ", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_email.grid(row = 2, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_email = Tkinter.Entry(self.signup_window)
        self.entry_email.grid(row = 2, column = 1)
        # Member's password
        self.label_password = Tkinter.Label(self.signup_window,text="Password: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_password.grid(row = 3, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_password = Tkinter.Entry(self.signup_window, show = "*")
        self.entry_password.grid(row = 3, column = 1)        
        # Member's repeat password
        self.label_repeat_password = Tkinter.Label(self.signup_window,text="Repeat password: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_repeat_password.grid(row = 4, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_repeat_password = Tkinter.Entry(self.signup_window, show = "*")
        self.entry_repeat_password.grid(row = 4, column = 1)

        self.button_submit = Tkinter.Button(self.signup_window,text="Submit",font="Helvetica 10 bold")
        self.button_submit.grid(row = 5, column = 0, sticky = Tkinter.E + Tkinter.W)
        self.button_cancel_submit = Tkinter.Button(self.signup_window,text = "Cancel",font="Helvetica 10 bold", command = self.parent.quit)
        self.button_cancel_submit.grid(row = 5, column = 2, sticky = Tkinter.E + Tkinter.W)

def main():
    root = Tkinter.Tk()
    b = Begueradj(root)
    b.mainloop()
# Start of the main program
if __name__ == "__main__":
    main()

第二种方法:

第二种方法是将前一种方法拆分为两个独立的login.pysignup.py,因此尊重您自己的设计。

1. signup.py:

这里保留我们重命名的之前的 signup() 方法。为方便起见,通过signup.py 模块中的subscribe(),但您需要将Tkinter.Frame 小部件传递给此模块的唯一类的构造函数,以便能够使用Toplevel() 方法:

def __init__(self, parent):
    Tkinter.Frame.__init__(self, parent)
    self.parent = parent

2。 login.py

此模块包含之前的initialize_membership_interface() 方法。

这里的主要技巧是如何绑定 signup.pysubscribe() 方法并成功地将 login.py 模块的主要 Tkinter.Frame 小部件传递给 @987654359 @ 按钮。这样做是这样的:

self.button_signup = Tkinter.Button(self.parent, text = "Sign up", command = signup.Signup(self.parent).subscribe)

3.完整应用:

以下是两个模块的内容:

  • signup.py

当然,main方法(程序的开始)与这个模块无关:

'''
Created on Mar 6, 2016

@author: Bill BEGUERADJ
'''

import Tkinter

class Signup(Tkinter.Frame):

    def __init__(self, parent):
        # This will allow to pass the main Frame widget as an argument
        # to Signup class
        Tkinter.Frame.__init__(self, parent)
        self.parent = parent

    def subscribe(self):
        self.signup_window = Tkinter.Toplevel(self.parent)
        self.signup_window.wm_title("Sign up Area")
        self.signup_window.grid_rowconfigure(0, weight = 1)
        self.signup_window.grid_columnconfigure(0, weight = 1)
        # Member's first name
        self.label_firstname = Tkinter.Label(self.signup_window,text="First name: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_firstname.grid(row = 0, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_firstname = Tkinter.Entry(self.signup_window)
        self.entry_firstname.grid(row = 0, column = 1)
        # Member's last name
        self.label_lastname = Tkinter.Label(self.signup_window,text="Last name: ", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_lastname.grid(row = 1, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_lastname = Tkinter.Entry(self.signup_window)
        self.entry_lastname.grid(row = 1, column = 1)
        # Member's email
        self.label_email = Tkinter.Label(self.signup_window,text="Email: ", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_email.grid(row = 2, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_email = Tkinter.Entry(self.signup_window)
        self.entry_email.grid(row = 2, column = 1)
        # Member's password
        self.label_password = Tkinter.Label(self.signup_window,text="Password: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_password.grid(row = 3, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_password = Tkinter.Entry(self.signup_window, show = "*")
        self.entry_password.grid(row = 3, column = 1)        
        # Member's repeat password
        self.label_repeat_password = Tkinter.Label(self.signup_window,text="Repeat password: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_repeat_password.grid(row = 4, column = 0, stick = Tkinter.E + Tkinter.W)
        self.entry_repeat_password = Tkinter.Entry(self.signup_window, show = "*")
        self.entry_repeat_password.grid(row = 4, column = 1)

        self.button_submit = Tkinter.Button(self.signup_window,text="Submit",font="Helvetica 10 bold")
        self.button_submit.grid(row = 5, column = 0, sticky = Tkinter.E + Tkinter.W)
        self.button_cancel_submit = Tkinter.Button(self.signup_window,text = "Cancel",font="Helvetica 10 bold", command = self.parent.quit)
        self.button_cancel_submit.grid(row = 5, column = 2, sticky = Tkinter.E + Tkinter.W)
  • login.py

main方法必须在这个模块中执行:

'''
Created on Mar 6, 2016

@author: Bill BEGUERADJ
'''
import Tkinter
import signup

class Begueradj(Tkinter.Frame):
    '''Define a GUI for membership subscription.
    '''
    def __init__(self, parent):
        '''Set the constructor.
        Set the parent Frame widget.
        Call initialize_membership_interface() to draw the GUI
        '''
        Tkinter.Frame.__init__(self, parent)
        self.parent = parent
        self.initialize_membership_interface()

    def initialize_membership_interface(self):
        ''' Draw a simplistic GUI consisting of 2 buttons.
        The user clicks on the sign up button to land on the second
        window dedicated for the subscription process.
        The user may click on the cancel button to leave 
        the application.
        '''
        self.parent.title('Membership Area')
        self.parent.grid_rowconfigure(0, weight = 1)
        self.parent.grid_columnconfigure(0, weight = 1)
        self.parent.config(background = "lavender")    

        self.label_welcome = Tkinter.Label(self.parent,text="Not a member? Please sign up: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_welcome.grid(row = 0, columnspan = 2, stick = Tkinter.E + Tkinter.W)

        self.button_signup = Tkinter.Button(self.parent,font="Helvetica 10 bold", text = "Sign up", command = signup.Signup(self.parent).subscribe)
        self.button_signup.grid(row = 1, column = 0, sticky = Tkinter.E + Tkinter.W)
        self.button_cancel_signup = Tkinter.Button(self.parent,text = "Cancel",font="Helvetica 10 bold", command = self.parent.quit)
        self.button_cancel_signup.grid(row = 1, column = 1, sticky = Tkinter.E + Tkinter.W)


def main():
    ''' Define the main method.
    '''
    root = Tkinter.Tk()
    b = Begueradj(root)
    b.mainloop()

# Start of the main application
if __name__ == "__main__":
    main()

请注意,运行我在此处描述的两个版本的解决方案会产生这个 GUI:

如果您想获得与上面屏幕截图中相同的按钮视觉效果,您将需要使用这个sign up 和那个cancel 图像。

为了能够将这些图片加载到各自的按钮中,您需要先导入:

from PIL import Image, ImageTk

然后你需要将图片设置为两个按钮的背景:

# Setting images to the buttons
self.img_signup = ImageTk.PhotoImage(Image.open("img.png").resize((100,40),Image.ANTIALIAS))
self.img_cancel = ImageTk.PhotoImage(Image.open("cancel.png").resize((100,40), Image.ANTIALIAS))
self.button_signup = Tkinter.Button(self.parent, image = self.img_signup,command = self.signup)
self.button_signup.grid(row = 1, column = 0, sticky = Tkinter.E + Tkinter.W)
self.button_cancel_signup = Tkinter.Button(self.parent, image = self.img_cancel, command = self.parent.quit)
self.button_cancel_signup.grid(row = 1, column = 1, sticky = Tkinter.E + Tkinter.W)

【讨论】:

  • 多么棒的答案!是的,我终于使用 Steven Summers 的建议解决了它,但是我在 login.py 和 signup.py 中遇到了一个问题,所以我使用的是我将它们结合起来解决了我的问题。谢谢你的精彩解释! :)
猜你喜欢
  • 2015-07-21
  • 1970-01-01
  • 2012-07-21
  • 2012-01-15
  • 2011-04-23
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多