我有一个自定义代理模型,当一个新的列/行被添加到它的源模型中时,它偶尔会自我检查。从文档中可以看出,在这样的操作开始和结束时调用QAbstractItemModel::beginResetModel()和QAbstractItemModel::endResetModel()是正确的方法。不幸的是,我的检修函数有几个可能的退出点,我只知道我将忘记在每个退出点调用endResetModel
,因为它变得更复杂。
beginResetModel
,然后在销毁时调用endResetModel
,如下所示:
class ModelResetter
{
public:
ModelResetter(QAbstractItemModel* model) : m_model(model)
{
m_model->beginResetModel();
}
~ModelResetter()
{
m_model->endResetModel();
}
private:
QAbstractItemModel* m_model;
};
问题是beginResetModel()
和endResetModel()
都是QAbstractItemModel
中的protected
。在我的继承的模型中声明ModelResetter
为friend class
似乎没有帮助,因为我试图与基类交互。
我宁愿不为我实现的每个模型做一个自定义实现,所以我可以用模板做到这一点吗?我还不太熟悉模板语法。
Edit 1:(为了避免混淆,我在Edit 2中删除了示例模板代码)
如果我能以某种方式限制模板只允许继承QAbstractItemModel
的类型,那就太好了,但我在标准c++中没有看到任何允许这样做的东西。我不会使用Boost
编辑2:我想我不是很清楚我的要求。如下:
- 对一般情况下的基类进行操作
- 在调试模式下强制
QAbstractItemModel
继承要求,而在发布模式下不受惩罚 - 使用简单,几乎没有开销
- 不需要修改基类或新函数
你可以让你继承的模型暴露方法分别只调用beginResetModel()和endResetModel(),然后让ModelResetter调用这些方法
我讨厌回答我自己的问题,但几天后,我整理了一个基于模板的解决方案,满足了我的所有需求。这是我的第一个从头开始的模板类。下面是实现:
//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;
};
和用法:
//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
}
谢谢你的帮助!