首页 > 解决方案 > 如何在 tkinter 中将多个按钮链接到一个文本小部件?

问题描述

我正在尝试学习 tkinter,我想编写一个简单的石头剪刀布游戏,其中有一个带有 3 个按钮和一个文本小部件的窗口。

我希望能够按下任何按钮并使消息出现在文本字段中,然后单击另一个按钮,清除文本字段并显示与第二个按钮相关联的新消息,依此类推。

从我看过的教程中,我知道我可以将容纳文本小部件的函数作为参数传递给按钮命令参数。我知道我可以用一个文本字段创建 3 个函数,每个按钮一个(一次显示一个)但这可能不是正确的方法。这是我到目前为止所拥有的:

import tkinter as tk

root = tk.Tk()
root.title("Rock Paper Scissors")
root.geometry("420x200")

def Rock():
    rockText = "Paper!"
    return rockText

def Paper():
    paperText = "Scissors!"
    return paperText

def Scissors():
    scissorsText = "Rock!"
    return scissorsText

def display():

    textDisplay = tk.Text(master = root, height = 10, width = 50)
    textDisplay.grid(row = 1, columnspan = 5)
    textDisplay.insert(tk.END, Rock())

buttonRock = tk.Button(text = "Rock", command = display).grid(row = 0, column = 1, padx = 10)
buttonPaper = tk.Button(text = "Paper").grid(row = 0, column = 2, padx = 10)
buttonScissors = tk.Button(text = "Scissors").grid(row = 0, column = 3, padx = 10)

root.mainloop()

任何帮助将不胜感激。

编辑:第二个想法 - 我可以想象我通过试图强迫游戏以这种方式工作来为自己复杂化。使用随机模块,我可以通过一个列表来摆脱计算机选择的一个功能,并将随机选择保存在一个参数中,然后将值返回到显示函数中。

标签: pythontkinter

解决方案


因此,如果我做对了,您只需单击按钮即可更改 Text-widget 中的文本。为此,您有两个简单且非常相似的选项。首先是定义 3 个函数,就像您所做的那样,让它们直接更改文本。第二种选择是制作一个根据给定内容更改文本的功能。请注意,在第二种情况下,我们将不得不使用lambda它在较小的项目中运行良好,但当它们变得更大时会降低程序的效率。

第一个选项:

import tkinter as tk

class App:
    def __init__(self):
        root=tk.Tk()
        root.title("Rock Paper Scissors")
        root.geometry("420x200")
        self.text=Text(root)
        self.text.grid(row=1,columnspan=5)
        tk.Button(root,text="Rock",command=self.Rock).grid(row=0,column=1,padx=10)
        tk.Button(root,text="Paper",command=self.Paper).grid(row=0,column=2)
        tk.Button(root,text="Scissors",command=self.Scissors).grid(row=0,column=3,padx=10)
        root.mainloop()

    def Rock(self):
        text="Paper!"
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

    def Paper(self):
        text="Scissors!"
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

    def Scissors(self):
        text="Rock!"
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

if __name__=='__main__':
    App()

第二种选择:

import tkinter as tk

class App:
    def __init__(self):
        root=tk.Tk()
        root.title("Rock Paper Scissors")
        root.geometry("420x200")
        self.text=Text(root)
        self.text.grid(row=1,columnspan=5)
        tk.Button(root,text="Rock",command=lambda: self.updateText('Paper!')).grid(row=0,column=1,padx=10)
        tk.Button(root,text="Paper",command=lambda: self.updateText('Scissors!')).grid(row=0,column=2)
        tk.Button(root,text="Scissors",command=lambda: self.updateText('Rock!')).grid(row=0,column=3,padx=10)
        root.mainloop()

    def updateText(self,text):
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

if __name__=='__main__':
    App()

我在这里的一些小旁注:

  1. 如果您在小部件本身上使用或grid,您不会将小部件分配给变量,而是返回,或. 因此,首先将小部件分配给一个变量,然后像我为-widget 所做的那样在其上使用几何管理器。packplacegridpackplaceNoneText
  2. 之后您不必使用标题功能额外设置标题。您可以使用 - 参数设置classNameTk
  3. 如果您正在使用 tkinter,则可以在功能上执行它,而是使用一个类来构建 GUI。
  4. 创建新小部件时,请务必首先将根窗口的变量传递给它们。如果您不这样做,他们也会自己获得它,但这需要更多不必要的后台活动,并且如果您打开多个Tk窗口,它将自动选择一个可能不是您想要的窗口。
  5. 最后还有一个小提示:如果您想了解有关所有 tkinter 小部件的更多信息,请尝试http://effbot.org/tkinterbook/tkinter-index.htm#class-reference

我希望它有帮助。玩得开心编程!

编辑:我刚刚看到您使用随机模块进行的编辑。在这种情况下,我会推荐第二种选择。只需从中删除text-argumentupdateText并替换lambda: self.updateText(...)self.updateText(). 就updateText其本身而言,您添加了您提到的随机列表。:D


推荐阅读