While building a script that can be toggled to spam, I encountered the following problem.
First is the normal functioning version of the script:
import keyboard
import threading
def spam_this():
status = 0
while True:
if keyboard.is_pressed("F9") and status == 0:
status = 1
event.wait(1)
if keyboard.is_pressed("F9") and status == 1:
status = 0
event.wait(1)
while status == 1:
if keyboard.is_pressed("F9") and status == 1:
status = 0
event.wait(1)
print("test")
event = threading.Event()
threading.Thread(target=spam_this).start()
The script above works perfectly. However, when I change the line print("test")
to keyboard.write("test")
, the script breaks.
import keyboard
import threading
def spam_this():
status = 0
while True:
if keyboard.is_pressed("F9") and status == 0:
status = 1
event.wait(1)
if keyboard.is_pressed("F9") and status == 1:
status = 0
event.wait(1)
while status == 1:
if keyboard.is_pressed("F9") and status == 1:
status = 0
event.wait(1)
keyboard.write("test")
event = threading.Event()
threading.Thread(target=spam_this).start()
This version of the script with the keyboard.write()
function can be initiated with the implemented toggle key "F9", but when I try to toggle off the switch by pressing "F9" again, it does not stop like the print("test")
version of itself.
Note: I am not sure how to word this problem in the title. I use the term "blocked" because the effect is similar to what blocking method like time.sleep()
would do when trying to create a while True:
loop with a toggle.
import threading
import keyboard
# global variable
status = False
def spam_this():
print('start: spam_this')
while True:
if status is True:
print("test")
keyboard.write("test")
event.wait(0.1)
def test(event=None):
global status
status = not status
print('change:', status)
event = threading.Event()
keyboard.add_hotkey("F9", test)
#alternatively:
#keyboard.on_key_press("F9", test)
threading.Thread(target=spam_this).start()
there are a few modifications that has been made to @furas's answers.
for the test
function, a parameter event=None
was added, otherwise the keyboard.on_press_key
will pass the F9
key-pressed-event to the test function, which results in a typeError
.
in the test
function, the event.wait()
was removed due to an error, and upon testing, the keyboard.on_press_key
and keyboard.add_hotkey
function does have inbuilt delays, so as long as the F9
key was not HELD down, the inbuilt delays are more than enough.
regardless of whether using on_key_press
or add_hotkey
, the thread should be initialized AFTER the desired "hotkey method" is called. otherwise the thread will block the main loop of the python script.(this part I cannot explain why, it was just trial and error leading to this conclusion.)
the keyboard.wait()
was removed, because this function was not used.
NUMBER 1 and 3 ARE THE MOST IMPORTANT CHANGES (for the people who doesn't want to read through the minor bits)