知識は単独のものではなく、体系化されたものでなければなりません。私の個人的な概要と関連する経験の詳細については、このコラム「 Visual Studio」を参照してください。
このプロジェクトの開発中に次の問題が発生しました: [VTK] VTK はボールを動かします。Visual Studio と Qt を使用して Windows 上で VTK を構築します。
質問
Qt を使用して VTK を開発する場合、UI のウィジェット コントロールに小さなボールを表示し、その位置を変更することを目的として、新しい小さなボールが作成されます。ただし、プログラムがスタックしているため、プロンプトを表示しても QOpenGLContext を別のスレッドで最新にすることができません。QVTKOpenGLNativeWidget
レンダリングウィンドウとして使用しています。
他の人が検索時に私の記事を取得できるように、エラー メッセージをコピーします。エラーメッセージは次のとおりです。
QOpenGLContext を別のスレッドで現在にすることはできません
解決
「別のスレッドでは QOpenGLContext を最新にできません」というエラー メッセージは、Qt と VTK で QOpenGLContext を別のスレッドで使用しようとしたことを示します。
Qt と VTK を使用する場合は、次のことを確認する必要があります。
- メインスレッドで Qt オブジェクトと VTK オブジェクトを作成して使用します。Qt と VTK はどちらも、特にグラフィックス レンダリングに関してはスレッドに依存します。そのため、QtやVTKの初期化や操作をメインスレッドで行うことができます。
- 時間のかかる計算やデータ処理を別のスレッドで実行する必要がある場合は、メイン スレッドでシグナル スロット メカニズムを使用して結果をレンダリング スレッドに送信し、レンダリング スレッドで VTK シーンを更新できます。これにより、OpenGL コンテキスト操作が正しいスレッドで実行されることが保証されます。
- 別のスレッドで VTK シーンを更新する必要がある場合は、QVTKWidget の代わりに QVTKOpenGLWidget を使用してみてください。QVTKOpenGLWidget は Qt で VTK シーンを表示するためのウィジェットで、内部的には QOpenGLWidget を使用します。QOpenGLWidget には、スレッド間のコンテキスト切り替えをより適切に処理するために、OpenGL コンテキストに関連したスレッド制限があります。
- マルチスレッドを使用する場合は、OpenGL コンテキストが正しいスレッドで動作していることを確認してください。QOpenGLContext::currentContext() 関数を使用して現在のスレッド内のコンテキストを取得し、OpenGL を動作させる必要があるコード ブロックに判断して設定します。
OpenGL コンテキストを操作する前に Qt のスレッド モデルを必ず理解し、必要に応じてスレッド間のコンテキストの切り替えを適切に管理および処理するようにしてください。
QVTKOpenGLNativeWidget
レンダリングウィンドウとして使用しているため、次の点に特に注意する必要があります。
- 必ずメインスレッドで QVTKOpenGLNativeWidget オブジェクトを作成して初期化してください。これをメインスレッドのウィンドウ階層に追加します。ここでウィジェットが表示および操作されます。
- VTK シーンを他のスレッドで更新する必要がある場合は、Qt のシグナル スロット メカニズムを使用してメイン スレッドと通信します。シーンを更新するリクエストをメイン スレッドに送信し、メイン スレッドで VTK シーンを更新します。
- 他のスレッドからシグナルを受信する場合は、必ずメイン スレッドでシグナルを処理し、メイン スレッドで VTK 関連関数を呼び出してシーンを更新してください。これにより、OpenGL コンテキスト操作が正しいスレッドで実行されることが保証されます。
- 複数のスレッドが関係する場合は、OpenGL コンテキスト操作を実行する前にコンテキストを適切に切り替えるようにしてください。QOpenGLContext::currentContext() を使用して現在のスレッドのコンテキストを取得し、OpenGL を動作させる必要があるコード ブロックに判断して設定できます。
最後に、私の成功事例とコードをこの記事に記載します。必要に応じて参照してください: [VTK] VTK はボールを動かします。Visual Studio と Qt を使用して Windows 上で VTK を構築します。
解決後、QOpenGLContext を別のスレッドで現在にすることができません。ちなみに、次のエラーが発生しました: vtkGenericOpenGLRenderWindow GLEW を初期化できませんでした: Missing GL version も自動的に消えました。