【发布时间】:2014-12-16 05:31:08
【问题描述】:
我希望以 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()
【问题讨论】:
-
为什么将代码放在类中,而不是放在包含该类的模块中?
-
我假设如果我导入了 GUI 类并且 tkinter 导入代码不在 GUI 类中,那么在创建 GUI 类的实例时它将被忽略。
-
你从哪里得到这样的印象?我不认为这是真的。此外,您根本不需要使用
__import__。你可以直接到import Tkinter as TK并捕获同样的错误。 -
将它移出类定义似乎已经完成了。为什么类定义之外的代码会被执行?不应该只执行 GUI 类中的代码吗?
-
我认为您误解了 Python 中导入的工作方式。在此站点上查找有关此的其他问题。当您执行
from view import GUI时,将执行view.py的全部。