perlence / autohotkey.py Goto Github PK
View Code? Open in Web Editor NEWWrite AutoHotkey scripts in Python.
Home Page: https://ahkpy.readthedocs.io
License: BSD 3-Clause "New" or "Revised" License
Write AutoHotkey scripts in Python.
Home Page: https://ahkpy.readthedocs.io
License: BSD 3-Clause "New" or "Revised" License
I use this module on three Windows machines and it worked flawlessly. It's an awesome tool, thank you for developing it.
A couple of days ago I decided to migrate one of the machines to a proper python environment. I'm usually not working on the machine and didn't spend the time to setup python properly, initially.
I uninstalled the system python, and installed python 3.10.2
using pyenv
. The other machines are running the same python version and are running fine. I then installed other modules and did not experience any kind of trouble until I attempted to run 2 of my scripts via python -m ahkpy script.py
:
This command returns an empty line and terminates immediately. No error, no logs. Same effect when I call python -m ahkpy -h
. Any idea how I could debug the problem without cloning this repo and doing the pip install -e .
shenanigans?
I did:
autohotkey.py
python -m pip install autohotkey.py
import ahkpy
from within the interpreter; no import errorspython script.py
and I correctly receive the RuntimeError: AHK interop is not available. Please start your code as 'py -m ahkpy main.py'.
I am not using virtualenv
.
Locations:
c:\users\tommi\.pyenv\pyenv-win\versions\3.10.2\lib\site-packages\ahkpy\*
c:\users\tommi\.pyenv\pyenv-win\versions\3.10.2\lib\site-packages\autohotkey.py-0.1.2.dist-info\*
c:\users\tommi\.pyenv\pyenv-win\versions\3.10.2\scripts\ahkpy.exe
$ pyenv which python
C:\Users\Tommi\.pyenv\pyenv-win\versions\3.10.2\python.exe
$ pyenv which pip
C:\Users\Tommi\.pyenv\pyenv-win\versions\3.10.2\Scripts\pip.exe
Any idea what I am missing and how to debug the situation? Thank you for your time!
Thank you
Phone numbers usually look like this:
+49-1234-56 78 90
+491234567890
Problem: When you copy the second number to the clipboard (manually or programmatically) and afterwards try to receive it with get_clipboard()
, you will only get 491234567890
instead of +491234567890
(spot the missing +
). The first number is copied as-is.
You might find the following examples useful.
BUG_clipboard.py
:
import ahkpy as ahk
@ahk.hotkey('^p')
def print_clipboard():
print(ahk.get_clipboard())
def test_clipboard(test_str: str):
print('----------')
ahk.set_clipboard(test_str)
ahk.sleep(.5)
clipboard = ahk.get_clipboard()
if clipboard == test_str:
print("OK:", test_str)
else:
print("ERROR:")
print(test_str, "!=")
print(clipboard, type(clipboard))
# Failing:
test_clipboard('+491234567890')
test_clipboard(' +491234567890 ')
test_clipboard('+49.1234567890')
# OK:
test_clipboard('+49.1234.567890')
test_clipboard('+49-1234-56 78 90')
test_clipboard('+49 1234 56 78 90')
test_clipboard('-491234567890')
test_clipboard('Phone: +491234567890')
test_clipboard('+491234567890 x')
It looks like as if somewhere on it's way from AHK to Python the clipboard content get's interpreted as a number (if possible) and as consequence looses it's plus sign.
The following Autohotkey script works fine:
phone := "+491234567890"
clipboard := phone
MsgBox % clipboard
Hi guys,
Anyone knows that how do I do the same as below AHK script?
// Click F7 to hold-on Alt for 1 sec before release
F7::
Send {Alt down}
Sleep 1000
Send {Alt up}
Regards,
Wayne
Is it possible to implement #SingleInstance?
I am thinking it's not possible unless you can
AHK version 2 was officially released a few weeks ago.
When I use "py -m pip install --user autohotkey.py" I get this error: The term 'py' is not recognized as the name of a cmdlet, function, script file, or operable program.
When installing v1 and v2 both in pc, it will use v2 automatically. Any idea to force it to use v1?
I remapped the side buttons of my mouse to the mouse wheel but it sometimes locks.
@ahk.hotkey("XButton2")
def scroll_up():
while ahk.is_key_pressed("XButton2"): # remains true forever sometimes
ahk.send("{WheelUp}")
ahk.sleep(0.010)
@ahk.hotkey("XButton1")
def scroll_down():
while ahk.is_key_pressed("XButton1"): # remains true forever sometimes
ahk.send("{WheelDown}")
ahk.sleep(0.010)
Using is_key_pressed_logical does not work
The script errors out with Cannot load Python DLL: 5
.
The user running the script is not an admin.
When I start the following script with py -m ahkpy hello-world.py
the hotkey [Ctrl+Shift+H]
works as expected but both hotstrings don't. When typing hw
followed by a space the space is ommited but nothing else happens. When typing wtf
followed by a space the space is replaced by Hello World
which results in wtfHello World
.
hello-world.py:
import ahkpy
CTRL = '^'
SHIFT = '+'
WIN = '#'
ALT = '!'
print('Ready...')
ahkpy.hotstring("hw", "Hello World")
@ahkpy.hotstring("wtf")
def hello1():
ahkpy.send("Hello World")
@ahkpy.hotkey(CTRL+SHIFT+"H")
def hello2():
ahkpy.send("Hello World")
I'm using Autohotkey 1.1.33.10 and Python 3.11.1 on Windows 10.
Hello,
apologies if this is not the right place for this question, but I've been struggling with this for a while now.
I'm trying to use the wrapper for a game made with Ren'Py. Normally it can use 3rd party modules from a folder called 'python-packages' in the game's directory (it works fine with the keyboard module, for example). But when I test anything inside the game, it returns with RuntimeError: AHK interop is not available.
And if I run the traceback, I get this:
File "C:\Users\fanto\Desktop\renpy-8.1.0-sdk\renpy\compat\__init__.py", line 61, in <module>
import future.standard_library
ModuleNotFoundError: No module named 'future'
I have tried updating and re-installing future, but the same message comes up every time.
Thanks
Edit:
While re-reading this I noticed that I somehow assumed the ahkpy.windows.first(...)
call would retrieve the active window. I should specifiy that I did not notice a problem with the get_active_window()
method.
Over the past three weeks I've been migrating several huge AHK scripts (ranging from 3k-7.5k lines) to python using this module. I'm amazed how smoothly the migration has been going for me and at this point I feel confident to notice "strange" behaviour. I've had trouble multiple times regarding a reliable active window detection while using the tools provided in the documentation. I did not think too much of it at first, because some of the software I am automating is really crappy, proprietary, early 2000s, retail-sale trash which does not behave like well written software. BUT now that I migrated more scripts, I noticed several strange things:
ahkpy.windows.first(...)
call, or with the class_name=
parameter. (.get_active_window()
seems to be working fine)The original AHK scripts are usually split into several segments divided by #IfWinActive <part_of_window_name>
statements. My goal while migrating the scripts into python is to split these segments into different classes all united in one master script.
I threw together a tiny sample that shows at least some of the behaviour I do not understand. Especially interesting to me is the output of lines 6, 7, 8
import ahkpy as ahk
classes = ['VSCodium', 'Firefox']
titles = ['main.py', 'Github']
for c, t in zip(classes, titles):
print('ContextManager check if {}({}) active: '.format(c, t), CM.is_window_active(c), CM.is_window_active(t))
print('01: ', ahk.windows.filter(t, class_name=c))
print('02: ', ahk.windows.active_window_context(class_name=c))
print('03: ', ahk.windows.filter(exe='{}.exe'.format(c)))
print('04: ', ahk.windows.filter(class_name=c))
print('05: ', ahk.windows.filter(title=t))
print('06: ', ahk.windows.first(class_name=c))
print('07: ', ahk.windows.first(exe='{}.exe'.format(c)))
print('08: ', ahk.windows.first(title=t))
Out#1: Active Win: VSCodium, active file: main.py
ContextManager check if VSCodium(main.py) active: True True
01: Windows(title='main.py', class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A1510>)))
03: Windows(exe='VSCodium.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='main.py', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=262836)
08: Window(id=262836)
ContextManager check if Firefox(Github) active: False False
01: Windows(title='Github', class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A1750>)))
03: Windows(exe='Firefox.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='Github', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=132390)
08: Window(id=None)
Out#1: Active Win: VSCodium, active file: AHK.py
ContextManager check if VSCodium(main.py) active: True False
01: Windows(title='main.py', class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A2290>)))
03: Windows(exe='VSCodium.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='main.py', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=262836)
08: Window(id=None)
ContextManager check if Firefox(Github) active: False False
01: Windows(title='Github', class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A24D0>)))
03: Windows(exe='Firefox.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='Github', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=656672)
08: Window(id=None)
Out#3: Active Win: Firefox, active tab: Github
ContextManager check if VSCodium(main.py) active: False False
01: Windows(title='main.py', class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A1990>)))
03: Windows(exe='VSCodium.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='main.py', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=262836)
08: Window(id=262836)
ContextManager check if Firefox(Github) active: True True
01: Windows(title='Github', class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A1BD0>)))
03: Windows(exe='Firefox.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='Github', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=132390)
08: Window(id=None)
Out#4: Active Win: Firefox, active tab: Youtube
ContextManager check if VSCodium(main.py) active: False False
01: Windows(title='main.py', class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A1E10>)))
03: Windows(exe='VSCodium.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='VSCodium', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='main.py', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=262836)
08: Window(id=262836)
ContextManager check if Firefox(Github) active: True False
01: Windows(title='Github', class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
02: HotkeyContext(active_when=functools.partial(<function _bare_predicate at 0x00000000083AA290>, functools.partial(<function Windows.active_window_context.<locals>.<lambda> at 0x000000006D0A2050>)))
03: Windows(exe='Firefox.exe', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
04: Windows(class_name='Firefox', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
05: Windows(title='Github', hidden_windows=False, hidden_text=True, title_mode='startswith', text_mode='fast')
06: Window(id=None)
07: Window(id=132390)
08: Window(id=None)
I am trying to set it so my mouse side buttons revert back to the default values when Overwatch is in front. But this does not appear to work
def is_overwatch():
return ahk.visible_windows.get_active().process_name == "Overwatch.exe"
overwatch_ctx = ahk.HotkeyContext(is_overwatch)
overwatch_ctx.hotkey("XButton2").disable()
overwatch_ctx.hotkey("XButton1").disable()
I also tried also no luck
overwatch_ctx.hotkey("XButton2", lambda hotkey: hotkey.disable())
overwatch_ctx.hotkey("XButton1", lambda hotkey: hotkey.disable())
I also tried
overwatch_ctx.hotkey("XButton2", ahk.send("XButton2"))
overwatch_ctx.hotkey("XButton1", ahk.send("XButton1"))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.