Um invólucro Python totalmente digitado em torno do AutohotKey.
pip install ahk
Requer Python 3.8+
Suporta o AutoHotKey V1 e V2. Veja também: dependências não python
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)Exemplos não exaustivos de algumas funções disponíveis com este pacote. Consulte a documentação completa para obter referências completas da API e recursos adicionais.
As teclas de atalho podem ser configuradas para executar funções Python como retornos de chamada.
Por exemplo:
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 Agora sempre que você pressiona + n , a função my_callback de retorno de chamada será chamada em um thread em segundo plano.
Você também pode adicionar um manipulador de exceção para o seu retorno de chamada:
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 )Também existem métodos para remover teclas de atalho:
# ...
ahk . remove_hotkey ( '#n' ) # remove a hotkey by its keyname
ahk . clear_hotkeys () # remove all hotkeysObserve que:
ahk.start_hotkeys() )ahk.stop_hotkeys() (não parará de executar ativamente retornos de chamada)Veja também a documentação AHK relevante
As quentes também podem ser adicionadas ao thread de processo de tecla de atalho.
Além de, que suporta as substituições normais de string AHK, você também pode fornecer retornos de chamada Python (com manipuladores de exceção opcionais) em resposta ao acionamento do Hotstrings.
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 hotstringVocê também pode remover o Hotstrings:
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' )Você também pode fazer coisas com janelas.
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) Vários métodos de janela também podem ser chamados diretamente sem primeiro criar um objeto Window usando os métodos win_* subjacentes na classe AHK . Por exemplo, em vez de win.close() , como acima, pode -se chamar 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 Obtenha/defina dados 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 Você também pode obter/definir ClipboardAll - no entanto, nunca deve tentar chamar set_clipboard_all com outros dados, exceto exatamente o retorno por get_clipboard_all ou problemas inesperados.
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 Você também pode definir um retorno de chamada para executar quando o conteúdo da área de transferência mudar. Como nos métodos de tecla de atalho mencionados acima, você também pode definir um manipulador de exceção. Como os Hotkeys, on_clipboard_change Retornos também exigem que .start_hotkeys() sejam chamados para entrar em vigor.
A função de retorno de chamada deve aceitar um argumento posicional, que é um número inteiro que indica o tipo de dados da área de transferência.
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 Dicas de ferramentas/bandejas
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 trytipCaixas de diálogo
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' ) Você pode alterar vários estados globais, como CoordMode , DetectHiddenWindows , etc. para que você não precise passar esses parâmetros diretamente para funcionar chamadas
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 Você pode adicionar diretivas que serão adicionadas a todos os scripts gerados. Por exemplo, para impedir que o AHK Trayicon apareça, você pode adicionar a diretiva Notrayicon.
from ahk import AHK
from ahk . directives import NoTrayIcon
ahk = AHK ( directives = [ NoTrayIcon ])Por padrão, algumas diretivas são adicionadas automaticamente para garantir a funcionalidade e são mescladas a quaisquer diretivas fornecidas pelo usuário.
As diretrizes não são aplicadas para o processo AHK usado para manusear teclas de atalho e entusiasmo (discutido abaixo) por padrão. Para aplicar uma diretiva ao processo do Hotkeys usando o argumento da palavra -chave 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 )Como discutido acima, você pode ocultar o ícone da bandeja, se desejar. Além disso, existem alguns métodos disponíveis para personalizar o ícone da bandeja.
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 ()Você pode ler/escrever/excluir as chaves do registro:
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' )Se uma chave não existir ou ocorrer algum outro problema, será levantada uma exceção.
A maioria dos métodos nesta biblioteca fornece uma interface não bloqueadora, para que seus scripts Python possam continuar executando enquanto seus scripts AHK são executados.
Por padrão, todas as chamadas estão bloqueando - cada função será executada completamente antes que a próxima função seja executada.
No entanto, às vezes você pode executar outro código enquanto a AHK executa algum código. Quando o argumento da palavra -chave blocking é fornecido com False , as chamadas de função retornarão imediatamente enquanto a função AHK é realizada em segundo plano.
Como exemplo, você pode mover o mouse lentamente e relatar sua posição à medida que ela se move:
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 Quando você especificar blocking=False você sempre receberá um objeto FutureResult especial (ou objeto AsyncFutureResult na API ASYNC, discutido abaixo), que permite aguardar a função para concluir e recuperar o valor de retorno por meio de uma função get_result . Mesmo quando uma função normalmente None , isso pode ser útil para garantir que o AHK termine de executar a função.
Chamadas não bloqueadas:
set_coord_mode ou similares) - isso pode mudar em uma versão futura.FutureResult especial (ou objeto AsyncFutureResult na API Async, discutida abaixo), que permite que você aguarde a função para concluir e recuperar o valor de retorno através da função result . Mesmo quando uma função normalmente None , isso pode ser útil para garantir que o AHK termine de executar a função. 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 Uma API assíncrona é fornecida para que as funções possam ser chamadas usando async / await . Todos os mesmos métodos da API síncrona estão disponíveis na API Async.
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 ())A API assíncrona é idêntica à da API normal, com algumas diferenças notáveis:
.mouse_position ou .title for windows) possam ser await , métodos adicionais (como get_mouse_position() e get_title() ) foram adicionados para uma API mais intuitiva e são recomendados sobre o uso de propriedades.ahk.mouse_postion = (200, 200) ) não são permitidos na API assíncrona (um tempo de execução é levantado). Os setters de propriedades permanecem disponíveis na API de sincronização.AsyncFutureResult (retornados ao especificar blocking=False ) funcionam da mesma forma que os objetos FutureResult na API de sincronização, exceto que a palavra -chave timeout não é suportada para o método result ).Observe também isso:
AsyncAHK não serão executadas simultaneamente. Você deve usar blocking=False , como na API de sincronização ou usar várias instâncias de AsyncAHK . Esta biblioteca é totalmente indiscutida, permitindo que você aproveite ferramentas como mypy para ajudar a validar a correção de tipo do seu código. Os IDEs que implementam os recursos de verificação do tipo também podem aproveitar dicas do tipo para ajudar a garantir que seu código seja seguro.
Você também pode executar o código arbitrário do AutoHotKey como um arquivo de script .ahk ou como uma string que contém código 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 ) Para usar este pacote, você precisa do AutoHotKey Executável (por exemplo, AutoHotkey.exe ). Espera -se estar no caminho por padrão ou em um local de instalação padrão ( C:Program FilesAutoHotkeyAutoHotkey.exe para V1 ou C:Program FilesAutoHotkeyv2AutoHotkey64.exe para V2)
O AutoHotKey V1 e V2 são totalmente suportados, embora algumas diferenças comportamentais ocorram dependendo da versão que você usa. Veja as notas abaixo.
A maneira recomendada de fornecer o binário automático (para V1 e V2) é instalar o binary extra para este pacote. Isso fornecerá os executáveis necessários e ajudará a garantir que eles sejam colocados corretamente no caminho.
pip install "ahk[binary]"
Como alternativa, você pode fornecer o caminho no código:
from ahk import AHK
ahk = AHK ( executable_path = 'C: \ path \ to \ AutoHotkey.exe' ) Você também pode usar a variável de ambiente AHK_PATH para especificar o local executável.
set AHK_PATH=C:PathToAutoHotkey.exe
python myscript.py Por padrão, quando nenhum parâmetro executable_path (ou variável de ambiente AHK_PATH ) é definido, apenas os nomes binários do AutoHotKey V1 são pesquisados no caminho ou nos locais de instalação padrão. Esse comportamento pode mudar em versões futuras para permitir que a V2 seja usada por padrão.
Para usar a versão 2 do AutoHotKey, você pode fazer qualquer uma das seguintes coisas:
executable_path com a localização do binário AutoHotKey V2AHK_PATH com a localização de um binário autohotkey v2version com o valor v2 , que permite encontrar o executável usando nomes binários do AutoHotKey V2 e locais de instalação padrão.Por exemplo:
from ahk import AHK
ahk = AHK ( executable_path = r'C:Program FilesAutoHotkeyv2AutoHotkey64.exe' )
# OR
ahk = AHK ( version = 'v2' ) Quando você fornece o argumento da palavra -chave de version (com "v1" ou "v2" ), uma verificação é executada para garantir que o binário fornecido (ou descoberto) corresponda à versão solicitada. Quando a palavra -chave version é omitida, a versão é determinada automaticamente a partir do binário executável (ou descoberto) (ou descoberto).
A API deste projeto é originalmente projetada contra o AutoHotKey V1 e as assinaturas de funções são as mesmas, mesmo ao usar o AutoHotKey V2. Embora a maior parte do comportamento permaneça a mesma, algum comportamento muda ao usar o AutoHotkey V2 em comparação com a V1. Isso se deve principalmente a diferenças subjacentes entre as duas versões.
Algumas das diferenças notáveis que você pode experimentar ao usar o AutoHotKey V2 com esta biblioteca incluem:
None (como no Autohotkey V2, um TargetError é jogado na maioria dos casos em que a janela ou controle não pode ser encontrado)ControlSend ( ahk.control_send ou Window.send ou Control.send ) difere no autohotkey v2 quando o parâmetro control não é especificado. Em V1, as chaves são enviadas para os controles mais superiores, que geralmente é o comportamento correto. No V2, as chaves são enviadas diretamente para a janela. Isso significa que, em muitos casos, você precisa especificar o controle explicitamente ao usar V2.secondstowait para TrayTip ( ahk.show_traytip ) foi removido em V2. Especificar esse parâmetro no invólucro Python fará com que um aviso seja emitido e o parâmetro será ignorado.Input e não no Event em V1 (como conseqüência, por exemplo, os parâmetros de velocidade do mouse para mouse_move e mouse_drag serão ignorados em V2, a menos que o modo de envio seja alterado)2 no AutoHotKey V2. É 1 no AutohotKey v1. Use os argumentos de palavra-chave title_match_mode para win_get e outros métodos que aceitam essa palavra-chave para controlar esse comportamento ou usar set_title_match_mode para alterar o comportamento padrão (as chamadas não bloqueadoras são executadas em processos separados e não são afetados por set_title_match_mode ) Você pode desenvolver extensões para estender a funcionalidade do ahk - isto é: escrever seu próprio código AutoHotKey e adicionar métodos adicionais à classe AHK. Consulte os documentos estendidos para obter mais informações.
Todas as contribuições são bem -vindas e apreciadas.
Sinta -se à vontade para abrir um problema do GitHub ou PR para feedback, idéias, solicitações de recursos ou perguntas.
Estes são alguns projetos semelhantes comumente usados para automação com Python.
keyboard , controle puro do mouse python!