Drawing rectangle using mouse events in Tkinter - python

This is with respect to Draw rectangle on mouse click [Python]. I tried out the first solution and it works perfectly. Can someone please tell me, what to do if I want to see the rectangle being drawn and the rectangle gets fixed once the mouse button is released as I can only see the drawn rectangle once the button is released.
Any kind of help will be appreciated.

I amended the code from the referenced question. Now it shows the rectangle when mouse is being dragged on the canvas. The canvas displays Lena image.
import tkinter as tk # this is in python 3.4. For python 2.x import Tkinter
from PIL import Image, ImageTk
class ExampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.x = self.y = 0
self.canvas = tk.Canvas(self, width=512, height=512, cursor="cross")
self.canvas.pack(side="top", fill="both", expand=True)
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._draw_image()
def _draw_image(self):
self.im = Image.open('./resource/lena.jpg')
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="black")
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__":
app = ExampleApp()
app.mainloop()
The black square is drawn on top of the image. Hope this helps.

Related

move canvas objects individually with mouse

The code below works the way I want it to but when I scroll down it starts to move the objects above instead of the one I try to move. I can't fix the problem. It only moves the first visible area of canvas. İs there a solution for this?
win = Tk()
win.geometry("1000x700")
# Define a Canvas widg
canvas = Canvas(win, width=1000, height=1000, bg="white",scrollregion=(0,0,3000,3000))
hbar=Scrollbar(win,orient=HORIZONTAL)
hbar.pack(side=BOTTOM,fill=X)
hbar.config(command=canvas.xview)
vbar=Scrollbar(win,orient=VERTICAL)
vbar.pack(side=RIGHT,fill=Y)
vbar.config(command=canvas.yview)
canvas.config(width=1000, height=1000)
canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
canvas.pack(side=LEFT,expand=True,fill=BOTH)
def move_start(event):
canvas.scan_mark(event.x, event.y)
return True
def move_move(event):
canvas.scan_dragto(event.x, event.y, gain=1)
return True
def on_click(event):
selected = canvas.find_overlapping(event.x-10, event.y-10, event.x+10, event.y+10)
if selected:
canvas.selected = selected[-1] # select the top-most item
canvas.startxy = (event.x, event.y)
print(canvas.selected, canvas.startxy)
else:
canvas.selected = None
def on_drag(event):
if canvas.selected:
# calculate distance moved from last position
dx, dy = event.x-canvas.startxy[0], event.y-canvas.startxy[1]
# move the selected item
canvas.move(canvas.selected, dx, dy)
# update last position
canvas.startxy = (event.x, event.y)
def delete():
msg = messagebox.askyesnocancel('Info', 'Delete canvas ?')
if msg == True:
canvas.delete(ALL)
canvas.bind("<Button-1>", on_click)
canvas.bind("<B1-Motion>", on_drag)
canvas.bind("<ButtonPress-3>", move_start)
canvas.bind("<B3-Motion>", move_move)
win.mainloop ()

Tkinter: Draw rectangle using a mouse, and crop a photo in the shape of that rectangle

I found this code online, and I changed it for my benefit, so it creates a rectangle and then it crops the photo in the shape of this rectangle. But, I've been facing a problem for a very long time: when the mouse is released, I can't use the image that I created and return it and use it in a variable. I think it's the section of on_button_release.
Basically, I would like to take a photo, then allow the user to draw a rectangle on the screen, crop this certain image in the rectangle shape and use it after wise in a variable as a PIL image.
Here's some code I found online after I changed it for my benefit:
import tkinter as tk
from tkinter import filedialog
import numpy
import PIL
from PIL import ImageTk, Image
from tkinter import *
class ExampleApp(Frame):
def __init__(self,master, file_path):
Frame.__init__(self,master=None)
self.file_path = file_path
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(self.file_path)
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)
self.im2 = self.im.crop((self.start_x, self.start_y, curX, curY))
self.tk_im2 = ImageTk.PhotoImage(self.im2)
def on_button_release(self, event):
self.canvas.delete("all")
self.canvas.create_image(0,0,anchor="nw",image=self.tk_im2)
if __name__ == "__main__":
file_path = 'images.jpg'
root=Tk()
app = ExampleApp(root, file_path = file_path)
app.pack()
root.mainloop()

Filling colour logically while drawing rectangle Tkinter

While using PIL draw rectangles on an image in the canvas. I wish to change the fill rectangle depending on the pixel color of my image in the canvas.
I have referred one of the cross posts (link pasted below) to create rectangles with mouse events in Tkinter.
create_rectangle fills the rectangle with a color specified with mouse events (example: the rectangle is filled with black in this example). Is there a way to logically change the fill color depending on the existing pixel color of the background image? I mean, while drawing a rectangle, I need only the white colored pixels of the background image to be turning red and the rest with a different color.
Drawing rectangle using mouse events in Tkinter
[1]: https://i.stack.imgur.com/W41kX.jpg
def rec_on_button_press(self,event):
self.start_x = event.x
self.start_y = event.y
self.rect=self.image_canvas.create_rectangle(self.x, self.y, 1, 1,fill=self.python_red)
def rec_on_move(self, event):
curX, curY = (event.x, event.y)
imagenp= np.array(image)
if imagenp[curY,curX]==255:
self.python_red="#EE204D"
else:
self.python_red=None
self.image_canvas.coords(self.rect, self.start_x, self.start_y, curX, curY)
def rec_on_button_release(self, event):
pass
Principle:
Crop the image you select,create it and show it.
The code need to be modified,the example of full code(the example is convert 255(white) to 0(black)):
import tkinter as tk # this is in python 3.4. For python 2.x import Tkinter
from PIL import Image, ImageTk
import numpy as np
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2) # for windows 10
class ExampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.x = self.y = 0
self.canvas = tk.Canvas(self, width=512, height=512, cursor="cross")
self.canvas.pack(side="top", fill="both", expand=True)
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.python_red = None
self.im = Image.open(r'ImagePath').convert("L")
self.move_imageID = None
self.move_image = None
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
self.rect = self.canvas.create_rectangle(self.x, self.y, 0, 0, outline="black")
def on_move_press(self, event):
self.canvas.delete(self.move_imageID)
crop_image = self.im.crop((self.start_x,self.start_y,event.x,event.y))
imageArray = np.array(crop_image)
if imageArray.shape:
for i in range(imageArray.shape[0]):
for j in range(imageArray.shape[1]): # convert the white pixel to black
if imageArray[i,j] == 255:
imageArray[i,j] = 0
self.move_image = Image.fromarray(imageArray)
self.move_image = ImageTk.PhotoImage(self.move_image)
self.move_imageID = self.canvas.create_image(self.start_x,self.start_y,anchor="nw",image=self.move_image)
self.canvas.coords(self.rect,self.start_x,self.start_y,event.x,event.y)
self.canvas.lift(self.rect)
def on_button_release(self, event):
pass
if __name__ == "__main__":
app = ExampleApp()
app.mainloop()
Now:
Select area:
Principle: Convert image to numpy array and use opencv to draw rectangles. After processing pixel colors convert back to image.
def rec_on_button_press(self,event):
self.start_x = event.x
self.start_y = event.y
self.rect=self.image_canvas.create_rectangle(self.x, self.y, 1, 1,fill=self.python_red)
def rec_on_move(self, event):
curX, curY = (event.x, event.y)
cropimage=originalimage.crop((self.start_x,self.start_y,curX,curY))
cropimagergb=cropimage.convert('RGB')
cropimagergb.save('crop1.png')
imagergbcv2=cv2.imread('crop1.png')
if imagergbcv2.shape[:2]:
for i in range(imagergbcv2.shape[0]):
for j in range(imagergbcv2.shape[1]):
color=imagergbcv2[i,j]
if (color[0]==255 and color[1]==255 and color[2]==255):
imagergbcv2[i,j]=(0,255,0)
cv2.imwrite('crop2.png',imagergbcv2)
croppedimage=cv2.imread('crop2.png')
originalimage[self.start_y:self.start_y+croppedimage.shape[0],self.start_x:self.start_x+croppedimage.shape[1]]=croppedimage
cv2.imwrite('originalpluscropped.png',originalimage)
self.image_canvas.coords(self.rect, self.start_x, self.start_y, curX, curY)
def rec_on_button_release(self, event):
pass
self.image=Image.open('originalpluscropped.png')

Basic image editing on Python tkinter working but unwanted image scrolling course when dragging mouse

The following code produces a nice Canvas with an image and I can draw a square on top of it. However:
a) I can't get the Canvas to not scroll.
b) I only want the image to appear and nothing else and can't get the sizes right
As you will see, I have even tried to stop the scrolling but it does not work all the time. In addition the image is never fully aligned with the Canvas nor the window even though I set the sizes to be the same for the three (root, canvas and image).
Here is the code (partly taken already from another example with some portions commented out):
try:
from PIL import Image
except ImportError:
import Image
from PIL import ImageTk
try:
import Tkinter as tk # Python2
except ImportError:
import tkinter as tk # Python3s
import Tkinter
from Tkinter import *
import PIL as PILAll
class ExampleApp(Frame):
def __init__(self,master):
Frame.__init__(self,master=None)
self.x = 0
self.y = 0
self.canvas = Canvas(self, cursor="cross", width=640, height=480, confine=True, scrollregion=(10, 10, 10, 10), relief="groove", bg="blue")# and I have experimented with a few other options
#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.config(scrollregion=self.canvas.bbox(ALL))
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.canvas.bind("<Leave>", self.on_button_leave)
self.canvas.bind("<Enter>", self.on_button_enter)
self.canvas.bind("<Double-Button-1>", self.on_double_click)
self.canvas.create_line(0, 0, 200, 100)
self.canvas.create_line(0, 100, 200, 0, fill="red", dash=(4, 4))
self.canvas.create_rectangle(50, 25, 150, 75, fill="blue")
self.rect = None
self.text = None
self.start_x = None
self.start_y = None
self.im = PILAll.Image.open("../../" + "image6.JPG")
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)
out_of_scope = 1
def on_button_leave(self, event):
self.out_of_scope = 2
print "out_of_scope....", self.out_of_scope
def on_button_enter(self, event):
print("entering...")
self.out_of_scope = 1
def on_double_click(self, event):
print("double click")
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:
if self.out_of_scope == 1:
self.rect = self.canvas.create_rectangle(self.x, self.y, 1, 1, outline='blue', fill='yellow') #since it's only created once it always remains at the bottom
def get_out_of_scope(self, x, y):
return self.out_of_scope
def on_move_press(self, event):
curX = self.canvas.canvasx(event.x)
curY = self.canvas.canvasy(event.y)
var=self.get_out_of_scope(event.x, event.y)
print(var, event.x, event.y)
if var == 1:
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):
print(event.x, event.y)
pass
root=Tk()
root.geometry("640x480")
app = ExampleApp(root)
app.grid()
root.mainloop()
I think your code would benefit from beingreviewed but I will try to limit myself to the question...
If the canvas needs to be the same size as the image why is it constructed with width=640, height=480? You figure out the width and height of the image further down:
self.im = PILAll.Image.open("../../" + "image6.JPG")
self.wazil,self.lard=self.im.size
(interesting variable name choice btw) so if self.wazil and self.lard represent the width and height of the image why don't you make that the width and height of the canvas?
self.im = PILAll.Image.open("../../" + "image6.JPG")
self.wazil,self.lard=self.im.size
self.canvas = Canvas(self, width=self.wazil, height=self.lard) #, ...)
then the canvas will be the correct size but the root window is still forcing itself to be 640x480 from:
root.geometry("640x480")
but since widgets will automatically scale themselves to the contents you can just comment that line out and it should be the correct size.
#root.geometry("640x480")
I should note that I was experiencing some very odd behaviour about the position of the image being 3 pixels too high and 3 pixels to the left, drawing the image with:
self.canvas.create_image(3,3,anchor="nw",image=self.tk_im)
fixed it for me but I have no idea why...
As for the scrolling you removed the parts about the scroll bars but you left in this in on_move_press:
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')
This is the section of code that is occasionally scrolling the canvas (happened when I tried to resize the window) so again you can comment that section out and it shouldn't scroll anymore.
Last note which is unrelated to question, you have:
def __init__(self,master):
Frame.__init__(self,master=None)
But I'm pretty sure you mean to have:
def __init__(self,master=None):
Frame.__init__(self,master)
since the first way you require a master argument but do not pass it to Frame.__init__. When Frame.__init__ receives a master of None it just uses the Tk instance which in your case is the same thing but if you used any other master it would cause very odd issues.

Tkinter: Draw rectangle using a mouse

Please, help me to resolve this problem.
I want to allow the user to draw a random rectangle around a specific region of interest in a picture using the mouse ( by clicking the right or left button of the mouse until he releases it).
I deal with large images (images larger than the resolution of my screen, such as this one), so the user needs to scroll the window in order to be able to see the picture fully.
Here is the code I tried just to display a large picture, but I have no idea on how to allow the user to draw using his mouse a rectangle over an object (say a person in a picture):
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()
EDIT 1:
The rectangle must not be filled. I mean I want to draw only its 4 lines (segments) but it must be empty inside, I want to draw only its contours in one pixel width.
I also want to draw as the cursor is moving (dragging) not after button release.
Also, note that the rectangle to draw may be a long one, I mean the vertical scroll-bar will need to move down to be able to delimitate the whole object of interest (let's say it is a person)
Any help will be highly appreciated.
Thank you very much in advance
EDIT 2:
Following the link given to me above, I coded this. My problem is that the scroll-bars do not appear. May be someone could tell me why ?
Note that in this code, I resolved the first and second problems highlighted in 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()
The Scrollbars do not show because you grid them into a Frame (self.sbarv=Scrollbar(self, ...)) which you do not place into the parent window. You directly grid the Canvas into the parent window though (self.canvas = Canvas(master, ...)).
What you should do is also put the Canvas in self and then pack the Frame into the master window using
app = ExampleApp(root)
app.pack()
However, when scrolling, the event.x and event.y do not represent the correct position on tha canvas anymore, so you should use
self.start_x = self.canvas.canvasx(event.x)
self.start_y = self.canvas.canvasy(event.y)
and
curX = self.canvas.canvasx(event.x)
curY = self.canvas.canvasy(event.y)
Then, I understand you want to automatically scroll the canvas when the mouse is dragging to one of the borders of the canvas? To do that, you need to check if the mouse is at one of the edges of the canvas and scroll in that direction if it is. You can use something like:
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')
So, all that implemented in your code becomes:
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()

Categories