Создание графического интерфейса Tkinter с использованием классов

#python #class #tkinter

#python #класс #tkinter

Вопрос:

Я хочу создать графический интерфейс в классе, который может создавать страницы, используя другой класс, который создает фреймы и виджеты. Страницы устанавливаются с использованием класса для них. Я хочу иметь возможность использовать графический интерфейс, чтобы иметь возможность переключаться между различными наборами страниц. Я не могу создать кнопку для класса Login_page, которая переключает Login_page с классом Sign_page.

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

Редактировать: произошло исключение: ошибка атрибута
объект ‘_tkinter.tkapp’ не имеет атрибута ‘root’
Онлайн

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

В этой строке

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

Я пытаюсь создать кнопку, используя класс, а команда из другого класса.

Комментарии:

1. Я редактирую его, чтобы включить конкретную проблему.

2. Предлагаю сделать maingui наследование от Tk .

3. как по мне, у вас слишком много mainloop() — найдено 3: in maingui.__init__() , in maingui.changepage() , in createWindow — но tkintner следует использовать только один mainloop()

4. всегда помещайте полное сообщение об ошибке (начинающееся со слова «Tracebak») в вопрос (не комментарий) в виде текста (не скриншота). Есть и другая полезная информация.

Ответ №1:

Поскольку вы передаете self.root (экземпляр Tk() ) maingui класса Login_Page и присваиваете его self.window . Затем self.window используется во maingui.changepage(self.window, 1) внутреннем Login_Page классе. Поскольку вы используете имя класса для доступа changepage() , self.window оно будет рассматриваться как self аргумент changepage() и использоваться в Sign_Page(self.root) . Это означает, что вы хотите получить доступ к атрибуту root self (экземпляру Tk() ), но Tk у него нет атрибута root .

Предлагаю создать maingui интерфейс из Tk , а не создавать его внутри __init__() .

Ниже приведен обновленный пример, основанный на вашем:

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

Ответ №2:

Вот рабочий код, я бы также посоветовал вам прочитать и попрактиковаться в занятиях, прежде чем двигаться дальше.

(Примечание: я не определил ваш метод clear и не добавил какой-либо новый метод, я только что исправил ваш существующий код и исправил вашу ошибку. вы можете дополнительно, если хотите, определить свой метод очистки и уничтожить свои виджеты).

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

обновление: вот способ переключения между страницами (в моем случае вы можете переключаться между страницей регистрации и входа в систему). нажмите «Войти», чтобы перейти к регистрации, и наоборот.

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

Комментарии:

1. как по мне, у вас слишком много mainloop() — найдено 3 : in main() , in changepage() , in createWindow — но tkintner следует использовать только один mainloop()

2. @furas да, я забыл удалить их thx для указания.