Question

I'm writing some wrappers over QStandardItemModel. Is it possible to track lifetime (delete events) of QStandardItems?

I think that the only way is to interhit QObject + QStandardItem. But I don't want to do it for some reasons.

UPDATE:

I need to delete my object, that contains pointer to QStandardItem, when this item removed from model.

Here is solution. But I want to do the same for external (not mine) 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 );
  }
  // ...
};
Was it helpful?

Solution

As is often the case in Qt, there are objects that are not QObjects, but that are managed by a QObject (or otherwise accessible via one). You need to make MyObject monitor the model the items are in. The code below could be a starting point.

Another approach, not implemented but certainly feasible, is to dynamically replace all items in a model with copies that are instances that you yourself created. By monitoring the relevant model signals, you can be notified of all item additions and replace items with instances that you are a factory for. It would be a thinly veiled dependency injection into a QStandardItemModel.

The lowest-overhead approach would be to move the signals and slots from individual objects to the model itself, so that you avoid the overhead of having potentially very many QObjects, while still retaining their signal/slot functionality.

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

OTHER TIPS

Every data model has signals about changes in the model, see documentation of QAbstractItemModel and this is what you need.

Note that QStandardItem is not a QObject so it doesn't have any signals or slots.

Can you please clarify what you mean by track lifetime. Why do you want to subclass QObject? Are you going to use SIGNALS and SLOTs? If no then I don't think it is going to be of much use. Apart from that you can subclass QStandardItem and track the lifetime using your constructor and destructor or a suitable function?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top