子类:QAbstractItemModel没有成员

时间:2014-08-04 13:18:51

标签: c++ qt subclassing qabstractitemmodel

我对C ++和Qt Framework相对较新。我尝试使用从QAbstractListModel派生的自定义模型实现一个简单的QTableView。

如果我打电话

model->appendRow("Test");

在我的主要应用程序中,一切都运行得很好。但是,如果我打电话

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

我收到以下构建错误:

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

我错过了什么?

源码:

的main.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;

}

2 个答案:

答案 0 :(得分:4)

QTableView::model()成员函数返回指向QAbstractItemModel的指针。这就是编译器在调用table->model()->appendRow("Test")时所知道的所有类型。它并不知道您的派生模型实际上是指向的。有几种方法可以处理。

一种方法是使用演员:

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

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

如Kuba Ober所述,Qt有自己的演员,将验证类型是否正确

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

这比static_cast更好,但这项检查只会在运行时完成,编译过程中遇到的问题越多越好。

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

答案 1 :(得分:3)

由于table->model()返回QAbstractItemModel,而QAbstractItemModel没有appendRow函数,您在exerciseModel中声明了QAbstractItemModel,这是{{1}的子类}}。编译器无法知道table存储的实际类型。

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

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