QDir::entryList()
を使用してディレクトリの内容を読み取っています。内のファイル名は次のように構成されています。
index_randomNumber.png
index
で並べ替える必要があります。これは、Windowsエクスプローラーがファイルを並べ替える方法です。
0_0815.png
1_4711.png
2_2063.png
...
QDir::Name
で並べ替えると、次のようになります。
0_0815.png
10000_6661.png
10001_7401.png
...
これを達成するための組み込みの方法がQtにありますか?そうでない場合、それを実装する適切な場所はどこですか?
QCollator
を使用して、 QDir::entryList
によって返されたエントリのリストからエントリを並べ替える場合は、並べ替えることができます std::sort()
の結果:
dir.setFilter(QDir::Files | QDir::NoSymLinks);
dir.setSorting(QDir::NoSort); // will sort manually with std::sort
auto entryList = dir.entryList();
QCollator collator;
collator.setNumericMode(true);
std::sort(
entryList.begin(),
entryList.end(),
[&collator](const QString &file1, const QString &file2)
{
return collator.compare(file1, file2) < 0;
});
The Badger のコメントによると、QCollator
はstd::sort
の引数として直接使用してラムダを置き換えることもできるため、std::sort
の呼び出しは次のようになります。
std::sort(entryList.begin(), entryList.end(), collator);
Qtには、Qt 5.2まで自然ソートの実装がありませんでした。 この機能リクエスト を参照してください。
Qt 5.2以降、 QCollator があり、 数値モード が有効になっている場合に自然ソートが可能になります。
はい、可能です。
これを行うには、QDir
を作成するときにフラグ LocaleAware を指定する必要があります。オブジェクト。コンストラクターは
QDir(const QString & path, const QString & nameFilter, SortFlags sort = SortFlags( Name | IgnoreCase ), Filters filters = AllEntries)
使用することもできます
QDir dir;
dir.setSorting(QDir::LocaleAware);
これはそのような質問への答えではありませんが、「自然にソートする」方法を見つけようとしてこれに遭遇した他の人の利益のためのいくつかの一般的な情報。
まず最初に:それは不可能です。 「正しい」自然ソートは、「真の」人工知能がなければ、事実上不可能なコンテキストに依存します。たとえば、数字と文字が混在するファイル名がたくさんあり、それらの名前の一部がたまたま[0-9a-f]
と一致する場合、それは16進数ですか? 「1,500」は「1500」と同じですか、それとも「1」と「500」の個別の番号ですか? 「2019/06/07」は「2019/07/06」の前後にありますか? 「1.21」と「1.5」はどうですか? (ヒント:最後は、それらが10進数であるかセマンティックバージョン番号であるかによって異なります。)
この問題を「解決」するには、それを制約する必要があります。特定のケースのみを処理することを決定し、それらの範囲外のものはすべて「間違った」答えを生成します。 (幸いなことに、OPの問題は、通常の一連の制約をすでに満たしているように見えます。)
とは言うものの、QCollator
は一般的にうまく機能すると思います(繰り返しますが、「実際には」機能しませんが、一般的に受け入れられている制約の範囲内で成功します)。 「独自のソリューション」部門では、 qtNaturalSort もご覧ください。これは、別の(QCollator
ではない)アルゴリズムに対するQt-APIの改善として作成したものです。 (大文字と小文字の区別は、執筆時点ではサポートされていませんが、パッチは歓迎されます!)任意の長さの数値や非BMP桁を処理する場合でも、数値を「正しく」解析するように多大な努力を払いました。