I’m not sure if this is even possible but I’m working on a menu.py script for SG-integerated Nuke.
So far I’m able to tell that I can import sgtk and get the current engine but after that it seems to not work.
If I make a call like this, it will crash the Nuke startup:
engine = sgtk.platform.current_engine()
project = engine.context.project
Yet if I make that same call in the Nuke scripting terminal it comes up with the project context.
Is this a matter of the engine not being fully started when menu.py is called?
Also, all this is completely invisible to me. I can’t see any logs out of my init or menu.py despite calling the engine logger.
import os
import nuke
import sgtk
logger = sgtk.platform.get_logger(__name__)
logger.info("Hello from menu.py?")
Any possible way I can get this working?
Thanks!
Yeah it does seem your menu.py is probably loading before the engine is initialized.
There’s a couple things you could do here.
- Use the engine_init core hook instead of a menu.py. That core hook is guaranteed to run after the engine is fully initialized.
https://developer.shotgridsoftware.com/tk-core/core.html#module-engine_init
- Use a thread to wait for the engine to be fully initialized then use nuke.executeInMainThread to call a method that performs the actions using the nuke engine when it’s available. That would probably look something like this (untested).
import time
import threading
import nuke
import sgtk
def startup():
engine = sgtk.platform.current_engine()
# Do something with engine here...
def await_sg_engine_and_call(callback):
retries = 60
for i in range(retries):
# Check if an engine is available
if sgtk.platform.current_engine() is not None:
print(f"SG Engine loaded!! Executing {callback}...")
return nuke.executeInMainThread(callback)
# Wait a second before checking again...
time.sleep(1)
print("SG Engine didn't initialize within 60 seconds. Callback will not be executed.")
task = threading.Thread(
target=await_sg_engine_and_call,
args=(startup,),
daemon=True,
)
task.run()
Option 1 is more robust, but if you don’t have the option of using a hook then using option 2 would probably work. I’m not sure what the best method of waiting for an engine to be fully initialized is, above we simply check if current_engine()
returns a value.
Ill give that a try and report back. Thanks!
The threaded wait in the menu.py didn’t seem to work. It times out before the engine is ready. I even set the timeout to 2 minutes and it never started. Not sure what’s up with it.
I would recommend creating a custom app for this so you can hook into the events properly.
Events like app_init, etc.
You can also hook into context change events this way.