目次
この問題はWindows固有の問題
とりあえず自分の環境で確認する限り、Macでは起きてません。
バックグラウンドでQListWidgetの内容を常時更新するようなマルチスレッドな状態で、テキストボックスにフォーカス中(テキストを編集中)にQListWidget内のQListItemが削除されるような動作を行うと、編集中のテキストボックスからフォーカスが外れたような挙動になる。
フォーカスが外れるというよりはエンターを押されているような挙動かもしれない。
とりあえず、ウザい。
原因
原因はとりあえず判明してる限り、上で述べたようにQListWidget内のQListItemを削除するようなアクションを取った時。
- list_widget.clear()
- list_widget.takeItem(i)
この両方で確認。
QListWidgetが表示中かどうかは関係ない。裏に隠れててもこの現象は起きる。
なんだったらlist_widget.setUpdatesEnabled(False)で描画のアップデートを抑制しても起きる。
根本的な原因はよくわからん。(分かる人教えて)
解決策(回避策)
テキストボックスにフォーカスがある時はQListWidgetを更新しない(Itemを削除しない)という処理をすればOK.
def list_widget_update(self): # アップデートの冒頭でフォーカスがどこにあるかを判定する # QApplication.focusWidget() でアプリケーション内の現在のフォーカスのオブジェクトを取得可能 # isinstance で目的のテキスト編集系のクラスと比較しTrueなら抜ける if isinstance( QApplication.focusWidget(), (QtWidgets.QLineEdit, QtWidgets.QPlainTextEdit)): # ただ抜けるだけだと芸がないので、フォーカスがテキストボックスから外れるまで再帰的にupdateにディレイを入れる処理 print('list_widget_update(): delay update because focus textbox, retry 5 sec later') QTimer.singleShot(5000, self.list_widget_update) return # これ以降はフォーカスがテキストボックス外にないと辿りつかない # 実際にQListWidgetのItemを削除する処理はこれ以降に書く
とりあえず回避。
ちなみにQApplication.focusWidgetはchatGPTに教えてもろたやで。GPT最高!
コメント