如何在Tkinter Canvas中实现可填充、多色边框的圆角矩形
Tkinter Canvas 实现带多色边框、自定义圆角与填充的圆角矩形
核心解决方案
通过先绘制填充的圆角多边形底色,再叠加分色边框线条和分段圆角圆弧的方式,同时满足多色边框、自定义圆角半径和内部填充的需求。
实现代码
import tkinter as tk import math def draw_rounded_rect(canvas, x1, y1, x2, y2, border_colors=("black", "black", "black", "black"), fill_color="", corner_radii=(10,10,10,10)): # 提取四个角的圆角半径,限制最大值避免异常 r_tl, r_tr, r_br, r_bl = corner_radii max_radius = min((x2-x1)//2, (y2-y1)//2) r_tl, r_tr, r_br, r_bl = [min(r, max_radius) for r in (r_tl, r_tr, r_br, r_bl)] # ---------------------- 绘制填充区域 ---------------------- points = [] # 左上圆角采样(90°-180°) for angle in range(90, 181, 5): rad = math.radians(angle) points.append((x1 + r_tl*math.cos(rad), y1 + r_tl*math.sin(rad))) # 左边缘直线 points.extend([(x1, y1+r_tl), (x1, y2-r_bl)]) # 左下圆角采样(180°-270°) for angle in range(180, 271, 5): rad = math.radians(angle) points.append((x1 + r_bl*math.cos(rad), y2 + r_bl*math.sin(rad))) # 下边缘直线 points.extend([(x1+r_bl, y2), (x2-r_br, y2)]) # 右下圆角采样(270°-360°) for angle in range(270, 361, 5): rad = math.radians(angle) points.append((x2 + r_br*math.cos(rad), y2 + r_br*math.sin(rad))) # 右边缘直线 points.extend([(x2, y2-r_br), (x2, y1+r_tr)]) # 右上圆角采样(0°-90°) for angle in range(0, 91, 5): rad = math.radians(angle) points.append((x2 + r_tr*math.cos(rad), y1 + r_tr*math.sin(rad))) # 上边缘直线 points.extend([(x2-r_tr, y1), (x1+r_tl, y1)]) # 扁平化点列表并绘制填充多边形 flat_points = [coord for p in points for coord in p] canvas.create_polygon(flat_points, fill=fill_color, outline="") # ---------------------- 绘制分色边框线条 ---------------------- # 上边框 canvas.create_line(x1+r_tl, y1, x2-r_tr, y1, fill=border_colors[0], width=2) # 右边框 canvas.create_line(x2, y1+r_tr, x2, y2-r_br, fill=border_colors[1], width=2) # 下边框 canvas.create_line(x2-r_br, y2, x1+r_bl, y2, fill=border_colors[2], width=2) # 左边框 canvas.create_line(x1, y2-r_bl, x1, y1+r_tl, fill=border_colors[3], width=2) # ---------------------- 绘制分段圆角圆弧 ---------------------- # 左上圆角:上边框色(90°-135°)+ 左边框色(135°-180°) canvas.create_arc(x1, y1, x1+2*r_tl, y1+2*r_tl, start=90, extent=45, style=tk.ARC, outline=border_colors[0], width=2) canvas.create_arc(x1, y1, x1+2*r_tl, y1+2*r_tl, start=135, extent=45, style=tk.ARC, outline=border_colors[3], width=2) # 右上圆角:上边框色(0°-45°)+ 右边框色(45°-90°) canvas.create_arc(x2-2*r_tr, y1, x2, y1+2*r_tr, start=0, extent=45, style=tk.ARC, outline=border_colors[0], width=2) canvas.create_arc(x2-2*r_tr, y1, x2, y1+2*r_tr, start=45, extent=45, style=tk.ARC, outline=border_colors[1], width=2) # 右下圆角:右边框色(270°-315°)+ 下边框色(315°-360°) canvas.create_arc(x2-2*r_br, y2-2*r_br, x2, y2, start=270, extent=45, style=tk.ARC, outline=border_colors[1], width=2) canvas.create_arc(x2-2*r_br, y2-2*r_br, x2, y2, start=315, extent=45, style=tk.ARC, outline=border_colors[2], width=2) # 左下圆角:下边框色(180°-225°)+ 左边框色(225°-270°) canvas.create_arc(x1, y2-2*r_bl, x1+2*r_bl, y2, start=180, extent=45, style=tk.ARC, outline=border_colors[2], width=2) canvas.create_arc(x1, y2-2*r_bl, x1+2*r_bl, y2, start=225, extent=45, style=tk.ARC, outline=border_colors[3], width=2) # 测试示例 if __name__ == "__main__": root = tk.Tk() root.title("Custom Rounded Rectangle") canvas = tk.Canvas(root, width=400, height=300, bg="white") canvas.pack(padx=10, pady=10) # 自定义参数绘制:四色边框、浅灰填充、不同圆角半径 draw_rounded_rect( canvas, x1=50, y1=50, x2=350, y2=250, border_colors=("#ff4444", "#44dd44", "#4444ff", "#ffdd44"), fill_color="#eeeeee", corner_radii=(20, 30, 15, 25) ) root.mainloop()
关键细节说明
- 填充区域实现:通过对每个圆角按角度采样生成密集点,组成闭合多边形,确保填充后的圆角平滑自然。采样步长设为5°,可根据需求调整(步长越小,圆角越细腻)。
- 分色边框处理:分别绘制上下左右四条直线边框,对应独立颜色;每个圆角拆分为两段圆弧,分别使用相邻边框的颜色,保证边框颜色的连贯性。
- 边界安全限制:自动限制圆角半径不超过对应边长度的一半,避免出现图形异常。
内容的提问来源于stack exchange,提问作者DazzRick
相关产品推荐
相关产品推荐

