与this question略有关系,但你真的不需要阅读。截图有用:
所以当你点击一个对象,更改一个属性,取消选择它然后重新选择它时,属性编辑器将重置为全0,即使这些不是实际值。实际单击编辑器中的文本框时,将显示正确的值。这是否意味着它只是一个显示问题或什么?为什么编辑器有两个不同的值? 仅当突出显示的行(带箭头)保持不变时才会发生这种情况 - 如果它们被注释掉,则不会发生这种情况。代码:
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_PROPERTY。
相关课程:http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Widgets/qtpropertybrowser/
答案 0 :(得分:2)
您是否将其他任何内容连接到m_variantManager?断开线路将断开与“this”的所有连接,但您只能连接回一个插槽。
不确定这是否会解决问题,但您可以使用object-&gt; blockSignals(true)停止一个对象上的信号。这将关闭对象,直到您使用false调用该函数。
尝试仅断开连接的信号,关闭m_variantManager而不是断开连接,并在相关的插槽中添加qDebug() - 当你断开它时会发出一些恶意信号。
编辑: 由于您自己实现了插槽,因此您可以始终使用标志并在PropertyBrowser :: valueChanged中进行检查,然后忽略该信号。
我想知道m_variantManager-&gt; addProperty()(从setSelected()调用不会立即设置值,或者设置它们但是队列更新。然后你在objectUpdated()中断开连接会导致这些事件被丢弃。