我有Label
textvariable
是StringVar
,最初设置为0.按下某个按钮后,我希望Label
更新为#dictionary module contains some custom functions
#to be used later
from dictionary import *
import os
import pickle
from tkinter import *
#file_path is what will be the text
#for the entry box
file_path = ''
#SampleApp allows for frames to be stacked on top of each other
class SampleApp(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, ProcessPage, ReviewPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, c):
'''Show a frame for the given class'''
frame = self.frames[c]
frame.tkraise()
#The first page the user sees, has a dynamic label which shows
#the number of words in the dictionary
class StartPage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
#Variable string for the word number
self.Total_words_text = StringVar()
self.Total_words_text.set('Total number of words in dictionary: 0')
Total_words = Label(self, textvariable = self.Total_words_text)
Total_words.pack()
#This button leads to another page allowing user to process
#more text files
Add_more_words_btn = Button(self, text ='Add more words',
command=lambda: controller.show_frame(ProcessPage))
Add_more_words_btn.pack(side = LEFT, anchor = 's',expand = TRUE, fill = X)
#Goes to the flash-card game
Review_btn = Button(self, text='Review',
command=lambda: controller.show_frame(ReviewPage))
Review_btn.pack(side = LEFT, anchor = 's',expand = TRUE, fill = X)
#This page allows the user to process more documents
#and increase the word count
class ProcessPage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
Instruction_label = Label(self, text = 'Please enter the path of your text-file below:')
Instruction_label.pack(side = 'top')
self.Path_box = Entry(self, textvariable = file_path)
self.Path_box.pack(expand = True, fill = 'x')
Browse_btn = Button(self, text = 'Browse', command = self.browse_text)
Browse_btn.pack(expand = True, fill = 'x')
Process_btn = Button(self, text = 'Process', command = self.process_path)
Back_btn = Button(self, text = 'Back',
command=lambda: controller.show_frame(StartPage))
Process_btn.pack(side='left', fill='x', expand = True, anchor='sw')
Back_btn.pack(side='right', fill='x', expand = True, anchor='se')
#This function is what the "Browse" Button does, it pulls
#up a file browser, allows the user to select a file,
#then puts the path of the file into the entry box
def browse_text(self):
global file_path
from tkinter.filedialog import askopenfilename
filename = filedialog.askopenfilename()
file_path = os.path.normpath(filename)
self.Path_box.delete(0, END)
self.Path_box.insert(0, file_path)
#This function is bound to the "Process" button
#It gets the path from the entry box, and processes
#the document, it then loads the freq_dict, and updates
#the label's textvariable in the start page
def process_path(self):
path_name = self.Path_box.get()
process_book(path_name)
self.Path_box.delete(0, END)
freq_dict = load_dict('svd_f_dict')
dict_words_num = len(freq_dict.keys())
StartPage.Total_words_text.set(dict_words_num)
#WIP, will allow user to play a SRS flash-card game
class ReviewPage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
Start_btn = Button(self, text = 'Start Review')
Back_btn = Button(self, text = 'Back',
command=lambda: controller.show_frame(StartPage))
Define_btn = Button(self, text = 'Define new words')
Start_btn.pack()
Back_btn.pack(side='left', fill='x', expand = True, anchor='se')
Define_btn.pack(side = 'right', fill = 'x', expand = True, anchor = 'sw')
if __name__ == "__main__":
app = SampleApp()
app.mainloop()`
来自按钮的相关信息。我先来看一下代码:
freq_dict
该程序应该采用用户指定的外语文本文件,对其进行处理(通过分解,计数,排序,然后构建包含文本文件中所有唯一单词的字典)。
我想要的是开始页面,以显示频率字典中的单词总数。最初它应该为零(因为没有处理过文档),然后在处理文档时,应根据pickle频率字典中的键数(称为>>>
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
return self.func(*args)
File "C:\Users\User 3.1\Desktop\Code Projects\test.py", line 105, in process_path
StartPage.Total_words_text.set(dict_words_num)
AttributeError: type object 'StartPage' has no attribute 'Total_words_text'
>>>
)更新标签。问题是我不知道如何制作它,以便每当按下过程按钮时文本变量实际更新。我上面尝试的内容返回以下错误:
{{1}}
答案 0 :(得分:1)
在self.controller = controller
中设置__init__
,然后使用self.controller.frames[StartPage]
访问StartPage
中ProcessPage.process_path
的实例:
import functools
class ProcessPage(Frame):
def __init__(self, parent, controller):
...
self.controller = controller
Process_btn = Button(
self, text = 'Process',
command = self.process_path)
def process_path(self):
...
self.controller.frames[StartPage].Total_words_text.set(dict_words_num)
您的代码无效的原因是因为Total_words_text
是一个
StartPage
的实例的属性,而不是该类的属性
StartPage
。
每个帧都传递给控制器,SampleApp的一个实例。
SampleApp实例具有指向StartPage实例的属性self.frames[StartPage]
。因此controller.frames[StartPage].Total_words_text
将访问所需的Total_words_text属性。