在从根类中提出第一帧后,我一直试图从第一类中提出第二帧,但是每次都会出错 类型对象“ 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()
追踪
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'
此外,有人可以告诉我还有什么其他方法可以更好地执行此程序。 对不起,英语不好。
答案 0 :(得分:0)
部分问题是您没有使用PEP8命名约定,这使您的代码难以阅读和理解。阅读代码时,我们会根据命名约定进行假设,而由于不使用命名约定,最终会做出错误的假设。
具体来说,您所有的课程都必须以大写字母(Root
,Vote_third
,Done_fourth
)开头。当我们阅读您的代码并看到类似root.some_method()
的内容时,我们假设您正在实例上调用some_method()
。但是,就您而言,您是在类本身上调用它。
问题是这一行:
root.show_Class_frame(root)
root
是一个类,而不是一个类的 instance 。该参数最终成为另一个小部件的母版,但是您不能将一个类用作母版。您必须使用小部件类的实例作为主实例。
您已经在创建名为root
的{{1}}实例。您无需致电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)
。