As a more “clean” example of the issue here is some more “code” that I’m not quite sure how to properly execute to test… but it shows the intent/workflow>
import bpy
import queue
from bpy.app.handlers import persistent
import threading
### Thread save queue for job list to run
execution_queue = queue.Queue()
### Test job
def makeUV():
bpy.ops.uv.smart_project()
### Get Job & run it
def executeInternalFastCommands():
while execution_queue.empty():
f = execution_queue.get()
f()# run all functions from queue
pass
### Make sure we call it every 0.05 seconds
def runInternal():
executeInternalFastCommands()
return 0.05
### Register timmer/function caller
@persistent
def load_handler(dummy):
bpy.app.timers.register(runInternal)
def register():
bpy.app.handlers.load_post.append(load_handler)
### Send job from Thread
def createTestActionInThread():
execution_queue.put(makeUV) # add job to queue that blender will run in its main thread
### Start thread and ask it to create a job for us
def testAction():
thread = threading.Thread(target=createTestActionInThread, name='Daemon')
thread.daemon = True
thread.start()
if __name__ == "__main__":
register()
testAction()