0

I want to have a loop running that will print "Hello" and when I press "K" it stops printing but it doesn't end the program, then when I press "K" again it starts printing again.

I tried this(using the keyboard module):

import keyboard

running = True

while running == True:
    print("hello")
    if keyboard.is_pressed("k"):
        if running == True:
            running = False
        else:
            running = True

but when I press the button it just ends the program and that's not what I'm trying to do. I understand why it ends but I don't know how to make it not end. How can I do that?

6 Answers6

2
import keyboard

running = True
display = True
block = False

while running:
    if keyboard.is_pressed("k"):
        if block == False:
            display = not display
            block = True
    else:
        block = False
    if display:
        print("hello")
    else:
        print("not")
IzZy
  • 364
  • 3
  • 16
  • Thank you. I just changed: `else: print("not")` to: `else: pass` and it's working as intended. Thank you again. – MentalCombination Aug 19 '20 at 11:55
  • hahah, I did that for my usage and forget about that :D – IzZy Aug 19 '20 at 11:56
  • Please note that, if you add print("stop/start") in Adrian Melon's program, you can see his program prints several time "hello" after 'k' is pressed until the buffer will be empty.You must empty the buffer, you can examine my answer. – rouhollah ghasempour Aug 19 '20 at 18:10
  • @rouhollahghasempour are you sure? If I understand correctly, you will see this "several time "hello"" until you stop pushing 'k' button, method only check if key is pressed at the moment of its call. Don't you put `print("stop/start")` in a wrong place? – IzZy Aug 19 '20 at 18:46
  • @adrianmelon yes I ran my program and your program and you can check both of them. I put print("stop/start") in the line that is executed after the 'k' is pressed. The problem rises as keyboard.is_pressed does not empty the buffer. As, the keys have two bytes, we need to read two bytes by doit = msvcrt.getch().decode('utf-8'). – rouhollah ghasempour Aug 19 '20 at 18:58
  • I don't understand problem. Could you give example of console output, which shows problem with buffer? – IzZy Aug 19 '20 at 19:11
  • @adrianmelon I put the output of both codes. please check it. – rouhollah ghasempour Aug 19 '20 at 19:24
1

Maybe something like that:

import keyboard

running = True
stop = False

while !stop:

    if keyboard.is_pressed("k"):
        running = !running          # Stops "hello" while
    if keyboard.is_pressed("q"):
        stop = !stop                # Stops general while

    if running:

        print("hello")

ThRnk
  • 575
  • 2
  • 19
1

You could use a handler for the keypress, which sets an event that the main thread can then test for periodically, and wait if required.

(Note that there are two types of events here, the keypress event and the setting of the running, so these should not be confused.)

from threading import Event
from time import sleep
import keyboard

hotkey = 'k'

running = Event()
running.set()  # at the start, it is running

def handle_key_event(event):
    if event.event_type == 'down':
        # toggle value of 'running'
        if running.is_set():
            running.clear()
        else:
            running.set()

# make it so that handle_key_event is called when k is pressed; this will 
# be in a separate thread from the main execution
keyboard.hook_key(hotkey, handle_key_event)

while True:
    if not running.is_set():
        running.wait()  # wait until running is set
    sleep(0.1)        
    print('hello')
alani
  • 12,573
  • 2
  • 13
  • 23
0
import sys
import keyboard
from time import sleep

running = True

while running:
    if keyboard.is_pressed("k"):
        sleep(1)
    elif keyboard.is_presed('Esc'):
        sys.exit()
    else:
        print("hello")

I didnt test it, so please give me feedback

MercifulSory
  • 337
  • 1
  • 14
  • It stops printing while I'm holding down "k", when I let go it waits 1 second and it starts printing again. What I'm trying to do is have the button "k" as a switch. – MentalCombination Aug 19 '20 at 11:22
0

I think the right way is flushing the buffer, because the previous solutions may print more. This works for windows, for Linux, you should refer to Python read a single character from the user


import time
import subprocess
import sys
import msvcrt

printing = True
while (1):
    # Try to flush the buffer
    while not msvcrt.kbhit() and printing:
        print("hello")

    doit = msvcrt.getch().decode('utf-8')
    if doit=="k":
        printing = not printing
        print("stop/start")
    if doit == 'q':
        break

This is the output of this code: enter image description here Please note that, if you add print("stop/start") in Adrian Melon's program, you can see his program prints several time "hello" after 'k' is pressed until the buffer will be empty.

    import keyboard

    running = True
    display = True
    block = False

    while running:
        if keyboard.is_pressed("k"):
            print("stop/start")
            if block == False:
                display = not display
                block = True
        else:
            block = False
        if display:
            print("hello")
        else:
            pass

This is the output of @Adrian-Melon program: enter image description here

  • I'm not sure about the problem you mean, but cloudn't you write line `print("stop/start")` after my `display = not display` to improve comparability of our codes? In your code this line is after analogous `printing = not printing`. – IzZy Aug 19 '20 at 19:52
  • print("stop/start") is executed after 'k' is pressed (a key is pressed and that key is 'k'). the 'block' variable is your own that is not related to 'k' is pressed. Please see https://stackoverflow.com/questions/510357/python-read-a-single-character-from-the-user. We should stop this discussion. Good luck. – rouhollah ghasempour Aug 19 '20 at 20:08
  • `block` is necessary to use `k` button as toggle switch, without it `k` would toggle print condition every loop pass. In my code pressing `k` is not sufficient condition to toggle `display` variable, opposite to your solution. Your `stop/start` should be after toggle condition to make sense. I think you misunderstood my code, but I agree that it is enough discussion about that. Have a nice day! – IzZy Aug 19 '20 at 20:25
0
import keyboard

running = True
display = True
block = False

while running:
    if keyboard.is_pressed("space"):
        if block == False:
            display = not display
            block = True
    else:
        block = False
    if display:
        print("hello")
    else:
        input("Press Enter to continue...")
        if block == False:
            display = not display
            block = True

You can use this to stop and start again.

E.MRZ
  • 71
  • 1
  • 7
  • I am sure it would help the community if you explained to us why and how you code would solve the OP's problem – Simas Joneliunas Jan 12 '22 at 11:25
  • When I ran the code given by IzZy, it didn't stop printing, it just continued to print "not", so I made this code smoother in my own project. My code works like this: We press the "Space" key to stop the printing loop, then if we want to continue our code again, we press the "Enter" key and our printing loop continues. This code worked for me. @SimasJoneliunas – E.MRZ Jan 12 '22 at 18:03