前面学习了Qt中的模型-视图,在模型中有一个常用的模型类,通用模型类QStandardItemModel,它是既支持表格形式存放数据项,又支持树形存放数据项的模型,在日常开发中比较常用。在讲解QVariant类之前,先来看看通用模型类QStandardItemModel。
1. 通用模型类QStandardItemModel
作为一个通用模型类,QStandardItemModel能够以任意方式(线性/非线性)组织数据,数据组织的基本单位为数据项QStandarItem,每个数据项能够存储多个具体的数据,需要使用数据角色来设置这多个数据(不然视图无法知道数据如何显示),每个数据项可以对数据状态进行设置,如可编辑、可选。QStandardItemModelQStandardItemModel在项目中的角色大抵如此:
QStandardItemModel继承自QAbstractItemModel类,QStandardItemModel类内有两个重要类:表示数据项的QStandardItem和对数据项进行索引使用的QModelIndex。QStandardItemModel作为一个模型类,它可供视图存取数据。
2. 万能数据类型QVariant类
在前面讲过,索引接口定义在QAbstractItemModel类中,它是一个虚函数:
virtual QModelIndex index(int row,int column, const QModelIndex &parent = QModelIndex()) const = 0;
它的返回值类型为QVariant类,那么上补充上图为:
通用模型类中存储的数据项的数据类型可能double、QString、int等常见的数据类型,那么index()函数的返回值大可以是一个联合体?其实不然,因为c++禁止联合体中包含有非默认的构造函数和析构函数的类型,也就是说许多继承的Qt类不能在联合体中使用,如QString(关于联合体和类的配合使用在文章http://blog.csdn.net/qq_29344757/article/details/78060189有介绍)。这就需要引入跟联合体功能类似的QVariant类。
QVariant类的常用函数有:
bool isNull(); //判断数据项是否为空
bool isValid(); //判断是否为QVariant类对象
void setValue(); //设置QVariant类对象的值
Type type(); //返回QVariant类数据项的类型
const char* typeName(); //返回QVariant类数据项的类型
T value(); //返回数据项的值,注意这是一个函数模板,使用该函数时需要指定T的具体类型
QVariant类的使用,可参照下面代码片段:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVariant v1(6);
qDebug() << v1.type(); //QVariant::in
qDebug() << v1.typeName(); //int
qDebug() << v1.toInt(); //6
qDebug() << endl;
QVariant v2(0.618);
qDebug() << v2.type(); //QVariant::double
qDebug() << v2.typeName(); //double
qDebug() << v2.toInt(); //1
qDebug() << v2.toDouble(); //0.618
qDebug() << v2.value<double>(); //0.618
qDebug() << endl;
QVariant v3("456");
qDebug() << v3.type(); //QVariant::QString
qDebug() << v3.typeName(); //QString
qDebug() << v3.toInt(); //456
qDebug() << v3.value<QString>(); //"456"
qDebug() << endl;
QVariant v4(QPoint(16, 16));
bool ok = true;
qDebug() << v4.type(); //QVariant::QPoint
qDebug() << v4.typeName(); //QPoint
qDebug() << v4.toInt(&ok); //0
qDebug() << ok; //false,QPoint转换为int类型肯定失败
qDebug() << v4.toPoint(); //QPoint(16,16)
qDebug() << endl;
QVariant v5;
qDebug() << v5.isValid(); //false,v5没有设置值
return a.exec();
}
要为QVariant增加程序员自定义的类型,需要先注册,如:
class hello{
public:
int a;
char c;
};
Q_DECLARE_METATYPE(hello)
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
hello h;
h.a = 12;
h.c = 'c';
QVariant v3;
v3.setValue(h);
qDebug() << v3.type(); //QVariant::UserType
qDebug() << v3.typeName(); //hello
}