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()
任何帮助将不胜感激。
编辑:第二个想法 - 我可以想象我通过试图强迫游戏以这种方式工作来为自己复杂化。使用随机模块,我可以通过一个列表来摆脱计算机选择的一个功能,并将随机选择保存在一个参数中,然后将值返回到显示函数中。
解决方案
因此,如果我做对了,您只需单击按钮即可更改 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()
我在这里的一些小旁注:
- 如果您在小部件本身上使用或
grid
,您不会将小部件分配给变量,而是返回,或. 因此,首先将小部件分配给一个变量,然后像我为-widget 所做的那样在其上使用几何管理器。pack
place
grid
pack
place
None
Text
- 之后您不必使用标题功能额外设置标题。您可以使用 - 参数设置
className
它Tk
。 - 如果您正在使用 tkinter,则可以在功能上执行它,而是使用一个类来构建 GUI。
- 创建新小部件时,请务必首先将根窗口的变量传递给它们。如果您不这样做,他们也会自己获得它,但这需要更多不必要的后台活动,并且如果您打开多个
Tk
窗口,它将自动选择一个可能不是您想要的窗口。 - 最后还有一个小提示:如果您想了解有关所有 tkinter 小部件的更多信息,请尝试http://effbot.org/tkinterbook/tkinter-index.htm#class-reference。
我希望它有帮助。玩得开心编程!
编辑:我刚刚看到您使用随机模块进行的编辑。在这种情况下,我会推荐第二种选择。只需从中删除text
-argumentupdateText
并替换lambda: self.updateText(...)
为self.updateText()
. 就updateText
其本身而言,您添加了您提到的随机列表。:D
推荐阅读
- terraform - terraform“循环”没用吗?还是我错过了什么?
- javascript - 我可以在我的 chrome 扩展中添加 javascript 弹出框吗?
- android - Error: Program type already present: com.google.protobuf.DescriptorProtos$EnumDescriptorProto$Builder
- c++ - 这条 Intel Xeon mov 指令如何破坏我的应用程序的内存?
- r - 如何获取一段时间内某个年龄组的单位数?
- c++ - 在 sfml c++ 中移动一个圆圈时,球后面会出现结巴的轨迹故障
- python - 为什么 any() 比 in 快得多?
- bash - 在bash中将行转换为第n列之后的列
- python - 每类 cross_val_score 返回精度
- javascript - webRequest 可选权限和后台脚本