canvas 上的 Tkinter 显示网格

Tkinter show grid on canvas

我想 show/hide tkinter canvas 上的网格,例如在 Gimp 中看到的那样。

我有这个代码:

is_on = True

def my_grid():
    global is_on
    global hor
    global ver
        
    if is_on:
        y=0
        x=0
        for i in range(8):
            x+=64
            y+=64
            hor=A.create_line(0,y,512,y, fill="black")
            ver=A.create_line(x,0, x, 512, fill="black")
        is_on=False
    else:
        A.delete(hor)
        A.delete(ver)
        is_on=True

这只删除最后一行和最后一列。我也尝试过循环删除操作,但它不起作用。

希望有人能帮助我。

最佳

尝试这样的事情:

import tkinter as tk


class CanvasGrid(tk.Canvas):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        self.lines = []
        self.lines_displayed = False

    def display_lines(self):
        # If the lines are already displayed don't do anything
        if self.lines_displayed:
            return None
        self.lines_displayed = True
        # Clear the list of the lines as they are no longer on the screen
        self.lines.clear()

        # Get the width and height of the canvas
        width = super().winfo_reqwidth()
        height = super().winfo_reqheight()

        # Loop through and create the vertical lines
        for x in range(0, width-width//8, width//8):
            line = super().create_line(x, 0, x, height, fill="black")
            self.lines.append(line)

        # Loop through and create the horizontal lines
        for y in range(0, height-height//8, height//8):
            line = super().create_line(0, y, width, y, fill="black")
            self.lines.append(line)

    def hide_lines(self):
        # For each line that is on the screen
        for line in self.lines:
            # Delete the line
            super().delete(line)
        self.lines_displayed = False


# Example code that uses the class

def toggle_lines(event):
    if canvas.lines_displayed:
        canvas.hide_lines()
    else:
        canvas.display_lines()

root = tk.Tk()

canvas = CanvasGrid(root, width=400, height=400)
canvas.pack()

canvas.display_lines()
canvas.bind("<Button-1>", toggle_lines)

root.mainloop()

我通过添加 display_lineshide_lines 创建了 tkinter.Canvas class 的扩展。您可以像使用 tkinter.Canvas 一样使用 class 但它具有这两种方法。要试用示例代码,请单击 canvas 到 show/hide 行。

如果你给行添加一个标签,你可以用一个语句操作所有的行。

此外,无需每次都删除并重新创建行。您可以通过将它们的 state 设置为 "hidden".

来隐藏网格

例如,创建、隐藏和显示网格的方法如下:

def create_grid():
    x = y = 0
    for i in range(8):
        x+=64
        y+=64
        A.create_line(0,y,512,y, fill="black", tags=("grid",))
        A.create_line(x,0, x, 512, fill="black", tags=("grid",))

def show_grid():
    A.itemconfigure("grid", state="normal")

def hide_grid():
    A.itemconfigure("grid", state="hidden")

这是另一种方法:

from tkinter import Tk, Canvas, Button

vertical = 8
horizontal = 8
canvas_width = 700
canvas_height = 500
grid_lst = []


def grid(mode):
    if mode == 'show':
        if len(grid_lst):
            return
        for hor in range(horizontal):
            y = (hor + 1) * (canvas_height / (horizontal + 1))
            grid_lst.append(canvas.create_line((0, y, canvas_width, y), fill='black'))
        for ver in range(vertical):
            x = (ver + 1) * (canvas_width / (vertical + 1))
            grid_lst.append(canvas.create_line((x, 0, x, canvas_height), fill='black'))
    if mode == 'hide':
        for line in grid_lst:
            canvas.delete(line)
        grid_lst.clear()


root = Tk()

canvas = Canvas(root, width=canvas_width, height=canvas_height, bg='grey')
canvas.pack()

Button(root, text='Show Grid', command=lambda: grid('show')).pack(side='left', fill='x', expand=True)
Button(root, text='Hide Grid', command=lambda: grid('hide')).pack(side='right', fill='x', expand=True)

root.mainloop()

此方法仅使用一个函数,该函数的参数决定如何处理网格:显示或隐藏。它还以一种改变变量的方式使用变量也会自动调整网格:verticalhorizontalcanvas_widthcanvas_height。他们说到做到。 vertical 确定垂直线的数量,horizontal 确定水平线的数量,因此这是非常可调整的和“动态的”。

编辑:改进了性能,如果 grid('show') 被多次调用,行不会添加到列表中,并且当 grid('hide') 被调用时,列表被清除。