I’m running into a strange problem. I have a large program that uses wxpython for the GUI, and I use several threads to keep the GUI snappy. On occasion, I want to inform users about something (a result, error, etc) from one of those threads, so I show the user a dialog. To do so, I use the standard CallAfter formulation from a thread.
For a while I’ve also been using wx.CallAfter to Destroy these dialogs. This works fine on MacOS, Windows, and Debian. However, I’ve just had a user on Ubuntu report that the dialogs don’t work there.
I’ve been able to verify the issue. The code below is a minimal runnable example that creates a dialog from a thread. If you run this on most platforms it runs fine, and you see the dialog. If instead you run it on Ubuntu (I’ve tested 20.04 and 14.04) it gives the error:
(wx_example.py:4879): GLib-GObject-WARNING **: 13:54:01.989: invalid (NULL) pointer instance (wx_example.py:4879): GLib-GObject-CRITICAL **: 13:54:01.989: g_signal_handlers_disconnect_matched: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed (wx_example.py:4879): Gtk-CRITICAL **: 13:54:01.989: gtk_widget_destroy: assertion 'GTK_IS_WIDGET (widget)' failed (wx_example.py:4879): GLib-GObject-CRITICAL **: 13:54:01.989: g_object_unref: assertion 'G_IS_OBJECT (object)' failed Traceback (most recent call last): File "/home/jesse/miniconda3/envs/wx/lib/python3.8/site-packages/wx/core.py", line 3407, in <lambda> lambda event: event.callable(*event.args, **event.kw) ) wx._core.wxAssertionError: C++ assertion ""Assert failure"" failed at /home/conda/feedstock_root/build_artifacts/wxpython_1616628602755/work/ext/wxWidgets/src/gtk/msgdlg.cpp(281) in ShowModal(): unexpected GtkMessageDialog return code
If you remove the Destroy call, it works fine (besides the dialog not being destroyed).
Any thoughts on what’s going on here? Is there a better way to destroy the dialog after showing it? I should say that in my actual application, for reasons I can’t quite figure out, the dialog not only fails to show but trying to do so actually crashes the application with a Seg fault.
OS: Ubuntu 20.04/14.04
Installed by: Python installed via miniconda installer, wxpython installed from conda-forge
Here’s the example code:
import threading import wx class TestFrame(wx.Frame): def __init__(self, *args, **kwargs): super(TestFrame, self).__init__(*args, **kwargs) pnl = wx.Panel(self) show = wx.Button(pnl, label='Show Dialog from Thread') show.Bind(wx.EVT_BUTTON, self._on_show_dialog) sizer = wx.BoxSizer() sizer.Add(show) pnl.SetSizer(sizer) def _on_show_dialog(self, evt): t = threading.Thread(target=self._show_dialog) t.start() t.join() def _show_dialog(self): dlg = wx.MessageDialog(self, 'This is a test.', 'Test', style=wx.ICON_INFORMATION|wx.OK|wx.STAY_ON_TOP) wx.CallAfter(dlg.ShowModal) wx.CallAfter(dlg.Destroy) if __name__ == '__main__': app = wx.App() frm = TestFrame(None, title='TestFrame') frm.Show() app.MainLoop()