Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 光标处的实体。每个物理体存储一个指向我的对象类的引用(一个空指针!)。指针被转换回对象,并被推送到选定对象的列表上。然后,EditorView发出一个信号。EditorWindow随后捕获该信号,并将其与选定对象一起传递到PropertiesWindow。现在PropertiesWindow需要查询对象以获得要显示的属性列表。。。这就是我目前为止所做的。难以置信 解决方案 /* *文件:PropertyBrowser.cpp *作者:马克 * *创建于2009年8月23日晚上10:29 */ #包括 #包括“PropertyBrowser.h” PropertyBrowser::PropertyBrowser(QWidget*父) :QtTreePropertyBrowser(父级)、m_variantManager(新的QtVariantPropertyManager(此)){ setheadervible(false); 设置未标记值的属性(true); 设置压痕(10); setResizeMode(ResizeToContents); SetFactoryFormManager(m_variantManager,新的QtVariantEditorFactory); 设置交替生长颜色(假); } void PropertyBrowser::valueChanged(QtProperty*属性、常量QVariant和值){ 如果(m_propertyMap.find(property)!=m_propertyMap.end()){ foreach(QoObject*obj,m_选择的对象){ obj->setProperty(m_propertyMap[property],值); } } } QString PropertyBrowser::人性化(QString str)常量{ 返回str.at(0).toUpper()+str.mid(1).replace(QRegExp(([a-z])([a-z])”),“\\1\\2”); } void PropertyBrowser::SetSelectedObject(QList objs){ foreach(QoObject*obj,m_选择的对象){ obj->断开(本); } 清除(); m_variantManager->clear(); m_selectedObjects=objs; m_propertyMap.clear(); if(objs.isEmpty()){ 返回; } 对于(int i=0;imetaObject()->propertyCount();++i){ QMetaProperty元属性(objs.first()->metaObject()->property(i)); QtProperty*const属性 =m_variantManager->addProperty(metaProperty.type(),人化(metaProperty.name()); 属性->设置启用(metaProperty.isWritable()); m_propertyMap[property]=metaProperty.name(); 不动产(不动产); } foreach(QoObject*obj,m_选择的对象){ 连接(obj,信号(propertyChanged()),插槽(ObjectUpdate()); } objectUpdated(); } void PropertyBrowser::objectUpdated(){ 如果(m_selectedObjects.isEmpty()){ 返回; } 断开(m_variantManager,信号(值已更改(QtProperty*,QVariant)), 此插槽(值已更改(QtProperty*,QVariant)); qmaterator i(m_propertyMap); 布尔差异; while(i.hasNext()){ i、 next(); diff=假; 对于(int j=1;j属性(i.value())!=m_selectedObjects.at(j-1)->属性(i.value()){ diff=真; 打破 } } if(diff)setBackgroundColor(topLevelItem(i.key())、QColor(0xFF、0xFE、0xA9)); else setBackgroundColor(topLevelItem(i.key()),Qt::白色); m_variantManager->setValue(i.key(),m_SelectedObject.first()->属性(i.value()); } 连接(m_variantManager,信号(值已更改(QtProperty*,QVariant)), 此插槽(值已更改(QtProperty*,QVariant)); }_C++_Design Patterns_Qt - Fatal编程技术网

C++ 光标处的实体。每个物理体存储一个指向我的对象类的引用(一个空指针!)。指针被转换回对象,并被推送到选定对象的列表上。然后,EditorView发出一个信号。EditorWindow随后捕获该信号,并将其与选定对象一起传递到PropertiesWindow。现在PropertiesWindow需要查询对象以获得要显示的属性列表。。。这就是我目前为止所做的。难以置信 解决方案 /* *文件:PropertyBrowser.cpp *作者:马克 * *创建于2009年8月23日晚上10:29 */ #包括 #包括“PropertyBrowser.h” PropertyBrowser::PropertyBrowser(QWidget*父) :QtTreePropertyBrowser(父级)、m_variantManager(新的QtVariantPropertyManager(此)){ setheadervible(false); 设置未标记值的属性(true); 设置压痕(10); setResizeMode(ResizeToContents); SetFactoryFormManager(m_variantManager,新的QtVariantEditorFactory); 设置交替生长颜色(假); } void PropertyBrowser::valueChanged(QtProperty*属性、常量QVariant和值){ 如果(m_propertyMap.find(property)!=m_propertyMap.end()){ foreach(QoObject*obj,m_选择的对象){ obj->setProperty(m_propertyMap[property],值); } } } QString PropertyBrowser::人性化(QString str)常量{ 返回str.at(0).toUpper()+str.mid(1).replace(QRegExp(([a-z])([a-z])”),“\\1\\2”); } void PropertyBrowser::SetSelectedObject(QList objs){ foreach(QoObject*obj,m_选择的对象){ obj->断开(本); } 清除(); m_variantManager->clear(); m_selectedObjects=objs; m_propertyMap.clear(); if(objs.isEmpty()){ 返回; } 对于(int i=0;imetaObject()->propertyCount();++i){ QMetaProperty元属性(objs.first()->metaObject()->property(i)); QtProperty*const属性 =m_variantManager->addProperty(metaProperty.type(),人化(metaProperty.name()); 属性->设置启用(metaProperty.isWritable()); m_propertyMap[property]=metaProperty.name(); 不动产(不动产); } foreach(QoObject*obj,m_选择的对象){ 连接(obj,信号(propertyChanged()),插槽(ObjectUpdate()); } objectUpdated(); } void PropertyBrowser::objectUpdated(){ 如果(m_selectedObjects.isEmpty()){ 返回; } 断开(m_variantManager,信号(值已更改(QtProperty*,QVariant)), 此插槽(值已更改(QtProperty*,QVariant)); qmaterator i(m_propertyMap); 布尔差异; while(i.hasNext()){ i、 next(); diff=假; 对于(int j=1;j属性(i.value())!=m_selectedObjects.at(j-1)->属性(i.value()){ diff=真; 打破 } } if(diff)setBackgroundColor(topLevelItem(i.key())、QColor(0xFF、0xFE、0xA9)); else setBackgroundColor(topLevelItem(i.key()),Qt::白色); m_variantManager->setValue(i.key(),m_SelectedObject.first()->属性(i.value()); } 连接(m_variantManager,信号(值已更改(QtProperty*,QVariant)), 此插槽(值已更改(QtProperty*,QVariant)); }

C++ 光标处的实体。每个物理体存储一个指向我的对象类的引用(一个空指针!)。指针被转换回对象,并被推送到选定对象的列表上。然后,EditorView发出一个信号。EditorWindow随后捕获该信号,并将其与选定对象一起传递到PropertiesWindow。现在PropertiesWindow需要查询对象以获得要显示的属性列表。。。这就是我目前为止所做的。难以置信 解决方案 /* *文件:PropertyBrowser.cpp *作者:马克 * *创建于2009年8月23日晚上10:29 */ #包括 #包括“PropertyBrowser.h” PropertyBrowser::PropertyBrowser(QWidget*父) :QtTreePropertyBrowser(父级)、m_variantManager(新的QtVariantPropertyManager(此)){ setheadervible(false); 设置未标记值的属性(true); 设置压痕(10); setResizeMode(ResizeToContents); SetFactoryFormManager(m_variantManager,新的QtVariantEditorFactory); 设置交替生长颜色(假); } void PropertyBrowser::valueChanged(QtProperty*属性、常量QVariant和值){ 如果(m_propertyMap.find(property)!=m_propertyMap.end()){ foreach(QoObject*obj,m_选择的对象){ obj->setProperty(m_propertyMap[property],值); } } } QString PropertyBrowser::人性化(QString str)常量{ 返回str.at(0).toUpper()+str.mid(1).replace(QRegExp(([a-z])([a-z])”),“\\1\\2”); } void PropertyBrowser::SetSelectedObject(QList objs){ foreach(QoObject*obj,m_选择的对象){ obj->断开(本); } 清除(); m_variantManager->clear(); m_selectedObjects=objs; m_propertyMap.clear(); if(objs.isEmpty()){ 返回; } 对于(int i=0;imetaObject()->propertyCount();++i){ QMetaProperty元属性(objs.first()->metaObject()->property(i)); QtProperty*const属性 =m_variantManager->addProperty(metaProperty.type(),人化(metaProperty.name()); 属性->设置启用(metaProperty.isWritable()); m_propertyMap[property]=metaProperty.name(); 不动产(不动产); } foreach(QoObject*obj,m_选择的对象){ 连接(obj,信号(propertyChanged()),插槽(ObjectUpdate()); } objectUpdated(); } void PropertyBrowser::objectUpdated(){ 如果(m_selectedObjects.isEmpty()){ 返回; } 断开(m_variantManager,信号(值已更改(QtProperty*,QVariant)), 此插槽(值已更改(QtProperty*,QVariant)); qmaterator i(m_propertyMap); 布尔差异; while(i.hasNext()){ i、 next(); diff=假; 对于(int j=1;j属性(i.value())!=m_selectedObjects.at(j-1)->属性(i.value()){ diff=真; 打破 } } if(diff)setBackgroundColor(topLevelItem(i.key())、QColor(0xFF、0xFE、0xA9)); else setBackgroundColor(topLevelItem(i.key()),Qt::白色); m_variantManager->setValue(i.key(),m_SelectedObject.first()->属性(i.value()); } 连接(m_variantManager,信号(值已更改(QtProperty*,QVariant)), 此插槽(值已更改(QtProperty*,QVariant)); },c++,design-patterns,qt,C++,Design Patterns,Qt,非常感谢TimW冷静下来,您的代码并不复杂。您有一个嵌套循环,但只有一个循环计数为N(对象数),其他循环计数为固定数量的属性,这与N无关。因此您有O(N) 对于静态变量,您可以编写“没有任何特定于实例的属性”,然后编写对象的各个属性的更新,这些属性正是特定于实例的属性。也许您混淆了“类属性”(当然是所有属性共享的)和单个属性?所以我认为你根本不需要静态成员 是否仅在对象出现时才显示对其所做的更改,还是要连续显示?如果您的硬件能够处理后者,我建议您这样做。在这种情况下,您必须迭代所有对象,并沿途更

非常感谢TimW

冷静下来,您的代码并不复杂。您有一个嵌套循环,但只有一个循环计数为N(对象数),其他循环计数为固定数量的属性,这与N无关。因此您有O(N)

对于静态变量,您可以编写“没有任何特定于实例的属性”,然后编写对象的各个属性的更新,这些属性正是特定于实例的属性。也许您混淆了“类属性”(当然是所有属性共享的)和单个属性?所以我认为你根本不需要静态成员

是否仅在对象出现时才显示对其所做的更改,还是要连续显示?如果您的硬件能够处理后者,我建议您这样做。在这种情况下,您必须迭代所有对象,并沿途更新它们

编辑:不同之处在于,在前者(更改时更新)中,图形是通过更改值的操作启动的,例如对象移动。对于后者,一个continuos显示,您需要添加一个QTimer,它每秒触发60次,并调用一个SLOT(render()),该SLOT对所有对象进行实际渲染。根据变化的速度,这实际上可能更快。而且它可能更容易实现。 另一种可能性是让Qt使用图形视图处理整个图形,该视图以非常高效的树结构处理要在内部绘制的对象。看看


如果只想显示更改,可以对每个属性值使用单独的回调。每次更改属性的值时(在本例中,将属性设置为私有并使用setSomeThing(value)),都使用emit(update())调用update函数。如果您非常关心emit的速度慢,那么可以通过函数指针使用“真正的”回调,但我不建议这样做,因为Qt的connect/signal/slot更易于使用。而且在大多数情况下,开销是可以忽略不计的。

您看过Qt吗


你说,没有特定于对象的属性。但在你的屏幕上,我至少数了两个物体。你想说,这些对象的属性总是共享的吗?如果是这样,则不需要整个选择过程等。我想你不想那样。也许这是你设计中的缺陷?不,你误解了我。我所说的“属性”是指“允许睡眠”或“速度”——所有对象都有这些属性——但它们的值对于每个实例都是唯一的。+1用于O(n)分析和
function valueChanged(property, value) {
    if(property == xPosProp) {
        foreach(selectedObj as obj) {
            obj->setXPos(value);
        }
    } else if(property == ...
function xPosChanged(property, value) {
    foreach(selectedObj as obj) {
        obj->setXPos(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);

}

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;
    }
    disconnect(m_variantManager, SIGNAL(valueChanged(QtProperty*, QVariant)), 
            this, SLOT(valueChanged(QtProperty*, QVariant)));
    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(0xFF,0xFE,0xA9));
        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)));
}
bool QObject::setProperty ( const char * name, const QVariant & value );
QVariant QObject::property ( const char * name ) const
QList<QByteArray> QObject::dynamicPropertyNames () const;
//Changing the value of a dynamic property causes a 
//QDynamicPropertyChangeEvent to be sent to the object.


function valueChanged(property, value) {
       foreach(selectedObj as obj) {
           obj->setProperty(property, value);
   }
} 
class SelectableItem : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName );
    Q_PROPERTY(int velocity READ velocity WRITE setVelocity);

public:
    QString name() const { return m_name; }
    int velocity() const {return m_velocity; }

public slots:
    void setName(const QString& name) 
    {
        if(name!=m_name)
        {
            m_name = name;
            emit update();
        }
    }
    void setVelocity(int value)
    {
        if(value!=m_velocity)
        {
            m_velocity = value;
            emit update();
        }
    }

signals:
    void update();

private:
    QString m_name;
    int m_velocity;
};

class MyPropertyWatcher : public QObject
{
    Q_OBJECT
public:
    MyPropertyWatcher(QObject *parent) 
    : QObject(parent), 
      m_variantManager(new QtVariantPropertyManager(this)),
      m_propertyMap(),
      m_selectedItem(),
      !m_updatingValues(false)
    {
        connect(m_variantManager, SIGNAL(valueChanged(QtProperty*, QVariant)), SLOT(valueChanged(QtProperty*,QVariant)));
        m_propertyMap[m_variantManager->addProperty(QVariant::String, tr("Name"))] = "name";
        m_propertyMap[m_variantManager->addProperty(QVariant::Int, tr("Velocity"))] = "velocity";
        // Add mim, max ... to the property
        // you could also add all the existing properties of a SelectableItem
        // SelectableItem item;
        // for(int i=0 ; i!=item.metaObject()->propertyCount(); ++i)
        // {
        //     QMetaProperty metaProperty(item.metaObject()->property(i));
        //     QtProperty *const property 
        //         = m_variantManager->addProperty(metaProperty.type(), metaProperty.name());
        //     m_propertyMap[property] = metaProperty.name()
        // }
    }

    void setSelectedItem(SelectableItem * selectedItem)
    {
        if(m_selectedItem)
        {
            m_selectedItem->disconnect( this );
        }

        if(selectedItem)
        {
            connect(selectedItem, SIGNAL(update()), SLOT(itemUpdated()));
            itemUpdated();
        }
        m_selectedItem = selectedItem;
    }


private slots:
    void valueChanged(QtProperty *property, const QVariant &value)
    {
        if(m_updatingValues)
        {
            return; 
        }

        if(m_selectedItem && m_map)
        {
            QMap<QtProperty*, QByteArray>::const_iterator i = m_propertyMap.find(property);
            if(i!=m_propertyMap.end())
                m_selectedItem->setProperty(m_propertyMap[property], value);
        }
    }  

    void itemUpdated()
    {
        m_updatingValues = true;
        QMapIterator<QtProperty*, QByteArray> i(m_propertyMap);
        while(i.hasNext()) 
        {
            m_variantManager->next();
            m_variantManager->setValue(
                i.key(), 
                m_selectedItem->property(i.value()));                
        }
        m_updatingValues = false;
    }

private:
    QtVariantPropertyManager *const m_variantManager;
    QMap<QtProperty*, QByteArray> m_propertyMap;
    QPointer<SelectableItem> m_selectedItem;
    bool m_updatingValues;
};