enthought / enthought/traitsui
Qt Application does not exit when the last UI is closed manually
- Dominant language
- Python
- Stars
- 306
- Forks
- 99
- PR merge metrics
- No merged PRs in 30d
Description
This issue follows a report from this [thread](https://groups.google.com/g/ets-users/c/hIhuXWD8200/m/9BbboK1HAQAJ) in the user mailing list.
To reproduce:
```
from traits.api import HasTraits, Float
from traitsui.api import Item, View
from traitsui.menu import MenuBar, Menu, Action, CloseAction
class MyApp(HasTraits):
a = Float(1.0)
menubar = MenuBar(
Menu(
CloseAction,
name='File'
)
)
traits_view = View(
Item('a'),
menubar=menubar
)
app = MyApp()
app.configure_traits()
```
Attempt to close the window by pressing the "Close" item in the menu does make the window invisible, but the Python process is still blocking. The expectation is that it should behave like the "OK" button and the Python process should exit.
I also came across this issue when I experimented with defining a button that does the same action as the OK button (motivated by https://github.com/enthought/traitsui/issues/1148), by calling `ui.owner.close()` where `ui` is the main `UI` instance created by `configure_traits` (or `edit_traits`).
Quote from the mailing list
> I came across what looks like another (annoying) bug in traitsui/pyface 7.0 with PyQt5 5.14, this time with the menu CloseAction. (This is under Python 3.6.10 on RHEL 7.7.) If I try to close the main window using the CloseAction item in a menu in the menubar, Qt hangs in an infinite loop after destroying the window. Closing the window by clicking on the window's "X" close icon works just fine, with a message in the shell from which Python was executed indicating the python process has been killed. Following is a super-short example that reproduces the problem:
> ```
>
> from traits.api import HasTraits, Float
> from traitsui.api import Item, View
> from traitsui.menu import MenuBar, Menu, Action, CloseAction
>
> class MyApp(HasTraits):
> a = Float(1.0)
> menubar = MenuBar(
> Menu(
> CloseAction,
> name='File'
> )
> )
> traits_view = View(
> Item('a'),
> menubar=menubar
> )
>
> app = MyApp()
> app.configure_traits()
> ```
>
> By adding a custom handler to this code to override the Handler.close method and insert a "import ipdb; ipdb.set_trace()" statement, then stepping, it appears the infinite loop occurs after exiting traitsui.qt4.toolkit._KeyEventHook.eventFilter a number of times. Each time that method gets called, the "event" argument is a different QEvent, with a type such as 25 (WindowDeactivate), 52 (DeferredDelete), 71 (ChildRemoved), and so on. Eventually, it gets called with a QEvent type of 16, which does not appear to be a defined QEvent; after returning from this call, even with an ipdb step command, Python hangs.
>
> Perhaps this is a bug upstream in PyQt5 instead of PyFace or traitsui, but I wouldn't know how to determine this. Hopefully a developer would like to look at it, and if it is a bug, report this as such for the appropriate package?
>
> Jean-Paul Davis
>
>
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.