问题描述
我正在使用 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)
解决方法
因此,如果我从评论中得到了正确的答案,问题是能够平移幻灯片并使用绑定到鼠标点击和动作的方式在幻灯片上进行绘制。有几种方法可以做到这一点,例如:
-
使用单选按钮以便用户选择“模式”:平移或注释。这是绘图部分基于 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()
-
另一种可能性是使用事件修饰符(例如按下 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()