RTTR qt通用对象编辑表格

原创
2020/02/25 11:56
阅读数 1.6K

描述

    在应用开发中,经常有中需求就是每一个对象然后使用表格来编辑这个对象的属性,缺少一个通用性的做法就是针对每一个对象来实现一个tablemodel来实现编辑功能。结合RTTR可以非常简便的实现一个通用的编辑器

上图针对不用的属性使用了不同的控件来进行编辑,下面简要说明实际原理。

 

说明

    

    QApplication a(argc, argv);
    QTableView tableView;

    Bean bean;
    bean.a = 1;
    bean.b = 2;
    bean.c = 3;
    bean.d = true;
    bean.name = "test";
    QRTTRTableModel *_tableModel = new QRTTRTableModel(bean);
    tableView.setModel(_tableModel);
    tableView.setItemDelegate(new RTTRItemDelegate(_tableModel));
    tableView.show();
    return a.exec();

 

QRTTRTableModel是一个通用的tableModel,只要传入一个RTTR对象,就会自动遍历这个对象的属性创建model,并设置对应的itemDelegate就可以实现tableView的编辑功能,详细代码 https://github.com/onier/puppy/blob/master/puppycommon/src/model/QRTTRTableModel.cpp

 

关键代码如下,Data获取RTTR对象的表格数据,根据每一个属性的类型,或者对应的具体数据。

setData方法根据每一个属性的类型设置给对象。

QVariant QRTTRTableModel::data(const QModelIndex &index, int role) const {
    if (role == Qt::DisplayRole) {
        auto properties = getProperties(_instance);
        int col = index.column();
        int row = index.row();
        if (col == 0) {
            return properties[row].get_name().data();
        }
        std::string keyType = properties[row].get_type().get_name().data();
        if (keyType == "std::string") {
            return properties[row].get_value(_instance).to_string().data();
        } else if (keyType == "double") {
            return properties[row].get_value(_instance).to_double();
        } else if (keyType == "int") {
            return properties[row].get_value(_instance).to_int();
        } else if (keyType == "float") {
            return properties[row].get_value(_instance).to_float();
        } else if (keyType == "long") {
            return properties[row].get_value(_instance).to_int();
        } else if (keyType == "bool") {
            return properties[row].get_value(_instance).to_bool();
        } else if (properties[row].is_enumeration()) {
            return properties[row].get_enumeration().value_to_name(properties[row].get_value(_instance)).data();
        }

    }
    return QVariant();
}

bool QRTTRTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
    if (role == Qt::EditRole) {
        auto properties = getProperties(_instance);
        auto type = properties[index.row()].get_type();
        std::string keyType = type.get_name().data();
        if (keyType == "std::string") {
            properties[index.row()].set_value(_instance, value.toString().toStdString());
        } else if (keyType == "double") {
            properties[index.row()].set_value(_instance, value.toDouble());
        } else if (keyType == "int") {
            properties[index.row()].set_value(_instance, value.toInt());
        } else if (keyType == "float") {
            properties[index.row()].set_value(_instance, value.toFloat());
        } else if (keyType == "long") {
            properties[index.row()].set_value(_instance, value.toLongLong());
        } else if (keyType == "bool") {
            properties[index.row()].set_value(_instance, value.toBool());
        } else if (properties[index.row()].is_enumeration()) {
            auto var = properties[index.row()].get_enumeration().name_to_value(value.toString().toStdString().data());
            auto ret = properties[index.row()].set_value(_instance, var);
            LOG(INFO) << "ret  " << ret;
        }
    }
    return QAbstractItemModel::setData(index, value, role);
}

通过上述rttr提供的反射性质可以非常简单的实现一个通用的表格编辑器。

总结

    目前只支持基础数据类型,以及枚举类型。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部