Problem with Creating a Toggle-able Auto-clicker

I’m attempting to create a project that allows me to toggle on and off and auto-clicker using the keyboard. I expected this to be quite easy to make, given that I can create a toggle easily, and I can detect key presses easily. For some reason I couldn’t get the code to work right, it can toggle to the clicking mode, but then I can’t turn it off. Thanks!

Here is my current code:

import keyboard
import time
from pynput.mouse import Button, Controller
toggle = False
variable = False

mouse = Controller()

while True:
    if keyboard.is_pressed('t'):
        variable = True
    else:
        variable = False
        
    if variable == True:
        if toggle == False:
            toggle = True
        elif toggle == True:
            toggle = False
    if toggle == True:
        mouse.click(Button.left, 1)
        time.sleep(0.01)        

I was able to get the code working, what I did was I put the code into a while loop, and each time I pressed ‘t’ it would reset.
Here’s my code

import keyboard
import time
from pynput.mouse import Button, Controller
toggle = False
variable = False

mouse = Controller()
while True:
    toggle = False
    while True:
        if keyboard.is_pressed('tab'):
            variable = True
        else:
            variable = False

        if variable == True:
            toggle^=True
    
        if toggle == True:
            mouse.click(Button.left, 1)
            time.sleep(0.01)        
        print(toggle)
        if keyboard.is_pressed('t'):
            break

After trying the code out, it doesn’t really work for me, I was wondering if there is a way to create a toggle using a single key rather than having a “turn off” and a “turn on” key? Thanks!

Some remarks inline below:

while True:
toggle = False

Don’t do that! It resets the toggle at the top of the loop. You only
want toggle to change when you press ‘t’ (or ‘tab’, it was ‘t’ before).
So don’t tread on it here.

On, you’ve got 2 loops. Why?

while True:
if keyboard.is_pressed(‘tab’):
variable = True
else:
variable = False

You can just write:

variable = keyboard.is_pressed('tab')
   if variable == True:

This is better written:

if variable:
       toggle^=True

This is better written:

toggle = not toggle

The “^” operator is a bitwise operator - it is a numeric operation, not
a logical one. You really want the logical “not” operator as above. The
“^” works because Booleans are actually implemented as a type of int,
but it is normally a poor way to think about them.

   if toggle == True:

Again:

if toggle:
       mouse.click(Button.left, 1)
       time.sleep(0.01)

This clicks the button every time toggle is true. You you wantually
want your toggle to activate a “clock madly indefinitely” mode?

   print(toggle)
   if keyboard.is_pressed('t'):
       break

I’m wondering if this is the start/stop thing you allude to in your next
post?

What does “keyboard.is_pressed” measure? That someone typed a ‘t’, or
that the ‘t’ key is currently held down? It affects how the code behaves
for you.

Also, please pick a better name than “variable”. Pick a name which
expresses what the variable means. It makes debugging much easier
because the logic is clearer in the code.

I’m trying to understand your inner loop, and that depends on what
“keyboard.is_pressed” measures. Do you want do something while ‘t’ is
held down, stopping when it is not? Or do you want want act when the ‘t’
key is pressed, once?

Cheers,
Cameron Simpson cs@cskk.id.au

Thanks for the feedback!
Regarding your comment on the bottom, I would like this to turn on once I press a key, and turn off when I press the same key again. The code in my second post didn’t achieve that because you had to press ‘t’ to turn it on, and the tab button to turn it off.

When I run your code, the same thing happens as I described in my first post: I can turn on the autoclicker, but it doesn’t turn off. It doesn’t seem to be a problem with the code, because I see no reason that the program wouldn’t work. Assuming that the code is correct, could it be a problem with Terminal? (I’m running this program on Terminal)

Thanks!

So “toggle” in a sense is a Boolean representing: run “this” (which is
what, precisely?). Pressing the key toggles “toggle”.

So your nested while-loops are:

  • run forever
  • then toggle goes true, run a special loop?

Might you not be better off with something shaped like this (untested)?

toggle = False
while True:
    if keyboard.is_pressed('t'):
        toggle = not toggle
    if toggle:
        mouse.click(Button.left, 1)
    time.sleep(0.01)

Can you post your current most-working code with comments about what
behaviour you see, versus what you’d like to see?

When you say terminal, do you mean the Mac Terminal emulator? or
something else?

Cheers,
Cameron Simpson cs@cskk.id.au

Thanks! The code you posted works great!
In my previous code when I pressed ‘t’ it would turn on the autoclicker, but when I tried to turn it off, the program would switch it to false for one rotation, before going right back to true. And yes, I’m running this on the Mac Terminal.

Thanks! The code you posted works great!

Glad to hear it.

What you’ve got there is a crude version of a common interactive thing:
the event loop. Many GUIs and other interactive things run that way:

  • a loop while runs forever, to respond to events
  • code at the top of the loop to process events
  • code to run regular activity - in your case, to autoclock the mouse if
    “toggle” is true
  • a short delay, which might be conditional on not having seenany
    events, depending on what drives them; this prevents your programme
    spinning flat out, using as much CPU as is available while doing no
    real work

For you, you’re only interested in one, but in a real app there might be
a lot of this - the usual setup “registers” events, so that you don’t
write the loop itself - instead it processes all events and if you’ve
registered a handler for an event, your handler gets calls. For example,
you might register a handler for the ‘t’ keypress which runs a function
to toggle your state variable.

In my previous code when I pressed ‘t’ it would turn on the autoclicker, but when I tried to turn it off, the program would switch it to false for one rotation, before going right back to true.

Do you see the logic flow and how it differs from your previous code?
You’ll find it helpful to figure these differences out.

And yes, I’m running this on the Mac Terminal.

Ok, so a keypress is likely a just typing ‘t’. In a GUI framework you
might have distinct events you can handle for key up and key down and
“the key”, often fired on “key up”. On a terminal you just get to see
bytes representing keys, and normally the button press and release is
not apparent there.

Cheers,
Cameron Simpson cs@cskk.id.au