How can I run an operator right at the addon register function? The operator’s context will be very generic not for scene or object, more like to window manager or at a similar level.
There should be a way the operator is called, perhaps the window manager itself can do it? I still try to find how to do it, if you have any ideas please drop a comment, thanks.
CoDEmanX I have looked into your suggestion about using a scene handler and no more no less I went for Python’s task scheduling instead since it looks more straight forward. https://docs.python.org/2/library/sched.html
Now I change again my code to support this new way of invoking the operator and it works fine.
bl_info = {
"name": "Test",
"category": "Development"
}
import bpy
import time
from threading import Timer
def pseudo_operator():
print("Operator runs ", time.time())
# Surpisingly this works!!!
bpy.ops.wm.test_operator()
# This also works: access to scene context
print(bpy.context.scene)
class TestOperator(bpy.types.Operator):
bl_idname = "wm.test_operator"
bl_label = "Test Operator"
def execute(self, context):
print("Hello from test operator")
return {'FINISHED'}
def register():
bpy.utils.register_module(__name__)
# addon = bpy.context.user_preferences.addons[__name__]
# This line here fails due to invalid context:
# bpy.ops.wm.test_operator()
# This line here fails due to invalid context:
# print(bpy.context.scene)
Timer(1, pseudo_operator, ()).start()
def unregister():
bpy.utils.unregister_module(__name__)
It is a a bit odd to use this hack, but if it is a valid and safe practice then I guess that everything should be fine. :yes: Any comments about it?
EDIT: From what I found, it’s that the context while the register function is called, does not contain the full context set (such as scene, e.t.c.), it is specifically dedicated to addons.
If you want to check OS things, why do you want these checks to be wrapped in an operator? Why not call a regular python function and store the results e.g. in a global variable?
The “official” would be to check OS or that kinda things during each operator execution, so within the execute() method. Using a global function and some kind of cache can make it more efficient, i.e. remember the results of the first run and don’t do all the probing again.
The user would have to run operator normally, though if Blender do it automatically is just an additional benefit for me to to enhance usability.
But apart from operator itself (say that I won’t use it), I will still need access to scene properties so this also brings another roadblock. It’s only that this exact register() function is very strict and it’s context is limited.
P.S. Your initial suggestion with a app handler called only once, seems solid and won’t get out of Blender’s guidelines.