使用 Tkinter 手动注释

Manual Annotation with Tkinter

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

class ResizableCanvas(Canvas):

    def __init__(self, parent, **kwargs):
        Canvas.__init__(self, parent, **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["x"],self.coords["y"],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. 使用单选按钮让用户选择“模式”:平移或注释。这是一个基于 的绘图部分的小例子。 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["x"], coords["y"], 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",
                    variable=mode, value="annotate").pack(side='left')
    
     canvas = tk.Canvas(root, bg="white")
     canvas.create_rectangle(0, 0, 50, 50, fill='red')
     canvas.create_rectangle(400, 400, 450, 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, "y": 0, "x2": 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"], 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["x"], coords["y"], coords["x2"], coords["y2"])
    
    
     root = tk.Tk()
     toolbar = tk.Frame(root)
     toolbar.pack(fill='x')
    
     canvas = tk.Canvas(root, bg="white")
     canvas.create_rectangle(0, 0, 50, 50, fill='red')
     canvas.create_rectangle(400, 400, 450, 450, fill='blue')
     canvas.pack(fill='both')
    
     canvas.bind("<ButtonPress-1>", 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, event.y, gain=1))
    
     root.mainloop()