2014-02-28 54 views
1

我在QStandardItemModel上写了一些包装。是否有可能跟踪QStandardItems的生命周期(删除事件)?跟踪QStandardItem生命周期

我认为唯一的方法就是interhit QObject + QStandardItem。但我不想出于某些原因这样做。

UPDATE:

我要删除我的对象,包含指向QStandardItem,当这个项目从模型中移除。

这里是解决方案。但我想为外部(而不是我的)QStandardItem做同样的事情。

class ItemWrap : public QObject, public QStandardItem 
{ 
    // ... 
}; 
class MyObject : public QObject 
{ 
    MyObject(ItemWrap *item) // I need MyObject(QStandardItem *item) 
    { 
    connect(item, &QObject::destroyed, this, &MyObject::deletelater); 
    } 
    // ... 
}; 

回答

1

与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()); 
    } 
}; 
+0

谢谢,接受。也应该跟踪resetmodel这是非常重的 - 约。为O(n^2)。所以我们决定从QObject中插入QStandardItem。 –

+0

@DmitrySazonov我没有看到模型重置将是什么,但O(* n *),因为你所做的只是删除* n *对象。我认为你真的不应该使用QObject项目。您应该修改模型来为您提供相关的信号或插槽 - 单个模型对象应具有的信号或插槽。我也希望你没有重新实现'QDataWidgetMapper' :) –

+0

我有类MyItemWrapper的列表。类包含'QStandardItem * m_item;'字段。摘要** N **类。另外我有一个** K **项目的模型。在model resel上,我需要测试每个MyItemWrapper实例在模型中的存在。所以复杂度是_O_(** N ** * ** K **)〜_O_(n^2)。我对吗? –

0

能否请你澄清你的轨寿命的意思。 为什么你想要子类QObject? 您打算使用SIGNALSSLOTs吗?如果没有,那么我认为它不会有太大用处。 除此之外,你可以子类QStandardItem和跟踪使用你的构造函数和析构函数或一个合适的功能?

+0

更新的问题。顺便说一句,我告诉原来的问题,我不想Interhit'QObject'和QStandardItem。以理想的方式,我想要一个解决方案,而不需要用'QStandardItem'(尤其是子类)做任何事情。 –

1

每个数据模型都有关于模型变化的信号,请参阅文档QAbstractItemModel,这就是您需要的。

请注意,QStandardItem不是QObject,所以它没有任何信号或插​​槽。