void ShaderEffectItem::connectPropertySignals() { QSet<QByteArray>::const_iterator it; for (it = m_uniformNames.begin(); it != m_uniformNames.end(); ++it) { int pi = metaObject()->indexOfProperty(it->constData()); if (pi >= 0) { QMetaProperty mp = metaObject()->property(pi); if (!mp.hasNotifySignal()) qWarning("ShaderEffectItem: property '%s' does not have notification method!", it->constData()); QByteArray signalName("2"); signalName.append(mp.notifySignal().signature()); connect(this, signalName, this, SLOT(markDirty())); } else { qWarning("ShaderEffectItem: '%s' does not have a matching property!", it->constData()); } } for (int i = 0; i < m_sources.size(); ++i) { SourceData &source = m_sources[i]; int pi = metaObject()->indexOfProperty(source.name.constData()); if (pi >= 0) { QMetaProperty mp = metaObject()->property(pi); QByteArray signalName("2"); signalName.append(mp.notifySignal().signature()); connect(this, signalName, source.mapper, SLOT(map())); source.mapper->setMapping(this, i); connect(source.mapper, SIGNAL(mapped(int)), this, SLOT(changeSource(int))); } else {
void GraphicsDirectedEdge:: connect_source(GraphicsNodeSocket *source) { if (_source){ _source->set_edge(nullptr); QObject* data = _source->m_data; if(data!=0) QObject::disconnect(data,0,this,0); } _source = source; if (_source){ _source->set_edge(this); QObject* data = _source->m_data; if(data!=0) { const QMetaObject* mo = data->metaObject(); QMetaProperty mp = mo->property(_source->m_index); QMetaMethod notifySignal = mp.notifySignal(); int functionIndex = metaObject()->indexOfSlot("onSourceDataChange()"); QMetaMethod edgeInternalSlot = metaObject()->method(functionIndex); QObject::connect(data,notifySignal,this,edgeInternalSlot); } } }
void ObjectStaticPropertyModel::monitorObject(QObject* obj) { for (int i = 0; i < obj->metaObject()->propertyCount(); ++i) { const QMetaProperty prop = obj->metaObject()->property(i); if (prop.hasNotifySignal()) { connect(obj, QByteArray("2") + #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) prop.notifySignal().signature() #else prop.notifySignal().methodSignature() #endif , this, SLOT(propertyUpdated())); m_notifyToPropertyMap.insert(prop.notifySignalIndex(), i); } } }
void QQuickShaderEffectCommon::connectPropertySignals(QQuickItem *item, Key::ShaderType shaderType) { for (int i = 0; i < uniformData[shaderType].size(); ++i) { if (signalMappers[shaderType].at(i) == 0) continue; const UniformData &d = uniformData[shaderType].at(i); int pi = item->metaObject()->indexOfProperty(d.name.constData()); if (pi >= 0) { QMetaProperty mp = item->metaObject()->property(pi); if (!mp.hasNotifySignal()) qWarning("QQuickShaderEffect: property '%s' does not have notification method!", d.name.constData()); const QByteArray signalName = '2' + mp.notifySignal().methodSignature(); QSignalMapper *mapper = signalMappers[shaderType].at(i); QObject::connect(item, signalName, mapper, SLOT(map())); QObject::connect(mapper, SIGNAL(mapped(int)), item, SLOT(propertyChanged(int))); } else { // If the source is set via a dynamic property, like the layer is, then we need this // check to disable the warning. if (!item->property(d.name.constData()).isValid()) qWarning("QQuickShaderEffect: '%s' does not have a matching property!", d.name.constData()); } if (d.specialType == UniformData::Sampler) { QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value)); if (source) { if (item->window()) QQuickItemPrivate::get(source)->refWindow(item->window()); QObject::connect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*))); } } } }
QBinding::QBinding(const QObject *sourceObject, const char *sourcePropertyName, QState *state, QObject *targetObject, const char *targetPropertyName) { qimsysDebugIn() << sourceObject << sourcePropertyName << state << targetObject << targetPropertyName; d = new Private; if (!sourceObject || !sourcePropertyName || !targetObject || !targetPropertyName) { qWarning() << sourceObject << sourcePropertyName << targetObject << targetPropertyName; deleteLater(); qimsysDebugOut(); return; } d->sourceObject = sourceObject; d->sourcePropertyName = sourcePropertyName; d->state = state; d->targetObject = targetObject; d->targetPropertyName = targetPropertyName; const QMetaObject *sourceMetaObject = sourceObject->metaObject(); int sourcePropertyIndex = sourceMetaObject->indexOfProperty(sourcePropertyName); QMetaProperty sourceProperty = d->sourceObject->metaObject()->property(sourcePropertyIndex); if (sourceProperty.hasNotifySignal()) { connect(sourceObject, QByteArray("2") + sourceProperty.notifySignal().methodSignature(), this, SLOT(setProperty())); } else { qWarning() << sourceObject << "doesn't notify change for" << sourcePropertyName; deleteLater(); } connect(sourceObject, SIGNAL(destroyed()), this, SLOT(deleteLater())); connect(state, SIGNAL(destroyed()), this, SLOT(deleteLater())); connect(targetObject, SIGNAL(destroyed()), this, SLOT(deleteLater())); setProperty(); qimsysDebugOut(); }
QuickConfigListener::QuickConfigListener(const QString &path, const QString &group, const QMetaProperty &property, QObject *object, const ConfigValue<QVariant> &value, QuickConfig *parent) : QObject(parent), m_path(path), m_group(group), m_property(property), m_object(object), m_value(value) { static int slotIndex = staticMetaObject.indexOfMethod("onPropertyChanged()"); QMetaMethod slot = staticMetaObject.method(slotIndex); connect(m_object, property.notifySignal(), this, slot); }
void DataWidgetMapper::addMapping(QWidget *widget, int section) { QMetaProperty property = widget->metaObject()->userProperty(); Q_ASSERT(property.isValid()); QMetaMethod notifySignal = property.notifySignal(); Q_ASSERT(notifySignal.isValid()); connect(widget, notifySignal, this, QMetaMethod::fromSignal(&DataWidgetMapper::dataChanged)); QDataWidgetMapper::addMapping(widget, section); }
PropertyField::PropertyField(QObject* subject, const QMetaProperty& prop, QWidget *parent) : QLineEdit(parent), m_subject(subject), m_lastChangeTime(QTime::currentTime()), m_prop(prop) { setReadOnly(true); if (prop.hasNotifySignal()) { QMetaMethod signal = prop.notifySignal(); QMetaMethod updateSlot = metaObject()->method(metaObject()->indexOfSlot("propertyChanged()")); connect(m_subject, signal, this, updateSlot); } propertyChanged(); }
void PropertyEditor::Private::monitorElement(KDSME::Element* element) { if (!element) return; for (int i = 0; i < element->metaObject()->propertyCount(); ++i) { const QMetaProperty prop = element->metaObject()->property(i); if (!prop.hasNotifySignal()) continue; q->connect(element, "2" + prop.notifySignal().methodSignature(), q, SLOT(loadFromCurrentElement())); //krazy:exclude=doublequote_chars } }
/*! Connects the property's change notifier signal to the specified \a slot of the \a dest object and returns true. Returns false if this metaproperty does not represent a regular Qt property or if it has no change notifier signal, or if the \a dest object does not have the specified \a slot. */ bool QDeclarativeProperty::connectNotifySignal(QObject *dest, const char *slot) const { if (!(type() & Property) || !d->object) return false; QMetaProperty prop = d->object->metaObject()->property(d->core.coreIndex); if (prop.hasNotifySignal()) { QByteArray signal(QByteArray("2") + prop.notifySignal().signature()); return QObject::connect(d->object, signal.constData(), dest, slot); } else { return false; } }
void QMetaPropertyAdaptor::doSetObject(const ObjectInstance& oi) { auto mo = oi.metaObject(); if (!mo || oi.type() != ObjectInstance::QtObject || !oi.qtObject()) return; connect(oi.qtObject(), SIGNAL(destroyed(QObject*)), this, SIGNAL(objectInvalidated())); for (int i = 0; i < mo->propertyCount(); ++i) { const QMetaProperty prop = mo->property(i); if (prop.hasNotifySignal()) { connect(oi.qtObject(), QByteArray("2") + #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) prop.notifySignal().signature() #else prop.notifySignal().methodSignature() #endif , this, SLOT(propertyUpdated())); m_notifyToPropertyMap.insert(prop.notifySignalIndex(), i); } } }
/*! \brief TreeModel::connectProperty If \a property has got a notify signal, it will be connected to TreeModel::itemChanged( QStandardItem *item ). */ void TreeModel::connectProperty( QObject* object, const QMetaProperty& metaProperty, QStandardItem* item ) { Q_ASSERT( object ); if ( metaProperty.hasNotifySignal() ) { int index = object->metaObject()->indexOfProperty( metaProperty.name() ); m_propertyIndexToItemMap.insert( index, item ); QMetaMethod signal = metaProperty.notifySignal(); connect( object, signal, this, m_updateSlot ); } }
void Properties::monitorStaticProperties( ) { if ( getTarget() == nullptr ) return; int staticPropertyCount = getTarget()->metaObject( )->propertyCount( ); QMetaMethod propertiesModifiedSlot = getTarget()->metaObject( )->method( metaObject( )->indexOfSlot( "propertyChanged()" ) ); for ( int p = 0; p < staticPropertyCount; p++ ) { QMetaProperty staticProperty = getTarget()->metaObject( )->property( p ); if ( staticProperty.hasNotifySignal( ) ) { QMetaMethod propertyNotifySignal = staticProperty.notifySignal( ); connect( this, propertyNotifySignal, this, propertiesModifiedSlot, Qt::UniqueConnection ); } } }
void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const PropertyName &prefix) { if (m_registeredObjectList.contains(spiedObject)) // prevent cycles return; m_registeredObjectList.append(spiedObject); for (int index = QObject::staticMetaObject.propertyOffset(); index < spiedObject->metaObject()->propertyCount(); index++) { QMetaProperty metaProperty = spiedObject->metaObject()->property(index); // handle dot properties and connect the signals to the object if (metaProperty.isReadable() && !metaProperty.isWritable() && QDeclarativeMetaType::isQObject(metaProperty.userType())) { QObject *propertyObject = QDeclarativeMetaType::toQObject(metaProperty.read(spiedObject)); if (propertyObject) registerObject(propertyObject, prefix + metaProperty.name() + '.'); } else if (metaProperty.hasNotifySignal()) { QMetaMethod metaMethod = metaProperty.notifySignal(); bool isConnecting = QMetaObject::connect(spiedObject, metaMethod.methodIndex(), this, methodeOffset, Qt::DirectConnection); Q_ASSERT(isConnecting); Q_UNUSED(isConnecting); m_indexPropertyHash.insert(methodeOffset, prefix + metaProperty.name()); methodeOffset++; } // search recursive in objects if (metaProperty.isReadable() && metaProperty.isWritable() && QDeclarativeMetaType::isQObject(metaProperty.userType())) { QObject *propertyObject = QDeclarativeMetaType::toQObject(metaProperty.read(spiedObject)); if (propertyObject) registerObject(propertyObject, prefix + metaProperty.name() + '/'); } // search recursive in objects list if (metaProperty.isReadable() && QDeclarativeMetaType::isList(metaProperty.userType())) { QDeclarativeListReference list(spiedObject, metaProperty.name()); if (list.canCount() && list.canAt()) { for (int i = 0; i < list.count(); i++) { QObject *propertyObject = list.at(i); if (propertyObject) registerObject(propertyObject, prefix + metaProperty.name() + '/'); } } } } }
QWidget* GooeyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { const QAbstractItemModel* model = index.model(); QVariant data = model->data(index, Qt::EditRole); QWidget* result = K_NULL; // Static types... switch(data.type()) { case QMetaType::Bool: result = new GooeyCheckBox(parent); break; case QMetaType::Double: case QMetaType::Float: result = new GooeyDoubleSpinBox(parent); break; case QMetaType::Int: result = new GooeySpinBox(parent); break; case QMetaType::UInt: result = new GooeySpinBox(parent); static_cast<GooeySpinBox*>(result)->minimum(0); // Unsigned integer ! break; case QMetaType::QString: result = new GooeyLineEdit(parent); break; default: result = QStyledItemDelegate::createEditor(parent, option, index); break; } QMetaProperty property = result->metaObject()->userProperty(); if(property.hasNotifySignal()) { connect(result, SIGNAL(destroyed(QObject*)), SLOT(editorDestroyed(QObject*))); _mapper->setMapping(result, result); const int index = _mapper->metaObject()->indexOfMethod(QMetaObject::normalizedSignature("map()")); Q_ASSERT( index != -1 ); connect(result, property.notifySignal(), _mapper, _mapper->metaObject()->method(index)); } else { qWarning("GooeyItemDelegate: The editor widget %s has no notify signal on its USER property!", result->metaObject()->className()); } return result; }
ObjectMapperForwarder::ObjectMapperForwarder(ObjectMapper *m, QObject *o) : QObject(m), m_mapper(m), m_source(o) { for (int i = 0; i < o->metaObject()->propertyCount(); ++i) { QMetaProperty property = o->metaObject()->property(i); if (!property.isStored() || !property.isReadable() || !property.isWritable()) { continue; } if (!property.hasNotifySignal()) { DEBUG << "ObjectMapperForwarder: No notify signal for property " << property.name() << endl; continue; } // Signals can be connected to slots with fewer arguments, so // long as the arguments they do have match. So we connect // the property notify signal to our universal // property-changed slot, and use the sender() of that to // discover which object's property has changed. // Unfortunately, we don't then know which property it was // that changed, as the identity of the signal that activated // the slot is not available to us. The annoying part of this // is that Qt does actually store the identity of the signal // in the same structure as used for the sender() object data; // it just doesn't (at least as of Qt 4.5) make it available // through the public API. QString sig = QString("%1%2").arg(QSIGNAL_CODE) .arg(property.notifySignal().methodSignature().data()); QByteArray ba = sig.toLocal8Bit(); if (!connect(o, ba.data(), this, SLOT(objectModified()))) { std::cerr << "ObjectMapperForwarder: Failed to connect notify signal" << std::endl; } } connect(o, SIGNAL(destroyed(QObject *)), this, SLOT(objectDestroyed())); }
bool CQmlViewer::connectToChangeNotify(QObject *item, const QString &propName, QObject *receiver, const char *slotName) { bool rv = false; do { const QMetaObject *metaObject = item->metaObject (); if (NULL == metaObject) { Q_WARN("NULL metaObject"); break; } QMetaProperty metaProp; for (int i = 0; i < metaObject->propertyCount (); i++) { metaProp = metaObject->property (i); if (metaProp.name () == propName) { rv = true; break; } } if (!rv) { Q_WARN(QString("Couldn't find property named %1").arg(propName)); break; } rv = false; if (!metaProp.hasNotifySignal ()) { Q_WARN(QString("Property %1 does not have a notify signal") .arg(propName)); break; } QString signalName = metaProp.notifySignal().methodSignature(); signalName = "2" + signalName; Q_DEBUG(QString("Connect %1 to %2").arg(signalName).arg(slotName)); rv = connect(item, signalName.toLatin1().constData(), receiver, slotName); } while(0); return (rv); }//CQmlViewer::connectToChangeNotify
const char *SettingsWidget::lookForWidgetState(QWidget *widget, const char *property, const char *signal) { const QMetaObject *meta = widget->metaObject(); WidgetInfo info = { widget, NULL, QVariant(), false }; bool free_signal = false; // Firstly try to search this widget in predefined classes if (!signal && !property) { for (int i = 0, size = sizeof(widget_infos) / sizeof(AbstractWidgetInfo*); i < size; i++) { if (widget_infos[i]->handle(widget)) { info.property = widget_infos[i]->property; signal = widget_infos[i]->signal; break; } } } // Then try to find "User" property with signal or signal by property if (!signal) { for (int i = 0, size = meta->propertyCount(); i < size; i++) { QMetaProperty prop = meta->property(i); if (prop.hasNotifySignal() && ((property && !qstrcmp(prop.name(), property)) || (!property && prop.isUser()))) { info.property = prop.name(); const char *sig = prop.notifySignal().signature(); int len = strlen(sig); char *str = (char *)qMalloc(sizeof(char) * (len + 2)); str[0] = QSIGNAL_CODE; qstrcpy(str + 1, sig); signal = str; free_signal = true; break; } } } bool result(signal); if (result) { p->mapper->setMapping(widget, p->infos.size()); connect(widget, signal, p->mapper, SLOT(map())); p->infos << info; } if (free_signal) qFree((void *)signal); return result ? info.property : 0; }
QString ObjectStaticPropertyModel::detailString(const QMetaProperty& prop) const { QStringList s; s << tr("Constant: %1").arg(translateBool(prop.isConstant())); s << tr("Designable: %1").arg(translateBool(prop.isDesignable(m_obj.data()))); s << tr("Final: %1").arg(translateBool(prop.isFinal())); if (prop.hasNotifySignal()) { s << tr("Notification: %1").arg(Util::prettyMethodSignature(prop.notifySignal())); } else { s << tr("Notification: no"); } s << tr("Resetable: %1").arg(translateBool(prop.isResettable())); #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) s << tr("Revision: %1").arg(prop.revision()); #endif s << tr("Scriptable: %1").arg(translateBool(prop.isScriptable(m_obj.data()))); s << tr("Stored: %1").arg(translateBool(prop.isStored(m_obj.data()))); s << tr("User: %1").arg(translateBool(prop.isUser(m_obj.data()))); s << tr("Writable: %1").arg(translateBool(prop.isWritable())); return s.join("\n"); }
void DataWidgetBinder::addBinding(QWidget *widget, QString property, int column, QString notifySignal) { assert(mModel); assert(widget->metaObject()->indexOfProperty(property.toStdString().c_str()) != -1); assert(!mBindings.contains(widget)); if(notifySignal.isNull()) { QMetaProperty mp = widget->metaObject()->property(widget->metaObject()->indexOfProperty(property.toStdString().c_str())); notifySignal = signature(mp.notifySignal()); } int sigId = widget->metaObject()->indexOfSignal(widget->metaObject()->normalizedSignature(notifySignal.toStdString().c_str())); int methodId = metaObject()->indexOfMethod(metaObject()->normalizedSignature("propertyChanged()")); metaObject()->connect(widget, sigId, this, methodId); Binding b; b.mWidget = widget; b.mProperty = property; b.mColumn = column; b.mNotifySignal = notifySignal; mBindings[widget] = b; }
QString QMetaPropertyAdaptor::detailString(const QMetaProperty &prop) const { QObject *obj = object().qtObject(); QStringList s; s << tr("Constant: %1").arg(translateBool(prop.isConstant())); s << tr("Designable: %1").arg(translateBool(prop.isDesignable(obj))); s << tr("Final: %1").arg(translateBool(prop.isFinal())); if (prop.hasNotifySignal()) s << tr("Notification: %1").arg(Util::prettyMethodSignature(prop.notifySignal())); else s << tr("Notification: no"); s << tr("Resetable: %1").arg(translateBool(prop.isResettable())); #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) s << tr("Revision: %1").arg(prop.revision()); #endif s << tr("Scriptable: %1").arg(translateBool(prop.isScriptable(obj))); s << tr("Stored: %1").arg(translateBool(prop.isStored(obj))); s << tr("User: %1").arg(translateBool(prop.isUser(obj))); s << tr("Writable: %1").arg(translateBool(prop.isWritable())); return s.join(QStringLiteral("\n")); }
void PropertyWidget::setData(Kore::data::Block* block, kint propertyIndex) { _block = block; _propertyIndex = propertyIndex; QMetaProperty property = _block->metaObject()->property(_propertyIndex); if(property.hasNotifySignal()) { static const int slotIndex = staticMetaObject.indexOfMethod(QMetaObject::normalizedSignature("update()")); Q_ASSERT(slotIndex != -1); connect(_block, property.notifySignal(), this, staticMetaObject.method(slotIndex)); } else { qWarning( "%s / Block %s's property %s has no notify signal, it won't be updated!", __FUNCTION__, qPrintable(block->objectClassName()), property.name() ); } }
QString AsemanQtTools::exportItem(const QString &module, int major, int minor, const QString &component, bool store) { QString result; aseman_qt_tools_indexCache << component; QMetaObject meta = T::staticMetaObject; QString inherits = fixType(meta.superClass()? meta.superClass()->className() : ""); bool isModel = component.toLower().contains("model"); result += QString("# %1\n\n").arg(component); QString headers; headers += QString(" * [Component details](#component-details)\n"); QString details = QString("\n### Component details:\n\n"); details += QString("|Detail|Value|\n" "|------|-----|\n"); details += QString("|%1|%2 %3.%4|\n").arg("Import").arg(module).arg(major).arg(minor); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("Component").arg(component); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("C++ class").arg(meta.className()); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("Inherits").arg(inherits); details += QString("|%1|<font color='#074885'>%2</font>|\n").arg("Model").arg(isModel?"Yes":"No"); QString resultProperties; QStringList propertiesSignals; for(int i=0; i<meta.propertyCount(); i++) { QMetaProperty property = meta.property(i); const QString &propertyName = property.name(); const QString &propertyType = fixType(property.typeName()); propertiesSignals << property.notifySignal().name(); QString text = QString("* <font color='#074885'><b>%1</b></font>: %2").arg(propertyName).arg(propertyType); if(!property.isWritable()) text += " (readOnly)"; text += "\n"; if(meta.propertyOffset()<=i) resultProperties += text; } QString enumResults; for(int i=meta.enumeratorOffset(); i<meta.enumeratorCount(); i++) { QMetaEnum enumerator = meta.enumerator(i); const QString &enumName = enumerator.name(); enumResults += QString("\n##### %1\n\n").arg(enumName); enumResults += QString("|Key|Value|\n" "|---|-----|\n"); for(int j=0; j<enumerator.keyCount(); j++) enumResults += QString("|%1|%2|\n").arg(enumerator.key(j)).arg(enumerator.value(j)); } QString resultSlots; QString resultSignals; for(int i=meta.methodOffset(); i<meta.methodCount(); i++) { QMetaMethod method = meta.method(i); if(method.access() != QMetaMethod::Public) continue; const QString &methodName = method.name(); if(propertiesSignals.contains(methodName)) continue; const QString &methodType = fixType(method.typeName()); QString args; const QList<QByteArray> ¶mNames = method.parameterNames(); const QList<QByteArray> ¶mTypes = method.parameterTypes(); for(int j=0; j<paramNames.count(); j++) { if(j != 0) args += ", "; args += fixType(paramTypes[j]) + " " + paramNames[j]; } QString text = QString(" * %1 <font color='#074885'><b>%2</b></font>(%3)\n").arg(methodType).arg(methodName).arg(args); switch(static_cast<int>(method.methodType())) { case QMetaMethod::Slot: resultSlots += text; break; case QMetaMethod::Signal: resultSignals += text; break; } } if(!resultProperties.isEmpty()) { headers += QString(" * [Normal Properties](#normal-properties)\n"); resultProperties = QString("\n### Normal Properties\n\n") + resultProperties; } if(!enumResults.isEmpty()) { headers += QString(" * [Enumerator](#enumerator)\n"); enumResults = QString("\n### Enumerator\n\n") + enumResults; } if(!resultSlots.isEmpty()) { headers += QString(" * [Methods](#methods)\n"); resultSlots = QString("\n### Methods\n\n") + resultSlots; } if(!resultSignals.isEmpty()) { headers += QString(" * [Signals](#signals)\n"); resultSignals = QString("\n### Signals\n\n") + resultSignals; } if(isModel) headers += QString(" * [Roles](#roles)\n"); result += headers + "\n"; result += details + "\n"; result += resultProperties + "\n"; result += resultSlots + "\n"; result += resultSignals + "\n"; result += enumResults + "\n"; if(!store) return result; QString path = aseman_qt_tools_destination + "/" + component.toLower() + ".md"; QFile file(path); if(!file.open(QFile::WriteOnly)) return result; file.write(result.toUtf8()); file.close(); return result; }
/*! \brief TreeModel::slotItemChanged */ void TreeModel::slotItemChanged( QStandardItem* item ) { // Item should always be there. Q_ASSERT( item ); // Get property name. QStandardItem* propNameItem = QStandardItemModel::item( item->row(), 0 ); Q_ASSERT( propNameItem ); QString propertyName; if ( item->parent() && item->parent() != invisibleRootItem() ) { propertyName = item->parent()->text(); } else { propertyName = propNameItem->text(); } int propertyIndex = mp_object->metaObject()->indexOfProperty( propertyName.toStdString().c_str() ); QMetaProperty metaProperty = mp_object->metaObject()->property( propertyIndex ); QVariant value = mp_object->property( metaProperty.name() ); if ( metaProperty.isWritable() ) { // Interupt connection ConnectionHelper connectionHelper( mp_object, metaProperty.notifySignal(), this, m_updateSlot ); if ( value.canConvert<QVector3D>() ) { QVector3D vec; vec.setX( propNameItem->child( 0, 0 )->data( Qt::EditRole ).toFloat() ); vec.setY( propNameItem->child( 0, 1 )->data( Qt::EditRole ).toFloat() ); vec.setZ( propNameItem->child( 0, 2 )->data( Qt::EditRole ).toFloat() ); mp_object->setProperty( metaProperty.name(), QVariant::fromValue( vec ) ); } else if ( value.canConvert<cv::Size>() ) { cv::Size size; size.width = propNameItem->child( 0, 0 )->data( Qt::EditRole ).toInt(); size.height= propNameItem->child( 0, 1 )->data( Qt::EditRole ).toInt(); mp_object->setProperty( metaProperty.name(), QVariant::fromValue( size ) ); } else if ( value.canConvert<FixedPropertyVector>() ) { int count = propNameItem->rowCount(); FixedPropertyVector vec ( count ); for ( int i = 0; i < vec.size(); ++i ) { vec.setData( i, propNameItem->child( i, 1 )->data( Qt::EditRole).toFloat() ); } mp_object->setProperty( metaProperty.name(), QVariant::fromValue( vec ) ); } else { // case : Standardprocedure mp_object->setProperty( metaProperty.name(), item->data( Qt::EditRole ) ); } } }
void ensureInitialized() { if (!onVisibleChanged.isValid()) { int index = q_ptr->metaObject()->indexOfMethod("implementationVisibileChanged()"); Q_ASSERT(index >= 0); onVisibleChanged = q_ptr->metaObject()->method(index); } if (component.isNull()) { Config config; config.beginGroup(QStringLiteral("qml/themes")); QString themeName = config.value(dialogName, QStringLiteral("default")); QString themePath = ThemeManager::path(QStringLiteral("qml/") + dialogName, themeName); if (themePath.isEmpty()) { qWarning() << "Failed to find theme:" << themeName << "for dialog:" << dialogName; themePath = ThemeManager::path(QStringLiteral("qml/") + dialogName, QStringLiteral("default")); if (themePath.isEmpty()) { qCritical() << "Failed to find default theme for dialog:" << dialogName; return; } } QString fileName = themePath + QStringLiteral("/main.qml"); component.reset(new QQmlComponent(DeclarativeView::globalEngine(), fileName)); } if (dialog.isNull()) { dialog = component->create(); visibleProperty = QMetaProperty(); if (!dialog) { qCritical() << "Failed to create object for component:" << component->url() << "errors:"; for (QQmlError error : component->errors()) { qCritical() << error.toString(); } return; } deathConnection = QObject::connect(dialog.data(), &QObject::destroyed, q_ptr, [this] () { dialog.clear(); visibleProperty = QMetaProperty(); updateVisible(); }); int visibleIndex = dialog->metaObject()->indexOfProperty("visible"); if (visibleIndex < 0) { qCritical() << "Failed to find \"visible\" property for component:" << component->url(); return; } visibleProperty = dialog->metaObject()->property(visibleIndex); if (!visibleProperty.hasNotifySignal()) { qCritical() << "Property \"visible\" has no notify signal for component:" << component->url(); } else { QObject::connect(dialog.data(), visibleProperty.notifySignal(), q_ptr, onVisibleChanged); } updateVisible(); } }
void QJnextMainLoop::introspect(QObject *object, QVariantList& args, QByteArray* retval) { const QMetaObject * meta = object->metaObject(); QVariantMap data; QVariantList properties; for (int i = 0; i < meta->propertyCount(); ++i) { QVariantMap propData; QMetaProperty prop = meta->property(i); propData["name"] = prop.name(); propData["type"] = prop.typeName(); if (!prop.isReadable()) { if (!prop.isWritable()) continue; propData["writeOnly"] = true; } if (!prop.isWritable()) propData["readOnly"] = true; if (prop.hasNotifySignal()) propData["notifySignal"] = getMethodName(prop.notifySignal()); if (prop.isEnumType()) propData["enumeration"] = true; properties.append(QVariant::fromValue(propData)); } data["properties"] = properties; QVariantList methods; QVariantList sigs; for (int i = 0; i < meta->methodCount(); ++i) { QVariantMap methodData; QMetaMethod method = meta->method(i); QByteArray name = getMethodName(method); if (method.access() == QMetaMethod::Private || name.startsWith("_") || name == "deleteLater" || name == "destroyed" || name == "creationCompleted") continue; else if (method.access() == QMetaMethod::Protected && method.methodType() != QMetaMethod::Signal) continue; methodData["name"] = name; QByteArray rType(method.typeName()); if (!rType.isEmpty()) methodData["type"] = rType; QList<QByteArray> pTypes = method.parameterTypes(); QList<QByteArray> pNames = method.parameterNames(); QVariantList params; for (int i = 0; i < pTypes.count(); ++i) { QVariantMap tp; tp["type"] = pTypes.at(i); tp["name"] = pNames.value(i); params.append(tp); } if (params.size() > 0) methodData["parameters"] = params; switch (method.methodType()) { case QMetaMethod::Method: //qDebug() << "=== METHOD ===" << methodData << method.signature(); methods.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Signal: sigs.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Constructor: methodData["constructor"] = true; methods.append(QVariant::fromValue(methodData)); break; case QMetaMethod::Slot: methods.append(QVariant::fromValue(methodData)); break; } } if (methods.size() > 0) data["methods"] = methods; if (sigs.size() > 0) data["signals"] = sigs; data["id"] = args.takeFirst(); bridge->json()->saveToBuffer(QVariant::fromValue(data), retval); #ifdef DEBUG_QJnextMainLoop qDebug() << "[QJnextMainLoop]\t[INTROSPECT]" << retval; #endif }
void tst_QQmlMetaObject::property() { QFETCH(QString, testFile); QFETCH(QByteArray, cppTypeName); QFETCH(int, cppType); QFETCH(bool, isDefault); QFETCH(QVariant, expectedValue); QFETCH(bool, isWritable); QFETCH(QVariant, newValue); QQmlEngine engine; QQmlComponent component(&engine, testFileUrl(testFile)); QObject *object = component.create(); QVERIFY(object != 0); const QMetaObject *mo = object->metaObject(); QVERIFY(mo->superClass() != 0); QVERIFY(QByteArray(mo->className()).contains("_QML_")); QCOMPARE(mo->propertyOffset(), mo->superClass()->propertyCount()); QCOMPARE(mo->propertyCount(), mo->superClass()->propertyCount() + 1); QMetaProperty prop = mo->property(mo->propertyOffset()); QCOMPARE(prop.name(), "test"); QCOMPARE(QByteArray(prop.typeName()), cppTypeName); if (prop.userType() < QMetaType::User) QCOMPARE(prop.type(), QVariant::Type(cppType)); else QCOMPARE(prop.type(), QVariant::UserType); QCOMPARE(prop.userType(), cppType); QVERIFY(!prop.isConstant()); QVERIFY(!prop.isDesignable()); QVERIFY(!prop.isEnumType()); QVERIFY(!prop.isFinal()); QVERIFY(!prop.isFlagType()); QVERIFY(prop.isReadable()); QVERIFY(!prop.isResettable()); QVERIFY(prop.isScriptable()); QVERIFY(!prop.isStored()); QVERIFY(!prop.isUser()); QVERIFY(prop.isValid()); QCOMPARE(prop.isWritable(), isWritable); QCOMPARE(mo->classInfoOffset(), mo->superClass()->classInfoCount()); QCOMPARE(mo->classInfoCount(), mo->superClass()->classInfoCount() + (isDefault ? 1 : 0)); if (isDefault) { QMetaClassInfo info = mo->classInfo(mo->classInfoOffset()); QCOMPARE(info.name(), "DefaultProperty"); QCOMPARE(info.value(), "test"); } QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount()); QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); // the signal QVERIFY(prop.notifySignalIndex() != -1); QMetaMethod signal = prop.notifySignal(); QCOMPARE(signal.methodType(), QMetaMethod::Signal); QCOMPARE(signal.name(), QByteArray("testChanged")); QCOMPARE(signal.methodSignature(), QByteArray("testChanged()")); QCOMPARE(signal.access(), QMetaMethod::Public); QCOMPARE(signal.parameterCount(), 0); QCOMPARE(signal.parameterTypes(), QList<QByteArray>()); QCOMPARE(signal.parameterNames(), QList<QByteArray>()); QCOMPARE(signal.tag(), ""); QCOMPARE(signal.typeName(), "void"); QCOMPARE(signal.returnType(), int(QMetaType::Void)); QSignalSpy changedSpy(object, SIGNAL(testChanged())); QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater())); if (expectedValue.isValid()) QCOMPARE(prop.read(object), expectedValue); else QVERIFY(prop.read(object).isValid()); QCOMPARE(changedSpy.count(), 0); if (isWritable) { QVERIFY(prop.write(object, newValue)); QCOMPARE(changedSpy.count(), 1); QCOMPARE(prop.read(object), newValue); } else { QVERIFY(!prop.write(object, prop.read(object))); QCOMPARE(changedSpy.count(), 0); } delete object; }
void serializeInitDynamicPacket(DataStreamPacket &ds, const QRemoteObjectSource *object) { const QMetaObject *meta = object->m_object->metaObject(); const QMetaObject *adapterMeta = Q_NULLPTR; if (object->hasAdapter()) adapterMeta = object->m_adapter->metaObject(); const SourceApiMap *api = object->m_api; ds.setId(InitDynamicPacket); ds << api->name(); //Now copy the property data const int numSignals = api->signalCount(); ds << quint32(numSignals); //Number of signals const int numMethods = api->methodCount(); ds << quint32(numMethods); //Number of methods for (int i = 0; i < numSignals; ++i) { const int index = api->sourceSignalIndex(i); if (index < 0) { qCWarning(QT_REMOTEOBJECT) << "QInitDynamicPacketEncoder - Found invalid signal. Index not found:" << i << "Dropping invalid packet."; ds.size = 0; return; } ds << api->signalSignature(i); } for (int i = 0; i < numMethods; ++i) { const int index = api->sourceMethodIndex(i); if (index < 0) { qCWarning(QT_REMOTEOBJECT) << "QInitDynamicPacketEncoder - Found invalid method. Index not found:" << i << "Dropping invalid packet."; ds.size = 0; return; } ds << api->methodSignature(i); ds << api->typeName(i); } const int numProperties = api->propertyCount(); ds << quint32(numProperties); //Number of properties for (int i = 0; i < numProperties; ++i) { const int index = api->sourcePropertyIndex(i); if (index < 0) { qCWarning(QT_REMOTEOBJECT) << "QInitDynamicPacketEncoder - Found invalid method. Index not found:" << i << "Dropping invalid packet."; ds.size = 0; return; } if (api->isAdapterProperty(i)) { const QMetaProperty mp = adapterMeta->property(index); ds << mp.name(); ds << mp.typeName(); if (mp.notifySignalIndex() == -1) ds << QByteArray(); else ds << mp.notifySignal().methodSignature(); ds << mp.read(object->m_adapter); } else { const QMetaProperty mp = meta->property(index); ds << mp.name(); ds << mp.typeName(); if (mp.notifySignalIndex() == -1) ds << QByteArray(); else ds << mp.notifySignal().methodSignature(); ds << mp.read(object->m_object); } } ds.finishPacket(); }
bool AppSettings::addTrackingProperty(const QString &key, QObject *object, const char *propname) { const QMetaObject *metaObject = object->metaObject(); /* Get the meta-property */ QMetaProperty property; if (propname) property = metaObject->property(metaObject->indexOfProperty(propname)); else property = metaObject->userProperty(); if (!property.isValid()) { qWarning() << "AppSettings: Unknown property" << propname << "for object" << object->objectName() << "of class" << metaObject->className() << "with key" << key; return false; } #ifdef QT_DEBUG /* Check for duplicates */ QMultiHash<QObject*,QPair<QString,int> >::Iterator it = trackingObjectMap.find(object); for (; it != trackingObjectMap.end() && it.key() == object; ++it) { if (it->first == key && it->second == metaObject->indexOfProperty(propname)) { qWarning() << "AppSettings: Duplicate tracking of key" << key << "by object" << object->objectName() << "of class" << metaObject->className() << "for property" << property.name(); break; } } #endif /* Connect to the notify signal of that property */ if (property.hasNotifySignal()) { /* See the comment in the header for why this hack is necessary; what we're doing here is * determining how many properties are connected from this object, and choosing one of the * five available slots based on that. Because the order in QMultiHash is based on insertion * order, we can map this back in the slot. */ char slot[] = { "1objectChanged?()" }; int propsForObject = trackingObjectMap.count(object); if (propsForObject >= 5) { qWarning() << "AppSettings: Too many properties tracked from object" << object->objectName() << "of class" << metaObject->className(); return false; } /* Cheap conversion from a single-digit number to ASCII */ slot[14] = (char)propsForObject + 48; QByteArray notify(property.notifySignal().methodSignature()); notify.prepend('2'); bool ok = connect(object, notify.constData(), this, slot); if (!ok) { qWarning() << "AppSettings: Signal connection failed for property" << property.name() << "of object" << object->objectName() << "of class" << metaObject->className() << "with key" << key; return false; } } if (!trackingObjectMap.contains(object)) connect(object, SIGNAL(destroyed(QObject*)), SLOT(removeTrackingProperty(QObject*))); /* Insert key/object mappings */ trackingKeyMap.insertMulti(key, object); trackingObjectMap.insertMulti(object, qMakePair(key, metaObject->indexOfProperty(propname))); return true; }
void DataWidgetMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName) { QMetaProperty property; for (int i=0; i<widget->metaObject()->propertyCount(); ++i) { if (QString(widget->metaObject()->property(i).name()) == propertyName) { property = widget->metaObject()->property(i); break; } } Q_ASSERT(property.isValid()); QMetaMethod notifySignal = property.notifySignal(); Q_ASSERT(notifySignal.isValid()); connect(widget, notifySignal, this, QMetaMethod::fromSignal(&DataWidgetMapper::dataChanged)); QDataWidgetMapper::addMapping(widget, section, propertyName); }