千家信息网

Qt如何实现加载属性

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章给大家分享的是有关Qt如何实现加载属性的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、前言控件能加载拖曳拉伸了,这些都是基本的前提工作,接下来的重点就是要动态加载
千家信息网最后更新 2026年11月03日Qt如何实现加载属性

这篇文章给大家分享的是有关Qt如何实现加载属性的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

一、前言

控件能加载拖曳拉伸了,这些都是基本的前提工作,接下来的重点就是要动态加载选中控件的属性了,Qt的属性机制那是异常的强大,只能用强大到爆来形容,Qt中编写自定义控件,如果属性都用Q_PROPERTY来描述过,那都支持整个Qt生态环境中的各种应用场景的加载,比如widget的属性设计,qml中的属性识别等,都是非常的方便。 仔细观察QtDesigner设计器的属性控件,看起来和表格控件很类似,如果自己重新造轮子整一个,需要花费巨大的代价,其实Qt已经有这个开源组件在qt-solutions-master中,名字叫qtpropertybrowser,搜索下有很多该组件的使用方法,demo也是非常的详细,本人改过其中的部分代码以便过滤父类属性和中文属性映射等。

二、实现的功能

  1. 自动加载插件文件中的所有控件生成列表,默认自带的控件超过120个。

  2. 拖曳到画布自动生成对应的控件,所见即所得。

  3. 右侧中文属性栏,改变对应的属性立即应用到对应选中控件,直观简洁,非常适合小白使用。

  4. 独创属性栏文字翻译映射机制,效率极高,可以非常方便拓展其他语言的属性栏。

  5. 所有控件的属性自动提取并显示在右侧属性栏,包括枚举值下拉框等。

  6. 支持手动选择插件文件,外部导入插件文件。

  7. 可以将当前画布的所有控件配置信息导出到xml文件。

  8. 可以手动选择xml文件打开控件布局,自动根据xml文件加载控件。

  9. 可拉动滑动条、勾选模拟数据复选框、文本框输入,三种方式来生成数据应用所有控件。

  10. 控件支持八个方位拉动调整大小,自适应任意分辨率,可键盘上下左右微调位置。

  11. 打通了串口采集、网络采集、数据库采集三种方式设置数据。

  12. 代码极其精简,注释非常详细,可以作为组态的雏形,自行拓展更多的功能。

  13. 纯Qt编写,支持任意Qt版本+任意编译器+任意系统。

三、效果图

四、核心代码

void QtObjectController::setObject(QObject *object){    //如果设置的控件已经是当前控件则不处理    if (d_ptr->m_object == object) {        return;    }    if (d_ptr->m_object) {        d_ptr->saveExpandedState();        QListIterator it(d_ptr->m_topLevelProperties);        while (it.hasNext()) {            d_ptr->m_browser->removeProperty(it.next());        }        d_ptr->m_topLevelProperties.clear();    }    d_ptr->m_object = object;    if (!d_ptr->m_object) {        return;    }    //加载父类的属性    d_ptr->addClassPropertiesParent(d_ptr->m_object->metaObject()->superClass());    //加载当前控件的属性    d_ptr->addClassProperties(d_ptr->m_object->metaObject());    //存储节点状态    d_ptr->restoreExpandedState();    //折叠所有节点    d_ptr->collapseAll();}void QtObjectControllerPrivate::addClassProperties(const QMetaObject *metaObject){    if (!metaObject) {        return;    }    QtProperty *classProperty = m_classToProperty.value(metaObject);    if (!classProperty) {        QString className = QLatin1String(metaObject->className());        classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className);        m_classToProperty[metaObject] = classProperty;        m_propertyToClass[classProperty] = metaObject;        for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) {            QMetaProperty metaProperty = metaObject->property(idx);            int type = metaProperty.userType();            QtVariantProperty *subProperty = 0;            //将英文属性换成中文属性            QString propertyName = metaProperty.name();            propertyName = QtPropertyName::maps.value(propertyName, propertyName);            if (!metaProperty.isReadable()) {                subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);                subProperty->setValue(QLatin1String("< Non Readable >"));            } else if (metaProperty.isEnumType()) {                if (metaProperty.isFlagType()) {                    subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), propertyName);                    QMetaEnum metaEnum = metaProperty.enumerator();                    QMap valueMap;                    QStringList flagNames;                    for (int i = 0; i < metaEnum.keyCount(); i++) {                        int value = metaEnum.value(i);                        if (!valueMap.contains(value) && isPowerOf2(value)) {                            valueMap[value] = true;                            flagNames.append(QLatin1String(metaEnum.key(i)));                        }                        subProperty->setAttribute(QLatin1String("flagNames"), flagNames);                        subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt()));                    }                } else {                    subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), propertyName);                    QMetaEnum metaEnum = metaProperty.enumerator();                    QMap valueMap; // dont show multiple enum values which have the same values                    QStringList enumNames;                    for (int i = 0; i < metaEnum.keyCount(); i++) {                        int value = metaEnum.value(i);                        if (!valueMap.contains(value)) {                            valueMap[value] = true;                            //将枚举类型强制转为中文                            QString enumName = metaEnum.key(i);                            enumName = QtPropertyName::maps.value(enumName, enumName);                            enumNames.append(enumName);                        }                    }                    subProperty->setAttribute(QLatin1String("enumNames"), enumNames);                    subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt()));                }            } else if (m_manager->isPropertyTypeSupported(type)) {                if (!metaProperty.isWritable()) {                    subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Writable)"));                }                if (!metaProperty.isDesignable()) {                    subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Designable)"));                } else {                    subProperty = m_manager->addProperty(type, propertyName);                }                subProperty->setValue(metaProperty.read(m_object));            } else {                subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);                subProperty->setValue(QLatin1String("< Unknown Type >"));                subProperty->setEnabled(false);            }            classProperty->addSubProperty(subProperty);            m_propertyToIndex[subProperty] = idx;            m_classToIndexToProperty[metaObject][idx] = subProperty;        }    } else {        updateClassProperties(metaObject, false);    }    m_topLevelProperties.append(classProperty);    m_browser->addProperty(classProperty);}void QtObjectControllerPrivate::addClassPropertiesParent(const QMetaObject *metaObject){    if (!metaObject) {        return;    }    //存储需要过滤的属性,有时候大部分属性都用不上    QStringList keyName;    keyName << "geometry";    QtProperty *classProperty = m_classToProperty.value(metaObject);    if (!classProperty) {        QString className = QLatin1String(metaObject->className());        classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className);        m_classToProperty[metaObject] = classProperty;        m_propertyToClass[classProperty] = metaObject;        for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) {            QMetaProperty metaProperty = metaObject->property(idx);            int type = metaProperty.userType();            QtVariantProperty *subProperty = 0;            //如果当前属性不在需要过滤的属性中则继续下一个属性判断            QString propertyName = metaProperty.name();            if (!keyName.contains(propertyName)) {                continue;            }            propertyName = QtPropertyName::maps.value(propertyName, propertyName);            if (!metaProperty.isReadable()) {                subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);                subProperty->setValue(QLatin1String("< Non Readable >"));            } else if (metaProperty.isEnumType()) {                if (metaProperty.isFlagType()) {                    subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), propertyName);                    QMetaEnum metaEnum = metaProperty.enumerator();                    QMap valueMap;                    QStringList flagNames;                    for (int i = 0; i < metaEnum.keyCount(); i++) {                        int value = metaEnum.value(i);                        if (!valueMap.contains(value) && isPowerOf2(value)) {                            valueMap[value] = true;                            flagNames.append(QLatin1String(metaEnum.key(i)));                        }                        subProperty->setAttribute(QLatin1String("flagNames"), flagNames);                        subProperty->setValue(flagToInt(metaEnum, metaProperty.read(m_object).toInt()));                    }                } else {                    subProperty = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), propertyName);                    QMetaEnum metaEnum = metaProperty.enumerator();                    QMap valueMap; // dont show multiple enum values which have the same values                    QStringList enumNames;                    for (int i = 0; i < metaEnum.keyCount(); i++) {                        int value = metaEnum.value(i);                        if (!valueMap.contains(value)) {                            valueMap[value] = true;                            enumNames.append(QLatin1String(metaEnum.key(i)));                        }                    }                    subProperty->setAttribute(QLatin1String("enumNames"), enumNames);                    subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt()));                }            } else if (m_manager->isPropertyTypeSupported(type)) {                if (!metaProperty.isWritable()) {                    subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Writable)"));                }                if (!metaProperty.isDesignable()) {                    subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Designable)"));                } else {                    subProperty = m_manager->addProperty(type, propertyName);                }                subProperty->setValue(metaProperty.read(m_object));            } else {                subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);                subProperty->setValue(QLatin1String("< Unknown Type >"));                subProperty->setEnabled(false);            }            classProperty->addSubProperty(subProperty);            m_propertyToIndex[subProperty] = idx;            m_classToIndexToProperty[metaObject][idx] = subProperty;        }    } else {        updateClassProperties(metaObject, false);    }    m_topLevelProperties.append(classProperty);    m_browser->addProperty(classProperty);}

感谢各位的阅读!关于"Qt如何实现加载属性"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

属性 控件 文件 数据 支持 代码 插件 更多 中文 应用 强大 内容 功能 右侧 手动 方式 机制 画布 篇文章 组件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 有格互联网科技 互联网科技工作委员会毛军 互联网科技与金融科技 合肥互联网科技公司 奇酷互联网科技公司 广州宏创互联网科技 科技伦理 互联网公司 互联网实体化科技化 中国的互联网科技企业的崛起 岳阳华臻互联网科技有限公司 互联网科技人工智能实验室 明优互联网科技有限公司 山东有哪些互联网科技公司 科技互联网的核心竞争力 山东星卡互联网科技有限公司官网 每天都有哪些好的互联网科技 郑州欣桑互联网科技有限公司 数字互联网科技有限公司 长沙易易互联网科技有限公司 上海互联网科技园景观 互联网科技公司经营范围 新华互联网科技学校 高科技与互联网 九亚互联网科技 博兴的互联网电子科技公司 互联网还是高科技吗 知域互联网科技有限公司大骗子 坤平互联网科技 上海同邻互联网科技有限公司规模 云南互联网科技学费
0