Tkinter: 存储给定宽度绘制线条的坐标

76 阅读3分钟

在 Tkinter 中,用户可以使用鼠标在画布上绘制线条。默认情况下,线条的宽度为1像素,但用户还可以通过设置 width 选项来调整线条的宽度。如果线条的宽度大于1像素,则线条两侧的像素也会被更改,但是在保存线条的坐标时,只能获得端点坐标,无法获得线条两侧像素的坐标。

  1. 解决方案

由于无法直接获得线条两侧的像素坐标,因此无法满足用户的要求。但是,我们可以使用一些技巧来估计线条两侧的像素坐标。

以下是一个估计线条两侧像素坐标的示例代码:

# 估计线条两侧像素坐标的示例代码

import tkinter as tk

class Test:
    def __init__(self):
        self.b1 = "up"
        self.xold = None
        self.yold = None
        self.lines = []  # 存储绘制的线条

    def test(self, obj):
        self.drawingArea = tk.Canvas(obj)
        self.drawingArea.pack()
        self.drawingArea.bind("<Motion>", self.motion)
        self.drawingArea.bind("<ButtonPress-1>", self.b1down)
        self.drawingArea.bind("<ButtonRelease-1>", self.b1up)

    def b1down(self, event):
        self.b1 = "down"

    def b1up(self, event):
        self.b1 = "up"
        self.xold = None
        self.yold = None

    def motion(self, event):
        if self.b1 == "down":
            if self.xold is not None and self.yold is not None:
                line = self.drawingArea.create_line(self.xold, self.yold, event.x, event.y, fill="red", width=4, smooth=True)
                self.lines.append(line)  # 将线条添加到列表中
            self.xold = event.x
            self.yold = event.y


if __name__ == "__main__":
    root = tk.Tk()
    root.wm_title("Test")
    v = Test()
    v.test(root)
    root.mainloop()

在上面的代码中,我们将绘制的线条存储在 lines 列表中。然后,我们可以使用 itemconfig() 方法来获取每条线条的坐标和宽度。

以下是一个获取线条坐标和宽度的示例代码:

# 获取线条坐标和宽度的示例代码

import tkinter as tk

class Test:
    def __init__(self):
        self.b1 = "up"
        self.xold = None
        self.yold = None
        self.lines = []  # 存储绘制的线条

    def test(self, obj):
        self.drawingArea = tk.Canvas(obj)
        self.drawingArea.pack()
        self.drawingArea.bind("<Motion>", self.motion)
        self.drawingArea.bind("<ButtonPress-1>", self.b1down)
        self.drawingArea.bind("<ButtonRelease-1>", self.b1up)

    def b1down(self, event):
        self.b1 = "down"

    def b1up(self, event):
        self.b1 = "up"
        self.xold = None
        self.yold = None

    def motion(self, event):
        if self.b1 == "down":
            if self.xold is not None and self.yold is not None:
                line = self.drawingArea.create_line(self.xold, self.yold, event.x, event.y, fill="red", width=4, smooth=True)
                self.lines.append(line)  # 将线条添加到列表中
            self.xold = event.x
            self.yold = event.y

    def get_line_info(self):
        for line in self.lines:
            # 获取线条的坐标和宽度
            coords = self.drawingArea.coords(line)
            width = self.drawingArea.itemconfig(line)["width"]

            # 打印线条的坐标和宽度
            print("Line coordinates:", coords)
            print("Line width:", width)


if __name__ == "__main__":
    root = tk.Tk()
    root.wm_title("Test")
    v = Test()
    v.test(root)
    v.get_line_info()  # 获取线条的坐标和宽度
    root.mainloop()

在上面的代码中,我们使用 coords() 方法来获取线条的坐标,使用 itemconfig() 方法来获取线条的宽度。然后,我们将线条的坐标和宽度打印出来。

我们还可以使用 bbox() 方法来获取线条的边界框。边界框是一个矩形,它包含线条的所有像素。

以下是一个获取线条边界框的示例代码:

# 获取线条边界框的示例代码

import tkinter as tk

class Test:
    def __init__(self):
        self.b1 = "up"
        self.xold = None
        self.yold = None
        self.lines = []  # 存储绘制的线条

    def test(self, obj):
        self.drawingArea = tk.Canvas(obj)
        self.drawingArea.pack()
        self.drawingArea.bind("<Motion>", self.motion)
        self.drawingArea.bind("<ButtonPress-1>", self.b1down)
        self.drawingArea.bind("<ButtonRelease-1>", self.b1up)

    def b1down(self, event):
        self.b1 = "down"

    def b1up(self, event):
        self.b1 = "up"
        self.xold = None
        self.yold = None

    def motion(self, event):
        if self.b1 == "down":
            if self.xold is not None and self.yold is not None:
                line = self.drawingArea.create_line(self.xold, self.yold, event.x, event.y, fill="red", width=4, smooth=True)
                self.lines.append(line)  # 将线条添加到列表中
            self.xold = event.x
            self.yold = event.y

    def get_line_info(self):
        for line in self.lines:
            # 获取线条的边界框
            bbox = self.drawingArea.bbox(line)

            # 打印线条的边界框
            print("Line bounding box:", bbox)


if __name__ == "__main__":
    root = tk.Tk()
    root.wm_title("Test")
    v = Test()
    v.test(root)
    v.get_line_info()  # 获取线条的边界框
    root.mainloop()

在上面的代码中,我们使用 bbox() 方法来获取线条的边界框。然后,我们将线条的边界框打印出来。