Carb crash upon destroying a window from a button

The attached code is crashing strangely and I’m not quite sure why.

It’s a low level crash and generates a dump. The dump seems to be uploading to your (NVidia’s) servers. So perhaps the following id is useful from the crash log:

d4d2f350-254a-437b-a3de-96e1b1dae560

The code that’s crashing is below:

import omni.ui as ui
from omni.ui import DockPreference


class NewUserDialog(ui.Window):

    _username_model:ui.SimpleStringModel
    _printname_model:ui.SimpleStringModel
    _password_model:ui.SimpleStringModel


    def __init__(self, title: str, dockPreference: DockPreference = DockPreference.DISABLED, **kwargs) -> None:
        self._username_model = ui.SimpleStringModel()
        self._printname_model = ui.SimpleStringModel()
        self._password_model = ui.SimpleStringModel()

        super().__init__(title, dockPreference, **kwargs)

        self._build_window()

        self.set_visibility_changed_fn(self._on_vis_changed)

    def _build_window(self):
        with self.frame:
            with ui.VStack(height=0):
                ui.StringField(self._username_model)
                ui.StringField(self._printname_model)
                ui.StringField(self._password_model)
                with ui.HStack(width=0):

                    ui.Button("Create", clicked_fn=lambda: self._on_create())
                    ui.Button("Cancel", clicked_fn=lambda: self._on_cancel())

    def _on_create(self):
        pass

    def _on_cancel(self):
        self.visible = False

    def _on_vis_changed(self,vis:bool):
        if not vis:
            self.destroy()

    def destroy(self) -> None:
        self._username_model = None
        self._printname_model = None
        self._password_model = None
        print("destroying!")
        super().destroy()



Here’s the weird bit. If you click the “Cancel” button, then I crash out with the minidump referenced above. But, if you instead click the ‘x’ button for the window, which presumably just sets visibility to False: it DOES NOT crash. This suggests to me that there’s something having to do with the call coming from within the button’s loop? Or perhaps I’m doing this all wrong. Thoughts?

I’ve tried making those clicked_fn args as lambdas, and also as simple function pointers. I’ve also tried defining the function just above inside the method rather than as a class function. All with the same results: a crash.

Anyhow, without a debug-able version of carb (which I presume to be c++ code) I cannot debug any further and find what is probably a stupid mistake on my part.

Hi @brad_f. The team is aware of this issue. You’re right, it has to do with destroying UI elements in a callback. You can work around it by putting the destroy call in an async function.

    def _on_vis_changed(self,vis:bool):
        if not vis:
            async def destroy_self_async(self):
                self.destroy()
            asyncio.ensure_future(destroy_self_async(self))
1 Like

Makes sense. I used async as you suggested and tested. It works.

Thanks.

fixed code below for reference with a slightly different structure:

import omni.ui as ui
from omni.ui import DockPreference
import asyncio

class NewUserDialog(ui.Window):

    _username_model:ui.SimpleStringModel
    _printname_model:ui.SimpleStringModel
    _password_model:ui.SimpleStringModel


    def __init__(self, title: str, dockPreference: DockPreference = DockPreference.DISABLED, **kwargs) -> None:
        self._username_model = ui.SimpleStringModel()
        self._printname_model = ui.SimpleStringModel()
        self._password_model = ui.SimpleStringModel()

        super().__init__(title, dockPreference, **kwargs)

        self._build_window()

        self.set_visibility_changed_fn(self._on_vis_changed)

    def _build_window(self):
        with self.frame:
            with ui.VStack(height=0):
                ui.StringField(self._username_model)
                ui.StringField(self._printname_model)
                ui.StringField(self._password_model)
                with ui.HStack(width=0):

                    ui.Button("Create", clicked_fn=lambda: self._on_create())
                    ui.Button("Cancel", clicked_fn=lambda: self._on_cancel())

    def _on_create(self):
        pass

    def _on_cancel(self):
        self.visible = False

    def _on_vis_changed(self,vis:bool):
        if not vis:
            self.schedule_destroy()

    def schedule_destroy(self):
        async def do_destroy():
            self.destroy()
        asyncio.ensure_future(do_destroy())

    def immediate_destroy(self):
        self.destroy()

    def destroy(self) -> None:
        self._username_model = None
        self._printname_model = None
        self._password_model = None
        print("destroying!")
        super().destroy()



1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.