你能在 tkinter 的形状上添加回调/命令吗
Can you add a callback / command on a shape in tkinter
目前我正尝试在 OSX 上编写 Ultimate Tic Tac Toe 代码,并且我读到 here 您无法更改 OSX 上按钮的颜色。这使得 GUI 看起来像这样......
我觉得白色按钮很碍眼,而且真的很影响游戏
那么是否可以向按钮以外的对象添加回调。像这样...
window.create_rectangle(x1,y1,x2,y2,callback = foo)
如果您在坐标 (a, b)
和 (c, d)
处绘制矩形:
def callback(event):
if a <= event.x <= c:
if b <= event.y <= d:
print 'Rectangle clicked' # change rect here
window.bind('<ButtonPress-1>', callback)
如果 rects
是一个矩形列表:
rects = [] # contains rects
def callback(event):
for rect in rects:
if rect.a <= event.x <= rect.c:
if rect.b <= event.y <= rect.d:
rect.change()
window.bind('<ButtonPress-1>', callback)
是的,您可以对任何小部件进行绑定。一个常见的做法是使用标签小部件,但您也可以使用 canvas 并绘制任何您想要的形状。如果您使用行和列作为键将所有小部件存储在字典中,则回调很容易知道您单击了什么(当然,event.widget
也会告诉您)。
这是一个使用标签的简单示例,并说明了如何将行和列传递到回调中。为了简洁起见,它只是创建了一个井字棋盘:
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent, background="bisque")
self.canvas = tk.Canvas(self, width=400, height=400)
board = TicTacToe(self)
board.pack(padx=20, pady=20)
class TicTacToe(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent, background='black')
self.player = "X"
self.cell = {}
for row in range(3):
for col in range(3):
cell = tk.Label(self, background="darkgray", foreground="white", width=2)
cell.bind("<1>", lambda event, col=col, row=row: self.on_click(row, col))
cell.grid(row=row, column=col, sticky="nsew", padx=1, pady=1)
self.cell[(row,col)] = cell
def on_click(self, row, col):
current = self.cell[(row, col)].cget("text")
if current == "X" or current == "O":
self.bell()
return
self.cell[(row, col)].configure(text=self.player)
self.player = "X" if self.player == "O" else "O"
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
目前我正尝试在 OSX 上编写 Ultimate Tic Tac Toe 代码,并且我读到 here 您无法更改 OSX 上按钮的颜色。这使得 GUI 看起来像这样......
我觉得白色按钮很碍眼,而且真的很影响游戏 那么是否可以向按钮以外的对象添加回调。像这样...
window.create_rectangle(x1,y1,x2,y2,callback = foo)
如果您在坐标 (a, b)
和 (c, d)
处绘制矩形:
def callback(event):
if a <= event.x <= c:
if b <= event.y <= d:
print 'Rectangle clicked' # change rect here
window.bind('<ButtonPress-1>', callback)
如果 rects
是一个矩形列表:
rects = [] # contains rects
def callback(event):
for rect in rects:
if rect.a <= event.x <= rect.c:
if rect.b <= event.y <= rect.d:
rect.change()
window.bind('<ButtonPress-1>', callback)
是的,您可以对任何小部件进行绑定。一个常见的做法是使用标签小部件,但您也可以使用 canvas 并绘制任何您想要的形状。如果您使用行和列作为键将所有小部件存储在字典中,则回调很容易知道您单击了什么(当然,event.widget
也会告诉您)。
这是一个使用标签的简单示例,并说明了如何将行和列传递到回调中。为了简洁起见,它只是创建了一个井字棋盘:
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent, background="bisque")
self.canvas = tk.Canvas(self, width=400, height=400)
board = TicTacToe(self)
board.pack(padx=20, pady=20)
class TicTacToe(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent, background='black')
self.player = "X"
self.cell = {}
for row in range(3):
for col in range(3):
cell = tk.Label(self, background="darkgray", foreground="white", width=2)
cell.bind("<1>", lambda event, col=col, row=row: self.on_click(row, col))
cell.grid(row=row, column=col, sticky="nsew", padx=1, pady=1)
self.cell[(row,col)] = cell
def on_click(self, row, col):
current = self.cell[(row, col)].cget("text")
if current == "X" or current == "O":
self.bell()
return
self.cell[(row, col)].configure(text=self.player)
self.player = "X" if self.player == "O" else "O"
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()