如何在tkinter中将多个按钮链接到一个文本小部件?

时间:2018-09-29 11:42:06

标签: python 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()

任何帮助将不胜感激。

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

1 个答案:

答案 0 :(得分:1)

因此,如果我没错,您只想单击一个按钮,即可在“文本”窗口小部件中更改文本。为此,您有两个简单且非常相似的选项。首先是像您定义的那样定义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. 如果您直接在小部件本身上使用gridpackplace,则不会将小部件分配给变量,而是返回grid,{{1 }}或pack函数。因此,宁可先将窗口小部件分配给变量,然后像对place-widget一样对它使用几何管理器。
  2. 之后,您无需额外使用标题功能设置标题。您可以使用None中的Text参数进行设置。
  3. 如果您正在使用tkinter,则可以在功能上做到这一点,而可以使用类来构建GUI。
  4. 在创建新的窗口小部件时,始终确保首先将根窗口的变量传递给它们。如果您不这样做,但是他们需要更多不必要的后台活动,他们也会自己获取;如果您打开了多个className窗口,它将自动选择一个可能不是您想要的窗口拿。
  5. 最后还有一个小技巧:如果您想了解有关所有tkinter小部件的更多信息,请尝试http://effbot.org/tkinterbook/tkinter-index.htm#class-reference

希望对您有所帮助。祝您编程愉快!

编辑: 我刚刚看到了您对random模块的编辑。在这种情况下,我建议第二种选择。只需从Tk中删除Tk参数,然后将text替换为updateText。在lambda: self.updateText(...)本身中,添加了您提到的随机列表项。 :D