Toggle (on/off) a key

935 views
Skip to first unread message

felix...@gmail.com

unread,
Feb 11, 2015, 8:38:02 AM2/11/15
to autoke...@googlegroups.com
Hi,

I would like to toggle a key with an on/off mode. It would be actually used in Minecraft for the sneak mode, instead of pressing the key, I would just have to click one time to sneak, click one time to remove.

I am kinda new to Python and AutoKey (just discovered it yesterday), and the script I have done is not working. I added some comments to tell you what I think my script is doing.

x = 1                              # infinite loop, to make the script work all
while x > 0:                       # the time I play Minecraft.
if store.has_key("v"):             # if the user press "v"
    key
= store.has_key("random")  # We change the stored key to make the programme work
   
while key != "v":              # while the key pressed is different from "v", we basically hold down
        keyboard
.press_key(v)      # the "v" key.
   
if store.has_key("v"):         # If the user press again "v", we stop holding down "v" key.
        keyboard
.release_key(v)

I don't think the store.set_value(key, value) and store.get_value(key) fonctions would be useful in my case, because if I understood well the API and the scripts examples, it stores a number and not a key. Furthermore, I use the "v" key also to chat in Minecraft (multiplayer), and I don't think it would be possible to do a counter. It would maybe be possible if I "desactivate" the counter and the script every time I press "t" (the key to chat in Minecraft), but it seems for me far away from my competance... What do you think?

I also set an hotkey (ctrl+e) to start the script.

I will keep working on it and tell you if I succeed.


Regards

Joe

unread,
Feb 12, 2015, 4:40:24 AM2/12/15
to autoke...@googlegroups.com
Welcome to the list and to AutoKey!

I know very little Python, so some of my ideas may be wrong. I also know
nothing about Minecraft.

Here goes anyway:

Rather than just trying to solve your problem, I'm going to "critique"
your code and mention a number of general issues that may be helpful to
consider
in any code you write.

TL;DR: Just skip to 7).

1) I think
while True:
would give you a cleaner test.
2) I believe that Python's block structure syntax demands that the code
beneath (within) the while be indented.
The way you have it *might* be an infinite empty loop.
3) With an infinite loop, you still need a way to terminate it (better
than just quitting AutoKey) - like typing another key and having it
break out of the loop.
4) What you have appears to be a very tight loop - which means it will
use a lot of resources spinning its wheels.
Whenever you do something like this, you should introduce some sort of
pause or delay like
import time
...
time.sleep(1.0) # to sleep 1 second

5) You probably shouldn't use a plain character to activate a macro -
especially one that already has a special meaning in the application
context. This is just asking for trouble (and, in your case, might even
cause some bizarre recursion to take place). That's why all the modifier
keys are available. Choose a key combination that doesn't do anything in
the native application (or in any other layers of software that may be
in play.) E.g. Assigning a macro to something like ALT+F4 would most
probably end up closing your application window when you press Alt+F4
because the window manager would act on it before AutoKey or your
application saw it.

6) Since all you want to do is toggle the state of whether the computer
thinks you're holding down the V key, you can use a saved variable that
is essentially Boolean.
It can have any two values. It doesn't matter what they are as long as
your code can tell them apart. True and False would be good values. They
make your logic very simple. (And I do believe saved variables can be
anything.)

> There are (at least) two ways to deal with persistent variables.
>
> 1) Within one macro:
> AutoKey has a way to store variables which are "local" to a specific
> macro, but are retained from invocation to invocation so you can
> preserve state information.
>
> If you go to
> https://code.google.com/p/autokey/wiki/SampleScripts
>
> and scroll down to Persistent Value, it shows how to use a persistent
> variable.
>
> 2) Within whatever scope you require:
> Since AutoKey macros are written in Python, you can take advantage of
> that to do almost anything you can think of. In this case, you could
> save variable information in environment variables or in regular files
> and read and write them from within your macros.
>
> This is pretty simple as long as you make sure you have only one thing
> reading and writing these at one time so the data you put there is
> what you get back when you read it and not something that got put
> there subsequently by another process.
7) So, after all that, I think all your macro has to do is see if the V
key is already being pressed (by examining the saved variable for the
value of True - after having initialized it as False). If it has been
pressed, then release it, set the saved variable to False and exit. If
it hasn't been pressed, (saved value is False), then press it, set the
saved value to True and exit.

But since holding down keys is a special kind of situation, I have no
idea if that would persist between macro calls.

Joe

On 02/11/2015 08:38 AM, felix...@gmail.com wrote:
> Hi,
>
> I would like to toggle a key with an on/off mode. It would be actually
> used in Minecraft for the sneak mode, instead of pressing the key, I
> would just have to click one time to sneak, click one time to remove.
>
> I am kinda new to Python and AutoKey (just discovered it yesterday),
> and the script I have done is not working. I added some comments to
> tell you what I think my script is doing.
>
> |
> x =1 # infinite loop, to make the script
> work all
> whilex >0: # the time I play Minecraft.
> ifstore.has_key("v"): # if the user press "v"
> key =store.has_key("random") # We change the stored key to make
> the programme work
> whilekey !="v": # while the key pressed is different
> from "v", we basically hold down
> keyboard.press_key(v) # the "v" key.
> ifstore.has_key("v"): # If the user press again "v", we
> stop holding down "v" key.
> keyboard.release_key(v)
> |
> ||||
> I don't think the |store.set_value(key, value) and
> ||store.get_value(key)||fonction|s would be useful in my case, because
> if I understood well the API and the scripts examples, it stores a
> number and not a key. Furthermore, I use the "v" key also to chat in
> Minecraft (multiplayer), and I don't think it would be possible to do
> a counter. It would maybe be possible if I "desactivate" the counter
> and the script every time I press "t" (the key to chat in Minecraft),
> but it seems for me far away from my competance... What do you think?
>
> I also set an hotkey (ctrl+e) to start the script.
>
> I will keep working on it and tell you if I succeed.
>
>
> Regards
>
> --
> You received this message because you are subscribed to the Google
> Groups "autokey-users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to autokey-user...@googlegroups.com
> <mailto:autokey-user...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.

felix...@gmail.com

unread,
Feb 12, 2015, 10:17:36 AM2/12/15
to autoke...@googlegroups.com
Hi, thanks a lot for your answer. First of all, I am writing from the Google interface, so I apologize if my code is/was not readable at all in your email client (if the HTML option is not enabled, I believe).

I will try to answer from what I understood.

1) I didn't know about "while True:". And I guess I could stop the script (or at least the loop) by adding a condition that would break the while loop if e.g. ctrl+e is pressed. I think I should us the store.has_key founction, but I don't see any documentation about it ( http://autokey.googlecode.com/svn/trunk/doc/scripting/lib.scripting.Store-class.html ), and I wonder if it can store/detect ctrl, alt, etc.

2) Indeed. I completly forget the "if store.has_key("v"):" line just after the while line.

3) See 1)

4) I see the point. I should put the delay in my loop I guess? Won't it delay too much my script?

5) You mean that I shouldn't use the V key to toggle on/off the V key? I see the point, if I start chatting I wouldn't have any problem if I press "v" (I should just break the loop before opening the chat, or I would have v spamming).

6) 7) I think I didn't understood at all. From all your post, there's what I did:

key = bool(0)
while True:
    time
.sleep(1.0)
   
if not store.has_key("v"):
        store
.set_value("v", loop(key+1))
        keyboard
.press_key("v")
   
elif store.has_key("v"):
        key
= bool(0)
        keyboard
.release_key("v")
   
elif store.has_key("<ctrl>+e"):
       
break
(If you can not see it well, take a look at: http://paste.awesom.eu/0DDP )

So I start my script with an hotkey set in AutoKey (ctrl + r), and if I want to stop it I press ctrl +e. Actually, I think I misunderstood your message, as far as it is not working, and as far as I don't understand the utility of the "True/False" boolean.

Regards

felix...@gmail.com

unread,
Feb 12, 2015, 10:20:49 AM2/12/15
to autoke...@googlegroups.com
A little edit: I had my head somewhere else when I wrote "loop(key+1)", it is obviously bool(key+1).

Joe

unread,
Feb 12, 2015, 6:15:05 PM2/12/15
to autoke...@googlegroups.com
Sounds like it's closer to right than it was. You left out one important
detail: Does your new script work?

As far as debugging it further, You'll need someone who knows more
Python and AutoKey details than I do.

1) I would put the time.sleep at the end of the loop so when it first
starts it works immediately - especially for a game.
The while loop has very little code in it (called a tight loop) so once
around it happens very quickly. This will make your computer spend most
of its time just processing your loop instead of doing all the other
things you need it to do. This can even make your computer completely or
mostly stall out. That's why you need a delay that puts the loop to
sleep for a short time so your computer can do something else. The
actual delay value should take into account how fast the condition
you're checking on can change and how fast you need to be able to
respond to it. One second was just a starting value so you would have
the correct syntax for it.

2) As far as 7) in the previous answer, I was thinking along the lines
of a simple toggle. When you execute your macro (the way I was thinking)
it would simply see if the thing you're controlling is on or off and
switch it to off or on respectively and exit - with no need for any loop
at all. But I don't know if something like that would work for holding a
key down.

3) I have no idea what you're doing with the store... stuff.
I would have done something like creating a variable such as v_on,
initialized as
v_on = False
and saved as a persistent value.
When your macro is called, I would do (in pseudocode - not valid Python
syntax)

if v_on undefined:
v_on = False

if v_on:
release the key
else:
press the key

v_on = NOT v_on

save v_on as a persistent value

exit the macro

Joe
> elifstore.has_key("<ctrl>+e"):
> break
> |
> (If you can not see it well, take a look at: http://paste.awesom.eu/0DDP )
>
> So I start my script with an hotkey set in AutoKey (ctrl + r), and if
> I want to stop it I press ctrl +e. Actually, I think I misunderstood
> your message, as far as it is not working, and as far as I don't
> understand the utility of the "True/False" boolean.
>
> Regards

felix...@gmail.com

unread,
Feb 13, 2015, 9:49:17 AM2/13/15
to autoke...@googlegroups.com
Well in my opinion the problem of a no-loop script would be that it would basically not hold the key down, because it would just check one time if the key is pressed (True). I mean, instead of holding the key for a long time (until the user press V), it would hold it just the time the script runs. At least, it is what I undertstand from http://autokey.googlecode.com/svn/trunk/doc/scripting/lib.scripting.Keyboard-class.html#press_key .
Even if we save v_on as a persistent value, I don't think the script will keep running by himself, and I wouldn't like to press my hotkey everytime...


> I have no idea what you're doing with the store... stuff
I think I misunderstand the store.has_key founction. I didn't find anything in the documentation, could you explain it a bit?
For me it is meant to check if the user pressed a certain key, or a string.
That's why I was using it, and for me I would have to use it also in your script, to check if the V key has been pressed or not (in order to set True or False value in the e.g. v_on variable).

Regards

(I will search for similar scripts in AutoHotKey to see the "algorithm", even if from what I saw the synthax looks not friendly)

Joe

unread,
Feb 13, 2015, 2:15:35 PM2/13/15
to autoke...@googlegroups.com
I suspect you're right about the keypress going away when the macro ends.

I only know a tiny bit of Python and very little about AutoKey
internals, so I can't help any further on the specifics. The two current
developers sometimes frequent this list. Maybe one of them will jump in
at some point.

Joe

On 02/13/2015 09:49 AM, felix...@gmail.com wrote:
> Well in my opinion the problem of a no-loop script would be that it
> would basically not hold the key down, because it would just check one
> time if the key is pressed (True). I mean, instead of holding the key
> for a long time (until the user press V), it would hold it just the
> time the script runs. At least, it is what I undertstand from
> http://autokey.googlecode.com/svn/trunk/doc/scripting/lib.scripting.Keyboard-class.html#press_key
> .
> Even if we save v_on as a persistent value, I don't think the script
> will keep running by himself, and I wouldn't like to press my hotkey
> everytime...
>
> > I have no idea what you're doing with the store... stuff
> I think I misunderstand the |store.has_keyfounction. I didn't find
> anything in the documentation, could you explain it a bit?
> For me it is meant to check if the user pressed a certain key, or a
> string. That's why I was using it, and for me I would have to use it
> also in your script, to check if the V key has been pressed or not (in
> order to set True or False value in the e.g. v_on variable).
>
> Regards
>
> (I will search for similar scripts in AutoHotKey to see the
> "algorithm", even if from what I saw the synthax looks not friendly)
> |

felix...@gmail.com

unread,
Feb 17, 2015, 2:14:19 PM2/17/15
to autoke...@googlegroups.com
Thanks again Joe!
Reply all
Reply to author
Forward
0 new messages