Planet Python 日本語
フォロー
Python GUI:QtスレッドでNumPy配列をQImageと共に使用する際のクラッシュ修正 — 動画ストリーミングやディスプレイ更新時にスレッド間で安全に画像データを渡す方法
NumPyとPyQt6を使用したスレッド化されたビデオストリーマーでのクラッシュは、多くの場合、QImageがNumPy配列メモリとどのように相互作用するかに起因します。NumPy配列からQImageが作成されるとき、データはコピーされず、代わりに元のメモリバッファを参照します。これはマルチスレッドアプリケーションでは危険な状況を生み出します。なぜなら、ワーカー スレッドがNumPy配列を変更または破棄した場合、GUI スレッドのQImageが無効になり、クラッシュにつながる可能性があるからです。解決策は、QImageが独自の独立したデータのコピーを持つことを保証することです。これは、QImageで.copy()メソッドを呼び出すことによって達成されます。このコピーのタイミングは重要です。QImageがワーカー スレッドからGUI スレッドに渡される前に、通常はシグナルを介して発行される前に実行する必要があります。さらに、setPixmapの呼び出しなどのすべてのGUI更新は、メイン スレッドでのみ実行する必要があります。シグナルとスロットの使用は、ワーカー スレッドがGUI更新のためにメイン スレッドと通信するための正しい方法です。提供された例は、NumPy配列からQImageを作成し、すぐにコピーし、次にコピーされたQImageをシグナルを介して発行することによってこれを実証しています。メイン スレッドのスロットは、この安全なQImageを受信し、QPixmapに変換し、クラッシュを引き起こすことなくQLabelを更新します。これらのプラクティスを実装することにより、PyQt6での信頼性の高いスレッド化されたビデオストリーミングを実現できます。