123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704 |
-
- #include <QMetaObject>
- #include <QMetaProperty>
- #include <QVBoxLayout>
- #include <QScrollArea>
- #include <QApplication>
- #include <QDebug>
- #include "objectcontroller.h"
- #include "qtvariantproperty.h"
- #include "qtgroupboxpropertybrowser.h"
- #include "qttreepropertybrowser.h"
- #include "qtpropertybrowser.h"
- #include "variantfactory.h"
- #include "variantmanager.h"
- #include "vpControls/VTableControl.h"
- #include "vpControls/VPieChart.h"
- #include "vpControls/VCustomPlot.h"
- #include "vpControls/VImageControl.h"
- #include "UiManager.h"
- // #include "WindowAppUiView.h"
- #define PROPERTY_EX_MISC "杂项"
- QMap<QString, QString> propertyNamesMap;
- class ObjectControllerPrivate
- {
- // 基础属性的中英文对照表
- ObjectControllerPrivate()
- {
- propertyNamesMap.insert("tip", "文本");
- propertyNamesMap.insert("title", "标题");
- propertyNamesMap.insert("dataLink", "链接");
- propertyNamesMap.insert("textColor", "文本色");
- propertyNamesMap.insert("bgColor", "背景色");
- propertyNamesMap.insert("Red", "红");
- propertyNamesMap.insert("Green", "绿");
- propertyNamesMap.insert("Blue", "蓝");
- propertyNamesMap.insert("Alpha", "明度");
- propertyNamesMap.insert("font", "字体");
- propertyNamesMap.insert("enable", "启用");
- propertyNamesMap.insert("rowCount", "行数");
- propertyNamesMap.insert("colCount", "列数");
- propertyNamesMap.insert("borderColor", "边框色");
- propertyNamesMap.insert("sliceCount", "分块数");
- propertyNamesMap.insert("lineCount", "曲线数");
- propertyNamesMap.insert("objCount", "图层数");
- propertyNamesMap.insert("tupleCount", "文本数");
- propertyNamesMap.insert("displayCount", "显示数");
- propertyNamesMap.insert("geometry", "形状");
- propertyNamesMap.insert("interactions", "交互模式");
- propertyNamesMap.insert("drawingMode", "绘图模式");
- propertyNamesMap.insert("rangeX", "x轴范围");
- propertyNamesMap.insert("rangeY", "y轴范围");
- propertyNamesMap.insert("tickCountX", "x网格数");
- propertyNamesMap.insert("tickCountY", "y网格数");
- m_pVcontrol = nullptr;
- q_ptr = nullptr;
- m_object = nullptr;
- m_browser = nullptr;
- m_manager = nullptr;
- m_readOnlyManager = nullptr;
- }
- ObjectController *q_ptr;
- Q_DECLARE_PUBLIC(ObjectController)
- public:
- void expandAll();
- void collapseAll();
- void saveExpandedState();
- void restoreExpandedState();
- // 数值变更
- void slotValueChanged(QtProperty *property, const QVariant &value);
- //=======================================================
- // 辅助类型转换函数
- int enumToInt(const QMetaEnum &metaEnum, int enumValue) const;
- int intToEnum(const QMetaEnum &metaEnum, int intValue) const;
- int flagToInt(const QMetaEnum &metaEnum, int flagValue) const;
- int intToFlag(const QMetaEnum &metaEnum, int intValue) const;
- bool isSubValue(int value, int subValue) const;
- bool isPowerOf2(int value) const;
- // 获取属性的中文名称
- QString chName(const QString& enName);
- //=======================================================
- // 基础控件相关
-
- // 设置控件属性
- void setBasicControlProperties(const QMetaObject* metaObject);
- // 设置复杂控件属性
- void setComplexControlProperties(const QMetaObject* metaObject);
- // 构建新的基础属性表
- void buildBasicProperty(const QMetaObject* metaObject, QtProperty*& classProperty);
- // 更新基础属性
- void changeBasicProperties(QtProperty* property, const QVariant& value);
- // 更新基础属性表
- void updateBasicProperties(const QMetaObject* metaObject);
- // 2022-2-12 更新geometry属性
- // (针对geometry专门处理一下,因为这个属性比较特殊,不需要手工处理,只需要刷新一下界面)
- void changeGeometryProperty(const QVariant& value);
- // 2022-2-13 用户控件到属性表的同步
- void syncToPropertyTable(QObject* pControl, const OBJECT_SYNC_PROPERTY& syncInfo);
- // 2022-2-14 保存到同步列表中
- void saveToSyncProperty(OBJECT_SYNC_TYPE type, QtVariantProperty* prop);
- //=======================================================
- // 复杂控件相关
- // 构建控件扩展属性表
- void buildExtendProperty(QtProperty*& objectProperty);
- // 构建控件扩展属性表中的主索引部分
- void buildPropertyMainLinks(QtProperty*& objectProperty);
- // 构建控件扩展属性表中的分组部分
- void buildPropertyGroups(QtProperty*& objectProperty);
- // 构建控件扩展属性表中的子分组部分(2022-1-25,增加了分组ID)
- void buildPropertySubGroup(const int groupID, const PROPERTY_EX_SUBGROUP& prop, QtProperty*& subGroupRoot);
- // 修改控件的扩展属性
- void changeExtendProperties(QtProperty* property, const QVariant& value);
- //// 更新基础属性表
- //void updateBasicProperties(const QMetaObject* metaObject);
- // 更新扩展属性表
- void updateExtendProperties(QtProperty*& objectProperty);
- //// 动态增加新的属性项
- //void appendExtendPropertiesCount(const int fixCount, const QString& propertyName);
- //// 动态减少新的属性项
- //void removeExtendPropertiesCount(const int fixCount, const QString& propertyName);
- // 动态调整属性项
- void updateExtendPropertiesCount(const int newCount, const QString& propertyName);
- // 仅展开扩展属性项
- void setExtendItemsExpandOnly();
- //// 2022-2-7为了解决反序列化时数据链接数值无法自动显示的问题,增加此函数
- //void setDataLinkItem(QtVariantProperty*& item, const DataLink& dataLink);
- //// 根据类型获取对应的VControlObject指针
- //VControlObject* controlObject();
- // 当前控件是否是 Table
- bool isVTableControl();
- // 当前控件是否是 Pie
- bool isVPieChart();
- // 当前控件是否是 Wave
- bool isVCustomPlot();
- // 当前控件是否是 Image
- bool isVImageControl();
- public:
- // 绑定的控件对象指针
- QObject *m_object;
- // Object的VControlObject对象
- VControlObject *m_pVcontrol;
- // 属性和QMetaObject的双向对应关系(用于简单控件)
- // QMap<const QMetaObject *, QtProperty *> m_classToProperty;
- // 属性和Index索引的对应关系
- QMap<QtProperty *, int> m_propertyToIndex;
- // QMetaObject和索引以及对应属性的关系
- // QMap<const QMetaObject *, QMap<int, QtVariantProperty *> > m_classToIndexToProperty;
- QMap<const QObject*, QMap<int, QtVariantProperty*> > m_objectToIndexToProperty;
- // 每个属性是否展开
- QMap<QtProperty *, bool> m_propertyToExpanded;
- // 属性表顶层节点
- QList<QtProperty *> m_topLevelProperties;
- // 2021-9-11 修改 此处直接使用 QtTreePropertyBrowser 指针即可
- QtTreePropertyBrowser *m_browser;
- // 属性数据结构管理者
- QtVariantPropertyManager *m_manager;
- // 只读属性数据结构管理者
- QtVariantPropertyManager *m_readOnlyManager;
- // 2021-12-2 属性指针与属性名字对应关系
- QMap<QtProperty*, QString> m_propertyToName;
- // 2022-1-15,每个控件对应的属性分组根节点
- QMap < const QObject*, QVector<QtProperty*>> m_objectToGroups;
- // 2021-12-3 控件与对应的扩展子属性组
- // QMap < const QObject*, QVector<QtProperty*>> m_objectToSubGroups;
- // 2022-1-25,由于此处数据结构变动,Group-SubGroup的关系只能这样定义了
- QMap < const QtProperty*, QVector<QtProperty*>> m_groupToSubGroups;
- // 2021-12-23 用于保存对象以及扩展属性的对应关系,用于后续更新
- QMap<const QObject*, QMap<QString, QtVariantProperty*>> m_objectToNameToProperty;
- // 属性和QObject的双向对应关系(用于复杂控件)
- QMap<const QObject*, QtProperty*> m_objectToProperty;
- // 2022-2-13 使用,用于控件属性到属性表的同步
- QMap<const QObject*, QVector<OBJECT_SYNC_PROPERTY>> m_objectToSyncProperty;
- };
- //=======================================================================
- //
- // 简单控件属性表处理
- //
- //=======================================================================
- /// <summary>
- /// 设置控件属性
- /// </summary>
- /// <param name="metaObject"></param>
- void ObjectControllerPrivate::setBasicControlProperties(const QMetaObject* metaObject)
- {
- if (!metaObject)
- {
- return;
- }
- // 取出属于本控件的控件属性组
- QtProperty* objectProperty = m_objectToProperty.value(m_object);
- // 重新创建新的属性表
- if (!objectProperty)
- {
- // 首先添加基础属性
- buildBasicProperty(metaObject, objectProperty);
- }
- // 如果之前已经创建过本类型控件的属性表,那么直接从数据结构中更新即可
- else
- {
- // 首先更新基础属性
- // updateProperties(metaObject);
- }
- // 保存根节点
- m_topLevelProperties.append(objectProperty);
- // 界面中添加此根节点
- m_browser->addProperty(objectProperty);
- // 基础属性表全部不展开
- this->collapseAll();
- }
- /// <summary>
- /// 构建新的基础属性表
- /// </summary>
- /// <param name="metaObject"></param>
- /// <param name="classProperty"></param>
- void ObjectControllerPrivate::buildBasicProperty(const QMetaObject *metaObject, QtProperty*& objectProperty)
- {
- // 清空需要同步的属性关系,重新建立
- // m_objectToSyncProperty.clear();
- // 获取类名,根据类型名建立属性表根节点
- QString className = QLatin1String(metaObject->className());
- // 创建根节点
- objectProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className);
- // 保存根节点和控件对象的对应关系
- m_objectToProperty[m_object] = objectProperty;
- int nPropertyCount = metaObject->propertyCount();
- int nPropertyOffset = metaObject->propertyOffset();
- // 遍历所有的固定属性执行添加
- for (int idx = nPropertyOffset; idx < nPropertyCount; idx++)
- {
- // 取出对应的固定属性
- QMetaProperty metaProperty = metaObject->property(idx);
- // 取出属性的Type值
- int type = metaProperty.userType();
- // 准备添加子属性节点(注意要保存带值的子属性,需要用QtVariantProperty类型)
- QtVariantProperty* subProperty = 0;
- // 翻译后的属性名称
- QString propertyName = chName(metaProperty.name());
-
- // 确保是所支持的类型
- if (m_manager->isPropertyTypeSupported(type))
- {
- // 添加属性
- subProperty = m_manager->addProperty(type, propertyName);
- // 设置值
- // 2022-2-8 针对数据连接专门处理了一下,要不直接从metaProperty里读不出来
- if (propertyName != "链接")
- {
- QVariant var = metaProperty.read(m_object);
- subProperty->setValue(var);
- }
- else
- {
- subProperty->setValue(m_pVcontrol->m_Property.m_DataLink.toString());
- }
- if (propertyName == "图层数" ||
- propertyName == "文本数" ||
- propertyName == "显示数" ||
- propertyName == "曲线数"
- )
- {
- subProperty->setAttribute(QLatin1String("minimum"), 0);
- subProperty->setAttribute(QLatin1String("maximum"), 10);
- subProperty->setAttribute(QLatin1String("singleStep"), 1);
- }
- // 2022-2-13 如果属性是形状或者标题,则需要额外保存一下
- else if (propertyName == "标题")
- {
- saveToSyncProperty(OBJECT_SYNC_TYPE::SYNC_TITLE, subProperty);
- }
- else if (propertyName == "形状")
- {
- saveToSyncProperty(OBJECT_SYNC_TYPE::SYNC_GEOMETRY, subProperty);
- //QMap<OBJECT_SYNC_TYPE, QtVariantProperty*> syncProp;
- //syncProp.insert(OBJECT_SYNC_TYPE::SYNC_TITLE, subProperty);
- //m_objectToSyncProperty.insert(m_object, syncProp);
- }
- }
- // 设置无效属性
- else
- {
- subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName);
- subProperty->setValue(QLatin1String("< Unknown Type >"));
- subProperty->setEnabled(false);
- }
- // 根节点下添加此子节点
- objectProperty->addSubProperty(subProperty);
- // 保存此子属性和索引值的对应关系
- m_propertyToIndex[subProperty] = idx;
- // 保存根节点下所有子节点和子属性的对应关系
- m_objectToIndexToProperty[m_object][idx] = subProperty;
- }
- }
- /// <summary>
- /// 更新基础属性表
- /// </summary>
- /// <param name="metaObject"></param>
- /// <param name="recursive"></param>
- void ObjectControllerPrivate::updateBasicProperties(const QMetaObject* metaObject)
- {
- if (!metaObject)
- {
- return;
- }
- // 遍历所有的属性更新数值
- for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++)
- {
- QMetaProperty metaProperty = metaObject->property(idx);
- if (metaProperty.isReadable())
- {
- // 从数据结构中找到对应的子属性
- if (m_objectToIndexToProperty.contains(m_object)
- && m_objectToIndexToProperty[m_object].contains(idx))
- {
- QtVariantProperty* subProperty = m_objectToIndexToProperty[m_object][idx];
-
- // 设置属性值
- QVariant propertyValue = metaProperty.read(m_object);
- subProperty->setValue(propertyValue);
- }
- }
- }
- }
- /// <summary>
- /// 2022-2-12 更新geometry属性
- /// (针对geometry专门处理一下,因为这个属性比较特殊,不需要手工处理,只需要刷新一下界面)
- /// </summary>
- void ObjectControllerPrivate::changeGeometryProperty(const QVariant& value)
- {
- // WindowAppUiView* pUiView = g_pUiManager->getViewByControl(m_pVcontrol);
- // 按照属性表中的值重新设置控件形状
- m_pVcontrol->m_pWidget->setGeometry(value.toRect());
- // 界面中刷新此控件
- g_pUiManager->refreshControlDrawPoint(m_pVcontrol);
- }
- /// <summary>
- /// 同步指定的属性值到属性表中
- /// </summary>
- /// <param name="value"></param>
- /// <param name="syncType"></param>
- void ObjectControllerPrivate::syncToPropertyTable(QObject* pControl, const OBJECT_SYNC_PROPERTY& syncInfo)
- {
- QtVariantProperty* syncProp = nullptr;
- // 找出需要同步的Property指针
- QVector<OBJECT_SYNC_PROPERTY>& propInfos = m_objectToSyncProperty[pControl];
- for (auto propInfo : propInfos)
- {
- if (propInfo.type == syncInfo.type)
- {
- syncProp = propInfo.prop;
- break;
- }
- }
- if (syncProp == nullptr)
- {
- //qWarning() << "[Error] ObjectControllerPrivate::syncToPropertyTable - syncProp is nullptr.";
- return;
- }
- int idx = m_propertyToIndex.value(syncProp);
- // 更新MetaObject中的值
- const QMetaObject* metaObject = m_object->metaObject();
- QMetaProperty metaProperty = metaObject->property(idx);
- metaProperty.write(m_object, syncInfo.value);
- // 更新对应的属性表
- syncProp->setValue(syncInfo.value);
- }
- /// <summary>
- /// 2022-2-14 保存到同步列表中
- /// </summary>
- /// <param name="type"></param>
- /// <param name="prop"></param>
- void ObjectControllerPrivate::saveToSyncProperty(OBJECT_SYNC_TYPE type, QtVariantProperty* prop)
- {
- OBJECT_SYNC_PROPERTY propInfo;
- propInfo.type = type;
- propInfo.prop = prop;
- if (!m_objectToSyncProperty.contains(m_object))
- {
- QVector<OBJECT_SYNC_PROPERTY> syncProps;
- syncProps.push_back(propInfo);
- m_objectToSyncProperty.insert(m_object, syncProps);
- }
- else
- {
- QVector<OBJECT_SYNC_PROPERTY>& syncProps = m_objectToSyncProperty[m_object];
- syncProps.push_back(propInfo);
- }
- }
- //=======================================================================
- //
- // 复杂控件属性表处理
- //
- //=======================================================================
- /// <summary>
- /// 设置复杂控件属性
- /// </summary>
- void ObjectControllerPrivate::setComplexControlProperties(const QMetaObject* metaObject)
- {
- if (!m_object)
- {
- return;
- }
- // 取出属于本控件的控件属性组
- QtProperty* objectProperty = m_objectToProperty.value(m_object);
- // 重新创建新的属性表
- if (!objectProperty)
- {
- // 首先建立基础属性
- buildBasicProperty(metaObject, objectProperty);
- // 继续建立扩展属性
- buildExtendProperty(objectProperty);
- }
- // 如果之前已经创建过本类型控件的属性表,那么直接从数据结构中更新即可
- else
- {
- // 首先更新基础属性
- // updateProperties(metaObject);
- // 继续更新扩展属性
- // updateExtendProperties(objectProperty);
- }
- // 保存根节点
- m_topLevelProperties.append(objectProperty);
- // 界面中添加此根节点
- m_browser->addProperty(objectProperty);
- // 基础属性表全部不展开
- this->collapseAll();
- // 只展开扩展属性表以及子属性表的部分
- this->setExtendItemsExpandOnly();
- }
- ///// <summary>
- ///// 为复杂控件增加其中的基础属性
- ///// </summary>
- ///// <param name="metaObject"></param>
- ///// <param name="classProperty"></param>
- //void ObjectControllerPrivate::buildBasicProperties(const QMetaObject* metaObject, QtProperty*& objectProperty)
- //{
- //
- // buildProperties(metaObject, objectProperty);
- //
- //}
- //
- //
- ///// <summary>
- ///// 为复杂控件更新基础属性表
- ///// </summary>
- ///// <param name="metaObject"></param>
- //void ObjectControllerPrivate::updateBasicProperties(const QMetaObject* metaObject)
- //{
- // this->updateProperties(metaObject);
- //}
- /// <summary>
- /// 构建控件扩展属性表(仅复杂控件才有)
- /// </summary>
- /// <param name="metaObject"></param>
- /// <param name="classProperty"></param>
- void ObjectControllerPrivate::buildExtendProperty(QtProperty*& objectProperty)
- {
- // 构建控件扩展属性表中的主索引部分
- this->buildPropertyMainLinks(objectProperty);
- // 构建控件扩展属性表中的分组部分
- this->buildPropertyGroups(objectProperty);
- }
- /// <summary>
- /// 构建控件扩展属性表中的主索引部分
- /// </summary>
- /// <param name="objectProperty"></param>
- void ObjectControllerPrivate::buildPropertyMainLinks(QtProperty*& objectProperty)
- {
- // 取出对应的扩展属性
- const CONTROL_PROPERTY_EX& propex = m_pVcontrol->m_PropertyEx;
- // 建立主索引分类节点
- QtProperty* groupRoot = m_manager->addProperty(
- QtVariantPropertyManager::groupTypeId(),
- propex.m_strTitle
- );
- // 控件刷新索引链接
- QtVariantProperty* item = m_manager->addProperty(
- VariantManager::tagDataLinkTypeId(),
- propex.m_refreshLink.title
- );
- // 设置索引连接数值
- // this->setDataLinkItem(item, propex.m_refreshLink);
- item->setValue(propex.m_refreshLink.toString());
-
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, propex.m_refreshLink.title);
- // 添加此主刷新索引
- groupRoot->addSubProperty(item);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][propex.m_refreshLink.title] = item;
- // 控件主索引链接
- for (int i = 0; i < propex.m_mainDataLinks.size(); i++)
- {
- const DataLink& dataLink = propex.m_mainDataLinks[i];
- // 添加索引Property
- item = m_manager->addProperty(
- VariantManager::tagDataLinkTypeId(),
- dataLink.title
- );
- // 数据链接值
- item->setValue(dataLink.toString());
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, dataLink.title);
- // 添加此主索引
- groupRoot->addSubProperty(item);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][dataLink.title] = item;
- }
- // 在数据结构中保存本分类节点信息
- m_objectToGroups[m_object].push_back(groupRoot);
- // 在控件属性表中添加本属性分组根节点
- objectProperty->addSubProperty(groupRoot);
- }
- /// <summary>
- /// 构建控件扩展属性表中的分组部分
- /// </summary>
- /// <param name="objectProperty"></param>
- void ObjectControllerPrivate::buildPropertyGroups(QtProperty*& objectProperty)
- {
- // 取出对应的扩展属性
- const CONTROL_PROPERTY_EX& propex = m_pVcontrol->m_PropertyEx;
- // 循环添加控件扩展属性的每一个分组
- for (int i = 0; i < propex.m_groups.size(); i++)
- {
- const PROPERTY_EX_GROUP& group = propex.m_groups[i];
- // 建立分类根节点
- QtProperty* groupRoot = m_manager->addProperty(
- QtVariantPropertyManager::groupTypeId(),
- group.strTitle
- );
- // 循环将所有子项添加到属性表中
- for (int j = 0; j < group.subGroups.size(); j++)
- {
- this->buildPropertySubGroup(i, group.subGroups[j], groupRoot);
- }
- // 在数据结构中保存本分类节点信息
- m_objectToGroups[m_object].push_back(groupRoot);
- // 在控件属性表中添加本属性分组根节点
- objectProperty->addSubProperty(groupRoot);
- }
- }
- /// <summary>
- /// 更新扩展属性表
- /// </summary>
- void ObjectControllerPrivate::updateExtendProperties(QtProperty*& objectProperty)
- {
- Q_UNUSED(objectProperty);
- }
- /// <summary>
- /// 向界面属性表中增加属性内容(2022-1-25,增加了分组ID)
- /// Table 扩展属性项:列名、数据链接
- /// Pie 扩展属性项:分块名、分块颜色、数据链接
- /// Image 扩展属性项1:图层颜色、图层透明度、图层线宽、图层数据链接
- /// Image 扩展属性项2:文本颜色、文本横坐标、文本纵坐标、文本尺寸
- /// </summary>
- /// <param name="prop"></param>
- void ObjectControllerPrivate::buildPropertySubGroup(
- const int groupID,
- const PROPERTY_EX_SUBGROUP& subGroupInfo,
- QtProperty*& subGroupRoot
- )
- {
- // 创建子分组
- QtProperty* subGroup = m_manager->addProperty(
- QtVariantPropertyManager::groupTypeId(),
- subGroupInfo.strTitle
- );
- // 子分组属性项
- QtVariantProperty* item = nullptr;
-
- // --------- 数据链接部分
- // 循环添加所有数据链接
- for (int i = 0; i < subGroupInfo.dataLinks.size(); i++)
- {
- const DataLink& dataLink = subGroupInfo.dataLinks[i];
- // 数据链接项名
- item = m_manager->addProperty(
- VariantManager::tagDataLinkTypeId(),
- dataLink.title
- );
- // 数据链接值
- item->setValue(dataLink.toString());
- // 添加数据链接
- subGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, dataLink.title);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][dataLink.title] = item;
- }
-
- // --------- 杂项部分
- // 创建杂项子分组
- QtProperty* subMiscGroup = m_manager->addProperty(
- QtVariantPropertyManager::groupTypeId(),
- PROPERTY_EX_MISC
- );
- // 1.
- // 名称 (Table、Pie、Wave)
- if (!this->isVImageControl())
- {
- item = m_manager->addProperty(QVariant::String, subGroupInfo.strValueName);
- // 子项值
- item->setValue(subGroupInfo.strValue);
- // 添加子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strValueName);
- // 2021-12-24 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strValueName] = item;
- }
- // 2.
- // 颜色(Pie、Wave、Image)
- if (!this->isVTableControl() && !subGroupInfo.strColorName.isEmpty())
- {
- // 分块颜色项名
- item = m_manager->addProperty(QVariant::Color, subGroupInfo.strColorName);
- // 颜色数值
- item->setValue(subGroupInfo.color);
- // 添加颜色子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strColorName);
- // 2021-12-24 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strColorName] = item;
- }
- // 3.
- // 如果是Image控件,还需要加入其他杂项
- if (this->isVImageControl())
- {
- // 如果是HObject子分组
- if (groupID == GROUP_INDEX_HOBJECT)
- {
- // 线宽
- // 线宽项名
- item = m_manager->addProperty(QVariant::Int, subGroupInfo.strLineWidthName);
- // 线宽数值
- item->setValue(subGroupInfo.nLineWidth);
- // 添加线宽子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strLineWidthName);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strLineWidthName] = item;
- }
- // 如果是HTuple子分组
- else if (groupID == GROUP_INDEX_HTUPLE)
- {
- // 坐标
- // 坐标项名
- item = m_manager->addProperty(QVariant::Point, subGroupInfo.strPtName);
- // 坐标数值
- item->setValue(subGroupInfo.pt);
- // 添加坐标子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strPtName);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strPtName] = item;
- //// 坐标(数据链接)
- //// 数据链接项名
- //item = m_manager->addProperty(
- // VariantManager::tagDataLinkTypeId(),
- // subGroupInfo.dataLinkPoint.title
- //);
- //// 数据链接值
- //item->setValue("");
- //// 添加数据链接
- //subMiscGroup->addSubProperty(item);
- //// 保存子项和名字的对应关系
- //m_propertyToName.insert(item, subGroupInfo.dataLinkPoint.title);
- //// 保存本属性对应关系,用于后续查找和更新
- //m_objectToNameToProperty[m_object][subGroupInfo.dataLinkPoint.title] = item;
- // 尺寸
- // 尺寸项名
- item = m_manager->addProperty(QVariant::Int, subGroupInfo.strSize);
- // 尺寸数值
- item->setValue(subGroupInfo.nSize);
- // 添加尺寸子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strSize);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strSize] = item;
- }
- // 如果是 Display 子分组
- else if (groupID == GROUP_INDEX_DISPLAY)
- {
- }
- // 如果是Save 子分组
- else if (groupID == GROUP_INDEX_SAVE)
- {
- // 1 启用存图(复选框)
- {
- item = m_manager->addProperty(QVariant::Bool, subGroupInfo.strSaveImage);
- item->setValue(subGroupInfo.bEnSaveImage);
- // 添加坐标子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strSaveImage);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strSaveImage] = item;
- }
-
- // 2 启用转储(复选框)
- {
- item = m_manager->addProperty(QVariant::Bool, subGroupInfo.strDumpWindow);
- item->setValue(subGroupInfo.bEnDumpWindow);
- // 添加坐标子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strDumpWindow);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strDumpWindow] = item;
- }
-
- // 3 启用应用状态(复选框)
- {
- item = m_manager->addProperty(QVariant::Bool, subGroupInfo.strExecuteState);
- item->setValue(subGroupInfo.bEnExecuteState);
- // 添加坐标子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strExecuteState);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strExecuteState] = item;
- }
- // 4 命名方式(下拉列表 1、序号模式,2、日期模式,3、链接模式 )
- {
- item = m_manager->addProperty(QtVariantPropertyManager::enumTypeId(), subGroupInfo.strSaveMode);
- QStringList enumNames;
- enumNames << "序号模式" << "日期模式" << "链接模式";
- item->setAttribute(QLatin1String("enumNames"), enumNames);
- item->setValue(subGroupInfo.nSaveMode);
- // 添加坐标子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strSaveMode);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strSaveMode] = item;
- }
- // 5 BufferSize
- {
- item = m_manager->addProperty(QVariant::Int, subGroupInfo.strBufferSize);
- item->setValue(subGroupInfo.nBufferSize);
- item->setAttribute(QLatin1String("minimum"), 10);
- item->setAttribute(QLatin1String("maximum"), 999);
- item->setAttribute(QLatin1String("singleStep"), 1);
- // 添加坐标子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strBufferSize);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strBufferSize] = item;
- }
- // 6 Free Time
- {
- item = m_manager->addProperty(QVariant::Int, subGroupInfo.strFreeTime);
- item->setValue(subGroupInfo.nFreeTime);
- item->setAttribute(QLatin1String("minimum"), 10);
- item->setAttribute(QLatin1String("maximum"), 500);
- item->setAttribute(QLatin1String("singleStep"), 1);
- // 添加坐标子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strFreeTime);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strFreeTime] = item;
- }
- // TODO: 此处,需要完成存储组的默认折叠
- }
- // 不应该执行到这里
- else
- {
- qDebug() << "[Error] ObjectControllerPrivate::buildPropertySubGroup - invalid groupID: " << groupID;
- }
- }
- // 4.
- // 如果是曲线控件,还需要加入其他杂项
- if (this->isVCustomPlot())
- {
- // 线宽
- // 线宽项名
- item = m_manager->addProperty(QVariant::Int, subGroupInfo.strLineWidthName);
- // 线宽数值
- item->setValue(subGroupInfo.nLineWidth);
- // 添加线宽子项
- subMiscGroup->addSubProperty(item);
- // 保存子项和名字的对应关系
- m_propertyToName.insert(item, subGroupInfo.strLineWidthName);
- // 保存本属性对应关系,用于后续查找和更新
- m_objectToNameToProperty[m_object][subGroupInfo.strLineWidthName] = item;
- }
- // 添加杂项分组
- subGroup->addSubProperty(subMiscGroup);
- // 添加子分组
- subGroupRoot->addSubProperty(subGroup);
- // 保存这个SubGroup的信息(用于删除使用)
- QtProperty* curGroup = m_objectToGroups[m_object][groupID];
- m_groupToSubGroups[curGroup].push_back(subGroup);
- // m_objectToSubGroups[m_object].push_back(subGroup);
- }
- void ObjectControllerPrivate::saveExpandedState()
- {
- }
- void ObjectControllerPrivate::restoreExpandedState()
- {
- }
- /// <summary>
- /// 属性表数据变动槽函数
- /// </summary>
- void ObjectControllerPrivate::slotValueChanged(QtProperty *property, const QVariant &value)
- {
- // qDebug() << "ObjectControllerPrivate::slotValueChanged - Property: " << property->propertyName() << " - Value: " << value;
- // 2022-2-12 如果更新的是geometry
- if (property->propertyName()=="形状")
- {
- this->changeGeometryProperty(value);
- }
- // 基础属性
- if (m_propertyToIndex.contains(property))
- {
- this->changeBasicProperties(property, value);
- }
- // 动态属性
- else
- {
- // 动态改变复杂控件的扩展属性
- this->changeExtendProperties(property, value);
- }
- }
- /// <summary>
- /// 更新基础属性
- /// </summary>
- /// <param name="property"></param>
- /// <param name="value"></param>
- void ObjectControllerPrivate::changeBasicProperties(QtProperty* property, const QVariant& value)
- {
- int idx = m_propertyToIndex.value(property);
- const QMetaObject* metaObject = m_object->metaObject();
- QMetaProperty metaProperty = metaObject->property(idx);
- metaProperty.write(m_object, value);
- updateBasicProperties(metaObject);
- //// 2022-2-14 修正,似乎不需要这么复杂,简化逻辑提高了效率
- //// updateBasicProperties(metaObject);
- //QtVariantProperty* subProperty = m_objectToIndexToProperty[m_object][idx];
- //subProperty->setValue(value);
- // 此处需要进行额外处理,如果改变的是扩展属性数量的关联Key,需要更新对应的扩展属性数量
- QString propertyName = metaProperty.name();
- // 如果改变了复杂控件扩展属性的数量
- if (propertyName == TABLE_COL_COUNT_NAME
- || propertyName == PIE_SLICE_COUNT_NAME
- || propertyName == CUSTOM_PLOT_COUNT_NAME
- || propertyName == IMAGE_OBJ_COUNT_NAME
- || propertyName == IMAGE_MSG_COUNT_NAME
- || propertyName == IMAGE_DISPLAY_COUNT_NAME
- )
- {
- // 调整对应的属性数量
-
- // 新的属性数量
- int newCount = value.toInt();
- // 动态更新属性数量
- this->updateExtendPropertiesCount(newCount, propertyName);
- }
- }
- /// <summary>
- /// 修改控件的扩展属性
- /// </summary>
- /// <param name="property"></param>
- /// <param name="value"></param>
- void ObjectControllerPrivate::changeExtendProperties(QtProperty* property, const QVariant& value)
- {
- // 找到属性对应的属性名字
- if (m_propertyToName.contains(property))
- {
- // 获取属性名字
- QString strValueTitle = m_propertyToName[property];
- // 调用虚函数更新对应的控件属性值
- m_pVcontrol->changeExProperties(strValueTitle, value);
- }
- }
- ///// <summary>
- ///// 增加新的属性项
- ///// </summary>
- ///// <param name="pTable"></param>
- ///// <param name="newCount"></param>
- //void ObjectControllerPrivate::appendExtendPropertiesCount(const int fixCount, const QString& propertyName)
- //{
- // //// 首先调用虚函数变更控件中扩展属性的数量
- // //m_pVcontrol->updateExPropertyCount(fixCount);
- //
- // //// 从对应的子属性组中获取最新的属性数据
- // //const QVector<PROPERTY_EX_SUBGROUP>& propsItems = m_pVcontrol->getPropertyEx().m_subGroups[groupID];
- //
- // // // 同步进行界面信息变更
- // //int nStart = m_pVcontrol->getPropertyExSubGroupCountByID(groupID) - fixCount;
- // //int nEnd = nStart + fixCount;
- // //for (int i = nStart; i < nEnd; i++)
- // //{
- // // this->addExtendPropertiesSubGroup(propsItems[i], m_objectToExRoots[m_object][groupID]);
- // //}
- //
- //}
- //
- //
- ///// <summary>
- ///// 减少新的属性项
- ///// </summary>
- ///// <param name="pTable"></param>
- ///// <param name="newCount"></param>
- //void ObjectControllerPrivate::removeExtendPropertiesCount(const int fixCount, const QString& propertyName)
- //{
- // //// 首先控件中减少数据结构信息(虚函数)
- // //m_pVcontrol->updateExPropertyCount(fixCount);
- //
- // // // 同步进行界面信息变更
- // // int nDelCount = -fixCount;
- //
- // // // 从后往前依次删除掉属性
- // // for (int i = 0; i < nDelCount; i++)
- // // {
- // // QtProperty* pDelSubGroup = m_objectToSubGroups[m_object].back();
- //
- // // // 删除子属性
- // // m_objectToExRoots[m_object]->removeSubProperty(pDelSubGroup);
- //
- // //m_objectToSubGroups[m_object].pop_back();
- // // }
- //}
- /// <summary>
- /// 动态调整属性项
- /// </summary>
- /// <param name="newCount"></param>
- /// <param name="propertyName"></param>
- void ObjectControllerPrivate::updateExtendPropertiesCount(const int newCount, const QString& propertyName)
- {
- // 需要调整的属性数量
- int nFixCount = newCount - m_pVcontrol->getExPropertyCountByName(propertyName);
- // GroupID
- int nGroupID = m_pVcontrol->getGroupIDByName(propertyName);
- // 检查有效性
- if (nGroupID < 0)
- {
- qDebug() << "[Error] ObjectControllerPrivate::updateExtendPropertiesCount - nGroupID in invalid: " << nGroupID;
- return;
- }
- // 2022-1-23 由于属性表中的0号分组是主索引链接分组,所以此处取到的nGroupID + 才是真实的属性表分组ID
- int nPropGroupID = nGroupID + 1;
- // 变更控件中扩展属性对应的数据结构数量(虚函数)
- m_pVcontrol->updateExPropertyCount(nFixCount, propertyName);
- // 需要增加
- if (nFixCount > 0)
- {
- // 获取最新的子分组数据
- // 从对应的子属性组中获取最新的属性数据
- const QVector<PROPERTY_EX_SUBGROUP>& subGroups = m_pVcontrol->m_PropertyEx.m_groups[nGroupID].subGroups;
- int nStart = m_pVcontrol->getExPropertyCountByID(nGroupID) - nFixCount;
- int nEnd = nStart + nFixCount;
- // 把新增加的subGroup数据结构添加到属性表中
- for (int i = nStart; i < nEnd; i++)
- {
- this->buildPropertySubGroup(nGroupID, subGroups[i], m_objectToGroups[m_object][nPropGroupID]);
- }
- }
- // 需要减少
- else
- {
- // 从后往前依次删除掉属性
- for (int i = 0; i < -nFixCount; i++)
- {
- // QtProperty* pDelSubGroup = m_objectToSubGroups[m_object].back();
- // 从分组中找到对应的子分组
- QtProperty* curGroup = m_objectToGroups[m_object][nGroupID];
- QtProperty* pDelSubGroup = m_groupToSubGroups[curGroup].back();
- // 删除子属性
- m_objectToGroups[m_object][nPropGroupID]->removeSubProperty(pDelSubGroup);
- m_groupToSubGroups[curGroup].pop_back();
- }
- }
- // 基础属性表全部不展开
- this->collapseAll();
- // 只展开扩展属性表以及子属性表的部分
- this->setExtendItemsExpandOnly();
- }
- /// <summary>
- /// 仅展开扩展属性项
- /// </summary>
- void ObjectControllerPrivate::setExtendItemsExpandOnly()
- {
- // 2022-1-12 遍历所有的子属性项进行判断
- for (int i = 0; i < m_objectToGroups[m_object].size(); i++)
- {
- QtProperty* prop = m_objectToGroups[m_object][i];
- if (!prop || m_browser->items(prop).size() <= 0)
- {
- return;
- }
- // 枚举所有子项逐一进行展开
- QtBrowserItem* pExRoot = m_browser->items(prop).at(0);
- m_browser->setExpanded(pExRoot, true);
- // Groups
- QList<QtBrowserItem*> pGroups = pExRoot->children();
- for (QtBrowserItem* group : pGroups)
- {
- m_browser->setExpanded(group, true);
- //// subgroups
- //QList<QtBrowserItem*> subGroups = group->children();
- //for (QtBrowserItem* subGroup : subGroups)
- //{
- // m_browser->setExpanded(subGroup, true);
- //}
- }
- }
- }
- ///// <summary>
- ///// 2022-2-7为了解决反序列化时数据链接数值无法自动显示的问题,增加此函数
- ///// </summary>
- ///// <param name="dataLink"></param>
- //void ObjectControllerPrivate::setDataLinkItem(QtVariantProperty*& item, const DataLink& dataLink)
- //{
- // item->setValue(dataLink.toString());
- //
- //
- // //if (propex.m_refreshLink.value.size() <= 0)
- // //{
- // // item->setValue("");
- // //}
- // //else
- // //{
- // // item->setValue(propex.m_refreshLink.toString());
- // //}
- //}
- //===================================================================
- //
- // ObjectController
- //
- //===================================================================
- /// <summary>
- ///
- /// </summary>
- /// <param name="parent"></param>
- ObjectController::ObjectController(QWidget *parent)
- : QWidget(parent)
- {
- d_ptr = new ObjectControllerPrivate;
- d_ptr->q_ptr = this;
- d_ptr->m_object = nullptr;
- /*
- QScrollArea *scroll = new QScrollArea(this);
- scroll->setWidgetResizable(true);
- d_ptr->m_browser = new QtGroupBoxPropertyBrowser(this);
- QVBoxLayout *layout = new QVBoxLayout(this);
- layout->setMargin(0);
- layout->addWidget(scroll);
- scroll->setWidget(d_ptr->m_browser);
- */
- // 生成属性浏览控件
- QtTreePropertyBrowser *browser = new QtTreePropertyBrowser(this);
- browser->setRootIsDecorated(false);
- d_ptr->m_browser = browser;
- QVBoxLayout *layout = new QVBoxLayout(this);
- layout->setMargin(0);
- // 添加新的属性表到界面中
- layout->addWidget(d_ptr->m_browser);
- d_ptr->m_readOnlyManager = new QtVariantPropertyManager(this);
- // 2021-9-11 修改,此处生成 扩展的 VariantManager 对象
- VariantManager* pVariantManager = new VariantManager(this);
- d_ptr->m_manager = pVariantManager;
- pVariantManager->setPropertyEditor(d_ptr->m_browser);
- // d_ptr->m_manager = new QtVariantPropertyManager(this);
- // 此处生成扩展的 VariantFactory 对象
- QtVariantEditorFactory *factory = new VariantFactory(this);
- d_ptr->m_browser->setFactoryForManager(d_ptr->m_manager, factory);
- // 绑定数据更新消息
- connect(d_ptr->m_manager, SIGNAL(valueChanged(QtProperty *, const QVariant &)),
- this, SLOT(slotValueChanged(QtProperty *, const QVariant &)));
- }
- ObjectController::~ObjectController()
- {
- delete d_ptr;
- }
- /// <summary>
- /// 设置对象属性
- /// </summary>
- /// <param name="object"></param>
- void ObjectController::setObject(QObject *object)
- {
- // 根据控件类型分别进行不同的处理
- // 根据控件类型的不同,分为设置基础控件属性和复杂控件属性
- // Memo:基础控件属性的设置和复杂控件属性的设置还是有很大区别
- // 基础控件可以根据metaObject来分类设置属性表,因为同一个metaObject类型的属性表项是完全一致的,直接更新即可
- // 而复杂控件的属性表项是动态变化的,无法直接根据metaObject类型来成组设置,所以每次切换控件都需要清空删除后重新来过
- // // QString name = object->objectName();
- //如果设置的控件已经是当前控件则不处理
- if (d_ptr->m_object == object)
- {
- return;
- }
- // 清空属性表
- this->clearProperties();
- // 将新的对象指针保存
- d_ptr->m_object = object;
- if (!d_ptr->m_object)
- {
- return;
- }
- // 2021-12-28 转换成VControlObject指针留着后面使用
- d_ptr->m_pVcontrol = VControlObject::controlPtr(d_ptr->m_object);
- // 将简单控件的处理逻辑和复杂控件完全分开
- if (this->isBasicControl())
- {
- // 添加基础控件的属性,设置对应属性表(新建或更新)
- d_ptr->setBasicControlProperties(d_ptr->m_object->metaObject());
- }
- else
- {
- if (!d_ptr->m_pVcontrol)
- {
- return;
- }
- // 添加复杂控件的属性,设置对应属性表(新建或更新)
- d_ptr->setComplexControlProperties(d_ptr->m_object->metaObject());
- }
- //// 还原属性结构中子属性的展开状态
- //d_ptr->restoreExpandedState();
- // 展开所有节点
- // d_ptr->expandAll();
- }
- QObject *ObjectController::object() const
- {
- return d_ptr->m_object;
- }
- /// <summary>
- /// 清空属性表
- /// </summary>
- void ObjectController::clearProperties()
- {
- // 删除旧属性表中的内容
- if (d_ptr->m_object)
- {
- //// 保存当前属性表中子属性的状态
- //d_ptr->saveExpandedState();
- // 枚举属性表中之前的所有属性进行删除
- QListIterator<QtProperty*> it(d_ptr->m_topLevelProperties);
- while (it.hasNext())
- {
- d_ptr->m_browser->removeProperty(it.next());
- }
- d_ptr->m_topLevelProperties.clear();
- //// 2022-1-6增加,切换控件时需要清除相关的数据结构
- //d_ptr->m_subGroups.clear();
- // d_ptr->m_exPropertiesRoot = nullptr;
- }
- }
- /// <summary>
- /// 2021-12-25增加,删除对应属性表相关的数据结构
- /// </summary>
- /// <param name="object"></param>
- void ObjectController::delObject(QObject* object)
- {
- d_ptr->m_object = object;
- if (!d_ptr->m_object)
- {
- return;
- }
- // 清空对应的数据结构
- d_ptr->m_objectToIndexToProperty.remove(object);
- d_ptr->m_objectToProperty.remove(object);
- d_ptr->m_objectToNameToProperty.remove(object);
- // 清除当前分组中的所有子分组属性表
- for (QtProperty* group : d_ptr->m_objectToGroups[object])
- {
- d_ptr->m_groupToSubGroups.remove(group);
- }
- d_ptr->m_objectToGroups.remove(object);
- // 清空最终属性表
- clearProperties();
- d_ptr->m_object = nullptr;
- }
- /// <summary>
- /// 2022-2-13 用于控件数值改变后向属性表同步
- /// </summary>
- /// <param name="pControl"></param>
- /// <param name="value"></param>
- void ObjectController::syncToObject(QObject* pControl, const OBJECT_SYNC_PROPERTY& syncInfo)
- {
- // 暂时未使用到pControl,因为ObjectController本身是绑定了控件指针的
- // 同步到属性表
- d_ptr->syncToPropertyTable(pControl, syncInfo);
- }
- /// <summary>
- /// 是否是基础类型控件
- /// </summary>
- /// <returns></returns>
- bool ObjectController::isBasicControl()
- {
- QString className = object()->metaObject()->className();
- if (className != CLASS_NAME_TABLECONTROL
- && className != CLASS_NAME_CUSTOMPLOT
- && className != CLASS_NAME_PIECHART
- && className != CLASS_NAME_IMAGECONTROL
- )
- {
- return true;
- }
- return false;
- }
- //===================================================================
- //
- // 辅助函数
- //
- //===================================================================
- int ObjectControllerPrivate::enumToInt(const QMetaEnum& metaEnum, int enumValue) const
- {
- QMap<int, int> valueMap; // dont show multiple enum values which have the same values
- int pos = 0;
- for (int i = 0; i < metaEnum.keyCount(); i++) {
- int value = metaEnum.value(i);
- if (!valueMap.contains(value)) {
- if (value == enumValue) {
- return pos;
- }
- valueMap[value] = pos++;
- }
- }
- return -1;
- }
- int ObjectControllerPrivate::intToEnum(const QMetaEnum& metaEnum, int intValue) const
- {
- QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
- QList<int> values;
- for (int i = 0; i < metaEnum.keyCount(); i++) {
- int value = metaEnum.value(i);
- if (!valueMap.contains(value)) {
- valueMap[value] = true;
- values.append(value);
- }
- }
- if (intValue >= values.count()) {
- return -1;
- }
- return values.at(intValue);
- }
- bool ObjectControllerPrivate::isSubValue(int value, int subValue) const
- {
- if (value == subValue) {
- return true;
- }
- int i = 0;
- while (subValue) {
- if (!(value & (1 << i))) {
- if (subValue & 1) {
- return false;
- }
- }
- i++;
- subValue = subValue >> 1;
- }
- return true;
- }
- bool ObjectControllerPrivate::isPowerOf2(int value) const
- {
- while (value) {
- if (value & 1) {
- return value == 1;
- }
- value = value >> 1;
- }
- return false;
- }
- /// <summary>
- /// 获取属性的中文名称
- /// </summary>
- /// <param name="enName"></param>
- /// <returns></returns>
- QString ObjectControllerPrivate::chName(const QString& enName)
- {
- // 中文属性名称
- QString propertyName = propertyNamesMap.value(enName);
- if (propertyName.isEmpty())
- {
- return enName;
- }
- return propertyName;
- }
- int ObjectControllerPrivate::flagToInt(const QMetaEnum& metaEnum, int flagValue) const
- {
- if (!flagValue) {
- return 0;
- }
- int intValue = 0;
- QMap<int, int> valueMap; // dont show multiple enum values which have the same values
- int pos = 0;
- for (int i = 0; i < metaEnum.keyCount(); i++) {
- int value = metaEnum.value(i);
- if (!valueMap.contains(value) && isPowerOf2(value)) {
- if (isSubValue(flagValue, value)) {
- intValue |= (1 << pos);
- }
- valueMap[value] = pos++;
- }
- }
- return intValue;
- }
- int ObjectControllerPrivate::intToFlag(const QMetaEnum& metaEnum, int intValue) const
- {
- QMap<int, bool> valueMap; // dont show multiple enum values which have the same values
- QList<int> values;
- for (int i = 0; i < metaEnum.keyCount(); i++) {
- int value = metaEnum.value(i);
- if (!valueMap.contains(value) && isPowerOf2(value)) {
- valueMap[value] = true;
- values.append(value);
- }
- }
- int flagValue = 0;
- int temp = intValue;
- int i = 0;
- while (temp) {
- if (i >= values.count()) {
- return -1;
- }
- if (temp & 1) {
- flagValue |= values.at(i);
- }
- i++;
- temp = temp >> 1;
- }
- return flagValue;
- }
- void ObjectControllerPrivate::expandAll()
- {
- //打开所有节点
- QtTreePropertyBrowser* browser = (QtTreePropertyBrowser*)m_browser;
- browser->expandAll();
- }
- void ObjectControllerPrivate::collapseAll()
- {
- //折叠所有节点
- QtTreePropertyBrowser* browser = (QtTreePropertyBrowser*)m_browser;
- browser->collapseAll();
- //展开父节点
- QList<QtBrowserItem*> items = browser->topLevelItems();
- for (QtBrowserItem* item : items)
- {
- browser->setExpanded(item, true);
- }
- }
- /// <summary>
- /// 当前控件是否是 Table
- /// </summary>
- /// <returns></returns>
- bool ObjectControllerPrivate::isVTableControl()
- {
- QString className = m_object->metaObject()->className();
- if (className == CLASS_NAME_TABLECONTROL)
- {
- return true;
- }
- return false;
- }
- /// <summary>
- /// 当前控件是否是 Pie
- /// </summary>
- /// <returns></returns>
- bool ObjectControllerPrivate::isVPieChart()
- {
- QString className = m_object->metaObject()->className();
- if (className == CLASS_NAME_PIECHART)
- {
- return true;
- }
- return false;
- }
- /// <summary>
- /// 当前控件是否是 Wave
- /// </summary>
- /// <returns></returns>
- bool ObjectControllerPrivate::isVCustomPlot()
- {
- QString className = m_object->metaObject()->className();
- if (className == CLASS_NAME_CUSTOMPLOT)
- {
- return true;
- }
- return false;
- }
- /// <summary>
- /// 当前控件是否是 Image
- /// </summary>
- /// <returns></returns>
- bool ObjectControllerPrivate::isVImageControl()
- {
- QString className = m_object->metaObject()->className();
- if (className == CLASS_NAME_IMAGECONTROL)
- {
- return true;
- }
- return false;
- }
- #include "moc_objectcontroller.cpp"
|