简体   繁体   English

在程序运行时按下任意键时停止 python 程序

[英]Stopping a python program when an arbitrary key was pressed while the program is running

I recently got to know about the python module signal.我最近了解了 python 模块信号。 With that, we can capture a SIGINT and do what we want after capturing it.有了它,我们可以捕获一个 SIGINT 并在捕获它之后做我们想做的事情。 I used it as below.我使用它如下。 In that case I am just using SIGINT to print that program is going to be stopped and stop the program.在那种情况下,我只是使用 SIGINT 来打印该程序将被停止并停止该程序。

import signal  
import os
import time

def signalHandler(signalnumb, frame):  
    print("Signal Number:", signalnumb, " Frame: ", frame)
    print('Exiting the program...')
    os._exit(0)
 
signal.signal(signal.SIGINT, signalHandler)
 
c=0
# Loop infinite times using the while(1) which is always true
while 1:
    print(c)
    #sleep for 1 seconds using the sleep() function in time 
    time.sleep(1)
    c=c+1

Now I want to give any signal from keyboard(for example pressing 'q') and as soon as signal was recieved, the python program should be stopped.现在我想从键盘发出任何信号(例如按“q”),一旦收到信号,python 程序就应该停止。 Has anyone got some experience on how to do that?有没有人有一些经验如何做到这一点? Any other method rather than using signal module (for example using multithreading) is accepted.接受任何其他方法而不是使用信号模块(例如使用多线程)。

Edit1- Later I tried to use pynput module as suggested in one of a similar kind of question. Edit1- 后来我尝试使用类似问题之一中建议的 pynput 模块。 For sure I have done a mistake.我肯定做错了。 It doesn't work as I expected.它不像我预期的那样工作。 It means with a key press, I couldn't stop the for loop from running.这意味着通过按键,我无法停止 for 循环的运行。

from pynput import keyboard
import time

def on_press(key):
    for i in range(100):
        print(i)
        time.sleep(1)
        if key == keyboard.Key.esc:
            return False  # stop listener
        try:
            k = key.char  # single-char keys
        except:
            k = key.name  # other keys
        if k in ['1', '2', 'left', 'right']:  # keys of interest
            # self.keys.append(k)  # store it in global-like variable
            print('Key pressed: ' + k)
            return False  # stop listener; remove this if want more keys

listener = keyboard.Listener(on_press=on_press)
listener.start()  # start to listen on a separate thread
listener.join()  # remove if main thread is polling self.keyspython

Can someone point out how to do it using pynput in correct way?有人可以指出如何以正确的方式使用 pynput 吗?

This was my original implementation:这是我最初的实现:

a = input('Press a key to exit')
if a:
    exit(0)

However, it seems that you need a piece of code that will allow for any key to be clicked and immediately exit out of the program, without hitting enter afterwards.但是,您似乎需要一段代码来允许单击任何键并立即退出程序,而无需随后按 Enter。 This may be a better way to do that:这可能是一个更好的方法:

import readchar
print("Press Any Key To Exit")
k = readchar.readchar()

Hope this helps!希望这可以帮助!

After carefully understanding about the threads and pynput module, I managed to stop a for loop (or any program which runs as a separate thread) using a key press callback.在仔细了解线程和 pynput 模块后,我设法使用按键回调停止了 for 循环(或任何作为单独线程运行的程序)。

from pynput import keyboard
import os
import threading
import time

loop_running = False

def on_press(key):
    print(dir(key))
    global loop_running
    #if key == keyboard.Key.delete and not loop_running:
    if ('char' in dir(key)) and (key.char == 's') and (not loop_running):
        t=threading.Thread(target=start_loop)
        t.start()
        
    #elif key==keyboard.Key.tab:   #if this is used, the attributes related to 'key' will be changed. you can see them since I have used a print(dir(key))
    elif key.char == 'q':
        loop_running=False
        

def start_loop():
    global loop_running
    loop_running = True
    for i in range(100):
        if not loop_running:
            os._exit(0)                          
            
        print(i)
        time.sleep(1)
        
with keyboard.Listener(on_press=on_press) as listner:
    listner.join()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM