与Qt中的情况一样,有些对象不是QObject,而是由QObject管理(或者通过其他方式访问)。您需要让MyObject
监控型号该项目所在。下面的代码可能是一个起点。
另一种未实现但确实可行的方法是动态替换模型中的所有项目,并使用您自己创建的实例的副本。通过监视相关的模型信号,您可以通知所有项目添加项目,并将项目替换为您所在工厂的实例。这将是一个薄弱的依赖注入到QStandardItemModel
。
开销最低的方法是将信号和插槽从单个对象移到模型本身,这样可以避免带有潜在非常多QObject的开销,同时仍保留其信号/插槽功能。
class MyObject : public QObject {
Q_OBJECT
QStandardItem * m_item;
Q_SLOT void onRowsAboutToBeRemoved(const QModelIndex & parent, int start, int end) {
if (m_item->parent() == parent &&
m_item->index().row() >= start &&
m_item->index().row() <= end) onItemGone;
}
Q_SLOT void onColumnsAboutToBeRemoved(const QModelIndex & parent, int start, int end) {
if (m_item->parent() == parent &&
m_item->index().column() >= start &&
m_item->index().column() <= end) onItemGone;
}
Q_SLOT void onItemGone() {
m_item = 0;
deleteLater();
}
public:
MyObject(QStandardItem* item, QObject * parent = 0) :
QObject(parent), m_item(item)
{
Q_ASSERT(m_item.model());
connect(m_item.model(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
SLOT(onRowsAboutToBeRemoved(QModelIndex,int,int)));
connect(m_item.model(), SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
SLOT(onColumnsAboutToBeRemoved(QModelIndex,int,int)));
connect(m_item.model(), SIGNAL(modelAboutToBeReset()), SLOT(onItemGone());
connect(m_item.model(), SIGNAL(destroyed()), SLOT(onItemGone());
}
};
谢谢,接受。也应该跟踪resetmodel这是非常重的 - 约。为O(n^2)。所以我们决定从QObject中插入QStandardItem。 –
@DmitrySazonov我没有看到模型重置将是什么,但O(* n *),因为你所做的只是删除* n *对象。我认为你真的不应该使用QObject项目。您应该修改模型来为您提供相关的信号或插槽 - 单个模型对象应具有的信号或插槽。我也希望你没有重新实现'QDataWidgetMapper' :) –
我有类MyItemWrapper的列表。类包含'QStandardItem * m_item;'字段。摘要** N **类。另外我有一个** K **项目的模型。在model resel上,我需要测试每个MyItemWrapper实例在模型中的存在。所以复杂度是_O_(** N ** * ** K **)〜_O_(n^2)。我对吗? –