Python 3.x 如何确保;绑定";在tkinter中未跳过订单?
我正在尝试使用tkinter创建一个游戏,在这个游戏中,玩家将自己的名字输入一个输入小部件 输入姓名后,用户应按enter键调用函数“player_names”,理想情况下,该函数将玩家姓名保存在列表中,删除条目小部件中的文本,然后继续下一个循环(即player) 脚本似乎忽略了绑定并直接移动到行“self.name\u entry.destroy()”。如何确保脚本在继续之前等待命令Python 3.x 如何确保;绑定";在tkinter中未跳过订单?,python-3.x,tkinter,Python 3.x,Tkinter,我正在尝试使用tkinter创建一个游戏,在这个游戏中,玩家将自己的名字输入一个输入小部件 输入姓名后,用户应按enter键调用函数“player_names”,理想情况下,该函数将玩家姓名保存在列表中,删除条目小部件中的文本,然后继续下一个循环(即player) 脚本似乎忽略了绑定并直接移动到行“self.name\u entry.destroy()”。如何确保脚本在继续之前等待命令 def initialise_game(self, num_of_players): self.pl
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')
def初始化游戏(自我,玩家数量):
self.players_list=[]
对于范围内的i(玩家数量):
玩家数量=i+1
self.name\u label=tk.label(self.bg\u label,text='name'
'玩家的'+str(玩家数量)+'?')
self.name\u label.grid(行=0,padx=200,pady=120)
self.name\u entry=tk.entry(self.bg\u标签)
self.name\u entry.grid(行=1,padx=200,pady=0)
self.name\u entry.bind(“”,self.player\u name)
self.name\u entry.destroy()
def播放器名称(自身、事件):
self.players\u list.append(self.name\u entry.get())
self.name\u entry.delete(0,'end')
条目
的工作方式与输入()不同
它不会停止编码并等待您输入文本并按enter键<代码>GUI创建条目
,并在条目
之后立即执行代码。您有bind
来分配将在按下Enter键时执行的函数,该函数应从输入中获取值,并替换小部件(或仅替换标签中的文本)。它还应该删除最后一个播放器之后的条目
,这样您就必须计算函数执行了多少次(或者您已经有多少个播放器-self.player\u 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()
def初始化游戏(自我,玩家数量):
self.players_list=[]
#记住类变量中的值,而不是局部变量
self.num_of_players=num_of_players
self.player_num=0
#只创建一个标签-并更改其中的文本
self.name\u label=tk.label(self.bg\u label,
self.name\u label.grid(行=0,padx=200,pady=120)
#只创建一个条目并分配函数“self.player\u name”`
self.name\u entry=tk.entry(self.bg\u标签)
self.name\u entry.grid(行=1,padx=200,pady=0)
self.name\u entry.bind(“”,self.player\u name)
#为第一个播放器设置文本
self.player_num+=1
self.name_label[“text”]=“Player{}的名称是什么?”格式(Player_num)
def播放器名称(自身、事件):
#从条目中获取玩家名称
self.players\u list.append(self.name\u entry.get())
self.name\u entry.delete(0,'end')
#为下一个玩家设置文本或在最后一个玩家之后销毁条目
self.player_num+=1
如果self.player_num我对你想要完成什么的想法应该是一样的,一个接一个地接受玩家的输入,直到所有玩家都添加了一个名字。
您的代码的问题是
的,它需要在没有玩家输入的情况下编译(技术),而我选择了tkinter拥有的更新机制,如果winget中的值发生变化,winget将更新自身,并且我绑定到按钮,从增量中更改值。
如果要重复使用i
,请在def
相同wey的开头引用它
此示例工作,IngalIsIsAdvase/Cuth>的输入与以前相同,在中间替换CONDE将工作正常,除非代码使用<代码> .GRID()/Case>,然后替换<代码> ASKYNAME.PACK()/<代码> < /P>
将tkinter作为tk导入
root=tk.tk()
root.bg_label=tk.Frame(root)
#添加代码,顶部和底部用于测试
#--------------------------------------------------------------------------------
root.players_list=[]#所有函数都可以访问全局变量开关
i=1#此全局值用于保持窗口计数的清晰参考
def初始化游戏(自我,玩家数量):
ask_name=tk.Frame(self)
L=tk.Label(询问_name,text=('Player'+str(i)+'?'的名字是什么?)
L.网格(行=0,padx=200,pady=120)
E=tk.条目(询问名称)
def修改_条目(空):
root.players\u list.append(E.get())
E.删除(0,“结束”)
全局i#将值的“搜索”更改为函数外部
i+=1
L.config(text=('Player的名字是什么'+str(i)+'?'))
如果(i>num_of_players):#关闭框架,所有人都得到了回答
root.players\u list.append(E.get())
问你的名字。销毁()
E.bind(“”,修改_条目)
E.网格(行=1,padx=200,pady=0)
询问_name.pack()#您可以将其替换为grin,这将移动您想要的标签+条目
#--------------------------------------------------------------------------------
初始化游戏(root.bg\u标签,3)
root.bg_label.pack()
root.mainloop()
entry
和bind
不像input()那样工作
。他们不会等待您的文本。他们只会通知mainloop它必须显示的小部件以及当您按下Enter
时mainloop必须执行的操作。他们不会停止代码,所以在输入后立即执行所有操作,绑定甚至会在您看到窗口之前执行,因为mainloop
会启动所有操作。如果您愿意的话在您按下eNet后销毁小部件,然后您必须在按下Enter键时执行的player_names
中执行。您的循环一次创建许多条目
,但它会将所有条目放在同一个单元格中,所以您看不到它。使用网格(row=i,…)
,您将在窗口中看到许多条目。
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()