この記事は Qt Advent Calendar 2016 15日目の記事です。
QVariantはQtにおけるバリアント型のクラスです。
QString, QPointのようなQtの型から、int, double のようなプリミティブ型まで
多くの型を格納することができます。
また、void*, QObject*, QWidget*というポインタ型も扱えます。
そのため、多くの型に対応する必要がある場合などに役立ちます。
このクラスはQSettingsなどで活用する機会があるのですが、
直接扱う記事はQiitaになかったので書いてみました。
基本的な使い方
QVariantに値を格納するには以下のメソッドを使います。
- コンストラクタ
- QVariant::setValue(const T &)
- QVariant::fromValue(const T &) [static]
void set_value()
{
QString text("text");
QVariant variant1(text); // constructor
QVariant variant2;
variant2.setValue(text); // QVariant::setValue()
QVariant variant3 = QVariant::fromValue(text); // QVariant::fromValue() [static]
}
反対にQVariantから値を取り出すには以下のメソッドを使います。
- toメソッド
- QVariant::value()
void get_value()
{
QVariant variant(QString("text"));
QString text1 = variant.toString(); // to method
QString text2 = variant.value<QString>(); // QVariant::value<T>()
}
具体的な使い方
QSettings を使う例がわかりやすいかと考えたのですが、
昨年のアドベントカレンダーに@taura_noさんのQSettingsでアプリケーションの設定を保存するという記事がありましたので、
他の一例としてQVariantMapを用いた方法を示します。
void getFileName(QVariantMap & map)
{
QString caption = map["caption"].toString();
QString fileName = QFileDialog::getOpenFileName(Q_NULLPTR, caption);
map["fileName"] = QVariant::fromValue(fileName);
}
void func()
{
QVariantMap map;
QString caption("Let's select file!");
map["caption"] = QVariant::fromValue(caption);
getFileName(map);
qDebug() << map["fileName"].toString();
}
上記のgetFileNameメソッドはファイル名を取得するメソッドですが、
引数にQVariantMapを渡すことで引数の変更に柔軟な対応ができるようにしています。
後にファイル名の取得方法が変更になった場合
必要に応じて呼び出し元と呼び出し先でQVariantMapのkey/valueを修正しますが、
getFileNameメソッドの引数は一切変更の必要が生じません。
尤も、保守の観点からは引数が明らかである方が望ましいです。
このような方法は自衛的なプログラミング方法として使うべきで、
引数の変更が容易にできないが、仕様の変更が考えられるなどの
限られたケースにおいて最小限で利用がよいでしょう。