Tkinter Cursors

Summary: in this tutorial, you’ll learn how to set the cursors for widgets in the Tkinter application.

Changing the cursor for the root window

The root window has only two cursors:

  • Normal cursor
  • Busy cursor

The Normal cursor has the value of "" while the busy cursor has the value of "watch".

The following program shows how to change the cursor of the root window from normal to busy:

import tkinter as tk

root = tk.Tk()

root.geometry("300x300")
root.config(cursor="watch")

root.mainloop()Code language: Python (python)

How it works.

  • First, set the width and height of the root windows to 300×300.
  • Second, change the cursor to busy using the cursor parameter.

If you want to change the cursor for an area of the root window, you can use the <Motion> event and track the x (and/or y) coordinate of the cursor. For example:

import tkinter as tk

root = tk.Tk()
root.geometry("300x300")


def change_cursor(event):
    if event.x in range(100, 300):
        root.config(cursor="watch")
    else:
        root.config(cursor="")


root.bind("<Motion>", change_cursor)
root.mainloop()Code language: Python (python)

In this example, the cursor changes to busy when the mouse is starting on the x-coordinates from 100 to 300.

Changing cursor for widgets

All ttk widgets have the cursor parameter that allows you to change the cursor when the mouse hovers them.

For example, if you want to change the cursor of a button, you can set the cursor name using the cursor parameter as follows:

from tkinter import ttk

#...
button = ttk.Button(cursor=cursor_name)Code language: Python (python)

The cursor name can be one of the following values:

  • arrow
  • based_arrow_down
  • based_arrow_up
  • boat
  • bogosity
  • bottom_left_corner
  • bottom_right_corner
  • bottom_side
  • bottom_tee
  • box_spiral
  • center_ptr
  • circle
  • clock
  • coffee_mug
  • cross
  • cross_reverse
  • crosshair
  • diamond_cross
  • dot
  • dotbox
  • double_arrow
  • draft_large
  • draft_small
  • draped_box
  • exchange
  • fleur
  • gobbler
  • gumby
  • hand1
  • hand2
  • heart
  • icon
  • iron_cross
  • left_ptr
  • left_side
  • left_tee
  • leftbutton
  • ll_angle
  • lr_angle
  • man
  • middlebutton
  • mouse
  • pencil
  • pirate
  • plus
  • question_arrow
  • right_ptr
  • right_side
  • right_tee
  • rightbutton
  • rtl_logo
  • sailboat
  • sb_down_arrow
  • sb_h_double_arrow
  • sb_left_arrow
  • sb_right_arrow
  • sb_up_arrow
  • sb_v_double_arrow
  • shuttle
  • sizing
  • spider
  • spraycan
  • star
  • target
  • tcross
  • top_left_arrow
  • top_left_corner
  • top_right_corner
  • top_side
  • top_tee
  • trek
  • ul_angle
  • umbrella
  • ur_angle
  • watch
  • xterm
  • X_cursor

To change the cursor of the root window, you can:

  • First, create a new Frame.
  • Second, place it on the root window and expand it 100%.
  • Third, set the cursor on the frame.

The following program allows you to change the cursor by selecting it in a combobox:

from tkinter import ttk
import tkinter as tk

root = tk.Tk()

# config the root window
root.geometry('600x400')
root.resizable(False, False)
root.title('Tkinter Cursors')

frame = ttk.Frame(root)


# label
label = ttk.Label(frame, text="Cursor:")
label.pack(fill=tk.X, padx=5, pady=5)

# cursor list
selected_cursor = tk.StringVar()
cursor_list = ttk.Combobox(frame, textvariable=selected_cursor, cursor='arrow')
cursors = ['arrow', 'man', 'based_arrow_down', 'middlebutton', 'based_arrow_up', 'mouse', 'boat', 'pencil', 'bogosity', 'pirate', 'bottom_left_corner', 'plus', 'bottom_right_corner', 'question_arrow', 'bottom_side', 'right_ptr', 'bottom_tee', 'right_side', 'box_spiral', 'right_tee', 'center_ptr', 'rightbutton', 'circle', 'rtl_logo', 'clock', 'sailboat', 'coffee_mug', 'sb_down_arrow', 'cross', 'sb_h_double_arrow', 'cross_reverse', 'sb_left_arrow', 'crosshair', 'sb_right_arrow', 'diamond_cross',
           'sb_up_arrow', 'dot', 'sb_v_double_arrow', 'dotbox', 'shuttle', 'double_arrow', 'sizing', 'draft_large', 'spider', 'draft_small', 'spraycan', 'draped_box', 'star', 'exchange', 'target', 'fleur', 'tcross', 'gobbler', 'top_left_arrow', 'gumby', 'top_left_corner', 'hand1', 'top_right_corner', 'hand2', 'top_side', 'heart', 'top_tee', 'icon', 'trek', 'iron_cross', 'ul_angle', 'left_ptr', 'umbrella', 'left_side', 'ur_angle', 'left_tee', 'watch', 'leftbutton', 'xterm', 'll_angle', 'X_cursor', 'lr_angle']
cursor_list['values'] = cursors
cursor_list['state'] = 'readonly'


cursor_list.pack(fill=tk.X, padx=5, pady=5)

frame.pack(expand=True, fill=tk.BOTH)


# bind the selected value changes
def cursor_changed(event):
    frame.config(cursor=selected_cursor.get())


cursor_list.bind('<<ComboboxSelected>>', cursor_changed)

root.mainloop()Code language: Python (python)

Summary

  • The root window has only two cursors: normal ("") and busy ("watch").
  • The widget has many cursors with fixed names.
  • Use the cursor parameter to change the cursor for the root window or a widget.
Did you find this tutorial helpful ?