gpt4 book ai didi

python - 如何用Python处理异步击键?

转载 作者:行者123 更新时间:2023-12-01 04:15:14 24 4
gpt4 key购买 nike

我正在寻找将击键发送到 Python 脚本的方法。在本例中,我尝试让脚本检测是否按下任意键,而不仅仅是中断信号(ctrl + c、ctrl + d,...)。

我已经检查了信号Python模块。但似乎它只准备处理中断信号,而如果我按“K”或“空格”,则不会。我在模块的官方文档中看到了这一点:

import signal
import os
import time

def receive_signal(signum, stack):
print 'Received:', signum

signal.signal(signal.SIGUSR1, receive_signal)
signal.signal(signal.SIGUSR2, receive_signal)

print 'My PID is:', os.getpid()

while True:
print 'Waiting...'
time.sleep(3)

他们说:

To send signals to the running program, I use the command line program kill. To produce the output below, I ran signal_signal.py in one window, then kill -USR1 $pid, kill -USR2 $pid, and kill -INT $pid in another.

我非常确定这个模块不是解决方案。你知道一些模块或其他东西可以帮助我将击键异步发送到我的 python 脚本吗?

非常感谢!!

最佳答案

I want the user has the possibility of skip a day, a month or a machine by pressing a key in whatever moment.

啊。现在看来是有道理的。

And not very sure that this would be possible.

一切皆有可能。对于真正的异步解决方案来说,它可能相当复杂。

我能想到的唯一方法,同时避免轮询方法,是fork(2)进程,让父进程监听按键,并向子进程发送信号,它实际上完成了工作。

类似这样的事情...

#!/usr/bin/env python

import sys, os, time, termios, tty, signal


# Define some custom exceptions we can raise in signal handlers
class SkipYear(Exception):
pass

class SkipMonth(Exception):
pass


# Process one month
def process_month(year, month):

# Fake up whatever the processing actually is
print 'Processing %04d-%02d' % (year, month)
time.sleep(1)


# Process one year
def process_year(year):

# Iterate months 1-12
for month in range(1, 13):

try:
process_month(year, month)
except SkipMonth:
print 'Skipping month %d' % month


# Do all processing
def process_all(args):

# Help
print 'Started processing - args = %r' % args

try:

# Iterate years 2010-2015
for year in range(2010, 2016):

try:
process_year(year)
except SkipYear:
print 'Skipping year %d' % year

# Handle SIGINT from parent process
except KeyboardInterrupt:
print 'Child caught SIGINT'

# Return success
print 'Child terminated normally'
return 0


# Main entry point
def main(args):

# Help
print 'Press Y to skip current year, M to skip current month, or CTRL-C to abort'

# Get file descriptor for stdin. This is almost always zero.
stdin_fd = sys.stdin.fileno()

# Fork here
pid = os.fork()

# If we're the child
if not pid:

# Detach child from controlling TTY, so it can't be the foreground
# process, and therefore can't get any signals from the TTY.
os.setsid()

# Define signal handler for SIGUSR1 and SIGUSR2
def on_signal(signum, frame):
if signum == signal.SIGUSR1:
raise SkipYear
elif signum == signal.SIGUSR2:
raise SkipMonth

# We want to catch SIGUSR1 and SIGUSR2
signal.signal(signal.SIGUSR1, on_signal)
signal.signal(signal.SIGUSR2, on_signal)

# Now do the thing
return process_all(args[1:])

# If we get this far, we're the parent

# Define a signal handler for when the child terminates
def on_sigchld(signum, frame):
assert signum == signal.SIGCHLD
print 'Child terminated - terminating parent'
sys.exit(0)

# We want to catch SIGCHLD
signal.signal(signal.SIGCHLD, on_sigchld)

# Remember the original terminal attributes
stdin_attrs = termios.tcgetattr(stdin_fd)

# Change to cbreak mode, so we can detect single keypresses
tty.setcbreak(stdin_fd)

try:

# Loop until we get a signal. Typically one of...
#
# a) SIGCHLD, when the child process terminates
# b) SIGINT, when the user presses CTRL-C
while 1:

# Wait for a keypress
char = os.read(stdin_fd, 1)

# If it was 'Y', send SIGUSR1 to the child
if char.lower() == 'y':
os.kill(pid, signal.SIGUSR1)

# If it was 'M', send SIGUSR2 to the child
if char.lower() == 'm':
os.kill(pid, signal.SIGUSR2)

# Parent caught SIGINT - send SIGINT to child process
except KeyboardInterrupt:
print 'Forwarding SIGINT to child process'
os.kill(pid, signal.SIGINT)

# Catch system exit
except SystemExit:
print 'Caught SystemExit'

# Ensure we reset terminal attributes to original settings
finally:
termios.tcsetattr(stdin_fd, termios.TCSADRAIN, stdin_attrs)

# Return success
print 'Parent terminated normally'
return 0


# Stub
if __name__ == '__main__':
sys.exit(main(sys.argv))

...应该可以解决问题,尽管您会受到可以发送的不同信号数量的限制。

关于python - 如何用Python处理异步击键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34396564/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com