2

新しい列/行がソース モデルに追加されると、それ自体がオーバーホールされるカスタム プロキシ モデルがあります。ドキュメントから、そのような操作の開始時と終了時に QAbstractItemModel ::beginResetModel()QAbstractItemModel::endResetModel( ) を呼び出すことが適切な方法であるように見えます。endResetModel残念ながら、私のオーバーホール関数にはいくつかの出口点があり、複雑になるにつれてすべての出口点で呼び出すのを忘れてしまうことがわかっています。

beginResetModelしたがって、次のように、構築を呼び出しendResetModelてから破棄を呼び出す単純な RAII クラスを作成したいと思います。

class ModelResetter
{
public:
    ModelResetter(QAbstractItemModel* model) : m_model(model)
    {
        m_model->beginResetModel();
    }
    ~ModelResetter()
    {
        m_model->endResetModel();
    }

private:
    QAbstractItemModel* m_model;
};

問題は、beginResetModel()endResetModel()の両方が にあることprotectedですQAbstractItemModel。基本クラスと対話しようとしているので、継承ModelResetterされたモデルで として宣言しても役に立たないようです。friend class

実装するモデルごとにカスタム実装を行いたくないので、テンプレートでこれを行うことはできますか? 私はまだテンプレートの構文にあまり慣れていません。

編集 1: (混乱を避けるために、編集 2 のサンプル テンプレート コードを削除しました)

を継承する型のみを許可するようにテンプレートを何らかの形で制限できればいいのですが、それを許可するQAbstractItemModel標準 C++ には何もありません。ブーストは使用しません。

編集 2 : 私は自分の要件について本当に明確ではなかったと思います。どうぞ:

  • 一般的なケースの基本クラスで動作します
  • QAbstractItemModelリリース モードでのペナルティなしに、デバッグ モードで継承要件を強制します。
  • オーバーヘッドがほとんどないシンプルな使い方
  • 基本クラスや新しい関数の変更は不要
4

2 に答える 2

1

継承されたモデルに beginResetModel() と endResetModel() をそれぞれ呼び出すだけのメソッドを公開させ、ModelResetter にそれらのメソッドを呼び出させることができます。

于 2013-03-08T14:55:08.647 に答える
0

私は自分の質問に答えるのが嫌いですが、数日後、すべての要件を満たすテンプレートベースのソリューションをまとめました。私の最初のゼロからのテンプレートクラスに賛成です。実装は次のとおりです。

//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-08T19:23:49.850 に答える