¿Cómo dibujar un arco en un canvas tkinter?

Estoy estudiando teoría de autómatas y me pidieron que progtwigra la gráfica (árbol) de un autómata que se parece más o menos a:

esta

Hasta ahora tengo esto (estoy usando tkinter y canvas para dibujar):

 from tkinter import Tk, Canvas, mainloop def circle(canvas, x, y, r, width): id = canvas.create_oval (xr, yr, 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() 

Que muestra esto:

Captura de pantalla de la imagen creada por el código actual.

No necesito las flechas, porque usaré puntos en su lugar. El problema es que necesito dibujar una línea desde el círculo q3 al círculo q0, y desde el círculo q0 al círculo q0, también (un “bucle”). canvas.create_arc() método canvas.create_arc() , pero no puedo controlarlo. ¿Hay alguna alternativa? ¿Alguna idea sobre cómo dibujar el “bucle”?

Aquí hay algunas funciones de utilidad que proporcionan una forma alternativa de dibujar arcos en un tkinter.Canvas . En lugar de la especificación habitual de dos puntos, (x0, y0) y (x1, y1) para definir un rectángulo circundante, las funciones de arco aceptan un ángulo de inicio y parada en el rango abierto de [0..360) grados.

También ilustra cómo se dibujan puntas de flecha en los extremos de las líneas rectas (pero no en los arcos), ya que también preguntaste sobre eso.

 from tkinter import Canvas, mainloop, Tk def circle(canvas, x, y, r, width): return canvas.create_oval(x+r, y+r, xr, yr, width=width) def circular_arc(canvas, x, y, r, t0, t1, width): return canvas.create_arc(xr, yr, 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() 

Esto es lo que dibuja:

captura de pantalla que muestra la salida

No dibuja una "hebilla" como usted quiere en parte porque dibujar "una línea del círculo q3 al círculo q0, y del círculo q0 al círculo q0" no es como la ilustración al principio de su pregunta, que es una dibujada entre dos círculos (si entiendo correctamente lo que querías decir con el término).

Sin embargo, proporciona otra forma de dibujar arcos en un canvas .