使用 Tkinter 手动注释

问题描述

我正在使用 Tkinter 通过 Openslide 导入图像。我想像这样将手动注释模块集成到我的程序中:

class ResizableCanvas(Canvas):

    def __init__(self,parent,**kwargs):
        Canvas.__init__(self,**kwargs)
        self.bind("<Configure>",self.on_resize)
        self.height = self.winfo_reqheight()
        self.width = self.winfo_reqwidth()

    def on_resize(self,event):
        wscale = float(event.width) / self.width
        hscale = float(event.height) / self.height
        self.width = event.width
        self.height = event.height
        self.config(width=self.width,height=self.height)


    class ViewerTab:

    def __init__(self,master,model,dim=800):

        self.sideFrame = ttk.Frame(self.master,width=100)


        self.coords = {"x":0,"y":0,"x2":0,"y2":0}

        self.lines = []
    
    def click(self):

        self.coords["x"] = self.x
        self.coords["y"] = self.y
    
        self.lines.append(self.canvas.create_line(self.coords["x"],self.coords["y"],self.coords["x"],self.coords["y"]))
    
    def drag(self):
        # update the coordinates from the event
        self.coords["x2"] = self.x
        self.coords["y2"] = self.y
    

        self.canvas.coords(self.lines[-1],self.coords["x2"],self.coords["y2"])
    
        #self.canvas.bind("<Button-1>",self.dirbutton)
        #self.canvas.bind("<B1-Motion>",self.move)
        self.canvas.bind("<ButtonRelease-1>",self.nomove)
        self.canvas.bind("<Button-2>",self.get_position)
        self.canvas.bind("<ButtonPress-1>",self.click)
        self.canvas.bind("<B1-Motion>",self.drag) 

解决方法

因此,如果我从评论中得到了正确的答案,问题是能够平移幻灯片并使用绑定到鼠标点击和动作的方式在幻灯片上进行绘制。有几种方法可以做到这一点,例如:

  1. 使用单选按钮以便用户选择“模式”:平移或注释。这是绘图部分基于 https://stackoverflow.com/a/50129744/6415268 的一个小例子。 click()drag() 函数根据所选模式执行不同的操作(存储在 StringVar 中)。

     import tkinter as tk
    
     coords = {"x": 0,"y": 0,"x2": 0,"y2": 0}
     # keep a reference to all lines by keeping them in a list
     lines = []
    
     def click(event):
         if mode.get() == "pan":
             canvas.scan_mark(event.x,event.y)
         else:
             # define start point for line
             coords["x"] = canvas.canvasx(event.x)
             coords["y"] = canvas.canvasy(event.y)
    
             # create a line on this point and store it in the list
             lines.append(canvas.create_line(coords["x"],coords["y"],coords["x"],coords["y"]))
    
     def drag(event):
         if mode.get() == "pan":
             canvas.scan_dragto(event.x,event.y,gain=1)
         else:
             # update the coordinates from the event
             coords["x2"] = canvas.canvasx(event.x)
             coords["y2"] = canvas.canvasy(event.y)
    
             # Change the coordinates of the last created line to the new coordinates
             canvas.coords(lines[-1],coords["x2"],coords["y2"])
    
    
     root = tk.Tk()
     mode = tk.StringVar(root,"pan")
     toolbar = tk.Frame(root)
     toolbar.pack(fill='x')
    
     tk.Radiobutton(toolbar,text="Pan",variable=mode,value="pan").pack(side='left')
     tk.Radiobutton(toolbar,text="Annotate",value="annotate").pack(side='left')
    
     canvas = tk.Canvas(root,bg="white")
     canvas.create_rectangle(0,50,fill='red')
     canvas.create_rectangle(400,400,450,fill='blue')
     canvas.pack(fill='both')
    
     canvas.bind("<ButtonPress-1>",click)
     canvas.bind("<B1-Motion>",drag)
    
     root.mainloop()
    
  2. 另一种可能性是使用事件修饰符(例如按下 Ctrl、Shift 或 Alt 键)对两种操作使用不同的绑定。例如,平移可以绑定到 Ctrl + 鼠标事件,而绘图发生在简单的鼠标点击和移动上。

     import tkinter as tk
    
     coords = {"x": 0,"y2": 0}
     # keep a reference to all lines by keeping them in a list
     lines = []
    
     def draw_click(event):
         # define start point for line
         coords["x"] = canvas.canvasx(event.x)
         coords["y"] = canvas.canvasy(event.y)
    
         # create a line on this point and store it in the list
         lines.append(canvas.create_line(coords["x"],coords["y"]))
    
     def draw_drag(event):
         # update the coordinates from the event
         coords["x2"] = canvas.canvasx(event.x)
         coords["y2"] = canvas.canvasy(event.y)
    
         # Change the coordinates of the last created line to the new coordinates
         canvas.coords(lines[-1],coords["y2"])
    
    
     root = tk.Tk()
     toolbar = tk.Frame(root)
     toolbar.pack(fill='x')
    
     canvas = tk.Canvas(root,draw_click)
     canvas.bind("<B1-Motion>",draw_drag)
     canvas.bind('<Control-ButtonPress-1>',lambda event: canvas.scan_mark(event.x,event.y))
     canvas.bind("<Control-B1-Motion>",lambda event: canvas.scan_dragto(event.x,gain=1))
    
     root.mainloop()