nucleic / enaml

Declarative User Interfaces for Python
http://enaml.readthedocs.io/en/latest/
Other
1.53k stars 130 forks source link

Crash when closing a floating dock window which has a maximised dock item inside it #467

Closed e-calder closed 2 years ago

e-calder commented 2 years ago

Hey,

I've noticed a crash related to maximised floating windows within a group... to reproduce:

1) Run examples/widgets/dock_area.enaml 2) Drag out 2 or more dock items so they are floating, and group them into their own floating dock window (terminology might not be accurate, please excuse)

Enaml1

3) Maximise one of these dock items within the dock window, then close the dock window via the outer red cross (circled).

Enaml2

4) This results in a hard crash, killing the application:

Traceback (most recent call last):
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\qt\q_deferred_caller.py", line 43, in customEvent
    event.callback(*event.args, **event.kwargs)
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\widgets\toolkit_object.py", line 169, in destroy
    super(ToolkitObject, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\styling.py", line 298, in destroy
    super(Stylable, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\core\declarative.py", line 128, in destroy
    super(Declarative, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\core\object.py", line 114, in destroy
    child.destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\widgets\toolkit_object.py", line 169, in destroy
    super(ToolkitObject, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\styling.py", line 298, in destroy
    super(Stylable, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\core\declarative.py", line 128, in destroy
    super(Declarative, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\core\object.py", line 114, in destroy
    child.destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\widgets\toolkit_object.py", line 172, in destroy
    self.proxy.destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\qt\qt_constraints_widget.py", line 46, in destroy
    super(QtConstraintsWidget, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\qt\qt_widget.py", line 95, in destroy
    super(QtWidget, self).destroy()
  File "c:\users\ecalder\code\virtualenvs\bc-env\lib\site-packages\enaml\qt\qt_toolkit_object.py", line 93, in destroy
    widget.setParent(None)
RuntimeError: wrapped C/C++ object of type QTextEdit has been deleted

Thanks in advance!

Emy

MatthieuDartiailh commented 2 years ago

Thanks for reporting. Could you also report the enaml version, the Qt library, the python version and the OS you are running on ?

e-calder commented 2 years ago

Hey, thanks for the speedy response.

enaml==0.12.0 (I know this isnt the most up to date version, we haven't updated to it yet... so it's possible it might be fixed there?)

PyQt5==5.14.1

Python is 3.8.10

OS is Windows 10 Pro, 64 bit

Cheers

frmdstryr commented 2 years ago

I'm able to reproduce it here...

Does it make sense to check if the handle is valid or is there a better way to do that?

Eg, this fixes that particular case https://github.com/nucleic/enaml/commit/c21605ac2348495627e38f004f11791262f3329c

MatthieuDartiailh commented 2 years ago

Thanks for reproducing @frmdstryr. I will investigate but enaml should prevent the need to explicitly checking the widget state.

MatthieuDartiailh commented 2 years ago

Since I am not sure when I will time to dive deep enough to figure this out, I will spell a bit my guesses regarding what may be happening in case somebody else wants to have a look.

Typically enaml will have the backend (Qt) forward any closing request to the front-end (Enaml widget) which ensures that the back-end does not disappear without the front-end not knowing about it. However in this issue it is typically what happens.

~My best guess is that in the case of floating dock-window which are not backed by an actual enaml widget part of that logic fails when multiple dock-items are involved. Actually I think it would be worthwhile checking if vetoing the closing of a floating dock-item works at all and if it works hen multiple items belong to the same window. This is likely the easiest way to check if the front-end get the messages as it should. The relevant parts are under enaml/qt/docking, I think that the dock_manager, q_dock_window and q_dock_container are the most likely to be relevant.~ Actually the confirmation works, however I can reproduce and I found another issue when maximizing an element from a notebook when only the notebook exists in the area.

bburan commented 2 years ago

This seems to have been fixed. I attempted to replicate the crash but could not. Should we close this issue?