如何处理 python 模块 tkinter 中的单击按钮事件



我正在尝试使用 tkinter 在 python 中制作一个问题游戏。我正在努力定义一个函数,该函数可以检查玩家单击的答案并添加到分数中,然后将其打印在答案下方。

每当我单击时,代码的结果是分数为 0,问题和答案不会改变。另外,如果我反复单击,它会将 0 打印为彼此下方的标签。

只包含了我所有的代码,这样如果有人想自己测试代码,它不会抛出任何错误。

import tkinter
import random
from random import shuffle
score = 0
def check_answer(answer):
    if answer == answers[s][0] or answer == answers[s][1]:
        global score
        score += 1
    lbl = tkinter.Label(window, text=score)
    lbl.pack()

#This sets up a window and names it "The Hunt" but doesn't generate the window
window = tkinter.Tk()
window.title("The Hunt!")
#This sets the background colour
window.configure(background="#1C3F95")
#This generates labels and buttons that are the same or similar colour to the background
welcome = tkinter.Label(window, text="Welcome to the Hunt!", bg="#1C3F95")
begin = tkinter.Button(window, text="Click here to begin", bg="#1C7C95")

#This is my code for the question generation. As I made that for a pygame window, I obviously had to change it slightly
questions = ["What species of bird is also a nickname for New Zealand?", "Which Twins can you play as in Assassin's Creed Syndicate?",
                 "Which year was 'Killing In The Name' Christmas Number one?"]
answers = [["kiwi", "Kiwi", "Falcon", "Sparrow", "Crow"], ["frye", "Frye", "Bank", "Green", "Bundy"], ["2009", "2009",
                                                                                                       "1999", "1993",
                                                                                                       "2004"]]
#I had to do it in two separate lists as it's easier to work with later on
# Also I made the correct answers non-case sensitive to make it easier to test.
r = len(questions)
score = 0
s = random.randrange(0, r, 1)
#This generates a random number within the range of how many questions there are
# and then prints out that question
#This generates a label that displays the randomly generated question
question = tkinter.Label(window, text=questions[s])

list = answers[s]
output = []
for i in range(1, 5):
    output.append(answers[s][i])
shuffle(output)

# this takes the answers that correspond with the randomly generated question and shuffles the answers
# I did this as otherwise, the answer would always be the first answer to appear and the player could exploit this
#This code is what displays the labels and buttons on the window. It lets the computer decide where the best place for
#each component is
welcome.pack()
begin.pack()
question.pack()
for i in output:
    answer = tkinter.Button(window, text=i, command=lambda answer = i: check_answer(i))
    answer.pack()

#I had decided to pack the answers like this as it was easier than typing out each element of the list and also
#more efficent
window.mainloop()
#this is the code that actually generates the window

从顶部开始,让我们更改check_answer定义,以便每次都不创建新标签:

def check_answer(answer):
    if answer == answers[s][0] or answer == answers[s][1]:
        global score
        score += 1
        lbl["text"] = score

接下来,我们需要在你的 for 循环中进行一个小的更改:我们想要发送答案,而不是 i:

for i in output:
    answer = tkinter.Button(window, text=i, command=lambda answer = i: check_answer(answer))
    answer.pack()
lbl = tkinter.Label(window, text=score)
lbl.pack()

最后,我们将之前删除的标签添加到您最初拥有它的底部。 您可以通过更快地将其打包到代码中来更改它的位置,以求美观。 一旦回答了一个新问题(正确或其他(,您的代码仍然不会循环到一个新问题,但至少现在您可以看到用户何时正确回答。

希望这有帮助。

首先,你在 lambda 回调中犯了一个小错误:

command=lambda answer=i: check_answer(answer)

应该是。

然后,对于许多标签,创建一个标签并仅更改文本:

def check_answer(answer):
    print(answer)
    if answer == answers[s][0] or answer == answers[s][1]:
        global score
        score += 1
    lbl.configure(text=str(score))

(很多代码我没有复制(

for i in output:
    answer = tkinter.Button(window, text=i, command=lambda answer=i: check_answer(answer))
    answer.pack()
lbl = tkinter.Label(window, text=score)
lbl.pack()

最新更新