基本上,我所做的是将一个click事件绑定到一个函数。例如:
self.button1.bind("<Button-1>",self.chooseDice)
我现在想要的是在另一个函数中访问chooseDice()
的结果。这样做的最佳方法是什么?
class GraphicsInterface:
#we want to initialize the game board here, set up the dice and buttons
def __init__(self):
self.window = Tk()
self.window.geometry("720x500")
#buttons under each die
self.clicked=[] #empty list to collect all the buttons that were clicked (see chooseDice function)
self.button1 = Button(self.window, text="Dice 1", width=13) #create the button object
self.button1.place(x=60, y=160)
#bind button click event to a function (chooseDice())
self.button1.bind("<Button-1>",self.chooseDice)
self.button2 = Button(self.window, text="Dice 2", width=13)
self.button2.place(x=185, y=160)
self.button2.bind("<Button-1>",self.chooseDice)
#using the event as an argument, append the text to the clicked list
def chooseDice(self, event):
self.clicked.append(event.widget.cget('text'))
self.diceList=[] #create a new empty list
for i in range(len(self.clicked)):
self.diceList.append(int(self.clicked[i][5])) #get just the int value of the last character (i.e. the dice number)
self.deactivate(event.widget) #deactivate the button
return self.diceList
答案 0 :(得分:1)
只需在您的班级中添加self.result
属性,并将其设置为chooseDice()
答案 1 :(得分:1)
重构。将其分为两个功能。
一个返回正确的结果,可供其他对象使用。
另一个绑定到GUI控件,并使用正确的结果来激活和停用GUI对象。
确实,你应该始终这样做。你应该总是拥有能够执行普通Python工作的函数,无需GUI即可正常工作,并且可以在没有GUI的情况下进行单元测试。然后将这个工作“模型”连接到GUI。
答案 2 :(得分:1)
你已经在做你需要做的事了。您的示例代码将self.diceList
设置为某个值。您可以在代码中的任何其他位置直接使用self.diceList
。
顺便说一下 - 你编写的代码随着时间的推移很难维护。例如,如果您将骰子标签更改为“Dice One”或简单地“One”而不是“Dice 1”,该怎么办?或者,随着您的应用程序的进展,您可能需要图形图像而不是按钮上的文本。您必须修改解析按钮名称的代码。您实际上是在按钮标签中编码信息,这不是一个好主意。
一个简单的解决方案,也使您的chooseDice
方法更简单,更容易理解,是传递回调中的骰子数。例如:
self.button1.configure(command=lambda btn=self.button1: self.chooseDice(btn, 1))
以上将两个参数传递给chooseDice
方法:按钮实例(因此可以禁用它)和按钮编号(这样您就不必解析按钮名称来获取它)
这也允许您在循环中创建骰子,而不是硬编码同一代码块的多个副本。这是一个完整的工作示例:
from Tkinter import *
class GraphicsInterface:
def __init__(self):
self.window = Tk()
self.window.geometry("720x500")
self.clicked=[]
self.buttons = []
for n in range(1, 3):
btn = Button(text="Button " + str(n))
btn.configure(command=lambda btn=btn, n=n: self.chooseDice(btn, n))
btn.pack()
self.buttons.append(btn)
btn = Button(text="Go!", command=self.go)
btn.pack()
self.window.mainloop()
def go(self):
print "buttons:", self.clicked
self.reset()
def reset(self):
'''Reset all the buttons'''
self.clicked = []
for button in self.buttons:
button.configure(state="normal")
def chooseDice(self, widget, number):
self.clicked.append(number)
widget.configure(state="disabled")
app = GraphicsInterface()
最后,最后一些建议:
不要使用place
,它会使您的GUI更难创建,并且它们不会对窗口大小的变化,字体的变化,平台的变化等做出很好的反应。使用pack
而grid
代替。另外,不要创建固定宽度的按钮。同样,这是为了更好地处理字体的变化。有时您需要固定宽度按钮,但看起来您的代码没有任何理由使用它们。
最后,我不知道你实际想要完成什么,但通常如果你使用按钮来跟踪状态(是否按下这个东西?)你想使用复选框(选择N的N)或radiobuttons(选择N中的1)。您可能需要考虑切换到那些而不是按钮。