Advanced Usage

This document covers some of AutoHotkey.py more advanced features.

Threading

In Python, the threading module can be used to improve the responsiveness of applications that accept user input while other tasks run in the background. A related use case is running I/O in parallel with computations in another thread. These are actual OS threads, as opposed to AHK pseudo-threads.

Calling AHK functions from Python is implemented in AutoHotkey.py by registering a callback in AHK with RegisterCallback. These callbacks are not thread-safe. That is, while the main thread is busy executing an AHK function, trying to call another AHK function from another thread leads to unpredictable results like program crash.

Thus, the global AutoHotkey lock (GAL) was introduced. It ensures that only one OS thread interacts with AHK at a time.

In order for background threads to work, the main thread must also be crunching Python code, for example, actively waiting for the background threads to finish. However, calling threading.Thread.join() in the main thread will block the handling of the AHK message queue. That is, AHK won’t be able to handle the hotkeys and other callbacks. Instead, let AHK handle its message queue by calling ahkpy.sleep() repeatedly while checking that the background thread is alive:

import threading
th = threading.Thread(target=some_worker)
th.start()
while th.is_alive():
    ahkpy.sleep(0.01)

asyncio

AutoHotkey.py works well with asyncio. When starting a long-running loop, schedule the ahkpy.sleep() call repeatedly, so it could give time to AHK to process its message queue:

import asyncio

import ahkpy

async def main():
    # Schedule a function that will check AHK message queue repeatedly.
    loop = asyncio.get_running_loop()
    loop.call_soon(sleeper, loop)

    print('Hello ...')
    await asyncio.sleep(1)
    print('... World!')

def sleeper(loop):
    ahkpy.sleep(0.01)
    loop.call_soon(sleeper, loop)

asyncio.run(main())

Check out the example of a TCP server that receives keys strings and passes them to ahkpy.send().

GUI

Out of the box, Python provides the tkinter package, an interface to the Tk GUI toolkit. AutoHotkey.py supports tkinter, so it can be used to create user interfaces.

The following table contains a list of AutoHotkey GUI controls and the corresponding tkinter counterparts:

AHK Control

tkinter Widget

Text

tkinter.ttk.Label

Edit

tkinter.ttk.Entry

UpDown

tkinter.ttk.Spinbox

Picture

tkinter.BitmapImage, tkinter.PhotoImage

Button

tkinter.ttk.Button

Checkbox

tkinter.ttk.Checkbutton

Radio

tkinter.ttk.Radiobutton

DropDownList

tkinter.ttk.Combobox

ComboBox

ListBox

tkinter.Listbox

ListView

TreeView

tkinter.ttk.Treeview

Link

Hotkey

DateTime

MonthCal

Slider

tkinter.ttk.Scale

Progress

tkinter.ttk.Progressbar

GroupBox

tkinter.ttk.Labelframe

Tab3

tkinter.ttk.Notebook

StatusBar