Multiple Hooks On/off

2 parts:

  1. how would one make a hook be able to turn on/off.

i created a script that works just as intended. It is saved in this folder path. When i start up Revit, the script is up and running. However, I’d like to be able to turn it have it turn on/off.

image

This is the first hook i created that did not use a pushbutton and I guess it is intended to run in the background.

  1. If i wanted to create more hooks, what would be the right folder structure. I can’t have multiple “hooks” folders since file explorer won’t let me.

Thanks in advance.

I think pyrevit may only register a single UpdaterId thats hard coded. You might be able to prefix the name like xxxx_doc-updater.py to get around the naming issue. It works that way with script.py and config.py so it worth a shot I guess but it may not be possible.

If you are planning on using multiple/complex updaters I highly recommend using C# instead. I’ve run into a few strange bugs and limitations, but its fine for learning and simple tasks.

but either way you need to get the UpdaterId and use this method to enable and this method to disable.

You can create ribbon buttons with on/off image to indicate the status when you enable/disable the updaters. I have not done this myself using pyrevit updater, only using C#.

Here’s a head start with the toggle image for the button. The PostCommand in my example is executing an external command in a dll to enable/disable, but you should be able to do in python as well.

def __selfinit__(script_cmp, ui_button_cmp, __rvt__):
    on_icon = script_cmp.get_bundle_file('on.png')
    off_icon = script_cmp.get_bundle_file('off.png')

def toggle_state():
    new_state = not script.get_envvar(*env_variable*)
    script.set_envvar(*env_variable*, new_state)
    script.toggle_icon(new_state)
    uiapp.PostCommand(UI.RevitCommandId.LookupCommandId("*CommandId*"))  

if __name__ == '__main__':
    toggle_state()

2024-09-23_07-22-27

3 Likes

Ooh nice. I was trying to find something like that but did not see it the pyrevit shortcuts:
https://pyrevit1.readthedocs.io/en/latest/commandbutton.html

do you know where in the pyRevit docs i could find out more about this?

The other I came across was a maybe using a json file to read true/false but in the doc-updater.

All the links related to pyrevit are centralized here

The main documentation being on notion.
Look for ‘bundles’ in that documentation and you will find plenty.

Thank you for sharing the link. I am finding plenty to play around with.

Hey @Rafael-Marquez ,

Were you able to do so? can i ask you to share your approach?
Currently struggling with the same thing.

Thanks!

@dickelsman TBH, i don’t recall what I was trying to do here, but whatever it was, I did not implement it. I simply have a doc-opened hook.

Either I found a different way of doing what I was trying to do (more than likely two pushbuttons as a toggle option at the time as an on/off approach) or simply didn’t do anything with this. Sorry for the bad news.

1 Like

No worries, if i find out what the solution is, i will post it on this thread :slight_smile:

2 Likes

So I tried multiple things and ended up with some sort of hybrid solution.

The main idea is execute a logic triggered on the DocumentSynchronizingWithCentralEvent:

  • have a smartbutton function as a toggle that is persistent over Revit sessions
    • If enabled actions should be executed on the document → icon should be orange
    • if disabled the actions should not be executed → icon should be original color
  • Regardless of the toggle being on or off, i want to manually execute this command anyway.

Session settings are remembered by modifying the user_config file. the buttonstate is switched using the .toggle_button() method.

So since executing the routine should be optional, I registring an eventlistener in the smartbutton itself which is created everytime the application starts, and the synchmonitor is enabled. I chose this over the official ‘hooks’ builtin functionality of PyRevit as it is more flexible and better ‘isolated’ to this button specifically.
This worked for the first time the event was fired, however after the first run of the script the eventlistener was disposed of for somehow. It took me too much time to figure out why and i could not get it to work..

So now i have the following setup working succesfully:

In a folder ‘hooks’ I have a doc-synching.py script, calling a routine from another subfolder in a .nobutton folder. This script is read as text and then executed. The smartbutton solely serves to set the user_config() to ‘enabled’ or ‘disabled’
I have a second pushbutton that calls the same script from the .nobutton subfolder, allowing me to force-run the routine always even-though the routine is disabled.

1 Like