我对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;
}
答案 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");