I have a custom proxy model that occasionally overhauls itself when a new column/row is added to its source model. From the docs it appears that calling QAbstractItemModel::beginResetModel() and QAbstractItemModel::endResetModel() at the beginning and end of such an operation is the proper methodology. My overhaul function, unfortunately, has several possible exit points and I just know that I'll forget to call endResetModel
at every exit point as it gets more complex.
Therefore, I'd like to create a simple RAII class that will call beginResetModel
upon construction and then call endResetModel
upon destruction, like follows:
class ModelResetter
{
public:
ModelResetter(QAbstractItemModel* model) : m_model(model)
{
m_model->beginResetModel();
}
~ModelResetter()
{
m_model->endResetModel();
}
private:
QAbstractItemModel* m_model;
};
The problem is that beginResetModel()
and endResetModel()
are both protected
in QAbstractItemModel
. Declaring ModelResetter
as a friend class
in my inherited model doesn't appear to help, since I'm trying to interact with the base class.
I'd rather not do a custom implementation for every model I implement, so can I do this with templates? I'm not very familiar with template syntax yet.
Edit 1: (I removed the sample template code in Edit 2 to avoid confusion)
It'd be nice if I could somehow restrict the template to only allow types that inherit QAbstractItemModel
, but I don't see anything in standard C++ that allows that. I will not use Boost.
Edit 2: I guess I wasn't really clear about my requirements. Here they are:
QAbstractItemModel
inheritance requirement while in debug mode without penalty in release modeI hate to answer my own question, but after a couple days I put together a template-based solution that fulfills all of my requirements. Yay for my first from-scratch template class. Here's the implementation:
//modelresetter.h
#include <QAbstractItemModel>
/* you must declare this class as a friend to your model
* to give it access to protected members as follows:
* template <class Model> friend class ModelResetter;
*/
template<class Model>
class ModelResetter
{
public:
ModelResetter(Model* model) : m_model(model)
{
Q_ASSERT_X(qobject_cast<QAbstractItemModel*>(model) != 0, __FUNCTION__,
"templated object does not inherit QAbstractItemModel");
m_model->beginResetModel();
}
~ModelResetter()
{
m_model->endResetModel();
}
private:
Model* m_model;
};
and usage:
//mymodel.cpp
bool MyModel::overhaul()
{
ModelResetter<MyModel> resetter(this); resetter; //prevent compiler warning
//do stuff
if(somethingswrong)
return false; //model will finish reset at every exit point
//do more stuff
return true; //model also completes reset on success
}
Thanks for your help!