Revit Event Handler

It's time for advanced stuffs. Revit has many events that we can catch, such as closing / opening a document, activating a view, and so on. We can find a list of events on revitapidocks:

UIApplication: Link
ControlledApplication: Link

So we can tell revit to do something, when the event raises, the script should run in the background. Let's start with the simplest.

# -*- coding: UTF-8 -*-
#import Autodesk
#from Autodesk.Revit import DB   
#from Autodesk.Revit import UI
from pyrevit import DB
from pyrevit import UI
from pyrevit import HOST_APP, framework
from pyrevit import forms

__doc__='PostableCommand Enumeration'
__author__ = 'Dmytro Serebriian'

# define event handler
def docopen_eventhandler(sender, args):
    forms.alert('Document Opened: {}'.format(args.PathName))

# add the event handler function
HOST_APP.app.DocumentOpening += \
    framework.EventHandler[DB.Events.DocumentOpeningEventArgs](
        docopen_eventhandler
        )
print('ok') #just for checking

There are several ways to make it work. Create a startup.py file in the extensions directory and paste the code above:

Restart PyRevit, and you can now see the launcher console with the text "OK" printed. This means that everything should be fine. A warning message appears each time you open a project

What you can do with these events depends on your imagination!

The second method is more advanced. Download the full code from my githube page GitHube.

For example, I'll take the Sync Views script from the pyrevit tab.

When we press the script button, it changes the icon, and when you activate any view, it brings the screen to the same zoomstate as in the previous view. This means that each time the view is activated, the script is initiated. And we can turn on / off the event handler.

Let's try to understand this step by step.

We need to use the .smartbutton folder, not the .pushbutton folder for the script.py file. The smart button loads immediately when pyrevit is launched, and this allows us to initialize the event handler.

def __selfinit__(script_cmp, ui_button_cmp, __rvt__):
    try:
        __rvt__.ViewActivating += \
            framework.EventHandler[
                UI.Events.ViewActivatingEventArgs](copyzoomstate)
        __rvt__.ViewActivated += \
            framework.EventHandler[
                UI.Events.ViewActivatedEventArgs](applyzoomstate)
        return True
    except Exception:
        return False

You need to create a __selfinit__ function so the pyrevit smartbutton knows what you want to load from the start. Here we register 2 events. For ViewActivating(the script copy zoomstate) and for ViewActivated(the script applies zoomstate for activated view).

copyzoomstate and applyzoomstate are our functions where we write what to do.

Now we need to make it possible to turn on/off the eventhandlers. Here we need to understand what is the pyrevit environment variables link   p.4.5.

If you run the script below, you will see a console with all the existing variables:

# -*- coding: UTF-8 -*-
from pyrevit.coreutils import envvars
print(envvars.get_pyrevit_env_vars())

So we can, for example, create a variable and say if it's True, then run our script, if False - do nothing.

When we press the script button, the toggle function starts. 

SYNC_VIEW_ENV_VAR = 'TESTVIEW'

def togglestate():
    new_state = not script.get_envvar(SYNC_VIEW_ENV_VAR)
    if new_state:
        data_filename = get_data_filename(revit.doc)
        if os.path.exists(data_filename):
            os.remove(data_filename)
    script.set_envvar(SYNC_VIEW_ENV_VAR, new_state)
    script.toggle_icon(new_state)
    #print(script.get_envvar())

if __name__ == '__main__':
    togglestate()

Nothing special, if our variable is False, when we run the script, it changes to True.

script.toggle_icon(new_state) is a built-in pyrevit function, it changes the button icons. Just create 2 more icons in the script folder for different states:

Finally, the functions:

def copyzoomstate(sender, args):
    if script.get_envvar(SYNC_VIEW_ENV_VAR):
        forms.alert('view activating')

def applyzoomstate(sender, args):
    if script.get_envvar(SYNC_VIEW_ENV_VAR):
        forms.alert('view activated')

The event hadler anyway will run the function, but we can say to do further actions only if the environment variable has True value. 

That's all. Next time I'll talk about IUpdaters.

 

 

Post Comments(0)