【问题标题】:Associate widget buttons to each shape将小部件按钮与每个形状相关联
【发布时间】:2016-05-23 15:14:07
【问题描述】:

尽管阅读了其他文章,但在将我想在画布上绘制的每个形状与按钮/小部件相关联时遇到了麻烦。希望能够在绘制所选形状之前单击画布上的“椭圆”、“矩形”和“线条”按钮。

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

【问题讨论】:

  • 你有什么问题?您的代码与您的预期有何不同?
  • 当前代码在画布上绘制椭圆,然后是矩形,最后是线条。我暂时无法具体选择我要画的那个。
  • 创建设置变量shape = "oval"/"rectangle"/"polygon"的按钮,然后将此变量与if/elif/else一起使用来绘制选定的对象。
  • 你贴的代码缩进不正确;它不会运行。

标签: python canvas tkinter


【解决方案1】:

在这种情况下,我建议您为按钮使用单选按钮。原因是您一次只能选择一个“形状”按钮:椭圆、矩形、直线或多边形。单选按钮专门用于进行排他性选择。

要使其看起来像一个按钮而不是单选按钮,您可以将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]

【讨论】:

  • 非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-09-04
  • 1970-01-01
  • 2012-06-27
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 2012-01-04
相关资源
最近更新 更多