Python GUI中根据用户输入的数字使用任意数量的可使用文本框

57 阅读3分钟

在编写一个Python程序作为骰子游戏的评分系统时,遇到一个问题,该游戏可以参与的玩家数量不确定,因此需要通过用户输入来指定。可以使用GUI来实现,但遇到一个问题,就是如何根据用户输入的玩家数量,在GUI中创建对应数量的可使用文本框,以供输入每个玩家的得分。

最初尝试使用for循环来创建文本框,但发现这样做的结果是所有文本框都共享同一个变量名,导致只有最后一个创建的文本框可以使用。

2、解决方案

为了解决这个问题,可以使用一个更加灵活的方式来创建文本框,具体步骤如下:

  1. 创建一个函数来动态生成文本框变量名,该函数可以接受一个数字参数,并返回一个字符串,字符串格式为“PlayerXroundScore”,其中X是数字参数。

  2. 在GUI中使用一个循环来创建文本框,并在循环中调用上一步创建的函数来生成每个文本框的变量名。

  3. 在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中创建任意数量的可使用文本框,并且可以动态获取每个文本框的值。