我希望在MVC模式中将以下代码放在自己的文件(view.py)中。我将有一个初始化对象的控制器,然后调用main函数:
from view import GUI
gui = GUI()
gui.main()
然后GUI类确保正确导入tkinter以便它可以绘制gui。就目前而言,尝试运行控制器代码会导致以下错误:
> python controller.py
trying to load Tkinter
loading Tkinter failed, trying tkinter instead
Loading gui
main method
Traceback (most recent call last):
File "controller.py", line 9, in <module>
gui.main()
File "[...]\view.py", l
ine 31, in main
self.root = TK.Tk()
NameError: name 'TK' is not defined
这是view.py:
class GUI:
#import Tkinter # no underscore, uppercase 'T' for versions prior to V3.0
#import tkinter # no underscore, lowercase 't' for V3.0 and later
try:
print("trying to load Tkinter")
TK = __import__(Tkinter)
except:
print("loading Tkinter failed, trying tkinter instead")
TK = __import__("tkinter")
#from tkinter import N, S, E, W, END
def __init__(self):
print("Loading gui")
def main(self):
print("main method")
# Tk root widget: window with titlebar, etc
self.root = TK.Tk()
# Tk buttons frame (left hand side)
buttonsFrame = TK.Frame(self.root)
buttonsFrame.grid(row=0, column=0, sticky=TK.N+TK.S+TK.E+TK.W)
# Tk buttons:
self.buttonLoad = TK.Button(buttonsFrame, text="Load Recipes", command=self.actionLoad)
#more buttons
self.buttonLoad.grid(row=0, column=0, sticky=TK.N+TK.S+TK.E+TK.W)
#loading more buttons
self.root.mainloop()
def actionLoad(self):
print("\"Load Recipes\" pressed")
我担心这部分问题是由于缺乏对oop和python哲学的某种组合的理解,但我很高兴能够接受这两种教学。
我希望将tkinter加载为类变量而不是实例变量会使其更容易解决,但这似乎没有成功。
编辑:这是似乎正确运行的更新后的view.py
try:
print("trying to load Tkinter")
import Tkinter as TK
from Tkinter import N, S, E, W, END
except ImportError:
print("loading Tkinter failed, trying tkinter instead")
import tkinter as TK
from tkinter import N, S, E, W, END
class GUI:
#import Tkinter # no underscore, uppercase 'T' for versions prior to V3.0
#import tkinter # no underscore, lowercase 't' for V3.0 and later
#from tkinter import N, S, E, W, END
def __init__(self):
print("Loading gui")
def main(self):
print("main method")
# Tk root widget: window with titlebar, etc
self.root = TK.Tk()
# Tk buttons frame (left hand side)
buttonsFrame = TK.Frame(self.root)
buttonsFrame.grid(row=0, column=0, sticky=N+S+E+W)
# Tk buttons:
self.buttonLoad = TK.Button(buttonsFrame, text="Load Recipes", command=self.actionLoad)
self.buttonAdd = TK.Button(buttonsFrame, text="Add Recipe", command=self.actionAdd)
self.buttonModify = TK.Button(buttonsFrame, text="Modify Recipe", command=self.actionModify)
self.buttonRemove = TK.Button(buttonsFrame, text="Remove Recipe", command=self.actionRemove)
self.buttonQuit = TK.Button(buttonsFrame, text="Quit", command=self.actionQuit)
# have to assign the layout via grid later because .grid doesn't return a type which messes up stuff like .insert()
self.buttonLoad.grid(row=0, column=0, sticky=N+S+E+W)
self.buttonAdd.grid(row=1, column=0, sticky=N+S+E+W)
self.buttonModify.grid(row=2, column=0, sticky=N+S+E+W)
self.buttonRemove.grid(row=3, column=0, sticky=N+S+E+W)
self.buttonQuit.grid(row=4, column=0, sticky=N+S+E+W)
# Tk recipe listbox (b/c of TK.EXTENDED, it supports selection of any combination of entries)
self.recipeList = TK.Listbox(self.root, selectmode=TK.EXTENDED)
# have to assign the layout via grid later because .grid doesn't return a type which messes up stuff like .insert()
self.recipeList.grid(row=0, column=2, sticky=N+S+E+W, rowspan=10, columnspan=10)
# populate listbox
for option in range(0,5):
self.recipeList.insert(TK.END, "option " + str(option))
self.root.mainloop()
def actionLoad(self):
print("\"Load Recipes\" pressed")
return "load"
def actionAdd(self):
print("\"Add Recipe\" pressed")
return "add"
def actionRemove(self):
print("\"Remove Recipe\" pressed")
return "remove"
def actionModify(self):
print("\"Modify Recipe\" pressed")
return "modify"
def actionQuit(self):
quit()
答案 0 :(得分:2)
原始代码抛出NameError
关于&#39; TK
&#39;未定义的是您将其导入类(静态)变量。因此,要使原始代码正常工作,请执行以下操作:
TK
替换为GUI.TK
,无论在哪里使用(请参阅下面此答案的评论中的讨论)。try...except
块移到包含该类的模块中,方法是将其放在view.py
文件的顶部(参见问题评论中的讨论)。但是,我认为你应该避免使用__import__
(文档说&#34;这是日常Python编程中不需要的高级函数&#34;)。请尝试以下方法:
try:
print("trying to load Tkinter")
import Tkinter as TK
except ImportError:
print("loading Tkinter failed, trying tkinter instead")
import tkinter as TK
您可以将上面的块放在类中,就像之前一样(在这种情况下使用GUI.TK
无处不在),或者在模块中的类之外。我认为您应该将导入放在文件的顶部,就像您在更新的帖子中所做的那样(PEP 8建议&#34;导入始终放在文件的顶部&#34;)。
另请注意ImportError
的使用。最好在此处捕获特定的异常,而不是捕获所有异常(请参阅https://wiki.python.org/moin/HandlingExceptions中的&#34;常规错误捕获&#34;部分)。