将窗口小部件按钮关联到每个形状

时间:2016-02-12 12:51:48

标签: python canvas tkinter

尽管阅读了其他文章,却无法将我想在画布上绘制的每个形状与按钮/小部件相关联。希望能够点击一个椭圆形的矩形'和'线'在绘制所选形状之前,画布上的按钮。

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

1 个答案:

答案 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]