/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include "objectcontroller.h" #include "qtvariantproperty.h" #include "qtgroupboxpropertybrowser.h" #include "qttreepropertybrowser.h" #include "qtpropertybrowser.h" #include "variantfactory.h" #include "variantmanager.h" #include "VTableControl.h" QMap maps; class ObjectControllerPrivate { ObjectControllerPrivate() { maps.insert("tip", "文本"); maps.insert("title", "标题"); maps.insert("dataLink", "链接"); maps.insert("textColor", "文本色"); maps.insert("bgColor", "背景色"); maps.insert("Red", "红"); maps.insert("Green", "绿"); maps.insert("Blue", "蓝"); maps.insert("Alpha", "明度"); maps.insert("font", "字体"); maps.insert("enable", "启用"); maps.insert("rowCount", "行数"); maps.insert("colCount", "列数"); } ObjectController* q_ptr; Q_DECLARE_PUBLIC(ObjectController) public: void expandAll(); void collapseAll(); void addClassProperties(const QMetaObject* metaObject); void addClassPropertiesParent(const QMetaObject* metaObject); void updateClassProperties(const QMetaObject* metaObject, bool recursive); 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; // 添加扩展属性 void addTableProperties(); // 移除扩展属性 void removeTableProperites(int delCount); // 补充扩展属性 void appendTableProperties(int nFixCount); // 具体的控件数值变更处理代码 void updateTableProperties(VTableControl* pTable, QString propertyName, const QVariant& newValue); //// 2021-11-24,针对Table类型的控件生成对应的列信息属性表 // QtVariantProperty* addTableProperties(QtProperty* pParent, const int colCount); // // 更新表格的属性 // void updateTableProperties(QtProperty* pParent, const int colCount); QObject* m_object; QMap m_classToProperty; QMap m_propertyToClass; QMap m_propertyToIndex; QMap > m_classToIndexToProperty; QMap m_propertyToExpanded; QList m_topLevelProperties; // 2021-11-27增加,保存扩展属性 QList m_exProperties; QtProperty* m_groupEx; // 2021-9-11 修改 此处直接使用 QtTreePropertyBrowser 指针即可 QtTreePropertyBrowser* m_browser; // 属性数据结构管理器 QtVariantPropertyManager* m_manager; QtVariantPropertyManager* m_readOnlyManager; }; int ObjectControllerPrivate::enumToInt(const QMetaEnum& metaEnum, int enumValue) const { QMap 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 valueMap; // dont show multiple enum values which have the same values QList 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; } int ObjectControllerPrivate::flagToInt(const QMetaEnum& metaEnum, int flagValue) const { if (!flagValue) { return 0; } int intValue = 0; QMap 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 valueMap; // dont show multiple enum values which have the same values QList 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 items = browser->topLevelItems(); foreach(QtBrowserItem * item, items) { browser->setExpanded(item, true); } } void ObjectControllerPrivate::addClassPropertiesParent(const QMetaObject* metaObject) { if (!metaObject) { return; } //存储需要过滤的属性,有时候大部分属性都用不上 QStringList keyName; //keyName << "geometry" << "alignment"; 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 name = metaProperty.name(); //if (!keyName.contains(name)) { // continue; //} if (!metaProperty.isReadable()) { subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name())); subProperty->setValue(QLatin1String("< Non Readable >")); } else if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) { subProperty = m_manager->addProperty(QtVariantPropertyManager::flagTypeId(), QLatin1String(metaProperty.name())); 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(), QLatin1String(metaProperty.name())); 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, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Writable)")); } if (!metaProperty.isDesignable()) { subProperty = m_readOnlyManager->addProperty(type, QLatin1String(metaProperty.name()) + QLatin1String(" (Non Designable)")); } else { subProperty = m_manager->addProperty(type, QLatin1String(metaProperty.name())); } subProperty->setValue(metaProperty.read(m_object)); } else { subProperty = m_readOnlyManager->addProperty(QVariant::String, QLatin1String(metaProperty.name())); 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 ObjectControllerPrivate::saveExpandedState() { } void ObjectControllerPrivate::restoreExpandedState() { } /////////////////// ObjectController ObjectController::ObjectController(QWidget* parent) : QWidget(parent) { d_ptr = new ObjectControllerPrivate; d_ptr->q_ptr = this; d_ptr->m_object = 0; /* 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; } /// /// 核心函数,设置控件对象,加载对象的属性信息 /// /// void ObjectController::setObject(QObject* object) { //QString name = object->metaObject()->className(); //VTableControl* pTableControl = (VTableControl*)object; //QVector pEx = pTableControl->getExProperties(); //如果设置的控件已经是当前控件则不处理 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; } //加载父类的属性 // QWidget // d_ptr->addClassPropertiesParent(d_ptr->m_object->metaObject()->superClass()->superClass()); // 2021-9-21修改,此处只取子属性即可 // d_ptr->addClassPropertiesParent(d_ptr->m_object->metaObject()->superClass()); // 加载当前控件的属性 d_ptr->addClassProperties(d_ptr->m_object->metaObject()); // 根据不同的类型加载控件不同的扩展属性 QString strControlClassName = d_ptr->m_object->metaObject()->className(); // Table Control if (strControlClassName == CLASS_NAME_TABLECONTROL) { //VTableControl* pTable = qobject_cast(d_ptr->m_object); //d_ptr->addTablePropertiesEx(pTable, d_ptr->m_classToProperty.value(d_ptr->m_object->metaObject())); d_ptr->addTableProperties(); } // 还原属性结构中子属性的展开状态 d_ptr->restoreExpandedState(); //展开所有节点 d_ptr->expandAll(); } QObject* ObjectController::object() const { return d_ptr->m_object; } /// /// 核心函数,解析metaObject,添加对应属性表 /// /// void ObjectControllerPrivate::addClassProperties(const QMetaObject* metaObject) { if (!metaObject) { return; } // 根据类指针找到对应的属性表 QtProperty* classProperty = m_classToProperty.value(metaObject); // 如果属性表有效 if (!classProperty) { // 获取Object自身的名称作为属性表中的Top分组 QString className = QLatin1String(metaObject->className()); // 属性表中添加对应的Top分组 classProperty = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), className); // 保存Top分组和Object指针的对应关系 m_classToProperty[metaObject] = classProperty; // 保存Object指针和Top分组的对应关系 m_propertyToClass[classProperty] = metaObject; // 枚举本Object的所有属性,从propertyOffset开始 //// 保存控件多级属性的数量用于自动生成对应的属性设置信息 //int nLinkCount = 0; for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) { // 取出对应的属性 QMetaProperty metaProperty = metaObject->property(idx); // 取出Type编号 int type = metaProperty.userType(); // 用来保存子属性 QtVariantProperty* subProperty = 0; //将英文属性换成中文属性 QString propertyName = metaProperty.name(); // 从map对应表中获取对应的中文 propertyName = maps.value(propertyName, propertyName); // 如果属性不可读,则直接设置为 Non Readable if (!metaProperty.isReadable()) { subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName); subProperty->setValue(QLatin1String("< Non Readable >")); } // 是否是枚举类型 else if (metaProperty.isEnumType()) { // 是否是Flag类型 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 = maps.value(enumName, enumName); enumNames.append(enumName); } } subProperty->setAttribute(QLatin1String("enumNames"), enumNames); subProperty->setValue(enumToInt(metaEnum, metaProperty.read(m_object).toInt())); } } // 是否是Manager所支持的属性 else if (m_manager->isPropertyTypeSupported(type)) { // 如果不可写,则以只读Manager添加 if (!metaProperty.isWritable()) { subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Writable)")); } // 如果不可设计,则以只读Manager添加 else if (!metaProperty.isDesignable()) { subProperty = m_readOnlyManager->addProperty(type, propertyName + QLatin1String(" (Non Designable)")); } //// 如果是表格类型,则单独进行表格类型的添加 //else if (type == VariantManager::tagTableExInfoTypeId()) //{ // subProperty = this->addTableProperties(classProperty, nLinkCount); //} // 核心步骤:大部分属性都是通过此路径进行添加 else if (type != VariantManager::tagTableExInfoTypeId()) { subProperty = m_manager->addProperty(type, propertyName); } // 设置本属性的值 // (对于表格等复杂属性来说,这个值是空的) QVariant objValue = metaProperty.read(m_object); subProperty->setValue(objValue); //// 保存Table的列信息用于生成对应的属性设置项 //if (propertyName == "列数") //{ // nLinkCount = objValue.toInt(); //} } // 否则,则添加未知属性信息到表中,并且置为不可用 else { subProperty = m_readOnlyManager->addProperty(QVariant::String, propertyName); subProperty->setValue(QLatin1String("< Unknown Type >")); subProperty->setEnabled(false); } // 在本属性组中添加本属性 classProperty->addSubProperty(subProperty); // 保存属性及其对应的索引号 m_propertyToIndex[subProperty] = idx; // 保存Object指针、索引号以及对应的属性关系 m_classToIndexToProperty[metaObject][idx] = subProperty; } } else { // 否则不增加新属性,而是更新现有属性 updateClassProperties(metaObject, false); } // 在属性表中的顶层属性表信息中添加本组属性 //(由于控件的继承关系,属性表中会有多个顶层属性组) m_topLevelProperties.append(classProperty); // 向属性表中添加本组属性 m_browser->addProperty(classProperty); } ///// ///// 2021-11-24,针对Table类型的控件生成对应的列信息属性表 ///// ///// ///// //QtVariantProperty* ObjectControllerPrivate::addTableProperties(QtProperty* pParent, const int colCount) //{ // QtVariantProperty* groupItemTop = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), ("表格")); // // if (colCount <= 0) // { // return groupItemTop; // } // // for (int i = 0; i < colCount; i++) // { // QtProperty* subGroupItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列") + QString::number(i+1)); // // QtVariantProperty* item = m_manager->addProperty(QVariant::String, ("列名")); // subGroupItem->addSubProperty(item); // item->setValue(QString("列名") + QString::number(i + 1)); // // item = m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接")); // subGroupItem->addSubProperty(item); // item->setValue(""); // // groupItemTop->addSubProperty(subGroupItem); // } // // // m_topLevelProperties.append(groupItemTop); // // m_browser->addProperty(groupItemTop); // // return groupItemTop; // // //// QtVariantProperty* item = d_ptr->m_manager->addProperty(QVariant::Int, ("行数:")); //// item->setValue(2); //// groupItemTop->addSubProperty(item); // //// item = d_ptr->m_manager->addProperty(QVariant::Int, ("列数:")); //// item->setValue(6); //// groupItemTop->addSubProperty(item); // // //// QtProperty* groupItem2 = d_ptr->m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), ("列信息")); // // //// for (int i = 0; i < 3; i++) //// { //// QtProperty* subGroupItem = d_ptr->m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列名") + QString::number(i+1)); //// //// item = d_ptr->m_manager->addProperty(QVariant::String, ("列名")); //// subGroupItem->addSubProperty(item); //// item->setValue(QString("列名") + QString::number(i + 1)); // //// item = d_ptr->m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接")); //// subGroupItem->addSubProperty(item); //// item->setValue(""); // //// groupItem2->addSubProperty(subGroupItem); //// } // //// groupItemTop->addSubProperty(groupItem2); // // //d_ptr->m_topLevelProperties.append(groupItemTop); // //d_ptr->m_browser->addProperty(groupItemTop); //} /// /// 添加Table的扩展属性 /// /// void ObjectControllerPrivate::addTableProperties() { const QMetaObject* metaObject = m_object->metaObject(); //// 获取Table控件指针 //VTableControl* pTable = qobject_cast(m_object); //// 取出对应的扩展属性 //const QVector& props = pTable->getExProperties(); //if (props.size() <= 0) //{ // return; //} //int nExIndex = m_object->metaObject()->propertyCount(); //// 根据类指针找到对应的属性表 //QtProperty* classProperty = m_classToProperty.value(m_object->metaObject()); //// 表格属性根节点 //m_groupEx = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), ("表格")); //// 清空扩展属性表,准备保存新的扩展属性 //m_exProperties.clear(); //// 将子项添加到属性表中 //for (int i = 0; i < props.size(); i++) //{ // QtProperty* subGroupItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列") + QString::number(i + 1)); // // 增加列名 // QtVariantProperty* item = m_manager->addProperty(QVariant::String, ("列名")); // subGroupItem->addSubProperty(item); // item->setValue(props[i].m_strTitle); // // 保存属性及其对应的索引号 // m_propertyToIndex[item] = nExIndex++; // // 保存Object指针、索引号以及对应的属性关系 // m_classToIndexToProperty[metaObject][nExIndex] = item; // // 增加数据连接 // item = m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接")); // subGroupItem->addSubProperty(item); // item->setValue(""); // // 保存属性及其对应的索引号 // m_propertyToIndex[item] = nExIndex++; // // 保存Object指针、索引号以及对应的属性关系 // m_classToIndexToProperty[metaObject][nExIndex] = item; // // 本组中添加此属性 // m_groupEx->addSubProperty(subGroupItem); // // 保存扩展属性信息 // m_exProperties.push_back(subGroupItem); //} //// 在本属性组中添加本属性 //classProperty->addSubProperty(m_groupEx); } /// /// 当属性表中有数值变更时,进行对应的处理 /// /// /// void ObjectControllerPrivate::slotValueChanged(QtProperty* property, const QVariant& value) { qDebug() << "ObjectControllerPrivate::slotValueChanged - " << value.toString(); if (!m_propertyToIndex.contains(property)) { return; } int idx = m_propertyToIndex.value(property); const QMetaObject* metaObject = m_object->metaObject(); QMetaProperty metaProperty = metaObject->property(idx); if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) { metaProperty.write(m_object, intToFlag(metaProperty.enumerator(), value.toInt())); } else { metaProperty.write(m_object, intToEnum(metaProperty.enumerator(), value.toInt())); } } else { metaProperty.write(m_object, value); } updateClassProperties(metaObject, true); // 继续处理扩展属性 // 获取属性名称 QString propertyName = metaProperty.name(); QString className = metaObject->className(); QVariant newValue = metaProperty.read(m_object); // 如果是Table控件相关属性变更 if (className == CLASS_NAME_TABLECONTROL) { // 获取Table控件指针 VTableControl* pTable = qobject_cast(m_object); //// 获取Table的扩展属性信息 //QVector& props = pTable->getExProperties(); this->updateTableProperties(pTable, propertyName, newValue); } } /// /// 移除扩展属性 /// /// /// 需要删除的属性个数 void ObjectControllerPrivate::removeTableProperites(int delCount) { //// 获取Table控件指针 //VTableControl* pTable = qobject_cast(m_object); //// 获取Table的扩展属性信息 //QVector& props = pTable->getExProperties(); //for (int i = 0; i < delCount; i++) //{ // props.pop_back(); // QtProperty* pDelProperty = m_exProperties.back(); // // 递归删除此节点的数据及界面元素 // m_browser->removePropertyEx(pDelProperty); // m_exProperties.pop_back(); //} } /// /// 补充扩展属性 /// /// void ObjectControllerPrivate::appendTableProperties(int nFixCount) { //// 获取Table控件指针 //VTableControl* pTable = qobject_cast(m_object); //// 获取Table的扩展属性信息 //QVector& props = pTable->getExProperties(); //// 将子项添加到属性表中 //for (int i = 0; i < nFixCount; i++) //{ // TABLE_PROPERTY_EX newProp; // newProp.m_strTitle = "列名" + QString::number(props.size() + 1); // props.push_back(newProp); // QtProperty* subGroupItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), QString("列") + QString::number(props.size() + 1)); // QtVariantProperty* item = m_manager->addProperty(QVariant::String, ("列名")); // subGroupItem->addSubProperty(item); // item->setValue(newProp.m_strTitle); // item = m_manager->addProperty(VariantManager::tagDataLinkTypeId(), ("数据链接")); // subGroupItem->addSubProperty(item); // item->setValue(""); // m_groupEx->addSubProperty(subGroupItem); // // 保存扩展属性信息 // m_exProperties.push_back(subGroupItem); //} } /// /// 具体的控件数值变更处理代码 /// /// /// void ObjectControllerPrivate::updateTableProperties(VTableControl* pTable, QString propertyName, const QVariant& newValue) { //// 如果变更了列数,则需要动态调整属性表 //if (propertyName == "colCount") //{ // // 获取用户新输入的数量 // int nNewCount = newValue.toInt(); // int nFixCount = m_exProperties.size() - nNewCount; // // 如果新的数量小于旧的数量,则需要移除旧的属性项 // if (nFixCount > 0) // { // // 临时屏蔽了删除代码,尚存在问题 // // this->removeTableProperites(nFixCount); // return; // } // // 否则,增加新的属性项 // this->appendTableProperties(qAbs(nFixCount)); //} //// 如果变更了列名,则需要保存 //else if (propertyName.indexOf("列名") >= 0) //{ // int nColNameIndex = propertyName.remove("列名").toInt(); // pTable->updateTableColName(nColNameIndex, newValue.toString()); //} } /// /// 对已有属性表进行更新 /// /// /// void ObjectControllerPrivate::updateClassProperties(const QMetaObject* metaObject, bool recursive) { if (!metaObject) { return; } if (recursive) { updateClassProperties(metaObject->superClass(), recursive); } // 获取属性值的根节点 QtProperty* classProperty = m_classToProperty.value(metaObject); if (!classProperty) { return; } // 保存控件多级属性的数量用于自动生成对应的属性设置信息 // int nLinkCount = 0; // 遍历所有的属性执行更新 for (int idx = metaObject->propertyOffset(); idx < metaObject->propertyCount(); idx++) { QMetaProperty metaProperty = metaObject->property(idx); //// 取出Type编号 //int type = metaProperty.userType(); if (metaProperty.isReadable()) { if (m_classToIndexToProperty.contains(metaObject) && m_classToIndexToProperty[metaObject].contains(idx)) { QtVariantProperty* subProperty = m_classToIndexToProperty[metaObject][idx]; if (metaProperty.isEnumType()) { if (metaProperty.isFlagType()) { subProperty->setValue(flagToInt(metaProperty.enumerator(), metaProperty.read(m_object).toInt())); } else { subProperty->setValue(enumToInt(metaProperty.enumerator(), metaProperty.read(m_object).toInt())); } } // TODO: 需要在此处额外增加动态清除旧属性表,更新新属性表的内容 // TODO: 此处更新时还需要清空DataLink表中的值,解决旧有的bug // // 如果是Table类型 //else if (type == VariantManager::tagTableExInfoTypeId()) //{ // this->updateTableProperties(classProperty, nLinkCount); //} // 其他通用类型直接设置新的值 else { subProperty->setValue(metaProperty.read(m_object)); } //// 设置本属性的值 //QVariant objValue = metaProperty.read(m_object); //// 保存Table的列信息用于生成对应的属性设置项 //QString propertyName = metaProperty.name(); //if (propertyName == "colCount") //{ // nLinkCount = objValue.toInt(); //} } } } } #include "moc_objectcontroller.cpp"