与this question稍有关系,但你并不需要阅读它。该截图是有帮助的,但:奇怪的Qt错误(关于属性编辑器)
那么是什么发生的是,当你点击一个对象,更改属性,取消选择,然后重新选择它,属性编辑器将被重置为全0,即使那些AREN实际值。当您实际点击编辑器中的文本框时,会显示正确的值。这是否意味着它只是一个显示问题或什么?编辑如何有两个不同的价值观? 只有当突出显示的行(带有箭头)保持不变时才会发生这种情况 - 如果它们被注释掉,则不会发生。代码:
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
}
不过,我需要那些行,因为他们阻止setValue
从触发valueChanged
信号引起的其他问题。这似乎表明,调用该函数修复该问题:
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);
}
}
}
但是,该函数的作用的唯一的事情就是更新实际的对象...它无关,与属性编辑器(或不应该) 。如果你需要的话,这里是整个班级:
/*
* 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)));
}
如果你想使用它,它是非常酷的类。让我们编辑任何QObject的属性,因为它们附有Q_PROPERTYs。
相关类:http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Widgets/qtpropertybrowser/
使用'm_variantManager-> blockSignals'似乎与我所期望的断开/重新连接具有完全相同的效果,尽管它确实为更好的代码。**我是**没有连接任何其他的m_variantManager,但也许你'还有其他的东西是不经意的......也许我可以用SignalSpy或者其他东西来找出它是什么,明天我就得试试,谢谢。否则,不要发送'valueChanged'信号来阻止m_variantManager,我可以防止对象暂时收到它吗? – mpen 2009-08-25 07:49:44
“尝试di只连接你连接的信号“ - 做到了。没有意识到你可以通过更多的参数'断开连接',仍然是新的Qt :)仍然不知道是什么原因导致了这种行为,但哦... – mpen 2009-08-26 19:50:58
看起来像一些其他信号连接到“this”从m_variantManager,可能在构造函数中:new QtVariantPropertyManager(this)。 – Eugene 2009-08-27 03:26:12