1
$\begingroup$

In my add-on __init__.py file, I have a function defined def unregister(): which unregisters all other modules. But when I exit Blender normally (Windows 10, X button), this function is never called.

Edit Note: This is normal behavior - see answer

Is there something that needs to be done before Blender executes unregister() on exit? Or perhaps some error in my add-on may be causing this behavior? I get no warnings or errors. Only two lines print out on exit:

Saved session recovery to 'C:\Users\Moats\AppData\Local\Temp\quit.blend'
Blender quit

Maybe this is normal? Blender is saying - its over, so it doesn't matter? One other unlikely possibility is that print() doesn't function after a certain exit point. I can probably confirm this, but not easily.

If anyone knows what might be happening, or can confirm that their own unregister() is being called on exit, I'd really appreciate it.

$\endgroup$
3
  • 1
    $\begingroup$ The unregister() function is only called when you deactivate the add-on in your preferences, as far as I'm aware. Add-ons that store settings in the preferences commonly remove them when unregister() is called. It would be very inconvenient if that was the case whenever Blender is closed. For an example see the add-on in this answer blender.stackexchange.com/questions/153022/… $\endgroup$ – Robert Gützkow Sep 18 '19 at 13:21
  • $\begingroup$ Yeah, I'm still finding my way around in this area. I assumed register() was a sort of activation area, and 'unregister()' was the exit point of that activation. I just assumed all add-ons would be deactivated before Blender shuts down. I've noticed several add-ons doing this, so it must be a common assumption (unless they were only trying to clean up for add-on toggling). So then it would be unwise to try to initialize in register() and clean up in unregister()? Such as, for example, to flush some file buffers on exit (random example). Where would be the best place to do this? $\endgroup$ – Robert Sep 18 '19 at 18:49
  • 1
    $\begingroup$ The add-ons unregister the classes that they have registered and delete types that they have created. They shouldn't do anything that needs to be executed when Blender terminates (because the unregister() function doesn't get called when that happends). If anything needs to run when Blender closes you would use atexit. $\endgroup$ – Robert Gützkow Sep 18 '19 at 20:09
4
$\begingroup$

The unregister() function is only called when you deactivate the add-on in your preferences, while register() is always called when Blender starts in case the add-on is activated in the preferences. You can test this with the following simple add-on that writes into a text file whenever one of the functions is executed. The example also includes how to add a handler that is triggered when Blender is exiting.

This add-on tries to write the test file into Blender's install directory. If that directory requires special permissions, then you should adjust the path to somewhere it can write the file to.

bl_info = {
    "name": "Register and unregister test",
    "author": "Robert Guetzkow",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "Dummy panel in View3D",
    "description": "Check when register and unregister are called",
    "warning": "",
    "wiki_url": "",
    "category": "3D View"}

import bpy
import atexit


class EXAMPLE_PT_panel(bpy.types.Panel):
    bl_label = "My own addon"
    bl_category = "Name of your tab"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    def draw(self, context):
        layout = self.layout
        layout.label(text="This is a label")


classes = (EXAMPLE_PT_panel,)


def exit_handler():
    with open("test.txt", "a") as myfile:
        myfile.write("exiting\n")

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    with open("test.txt", "a") as myfile:
        myfile.write("register\n")
    atexit.register(exit_handler)


def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    with open("test.txt", "a") as myfile:
        myfile.write("unregister\n")


if __name__ == "__main__":
    register()
$\endgroup$
3
  • $\begingroup$ Extremely helpful, thank you. I was not able to find atexit in the manuals. I'm assuming that Is a python level event? Do you happen to know in what order it would call the event handler? Or rather, at what point in Blender's shutdown sequence exit_handler() would be called? I can probably figure this out with print() tracking, but if you have any experience using it, I appreciate any details. Anyway, thanks for this detailed example. It shows exactly how to use it. $\endgroup$ – Robert Sep 18 '19 at 20:20
  • 1
    $\begingroup$ It's a Python feature which is run when/before the interpreter is terminated. docs.python.org/3/library/atexit.html blender.stackexchange.com/questions/48565/… $\endgroup$ – Robert Gützkow Sep 18 '19 at 20:22
  • $\begingroup$ My bad - I tried to find something like this, but apparently didn't use great search terms. Thanks again. Huge help. $\endgroup$ – Robert Sep 18 '19 at 22:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.