Kkheartsmak
Kkheartsmak

Reputation: 49

Drawing a rectangle using Tkinter?

I have this code so far. At first I made it draw circles which worked well. I thought that drawing rectangles would be as easy, but I have only been able to draw squares. I was hoping to have shapes of various widths and lengths. Do I know I need to change the box of (x1, y1, x2, y2) but how would I go about that.

def down(event): # A mouse event will be passed in with x and y attributes
global startx, starty # Use global variables for assignment
startx = event.x # Store the mouse down coordinates in the global variables
starty = event.y

def up(event):
    tk_color_string = color(red_intvar, green_intvar, blue_intvar)
    r = (startx-event.x)**2 + (starty-event.y)**2  # Pythagorean theorem
    r = int(r**.5)                                 # square root to get distance
    new_shape = canvas.create_rectangle(startx-r, starty-r, startx+r, starty+r,
                                     fill=tk_color_string, outline='#000000')
    shapes.append(new_shape) # aggregate the canvas' item

The whole code is over 100 lines long, so I hope this piece helps demonstrate what I am asking.enter image description here

Upvotes: 2

Views: 10658

Answers (1)

Sun Bear
Sun Bear

Reputation: 8234

I am providing an example code below that I just wrote on how to create rectangles in tkinter canvas with a mouse. I hope this helps you understand the relevant procedures and the methods you need. Thereafter, adapt it for your particular problem. Hopes this helps you and best regards.

Example code: How to create tkinter canvas that allows a user to draw rectangle objects with a mouse.

import tkinter as tk

class App(tk.Frame):
    def __init__( self, parent):
        tk.Frame.__init__(self, parent)
        self._createVariables(parent)
        self._createCanvas()
        self._createCanvasBinding()

    def _createVariables(self, parent):
        self.parent = parent
        self.rectx0 = 0
        self.recty0 = 0
        self.rectx1 = 0
        self.recty1 = 0
        self.rectid = None

    def _createCanvas(self):
        self.canvas = tk.Canvas(self.parent, width = 800, height = 400,
                                bg = "white" )
        self.canvas.grid(row=0, column=0, sticky='nsew')

    def _createCanvasBinding(self):
        self.canvas.bind( "<Button-1>", self.startRect )
        self.canvas.bind( "<ButtonRelease-1>", self.stopRect )
        self.canvas.bind( "<B1-Motion>", self.movingRect )

    def startRect(self, event):
        #Translate mouse screen x0,y0 coordinates to canvas coordinates
        self.rectx0 = self.canvas.canvasx(event.x)
        self.recty0 = self.canvas.canvasy(event.y) 
        #Create rectangle
        self.rectid = self.canvas.create_rectangle(
            self.rectx0, self.recty0, self.rectx0, self.recty0, fill="#4eccde")
        print('Rectangle {0} started at {1} {2} {3} {4} '.
              format(self.rectid, self.rectx0, self.recty0, self.rectx0,
                     self.recty0))

    def movingRect(self, event):
        #Translate mouse screen x1,y1 coordinates to canvas coordinates
        self.rectx1 = self.canvas.canvasx(event.x)
        self.recty1 = self.canvas.canvasy(event.y)
        #Modify rectangle x1, y1 coordinates
        self.canvas.coords(self.rectid, self.rectx0, self.recty0,
                      self.rectx1, self.recty1)
        print('Rectangle x1, y1 = ', self.rectx1, self.recty1)

    def stopRect(self, event):
        #Translate mouse screen x1,y1 coordinates to canvas coordinates
        self.rectx1 = self.canvas.canvasx(event.x)
        self.recty1 = self.canvas.canvasy(event.y)
        #Modify rectangle x1, y1 coordinates
        self.canvas.coords(self.rectid, self.rectx0, self.recty0,
                      self.rectx1, self.recty1)
        print('Rectangle ended')


if __name__ == "__main__":
    root = tk.Tk()
    root.geometry( "600x400" )
    app = App(root)
    root.mainloop()

Overview of Steps and Methods Used:

  1. Create a canvas widget in Tk() window using tk.Canvas() method
  2. Bind mouse events <Button-1>, <ButtonRelease-1> and <B1-Motion> with their callbacks to tk.Canvas widget.
  3. For each of these events:
    3.1 Convert mouse pointer screen x, y coordinates to canvas coordinates using methods .canvasx(event.x) and .canvasy(event.y) and store these converted corrdinates in variables self.rectx0, self.recty0, self.rectx1, self.recty1. event.x and event.y provides the mouse pointer screen coordinates.
    3.2 Use canvas method .create_rectangle(x0, y0, x1, y1, option, ...) to create rectangle or use canvas method .coords(tagOrId, x0, y0, x1, y1) to modify rectangle coordinates. Here, x0, y0, x1, y1 denotes the rectangle object's top left corner and bottom right corner x & y canvas coordinates, and tagOrId denoted the rectangle object ID.
    3.3 Only for <Button-1>, need to store the created rectangle object's ID in a variable. This variable provides the value to tagOrId whenever .coords() method is called during <B1-Motion> and <ButtonRelease-1>.

Upvotes: 5

Related Questions