How to draw an arc on a tkinter canvas? How to draw an arc on a tkinter canvas? tkinter tkinter

How to draw an arc on a tkinter canvas?


Here's some utility functions that provide an alternative way draw arcs on a tkinter.Canvas. Instead of the usual specification of two-points, (x0, y0) and (x1, y1) to define an enclosing rectangle, the arc functions accept a starting and stopping angle in the open range of [0..360) degrees.

It also illustrates how to have arrowheads drawn at the ends of straight lines (but not arcs) since you asked about that, too.

from tkinter import Canvas, mainloop, Tkdef 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 edgecircle(w, 150, 300, 50, 3)  # q0 inner edgecircle(w, 370, 300, 70, 3)  # q1circle(w, 640, 300, 70, 3)  # q2circle(w, 910, 300, 70, 3)  # q3# Draw arc from circle q3 to q0.midx, midy = (150+910) / 2, 300r1, r2 = 910-midx, 70+70elliptical_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()

This is what it draws:

screenshot showing output

It doesn't draw a "buckle" like you want partly because drawing "a line from circle q3 to circle q0, and from circle q0 to circle q0" isn't like the illustration at the beginning of your question which is one drawn between two circles (if I understand correctly what you meant by the term).

However, it does provide another way for you to draw arcs on a canvas.


You can use tkinter canvas to draw your 'bucket' using Canvas line of arranged points (should be encircled). Here my example of drawing a returning angle with a 'bucket' shape. I use python 3.9

import tkinter as tkdef P(x,y):    """    For convenience only.    Transform point in cartesian (x,y) to Canvas (X,Y)    As both system has difference y direction:    Cartesian y-axis from bottom-left - up     Canvas Y-axis from top-left - down     """    X = M + (x/xmax) * (W-2*M)    Y = M + (1-(y/ymax)) * (H-2*M)    return (X,Y)def draw(window):    """"    Draw the lines    """    c = tk.Canvas(window, width=W, height=H)    c.grid()        # tuple of points to shape a 'bucket'    points = P(60,0), P(90,50), P(50,100), P(10,50), P(40,0)        fracture = c.create_line(points, arrow='last', fill='yellow')    smooth = c.create_line(points, arrow='last', smooth=1)   """xmin is minimum value along cartesian x-axisxmax is maximum value along cartesian x-axisymin is minimum value along cartesian y-axisymax is maximum value along cartesian y-axisW is canvas width, in pixelH is canvas height, in pixelM is minimum margin inside canvas to ensure objects like arrow fully shown."""M = 4  W = 310H = 210xmin = 0xmax = 100ymin = 0ymax = 100    window = tk.Tk()draw(window)window.mainloop()

If you run the above code you will seea yellow fracture lines which is the original point-line anda black smooth line of the same line with option smooth set to 1 and option arrow set to 'last'.

Here the result

enter image description here