Tkinter: Draw rectangle using a mouse Tkinter: Draw rectangle using a mouse tkinter tkinter

Tkinter: Draw rectangle using a mouse


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.Imageimport Imageimport ImageTkfrom 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()