等待变量更改(Python和Tkinter)

2024-10-02 12:27:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Java有更多的经验,但我正在尝试使用其他语言。我正在尝试用Python编写一个数字猜测游戏。该程序有两种模式;计算机试图猜测用户选择的数字,用户试图猜测计算机选择的数字。在这两种情况下,所选数字必须介于1和1000之间。我已经开始了第一种模式的工作,第二种模式尚未实现。在这个程序中,我将tkinter用于GUI元素

我有三个按钮,它们与猜测的数字是否小于、大于或等于用户选择的数字相关。程序要求用户按下其中一个按钮。如果按下“小于”或“大于”按钮,程序应生成一个新编号并重复该过程。如果按下“等于”按钮,程序会显示用户的号码。如果在10次尝试中没有猜到这个号码,程序会说它无法猜到用户的号码

我的问题是,在运行计算之前,我想等待用户按下按钮。在这些方法中,我已经尝试过(线程事件和sleep()),按钮和相关标签不会出现,因此程序无法更新,它最终永远处于循环中。即使他们这样做了,我也不确定他们是否会被按下

在下面的代码中,我使用线程事件保留了代码

谢谢你的帮助

from tkinter import *
import threading
root = Tk()
root.title("Number Guessing Game")
guessedNum = 500
numberRange = -1
comWaitEvt = threading.Event()


def ComGuess():
    global comInstructions
    global comGuessBtn
    global humGuessBtn
    global buttonEqual
    global buttonLess
    global buttonGreater
    global comGuess
    global numberRange
    global guessedNum
    global comCorrectAnswer
    global comIncorrectAnswer
    global comWaitEvt
    comGuessBtn.destroy()
    humGuessBtn.destroy()
    comInstructions.grid(row=0, columnspan=3)
    comGuess.grid(row=1, columnspan=3)
    buttonLess.grid(row=2, column=0)
    buttonEqual.grid(row=2, column=1)
    buttonGreater.grid(row=2, column=2)
    low = 0
    high = 1001
    middle = 500
    foundAnswer = False
    for num in range(0, 10):
        comWaitEvt.wait()
        if numberRange == 0:
            high = middle
            middle = (((high-low)/2)+low)
            guessedNum = middle
        elif numberRange == 1:
            foundAnswer = True
            comGuess.destroy()
            guessedNum = middle
            comCorrectAnswer.grid(row=1, columnspan=3)
            break
        elif numberRange == 2:
            low = middle
            middle = (((high-low)/2)+low)
            guessedNum = middle
        comWaitEvt.clear()
    if not foundAnswer:
        comGuess.destroy()
        comIncorrectAnswer.grid(row=1, columnspan=3)


def setLessThan():
    global numberRange
    global comWaitEvt
    numberRange = 0
    comWaitEvt.set()


def setEqualTo():
    global numberRange
    global comWaitEvt
    numberRange = 1
    comWaitEvt.set()


def setGreaterThan():
    global numberRange
    global comWaitEvt
    numberRange = 2
    comWaitEvt.set()


#Create Mode Buttons
comGuessBtn = Button(root, text="Should I guess your number?", command=lambda:ComGuess())
humGuessBtn = Button(root, text="Should you guess my number?")
#Create Computer Guessing Buttons & Labels
buttonEqual = Button(root, text="Equal To")
buttonLess = Button(root, text="Less Than")
buttonGreater = Button(root, text="Greater Than")
comInstructions = Label(root, text="Please select a number between or equal to 1 and 1000."
                                   "\nI only have 10 guess to get your number."
                                   "\nHit one of the buttons below when you have chosen a number.")
comGuess = Label(root, text="Is your number "+str(guessedNum)+"?\n")
comCorrectAnswer = Label(root, text="Your number is "+str(guessedNum)+".")
comIncorrectAnswer = Label(root, text="I was unable to guess your number in 10 tries.")
#Create Human Guessing Buttons
humanGuess = IntVar()
numInput = Entry(root, textvariable=humanGuess)
#Places mode buttons
comGuessBtn.grid(row=1, column=0)
humGuessBtn.grid(row=1, column=1)
#Creates window
root.mainloop()

Tags: text用户程序numbermiddle数字root按钮
1条回答
网友
1楼 · 发布于 2024-10-02 12:27:03

tkinter mainloop钩住按钮按下(以及其他鼠标和键盘活动),您不需要为此实现特定的循环

至于全局变量;只要不重新绑定变量名,就可以在每个函数中使用不需要global声明的可变对象。在我的示例中,我使用了list作为猜测的下限和上限以及当前猜测

我没有使用不同的标签来表示信息,而是将标签绑定到一个文本变量(frontkinter),该变量也是可变的。这允许我只更改文本,而不是切换标签

看一看下面的例子,它应该会给你一些可以玩的东西

from tkinter import *

root = Tk()
root.title("Number Guessing Game")

guessing = [1, 1000, None]  # A global variable with low, high and current guess
info_text = StringVar()    # Global variable to hold Label comGuess text

def ComGuess():
    # Change GUI
    comGuessBtn.grid_forget()   # Instead of destroying
    humGuessBtn.grid_forget()
    comInstructions.grid(row=0, columnspan=3)
    info_label.grid(row=1, columnspan=3)
    buttonLess.grid(row=2, column=0)
    buttonEqual.grid(row=2, column=1)
    buttonGreater.grid(row=2, column=2)
    # Process guess
    guessing[2] = guessing[0] + (guessing[1]-guessing[0])//2
    info_text.set("Is your number " + str(guessing[2]) + "?\n")

def setLessThan():
    # Calculate new guess
    guessing[1] = guessing[2]
    guessing[2] = guessing[0] + (guessing[1]-guessing[0])//2
    # Update text in info_label 
    info_text.set("Is your number " + str(guessing[2]) + "?\n")

def setEqualTo():
    # Update text in info_label 
    info_text.set("Your number is " + str(guessing[2]) + ".")

def setGreaterThan():
    # Calculate new guess
    guessing[0] = guessing[2]
    guessing[2] = guessing[0] + (guessing[1]-guessing[0])//2
    # Update text in info_label 
    info_text.set("Is your number " + str(guessing[2]) + "?\n")

# Type of game buttons
comGuessBtn = Button(root, text="Should I guess your number?", command=ComGuess)
comGuessBtn.grid(row=1, column=0)
humGuessBtn = Button(root, text="Should you guess my number?")
humGuessBtn.grid(row=1, column=1)

#Create Computer Guessing Buttons & Labels
buttonEqual = Button(root, text="Equal To", command=setEqualTo)
buttonLess = Button(root, text="Less Than", command=setLessThan)
buttonGreater = Button(root, text="Greater Than", command=setGreaterThan)
comInstructions = Label(root, text="Please select a number between or equal to 1 and 1000."
                                   "\nI only have 10 guess to get your number."
                                   "\nHit one of the buttons below when you have chosen a number.")
info_label = Label(root, textvariable=info_text)

#Create Human Guessing Buttons
humanGuess = IntVar()
numInput = Entry(root, textvariable=humanGuess)

root.mainloop()

还有一件事:其中一个按钮的命令是:

command=lambda:ComGuess()

这是不必要的。command参数采用回调函数的名称,但如果用括号结束函数,则实际运行该函数。要在不使用lambda函数的情况下实现:

command=ComGuess

希望这能有所帮助

相关问题 更多 >

    热门问题