與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