【问题标题】:Python tkinter Entry widget usagePython tkinter Entry 小部件使用
【发布时间】:2016-04-30 06:38:30
【问题描述】:

我目前正在尝试使用 tkinter 中的条目小部件从用户那里获取一个数字,然后使用该数字来定义我的其他函数之一的参数。

代码很长,块后我会尝试总结一下自己的想法。

class NimGame():

    def __init__(self, numberOfBalls):
        self.numberOfBallsRemaining = numberOfBalls
        print("Nim game initialized with {} balls.".format(self.numberOfBallsRemaining))

    def remainingBalls(self):
        return self.numberOfBallsRemaining

    def take(self, numberOfBalls):
        if (numberOfBalls < 1) or (numberOfBalls > 3) or (numberOfBalls > self.numberOfBallsRemaining):
            print("You can't take that number of balls. Try again.")
            # ## Update Label in the GUI to tell user they can't take that many balls.
            # It might be better to "inactivate" the buttons that correspond to invalid number to take.
            statusLabel.configure(text="You can't take that number of balls. Try again.")
        else:
            self.numberOfBallsRemaining = self.numberOfBallsRemaining - numberOfBalls
            print("You took {} balls. {} remain.".format(numberOfBalls, self.numberOfBallsRemaining))
            if self.numberOfBallsRemaining == 0:
                print("Computer wins!")
            else:
                # ## After removing player-chosen balls, update graphics and then pause for 1.0 seconds
                # before removing computer-chosen balls.  This way the player can "see" the
                # intermediate status.  Perhaps think about a nicer way of showing this.
                updateGraphics()
                sleep(1.0)

                computerMaxBalls = min(3, self.numberOfBallsRemaining)
                compBallsTaken = random.randint(1,computerMaxBalls)
                self.numberOfBallsRemaining = self.numberOfBallsRemaining - compBallsTaken

                # ## After removing computer-chosen balls, update graphics again.
                updateGraphics()
                print("Computer took {} balls. {} remain.".format(compBallsTaken, self.numberOfBallsRemaining))
                if self.numberOfBallsRemaining == 0:
                    print("You win!")

def updateGraphics():
    canvas.delete('all')
    centerX = leftmostBallXPosition
    centerY = ballYPosition
    for i in range(nimGame.remainingBalls()):
        canvas.create_oval(centerX - halfBallSize,
                           centerY - halfBallSize,
                           centerX + halfBallSize,
                           centerY + halfBallSize,
                           fill="#9999ff")
        centerX = centerX + spaceBetweenBalls + ballSize
        canvas.update_idletasks()

def initializeNewGame():
    numberOfBalls = e1.get()
    initializeNimAndGUI(numberOfBalls)

def initializeNimAndGUI(numberOfBalls):
    global nimGame
    global ballSize, halfBallSize, spaceBetweenBalls, leftmostBallXPosition, ballYPosition

    nimGame = NimGame(numberOfBalls)

    canvas.delete('all') 
    ballSize = min(maxBallSize, int(((canvasWidth-canvasBorderBuffer)//numberOfBalls)/1.2))
    halfBallSize = ballSize // 2
    spaceBetweenBalls = int(0.2 * ballSize)
    leftmostBallXPosition = (canvasBorderBuffer//2) + (spaceBetweenBalls//2) + halfBallSize
    ballYPosition = canvasHeight // 2
    updateGraphics()

 def createGUI():
    global rootWindow
    global canvas
    global statusLabel
    global textEntry
    global e1

    rootWindow = Tk()
    canvasAndButtons = Frame(rootWindow)
    canvas = Canvas(canvasAndButtons, height=canvasHeight, width=canvasWidth, relief=SUNKEN, borderwidth=2)
    canvas.pack(side=LEFT)

    buttonframe = Frame(canvasAndButtons)
    e1 = Entry(buttonframe)
    e1.pack()
    button1 = Button(buttonframe, text='Take 1', command=lambda:takeBalls(1))
    button2 = Button(buttonframe, text='Take 2', command=lambda:takeBalls(2))
    button3 = Button(buttonframe, text='Take 3', command=lambda:takeBalls(3))
    button4 = Button(buttonframe, text='New Game', command=initializeNewGame)
    button1.pack()
    button2.pack()
    button3.pack()
    button4.pack()
    buttonframe.pack(side=RIGHT)
    canvasAndButtons.pack()
    statusLabel = Label(rootWindow, text="Play Nim")
    statusLabel.pack()

def runNim(numberOfBalls):
    createGUI()
    initializeNimAndGUI(numberOfBalls)   
    rootWindow.mainloop()

所以在我看来,当我做第二个游戏时,程序在更新图形时遇到了问题。应该发生的是,例如,我调用 runNim(20) 并玩一个有 20 个球的游戏。游戏结束后,我需要能够在入口小部件中输入一个数字,单击新游戏,然后将其设为新的 numberOfBalls。当我这样做时,我收到 init 消息,说明“Nim 游戏已初始化为 10 个球”。但是 GUI 没有改变,GUI 中没有出现任何球,如果我尝试采取任何措施,它会给出回溯和错误。

【问题讨论】:

  • 你试过e1.get()吗?这将读取用户在输入框中输入的值。另外,回溯错误是什么?
  • 文件“文件信息”,第 1549 行,在 _call_ 中 return self.func(*args) 文件“文件信息”,第 86 行,在 initializeNewGame 中 initializeNimAndGUI(numberofBalls)文件“文件信息”,第 102 行,initalizeNimAndGUI ballSize = min(maxBallSize, int(((canvasWidth-canvasBorderBuffer)//numberOfBalls)/1.2))
  • 对于我的 numberOfBalls,我有 e1.get()。但有人告诉我返回一个字符串,我需要一个 int。在这种情况下,我用什么来返回 int?
  • 默认情况下,输入框采用字符串形式的值。使用 int() 将其转换为整数,然后返回。

标签: python user-interface tkinter tkinter-entry


【解决方案1】:

我发现了我的问题。当我试图将字符串从 e1.get() 转换为整数时,我在第一次运行程序时没有考虑空字符串。这给了我一个 ValueError: invalid literal for int() with base 10: ''。所以我必须考虑到这一点,现在它起作用了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-26
    • 2012-02-16
    • 2012-04-06
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2011-09-09
    相关资源
    最近更新 更多