tkinter Canvas大线宽下create_oval/create_arc绘制圆和弧形异常
问题环境
- 操作系统:Win10
- Python版本:3.10.1
- tkinter版本:8.6.12
增大图形边框宽度时,绘制出的圆形效果异常,黄色圆环外观显示不符合预期,复现代码如下:
from tkinter import * root = Tk() frame1 = Frame(root) frame1.pack(side='top') for i in range(-1, 2): canvas = Canvas(frame1, width=300, height=300, bg='green') canvas.pack(side='left') canvas.create_oval(50, 50, 250+i, 250+i, width=81, outline='yellow') canvas.create_rectangle(50, 50, 250+i, 250+i) canvas.create_oval(50, 50, 250+i, 250+i, width=1) frame2 = Frame(root) frame2.pack(side='top') for i in range(3): canvas = Canvas(frame2, width=300, height=300, bg='green') canvas.pack(side='left') canvas.create_arc(50, 50, 250, 250, start=0, extent=(i+1)*90, style='arc', width=81, outline='yellow',) root.mainloop()
异常现象
运行代码后可观察到两类问题:
- 所有绘制的圆形在0度位置附近均出现平直区域
- 绘制范围为090度的第一段弧形出现圆头端点,该异常偶尔也会在绘制0180度、0~270度弧形时出现,具体触发条件暂不明确
初步怀疑问题与线帽(cap)、线段连接(join)样式有关,但暂不清楚tkinter中对应的配置选项。
异常效果参考截图:
问题原因
异常确实由线帽、线段连接的默认配置导致:
- Tkinter的Canvas绘制非闭合圆弧时,默认线帽样式为圆头(
round),因此粗线绘制的圆弧端点会出现圆形突出 - 完整椭圆的轮廓并非一次绘制生成,而是由4段90度的圆弧拼接而成,大线宽场景下默认的拼接连接样式、线帽样式会在拼接点(0度位置)渲染出平直缺口。
修复方案
在create_oval、create_arc调用时显式指定样式参数即可解决问题:
- 对闭合的椭圆/圆环,同时指定
capstyle='butt'(平头线帽,无额外延伸)、joinstyle='miter'(斜接连接,拼接处保持尖锐平滑) - 对非闭合圆弧,仅需指定
capstyle='butt'即可消除圆头端点
修复后的可运行代码:
from tkinter import * root = Tk() frame1 = Frame(root) frame1.pack(side='top') for i in range(-1, 2): canvas = Canvas(frame1, width=300, height=300, bg='green') canvas.pack(side='left') canvas.create_oval(50, 50, 250+i, 250+i, width=81, outline='yellow', capstyle='butt', joinstyle='miter') canvas.create_rectangle(50, 50, 250+i, 250+i) canvas.create_oval(50, 50, 250+i, 250+i, width=1) frame2 = Frame(root) frame2.pack(side='top') for i in range(3): canvas = Canvas(frame2, width=300, height=300, bg='green') canvas.pack(side='left') canvas.create_arc(50, 50, 250, 250, start=0, extent=(i+1)*90, style='arc', width=81, outline='yellow', capstyle='butt') root.mainloop()
可选样式说明:
- 线帽
capstyle可选值:butt(平头,端点与路径终点齐平)、projecting(方头,端点向外延伸半个线宽长度)、round(圆头,端点为半圆形)- 线段连接
joinstyle可选值:miter(斜接锐角)、round(圆角)、bevel(平切角),可根据实际显示需求选择。
内容的提问来源于stack exchange,提问作者Jason Yang
相关产品推荐
相关产品推荐

