简体   繁体   English

使用类制作 Tkinter Gui

[英]Make a Tkinter Gui using classes

I want to create a GUI in a class that can create pages using another class that creates frames and widgets.我想在 class 中创建一个 GUI,它可以使用另一个创建框架和小部件的 class 创建页面。 The pages are set using a class for them.这些页面是使用 class 为它们设置的。 I want to be able to GUI to be able to switch between the different set of pages.我希望能够 GUI 能够在不同的页面集之间切换。 I can't create a button for the class of the Login_page that with switch the Login_page with the class of the Sign_page.我无法为 Login_page 的 class 创建一个按钮,该按钮将 Login_page 与 Sign_page 的 class 切换。

from tkinter import *
import random

class maingui:
    def __init__(self,title, geometry,):
        self.root = Tk()
        self.root.title(title)
        self.root.geometry(geometry)
        self.pageshow = Login_Page(self.root)
        self.root.mainloop()
    def changepage(self, page):
        self.page = page
        if self.page == 0:
            self.pageshow = Login_Page(self.root)
        if self.page == 1:
            self.pageshow = Sign_Page(self.root)
        self.root.mainloop()



class createWindow:
    def __init__(self,root, title, geometry,):
        self.root = root
        self.root.title(title)
        self.root.geometry(geometry)
        self.root.mainloop()
    
class createFrame:
    def __init__(self,window):
        self.window = window
        self.frame = Frame(self.window)
        self.frame.pack()
        print('c')
    def clear(self):
        pass
    def createlabel(self,message,postion = None):
        self.message =message
        self.postion = postion
        self.label= Label(self.frame, text =self.message)
        if self.postion == None:
            self.label.pack()
            print('a')
        else:
            print('b')
    def createbutton(self, text, command):
        self.text = text
        self.command = command
        self.button = Button(self.frame, text = self.text, command =self.command)

class Login_Page():
    def __init__(self,window):
        self.window = window
        self.frame = createFrame(self.window)
        self.frame.createlabel("Hello World")
        self.frame.createbutton("1",maingui.changepage(self.window,1))
class Sign_Page():
    def __init__(self,window):
        self.window = window
        self.frame = createFrame(self.window)
        self.frame.createlabel("Hello ")       

maingui = maingui("Rpg", "400x400") 

Edit: Exception has occurred: AttributeError '_tkinter.tkapp' object has no attribute 'root' On line编辑:发生异常:AttributeError '_tkinter.tkapp' object has no attribute 'root' Online

if self.page == 1:
      self.pageshow = Sign_Page(self.root)

On this line在这条线上

self.frame.createbutton("1",maingui.changepage(self.window,1))

I try to create a button using a class and the command is from a different class.我尝试使用 class 创建一个按钮,该命令来自不同的 class。

Here is a working code, I would also suggest you read and practice classes before moving further.这是一个工作代码,我还建议您在进一步移动之前阅读和练习课程。

( Note : I have not defined your clear method or added any new method, I have just corrected your existing code and rectified your error. you may further if you want, define your clear method and destroy your widgets). 注意:我没有定义您的清除方法或添加任何新方法,我只是更正了您现有的代码并纠正了您的错误。如果您愿意,可以进一步定义您的清除方法并销毁您的小部件)。

from tkinter import *
import random

class maingui:
    def __init__(self, root, title, geometry):

        self.root = root
        self.root.title(title)
        self.root.geometry(geometry)
        self.pageshow = Login_Page(self, self.root)
      
    def changepage(self, page):
        self.page = page
        
        if self.page == 0:
            self.pageshow = Login_Page(self, self.root)

        if self.page == 1:
            self.pageshow = Sign_Page(self, self.root)

class createWindow:
    def __init__(self,root, title, geometry):
        self.root = root
        self.root.title(title)
        self.root.geometry(geometry)
      
class createFrame:
    def __init__(self, parent, window):
        self.window = window
        self.frame = Frame(self.window)
        self.frame.pack()
        self.label = Label(self.frame)
        self.button = Button(self.frame)
        self.parent = parent
        

    def clear(self):
        pass

    def createlabel(self,message,postion = None):
        self.message =message
        self.postion = postion
        self.label.config(text=self.message)
        
        if self.postion == None:
            self.label.pack()
        
        else:
           pass


    def createbutton(self, text='Login', cmd=0):
        self.text = text

        self.button.configure(text=self.text, command=lambda :self.parent.changepage(cmd))
        self.button.pack()

class Login_Page():
    def __init__(self, parent, window):
        self.window = window
        self.frame = createFrame(parent, self.window)
        self.frame.createlabel("Hello World bye")
        self.frame.createbutton("Welcome", 1)


class Sign_Page():
    def __init__(self, parent, window):
        self.window = window
        self.frame = createFrame(parent, self.window)
        self.frame.createlabel("Hello ")       


def main():
    root = Tk()
    maingui(root, "Rpg", "400x400")
    root.mainloop()
    
if __name__ =='__main__':
    main()

update : here is a way you can switch between pages(in my case you can switch between the sign-up and login page).更新:这是一种您可以在页面之间切换的方式(在我的情况下,您可以在注册页面和登录页面之间切换)。 click on login it will direct you to sign-up and vice-versa.点击登录,它将引导您注册,反之亦然。

from tkinter import *
import random

class maingui:
    def __init__(self, root, title, geometry):

        self.root = root
        self.root.title(title)
        self.root.geometry(geometry)
        self.pageshow = Login_Page(self, self.root)
      
    def changepage(self, page):
        self.page = page
        
        if self.page == 0:
            #del self.pageshow
            self.pageshow = Login_Page(self, self.root)

        if self.page == 1:
            #del self.pageshow
            self.pageshow = Sign_Page(self, self.root)


class Login_Page:
    def __init__(self, parent, window):
        
        self.parent = parent
        
        self.frame = Frame(window)
        self.frame.pack()

        self.welcm_lbl = Label(self.frame, text='welcome')
        self.welcm_lbl.grid(row=0, column=1)

        self.name_lbl = Label(self.frame, text='name:')
        self.name_lbl.grid(row=1, column=0)

        self.name_entry = Entry(self.frame)
        self.name_entry.grid(row=1, column=1)

        self.sbt = Button(self.frame, text='login', command=self.clicked)
        self.sbt.grid(row=2, column=1)

    def clicked(self):
        self.frame.destroy()
        self.parent.changepage(1)
        

class Sign_Page():
    def __init__(self, parent, window):

        self.parent = parent
        
        self.frame = Frame(window)
        self.frame.pack()

        self.welcm_lbl = Label(self.frame, text='welcome sign-up')
        self.welcm_lbl.grid(row=0, column=1)

        self.name_lbl = Label(self.frame, text='name:')
        self.name_lbl.grid(row=1, column=0)

        self.name_entry = Entry(self.frame)
        self.name_entry.grid(row=1, column=1)

        self.sbt = Button(self.frame, text='sign-up', command=self.clicked)
        self.sbt.grid(row=2, column=1)      

    def clicked(self):
        self.frame.destroy()
        self.parent.changepage(0)
        
    
def main():
    root = Tk()
    maingui(root, "Rpg", "400x400")
    root.mainloop()
    
if __name__ =='__main__':
    main()

Since you pass self.root (instance of Tk() ) of maingui class to Login_Page and assign it to self.window .由于您将self.root的 self.root ( Tk()的实例)传递给maingui并将self.window Login_Page Then self.window is used in maingui.changepage(self.window, 1) inside Login_Page class.然后在self.window class 内的maingui.changepage(self.window, 1)Login_Page Since you use class name to access changepage() , self.window will be treat as the self argument of changepage() and used in Sign_Page(self.root) .由于您使用 class 名称来访问changepage()self.window将被视为changepage()self参数并在Sign_Page(self.root)中使用。 That means you want to access the attribute root of self (instance of Tk() ) but Tk does not have attribute root .这意味着您想访问self的属性rootTk()的实例)但Tk没有属性root

Suggest to make maingui interit from Tk instead of creating it inside __init__() .建议从Tk制作maingui interit 而不是在__init__()中创建它。

Below is an updated example based on yours:以下是基于您的更新示例:

from tkinter import *
#import random

class maingui(Tk):
    def __init__(self, title, geometry):
        super().__init__()
        self.title(title)
        self.geometry(geometry)
        self.pageshow = Login_Page(self)
    def changepage(self, page):
        self.page = page
        if self.page == 0:
            self.pageshow = Login_Page(self)
        if self.page == 1:
            self.pageshow = Sign_Page(self)

class createFrame:
    def __init__(self,window):
        self.window = window
        self.frame = Frame(self.window)
        self.frame.pack()
        print('c')
    def clear(self):
        pass
    def createlabel(self,message,postion = None):
        self.message =message
        self.postion = postion
        self.label= Label(self.frame, text =self.message)
        if self.postion == None:
            self.label.pack()
            print('a')
        else:
            print('b')
    def createbutton(self, text, command):
        self.text = text
        self.command = command
        self.button = Button(self.frame, text = self.text, command =self.command)
        self.button.pack() ###

class Login_Page():
    def __init__(self,window):
        self.window = window
        self.frame = createFrame(self.window)
        self.frame.createlabel("Hello World")
        ###self.frame.createbutton("1", maingui.changepage(self.window, 1)) ###
        self.frame.createbutton("1", lambda: self.window.changepage(1)) ###

class Sign_Page():
    def __init__(self,window):
        self.window = window
        self.frame = createFrame(self.window)
        self.frame.createlabel("Hello ")       

maingui = maingui("Rpg", "400x400") 
maingui.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM