ドキュメントに明確に記載されているように、QtGUIにはメインスレッドからのみアクセスする必要があります。複数の大きくて忙しいテーブルがある複雑なアプリの場合、これは、Qtが実行するすべてのフォントサイズのテキストメトリック計算からのボトルネックになる可能性があります。私が考えることができる唯一の選択肢は、別々のプロセスを使用したマルチタスクです。テーブルは現在、可能な限り高速であり、変更されたセルの最も保守的なセットでdataChanged()呼び出しを使用して、別のスレッドから供給されるキャッシュに直接マップされるカスタムモデルです。私はすでにvTuneでプロファイルを作成しましたが、アプリ時間の70%がQtレンダリングコードになっています。助言がありますか?
3 に答える
私はQTを使用したことがありませんが、1つのスレッド(GUIスレッド)からのみGUIにアクセスすることは、私が精通しているほとんどすべてのGUIで既知の問題です。このケースでは2つのソリューションを使用しましたが、そのうち最初のソリューションを使用します。
1)フォームはタイマー間隔でGUI(この場合はテーブル)を更新します。タイマーは、GUIスレッドのイベントでアクティブになります。これらのタイマーイベントで、グローバル変数からデータを読み取り、テーブルを更新します。グローバル変数は、必要な数のスレッドで更新できます。グローバル変数へのアクセスを同期する必要がある場合があります(たとえば、セマフォ)。
2)多くのGUI APIでは、スレッドはGUIスレッドに関数(またはオブジェクト)を渡してGUIを更新し、そのコンテキストでできるだけ早く実行するように要求できます。その間、GUIがアクションを実行するまで、呼び出し元のスレッドはブロックします。JavaとC#、またはInvoke
wxPythonの3つのそのような関数を思い出すことができます。InvokeLater
wx.CallAfter
MVCパターンのバリアントを使用して、モデルをマルチスレッドにします
テーブルエントリとメソッドがいくつかのステップで実行される場合は、 QCoreApplication :: processEvents()を呼び出して、計算の合間にqtuiを更新できます。もう1つできることは、すべてを別のスレッドで実行し、計算が完了したときにスレッドからシグナルを送信することです。最後に、更新はメインスレッドからUIで行われますが、非同期で行われます。別のスレッドからのシグナルに接続するには、qRegisterMetaType<>を使用する必要があります。