Toggle Sphere Visibility every second using a Python Timer Thread


I have following class.
The toggle() function will show\hide a SphereLight
It works fine when called from the UI.Button click
It does not work when called from inside the thread callback ‘my_callback’. When called from the timer callback Omniverse Code hangs. How do I get the callback to Toggle the SpereLight ?

class C2HelloWorldExtension(omni.ext.IExt):    
    def on_startup(self, ext_id):        
        print("[] c2 hello world startup")
        self._window = ui.Window("Sphere Light Tests", width=500, height=300)
        with self._window.frame:
            with ui.VStack():
                def setLightViaStage(mode):
                    stage = omni.usd.get_context().get_stage()
                    prim = stage.GetPrimAtPath("/World/SphereLight")
                    attribute = prim.GetAttribute("visibility")
                    attribute.Set("invisible" if mode == 0 else "inherited")

                def toggle():
                    self.mode = self.mode  ^ 1
                def my_callback():

                def start_timer():
                    self.timer = threading.Timer(1, my_callback)

                with ui.HStack():
                    ui.Button("Button Toggle", clicked_fn=toggle)
                    ui.Button("Thread Toggle", clicked_fn=start_timer)

    def on_shutdown(self):
        print("[] c2 hello world shutdown")


Hi @liam.mullane - The issue you are experiencing is due to using threading to make modifications to the USD stage. This is not allowed in Omniverse and can result in instability.

For this, you should use omni.async.loop.call_soon_threadsafe which will safely call your function from the main thread.