Как сгладить края вокруг овала в tkinter?

#python #tkinter #tkinter-canvas #antialiasing

#python #tkinter #tkinter-холст #сглаживание

Вопрос:

Я новичок в tkinter и недавно узнал о виджете canvas. После ознакомления с основами я подумал, что могу использовать canvas для создания пользовательского индикатора выполнения, и это сработало! Это действительно потрясающе, однако после удаления контура фигур я увидел, что края фигур были довольно грубыми, особенно овалы. Я немного поискал и только что обнаружил, что вы можете использовать аргумент ключевого слова smooth только с полигонами. Итак, мой вопрос в том, есть ли способ сгладить края фигур, особенно овалов, в tkinter, что-то вроде сглаживания? Мой код:

 from tkinter import *

root = Tk()
root.geometry("500x500")
percent = 0
progress_done, new_oval = None, None
canvas = Canvas(root, width=400, height=400, bg="white")
canvas.pack(pady=10)
prg_bar = canvas.create_rectangle(50, 140, 350, 160, fill="grey", outline="")
oval_one = canvas.create_oval(40, 140, 60, 160, fill="grey", outline="", )
oval_two = canvas.create_oval(340, 140, 360, 160, fill="grey", outline="")


def add_up():
    global percent, progress_done, new_oval
    if percent < 100:
        percent  = 20
        if progress_done is None and new_oval is None:
            canvas.create_oval(40, 140, 60, 160, fill="light blue", outline='')
            canvas.delete(oval_one)
            progress_done = canvas.create_rectangle(50, 140, (percent * 3)   50, 160, fill="light blue", outline="")
            new_oval = canvas.create_oval((percent * 3)   40, 140, (percent * 3)   60, 160, fill="light blue",
                                          outline="")
        else:
            canvas.delete(progress_done)
            canvas.delete(new_oval)
            progress_done = canvas.create_rectangle(50, 140, (percent * 3)   50, 160, fill="light blue", outline="")
            new_oval = canvas.create_oval((percent * 3)   40, 140, (percent * 3)   60, 160, fill="light blue",
                                          outline="")
            if percent == 100:
                canvas.delete(oval_two)


btn = Button(root, text="Add to prg", command=add_up)
btn.pack()
root.mainloop()
  

Комментарии:

1. Короткий ответ: нет.

2. Нарисуйте свой овал с помощью многоугольника.

3. @Michael Guidry, я пробовал это. Все формы холста имеют низкое разрешение.

Ответ №1:

Нарисуйте свой овал с create_polygon помощью . Ниже приведен пример рисования овала и круглого прямоугольника. В обоих примерах установлена splinesteps опция для повышения плавности сгенерированных кривых. splinesteps Параметр по умолчанию равен 12.

 import tkinter as tk
root = tk.Tk()

c = tk.Canvas(root)
c.pack(fill='both', expand=True, anchor='nw')

def poly_oval(x, y, width, height, resolution=32):
    points = [x, y,
              x width, y,
              x width, y height,
              x, y height,
              x, y]
              
    return c.create_polygon(points, fill='#f00', smooth=True, splinesteps=resolution)   
    
def poly_roundrect(x, y, width, height, radius, resolution=32):
    #this is not a true round rect
    #it's a round rect with the potential to have invisible garbage that cheats
    #it cheats convincingly if you don't use an outline when it is cheating
    radius = min(min(width, height), radius*2)
    points = [x, y,
              x radius, y,
              x (width-radius), y,
              x width, y,
              x width, y radius,
              x width, y (height-radius),
              x width, y height,
              x (width-radius), y height,
              x radius, y height,
              x, y height,
              x, y (height-radius),
              x, y radius,
              x, y]
              
    rect = c.create_polygon(points, fill='#1f1', smooth=True, splinesteps=resolution) 
    
    #display vertices
    #for i in range(0, len(points), 2):
    #    poly_oval(points[i]-2, points[i 1]-2, 4, 4)
              
    return rect
    
rect = poly_roundrect(10, 10, 300, 50, 10, 64)

root.mainloop()