简体   繁体   中英

Changing the colour of all canvas items (rectangles) pressed by a mouse click and drag (Tkinter)

I am designing an application for creating pixel art in Python. I currently have it so that the user can specify a required grid size (width * height) and it will create a grid of the specified height, with each grid square representing a point in a 2D list.

I used Tkinter's canvas widget and it's create_rectangle method to draw the grid, as the code excerpt shows.

I want to be able to click a grid square and drag my mouse, making the original clicked grid square and all of those which are dragged over by my mouse change colour.

A bit of research lead me to canvas tag_bind and bind, but neither of these seem to be able to allow me to implement the drag functionality I would like. The event.widget.findclosest method is very inaccurate.

Here is the code I have to draw the grid without any access to the onclick function.

 def drawGrid(self):
    for x in range(0, self.grid_width):
        for y in range(0, self.grid_height):
            x1 = (x * self.pixel_width)
            x2 = (x1 + self.pixel_width)
            y1 = (y * self.pixel_height)
            y2 = (y1 + self.pixel_height)
            self.grid[x,y] = self.canvas.create_rectangle(x1,y1,x2,y2)
    self.canvas.update()

def rectangleOnClick(event):
    #Colour the clicked square and all other squares that fall under mouse drag

You can create bindings that set a flag on button press, and release the flag on button release. You can set a binding on mouse motion that colors the item under the cursor when the flag is set.

It would look something like this:

class Example(object):
    def __init__(self, parent):
        ...
        self._dragging = False
        ...
        self.canvas.bind("<ButtonPress-1>", self.on_click)
        self.canvas.bind("<B1-Motion>", self.on_move)
        self.canvas.bind("<ButtonRelease-1>", self.on_release)

    def on_click(self, event):
        self._dragging = True
        self.on_move(event)

    def on_move(self, event):
        if self._dragging:
            items = self.canvas.find_closest(event.x, event.y)
            if items:
                rect_id = items[0]
                self.canvas.itemconfigure(rect_id, fill="red")

    def on_release(self, event):
        self._dragging = False

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM