尽管阅读了其他文章,却无法将我想在画布上绘制的每个形状与按钮/小部件相关联。希望能够点击一个椭圆形的矩形'和'线'在绘制所选形状之前,画布上的按钮。
from tkinter import *
trace = 0
class CanvasEvent:
def __init__(self, parent=None):
canvas = Canvas(width=1200, height=1200, bg='yellow')
canvas.pack()
canvas.bind('<ButtonPress-1>', self.onStart)
canvas.bind('<B1-Motion>', self.onGrow)
canvas.bind('<Double-1>', self.onClear)
self.canvas = canvas
self.drawn = None
self.kinds = [canvas.create_oval, canvas.create_rectangle,
canvas.create_polygon, canvas.create_line]
self.drag_data = {"x": 0, "y": 0, "item": None}
self.canvas.tag_bind("ovals", "<ButtonPress-3>", self.onItemPress)
self.canvas.tag_bind("ovals", "<ButtonRelease-3>", self.onItemRelease)
self.canvas.tag_bind("ovals", "<B3-Motion>", self.onItemMotion)
self.canvas.tag_bind("rectangles", "<ButtonPress-3>", self.onItemPress)
self.canvas.tag_bind("rectangles", "<ButtonRelease-3>", self.onItemRelease)
self.canvas.tag_bind("rectangles", "<B3-Motion>", self.onItemMotion)
self.canvas.tag_bind("lines", "<ButtonPress-3>", self.onItemPress)
self.canvas.tag_bind("lines", "<ButtonRelease-3>", self.onItemRelease)
self.canvas.tag_bind("lines", "<B3-Motion>", self.onItemMotion)
self.canvas.tag_bind("polygons", "<ButtonPress-3>", self.onItemPress)
self.canvas.tag_bind("polygons", "<ButtonRelease-3>", self.onItemRelease)
self.canvas.tag_bind("polygons", "<B3-Motion>", self.onItemMotion)
def onItemPress(self, event):
self.drag_data["item"] = self.canvas.find_closest(event.x, event.y)[0]
self.drag_data["x"] = event.x
self.drag_data["y"] = event.y
def onItemRelease(self, event):
self.drag_data["item"] = None
self.drag_data["x"] = 0
self.drag_data["y"] = 0
def onItemMotion(self, event):
delta_x = event.x - self.drag_data["x"]
delta_y = event.y - self.drag_data["y"]
self.canvas.move(self.drag_data["item"], delta_x, delta_y)
self.drag_data["x"] = event.x
self.drag_data["y"] = event.y
def onStart(self, event):
self.shape = self.kinds[0]
self.kinds = self.kinds[1:] + self.kinds[:1]
self.start = event
self.drawn = None
def onGrow(self, event):
canvas = event.widget
if self.drawn: canvas.delete(self.drawn)
objectId = self.shape(self.start.x, self.start.y, event.x, event.y)
if trace: print(objectId)
self.drawn = objectId
def onClear(self, event):
event.widget.delete('all')
class move(CanvasEvent):
def __init__(self, parent=None):
CanvasEvent.__init__(self, parent)
self.canvas.create_text(110, 50, text='Left click and drag to create a shape')
self.canvas.create_text(110, 85, text='Right click and drag a shape to move it')
self.canvas.create_text(110, 120, text='Double click to erase canvas')
self.kinds = self.create_oval_tagged, self.create_rectangle_tagged,self.create_line_tagged,self.create_polygon_tagged
def create_oval_tagged(self, x1, y1, x2, y2):
objectId = self.canvas.create_oval(x1, y1, x2, y2)
self.canvas.itemconfig(objectId, tag='ovals', fill='blue')
return objectId
def create_rectangle_tagged(self, x1, y1, x2, y2):
objectId = self.canvas.create_rectangle(x1, y1, x2, y2)
self.canvas.itemconfig(objectId, tag='rectangles', fill='red')
return objectId
def create_line_tagged(self,x1,y1,x2,y2):
objectId = self.canvas.create_line(x1, y1, x2, y2)
self.canvas.itemconfig(objectId, tag='lines', fill='black', arrow="last", width=5)
return objectId
def create_polygon_tagged(self,x1,y1,x2,y2):
objectId = self.canvas.create_polygon(x1, y1, x2, y2)
self.canvas.itemconfig(objectId, tag='polygons', fill='black')
return objectId
move()
mainloop()
答案 0 :(得分:0)
在这种情况下,我建议为按钮使用单选按钮。原因是您一次只能选择一个“形状”按钮:椭圆形,矩形,线形或多边形。 Radiobuttons专门用于做出独家选择。
要使它看起来像一个按钮而不是像一个单选按钮,你可以将indicatoron
选项设置为False
,这将删除传统的单选按钮,并只留下一个正常的按钮。选择后,按钮保持凹陷状态,未选中时,它看起来像一个按钮。
例如,这是创建工具栏的一种方法:
class CanvasEvent:
def __init__(self, parent=None):
toolbar = Frame()
toolbar.pack(side="top", fill="x")
self.shapeVar = StringVar(value="oval")
for shape in ("rectangle", "oval", "line", "polygon"):
button = Radiobutton(toolbar, text=shape, value=shape,
indicatoron=False, variable=self.shapeVar)
button.pack(side="left")
通过它,您可以使用self.shapeVar.get()
获取当前的形状类型。然后,您可以使用它来确定要调用的函数。一种简单的方法是创建一个字典。字典的键是形状名称(“字符串”,“矩形”,......),值是要调用的函数。
self.kinds = {
"oval": self.create_oval_tagged,
"rectangle": self.create_rectangle_tagged,
"line": self.create_line_tagged,
"polygon": self.create_polygon_tagged
}
shape_name = self.shapeVar.get()
self.shape = self.kinds[shape_name]