请帮我解决这个问题。
我想允许用户使用鼠标在图片中的特定感兴趣区域周围绘制一个随机矩形(通过单击鼠标的右键或左键直到他释放它)。
我处理大图像(图像大于我的屏幕分辨率,例如 one ),因此用户需要滚动窗 Eloquent 能完整地看到图片。
这是我尝试显示大图片的代码,但我不知道如何允许用户使用鼠标在对象(比如图片中的人)上绘制矩形:
from Tkinter import *
import Image,ImageTk
root=Tk()
canv=Canvas(root,relief=SUNKEN)
sbarv=Scrollbar(root,orient=VERTICAL)
sbarh=Scrollbar(root,orien=HORIZONTAL)
sbarv.config(command=canv.yview)
sbarh.config(command=canv.xview)
canv.config(yscrollcommand=sbarv.set)
canv.config(xscrollcommand=sbarh.set)
canv.grid(row=0,column=0,sticky=N+S+E+W)
sbarv.grid(row=0,column=1,sticky=N+S)
sbarh.grid(row=1,column=0,sticky=E+W)
im=Image.open("image.jpg")
width,height=im.size
canv.config(scrollregion=(0,0,width,height))
im2=ImageTk.PhotoImage(im)
imgtag=canv.create_image(0,0,anchor="nw",image=im2)
root.mainloop()
编辑 1:
不得填充矩形。我的意思是我只想画它的 4 条线(线段),但它里面必须是空的,我想只画一个像素宽度的轮廓。
我还想在光标移动(拖动)时绘制,而不是在按钮释放后绘制。
此外,请注意要绘制的矩形可能很长,我的意思是垂直滚动条需要向下移动才能界定整个感兴趣的对象(假设它是一个人)
我们将不胜感激任何帮助。
非常感谢您
编辑 2:
按照上面给我的链接,我对此进行了编码。我的问题是没有出现滚动条。可能有人能告诉我为什么?
请注意,在此代码中,我解决了EDIT 1中突出显示的第一个和第二个问题:
import PIL.Image
import Image
import ImageTk
from Tkinter import *
class ExampleApp(Frame):
def __init__(self,master):
Frame.__init__(self,master=None)
self.x = self.y = 0
self.canvas = Canvas(master, cursor="cross")
self.sbarv=Scrollbar(self,orient=VERTICAL)
self.sbarh=Scrollbar(self,orient=HORIZONTAL)
self.sbarv.config(command=self.canvas.yview)
self.sbarh.config(command=self.canvas.xview)
self.canvas.config(yscrollcommand=self.sbarv.set)
self.canvas.config(xscrollcommand=self.sbarh.set)
self.canvas.grid(row=0,column=0,sticky=N+S+E+W)
self.sbarv.grid(row=0,column=1,stick=N+S)
self.sbarh.grid(row=1,column=0,sticky=E+W)
self.canvas.bind("<ButtonPress-1>", self.on_button_press)
self.canvas.bind("<B1-Motion>", self.on_move_press)
self.canvas.bind("<ButtonRelease-1>", self.on_button_release)
self.rect = None
self.start_x = None
self.start_y = None
self.im = PIL.Image.open("logo.png")
self.wazil,self.lard=self.im.size
self.canvas.config(scrollregion=(0,0,self.wazil,self.lard))
self.tk_im = ImageTk.PhotoImage(self.im)
self.canvas.create_image(0,0,anchor="nw",image=self.tk_im)
def on_button_press(self, event):
# save mouse drag start position
self.start_x = event.x
self.start_y = event.y
# create rectangle if not yet exist
#if not self.rect:
self.rect = self.canvas.create_rectangle(self.x, self.y, 1, 1, fill="")
def on_move_press(self, event):
curX, curY = (event.x, event.y)
# expand rectangle as you drag the mouse
self.canvas.coords(self.rect, self.start_x, self.start_y, curX, curY)
def on_button_release(self, event):
pass
if __name__ == "__main__":
root=Tk()
app = ExampleApp(root)
root.mainloop()
最佳答案
滚动条不显示,因为您将它们网格化
到您没有放入的框架中(self.sbarv=Scrollbar(self, ...)
)父窗口。不过,您可以直接将 Canvas 网格化到父窗口中 (self.canvas = Canvas(master, ...)
)。
你应该做的也是将 Canvas 放在 self
中,然后使用
app = ExampleApp(root)
app.pack()
但是,当滚动时,event.x
和 event.y
不再代表 Canvas 上的正确位置,因此您应该使用
self.start_x = self.canvas.canvasx(event.x)
self.start_y = self.canvas.canvasy(event.y)
和
curX = self.canvas.canvasx(event.x)
curY = self.canvas.canvasy(event.y)
然后,我知道你想在鼠标拖动到 Canvas 的边框之一时自动滚动 Canvas ?为此,您需要检查鼠标是否位于 Canvas 的边缘之一,如果是,则向该方向滚动。你可以使用类似的东西:
w, h = self.canvas.winfo_width(), self.canvas.winfo_height()
if event.x > 0.9*w:
self.canvas.xview_scroll(1, 'units')
elif event.x < 0.1*w:
self.canvas.xview_scroll(-1, 'units')
if event.y > 0.9*h:
self.canvas.yview_scroll(1, 'units')
elif event.y < 0.1*h:
self.canvas.yview_scroll(-1, 'units')
因此,在您的代码中实现的所有内容变为:
import PIL.Image
import Image
import ImageTk
from Tkinter import *
class ExampleApp(Frame):
def __init__(self,master):
Frame.__init__(self,master=None)
self.x = self.y = 0
self.canvas = Canvas(self, cursor="cross")
self.sbarv=Scrollbar(self,orient=VERTICAL)
self.sbarh=Scrollbar(self,orient=HORIZONTAL)
self.sbarv.config(command=self.canvas.yview)
self.sbarh.config(command=self.canvas.xview)
self.canvas.config(yscrollcommand=self.sbarv.set)
self.canvas.config(xscrollcommand=self.sbarh.set)
self.canvas.grid(row=0,column=0,sticky=N+S+E+W)
self.sbarv.grid(row=0,column=1,stick=N+S)
self.sbarh.grid(row=1,column=0,sticky=E+W)
self.canvas.bind("<ButtonPress-1>", self.on_button_press)
self.canvas.bind("<B1-Motion>", self.on_move_press)
self.canvas.bind("<ButtonRelease-1>", self.on_button_release)
self.rect = None
self.start_x = None
self.start_y = None
self.im = PIL.Image.open("logo.png")
self.wazil,self.lard=self.im.size
self.canvas.config(scrollregion=(0,0,self.wazil,self.lard))
self.tk_im = ImageTk.PhotoImage(self.im)
self.canvas.create_image(0,0,anchor="nw",image=self.tk_im)
def on_button_press(self, event):
# save mouse drag start position
self.start_x = self.canvas.canvasx(event.x)
self.start_y = self.canvas.canvasy(event.y)
# create rectangle if not yet exist
if not self.rect:
self.rect = self.canvas.create_rectangle(self.x, self.y, 1, 1, outline='red')
def on_move_press(self, event):
curX = self.canvas.canvasx(event.x)
curY = self.canvas.canvasy(event.y)
w, h = self.canvas.winfo_width(), self.canvas.winfo_height()
if event.x > 0.9*w:
self.canvas.xview_scroll(1, 'units')
elif event.x < 0.1*w:
self.canvas.xview_scroll(-1, 'units')
if event.y > 0.9*h:
self.canvas.yview_scroll(1, 'units')
elif event.y < 0.1*h:
self.canvas.yview_scroll(-1, 'units')
# expand rectangle as you drag the mouse
self.canvas.coords(self.rect, self.start_x, self.start_y, curX, curY)
def on_button_release(self, event):
pass
if __name__ == "__main__":
root=Tk()
app = ExampleApp(root)
app.pack()
root.mainloop()
关于python - Tkinter:使用鼠标绘制矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29789554/