I'm working on a programm where I need a user input for selection while not focused on the console window. The method I want to use is with keyboard inputs on the numpad. I've found this library Python keyboard lib to achieve this. My problem here is that it takes very long time for python to register the key press and gives a feel of poor performance. I need to know whether numpad 4 or numpad 6 is pressed for navigation. In the wiki of the lib was mentioned that you shouldn't use:
while True:
if keyboard.is_pressed('space'):
print('space was pressed!')
This will use 100% of your CPU and print the message many times.
So, this is my code:
print("Choose Attacker or Defender operator:")
print(" Attacker Defender")
att_state = False
def_state = False
while True:
if keyboard.read_key() == "4":
clear()
print("->Attacker Defender")
def_state = False
att_state = True
if keyboard.read_key() == "6":
clear()
print(" Attacker ->Defender")
att_state = False
def_state = True
if keyboard.read_key() == "5" and att_state:
clear()
printAllOp(attackers)
break
if keyboard.read_key() == "5" and def_state:
clear()
printAllOp(defenders)
break
selection = 0
while att_state:
if keyboard.read_key() == "4":
if selection > 0:
selection -= 1
clear()
printAllOp(attackers, selection)
if keyboard.read_key() == "6":
if selection < 31:
selection = 1
clear()
printAllOp(attackers, selection)
if keyboard.read_key() == "2":
if selection < 23:
selection = 7
clear()
printAllOp(attackers, selection)
if keyboard.read_key() == "8":
if selection > 6:
selection -= 7
clear()
printAllOp(attackers, selection)
if keyboard.read_key() == "5":
clear()
searchOp(attackers, selection, att_source)
att_state = False
break
I've also realized that the performance is different when using if and elif that's why everything is written with ifs for now.
CodePudding user response:
You can put microseconds or millisecond sleep for each while iteration, for 10 microseconds sleep,
import time
while True:
if keyboard.is_pressed('space'):
print('space was pressed!')
time.sleep(seconds/100000.0)
This should reduce your CPU usage hence, it should increase the overall performance.
Even better, use keyboard hooks like keyboard.on_press. That's the right way of doing it.
Additionally, if it is ok for you to bind to an OS (Windows or particular version of Linux distribution), you can compile your python as binary, which is very simple to do using PyInstaller.
CodePudding user response:
You should not be using keyboard.read_key()
at all, instead use keyboard.add_hotkey()
to register callbacks which modify a global state.
Example:
att_state = False
def_state = False
def set_state(new_state):
att_state = (new_state == 'att')
def_state = not att_state
# add code to update display
# Register callbacks for 4 and 6
keyboard.add_hotkey('4', lambda: set_state('att'))
keyboard.add_hotkey('6', lambda: set_state('def'))
# Process keystrokes until '5' is pressed
keyboard.wait(hotkey='5')
Note: I have never used this library and did not test this code (no Windows) so buyer beware :)