QVariant识别类型的注册

QVariant为一个万能的数据类型--可以作为许多类型互相之间进行自动转换。将C++变为弱数据类型成为可能--也是许多控件中用户定义数据的类型--因为无法预先知道用户附加到控件的数据是什么类型。
而QT的Variant类型默认识别的类型都非常强制--只支持已注册的类型--如何将一个自己定义的结构或类赋予QVariant对象呢?
myStructor c;
QVariant v;
v.setValue (c); //将会错误--Qvariant还不认识myStructor呢。

首先必须先注册myStructor--使用Q_DECLARE_METATYPE(myStructor)。
这是一个Macro--只能在全局中使用--否则出现错误。
然后就可以按一般的方法来赋值了--取值代码为 v.value < myStructor >();
例子:
将一个指针赋予QVariant--可能有需要将一个指针赋予树型列表控件(QTreeWidget)中一个条目--点击此条目获取指针对数据进行处理--而无须通过查找来取得数据--缩短处理时间。

用int指针作为例子--QVariant不支持此类型必须先注册。
ifndef __XXX__
define __XXX__

Q_DECLARE_METATYPE(int*);
...

endif

附带记下如何在QTreeWidget控件中附加数据

增加Item

QTreeWidgetItem* newItem = new QTreeWidgetItem;

...增加newItem到treeWidget中...

int* itemVal = new int (123);
QVariant Var;
Var.setValue (testVal); // 已注册了int*--正确编译
newItem->setData (0, 0, Var); //newItem的第一列附加了Var--即指向itemVal的指针
//第二个参数为role角色的意思--我也不懂啥意思

点击某个条目获取对应的数据

on_treeWidget_click ()
{
...取得选择的条目-curItem...
//Data()的参数和当时设置数据的参数一样,value()是取得var的数据
int* ptr = curItem->Data (0, 0).value < int* >(); ...对ptr进行处理...
}
  • 详细描述:

QVariant类作为一个最为普遍的Qt数据类型的联合。

因为c++禁止没有构造函数和析构函数的联合体,许多继承的Qt类不能够在联合体当中使用。(联合体当中的变量共用一个存储区),没有了联合变量,我们在物体属性以及数据库的工作等方面受到很多的困扰。

一个QVariant对象在一个时间内只保留一种类型的值。我们可以使用canConvert来查询是否能够转换当前的类型。转换类型一般以toT()命名。

摘录了一个example来说明QVariant的使用方法:

QDataStream out(...);
QVariant v(123); // The variant now contains an int
int x = v.toInt(); // x = 123
out << v; // Writes a type tag and an int to out
v = QVariant("hello"); // The variant now contains a QByteArray
v = QVariant(tr("hello")); // The variant now contains a QString
int y = v.toInt(); // y = 0 since v cannot be converted to an int
QString s = v.toString(); // s = tr("hello") (see QObject::tr())
out << v; // Writes a type tag and a QString to out
...
QDataStream in(...); // (opening the previously written stream)
in >> v; // Reads an Int variant
int z = v.toInt(); // z = 123
qDebug("Type is %s", // prints "Type is int"
v.typeName());
v = v.toInt() + 100; // The variant now hold the value 223
v = QVariant(QStringList());
你甚至可以存储QList<QVariant>和QMap<QString ,QVariant>.所以你可以构造任意复杂的任意的数据类型。这个是非常强大而且又有
用的。QVariant也支持null值,你可以定义一个没有任何值的类型,然而,也要注意QVariant类型只能在他们有值的时候被强制转换。
QVariant x, y(QString()), z(QString(""));
x.convert(QVariant::Int);
// x.isNull() == true
// y.isNull() == true, z.isNull() == false
因为QVariant是QtCore库的一部分,它不能够提供定义在QtGui当中的类型的转换,如QColor,QImage,he QPixmap等。换句话说,没
有toColor()这样的函数。取代的,你可以使用QVariant::value()或者qVariantValue()这两个模板函数。
 QVariant variant;
...
QColor color = variant.value<QColor>();
反向转换(如把QColor转成QVariant)是自动完成的。也包含了GUI相关的那些数据类型。
QColor color=palette().background().color();
QVariant variant=color;
  • 实例代码:

    #include "widget.h"
    #include <QDebug>
    #include <QVariant>
    #include <QColor>
    Widget::Widget(QWidget *parent)
    : QWidget(parent)
    {
    QVariant v();
    qDebug()<<v.toInt();
    QVariant w("how are you!");
    qDebug()<<w.toString();
    QMap<QString, QVariant> map;
    map["int"] = ;
    map["double"] = 709.709;
    map["string"] = "how are you!";
    map["color"] = QColor(,,);
    qDebug()<<map["int"]<<map["int"].toInt();
    qDebug()<<map["double"]<<map["double"].toDouble();
    qDebug()<<map["string"]<<map["string"].toString();
    qDebug()<<map["color"]<<map["color"].value<QColor>();
    QStringList sl;
    sl<<"a"<<"b"<<"c"<<"d";
    QVariant slv(sl); if (slv.type() == QVariant::StringList){ QStringList list = slv.toStringList();
    for (auto c: list)
    qDebug()<<c;
    }
    } Widget::~Widget()
    { }

QT之Variant的更多相关文章

  1. QT内省机制、自定义Model、数据库

    本文将介绍自定义Model过程中数据库数据源的获取方法,我使用过以下三种方式获取数据库数据源: 创建 存储对应数据库所有字段的 结构体,将结构体置于容器中返回,然后根据索引值(QModelIndex) ...

  2. QT QString 很全的使用 (转)

    QString, QByteArray, 和 QVariant这三个类和容器有许多相同之处,并且在一些情况下可以被当作特殊的容器. 同样,像容器,这些类使用隐式共享来优化内存和速度. 我们将从QStr ...

  3. Qt中使用ActiveX(3篇)

    由于最近需要使用ActiveX,一般来说可以使用微软提供的MFC或者ATL框架来开发,由于我个人对这部分内容不是很熟悉,好在Qt也提供对于ActiveX的支持.本文主要记录个人学习ActiveX的一些 ...

  4. Qt 显示透明flash和编写QtWebkit插件

    Qt 有两种方法可以显示flash. 1. 通过QAxWidget 调用com形式显示flash, 需要本机安装IE flash插件 2. 直接通过qwebview显示flash, 需要下载webki ...

  5. Qt之界面数据存储与获取(使用setUserData()和userData())

    在GUI开发中,往往需要在界面中存储一些有用的数据,这些数据可以来配置文件.注册表.数据库.或者是server. 无论来自哪里,这些数据对于用户来说都是至关重要的,它们在交互过程中大部分都会被用到,例 ...

  6. qt 总结

    Qt中的每个类,都有一个对应的同名头文件,其中包含其类定义.例如要使用QApplication类,则需要在程序中添加" #include <QApplication>" ...

  7. QT中的字符串处理函数

    Fn 1 : arg 这个函数的具体声明不写了,它有20个重载,典型的示例代码如下: 1: #include <QtCore/QCoreApplication> 2: #include & ...

  8. Qt 学习之路 :使用 QJson 处理 JSON

    XML 曾经是各种应用的配置和传输的首选方式.但是现在 XML 遇到了一个强劲的对手:JSON.我们可以在 这里 看到有关 JSON 的语法.总体来说,JSON 的数据比 XML 更紧凑,在传输效率上 ...

  9. Qt 学习之路 2(80):定位器

    QML 提供了很多用于定位的元素.这些元素叫做定位器,都包含在 QtQuick 模块.这些定位器主要有 Row.Column.Grid和Flow等. 为了介绍定位器,我们先添加三个简单的组件用于演示: ...

随机推荐

  1. Linux编译前提前丰富库资源

    Linux在软件编译的时候,时常提示一些依赖,无谓浪费时间.我们可以事先将常用的依赖包,一起安装一下,防止后续编译过程被打断. 之前,有个很重要的前提,就是epel源的安装. # ls /etc/yu ...

  2. Go - 类型与变量

    类型 Go 语言中的类型与其他语言类似,比较特殊的有以下几个: bool 类型 - 它的值只能是 true 与 false. int / uint - 它们的长度会根据操作系统的不同(32/64 bi ...

  3. POJ-2282题解&数位DP总结

    一.题意 给定一个区间[a, b](注意输入的时候可能a > b,所以,在数据输入后,要先比较a和b,如果a > b,交换a和b的值),统计这个区间里面,数位上有多少个0.多少个1.--. ...

  4. 经典的CNN网络模型概述

    接下来几天,将把自己最近读的关于图片分类的经典网络模型论文整理一遍.大概做个摘要.这些论文都是在imagenet上1.2 million数据训练出来的. 由于从这些预训练的网络训练的deep feat ...

  5. Cinder Backup备份

    cinder 备份提供了三种驱动服务: Ceph,TSM,Swift 其中默认备份驱动服务为swift cinder 驱动服务的配置在cinder.conf文件中 backup_driver=cind ...

  6. 13.solr学习速成之IK分词器

    IKAnalyzer简介 IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包. IKAnalyzer特性 a. 算法采用“正向迭代最细粒度切分算法”,支持细粒度和最大词长两 ...

  7. nginx的下载和安装

    安装 下载必要组件 nginx下载地址 http://nginx.org/en/download.html  pcre库下载地址,nginx需要[解析正则] http://sourceforge.ne ...

  8. 跟我学算法聚类(DBSCAN)

    DBSCAN 是一种基于密度的分类方法 若一个点的密度达到算法设定的阖值则其为核心点(即R领域内点的数量不小于minPts) 所以对于DBSCAN需要设定的参数为两个半径和minPts 我们以一个啤酒 ...

  9. django html模板继承 {%block 标记名} {%endblock%}

    对于url文件 url(r'^tp1/', views.tp1) 对于views文件,跳转到tp1.html 同时将list列表传到前端 def tp1(request): list = [1, 2, ...

  10. ELK 日志管理系统,初次尝试记录

    简介: ELK 是一套开源的日志管理平台,主要包括三个组件,可以用于日志的收集.分析.存储和展示工作. ELK 成员:Elasticsearch .Logstash .Kibana( K4 ) ELK ...