Search code examples
pythonrevit-apipyrevit

Can't unsubscribe from an event in Revit


I'm trying to set up the UI to automatically clear elements when I subscribe to an event DialogBoxShowing. I can't unsubscribe from it and the replacement of user actions continues even when the code isn't executing.

I don't have enough experience to find the error. Maybe someone has encountered this. Thank you in advance!

def call_purge():

    def import_replacement(sender, args):

        print('5')
        print(type(args))

        if args.DialogId == 'Dialog_Revit_PurgeUnusedTree':
                args.OverrideResult(1)

    """Call Revit "Purge Unused" after completion."""
    # commandId = \
    #     UI.RevitCommandId.LookupPostableCommandId(
    #         UI.PostableCommand.PurgeUnused
    #         )

    commandId = UI.RevitCommandId.LookupCommandId("ID_PURGE_UNUSED")


    try:
        __revit__.DialogBoxShowing += framework.EventHandler[UI.Events.DialogBoxShowingEventArgs](import_replacement)
        __revit__.PostCommand(commandId)
        __revit__.DialogBoxShowing -= framework.EventHandler[UI.Events.DialogBoxShowingEventArgs](import_replacement) 
    except:
        print(traceback.format_exc())

        
if __name__ == '__main__':
    call_purge()
    print('-' * 50)
    print('Script is finished.')

I found a method in the articles where these functions were separated into a separate class, but this also did not work


Solution

  • I see a problem in your logic. PostCommand queues a command for execution after the current external command has terminated. You call both DialogBoxShowing += and DialogBoxShowing -= in the same external command. So, both of them are executed before the external command has terminates, and hence before the command queued for execution gets a chance to run. So, I would assume that they will not have any effect at all.

    One clean way to address this, at least in theory, would be to implement three external commands. One to call DialogBoxShowing +=, let's say D1, another for DialogBoxShowing -=, D2, and a third top-level one that makes three calls to PostCommand:

    • PostCommand(D1)
    • PostCommand(commandId)
    • PostCommand(D2)

    ... in the hope that the sequence in which you called PostCommand also determines the order of execution. I would assume that is the case, but there is probably no guarantee given for that.