我有一个自定义代理模型,当一个新的列/行被添加到它的源模型时,它偶尔会对自己进行大修。从文档中可以看出,在这样一个操作的开始和结束时调用QAbstractItemModel::beginResetModel()和QAbstractItemModel::endResetModel()是正确的方法。不幸的是,我的大修函数有几个可能的退出点,我只知道我会忘记在每个出口点调用endResetModel,因为它变得更复杂了。
因此,我想创建一个简单的RAII类,它将在构建时调用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声明为似乎没有帮助,因为我试图与基类交互。
我不想为我实现的每个模型做一个自定义实现,所以我可以用模板来实现吗?我还不太熟悉模板语法。
编辑1: (我删除了编辑2中的示例模板代码以避免混淆)
如果我能以某种方式将模板限制为只允许继承QAbstractItemModel的类型,那就太好了,但是我在标准C++中没有看到允许这样做的任何东西。我不会用助推的。
编辑2:我想我对我的需求不是很清楚。下面是它们:
QAbstractItemModel继承要求,而在发布模式中不受惩罚。发布于 2013-03-08 19:23:49
我不想回答我自己的问题,但几天后,我找到了一个基于模板的解决方案,满足了我所有的需求。为我的第一个从零开始的模板类。以下是实现:
//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
}谢谢你的帮忙!
发布于 2013-03-08 14:55:08
您可以让继承的模型公开方法分别调用beginResetModel()和endResetModel(),然后让ModelResetter调用这些方法。
https://stackoverflow.com/questions/15277447
复制相似问题