【问题标题】:Draw a THICK curve on a tkinter Canvas在 tkinter 画布上绘制一条粗曲线
【发布时间】:2021-10-30 05:23:45
【问题描述】:

我想使用 tkinter Canvas 对象在屏幕上画笔迹。使用example code from the tkdocs website,当我使用 20 的大线宽时,我得到以下绘图工件:

但是,对于小线宽,一切都很好:

这是完整的 Python 代码:

from tkinter import *
from tkinter import ttk

class Sketchpad(Canvas):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.bind("<Button-1>", self.save_posn)
        self.bind("<B1-Motion>", self.add_line)
        
    def save_posn(self, event):
        self.lastx, self.lasty = event.x, event.y

    def add_line(self, event):
        self.create_line((self.lastx, self.lasty, event.x, event.y))
        self.save_posn(event)

root = Tk()
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

sketch = Sketchpad(root)
sketch.grid(column=0, row=0, sticky=(N, W, E, S))

root.mainloop()

我使用的是 Python 3.8。

到目前为止我尝试了什么:

  • 不同的连接样式没有效果
  • smooth 参数无效
  • 不值得一提的各种不成功的肮脏黑客和变通方法

有人知道我如何摆脱这个神器吗?

谢谢!

【问题讨论】:

  • 您可以尝试将self.create_line 替换为self.create_oval 并检查是否会产生您想要的效果吗?
  • 是的,几乎成功了!我用两个self.create_oval 语句替换了self.create_line,用于“行”的开始和结束。如果我画得慢就行,如果我画得快就不行。

标签: python tkinter canvas drawing tkinter-canvas


【解决方案1】:

您可以在create_line() 中使用capstyle='round'

self.create_line((self.lastx, self.lasty, event.x, event.y), width=20, capstyle='round')

【讨论】:

  • 做到了!仍然不确定为什么标准 capstyle 不起作用,但将其设置为 ROUND 确实可以解决问题。
【解决方案2】:

您正在为每个&lt;B1-Motion&gt; 事件创建一条新线,而不是向每个新点延伸一条线。因此,这条线的每个新部分都不知道之前的部分,也没有努力很好地连接所有点。细线您不会注意到这一点,但如果仔细观察,您实际上也可以在您显示的细线的弯曲处看到它。

您可以使用圆形大写样式使问题不可见,因为大写填充了行之间的所有空间,但对我来说,创建一条线并通过在&lt;Button-1&gt; 上创建一条线来更新其坐标会更有意义并将其扩展至&lt;B1-Motion&gt;:

from tkinter import *
from tkinter import ttk


class Sketchpad(Canvas):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        self.bind("<Button-1>", self.new_line)
        self.bind("<B1-Motion>", self.add_to_line)

    def new_line(self, event):
        self.points = [event.x, event.y]
        self.line = self.create_line(event.x, event.y, event.x, event.y, width=20, capstyle=ROUND)

    def add_to_line(self, event):
        self.points.extend([event.x, event.y])
        self.coords(self.line, *self.points)


root = Tk()
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

sketch = Sketchpad(root)
sketch.grid(column=0, row=0, sticky=(N, W, E, S))

root.mainloop()

请注意,使用圆形 capstyle 可能看起来更好,但现在它只影响行尾,因为它应该是。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-02
    • 2015-07-22
    • 2018-03-12
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 2011-02-08
    相关资源
    最近更新 更多