【问题标题】:Is it possible to fill the outside of an arc/oval in tkinter canvas?是否可以在 tkinter 画布中填充弧形/椭圆形的外部?
【发布时间】: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 不会提供该功能,所以我已经为我的曲线设计了不同的图案化方法,但只是想看看是否有替代方法。

标签: python tkinter


【解决方案1】:

嗯,有几种不同的方法可以解决这个问题。对于弧线,您需要做的就是以您选择的颜色创建弧线的其余部分。例如,如果弧度是 134 度,我们可以创建一个 226 度的弧,加起来就是一个圆/椭圆的完整 360 度。

extent = 134 # How far the arc goes
canvas.create_arc(100, 100, 200, 200, extent = extent) # Create first arc
canvas.create_arc(100, 100, 200, 200, extent = (360 - extent)) 
# Create second arc with same circle

对于椭圆的边框,您有几个选择。首先,您可以将画布背景设置为您想要的颜色,如下所示:

canvas.create_oval(100, 100, 200, 200, width = 5000, outline = 'red') 
#The width of the border is 5000

这使得边框如此之大以至于覆盖了整个屏幕。如果您想制作其他对象,请在制作初始椭圆后制作它们。

您也可以使用 bg 操作将画布的背景设置为您想要的颜色:

canvas = Canvas(master, width = 750, height = 500, bg = 'red') 

【讨论】:

  • 感谢您的回答,但很遗憾您误解了我的问题。我不是要为圆弧/椭圆绘制边框,我的意思是在边界框内绘制椭圆/圆弧的倒数区域。我在问题中的 MCVE 实际上产生了类似的效果,但我只是想看看是否有更简单的方法。
猜你喜欢
  • 2019-12-06
  • 1970-01-01
  • 2017-03-13
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多