Reputation: 326
I've searched a lot on the net but I didn't find an answer and that's something really strange since I suppose it's a basic functionality most people should use (probably I don't understand how to correctly use TableView with QtQuick.Controls 2).
Tha problem is: I would like to know on which row I clicked and I want to access data of a particular column of that row (something like TableView.get(row, column)). In QtQuick.Controls 1.4 there are functions that allow me to access the rows (like this one) but I cannot find any for QtQuick.Control 2. Also there aren't the selection: and itemDelegate: that would be useful. How can implement these things in QtQuick.Controls 2?
I am using Qt 5.15.0 with MinGw. I have datas from a database that are passed to QML with QAbstractTableModel.
.cpp model
#include "archiviosqlmodel.h"
#include <QSqlRecord>
#include <QSqlError>
#include <QSqlQuery>
#include <QDebug>
ArchivioSqlModel::ArchivioSqlModel(QObject *parent) :
QAbstractTableModel(parent)
{
db_4= QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), "def.db");
db_4.setDatabaseName("def.db");
if (!db_4.isOpen())
db_4.open();
QSqlQuery query(db_4);
query.exec("CREATE TABLE IF NOT EXISTS A (ID INTEGER PRIMARY KEY AUTOINCREMENT, B INTEGER, C CHAR(5), D CHAR(5), E CHAR(5));");
query.exec("INSERT INTO A (ID, B, C, D, E) VALUES (1, 2, 'AAAAA', 'BBBBB', 'CCCCC')");
query.exec("INSERT INTO A (ID, B, C, D, E) VALUES (2, 4, 'DDDDD', 'FFFFF', 'QQQQQ')");
query.exec("INSERT INTO A (ID, B, C, D, E) VALUES (3, 5, 'EEEEE', 'GGGGG', 'HHHHH')");
model.setQuery("SELECT * FROM A", db_4);
qDebug() << "Row Count " << model.rowCount() << "Column count " << model.columnCount();
}
ArchivioSqlModel::~ArchivioSqlModel()
{
db_4.close();
}
QVariant ArchivioSqlModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role == Qt::DisplayRole)
{
if(orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
return tr("ID");
case 1:
return tr("A");
case 2:
return tr("A");
case 3:
return tr("A");
case 4:
return tr("A");
}
}
}
return QVariant();
}
int ArchivioSqlModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return model.rowCount();
}
int ArchivioSqlModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return model.columnCount();
}
QVariant ArchivioSqlModel::data(const QModelIndex &index, int role) const
{
QVariant value;
if (!index.isValid())
return QVariant();
if(role == Qt::DisplayRole && index.row() >= 0 && index.row() < rowCount()
&& index.column() >= 0 && index.column() < columnCount())
{
QModelIndex modelIndex = this->index(index.row(), index.column());
value = model.data(modelIndex, Qt::DisplayRole);
return value;//QString("data %1-%2").arg(index.row()).arg(index.column());
}
return QVariant();
}
.h model
#include <QSqlQueryModel>
class ArchivioSqlModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit ArchivioSqlModel(QObject *parent = 0);
Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
~ArchivioSqlModel() override;
signals:
void queryStrChanged();
public slots:
private:
const static char* COLUMN_NAMES[];
const static char* SQL_SELECT;
QSqlDatabase db_4;
QSqlQueryModel model;
QHash<int, QByteArray> m_roleNames;
};
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.4
import Archive 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle {
id: rectangle
x: 62
y: 106
width: 200
height: 200
color: "#000022"
border.width: 0
anchors.fill:parent
Rectangle {
id: rectangleBack
x: 10
y: 406
width: 64
height: 64
color: "#000033"
radius: 20
anchors.left: parent.left
anchors.leftMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
border.width: 2
border.color: "#ffffff"
MouseArea {
id: mouseAreaBack
anchors.fill: parent
onClicked: {
if (stackView.depth > 1)
stackView.pop()
}
onPressed: {
rectangleBack.width = 64 - 4
rectangleBack.height = 64 - 4
}
onReleased: {
rectangleBack.width = 64
rectangleBack.height = 64
}
}
}
Text {
id: textArchive
height: 25
color: "#ffffff"
text: qsTr("Datas:")
font.family: "Arial"
verticalAlignment: Text.AlignVCenter
font.bold: true
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
anchors.top: parent.top
anchors.topMargin: 10
font.pixelSize: 14
}
ArchivioSqlModel {
id: archiviomodel
}
Rectangle {
id: rectangle1
color: "#000022"
radius: 10
border.width: 2
border.color: "#ffffff"
anchors.right: parent.right
anchors.rightMargin: 5
anchors.left: parent.left
anchors.leftMargin: 5
anchors.bottom: rectangleBack.top
anchors.bottomMargin: 10
anchors.top: textArchive.bottom
anchors.topMargin: 10
TableView {
id: tableViewid
anchors.leftMargin: 5
anchors.bottomMargin: 5
anchors.rightMargin: 5
anchors.topMargin: 5
columnWidthProvider: function (column) { return 100; }
rowHeightProvider: function (column) { return 60; }
anchors.fill: parent
topMargin: columnsHeader.implicitHeight
model: archiviomodel
ScrollBar.horizontal: ScrollBar{}
ScrollBar.vertical: ScrollBar{}
clip: true
delegate: Rectangle {
Text {
id: textId
text: display
anchors.fill: parent
anchors.margins: 10
color: 'black'
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("prova:" + textId.text)
}
}
}
Rectangle { // mask the headers
z: 3
color: "#000033"
y: tableViewid.contentY
x: tableViewid.contentX
width: tableViewid.leftMargin
height: tableViewid.topMargin
}
Row {
id: columnsHeader
y: tableViewid.contentY
z: 2
Repeater {
model: tableViewid.columns > 0 ? tableViewid.columns : 1
Label {
width: tableViewid.columnWidthProvider(modelData)
height: 35
text: archiviomodel.headerData(modelData, Qt.Horizontal)
color: '#ffffff'
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter
background: Rectangle {
radius: 10
color: "#000022"
}
}
}
}
ScrollIndicator.horizontal: ScrollIndicator { }
ScrollIndicator.vertical: ScrollIndicator { }
}
}
Rectangle {
id: rectangleOpenlap
x: 10
y: 406
width: 64
height: 64
color: "#000033"
radius: 20
anchors.right: parent.right
anchors.rightMargin: 10
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
border.width: 2
border.color: "#ffffff"
MouseArea {
id: mouseAreaOpenlap
anchors.fill: parent
onClicked: {
console.log("Rows")
}
onPressed: {
rectangleOpenlap.width = 64 - 4
rectangleOpenlap.height = 64 - 4
}
onReleased: {
rectangleOpenlap.width = 64
rectangleOpenlap.height = 64
}
}
}
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "archiviosqlmodel.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<ArchivioSqlModel>("Archive", 1, 0, "ArchivioSqlModel");
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
Thanks in advance!
Upvotes: 3
Views: 2263
Reputation: 24416
To access data from the model, you can use the model context property and the built-in display role:
MouseArea {
anchors.fill: parent
onClicked: {
console.log(model.display)
}
}
Model data can be set in a similar way.
The above is basically a shorter way of the following:
MouseArea {
anchors.fill: parent
onClicked: {
console.log(row, column, tableViewid.model.data(tableViewid.model.index(row, column)))
}
}
The code above uses index() to create an index that can then be passed to data()
The row and column properties are provided to each delegate.
This is also useful if you need to get data from the model from outside the delegate, for whatever reason.
Upvotes: 4