答案 0 :(得分:3)
冷静下来,你的代码没有O(n ^ 2)完整性。你有一个嵌套循环,但只有一个计入N(对象数),另一个计入固定数量的属性,这与N无关。所以你有O(N)。
对于静态变量,您编写“没有任何特定于实例的属性”,稍后您将撰写对象的各个属性的更新,这些属性是特定于实例的属性。也许你把“类属性”(当然在所有属性中共享)与个别属性混淆了?所以我认为你根本不需要静态成员。
是否要仅在对象出现时显示对象的更改,还是要进行连续显示?如果您的硬件能够处理后者,我建议采用这种方式。在这种情况下,您必须遍历所有对象并在此过程中更新它们。
编辑:区别在于前者(更新时更新),绘图由更改值的操作启动,例如对象移动。对于后者,一个连续显示,你会添加一个QTimer,每秒激发60次并调用一个SLOT(render())来实现所有对象的实际渲染。根据变化的速度,这实际上可能更快。它可能更容易实现。 另一个可能性是让Qt使用图形视图来处理整个绘图,它在一个非常有效的树结构中内部处理要绘制的对象。看一眼 http://doc.trolltech.com/4.5/graphicsview.html
如果只想显示更改,可以为每个属性值使用单独的回调。每次更改属性的值(在这种情况下使属性值为private并使用setSomeThing(value))时,都使用emit(update())调用update函数。如果你绝对关注发射慢,你可以通过函数指针使用“真正的”回调,但我不建议,Qt的连接/信号/插槽更容易使用。在大多数情况下,开销确实可以忽略不计。
答案 1 :(得分:3)
您是否看过Qt的(dynamic) property system?
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);
}
}
这是一个不完整的例子,可以让您了解我对物业系统的看法。
我想SelectableItem * selectedItem
必须替换为您案例中的项目列表。
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;
};