今日のGUIクラッシュ(マルチスレッド関連)
threadを使うwxPythonによるGUIがクラッシュするときに表示される、エラーメッセージのいくつかのパターン。
- パターン1
(python:14799): Gtk-CRITICAL **: gtk_text_layout_wrap_loop_start: assertion `layout->one_style_cache == NULL' failed
- パターン2
(python:15403): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: assertion `layout->wrap_loop_count == 0' failed
- パターン3
Gtk-ERROR **: file gtktextlayout.c: line 1990 (gtk_text_layout_get_line_display): should not be reached
aborting...
- パターン4
(a.out:16337): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators
ここら辺が解決方法か。↓
python - multithreading issue with wx.TextCtrl (or underlying GTK+) - Stack Overflow
要約すると、これらのエラーを避けるため、wxPythonにおいてマルチスレッドのアプリケーションを作成する際の注意点は、以下のようにまとめられる*1。
- GUI上の操作(自分の場合であれば、別スレッドで実行した結果をGUI画面上に表示したりということか)は、メインスレッドで行わなければならない。
- その訳は、多くのUnix GUIライブラリはスレッドセーフ(thread-safe)でないことが往々にしてあるから。
- wx.Bitmapで画面に何か表示したりするときも危ない。
- バックグランドスレッドから、UIスレッドに何かメッセージを送って、画面表示を更新する場合等には、wx.CallAfter()を使うと良い。