Hey all,
I'm trying to connect a TableView in QtQuick Controls with a QAbstractTableModel in C++. The tableview correctly displays the model data, but I cannot figure out how to update the model data from the tableview. I've made a simple example in QML/C++ to illustrate my problem. There are 3 roles in the model, and a checkbox, a button, and a textfield in the tableview. I'd like to be able to write the checkbox state and the textfield text to the model. The model should be updated where the "*** Save X to model here! ***" comments are. Does any know how to do this?
/* main.qml */
import QtQuick 2.2
import QtQuick.Controls 1.1
ApplicationWindow {
id: applicationWindow1
visible: true
width: 640
height: 480
title: qsTr("Hello World")
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
TableView {
id: metadataTaskTable
anchors.fill: parent
alternatingRowColors: false
model: theModel
// Row Delegate
rowDelegate: Item {
height: 20 + 15
Rectangle {
anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
height: parent.height
color: styleData.selected ? 'lightblue' : 'white'
}
}
// Column 0
TableViewColumn {
role: "role_enable";
width: 25;
resizable: false;
delegate:
CheckBox {
id: checkBoxDelegate
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 5
checked: styleData.value
onCheckedChanged: {
// *** Save check state to model here! ***
// Print Model
theModel.print_rows()
}
}
}
// Column 1
TableViewColumn {
role: "role_m_one";
width: 70
delegate:
Button {
anchors.verticalCenter: parent.verticalCenter
text: "Click Me!"
width: parent.width
onClicked: {
console.log(styleData.value)
}
}
}
// Column 2
TableViewColumn {
title: "Some Text";
role: "role_m_two";
width: 70
delegate:
TextField {
anchors.fill: parent
text: styleData.value
onTextChanged: {
// *** Save text to model here! ***
// Print Model
theModel.print_rows()
}
}
}
}
}
import QtQuick 2.2
import QtQuick.Controls 1.1
ApplicationWindow {
id: applicationWindow1
visible: true
width: 640
height: 480
title: qsTr("Hello World")
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
TableView {
id: metadataTaskTable
anchors.fill: parent
alternatingRowColors: false
model: theModel
// Row Delegate
rowDelegate: Item {
height: 20 + 15
Rectangle {
anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
height: parent.height
color: styleData.selected ? 'lightblue' : 'white'
}
}
// Column 0
TableViewColumn {
role: "role_enable";
width: 25;
resizable: false;
delegate:
CheckBox {
id: checkBoxDelegate
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 5
checked: styleData.value
onCheckedChanged: {
// *** Save check state to model here! ***
// Print Model
theModel.print_rows()
}
}
}
// Column 1
TableViewColumn {
role: "role_m_one";
width: 70
delegate:
Button {
anchors.verticalCenter: parent.verticalCenter
text: "Click Me!"
width: parent.width
onClicked: {
console.log(styleData.value)
}
}
}
// Column 2
TableViewColumn {
title: "Some Text";
role: "role_m_two";
width: 70
delegate:
TextField {
anchors.fill: parent
text: styleData.value
onTextChanged: {
// *** Save text to model here! ***
// Print Model
theModel.print_rows()
}
}
}
}
}
To copy to clipboard, switch view to plain text mode
/* mymodel.h */
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QAbstractTableModel>
#include <QDebug>
struct SimpleData {
bool enable;
SimpleData() {
enable = true;
m_one = "1";
m_two = "2";
}
enable(enable), m_one(m_one), m_two(m_two) {}
};
{
Q_OBJECT
public:
explicit MyModel
(QObject *parent
= 0);
QHash<int, QByteArray> roleNames() const;
QList<SimpleData*> m_data_list;
enum MyRoles {
RoleOne = Qt::UserRole + 1,
RoleTwo,
RoleThree
};
signals:
public slots:
void print_rows();
};
#endif // MYMODEL_H
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QAbstractTableModel>
#include <QDebug>
struct SimpleData {
bool enable;
QString m_one;
QString m_two;
SimpleData() {
enable = true;
m_one = "1";
m_two = "2";
}
SimpleData(bool enable, const QString m_one, const QString m_two) :
enable(enable), m_one(m_one), m_two(m_two) {}
};
class MyModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit MyModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const ;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
bool setData(const QModelIndex & index, const QVariant &value, int role = Qt::EditRole);
QHash<int, QByteArray> roleNames() const;
QList<SimpleData*> m_data_list;
enum MyRoles {
RoleOne = Qt::UserRole + 1,
RoleTwo,
RoleThree
};
signals:
public slots:
void print_rows();
};
#endif // MYMODEL_H
To copy to clipboard, switch view to plain text mode
/* mymodel.cpp */
#include "mymodel.h"
SimpleData *m_simpledata;
// Create junk model data
m_simpledata = new SimpleData(true, "a1", "b1");
m_data_list.append(m_simpledata);
m_simpledata = new SimpleData(false, "a2", "b2");
m_data_list.append(m_simpledata);
}
int MyModel
::rowCount(const QModelIndex & /*parent*/) const { return m_data_list.length();
}
int MyModel
::columnCount(const QModelIndex & /*parent*/) const { return 3;
}
switch(role)
{
case RoleOne:
return m_data_list.at(index.row())->enable;
case RoleTwo:
return m_data_list.at(index.row())->m_one;
case RoleThree:
return m_data_list.at(index.row())->m_two;
}
}
qDebug() << "setData() called with:" << value;
switch(role)
{
case RoleOne:
m_data_list[index.row()]->enable = value.toBool();
case RoleTwo:
m_data_list[index.row()]->m_one = value.toString();
case RoleThree:
m_data_list[index.row()]->m_two = value.toString();
}
return true;
}
QHash<int, QByteArray> MyModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[RoleOne] = "role_enable";
roles[RoleTwo] = "role_m_one";
roles[RoleThree] = "role_m_two";
return roles;
}
void MyModel::print_rows() {
qDebug() << "Model Data:";
for (int i=0; i < m_data_list.length(); i++) {
qDebug() << "At" << i << ":" << m_data_list.at(i)->enable << m_data_list.at(i)->m_one << m_data_list.at(i)->m_two;
}
}
#include "mymodel.h"
MyModel::MyModel(QObject *parent) : QAbstractTableModel(parent) {
SimpleData *m_simpledata;
// Create junk model data
m_simpledata = new SimpleData(true, "a1", "b1");
m_data_list.append(m_simpledata);
m_simpledata = new SimpleData(false, "a2", "b2");
m_data_list.append(m_simpledata);
}
int MyModel::rowCount(const QModelIndex & /*parent*/) const {
return m_data_list.length();
}
int MyModel::columnCount(const QModelIndex & /*parent*/) const {
return 3;
}
QVariant MyModel::data(const QModelIndex &index, int role) const {
switch(role)
{
case RoleOne:
return m_data_list.at(index.row())->enable;
case RoleTwo:
return m_data_list.at(index.row())->m_one;
case RoleThree:
return m_data_list.at(index.row())->m_two;
}
return QVariant();
}
bool MyModel::setData(const QModelIndex & index, const QVariant & value, int role) {
qDebug() << "setData() called with:" << value;
switch(role)
{
case RoleOne:
m_data_list[index.row()]->enable = value.toBool();
case RoleTwo:
m_data_list[index.row()]->m_one = value.toString();
case RoleThree:
m_data_list[index.row()]->m_two = value.toString();
}
return true;
}
QHash<int, QByteArray> MyModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[RoleOne] = "role_enable";
roles[RoleTwo] = "role_m_one";
roles[RoleThree] = "role_m_two";
return roles;
}
void MyModel::print_rows() {
qDebug() << "Model Data:";
for (int i=0; i < m_data_list.length(); i++) {
qDebug() << "At" << i << ":" << m_data_list.at(i)->enable << m_data_list.at(i)->m_one << m_data_list.at(i)->m_two;
}
}
To copy to clipboard, switch view to plain text mode
/* main.cpp */
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "mymodel.h"
int main(int argc, char *argv[])
{
QQmlApplicationEngine engine;
MyModel model;
engine.rootContext()->setContextProperty("theModel", &model);
engine.
load(QUrl(QStringLiteral
("qrc:///main.qml")));
return app.exec();
}
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "mymodel.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
MyModel model;
engine.rootContext()->setContextProperty("theModel", &model);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
To copy to clipboard, switch view to plain text mode
Thanks!
Bookmarks