首页 > 解决方案 > 另一种移动画布对象的方法?

问题描述

我想知道除了 canvas.move() 之外,是否还有另一种方法可以更改画布内对象的位置。我宁愿设置特定的坐标而不是移动对象。

标签: pythontkintercanvas

解决方案


如果你想在画布上移动一个对象,试试这个:试试这个:

# In Python 3.8 and greater you can use this:
# `<tk.Canvas>.moveto(object, new_x, new_y)`
# like what @JacksonPro pointed out.
# but I am using python 3.7 so I am using this:

import tkinter as tk

def abs_move(self, _object, new_x, new_y):
    # Get the current object position
    x, y, *_ = self.bbox(_object)
    # Move the object
    self.move(_object, new_x-x, new_y-y)
# Monkey patch the `abs_move` method
tk.Canvas.abs_move = abs_move


"""
Testing script:
"""
# Moves the square to x=300
def move_square():
    canvas.abs_move(square, 300, 0)

root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=200, bg="cyan")
canvas.pack()
button = tk.Button(root, text="Move square to x=300", command=move_square)
button.pack()

square = canvas.create_rectangle(100, 0, 200, 100, fill="black")

root.mainloop()

另一种方法是直接调用 tcl 解释器。取自这里- @martineau 找到了它。

# Works python 3.7 and greater

import tkinter as tk

def moveto(self, tagOrId, xPos, yPos):
    # Taken from https://bugs.python.org/issue23831
    """Move the items given by tagOrId in the canvas coordinate  
    space so that the first coordinate pair of the bottommost 
    item with tag tagOrId is located at position (xPos,yPos). 
    xPos and yPos may be the empty string, in which case the        
    corresponding coordinate will be unchanged. All items matching
    tagOrId remain in the same positions relative to each other.    
    This command returns an empty string. 
    """
    return self.tk.call(self._w, "moveto", tagOrId, xPos, yPos)
tk.Canvas.moveto = moveto


"""
Testing script:
"""
# Moves the square to x=300
def move_square():
    canvas.moveto(square, 300, 0)

root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=200, bg="cyan")
canvas.pack()
button = tk.Button(root, text="Move square to x=300", command=move_square)
button.pack()

square = canvas.create_rectangle(100, 0, 200, 100, fill="black")

root.mainloop()

如果你想移动实际的画布,试试这个:

import tkinter as tk


class MovableCanvas(tk.Frame):
    def __init__(self, master, bg=None, canvas_bg=None, canvas_width=None,
                 canvas_height=None, **kwargs):
        super().__init__(master, bg=bg, **kwargs)
        self.canvas = tk.Canvas(self, bg=canvas_bg, width=canvas_width,
                                height=canvas_height)
        self.canvas.place(x=0, y=0)

    def move_canvas(self, new_x, new_y):
        self.canvas.place(x=new_x, y=new_y)


# Moves the whole Canvas to x=300
def move_square():
    canvas.move_canvas(300, 0)

root = tk.Tk()
canvas = MovableCanvas(root, width=400, height=200, canvas_width=100,
                       canvas_height=100, bg="cyan", canvas_bg="orange")
canvas.pack()
button = tk.Button(root, text="Move square to x=300", command=move_square)
button.pack()

root.mainloop()

推荐阅读