I am going through chapter 8 of the head first programming book by oreilly. I am getting ahead of myself here. The book only wants me to create the program so that it reads depots from a static txt file, but I wanted the option to change the file depots were imported from, and dynamically update the optionmenu withi the program.
我正在阅读OReilly的Head First编程一书的第8章。我在这里有点言过其实了。这本书只想让我创建一个程序,这样它就可以从静态的txt文件中读取仓库,但我想要的是更改导入仓库的文件的选项,并用程序动态更新选项菜单。
The problem I have is at line 28.
我遇到的问题是在第28行。
I get NameError: name 'tk' is not defined
What am I missing here?
我收到NameError:名称‘tk’未定义,我在这里遗漏了什么?
#import GUI
from tkinter import *
import tkinter.filedialog as filedialog
#define variables we will use for functions
global depot_fieldretrieve
global address_fieldretrieve
global item_desc_fieldretrieve
#define function for taking user input, storing it as a variable, then appending it to a file
def append_record():
file = open("deliveries.txt", "a")
depot_fieldretrieve = depotlocation.get()
item_desc_fieldretrieve = item_desc.get()
address_fieldretrieve = address.get("1.0",END)
file.write("Depot:\n%s\n" % (depot_fieldretrieve))
file.write("Item Description:\n%s\n" % (item_desc_fieldretrieve))
file.write("Address:\n%s\n" % (address_fieldretrieve))
depotlocation.set(None)
#define function for getting depots from text file and adding it to our menu
def read_depots():
depots = []
depots.clear()
somefile = filedialog.askopenfilename()
depotlist = open(somefile)
for line in depotlist:
om1['menu'].add_command(label=line.rstrip(), command=tk._setit(depotlocation, opt))
#define function for clearing fields when done
def clear_fields():
#clear the variable containing list of depots
om1['menu'].delete(0, END)
#clear the dropdown menu list of depots
depotlocation.set("")
#deselect depots
depotlocation.set(None)
#delete text in fields
item_desc.delete(0, END)
address.delete("1.0", END)
#Set up the GUI
app = Tk()
app.title("HeadEx shipment manifest")
#####WINDOW SIZE & SCALE CODE
#Get user's screen resolution
screenwidth = app.winfo_screenwidth()
screenheight = app.winfo_screenheight()
#Create variable that will determine how much the program is scaled, according to screen resolution
screenwidthforscaling = screenwidth/1000
#Set size of window based on screen resolution
programwidth = int(0.32 * int(screenwidth))
programheight = int(0.45 * int(screenheight))
#Scale the window
app.tk.call('tk', 'scaling', screenwidthforscaling)
app.geometry(f"{programwidth}x{programheight}")
#####DONE WITH SCALING CODE
#define the fields we will use, begin loop
b1 = Button(app, text = "Add", width = 10, command = append_record)
b1.pack(side = 'bottom')
b2 = Button(app, text = "Clear all", width=10, command = clear_fields)
b2.pack(side = 'bottom')
b3 = Button(app, text = "Add depots", width=10, command = read_depots)
b3.pack(side = 'bottom')
depotlabel = Label(app, text = "Depot:")
depotlabel.pack(side = 'top')
depotlocation = StringVar()
depotlocation.set(None)
om1 = OptionMenu(app, depotlocation, "")
om1.pack(side = 'top')
item_desc_label = Label(app, text = "Item description: ")
item_desc_label.pack(side = 'top')
item_desc = Entry(app)
item_desc.pack()
addresslabel = Label(app, text = "Destination address :")
addresslabel.pack()
address = Text(app)
address.pack()
app.mainloop()
If I use this on line 28:
如果我在第28行使用此命令:
om1['menu'].add_command(label=line.rstrip())
OM1[‘Menu’].add_Command(Label=line.rstrie())
it adds the labels for the options, but they're not usable. I click it, it doesn't work, and if I try to save info to the file using the append_record function it won't save anything for depot.
它为选项添加标签,但它们不可用。我点击它,它不起作用,如果我尝试使用append_record函数将信息保存到文件中,它不会为depot保存任何内容。
If I use this on line 28:
如果我在第28行使用此命令:
om1['menu'].add_command(label=line.rstrip(), command=app.tk._setit(depotlocation, opt))
OM1[‘Menu’].添加命令(Label=line.rstrid(),命令=app.tk._setit(depotLocation,opt))
I get
我得到
AttributeError: '_tkinter.tkapp' object has no attribute '_setit'
AttributeError:‘_tkinter.tkapp’对象没有属性‘_Setit’
更多回答
The tk
in tk._setit(...)
most probably is the alias name of the module tkinter
, so what you need is adding import tkinter as tk
. I think the code is copied from other example and you need to understand what you have copied. Also opt
in tk._setit(depotlocation, opt)
is undefined as well, it should be line.strip()
instead.
Tk中的tk_Stit(...)很可能是模块tkinter的别名,因此您需要将导入tkinter添加为tk。我认为代码是从其他示例复制的,您需要了解您复制了什么。此外,tk中的opt。_setit(depotLocation,opt)也是未定义的,它应该是line.strie()。
This was it. Thank you! I have 2 questions! 1st if I wanted to learn how to properly use .add_command, where would you look this up? When I check out the [tkinter documentation here][1] I see nothing mentioning it or anything like it but I have a feeling I am looking in the wrong place. Secondly, if I import tkinter using from tkinter import *
and on line 58 am using app.tk and it works there, why does .tk not work for _set.it method? I am confused as to when I need to import things differently so I don't make this mistake later! [1]: tkdocs.com/pyref/optionmenu.html
就是这样。谢谢!我有两个问题!1如果我想学习如何正确使用.add_命令,你会在哪里找到这个?当我查看[tkinter文档这里][1]时,我没有看到任何提及它或任何类似的东西,但我有一种感觉,我看错了地方。其次,如果我使用从tkinter import*导入tkinter,并在第58行使用app.tk导入tkinter,并且它在那里工作,为什么.tk不适用于_set.it方法?我不知道什么时候需要以不同的方式导入东西,这样我以后就不会犯这个错误了![1]:tkdocs.com/pyref/optionmenu.html
我是一名优秀的程序员,十分优秀!