Slightly related to this question, but you don’t really need to read that. The screenshot is helpful though:

So what’s happening is when you click an object, change a property, deselect it and then reselect it, the property editor will be reset to all 0s, even though those aren’t the actual values. When you actually click in the text boxes in the editor, the correct value appears. Does that mean it’s just a display issue or what? How come the editor has two different values? This only happens when the highlighted lines (with arrows) are left intact — if they are commented out, this won’t occur. The code:
void PropertyBrowser::objectUpdated() {
if(m_selectedObjects.isEmpty()) {
return;
}
m_variantManager->disconnect(this); // <--- THIS LINE
QMapIterator<QtProperty*, QByteArray> i(m_propertyMap);
bool diff;
while(i.hasNext()) {
i.next();
diff = false;
for(int j = 1; j < m_selectedObjects.size(); ++j) {
if(m_selectedObjects.at(j)->property(i.value()) != m_selectedObjects.at(j - 1)->property(i.value())) {
diff = true;
break;
}
}
if(diff) setBackgroundColor(topLevelItem(i.key()), QColor(232,232,232));
else setBackgroundColor(topLevelItem(i.key()), Qt::white);
m_variantManager->setValue(i.key(), m_selectedObjects.first()->property(i.value()));
}
connect(m_variantManager, SIGNAL(valueChanged(QtProperty*, QVariant)),
this, SLOT(valueChanged(QtProperty*, QVariant))); // <--- AND THIS LINE
}
However, I need those lines because they prevent setValue from triggering a valueChanged signal which causes other issues. This seems to indicate that calls this function fixes the issue:
void PropertyBrowser::valueChanged(QtProperty *property, const QVariant &value) {
if(m_propertyMap.find(property) != m_propertyMap.end()) {
foreach(QObject *obj, m_selectedObjects) {
obj->setProperty(m_propertyMap[property], value);
}
}
}
But the only thing that THAT function does is update the actual object… it has nothing to do with the property editor (or shouldn’t). Here’s the entire class if you need it:
/*
* File: PropertyBrowser.cpp
* Author: mark
*
* Created on August 23, 2009, 10:29 PM
*/
#include <QtCore/QMetaProperty>
#include "PropertyBrowser.h"
PropertyBrowser::PropertyBrowser(QWidget* parent)
: QtTreePropertyBrowser(parent), m_variantManager(new QtVariantPropertyManager(this)) {
setHeaderVisible(false);
setPropertiesWithoutValueMarked(true);
setIndentation(10);
setResizeMode(ResizeToContents);
setFactoryForManager(m_variantManager, new QtVariantEditorFactory);
setAlternatingRowColors(false);
connect(m_variantManager, SIGNAL(valueChanged(QtProperty*, QVariant)),
this, SLOT(valueChanged(QtProperty*, QVariant)));
}
void PropertyBrowser::valueChanged(QtProperty *property, const QVariant &value) {
if(m_propertyMap.find(property) != m_propertyMap.end()) {
foreach(QObject *obj, m_selectedObjects) {
obj->setProperty(m_propertyMap[property], value);
}
}
}
QString PropertyBrowser::humanize(QString str) const {
return str.at(0).toUpper() + str.mid(1).replace(QRegExp("([a-z])([A-Z])"), "\\1 \\2");
}
void PropertyBrowser::setSelectedObjects(QList<QObject*> objs) {
foreach(QObject *obj, m_selectedObjects) {
obj->disconnect(this);
}
clear();
m_variantManager->clear();
m_selectedObjects = objs;
m_propertyMap.clear();
if(objs.isEmpty()) {
return;
}
for(int i = 0; i < objs.first()->metaObject()->propertyCount(); ++i) {
QMetaProperty metaProperty(objs.first()->metaObject()->property(i));
QtProperty * const property
= m_variantManager->addProperty(metaProperty.type(), humanize(metaProperty.name()));
property->setEnabled(metaProperty.isWritable());
m_propertyMap[property] = metaProperty.name();
addProperty(property);
}
foreach(QObject *obj, m_selectedObjects) {
connect(obj, SIGNAL(propertyChanged()), SLOT(objectUpdated()));
}
objectUpdated();
}
void PropertyBrowser::objectUpdated() {
if(m_selectedObjects.isEmpty()) {
return;
}
m_variantManager->disconnect(this); // <---
QMapIterator<QtProperty*, QByteArray> i(m_propertyMap);
bool diff;
while(i.hasNext()) {
i.next();
diff = false;
for(int j = 1; j < m_selectedObjects.size(); ++j) {
if(m_selectedObjects.at(j)->property(i.value()) != m_selectedObjects.at(j - 1)->property(i.value())) {
diff = true;
break;
}
}
if(diff) setBackgroundColor(topLevelItem(i.key()), QColor(232,232,232));
else setBackgroundColor(topLevelItem(i.key()), Qt::white);
m_variantManager->setValue(i.key(), m_selectedObjects.first()->property(i.value()));
}
connect(m_variantManager, SIGNAL(valueChanged(QtProperty*, QVariant)), // <---
this, SLOT(valueChanged(QtProperty*, QVariant)));
}
It’s otherwise a very cool class if you want to use it. Let’s you edit the properties of any QObject given that they have Q_PROPERTYs attached.
Relevant class: http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Widgets/qtpropertybrowser/
Do you connect anything else to m_variantManager? Disconnecting line will disconnect everything from “this”, but you connect back only one slot.
Not sure if this will fix something, but you can stop signals on one object using object->blockSignals(true). This will shut the object up untill you call the function with false.
Try disconnecting only signal you connect, shutting m_variantManager instead of disconnecting, and adding qDebug() in relevant slots — there is some rogue signal emitted when you disconnected it seems.
EDIT:
Since you implement the slot yourself, you can always have a flag and check it in PropertyBrowser::valueChanged then just ignore the signal.
I wonder if m_variantManager->addProperty() (called from setSelected() doesn’t immidiately set the values, or sets them but queues updates. Then your disconnecting in objectUpdated() causes those events to be discarded.