如何在tkinter画布上绘制圆弧?

我正在研究自动机理论,我被要求编写一个看起来或多或少的自动机的图形(树):

到目前为止,我得到了这个(我使用tkinter和canvas绘制):

from tkinter import Tk, Canvas, mainloop

def circle(canvas, x, y, r, width):
   id = canvas.create_oval (x-r, y-r, x+r, y+r, width = width)
   return id

def line (canvas, x1, y1, x2, y2, width):
    canvas.create_line (x1, y1, x2, y2, width = width)

def text (canvas, x, y, text):
    canvas.create_text (x, y, text = text, font = ("bold", 20))

w = Canvas(Tk (), width=1000, height=600, bg = "white")

circle (w , 150, 300, 70, 3)
circle (w , 150, 300, 50, 3)
circle (w , 370, 300, 70, 3)
circle (w , 640, 300, 70, 3)
circle (w , 910, 300, 70, 3)

line (w, 10, 300, 80, 300, 3)
circle (w, 73, 300, 5, 6)
line (w, 220, 300, 300, 300, 3)
circle (w, 293, 300, 5, 6)
line (w, 440, 300, 570, 300, 3)
circle (w, 567, 300, 5, 6)
line (w, 710, 300, 840, 300, 3)
circle (w, 837, 300, 5, 6)

text (w, 150, 300, "q0")
text (w, 370, 300, "q1")
text (w, 640, 300, "q2")
text (w, 910, 300, "q3")

w.pack()
mainloop()

哪个显示这个:

《如何在tkinter画布上绘制圆弧?》

我不需要箭头,因为我会用点代替.问题是我需要从圆圈q3到圆圈q0画一条线,从圆圈q0到圆圈q0画一条线(“bucle”).我尝试了canvas.create_arc()方法,但我无法得到它的句柄.还有其他选择吗?关于如何绘制“bucle”的任何想法?

最佳答案 这里有一些实用程序函数,它们提供了另一种在tkinter.Canvas上绘制弧的方法.而不是通常规定的两点,(x0,y0)和(x1,y1)来定义一个封闭的矩形,弧函数接受在[0..360]度的开放范围内的起始和停止角度.

它还说明了如何在直线(但不是弧线)的末端绘制箭头,因为你也问过这个问题.

from tkinter import Canvas, mainloop, Tk

def circle(canvas, x, y, r, width):
    return canvas.create_oval(x+r, y+r, x-r, y-r, width=width)

def circular_arc(canvas, x, y, r, t0, t1, width):
    return canvas.create_arc(x-r, y-r, x+r, y+r, start=t0, extent=t1-t0,
                             style='arc', width=width)

def ellipse(canvas, x, y, r1, r2, width):
    return canvas.create_oval(x+r1, y+r2, x-r1, y-r2, width=width)

def elliptical_arc(canvas, x, y, r1, r2, t0, t1, width):
    return canvas.create_arc(x-r1, y-r2, x+r1, y+r2, start=t0, extent=t1-t0,
                             style='arc', width=width)

def line(canvas, x1, y1, x2, y2, width, start_arrow=0, end_arrow=0):
    arrow_opts = start_arrow << 1 | end_arrow
    arrows = {0b10: 'first', 0b01: 'last', 0b11: 'both'}.get(arrow_opts, None)
    return canvas.create_line(x1, y1, x2, y2, width=width, arrow=arrows)

def text(canvas, x, y, text):
    return canvas.create_text(x, y, text=text, font=('bold', 20))


w = Canvas(Tk(), width=1000, height=600, bg='white')

circle(w, 150, 300, 70, 3)  # q0 outer edge
circle(w, 150, 300, 50, 3)  # q0 inner edge
circle(w, 370, 300, 70, 3)  # q1
circle(w, 640, 300, 70, 3)  # q2
circle(w, 910, 300, 70, 3)  # q3

# Draw arc from circle q3 to q0.
midx, midy = (150+910) / 2, 300
r1, r2 = 910-midx, 70+70
elliptical_arc(w, midx, midy, r1, r2, 30, 180-30, 3)

line(w,  10, 300,  80, 300, 3, end_arrow=1)
line(w, 220, 300, 300, 300, 3, end_arrow=1)
line(w, 440, 300, 570, 300, 3, end_arrow=1)
line(w, 710, 300, 840, 300, 3, end_arrow=1)

text(w, 150, 300, 'q0')
text(w, 370, 300, 'q1')
text(w, 640, 300, 'q2')
text(w, 910, 300, 'q3')

w.pack()
mainloop()

这是它的绘制:

《如何在tkinter画布上绘制圆弧?》

它并不像你想要的那样画一个“扣”,因为画“从q3到圆q0的一条线,从q0到圆q0的线”并不像你问题开头的插图那样两个圆圈(如果我理解你的意思是什么).

但是,它确实为您在画布上绘制弧提供了另一种方法.

点赞