我正在尝试使用tkinter创建一个游戏,在该游戏中,玩家将其姓名输入到条目小部件中。
输入名称后,用户应按Enter键以调用“ player_names”功能,理想情况下,该功能会将玩家名称保存在列表中,删除条目小部件中的文本,然后继续进行下一个循环(即玩家) 。
该脚本似乎正在忽略绑定,而直接移至“ self.name_entry.destroy()”行。如何确保脚本在继续之前先等待命令?
def initialise_game(self, num_of_players):
self.players_list = []
for i in range(num_of_players):
player_num = i+1
self.name_label = tk.Label(self.bg_label, text='What is the name'
' of Player ' + str(player_num) + '?')
self.name_label.grid(row=0, padx=200, pady=120)
self.name_entry = tk.Entry(self.bg_label)
self.name_entry.grid(row=1, padx=200, pady=0)
self.name_entry.bind('<Return>', self.player_names)
self.name_entry.destroy()
def player_names(self, event):
self.players_list.append(self.name_entry.get())
self.name_entry.delete(0, 'end')
答案 0 :(得分:2)
Entry
不能像input()
那样工作,它不会停止代码并等待您输入文本并按Enter。 GUI
创建Entry
,并在Entry
之后立即执行代码。您有bind
来分配要按Enter键执行的功能,该功能应从Entry中获取值,并替换小部件(或仅Label中的文本)。它还应该删除最后一个玩家之后的Entry
,以便您必须计算执行功能的次数(或已经拥有多少玩家-self.player_num
)
我没有测试这段代码,但是应该可以。
def initialise_game(self, num_of_players):
self.players_list = []
# remeber values in class variables, not local one
self.num_of_players = num_of_players
self.player_num = 0
# create only one Label - and change text in it
self.name_label = tk.Label(self.bg_label,
self.name_label.grid(row=0, padx=200, pady=120)
# create only one Entry and assign function `self.player_names`
self.name_entry = tk.Entry(self.bg_label)
self.name_entry.grid(row=1, padx=200, pady=0)
self.name_entry.bind('<Return>', self.player_names)
# set text for first player
self.player_num += 1
self.name_label["text"] = 'What is the name of Player {} ?'.format(player_num)
def player_names(self, event):
# get player's name from Entry
self.players_list.append(self.name_entry.get())
self.name_entry.delete(0, 'end')
# set text for next player or destroy Entry after last player
self.player_num += 1
if self.player_num <= self.num_of_players:
self.name_label["text"] = 'What is the name of Player {} ?'.format(player_num)
else:
self.name_label.destroy()
self.name_entry.destroy()
与在其他GUI(不仅适用于tkinter
)和其他语言(不仅适用于Python
)中使用的方式相同
答案 1 :(得分:0)
我对您要完成的目标的想法应该是相同的,从一位玩家开始逐个输入直到所有玩家都添加了名字。
代码的问题是for
,它需要在没有玩家输入的情况下变得精打细算(技术上),指示我选择了tkinter拥有的更新机制,并在winget中更改了值,winget将会更新自身我将按钮的增量更改为绑定值。
如果您想重用i
,请将其引用为def
的开头
此示例有效,initialise_game
的输入与之前相同,替换中间的conde效果很好,除非您的代码使用.grid()
然后替换ask_name.pack()
< / p>
import tkinter as tk
root = tk.Tk()
root.bg_label = tk.Frame(root)
# Added code, top and bottom are for testing
#--------------------------------------------------------------------------------
root.players_list = [] # Global variabe witch can be accesd by all funcions
i = 1 # This global value is to keep a clear reference on the count of windows
def initialise_game(self, num_of_players):
ask_name = tk.Frame(self)
L = tk.Label(ask_name, text=('What is the name of Player ' + str(i) + '?'))
L.grid(row=0, padx=200, pady=120)
E = tk.Entry(ask_name)
def modify_entry(NULL):
root.players_list.append(E.get())
E.delete(0, 'end')
global i # Change the "search" of values to outside the funtion
i += 1
L.config(text=('What is the name of Player ' + str(i) + '?'))
if (i > num_of_players): # Close the Frame wen all were answered
root.players_list.append(E.get())
ask_name.destroy()
E.bind('<Return>', modify_entry)
E.grid(row=1, padx=200, pady=0)
ask_name.pack() # You can replace it with grin , this moves the Label + Entry were u want
#--------------------------------------------------------------------------------
initialise_game(root.bg_label, 3)
root.bg_label.pack()
root.mainloop()