コレクションは、複数のデータを格納できる型の総称です。コンテナと、呼ばれることもあります。
コンテナは GUI フレームワークでは、レイアウト用のウィジェットの総称なので、 ここではコレクションと呼ぶことにします。
Qt には、QList、QVector、QLinkedList、QMap、QHash のコレクションがあります。
コレクションは各値を順番で管理するシーケンシャル(連続)コレクションと、各値に名前をつけて、 その名前で管理するアソシエティブ(連想)コレクションがあります。
QList と QVector と QLinkedList はシーケンシャル(連続)コレクションで、QMap と QHash はアソシエティブ(連想)コレクションになります。
シーケンシャルコレクションは配列と呼ばれることが多く、アソシエティブコレクションは辞書もしくは連想配列と呼ばれることが多いです。
QVector は各要素 (それぞれの値) を隣接するメモリに格納していきます。各要素のインデックス (番号) で高速にアクセスできます。
大きな QVector になると、挿入操作が遅くなるので、その場合は QList を使ったほうが良いでしょう。
この章では、collection ディクトリに collection.cpp を作成して、作業を進めていきます。
#include <QVector>
#include <QTextStream>
int main (void)
{
QTextStream out (stdout);
QVector<int> vals = {1, 2, 3, 4, 5};
out << QString("ベクターのサイズは: ") << vals.size() << Qt::endl;
out << QString("最初の要素は: ") << vals.first() << Qt::endl;
out << QString("最後の要素は: ") << vals.last() << Qt::endl;
vals.append(6);
vals.prepend(0);
out << "各要素は: ";
for (int val: vals)
out << val << " ";
out << Qt::endl;
return 0;
}
collection ディレクトリで作業を続けます。
// プロジェクトを作ります。
qmake -project
// Windows の場合は出来上がった datetime.pro の末尾に次の一行を追加します。
CONFIG += console
// Makefile を作ります。
qmake
// 実行ファイルを作ります。
// Mac Linux の場合は make します。
make
// Windows の場合は nmake します。make じゃなく nmake です。
nmake
// エラーが表示されたら、collection.cpp を見直して、make あるいは nmake する作業を繰り返します。
// Mac の場合は datetime ディレクトリに collection.app ができあがります。
// GUI アプリケーションならこれをダブルクリックすると起動できますが、
// 今回はコマンドラインアプリなので次のようにして実行します
./collection.app/Contents/MacOS/collection
// 結果
ベクターのサイズは: 5
最初の要素は: 1
最後の要素は: 5
各要素は: 0 1 2 3 4 5 6
// Linux の場合には collection ディレクトリに collection という実行ファイルが出来上がっていますのでそれをそのまま実行します
./collection
// 結果 は同じ
// Windows の場合には collection ディレクトリの中の release ディレクトリに collection.exe が出来上がっています。
// release ディレクトリに移動して、collection.exe を実行します。
collection
// 結果 は同じ
QList もシーケンシャルコレクションですが、各要素への高速な挿入と削除ができます。
Qt で最もよく使われるコレクションです。
#include <QTextStream>
#include <QList>
int main (void)
{
QTextStream out (stdout);
QList writers = {QString("むらかみはるき"),
QString("なつめそうせき"),
QString("あくたがわりゅうのすけ"),
QString("かわばたやすなり"),
};
for (int i=0; i < writers.size(); i++)
out << writers.at(i) << Qt::endl;
writers << QString("いけなみしょうたろう") << QString("あかがわじろう");
out << "***********************" << Qt::endl;
std::sort(writers.begin(), writers.end());
out << QString("ソートされました。") << Qt::endl;
for (QString writer : writers)
out << writer << Qt::endl;
return 0;
}
漢字だとソートされているのかどうか分かりにくいのでひらがなにしました。
なつめそうせき
あくたがわりゅうのすけ
かわばたやすなり
***********************
ソートされました。
あかがわじろう
あくたがわりゅうのすけ
いけなみしょうたろう
かわばたやすなり
なつめそうせき
むらかみはるき
QStringList は QString 専用のシーケンシャルコレクションで、高速な挿入と削除ができます。
#include <QTextStream>
#include <QList>
int main (void)
{
QTextStream out (stdout);
QString string = "硬貨, 本, コップ, 鉛筆, 時計, しおり";
QStringList items = string.split(",");
QStringListIterator it(items);
while (it.hasNext())
out << it.next().trimmed() << Qt::endl;
return 0;
}
硬貨
本
コップ
鉛筆
時計
しおり
比較演算子は QTime、QDateTime にも使えます。
QSet は値の集合ですが、各要素には順序はなく、また同じ値の要素を持つこともできません。
#include <QTextStream>
#include <QList>
#include <QSet>
int main (void)
{
QTextStream out (stdout);
QSet<QString> cols1 = {"イエロー", "レッド", "ブルー"};
QSet<QString> cols2 = {"ブルー", "ピンク", "オレンジ"};
out << QString("セットに要素は") << cols1.size() << QString("個あります。") << Qt::endl;
cols1.insert("ブラウン");
out << QString("セットに要素は") << cols1.size() << QString("個あります。") << Qt::endl;
cols1.unite(cols2);
out << QString("セットに要素は") << cols1.size() << QString("個あります。") << Qt::endl;
for (QString val : cols1)
out << val << Qt::endl;
QList list = cols1.values();
std::sort(list.begin(), list.end());
out << "**********************************" << Qt::endl;
out << QString("ソートしました。") << Qt::endl;
out << "**********************************" << Qt::endl;
for (QString val : list)
out << val << Qt::endl;
return 0;
}
セットに要素は3個あります。
セットに要素は4個あります。
セットに要素は6個あります。
オレンジ
レッド
ピンク
イエロー
ブラウン
ブルー
**********************************
ソートしました。
**********************************
イエロー
オレンジ
ピンク
ブラウン
ブルー
レッド
起動するたびに最初の文字の並びは変わります。QSet には順序がないからです。
QMap は、キーと値のペアを格納するアソシエティブコレクションです。連想配列や辞書とも呼ばれます。
QMap の各要素にはキーを使って素早くアクセスできます。
#include <QTextStream>
#include <QMap>
int main (void)
{
QTextStream out (stdout);
QMap<QString, int> m = {{"鉛筆", 6}, {"りんご", 3}};
m.insert("空き缶", 4);
QList<int> vals = m.values();
out << QString("値は:") << Qt::endl;
for (int val : vals)
out << val << Qt::endl;
out << "*********************" << Qt::endl;
QList<QString> keys = m.keys();
out << QString("キーは:") << Qt::endl;
for (QString key : keys)
out << key << Qt::endl;
out << "*********************" << Qt::endl;
QMapIterator it(m);
out << QString("ペアは:") << Qt::endl;
while (it.hasNext())
{
it.next();
out << it.key() << ": " << it.value() << Qt::endl;
}
return 0;
}
値は:
3
4
6
*********************
キーは:
りんご
空き缶
鉛筆
*********************
ペアは:
りんご: 3
空き缶: 4
鉛筆: 6