Search code examples
pythonwhile-loopbreakpynput

Unable To Break Out Of While Loop When Using Pynput.mouse


I have this relatively simple program that listens for mouse clicks and when the mouse button is held down prints "1"s. Unfortunately when I let go of the mouse it just keeps printing "1"s, even though there is an if statement which checks if the mouse is clicked and should stop the loop if it is not. I am using the pynput.mouse module for the mouse interaction.

Here is my code:

import time
from pynput.mouse import Listener

def clicked(x, y, button, pressed):
    if pressed == True:
        while button == button.left:
            print("1")
            time.sleep(1)
            if pressed == False:
                break




with Listener(on_click=clicked) as listener:
    listener.join()

My theory is that once the loops starts it stops listening for mouse clicks, so it can never stop the loop. Would it be necessary to create a new thread for the loop? If yes, how would I do that?

Thanks!


Solution

  • Your current logic makes it impossible to get out of the loop, since pressed doesn't change within the loop. There is not a statement that checks if the mouse is clicked: your only if statements check whether the mouse was clicked when you entered the function. pressed doesn't change within the function.

    Look at the critical logiic:

    if pressed == True:
        while ...
            ...
            if pressed == False:
                break
    

    There is nothing in here to change the value of pressed; the first if guarantees that it's True anywhere within the loop.

    Yes, you need to set up another listener that operates within the loop. You already know the building blocks: create a new one within the function and bind it to another operation that breaks the loop. For instance, you might "cheat" and have it reset pressed as a global variable.

    You could also research how to do this in other answers, if you want an overall handler solution. keypress and keyrelease have been done often enough.