如何创建在后台运行并对键盘输入做出反应的Python脚本?

时间:2017-12-24 01:52:36

标签: python windows python-3.x background-process

目前,我正在使用AutoHotKey通过键盘快捷键触发脚本。我喜欢用Python编程,而不是处理AutoHotKey,每次触摸我的AutoHotKey脚本时,我都希望能编写干净的AutoHotkey代码。

让我们在我按下插入键的任何窗口中使用简单的AutoHotKey脚本打印hello world

foo(){
    send, "hello world"
}
Insert:: foo()

我如何在Windows上的Python3中做同样的事情?

2 个答案:

答案 0 :(得分:1)

你将不得不钩住窗户的g来实现这一目标。您可能必须通过ctypesCFFI模块执行此操作,因为必要的API似乎不存在于pywin32中。

根据this page,您需要使用三个Windows API调用:

答案 1 :(得分:0)

您可以将StackOverflow中的两个答案组合起来(几乎)解决此问题。

  1. 使用this回答(按tehvan)创建getch()类似方法,从用户读取一个字符,而无需\n。 (在答案下方重复)
  2. 使用Python this answer(Barafu Albino)版本在单独的进程中调用先前定义的_Getch()类。
  3. 请注意,以下代码仅适用于Python3,并使用任何键来停止进程,而不仅仅是插入密钥。

    # This code is a combination of two StackOverflow answers
    # (links given in the answer)
    
    # ------- Answer 1 by tehvan -----------------------------------
    class _Getch:
        """Gets a single character from standard input.  
           Does not echo to the screen."""
        def __init__(self):
            try:
                self.impl = _GetchWindows()
            except ImportError:
                self.impl = _GetchUnix()
    
        def __call__(self): return self.impl()
    
    class _GetchUnix:
        def __init__(self):
            import tty, sys
    
        def __call__(self):
            import sys, tty, termios
            fd = sys.stdin.fileno()
            old_settings = termios.tcgetattr(fd)
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(1)
            finally:
                termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
            return ch
    
    class _GetchWindows:
        def __init__(self):
            import msvcrt
    
        def __call__(self):
            import msvcrt
            return msvcrt.getch()
    
    getch = _Getch()
    
    # -------- Answer 2 by Barafu Albino (modified) -------
    import _thread
    
    def input_thread(a_list):
        _Getch().__call__()
        a_list.append(True)
    
    def do_stuff():
        a_list = []
        _thread.start_new_thread(input_thread, (a_list,))
        print('Press any key to stop.')
        while not a_list:
            pass  
            # This is where you can put the stuff 
            # you want to do until the key is pressed
        print('Stopped.')
    
    do_stuff()