【问题标题】:Subclassing: QAbstractItemModel has no member子类化:QAbstractItemModel 没有成员
【发布时间】:2014-08-04 13:18:51
【问题描述】:

我对 C++ 和 Qt 框架比较陌生。我尝试使用从 QAbstractListModel 派生的自定义模型来实现一个简单的 QTableView。

如果我打电话

model->appendRow("Test");

在我的主应用程序中,一切正常。但是,如果我打电话

table->model()->appendRow("Test");

我收到以下构建错误:

'class QAbstractItemModel' has no member named 'appendRow'
         table->model()->appendRow("Test");
                     ^

我错过了什么?

源码:

ma​​in.c

#include <QApplication>
#include <QTableView>
#include "exercises.h"


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTableView *table = new QTableView();
    exercisesModel *model = new exercisesModel();
    table->setModel(model);

    model->appendRow("Test"); //why does this work...
    table->model()->appendRow("Test"); //...and this doesn't?

    table->show();

    return a.exec();
} 

exercises.h

#ifndef EXERCISES_H
#define EXERCISES_H

#include <QWidget>
#include <QAbstractListModel>

class exercisesModel : public QAbstractListModel
{
public:
    exercisesModel(QObject *parent = 0);
    int rowCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    bool appendRow(QString data);
private:
    QList <QString> lst;

};

#endif // EXERCISES_H

exercises.c

#include "exercises.h"
#include <QDebug>


exercisesModel::exercisesModel(QObject *parent) : QAbstractListModel(parent){
}

int exercisesModel::rowCount(const QModelIndex &parent) const{
    Q_UNUSED(parent);
    return this->lst.size();

}

QVariant exercisesModel::data(const QModelIndex &index, int role) const{
    if(this->lst.size() != 0){
        if (role == Qt::DisplayRole){
            return this->lst[index.row()];
        }

        return QVariant();
    }
    return QVariant();

}

bool exercisesModel::appendRow(QString data){
    int lastElemPos = this->lst.size();
    beginInsertRows(QModelIndex(), lastElemPos, lastElemPos);
    this->lst << data;

    endInsertRows();

    return true;

}

【问题讨论】:

    标签: c++ qt subclassing qabstractitemmodel


    【解决方案1】:

    QTableView::model() 成员函数返回一个指向QAbstractItemModel 的指针。这就是编译器在您调用table-&gt;model()-&gt;appendRow("Test") 时所知道的所有类型。它不知道您的派生模型是实际指向的。有几种方法可以解决这个问题。

    一种方法是使用演员表:

    static_cast<exercisesModel*>(table->model())->appendRow("Test")
    

    现在你明确地告诉编译器“我知道对象的实际类型是exercisesModel”,所以它可以适当地对待它。

    正如 Kuba Ober 所指出的,Qt 有自己的强制转换来验证类型是否正确

    qobject_cast<exercisesModel*>(table->model())->appendRow("Test")
    

    这比static_cast 好,但是这种检查只会在运行时进行,并且在编译过程中可以发现的问题越多越好。

    最好的选择可能是保留指向您的 exercisesModel 的指针并使用它,因此毫无疑问基础类型是什么。

    【讨论】:

    • 您还应该提到可以使用qobject_cast&lt;exercisesModel*&gt; 代替,允许验证对象的类型是否正确。与dynamic_cast相反,即使禁用了 RTTI,这也将起作用。
    【解决方案2】:

    因为table-&gt;model() 返回一个QAbstractItemModel,而QAbstractItemModel 没有你在exerciseModel 中声明的appendRow 函数,它是QAbstractItemModel 的子类。编译器无法知道table 存储的实际类型。

    要从table-&gt;model() 访问appendRow,您需要进行类型转换:

    exercisesModel *model = qobject_cast<exercisesModel *>(table->model());
    // dynamic_cast could also be used.
    Q_ASSERT(model);
    model->appendRow("Test");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 2015-08-14
      • 1970-01-01
      相关资源
      最近更新 更多