I am trying to get the Qt model/view-architecture working with a QML-View, but for whatever reason it is only partially working.
What works:
- rowCount
- data
- roleNames
Not working:
- columnCount (the method is called, but seems to have no effect, as long is it is > 0)
- headerData (is this actually supposed to set the column headers? All examples set the headers in QML)
- flags
- setData
What I am trying to do (for some weeks already), is to create a simple ApplicationView with a TableView and a C++-model, which is editable by the view.
Right now only a whole row is selectable, not a single cell. The table data doesn't seem to be editable at all. Can anyone give me a hint?
main.qml
import QtQuick 2.3
import QtQuick.Controls 1.2
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TableView {
model: theModel
TableViewColumn {
role: "nameRole"
width: 75
}
TableViewColumn {
role: "ageRole"
width: 50
}
}
}
ModelItem.hpp
#ifndef MODELITEM
#define MODELITEM
#include <QString>
struct ModelItem {
ModelItem(QString name_, int age_)
: name(name_), age(age_) {}
QString name;
int age;
};
#endif // MODELITEM
TableModel.hpp
#ifndef TABLEMODEL_HPP
#define TABLEMODEL_HPP
#include <QAbstractTableModel>
#include "ModelItem.hpp"
class TableModel : public QAbstractTableModel
{
Q_OBJECT
public:
TableModel(QObject *parent = 0);
//works
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
//does not work
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QHash<int, QByteArray> roleNames() const;
enum Roles {
NameRole = Qt::UserRole + 1,
AgeRole
};
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
private:
QList<ModelItem*> items;
};
#endif // TABLEMODEL_HPP
TableModel.cpp
#include "TableModel.hpp"
TableModel::TableModel(QObject *parent)
: QAbstractTableModel(parent) {
items.append(new ModelItem("Hugo",33));
items.append(new ModelItem("Egon",34));
items.append(new ModelItem("Balder",66));
qDebug("TableModel initialisiert");
}
int TableModel::columnCount(const QModelIndex &parent) const {
Q_UNUSED(parent);
qDebug("columnCount");
return 2;
}
int TableModel::rowCount(const QModelIndex &parent) const {
Q_UNUSED(parent);
qDebug("rowCount");
return items.count();
}
QVariant TableModel::data(const QModelIndex &index, int role) const {
qDebug("data");
switch (role) {
case NameRole: return items[index.row()]->name;
case AgeRole: return items[index.row()]->age;
}
}
QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const {
qDebug("headerData");
switch (role) {
case NameRole: return "1";
case AgeRole: return "2";
};
return QVariant();
}
QHash<int, QByteArray> TableModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[NameRole] = "nameRole";
roles[AgeRole] = "ageRole";
qDebug("roleNames initialised");
return roles;
}
Qt::ItemFlags TableModel::flags(const QModelIndex &index) const {
qDebug("--flags called--");
return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}
bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
qDebug("setData called");
switch (role) {
case NameRole: items[index.row()]->name = value.toString();
case AgeRole: items[index.row()]->age = value.toInt();
}
emit dataChanged(index, index);
return true;
}
main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "TableModel.hpp"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
TableModel model;
engine.rootContext()->setContextProperty("theModel", &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}