python函数调用键盘热键_如何使用python在控制台中获取键盘事件

这可能取决于你所使用的平台,甚至可能是你正在使用的终端模拟器,我不确定它是否能解决你的问题,但……

您应该能够在不调用tty.setraw的情况下获得逐字符输入,只需将“规范模式”设置为关闭,您可以通过屏蔽tcgetattr()的lflag属性中的ICANON位来实现.您可能还需要设置VMIN或VTIME属性,但默认值应该已经正确.

有关详细信息,请参阅linux man page中的“规范和非规范模式”部分,OS X man page中的“非规范模式输入处理”部分,或者如果您使用的是其他平台,请参阅等效部分.

将此作为上下文管理器而不是进行显式清理可能更清晰.特别是因为你现有的代码每次都通过循环进行setraw,并且只在最后恢复;它们理想情况下应该是匹配对,并使用with语句保证. (另外,这种方式你不需要在except子句和正常流程中重复自己.)所以:

@contextlib.contextmanager

def decanonize(fd):

old_settings = termios.tcgetattr(fd)

new_settings = old_settings[:]

new_settings[3] &= ~termios.ICANON

termios.tcsetattr(fd, termios.TCSAFLUSH, new_settings)

yield

termios.tcsetattr(fd, termios.TCSAFLUSH, old_settings)

现在:

def change():

global switch

global loop_bool

with decanonize(sys.stdin.fileno()):

try:

while loop_bool:

i,o,e = select.select([sys.stdin],[],[],1)

if i and i[0] == sys.stdin:

input = sys.stdin.read(1)

if input =='q':

switch = not switch

except KeyboardInterrupt:

loop_bool = False

或者你可能想要在较低级别(在一段时间内,或至少尝试)的块.

(PS,我将几行代码转换为等效但更简单的形式,以删除几个级别的嵌套.)

YMMV,但这是我的Mac测试:

Retina:test abarnert$python termtest.py

aaaa

aaaa

aaaa

qbbbb

bbbb

bbbb

qaaaa

aaaa

aaaa

^CRetina:test abarnert$

这让我觉得你可能想要关闭输入回声(由new_settings [3]& = ~termios.ECHO执行),这意味着您可能希望用更通用的东西替换decanonize函数,用于临时设置或清除任意termios标志. (另外,如果tcgetattr返回一个namedtuple而不是列表,那将是很好的,所以你可以使用new_settings.lflag而不是new_settings [3],或者至少为属性索引提供符号常量.)

同时,根据您的评论,听起来^ C仅在第一或第二秒内有效,并且它与连接中的超时有关.这是有道理的 – 主线程只是启动两个线程,两个连接(1)调用,然后完成.所以,2.启动后的几秒钟,它完成了所有的工作 – 并离开了try:block – 所以不再有任何方法让KeyboardInterrupt触发loop_bool = False并发出工作线程退出的信号.

我不确定为什么你首先会有关于连接的超时,以及当它们超时时会发生什么,但有三种可能性:

>你不想在^ C之前退出,并且超时没有任何正当理由.所以把它们拿出来.然后主线程将永远等待其他两个线程完成,并且它仍然在try块内,因此^ C应该能够设置loop_bool = False.>该应用程序应在2秒后正常退出. (我猜你会更喜欢这对线程上的单个join-any或join-all,并且有2秒的超时,但是因为Python没有任何简单的方法,所以你顺序加入了线程.)在这种情况下,您希望在超时结束后立即设置loop_bool = False.所以只需将except更改为finally.>超时总是应该足够慷慨(可能这只是你的真实应用程序的简化版本),如果你超过了超时,这是一个特例.之前的选项可能仍然有效,也可能无效.如果没有,请在两个线程上设置daemon = True,并且当主线程完成时它们将被杀死(不好被要求关闭). (请注意,它的工作方式在Windows与Unix上有点不同 – 尽管你可能并不关心这个应用程序的Windows.更重要的是,所有文档都说“整个Python程序退出时没有活着的非留下守护程序线程,“因此你不应指望任何守护程序线程能够进行任何清理,但也不应指望它们不进行任何清理.不要在守护程序线程中做任何可能留下临时文件的事情周围,​​关键的日志消息不成文,等)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值