【发布时间】:2018-04-29 19:24:28
【问题描述】:
我昨天参加了一场当地的编程比赛,参加了一个由 4 人组成的团队,成员的技能水平各不相同。我们试图制作一个基于文本的 Zork 风格的游戏,但由于 UI 是我创建的 GUI 类别之一,但我没有使用 Python 的经验。我使用了 Tkinter,并且大部分都在 GUI 内部工作,但不知道如何让 GUI 与其余代码交互。
我只是在这里包含相关的部分,部分原因是其余的代码非常混乱,没有 cmets 和很多语法错误,但如果需要,我可以发布它。代码如下:
def pinput():
global e
player_input = e.get()
print(player_input)
def progress():
hallway_1()
def hallway_1():
global player_input
global prin
global e
prin.set("You are in a hallway. Yellow lockers line the sides of all walls and you see three doors. One leads into a Library, one to a History classroom, and one to a Math room. You can 1.) Search the hallway or 2.) Procede to one of the rooms.")
while player_input != "1" and player_input != "2": #Best guess at a way to get the code to wait for input, actually just causes code to freeze
pass
if player_input == "1": #Even if 1 is in the entry box beforehand, it never gets here
prin.set("You search through the lockers and find 1 health potion.\n Would you like to add it to your inventory? 1.) Yes 2.) No")
player_input = "999"
def player_attack():
global enemy_hp
enemy_hp -= player_strength
prin.set("You just attacked the " + enemy_name + "!")
def player_block():
global block
prin.set("You predict that your enemy is going to attack and decide to block")
block = 1
def player_use():
global player_item_use
global item_name
player_item_use = 100
prin.set("You decide to use one of your items. What do you use?")
while player_turn_input != 0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 or 17 or 18 or 19 or 20 or 21 or 22 or 23 or 24 or 25 or 26:
player_item_use = e.get()
time.sleep(1)
item_name = Inventory[player_item_use]
item(item_name)
def run_away():
global player_hp
global lost_item_1
global lost_item_2
prin.set("You decide to run away from the " + enemy_name + "!\nThis causes you to lose 20 health points and two inventory items.")
player_hp -= 20
if backpack == True:
lost_item_1 = random.randint(1,27)
lost_item_2 = random.randint(1,27)
else:
lost_item_1 = random.randint(1,9)
lost_item_2 = random.randint(1,9)
RemoveInventory(lost_item_1)
RemoveInventory(lost_item_2)
library()
top = tk.Tk()
prin = tk.StringVar()
#path = "smalllibrary.png"
#tkimage = ImageTk.PhotoImage(Image.open(path))
#displayimage = tk.Label(top, image=tkimage).grid(row=0)
inv = tk.Text(top, width="24")
inv.grid(row=0, column=1)
for x in Inventory:
inv.insert("end", str(x) + str(invnum) + '\n')
invnum += 1
healthbar = tk.Label(top, text=("Health: " + str(player_hp))).grid(row=1, column=1)
text = tk.Label(top, bg="black", fg="white", textvariable=prin, justify="left", cursor="box_spiral").grid(row=1, sticky="w")
e = tk.Entry(top)
e.grid(row=2)
e.focus_set()
Attack = tk.Button(top, text ="Attack", activebackground="red", width="10", command = player_attack).grid(row=4, sticky="e")
Block = tk.Button(top, text ="Block", activebackground="red", width="10", command = player_block).grid(row=5, sticky="e")
Use = tk.Button(top, text ="Use Item", activebackground="red", width="10", command = player_use).grid(row=4, column=1, sticky="w")
Run = tk.Button(top, text ="Run", activebackground="red", width="10", command = run_away).grid(row=5, column=1, sticky="w")
Enter = tk.Button(top,text='Enter',command=pinput).grid(row=3)
Progress = tk.Button(top, text="Progress", activebackground="green",
prin.set("REDACTED")#This had my team's full names
top.mainloop()
所以,有一些问题。出于测试目的,我添加了“进度”按钮,理想情况下游戏将从走廊 1 开始。但是,我无法弄清楚将 hallway_1() 函数放在哪里才能使其工作。在 top.mainloop() 之前,GUI 不会打开。之后,e.get() 抛出了 TCL 错误。
所以,我将它绑定到一个按钮。但是,现在即使在代码运行之前将 1 输入到输入框中,代码也会一直卡在“while”循环中。我对此感到困惑,因为 Visual Studio 在“自动”框中将 player_input 报告为“1”,但它仍然在循环中运行。
【问题讨论】:
-
您不能在 GUI 事件处理程序中执行像这样的
while循环。在您从处理程序函数返回之前,GUI 不会更新其显示、接受用户输入或执行任何其他操作,这意味着一旦您到达那里,player_input将永远不会改变。处理程序函数需要做一件事,设置未来处理程序所需的任何内容,然后立即返回。 -
好的,我明白了,但我仍然不明白为什么即使 player_input 等于 '1' 也会运行循环
-
啊,这又是一个问题——你只是在
pinput中忘记了global player_input,所以你只是创建了一个同名的局部变量。全局变量不是"1"。但是,鉴于您在这里的代码,这应该会引发NameError。 -
啊,好的,谢谢!!