点画 Tkinter 画布小部件的最简单方法是什么?

发布于 2024-10-14 21:13:27 字数 2098 浏览 5 评论 0原文

我有一个 Tkinter 画布小部件,我想在其上创建点画图案。我知道我可以使用 create_line 方法手动完成此操作。但是,我认为似乎有更好的方法。任何帮助将不胜感激。

我目前正在做什么。 (按 Alt-F4 退出程序)

import Tkinter, re

class StippleCanvas(Tkinter.Tk):
    def __init__(self, parent):
        Tkinter.Tk.__init__(self, parent)


        self.overrideredirect(1)
        self.resizable(False,False)
        self.wm_attributes("-topmost", 1)
        self.attributes("-alpha", 0.9)

        w = 90
        h = 90

        self.Ca = Tkinter.Canvas(self, width=w, height=h, highlightthickness=0, bd=0, bg='grey25')
        self.Ca.grid(column=0, row=0)
        self.bind('<Button-1>', self.relative_mouse_position)
        self.bind('<ButtonRelease-1>', self.wid_unbind)

        i0 = 0
        while i0 < w:
            i1 = 0
            while i1 < h:
                self.Ca.create_line(i1, i0, i1+1, i0, fill='grey20', width=1)
                i1 = i1 + 2
            i0 = i0 + 2

    def geom_grab (self):
        Cursorgfltr = re.compile(r"(\d+), (\d+)")
        CursorPos = self.winfo_pointerxy()
        CursorPosGr = Cursorgfltr.search(str(CursorPos))
        self.CursorX = int(CursorPosGr.group(1))
        self.CursorY = int(CursorPosGr.group(2))

        gfltr = re.compile(r"(\d+)?x?(\d+)?([+-])(\d+)([+-])(\d+)")

        gf = gfltr.search(self.wm_geometry())
        self.X = int(gf.group(4))
        self.Y = int(gf.group(6))

    def relative_mouse_position (self, event):
        self.geom_grab()

        RelX = self.CursorX - self.X
        RelY = self.CursorY - self.Y

        self.Ca.bind( "<Motion>", lambda event: self.wid_drag(event, RelX, RelY) )

    def wid_drag (self, event, RelX, RelY):


        self.geom_grab()

        X = self.CursorX - RelX
        Y = self.CursorY - RelY

        if X < 0:
            X = 0

        if Y < 0:
            Y = 0

        self.wm_geometry('+' + str(X) + '+' + str(Y))


    def wid_unbind (self, event):
        self.Ca.unbind("<Motion>")

def run():
    StippleCanvas(None).mainloop()
if __name__ == '__main__':
    run()

I have a Tkinter canvas widget and I'd like to create a stipple pattern on it. I know I could do it manually using the create_line method. However, I'd think there would seem to be a better way. Any help would be much appreciated.

What I'm currently working with. (press Alt-F4 to exit the program)

import Tkinter, re

class StippleCanvas(Tkinter.Tk):
    def __init__(self, parent):
        Tkinter.Tk.__init__(self, parent)


        self.overrideredirect(1)
        self.resizable(False,False)
        self.wm_attributes("-topmost", 1)
        self.attributes("-alpha", 0.9)

        w = 90
        h = 90

        self.Ca = Tkinter.Canvas(self, width=w, height=h, highlightthickness=0, bd=0, bg='grey25')
        self.Ca.grid(column=0, row=0)
        self.bind('<Button-1>', self.relative_mouse_position)
        self.bind('<ButtonRelease-1>', self.wid_unbind)

        i0 = 0
        while i0 < w:
            i1 = 0
            while i1 < h:
                self.Ca.create_line(i1, i0, i1+1, i0, fill='grey20', width=1)
                i1 = i1 + 2
            i0 = i0 + 2

    def geom_grab (self):
        Cursorgfltr = re.compile(r"(\d+), (\d+)")
        CursorPos = self.winfo_pointerxy()
        CursorPosGr = Cursorgfltr.search(str(CursorPos))
        self.CursorX = int(CursorPosGr.group(1))
        self.CursorY = int(CursorPosGr.group(2))

        gfltr = re.compile(r"(\d+)?x?(\d+)?([+-])(\d+)([+-])(\d+)")

        gf = gfltr.search(self.wm_geometry())
        self.X = int(gf.group(4))
        self.Y = int(gf.group(6))

    def relative_mouse_position (self, event):
        self.geom_grab()

        RelX = self.CursorX - self.X
        RelY = self.CursorY - self.Y

        self.Ca.bind( "<Motion>", lambda event: self.wid_drag(event, RelX, RelY) )

    def wid_drag (self, event, RelX, RelY):


        self.geom_grab()

        X = self.CursorX - RelX
        Y = self.CursorY - RelY

        if X < 0:
            X = 0

        if Y < 0:
            Y = 0

        self.wm_geometry('+' + str(X) + '+' + str(Y))


    def wid_unbind (self, event):
        self.Ca.unbind("<Motion>")

def run():
    StippleCanvas(None).mainloop()
if __name__ == '__main__':
    run()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤凫 2024-10-21 21:13:27

最简单的?这取决于你对“简单”的定义。一种方法是使用绘图程序创建所需的背景图像,然后将其放置在画布中。这假设您提前知道画布的大小。没有什么比将单个图像插入画布更简单的了。

此主题的一个变体是创建一个小图块,并使用 tkinter 的图像处理来创建一个适当大小的新图像,并将原始图像平铺在新图像中。每次调整画布大小时都可以执行此操作。可以在以下链接中看到这方面的一些示例,尽管它们是 Tcl 而不是 Python(将其转换为 python 非常简单,所以不要让这个吓到您):

http://wiki.tcl.tk/4389

不过,坦率地说,对于一个简单的点画来说,你所做的很好。我会将点画图移至一个函数,以便每当画布大小发生变化时(即:当它获取 事件时)它都可以重新运行。

The simplest? That depends on your definition of "simple". One way is to use a drawing program to create the image you want for the background, then place that in the canvas. This presumes you know the size of the canvas ahead of time. There's nothing much simpler than inserting a single image to the canvas.

A variation on this theme is to create a small tile, and use tkinter's image processing to create a new image of the appropriate size with the original image tiled in the new image. This can be done every time the canvas is resized. Some examples of this can be seen at the following link, though they are in Tcl rather than Python (converting it to python is very straight-forward so don't let that spook you):

http://wiki.tcl.tk/4389

Though, frankly, for a simple stipple what you've done is fine. I'd move the stipple-drawing to a function so it can be re-run whenever the canvas changes size (ie: when it gets a <Configure> event).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文