Как поднять класс кадра из класса кадра в Tkinter - PullRequest
0 голосов
/ 06 октября 2019

Я пытался поднять свой второй кадр из первого класса фреймов после того, как первый был поднят из корневого класса, но каждый раз выдается ошибка Тип объекта 'root' не имеет атрибута 'tk' . Но я могу поднять свой второй кадр из корневого класса, но это не то, что я хочу. Я хотел бы поднять каждый последующий кадр из предыдущего кадра, так как я хочу, чтобы 4 кадра поднимались по всей программе много раз с условиями. Если я думаю, что все это неправильно, пожалуйста, предоставьте обходной путь, ниже приведен мой код.

import mysql.connector as sql
from os import getenv
from datetime import date
from ttkthemes import themed_tk as ttkt
from tkinter import ttk
import tkinter as tk
from tkinter import messagebox as mg

class root(ttkt.ThemedTk):
    def __init__(self, *args):
        ttkt.ThemedTk.__init__(self, *args)
        self.geometry('800x450')
        self.resizable(0, 0)
        self.set_theme('arc') #equilux
        self.config(background = '#EFEFEF')
        self.navbar()
        self.show_frame(home_first) 
#### I'm able to call Class_second frame from changing the value here

    def show_frame(self, cont):
        frame = cont(self)
        frame.pack(side = 'right', expand = True, fill= 'both', ipadx = 210)
        frame.tkraise()

    def show_Class_frame(self):
        self.show_frame(self, Class_second)

    def about(self):
    ....

    def session(self): 
    ....

    #NAVBAR______________________________
    def navbar(self):
        fl = tk.Frame(self, background = '#0077CC')
        fl.pack(side = 'left', expand = 1, fill= 'both')
        #NAVBAR's internal items______________________________
        ....

class home_first(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        ....
        btnt = ttk.Button(btnfrm, text = 'Teachers', style = 'fntb.TButton', command = self.tch_sel)
        # I want to use these to get to second frame
        btnt.pack(pady = (0,8))
        btns = ttk.Button(btnfrm, text = 'Students', style = 'fntb.TButton', command = self.std_sel)
        btns.pack()

    def tch_sel(self):
        sel = 0 #for teachers direct to page 3 not Class_second Frame
        root.show_Class_frame(root)

    def std_sel(self):
        sel = 1 #for students move to Class_second frame
        root.show_Class_frame(root)

class Class_second(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

class vote_third(tk.Frame):
    pass #from here i need to bring 4th frame

class done_fourth(tk.Frame):
    pass #here there will be like 3 button each going either to Home, Class or Vote frames
if __name__ == '__main__':
    app = root()
    app.mainloop()

Traceback

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Sagar\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "d:\Code\Python\py_project_votm\vm_vot_main_oop.py", line 76, in tch_sel
    root.show_Class_frame(root)
  File "d:\Code\Python\py_project_votm\vm_vot_main_oop.py", line 31, in show_Class_frame
    self.show_frame(self, Class_second)
  File "d:\Code\Python\py_project_votm\vm_vot_main_oop.py", line 26, in show_frame
    frame = cont(self)
  File "d:\Code\Python\py_project_votm\vm_vot_main_oop.py", line 84, in __init__
    tk.Frame.__init__(self, parent)
  File "C:\Users\Sagar\Anaconda3\lib\tkinter\__init__.py", line 2744, in __init__
    Widget.__init__(self, master, 'frame', cnf, {}, extra)
  File "C:\Users\Sagar\Anaconda3\lib\tkinter\__init__.py", line 2292, in __init__
    BaseWidget._setup(self, master, cnf)
  File "C:\Users\Sagar\Anaconda3\lib\tkinter\__init__.py", line 2262, in _setup
    self.tk = master.tk
AttributeError: type object 'root' has no attribute 'tk'

Кроме того, кто-то может сказать мне, что другие способы будутлучше сделать эту программу. Извините за плохой английский.

1 Ответ

0 голосов
/ 06 октября 2019

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

В частности, все ваши классы должны начинаться с заглавной буквы (Root, Vote_third, Done_fourth). Когда мы читаем ваш код и видим что-то вроде root.some_method(), мы предполагаем, что вы вызываете some_method() для экземпляра. Однако в вашем случае вы вызываете его для самого класса.

Проблема заключается в следующей строке:

root.show_Class_frame(root)

root - это класс ,не экземпляр класса. Этот параметр в конечном итоге становится хозяином другого виджета, но вы не можете использовать класс в качестве мастера. Вы должны использовать экземпляр класса виджета в качестве мастера.

Вы уже создаете экземпляр root с именем app. Вместо того, чтобы звонить root.show_Class_frame(), вам нужно звонить app.show_Class_frame.

def tch_sel(self):
    sel = 0 #for teachers direct to page 3 not Class_second Frame
    app.show_Class_frame()

def std_sel(self):
    sel = 1 #for students move to Class_second frame
    app.show_Class_frame()

Также, как упоминалось в комментариях, self.show_frame(self, Class_second) необходимо изменить на self.show_frame(Class_second).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...