【发布时间】:2019-01-09 16:53:22
【问题描述】:
我正在尝试在 tkinter 画布上放置形状图案。到目前为止,我已经成功地用图案填充了一个矩形(比如砌砖),并且效果很好:
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.config(borderwidth=0.0, highlightthickness=0.0)
bbox = (0, 0, 100, 100)
x1, y1, x2, y2 = bbox
width = 10
height = 5
def laying_bricks():
for even, y in enumerate(range(y1, y2, height)):
x = 0
while x < x2:
increm = width //2 if even % 2 == 0 and x == 0 else width
x_end = x + increm
x_end = x_end if x_end < x2 else x2
canvas.create_rectangle(x, y, x_end, y + height, fill='firebrick3', outline='khaki')
x = x_end
laying_bricks()
# Add the final box outline for the shape
canvas.create_rectangle(*bbox)
canvas.pack()
root.mainloop()
对于锐角,我可以尝试在末端绘制单个多边形(不是首选),或者我可以应用蒙版以某个角度截断:
laying_bricks()
canvas.create_rectangle(*bbox)
triangulate = (0, 0, 0, 100, 100, 0)
canvas.create_polygon(triangulate, fill='black')
但是,如果我想在圆弧/椭圆等不规则形状中填充相同的图案,在末端绘制单独的图案不仅困难而且不切实际。我可以痛苦地为多边形截止形状创建自己的抛物线:
def create_parabola():
points = [0, 0]
for x in range(0, 200):
y = 170 - sqrt(100 * x + 20)
points.extend([x, y])
points.extend([200, 0, 0, 0])
canvas.create_polygon(points, fill='royalblue')
laying_bricks()
create_parabola()
但话又说回来,这似乎不切实际,特别是如果画布更大,并且它不能让我精确地将曲线放置在有界区域内。
我的问题:有没有一种明显的方法可以使用 tkinter 填充弧/椭圆的“负空间”或“外部”区域?或者,是否可以创建一个带填充的反圆弧/椭圆?还是只是功能有限?
【问题讨论】:
-
我认为你要让它在 Tkinter 中工作的唯一方法是在其他一些实际支持剪辑/遮罩的环境中生成图案形状(可能是 PIL/Pillow),然后添加它作为单个图像添加到您的 Canvas。
-
@jasonharper 我有点想它不可用,但只是想看看我是否缺少一些东西,因为 tkinter 不一定有最好的文档。我编辑了我的问题,包括创建我自己的弯曲多边形,但这似乎是不必要的痛苦。我还没有尝试过
PIL,所以这可能是一个值得探索的途径。谢谢! -
tkinter.canvas提供的方法只支持非常基本的图形操作和基元——因此使用它来做你想做的事情是相当困难的。您可以按照我对@stovfl 评论中链接问题的回答(并在后续评论中暗示)使用 PIL 来伪造它。 -
感谢大家的cmets。我寻找纯粹的
tkinter答案的原因是因为我想远离这个特定项目的外部图像。我很欣赏这样一个事实,如果图像是预先绘制的,它可能会更容易,但我想看看我可以保持我的脚本有多轻量级。我完全可以理解为什么tkinter不会提供该功能,所以我已经为我的曲线设计了不同的图案化方法,但只是想看看是否有替代方法。