是否可以在tkinter画布中填充弧形/椭圆形的外部?

时间:2019-01-09 16:53:22

标签: python tkinter

我正在尝试在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来填充弧形/椭圆形的“负空间”或“外部”区域?或者,是否可以创建带有填充的反弧/椭圆形?还是功能受到限制?

1 个答案:

答案 0 :(得分:0)

嗯,有几种不同的方法可以解决这个问题。对于弧,您所需要做的就是以您选择的颜色创建弧的其余部分。例如,如果圆弧度为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')