Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RuntimeError: wrapped C/C++ object of type QLabel has been deleted #110

Closed
multimeric opened this issue Jul 18, 2023 · 2 comments
Closed

Comments

@multimeric
Copy link

multimeric commented Jul 18, 2023

I've been hitting the above error. It seems to happen when we destroy and then create a viewer in quick succession. One such case where this happens is when running pytest.

Here is a minimal example. You will have to run pytest test.py for this to work.

from magicclass import magicclass
from magicgui import magicgui, widgets

@magicclass
class X:
    main_heading = widgets.Label(value="foo")

def test_a(make_napari_viewer):
    viewer = make_napari_viewer()
    widget = X()
    viewer.window.add_dock_widget(widget)

def test_b(make_napari_viewer):
    viewer = make_napari_viewer()
    widget = X()
    viewer.window.add_dock_widget(widget)

Full traceback:

Traceback (most recent call last):
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/_pytest/runner.py", line 341, in from_call
    result: Optional[TResult] = func()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/_pytest/runner.py", line 262, in <lambda>
    lambda: ihook(item=item, **kwds), when=when, reraise=reraise
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_hooks.py", line 433, in __call__
    return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_manager.py", line 112, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_callers.py", line 155, in _multicall
    return outcome.get_result()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_result.py", line 108, in get_result
    raise exc.with_traceback(exc.__traceback__)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_callers.py", line 80, in _multicall
    res = hook_impl.function(*args)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/_pytest/runner.py", line 177, in pytest_runtest_call
    raise e
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/_pytest/runner.py", line 169, in pytest_runtest_call
    item.runtest()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/_pytest/python.py", line 1788, in runtest
    self.ihook.pytest_pyfunc_call(pyfuncitem=self)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_hooks.py", line 433, in __call__
    return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_manager.py", line 112, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_callers.py", line 116, in _multicall
    raise exception.with_traceback(exception.__traceback__)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/pluggy/_callers.py", line 80, in _multicall
    res = hook_impl.function(*args)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/_pytest/python.py", line 194, in pytest_pyfunc_call
    result = testfunction(**testargs)
  File "/Users/milton.m/Programming/napari_lattice/plugin/tests/test_dock_widget.py", line 36, in test_plugin_initialize
    ui = _napari_lattice_widget_wrapper()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/napari_lattice/_dock_widget.py", line 1155, in _napari_lattice_widget_wrapper
    widget = LLSZWidget()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/core.py", line 204, in __init__
    self._convert_attributes_into_widgets()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/_gui/class_gui.py", line 289, in _convert_attributes_into_widgets
    format_error(e, _hist, name, attr)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/_gui/utils.py", line 84, in format_error
    raise e
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/_gui/class_gui.py", line 142, in _convert_attributes_into_widgets
    widget = attr()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/core.py", line 204, in __init__
    self._convert_attributes_into_widgets()
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/_gui/class_gui.py", line 289, in _convert_attributes_into_widgets
    format_error(e, _hist, name, attr)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/_gui/utils.py", line 90, in format_error
    raise construction_err from None
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/_gui/class_gui.py", line 283, in _convert_attributes_into_widgets
    self._fast_insert(n_insert, widget)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/_gui/class_gui.py", line 341, in _fast_insert
    self._widget._mgui_insert_widget(key, _widget)
  File "/opt/anaconda3/envs/napari-env/lib/python3.9/site-packages/magicclass/widgets/containers.py", line 70, in _mgui_insert_widget
    self._splitter.insertWidget(position, widget.native)
magicclass._gui.utils.MagicClassConstructionError: 

                LlszMenu (<class 'magicclass._gui._base._MagicTemplateMeta'>) <--- Error


                main_heading (<class 'magicgui.widgets.Label'>) <--- Error

RuntimeError: wrapped C/C++ object of type QLabel has been deleted

I believe this is another result of the issue discussed here: napari/napari#4377. If I construct the class inside a factory function as follows, the problem goes away, but this is obviously not desirable:

from magicclass import magicclass
from magicgui import magicgui, widgets

def make_x():
    @magicclass
    class X:
        main_heading = widgets.Label(value="foo")
    return X

def test_a(make_napari_viewer):
    viewer = make_napari_viewer()
    widget = make_x()()
    viewer.window.add_dock_widget(widget)

def test_b(make_napari_viewer):
    viewer = make_napari_viewer()
    widget = make_x()()
    viewer.window.add_dock_widget(widget)
@hanjinliu
Copy link
Owner

Could you try using field?

from magicclass import magicclass, field

@magicclass
class X:
    main_heading = field("foo", widget_type="Label")

It seems like the QLabel widget is destroyed at the end of the first test to me.

@multimeric
Copy link
Author

Great, this seems to fix it. Thanks for the quick response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants