如何用Python的pynput实现函数重复执行直至按下指定按键?
Solution Using
pynput for macOS Mojave (Python 3.9) Got it, let's get this working for you! Since the keyboard library isn't playing nice on your macOS Mojave setup, pynput is a reliable alternative that should handle key detection perfectly. Here's a step-by-step implementation that matches your desired logic:
Step 1: Install pynput
First, make sure you have the library installed (if you haven't already):
pip install pynput
Step 2: Full Implementation Code
This code will run your function() in a loop and exit as soon as you press the q key:
from pynput.keyboard import Listener import time # Flag to track if we need to stop the loop stop_loop = False def function(): # Replace this with your actual function logic print("Executing your function...") time.sleep(0.5) # Simulate work - remove this in your real code def check_for_q(key): global stop_loop try: # Trigger stop when 'q' is pressed if key.char == 'q': stop_loop = True return False # Stop the listener thread except AttributeError: # Ignore special keys like Shift/Ctrl - we only care about 'q' pass if __name__ == "__main__": # Start the key listener in a background thread listener = Listener(on_press=check_for_q) listener.start() # Run your function on loop until 'q' is pressed while not stop_loop: function() # Clean up the listener listener.join() print("Loop exited successfully after pressing 'q'!")
Key Notes for macOS
- Permissions: When you run this script for the first time, macOS will prompt you to grant input monitoring access to Python. Go to System Preferences > Security & Privacy > Privacy > Input Monitoring and check the box next to your Python interpreter to allow this. Without this permission,
pynputcan't detect key presses. - Non-blocking: The key listener runs in a separate thread, so your
function()will keep running smoothly without being interrupted by key checks.
Alternative: Cleaner Approach Without Global Variables
If you want to avoid global variables (a better practice for larger scripts), you can use a class to encapsulate the state:
from pynput.keyboard import Listener import time class LoopController: def __init__(self): self.stop_loop = False def function(self): print("Executing your function...") time.sleep(0.5) def check_for_q(self, key): try: if key.char == 'q': self.stop_loop = True return False except AttributeError: pass def run(self): listener = Listener(on_press=self.check_for_q) listener.start() while not self.stop_loop: self.function() listener.join() print("Loop exited!") if __name__ == "__main__": controller = LoopController() controller.run()
This works exactly the same way but keeps your state organized in a class instead of using globals.
内容的提问来源于stack exchange,提问作者Raz P
相关产品推荐
相关产品推荐

