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