简体   繁体   English

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

[英]How to link multiple buttons to one text widget in tkinter?

I'm trying to learn tkinter and I wanted to write a simple rock paper scissors game, where there is a window with 3 buttons and one text widget. 我正在尝试学习tkinter,我想写一个简单的剪刀石头布游戏,其中有一个带有3个按钮和一个文本小部件的窗口。

I'd like to be able to press any of the buttons and for the message to appear in the text field, then click a different button, the text field to clear and display a new message associated with the second button and so on. 我希望能够按任意一个按钮,并让消息出现在文本字段中,然后单击另一个按钮,在文本字段中清除并显示与第二个按钮关联的新消息,依此类推。

From the tutorials I've watched, I know that I can pass the function housing text widget as an argument in button command parameter.I know I could make 3 functions with a text field, one for each button (displaying one at a time) but that's probably not the correct way. 从我看过的教程中,我知道我可以将带有文本小部件的功能作为按钮命令参数中的一个参数传递给我,我知道我可以用一个文本字段制作3个函数,每个按钮一个(一次显示一个)但这可能不是正确的方法。 Here's what I have so far: 这是我到目前为止的内容:

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()

Any help will be appreciated. 任何帮助将不胜感激。

Edit: Second thought - I can imagine I'm complicating this for myself by trying to force the game to work this way. 编辑:第二个想法-我可以想象通过强迫游戏以这种方式使我自己变得复杂。 With the random module I'd be able to get away with one function for the computer choice with a list and saving the random pick in a parameter, then returning the value into the display function. 使用随机模块,我可以摆脱一个带有列表的计算机选择功能,并将随机选择保存在参数中,然后将值返回到显示功能。

So if I got this right you just want to make a button click change the text in the Text-widget. 因此,如果我没错,您只想单击一个按钮,即可在“文本”窗口小部件中更改文本。 For that you have two easy and quite similar options. 为此,您有两个简单且非常相似的选项。 First would be to define 3 functions, as you did, and let them change the text directly. 首先是像您定义的那样定义3个函数,然后让它们直接更改文本。 The second option would be to make one function which changes the text according to whats given. 第二种选择是使一个函数根据给定的内容更改文本。 Note that in the second case we will have to use lambda which works quite well in smaller projects but decreases the efficiency of your programs when they get bigger. 请注意,在第二种情况下,我们将不得不使用lambda ,它在较小的项目中效果很好,但是当程序变大时会降低其效率。

First option: 第一种选择:

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()

Second option: 第二种选择:

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()

Some little side notes from me here: 我在这里的一些小注意事项:

  1. If you use grid , pack or place right on the widget itself you wont assign the widget to a variable but the return of the grid , pack or place function which is None . 如果您在小部件本身上使用gridpackplace ,则不会将小部件分配给变量,而是将gridpackplace函数的返回值设置为None So rather first assign the widget to an variable and then use a geometry manager on it like I did for the Text -widget. 因此,宁愿先将窗口小部件分配给变量,然后像在Text -widget中一样,对它使用几何图形管理器。
  2. You don't have to extra set the title with the title function afterwards. 之后,您无需额外使用title函数设置标题。 You can set it with the className -argument in Tk . 您可以使用TkclassName -argument进行设置。
  3. If you're working with tkinter its fine to do it functionally but rather use a class to build up GUIs. 如果您使用的是tkinter,则可以在功能上做到这一点,而可以使用类来构建GUI。
  4. When creating new widgets always be sure to pass them the variable for the root window first. 创建新窗口小部件时,请务必先将根窗口的变量传递给它们。 They will get it themselves too if you don't do that but that needs more unnecessary background activity and if you have more than one Tk -window open it will automatically chooses one which may not be the one you want it to take. 如果您不这样做,他们也会自己获取,但是这需要更多不必要的后台活动;如果您打开了多个Tk窗口,它将自动选择一个可能不是您想要的窗口。
  5. And one small tip in the end: If you want to learn more about all the tkinter widgets try http://effbot.org/tkinterbook/tkinter-index.htm#class-reference . 最后还有一个小技巧:如果您想了解更多有关所有tkinter小部件的信息,请尝试http://effbot.org/tkinterbook/tkinter-index.htm#class-reference

I hope its helpfull. 希望对您有所帮助。 Have fun programming! 祝您编程愉快!

EDIT: I just saw your edit with the random module. 编辑:我刚刚看到您对随机模块的编辑。 In this case I would recommend the second option. 在这种情况下,我建议第二种选择。 Just remove the text -argument from updateText and replace lambda: self.updateText(...) with self.updateText() . 只需从updateText删除text argument并将lambda: self.updateText(...)替换为self.updateText() In updateText itself you add that random of list thing you mentioned. updateText本身中,您可以添加您提到的列表内容的随机性。 :D :d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM