7

いくつかのカスタム デザイン ファイル用に qt でファイル ブラウザーを作成しています。プレビューをサムネイルとしてロードしたいのでQIconProvider、アイコンを に戻すために使用していQFileSystemModelます。

問題は、作成するアルゴリズムQIconがいくつかのリソースを必要とするため、すべてのサムネイルの読み込みが完了するまでアプリケーションが応答しないことです。

QIconProviderアプリケーションが応答するように、バックグラウンド スレッドに入れる方法があるかどうか疑問に思っています。

4

2 に答える 2

6

受け入れられた答えは素晴らしいです-より高度なQtの概念のいくつかを紹介してくれました。

将来これを試す人のために、これをスムーズに機能させるためにいくつかの変更を加える必要がありました。

  • スレッドを制限する:QThreadPool最大スレッド数を 1 または 2 に設定して、 aをに渡しQConcurrent::runます。デフォルトを使用すると、すべてのスレッドがビルド イメージのプレビューを焼き付けるため、アプリが強制終了されました。ボトルネックはディスクになるため、このタスクに 1 つまたは 2 つ以上のスレッドを使用しても意味がありません。
  • 再入力の回避:アイコンの生成が完了する前に、同じパスのアイコンが複数回照会されるケースを処理する必要があります。現在のコードでは、同じアイコンを生成する複数のスレッドが生成されます。簡単な解決策は、QConcurrent::run 呼び出しの前に m_icons マップにプレースホルダー エントリを追加することです。default を呼び出したQIdentityProxyModel::data(index, QFileSystemModel::FileIconRole)ので、ロードが完了する前にアイコンはまともなデフォルトを取得します
  • タスクのキャンセル:モデルを破棄する場合 (またはビュー フォルダーなどを切り替えたい場合)、アクティブなタスクをキャンセルする方法が必要になります。QConcurrent::run残念ながら、保留中のタスクをキャンセルする組み込みの方法はありません。std::atomic_boolタスクが実行前にチェックするキャンセルを通知するために a を使用しました。そして、std::condition_variableすべてのタスクがキャンセル/完了するまで待機します。

ヒント:これの私の使用例は、ディスク上の画像からサムネイル プレビューを読み込むことでした (一般的な使用例と思われます)。いくつか実験した結果、プレビューを生成する最速の方法は、 を使用しQImageReader、サムネイル サイズを に渡すことであることがわかりましたsetScaledSize。正方形でない画像がある場合は、次のように適切な縦横比のサイズを渡す必要があることに注意してください。

    const QSize originalSize = reader.size(); // Note: Doesn't load the file contents
    QSize scaledSize = originalSize;
    scaledSize.scale(MaximumIconSize, Qt::KeepAspectRatio);
    reader.setScaledSize(scaledSize);
于 2017-03-30T16:20:58.697 に答える