在编写一个Python程序作为骰子游戏的评分系统时,遇到一个问题,该游戏可以参与的玩家数量不确定,因此需要通过用户输入来指定。可以使用GUI来实现,但遇到一个问题,就是如何根据用户输入的玩家数量,在GUI中创建对应数量的可使用文本框,以供输入每个玩家的得分。
最初尝试使用for循环来创建文本框,但发现这样做的结果是所有文本框都共享同一个变量名,导致只有最后一个创建的文本框可以使用。
2、解决方案
为了解决这个问题,可以使用一个更加灵活的方式来创建文本框,具体步骤如下:
-
创建一个函数来动态生成文本框变量名,该函数可以接受一个数字参数,并返回一个字符串,字符串格式为“PlayerXroundScore”,其中X是数字参数。
-
在GUI中使用一个循环来创建文本框,并在循环中调用上一步创建的函数来生成每个文本框的变量名。
-
在GUI中使用一个按钮来触发计算总分的功能,并在按钮的事件处理函数中使用eval()函数来动态获取每个文本框的值,并进行计算。
以下是代码示例:
import tkinter as tk
def generate_variable_name(counter):
"""
生成文本框变量名
Args:
counter: 数字参数
Returns:
字符串,格式为“PlayerXroundScore”,其中X是数字参数
"""
return "Player" + str(counter) + "roundScore"
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.Title = ("10,000 scorekeeping")
self.Header = tk.Label(self, text="Welcome to 10,000 scoring Module, Have Fun!!", font=("helvetica", "20", "bold")).grid(row=0, column=0, columnspan=(NumPlayers * 3))
for NameCount in range(1, (NumPlayers+1)):
# Allows me to create the names as column headers
self.PlayerName = tk.Label(self, text="%s" %NameList[NameCount - 1],font=("helvetica","12","bold")).grid(row = 1, column = ((2 * NameCount)))
# This if just makes things more aesthetically pleasing, not relevant to my question
if NameCount < (NumPlayers):
self.PlayerName = tk.Label(self, text = "|",font = ("helvetica","12","bold")).grid(row = 1, column = ((2 * NameCount + 1)))
# This is my problem
# It succesffully prints the correct number of text boxes
# however upon button click which calls the vals in each text box
# only the last created box is useful
# because that is the box corresponding to PlayerXroundScore
variable_name = generate_variable_name(NameCount)
self.__dict__[variable_name] = tk.Entry(self, width=4)
self.__dict__[variable_name].grid(row=2, column=(2 * NameCount))
self.__dict__[variable_name].insert(0, "0000")
self.NextRound = tk.Button(self, text="Next round", command=self.CalcRoundTotals)
self.NextRound.grid(row=1, column=0)
def CalcRoundTotals(self):
for i in range(1, NumPlayers+1):
variable_name = generate_variable_name(i)
score = eval(variable_name + ".get()")
print(score)
if __name__ == "__main__":
NumPlayers = input("How many players? ")
NameList = [0] * NumPlayers
for i in range(0, NumPlayers):
x = input("Player %d Name? " % (i+1))
NameList[i] = x
a = App()
a.mainloop()
在以上代码中,我们使用generate_variable_name()函数来生成每个文本框的变量名,并在循环中使用self.dict[variable_name]来动态创建文本框。在按钮的事件处理函数CalcRoundTotals()中,我们使用eval()函数来动态获取每个文本框的值,并进行计算。
使用这种方法,就可以在GUI中创建任意数量的可使用文本框,并且可以动态获取每个文本框的值。