Полностью напечатанная обертка Python вокруг Autohotkey.
pip install ahk
Требуется Python 3.8+
Поддерживает Autohotkey V1 и V2. См. Также: не питотонные зависимости
from ahk import AHK
ahk = AHK ()
ahk . mouse_move ( x = 100 , y = 100 , blocking = True ) # Blocks until mouse finishes moving (the default)
ahk . mouse_move ( x = 150 , y = 150 , speed = 10 , blocking = True ) # Moves the mouse to x, y taking 'speed' seconds to move
print ( ahk . mouse_position ) # (150, 150)Неэксуализирующие примеры некоторых функций, доступных с этим пакетом. См. Полную документацию для полных ссылок API и дополнительных функций.
Hotkeys можно настроить для запуска функций Python в качестве обратных вызовов.
Например:
from ahk import AHK
def my_callback ():
print ( 'Hello callback!' )
ahk = AHK ()
# when WIN + n is pressed, fire `my_callback`
ahk . add_hotkey ( '#n' , callback = my_callback )
ahk . start_hotkeys () # start the hotkey process thread
ahk . block_forever () # not strictly needed in all scripts -- stops the script from exiting; sleep forever Теперь, когда вы нажимаете + n , функция обратного вызова my_callback будет вызвана в фоновом потоке.
Вы также можете добавить обработчик исключений для вашего обратного вызова:
from ahk import AHK
ahk = AHK ()
def go_boom ():
raise Exception ( 'boom!' )
def my_ex_handler ( hotkey : str , exception : Exception ):
print ( 'exception with callback for hotkey' , hotkey , 'Here was the error:' , exception )
ahk . add_hotkey ( '#n' , callback = go_boom , ex_handler = my_ex_handler )Есть также методы удаления горячих клавиш:
# ...
ahk . remove_hotkey ( '#n' ) # remove a hotkey by its keyname
ahk . clear_hotkeys () # remove all hotkeysОбратите внимание, что:
ahk.start_hotkeys() )ahk.stop_hotkeys() (не остановится активно выполнять обратные вызовы)См. Также соответствующую документацию AHK
Жгутирование также может быть добавлено в потоку процесса Hotkey.
В дополнение к составу скота, поддерживающих нормальные замены AHK строки, вы также можете предоставить обратные вызовы Python (с дополнительными обработчиками исключений) в ответ на запуск скота.
from ahk import AHK
ahk = AHK ()
def my_callback ():
print ( 'hello callback!' )
ahk . add_hotstring ( 'btw' , 'by the way' ) # string replacements
ahk . add_hotstring ( 'btw' , my_callback ) # call python function in response to the hotstringВы также можете удалить жилища:
ahk . remove_hotstring ( 'btw' ) # remove a hotstring by its trigger sequence
ahk . clear_hotstrings () # remove all registered hotstrings from ahk import AHK
ahk = AHK ()
ahk . mouse_position # Returns a tuple of mouse coordinates (x, y) (relative to active window)
ahk . get_mouse_position ( coord_mode = 'Screen' ) # get coordinates relative to the screen
ahk . mouse_move ( 100 , 100 , speed = 10 , relative = True ) # Moves the mouse reletave to the current position
ahk . mouse_position = ( 100 , 100 ) # Moves the mouse instantly to absolute screen position
ahk . click () # Click the primary mouse button
ahk . click ( 200 , 200 ) # Moves the mouse to a particular position and clicks (relative to active window)
ahk . click ( 100 , 200 , coord_mode = 'Screen' ) # click relative to the screen instead of active window
ahk . click ( button = 'R' , click_count = 2 ) # Clicks the right mouse button twice
ahk . right_click () # Clicks the secondary mouse button
ahk . mouse_drag ( 100 , 100 , relative = True ) # Holds down primary button and moves the mouse from ahk import AHK
ahk = AHK ()
ahk . type ( 'hello, world!' ) # Send keys, as if typed (performs string escapes for you)
ahk . send_input ( 'Hello, {U+1F30E}{!}' ) # Like AHK SendInput
# Unlike `type`, control sequences must be escaped manually.
# For example the characters `!^+#=` and braces (`{` `}`) must be escaped manually.
ahk . key_state ( 'Control' ) # Return True or False based on whether Control key is pressed down
ahk . key_state ( 'CapsLock' , mode = 'T' ) # Check toggle state of a key (like for NumLock, CapsLock, etc)
ahk . key_press ( 'a' ) # Press and release a key
ahk . key_down ( 'Control' ) # Press down (but do not release) Control key
ahk . key_up ( 'Control' ) # Release the key
ahk . set_capslock_state ( "On" ) # Turn CapsLock on
if ahk . key_wait ( 'x' , timeout = 3 ): # wait for a key to be pressed; returns a boolean
print ( 'X was pressed within 3 seconds' )
else :
print ( 'X was not pressed within 3 seconds' )Вы также можете делать вещи с Windows.
from ahk import AHK
ahk = AHK ()
win = ahk . active_window # Get the active window
win = ahk . win_get ( title = 'Untitled - Notepad' ) # by title
all_windows = ahk . list_windows () # list of all windows
win = ahk . win_get_from_mouse_position () # the window under the mouse cursor
win = ahk . win_get ( title = 'ahk_pid 20366' ) # get window from pid
# Wait for a window
try :
# wait up to 5 seconds for notepad
win = ahk . win_wait ( title = 'Untitled - Notepad' , timeout = 5 )
# see also: win_wait_active, win_wait_not_active
except TimeoutError :
print ( 'Notepad was not found!' ) from ahk import AHK
ahk = AHK ()
ahk . run_script ( 'Run Notepad' ) # Open notepad
win = ahk . find_window ( title = 'Untitled - Notepad' ) # Find the opened window; returns a `Window` object
# Window object methods
win . send ( 'hello' , control = 'Edit1' ) # Send keys directly to the window (does not need focus!)
# OR ahk.control_send(title='Untitled - Notepad', control='Edit1')
win . move ( x = 200 , y = 300 , width = 500 , height = 800 )
win . activate () # Give the window focus
win . close () # Close the window
win . hide () # Hide the window
win . kill () # Kill the window
win . maximize () # Maximize the window
win . minimize () # Minimize the window
win . restore () # Restore the window
win . show () # Show the window
win . disable () # Make the window non-interactable
win . enable () # Enable it again
win . to_top () # Move the window on top of other windows
win . to_bottom () # Move the window to the bottom of the other windows
win . get_class () # Get the class name of the window
win . get_minmax () # Get the min/max status
win . get_process_name () # Get the process name (e.g., "notepad.exe")
win . process_name # Property; same as `.get_process_name()` above
win . is_always_on_top () # Whether the window has the 'always on top' style applied
win . list_controls () # Get a list of controls (list of `Control` objects)
win . redraw () # Redraw the window
win . set_style ( "-0xC00000" ) # Set a style on the window (in this case, removing the title bar)
win . set_ex_style ( "^0x80" ) # Set an ExStyle on the window (in this case, removes the window from alt-tab list)
win . set_region ( "" ) # See: https://www.autohotkey.com/docs/v2/lib/WinSetRegion.htm
win . set_trans_color ( "White" ) # Makes all pixels of the chosen color invisible inside the specified window.
win . set_transparent ( 155 ) # Makes the specified window semi-transparent (or "Off" to turn off transparency)
win . always_on_top = 'On' # Make the window always on top
# or
win . set_always_on_top ( 'On' )
for window in ahk . list_windows (): # list all (non-hidden) windows -- ``detect_hidden_windows=True`` to include hidden
print ( window . title )
# Some more attributes
print ( window . text ) # window text -- or .get_text()
print ( window . get_position ()) # (x, y, width, height)
print ( window . id ) # the ahk_id of the window
print ( window . pid ) # process ID -- or .get_pid()
print ( window . process_path ) # or .get_process_path()
if win . active : # or win.is_active()
...
if win . exist : # or win.exists()
...
# Controls
edit_control = win . list_controls ()[ 0 ] # get the first control for the window, in this case "Edit1" for Notepad
edit_control . get_text () # get the text in Notepad
edit_control . get_position () # returns a `Postion` namedtuple: e.g. Position(x=6, y=49, width=2381, height=1013) Различные методы окна также могут быть вызваны непосредственно без сначала создания объекта Window , используя основные методы win_* на классе AHK . Например, вместо win.close() , как указано выше, можно было бы назвать ahk.win_close(title='Untitled - Notepad') вместо этого.
from ahk import AHK
ahk = AHK ()
ahk . image_search ( 'C: \ path \ to \ image.jpg' ) # Find an image on screen
# Find an image within a boundary on screen
ahk . image_search ( 'C: \ path \ to \ image.jpg' , upper_bound = ( 100 , 100 ), # upper-left corner of search area
lower_bound = ( 400 , 400 )) # lower-right corner of search area
ahk . pixel_get_color ( 100 , 100 ) # Get color of pixel located at coords (100, 100)
ahk . pixel_search ( color = '0x9d6346' , search_region_start = ( 0 , 0 ), search_region_end = ( 500 , 500 )) # Get coords of the first pixel with specified color Получить/установить данные Clipboard
from ahk import AHK
ahk = AHK ()
ahk . set_clipboard ( 'hello N{EARTH GLOBE AMERICAS} ' ) # set clipboard text contents
ahk . get_clipboard () # get clipboard text contents
# 'hello ?'
ahk . set_clipboard ( "" ) # Clear the clipboard
ahk . clip_wait ( timeout = 3 ) # Wait for clipboard contents to change (with text or file(s))
ahk . clip_wait ( timeout = 3 , wait_for_any_data = True ) # wait for _any_ clipboard contents Вы также можете получить/установить ClipboardAll - однако, вы никогда не должны пытаться вызовать set_clipboard_all с любыми другими данными, как точно так же , как возвращено get_clipboard_all , или могут возникнуть непредвиденные проблемы.
from ahk import AHK
ahk = AHK ()
# save all clipboard contents in all formats
saved_clipboard = ahk . get_clipboard_all ()
ahk . set_clipboard ( 'something else' )
...
ahk . set_clipboard_all ( saved_clipboard ) # restore saved content from earlier Вы также можете установить обратный вызов для выполнения при изменении содержимого буфера обмена. Как и в случае с упомянутыми выше методами горячих клавиш, вы также можете установить обработчик исключений. Как и Hotkeys, обратные вызовы on_clipboard_change также требуют .start_hotkeys() для вступления в силу.
Функция обратного вызова должна принять один позиционный аргумент, который является целым числом, указывающим на данные буфера обмена.
from ahk import AHK
ahk = AHK ()
def my_clipboard_callback ( change_type : int ):
if change_type == 0 :
print ( 'Clipboard is now empty' )
elif change_type == 1 :
print ( 'Clipboard has text contents' )
elif change_type == 2 :
print ( 'Clipboard has non-text contents' )
ahk . on_clipboard_change ( my_clipboard_callback )
ahk . start_hotkeys () # like with hotkeys, must be called at least once for listening to start
# ...
ahk . set_clipboard ( "hello" ) # will cause the message "Clipboard has text contents" to be printed by the callback
ahk . set_clipboard ( "" ) # Clears the clipboard, causing the message "Clipboard is now empty" to be printed by the callback from ahk import AHK
ahk = AHK ()
ahk . sound_play ( 'C: \ path \ to \ sound.wav' ) # Play an audio file
ahk . sound_beep ( frequency = 440 , duration = 1000 ) # Play a beep for 1 second (duration in microseconds)
ahk . get_volume ( device_number = 1 ) # Get volume of a device
ahk . set_volume ( 50 , device_number = 1 ) # Set volume of a device
ahk . sound_get ( device_number = 1 , component_type = 'MASTER' , control_type = 'VOLUME' ) # Get sound device property
ahk . sound_set ( 50 , device_number = 1 , component_type = 'MASTER' , control_type = 'VOLUME' ) # Set sound device property По наступления инструментов/трейтип
import time
from ahk import AHK
ahk = AHK ()
ahk . show_tooltip ( "hello4" , x = 10 , y = 10 )
time . sleep ( 2 )
ahk . hide_tooltip () # hide the tooltip
ahk . show_info_traytip ( "Info" , "It's also info" , silent = False , blocking = True ) # Default info traytip
ahk . show_warning_traytip ( "Warning" , "It's a warning" ) # Warning traytip
ahk . show_error_traytip ( "Error" , "It's an error" ) # Error trytipДиалоговые окны
from ahk import AHK , MsgBoxButtons
ahk = AHK ()
ahk . msg_box ( text = 'Do you like message boxes?' , title = 'My Title' , buttons = MsgBoxButtons . YES_NO )
ahk . input_box ( prompt = 'Password' , title = 'Enter your password' , hide = True )
ahk . file_select_box ( title = 'Select one or more mp3 files' , multi = True , filter = '*.mp3' , file_must_exist = True )
ahk . folder_select_box ( prompt = 'Select a folder' ) Вы можете изменить различные глобальные состояния, такие как CoordMode , DetectHiddenWindows и т. Д., чтобы вам не приходилось передавать эти параметры непосредственно на вызовы функций
from ahk import AHK
ahk = AHK ()
ahk . set_coord_mode ( 'Mouse' , 'Screen' ) # set default Mouse CoordMode to be relative to Screen
ahk . set_detect_hidden_windows ( True ) # Turn on detect hidden windows by default
ahk . set_send_level ( 5 ) # Change send https://www.autohotkey.com/docs/v1/lib/SendLevel.htm
ahk . set_title_match_mode ( 'Slow' ) # change title match speed and/or mode
ahk . set_title_match_mode ( 'RegEx' )
ahk . set_title_match_mode (( 'RegEx' , 'Slow' )) # or both at the same time
ahk . set_send_mode ( 'Event' ) # change the default SendMode Вы можете добавить директивы, которые будут добавлены ко всем сгенерированным сценариям. Например, чтобы предотвратить появление AHK Trayicon, вы можете добавить директиву Notrayicon.
from ahk import AHK
from ahk . directives import NoTrayIcon
ahk = AHK ( directives = [ NoTrayIcon ])По умолчанию некоторые директивы добавляются автоматически для обеспечения функциональности и объединяются с любыми предоставленными пользователями директив.
Директивы не применяются для процесса AHK, используемого для обработки горячих клавиш и жилых констрит (обсуждается ниже) по умолчанию. Чтобы применить директиву для процесса Hotkeys, используя аргумент ключевого слова apply_to_hotkeys_process=True :
from ahk import AHK
from ahk . directives import NoTrayIcon
directives = [
NoTrayIcon ( apply_to_hotkeys_process = True )
]
ahk = AHK ( directives = directives )Как обсуждалось выше, вы можете скрыть значок подноса, если хотите. Кроме того, есть некоторые методы, доступные для настройки значка для подноса.
from ahk import AHK
ahk = AHK ()
# change the tray icon (in this case, using a builtin system icon)
ahk . menu_tray_icon ( 'Shell32.dll' , 174 )
# revert it back to the original:
ahk . menu_tray_icon ()
# change the tooltip that shows up when hovering the mouse over the tray icon
ahk . menu_tray_tooltip ( 'My Program Name' )
# Hide the tray icon
ahk . menu_tray_icon_hide ()
# Show the tray icon that was previously hidden by ``NoTrayIcon`` or ``menu_tray_icon_hide``
ahk . menu_tray_icon_show ()Вы можете прочитать/записать/удалить ключи реестра:
from ahk import AHK
ahk = AHK ()
ahk . reg_write ( 'REG_SZ' , r'HKEY_CURRENT_USERSOFTWAREmy-software' , value = 'test' )
ahk . reg_write ( 'REG_SZ' , r'HKEY_CURRENT_USERSOFTWAREmy-software' , value_name = 'foo' , value = 'bar' )
ahk . reg_read ( r'HKEY_CURRENT_USERSOFTWAREmy-software' ) # 'test'
ahk . reg_delete ( r'HKEY_CURRENT_USERSOFTWAREmy-software' )Если ключ не существует или возникает какая -либо другая проблема, возникает исключение.
Большинство методов в этой библиотеке предоставляют неблокирующий интерфейс, поэтому ваши скрипты Python могут продолжать выполнять, пока ваши скрипты AHK работают.
По умолчанию все вызовы блокируются - каждая функция будет выполняться полностью до выполнения следующей функции.
Однако иногда вы можете запустить другой код, пока AHK выполняет какой -то код. Когда аргумент blocking ключевых слов поставляется с False , вызовы функций возвращаются немедленно, в то время как функция AHK выполняется в фоновом режиме.
Например, вы можете медленно перемещать мышь и сообщать о своей позиции по мере ее движения:
import time
from ahk import AHK
ahk = AHK ()
ahk . mouse_position = ( 200 , 200 ) # Moves the mouse instantly to the start position
start = time . time ()
# move the mouse very slowly
ahk . mouse_move ( x = 100 , y = 100 , speed = 30 , blocking = False )
# This code begins executing right away, even though the mouse is still moving
while True :
t = round ( time . time () - start , 4 )
position = ahk . mouse_position
print ( t , position ) # report mouse position while it moves
if position == ( 100 , 100 ):
break Когда вы указываете blocking=False вы всегда будете получать специальный объект FutureResult (или AsyncFutureResult объекта в ASYNC API, обсуждаемый ниже), который позволяет вам ждать функции, чтобы завершить и получить возвратное значение через функцию get_result . Даже когда функция обычно не возвращает None , это может быть полезно, чтобы AHK завершил выполнение функции.
Неблокирующие звонки:
set_coord_mode или аналогичного) - это может измениться в будущей версии.FutureResult (или AsyncFutureResult объекта в Async API, обсуждаемый ниже), который позволяет вам ждать функции, чтобы завершить и получить возвратное значение через функцию result . Даже когда функция обычно не возвращает None , это может быть полезно, чтобы AHK завершил выполнение функции. from ahk import AHK
ahk = AHK ()
future_result = ahk . mouse_move ( 100 , 100 , speed = 40 , blocking = False )
...
# wait on the mouse_move to finish
future_result . result ( timeout = 10 ) # timeout keyword is optional Асинхронный API предоставляется, поэтому функции можно назвать с помощью async / await . Все те же методы из синхронного API доступны в Async API.
from ahk import AsyncAHK
import asyncio
ahk = AsyncAHK ()
async def main ():
await ahk . mouse_move ( 100 , 100 )
x , y = await ahk . get_mouse_position ()
print ( x , y )
asyncio . run ( main ())Async API идентичен API нормального API, с несколькими заметными различиями:
.mouse_position или .title для Windows) можно await , были добавлены дополнительные методы (например, get_mouse_position() и get_title() ) были добавлены для более интуитивного API и рекомендуются в отношении использования свойств.ahk.mouse_postion = (200, 200) ) не допускаются в Async API (повышается время выполнения). Сетчики свойств остаются доступными в API Sync.AsyncFutureResult объекты (возвращаются при определении blocking=False ) работают так же, как и объекты FutureResult в API Sync, за исключением того, что ключевое слово timeout не поддерживается для метода result ).Обратите внимание также, что:
AsyncAHK не будут выполняться одновременно. Вы должны либо использовать blocking=False , как в API Sync, либо использовать несколько экземпляров AsyncAHK . Эта библиотека полностью намекает на тип, что позволяет вам использовать такие инструменты, как mypy , чтобы помочь подтвердить корректность типа вашего кода. IDE, которые реализуют функции проверки типов, также способны использовать подсказки типа, чтобы обеспечить безопасность вашего кода.
Вы также можете запустить произвольный код автоматического обзора либо в виде файла скрипта .ahk , либо в виде строки, содержащей код AHK.
from ahk import AHK
ahk = AHK ()
my_script = '''
MouseMove, 100, 100
; etc...
'''
ahk . run_script ( my_script ) from ahk import AHK
ahk = AHK ()
script_path = r'C:PathTomyscript.ahk'
ahk . run_script ( script_path ) Чтобы использовать этот пакет, вам нужен исполняемый файл AutoHotKey (например, AutoHotkey.exe ). Ожидается, что он будет на пути по умолчанию или в месте установки по умолчанию ( C:Program FilesAutoHotkeyAutoHotkey.exe для V1 или C:Program FilesAutoHotkeyv2AutoHotkey64.exe для V2)
Autohotkey V1 и V2 оба полностью поддерживаются, хотя некоторые поведенческие различия будут происходить в зависимости от того, какую версию вы используете. См. Примечания ниже.
Рекомендуемый способ снабжения двоичного файла Autohotkey (как для V1, так и для V2) - установить binary дополнительное для этого пакета. Это предоставит необходимые исполняемые файлы и поможет убедиться, что они правильно размещены на пути.
pip install "ahk[binary]"
В качестве альтернативы, вы можете предоставить путь в коде:
from ahk import AHK
ahk = AHK ( executable_path = 'C: \ path \ to \ AutoHotkey.exe' ) Вы также можете использовать переменную среды AHK_PATH , чтобы указать расположение исполняемого файла.
set AHK_PATH=C:PathToAutoHotkey.exe
python myscript.py По умолчанию, когда не установлен параметр executable_path (или переменная среды AHK_PATH ), не установлено только двоичные имена Autohotkey v1, которые ищут на пути или расположения установки по умолчанию. Такое поведение может измениться в будущих версиях, чтобы V2 использовался по умолчанию.
Чтобы использовать версию 2 Autohotkey, вы можете сделать что -либо из следующих вещей:
executable_path с местоположением двоичного файла Autohotkey v2AHK_PATH с местоположением двоичного файла Autohotkey v2version со значением v2 , который позволяет найти исполняемый файл с использованием двоичных имен Autohotkey v2 и местоположений установки по умолчанию.Например:
from ahk import AHK
ahk = AHK ( executable_path = r'C:Program FilesAutoHotkeyv2AutoHotkey64.exe' )
# OR
ahk = AHK ( version = 'v2' ) Когда вы предоставляете аргумент ключевого слова version (с "v1" или "v2" ), выполняется проверка, чтобы обеспечить предоставленную (или обнаруженную) бинарную совпадения запрашиваемую версию. Когда ключевое слово version опущено, версия определяется автоматически из предоставленного (или обнаруженного) исполняемого двоичного файла.
API этого проекта изначально разработан против AutoHotkey V1, а функциональные подписи одинаковы, даже при использовании AutoHotKey V2. Хотя большая часть поведения остается прежним, некоторое поведение меняется при использовании Autohotkey V2 по сравнению с V1. Это в основном из -за основных различий между двумя версиями.
Некоторые из заметных различий, которые вы можете испытать при использовании Autohotkey V2 с этой библиотекой, включают:
None (как в Autohotkey v2, в большинстве случаев выбрасывается TargetError, когда окно или управление не могут быть найдены)ControlSend ( ahk.control_send или Window.send или Control.send ) отличается в Autohotkey v2, когда параметр control не указан. В V1 клавиши отправляются на самые верхние элементы управления, что обычно является правильным поведением. В V2 клавиши отправляются непосредственно в окно. Это означает, что во многих случаях вам необходимо явно указать управление при использовании V2.secondstowait Paramater для TrayTip ( ahk.show_traytip ) был удален в V2. Указание этого параметра в обертке Python приведет к излучению предупреждения, а параметр игнорируется.Input , а не Event в V1 (как следствие, например, параметры скорости мыши для mouse_move и mouse_drag будут игнорироваться в V2, если не будет изменен режим отправки)2 в Autohotkey v2. Это 1 в Autohotkey v1. Используйте аргументы ключевых слов title_match_mode с win_get и другими методами, которые принимают это ключевое слово для управления этим поведением или используйте set_title_match_mode , чтобы изменить поведение по умолчанию (не блокирующие вызовы выполняются в отдельных процессах и не влияют на set_title_match_mode ) Вы можете разработать расширения для расширения функциональности ahk , то есть: написание своего собственного кода AutoHotKey и добавление дополнительных методов в класс AHK. Смотрите расширяющие документы для получения дополнительной информации.
Все вклады приветствуются и ценятся.
Пожалуйста, не стесняйтесь открывать проблему GitHub или PR для обратной связи, идей, запросов функций или вопросов.
Это некоторые аналогичные проекты, которые обычно используются для автоматизации с Python.
keyboard , Pure Python Mouse Control!