-1

I was trying to make a while loop which would stop running when a specific key is pressed. The problem is that the loop runs infinitely. My loop:

import time
import keyboard

while (not keyboard.is_pressed("esc")):
    print("in loop...")
    time.sleep(2)

I am using the keyboard module. What is wrong with my loop and how can I fix it? (I don't really want to use a Repeat-until or equivalent loop in Python thing in this case.)

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Jermartyno
  • 43
  • 1
  • 7
  • Hi, this runs fine on ubuntu 20.04 – Stubborn Mar 06 '22 at 09:25
  • @Stubborn Okay so I tested it. It works but not as I wanted. It only detects the press when you time it perfectly (the moment from the last line of loop to its first line). `import keyboard import time while (not keyboard.is_pressed("esc")): print("in the loop") time.sleep(2) print("out of the loop")` You can see what I mean here ^ – Jermartyno Mar 06 '22 at 09:54
  • It runs fine on Windows 10 – Francis King Mar 06 '22 at 10:02
  • @FrancisKing after testing it, I found out that it works, but not as I wanted it to work (try using the code above). You can only break out of the loop in a specific moment - not always. What I wanted to achieve is to make a loop which would always break regardless of its completion state (you can break out of it at any time). – Jermartyno Mar 06 '22 at 10:11

2 Answers2

1

Here is a solution which works:

import keyboard
import time
import threading

class main:
    def __init__(self):
        # Create a run variable
        self.run = True

        # Start main thread and the break thread
        self.mainThread = threading.Thread(target=self.main)
        self.breakThread = threading.Thread(target=self.breakThread)

        self.mainThread.start()
        self.breakThread.start()

    def breakThread(self):
        print('Break thread runs')
        # Check if run = True
        while True and self.run == True:
            if keyboard.is_pressed('esc'):
                self.newFunction()

    def main(self):
        print('Main thread runs')
        
        # Also check if run = True   
        while not keyboard.is_pressed('esc') and self.run:
            print('test')
            time.sleep(2)
            
            # Break like this
            if keyboard.is_pressed('esc'):
                break

            print('test')
            time.sleep(2)

    def newFunction(self):
        self.run = False
        print('You are in the new function!')

program = main()
cmcnphp
  • 400
  • 1
  • 4
  • 14
Tom
  • 486
  • 1
  • 2
  • 11
-1

You don't need brackets in while loops, here is my code:

import keyboard

# You need no brackets
while not keyboard.is_pressed('esc'):
    print('test')
Tom
  • 486
  • 1
  • 2
  • 11
  • It works fine because there isn't much wait related code inside of the loop. However if I wanted to add some waits (see the comment above), you would see that it does only break in a specific time (I wanted my loop to break regardless of the completion state of the loop). – Jermartyno Mar 06 '22 at 10:02
  • 1
    If you have pauses in the loop, you have to press the key as long as you have a pause, unless you catch exactly the point where the loop ends. It is only ever queried whether the key was pressed when the loop starts from the beginning. I hope that helps :). – Tom Mar 06 '22 at 10:12
  • Is there any method (like creating multiple threads) that would achieve what I want? Is the method efficient? – Jermartyno Mar 06 '22 at 10:16
  • You could query several times in the while loop if the key was pressed with if, otherwise it should also work with threads. But I would have to test it first. – Tom Mar 06 '22 at 10:19
  • The brackets are not necessary but they also don't change anything. They are surely not the cause of any problem and since you already posted another answer, please delete this one... – Tomerikoo Mar 06 '22 at 10:45