5 Best Ways to Draw a Circle in Tkinter with Python

πŸ’‘ Problem Formulation: When working with Tkinter in Python, a common graphical task is to draw shapes on a canvas. Suppose you need to draw a circle based on user-defined parameters like coordinates and radius. Your input might include the center point (x, y) and a radius value, and the desired output would be a visual representation of a circle on a GUI application.

Method 1: Using Canvas.create_oval

This method involves using the create_oval method on a Tkinter canvas. To create a circle, you specify a bounding box for the oval that is essentially a square, with equal width and height corresponding to the diameter of the circle. The arguments are the top-left and bottom-right corners of this square.

Here’s an example:

import tkinter as tk

root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()
canvas.create_oval(50, 50, 150, 150, outline="black", fill="blue")
root.mainloop()

Output: A window with a blue circle inside.

This snippet creates a simple GUI window with a canvas widget. The create_oval method is used to draw an oval inside the canvas, where the bounding box coordinates (50, 50) and (150, 150) define a square. By making the width and height equal, an oval becomes a circle. The circle is outlined in black and filled with blue color.

Method 2: Using a Function

Creating a function to draw a circle abstracts your code and makes it reusable. You pass the center coordinates and radius, and the function calculates the bounding box to draw the circle using the create_oval method as previously described.

Here’s an example:

import tkinter as tk

def draw_circle(canvas, x, y, radius, **kwargs):
    canvas.create_oval(x - radius, y - radius, x + radius, y + radius, **kwargs)

root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()
draw_circle(canvas, 100, 100, 50, outline="red", fill="yellow")
root.mainloop()

Output: A window with a yellow circle that has a red outline.

The code defines a function draw_circle(), which takes a canvas object, center coordinates, a radius, and additional keyword arguments for styling. When called, it creates a circle centered at (100, 100) with a radius of 50, a red outline, and yellow fill, displayed on the GUI.

Method 3: Object-Oriented Approach

In this approach, you encapsulate the drawing logic within a class. The class manages its own canvas and provides a method like draw_circle() to add a circle to it. This is useful for larger applications, where modular components help maintain clean code.

Here’s an example:

import tkinter as tk

class CircleDrawer:
    def __init__(self, root):
        self.canvas = tk.Canvas(root, width=200, height=200)
        self.canvas.pack()

    def draw_circle(self, x, y, radius, **kwargs):
        self.canvas.create_oval(x - radius, y - radius, x + radius, y + radius, **kwargs)

root = tk.Tk()
drawer = CircleDrawer(root)
drawer.draw_circle(100, 100, 50, outline="green", fill="pink")
root.mainloop()

Output: A window with a pink circle with a green outline.

The class CircleDrawer contains a constructor that initializes a canvas, and a method draw_circle() that draws the circle. An instance of CircleDrawer is created and is used to draw a pink circle with a green outline on the GUI.

Method 4: Binding to Events

This method covers drawing a circle in response to an event, such as a mouse click. You bind an event handler that triggers draw_circle() whenever the user clicks on the canvas, drawing a circle at the click location.

Here’s an example:

import tkinter as tk

def draw_circle(event):
    radius = 20
    canvas.create_oval(event.x - radius, event.y - radius, event.x + radius, event.y + radius, outline="black")

root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()
canvas.bind("<Button-1>", draw_circle)  # Left mouse click
root.mainloop()

Output: A window where each left-click of the mouse creates a small black-outlined circle.

The code demonstrates handling a mouse click event to draw a circle on the canvas. The event handler draw_circle uses the click’s coordinates (event.x and event.y) to define the center of the circle and draw it with a fixed radius of 20.

Bonus One-Liner Method 5: Lambda Function

For those who love one-liners, here’s a minimalist approach using a lambda function inside the event binding, to draw a circle at a clicked point.

Here’s an example:

import tkinter as tk

root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()
canvas.bind("<Button-1>", lambda e: canvas.create_oval(e.x - 10, e.y - 10, e.x + 10, e.y + 10, outline="purple"))
root.mainloop()

Output: A window where each left-click of the mouse creates a small purple-outlined circle.

This approach skips the definition of a separate event handler function, and instead uses a lambda function to draw a small circle with a radius of 10 wherever the user clicks on the canvas.

Summary/Discussion

  • Method 1: Using Canvas.create_oval. Simple and direct. May become verbose for multiple circles.
  • Method 2: Using a Function. Encapsulates drawing logic. Adds reusability and readability but requires a separate function definition.
  • Method 3: Object-Oriented Approach. Provides excellent organization and modularity. Slightly more complex setup for smaller projects.
  • Method 4: Binding to Events. Interactive and dynamic. Suitable for applications requiring user interaction but not for static drawings.
  • Method 5: Bonus One-Liner. Quick and concise. Lacks the clarity and customization that separate functions offer.