2012年1月26日木曜日

( Qt C++ )QVariantについて


はいそれではQVariantについて書いていきます。

「コンテナクラスじゃないじゃん!」そう思った方、実は私もです。しかしC++ GUI Protramming with Qt4のcontainer classesの章によると「無関係じゃねぇし。QString,QByteArray,QVariantはここで説明すっから」と書かれています。ですので私もそれに従い書いていきます。

ということでQVariantについて書いていきますが、これは簡単にいうと"いろんな型入れれるクラス"です。多数の型を扱う場合だとか、型推論に使える便利なクラスです。
QBrush,QColor...などなど多くのQtクラスとdouble, int などのC++の基本数値型、QListなどのコンテナクラスを格納できます。

サンプルはC++ GUI Programming with Qt4 269ページからを参考にします。

ではコードを
(なおGUI関係のクラスをQVariantへ入れる場合はQtGuiモジュールへのリンクが必要です。)


(コンストラクタ)
QVariant var(QIcon("sample.png"));
//varにはQIconが入る
//※GUI関係はQtGuiモジュールへのリンクが必要です。

QVariant var_two(1000);
//var_twoにはint 1000が入る


(コンストラクタ以外での値の格納)
QVariant var.setValue(QIcon("sample.png"));
//varにはQIconが入る
//※GUI関係はQtGuiモジュールへのリンクが必要です。

var = QVariant("Hello!");
//varには"Hello!"が入る

var = QVariant::fromValue("Hello World");
//varには"Hello World"が入る


(値の取り出し)
QVariant var(QIcon("sample.png"));
//※GUI関係はQtGuiモジュールへのリンクが必要です。

QVariant var_two(1000);


//取り出し
//GUI関係の場合はQVariant::value<T>()を使う
QIcon icon = var.value<QIcon>();

//GUI以外は多くの場合to...()を使う
int num = var_two.toInt();


(コンテナを用いた複雑なデータ構造)
//キーをQString、値はほぼ何でもOK
QMap<QString, QVariant> map;
map["one"] = 1.95;
map["two"] = "Hello!";
map["three"] = QIcon("/home/ubuntu001/icon.png");

double num;
QString str;
QIcon icon;

//それぞれ値の型を確認してから各変数に取り出す。
//type()で確認できます。
if(QVariant::Double == map["one"].type())
{
    num = map["one"].toDouble();
}

if(QVariant::String == map["two"].type())
{
    str = map["two"].toString();
}

if(QVariant::Icon == map["three"].type())
{
    icon = map["three"].value<QIcon>();
}


(ユーザー定義クラスの格納)
//デフォルトコンストラクタと
//コピーコンストラクタがなければ登録できない。
class sample
{
public:
    sample();//デフォルトコンストラクタ
    sample(const sample& obj);//コピーコンストラクタ

};

//--------------------------------------------------
//下記のように登録さえすれば
Q_DECLARE_METATYPE(sample)

//登録したファイルの中でQVariantとして使える
//ファイルごとにQ_DECLARE_METATYPE()を書かないと使えない。
Test::testfunc()
{
    sample sm;
    QMap<QString, QVariant> map;
    map["one"] = QVariant::fromValue(sm);//格納

    sample sm2 = map["one"].value<sample>();//取り出し
}
//typeはQVariant::UserTypeとなる typenameでは"sample"となる

あとはリファレンスを参照してください。
(QVariant::Typeの一覧)

以上です。