* Note: this is a looong post *
This is Python 2.5 with wxPython 2.8.7.1 Unicode on Debian/
Testing.
Summary:
I have a similar problem. My application has a single top
level frame. When I close the application (via close box
top-right or via menu item or via keyboard shortcut) it runs
fine through the OnClose() handler of the frame (which is
bound to wx.EVT_CLOSE) but never reaches the OnExit() of
wx.App - it just hangs, no exception, no segfault.
Things tried:
I have removed for good the one global reference the the
frame instance (evil, I know).
I have reduced threading to just the one GUI thread.
None of that helped.
I am using RedirectStdio()/RestoreStdio() in
OnInit()/OnExit(), respectively, if that is of interest.
Data:
This is the backtrace which probably isn't too helpful:
#0 0xb7fed424 in __kernel_vsyscall ()
#1 0xb7efdadb in *__GI___poll (fds=0x91fbf00, nfds=2, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:83
#2 0xb61821bb in g_poll () from /usr/lib/libglib-2.0.so.0
#3 0xb6abe867 in ?? () from /usr/lib/libwx_gtk2u_core-2.8.so.0
#4 0xb6174c42 in ?? () from /usr/lib/libglib-2.0.so.0
#5 0x091fbf00 in ?? ()
#6 0x00000002 in ?? ()
#7 0xffffffff in ?? ()
#8 0x091fbf00 in ?? ()
#9 0x00000002 in ?? ()
#10 0x0960eed8 in ?? ()
#11 0xb61ed558 in ?? () from /usr/lib/libglib-2.0.so.0
#12 0xb61ed580 in ?? () from /usr/lib/libglib-2.0.so.0
#13 0xbf977ae4 in ?? ()
#14 0xb61ed558 in ?? () from /usr/lib/libglib-2.0.so.0
#15 0xb61ed580 in ?? () from /usr/lib/libglib-2.0.so.0
#16 0x08f3f114 in ?? ()
#17 0x00000001 in ?? ()
#18 0x08f3f110 in ?? ()
#19 0x091fbf00 in ?? ()
#20 0xb6abe820 in ?? () from /usr/lib/libwx_gtk2u_core-2.8.so.0
#21 0xb7fbc370 in ?? () from /lib/i686/cmov/libpthread.so.0
#22 0xb7fba890 in ?? () from /lib/i686/cmov/libpthread.so.0
#23 0x08f3f114 in ?? ()
#24 0x00000000 in ?? ()
I did install debugging symbols for libc6/python/wxWidgets.
Running python-dbg complains about the wrong mxDateTime
module being installed (works just fine with non-debug
Python, it's probably just that there's not mxdatetime-dbg
available on Debian).
Any other debugging symbols I need to install ?
The frame's OnClose() does this:
def OnClose(self, event):
"""This is the wx.EVT_CLOSE handler.
- framework still functional
"""
_log.debug('gmTopLevelFrame.OnClose() start')
self._clean_exit()
self.Destroy()
gmLog2.flush()
_log.debug('gmTopLevelFrame.OnClose() end')
return True
Again, it runs all the way through - I can the the last
debug statement in the log file. I then hangs *before*
reaching the apps:
def OnExit(self):
"""Called internally by wxPython after EVT_CLOSE has been handled on last frame.
- after destroying all application windows and controls
- before wx.Windows internal cleanup
"""
print "App OnExit"
_log.debug('gmApp.OnExit() start')
self.__shutdown_user_activity_timer(self)
print "user activity timer stopped"
if _cfg.get(option = 'debug'):
self.RestoreStdio()
sys.stdin = sys.__stdin__
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
_log.debug('gmApp.OnExit() end')
I do NOT see the print statement either in the redirection
window nor on the console neither do I find the log
statement in the log file.
(the sys.__std* dance is probably redundant, right ?)
For what it's worth here is the apps OnInit():
def OnInit(self):
self.__starting_up = True
gmExceptionHandlingWidgets.install_wx_exception_handler()
gmExceptionHandlingWidgets.set_client_version(_cfg.get(option = 'client_version'))
_log.info('display: %s:%s' % (wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X), wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)))
# set this so things like "wx.StandardPaths.GetDataDir()" work as expected
self.SetAppName(u'gnumed')
self.SetVendorName(u'The GNUmed Development Community.')
paths = gmTools.gmPaths(app_name = u'gnumed', wx = wx)
paths.init_paths(wx = wx, app_name = u'gnumed')
if not self.__setup_prefs_file():
return False
gmExceptionHandlingWidgets.set_sender_email(gmSurgery.gmCurrentPractice().user_email)
self.__guibroker = gmGuiBroker.GuiBroker()
self.__setup_platform()
if not self.__establish_backend_connection():
return False
self.__check_for_updates()
if _cfg.get(option = 'slave'):
if not self.__setup_scripting_listener():
return False
# FIXME: load last position from backend
frame = gmTopLevelFrame(None, -1, _('GNUmed client'), (640,440))
frame.CentreOnScreen(wx.BOTH)
self.SetTopWindow(frame)
frame.Show(True)
if _cfg.get(option = 'debug'):
self.RedirectStdio()
self.SetOutputWindowAttributes(title = _('GNUmed stdout/stderr window'))
# print this so people know what this window is for
# and don't get suprised when it pops up later
print '---=== GNUmed startup ===---'
print _('redirecting STDOUT/STDERR to this log window')
print '---=== GNUmed startup ===---'
self.__setup_user_activity_timer()
self.__register_events()
wx.CallAfter(self._do_after_init)
return True
And here's the frame's __init__():
def __init__(self, parent, id, title, size=wx.DefaultSize):
wx.Frame.__init__(self, parent, id, title, size, style = wx.DEFAULT_FRAME_STYLE)
self.__gb = gmGuiBroker.GuiBroker()
self.__pre_exit_callbacks = []
self.bar_width = -1
self.menu_id2plugin = {}
_log.info('workplace is >>>%s<<<', gmSurgery.gmCurrentPractice().active_workplace)
self.__setup_main_menu()
self.setup_statusbar()
self.SetStatusText(_('You are logged in as %s%s.%s (%s). DB account <%s>.') % (
gmTools.coalesce(_provider['title'], ''),
_provider['firstnames'][:1],
_provider['lastnames'],
_provider['short_alias'],
_provider['db_user']
))
self.__set_window_title_template()
self.__update_window_title()
self.__set_window_icon()
self.__register_events()
self.LayoutMgr = gmHorstSpace.cHorstSpaceLayoutMgr(self, -1)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(self.LayoutMgr, 10, wx.EXPAND | wx.ALL, 1)
self.SetAutoLayout(True)
self.SetSizerAndFit(self.vbox)
self.__set_GUI_size()
Eventually, the full code is here:
http://cvs.savannah.gnu.org/viewvc/gnumed/gnumed/client/wxpython/gmGuiMain.py?root=gnumed&view=log
Thanks for any insight !
Karsten
···
--
GPG key ID E4071346 @ wwwkeys.pgp.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346