PDA

View Full Version : How to add table headers via delegate with rectangle?



4k
30th April 2021, 11:57
I have a TableView




import QtQuick 2.12
import QtQuick.Controls 2.12

import credentials 1.0

TableView {
id: credentialsTableView
property alias credentialsTableView: credentialsTableView
anchors.fill: parent
columnSpacing: 2
rowSpacing: 2
clip: true

model: SqlCredentialsModel{}
delegate: Rectangle {
color: "lightblue"
implicitWidth: lbl_tableCell.width
implicitHeight: lbl_tableCell.height
Label {
id: lbl_tableCell
text: display
}
}
}




How can I add column headers?

Code is available in https://github.com/hstig/qt/tree/addTableViewViaReadingSqliteCredentials

Thanks

4k
3rd May 2021, 07:56
More description to help understand the case.

I want to populate a tableview with user data stored inside a SQLite DB. In the main.c I connect to DB and register the CredentialsModel as a Type:



#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardPaths>
#include <QSqlDatabase>
#include <QSqlError>
#include <QtQml>

#include "sqlcredentialsmodel.h"

static void connectToDatabase()
{
QSqlDatabase database = QSqlDatabase::database();
if (!database.isValid()) {
database = QSqlDatabase::addDatabase("QSQLITE");
if (!database.isValid())
qFatal("Cannot add database: %s", qPrintable(database.lastError().text()));
}

const QDir writeDir = QStandardPaths::writableLocation(QStandardPaths::A ppDataLocation);
if (!writeDir.mkpath("."))
qFatal("Failed to create writable directory at %s", qPrintable(writeDir.absolutePath()));

// Ensure that we have a writable location on all devices.
const QString fileName = writeDir.absolutePath() + "/chat-database.sqlite3";
qDebug()<< "file: "<<fileName;
// When using the SQLite driver, open() will create the SQLite database if it doesn't exist.
database.setDatabaseName(fileName);
if (!database.open()) {
qFatal("Cannot open database: %s", qPrintable(database.lastError().text()));
QFile::remove(fileName);
}
}

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDp iScaling);

QGuiApplication app(argc, argv);

connectToDatabase();

QQmlApplicationEngine engine;
qmlRegisterType<SqlCredentialsModel>("credentials", 1, 0, "SqlCredentialsModel");

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();
}



The model is implemented as following:

sqlcredentialsmodel.h



#ifndef SQLCREDENTIALSMODEL_H
#define SQLCREDENTIALSMODEL_H

#include <QSqlQueryModel>

class SqlCredentialsModel : public QSqlQueryModel
{
public:
SqlCredentialsModel(QObject *parent = 0);
};

#endif // SQLCREDENTIALSMODEL_H





sqlcredentialsmodel.cpp



#include "sqlcredentialsmodel.h"

#include <QDebug>
#include <QSqlError>
#include <QSqlQuery>

static void createTable()
{
for (auto table: QSqlDatabase::database().tables()){
qDebug()<<"table "<<table;
}

if (QSqlDatabase::database().tables().contains(QStrin gLiteral("Credentials"))) {
// The table already exists; we don't need to do anything.
return;
}

QSqlQuery query;
if (!query.exec(
"CREATE TABLE IF NOT EXISTS 'Credentials' ("
" 'username', 'password' TEXT NOT NULL,"
" PRIMARY KEY(username)"
")")) {
qFatal("Failed to query database: %s", qPrintable(query.lastError().text()));
}

query.exec("INSERT INTO Credentials VALUES('bert', 'b&c' )");
query.exec("INSERT INTO Credentials VALUES('emmy', 'e&c' )");
query.exec("INSERT INTO Credentials VALUES('hans', 'h&c' )");
}

SqlCredentialsModel::SqlCredentialsModel(QObject *parent) :
QSqlQueryModel(parent)
{
createTable();

QSqlQuery query;

if (!query.exec("SELECT * FROM Credentials"))
qFatal("Contacts SELECT query failed: %s", qPrintable(query.lastError().text()));

setQuery(query);
if (lastError().isValid())
qFatal("Cannot set query on SqlCredentialsModel: %s", qPrintable(lastError().text()));
}



QML is implemented as following:

main.qml




import QtQuick 2.12
import QtQuick.Controls 2.5

ApplicationWindow {
visible: true
width: 100
height: 120
title: qsTr("Credentials")

SwipeView {
id: swipeView
anchors.fill: parent

CredentialsView{
id: credentialsView
}
}
}





CredentialsView.ui.qml


import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3

import credentials 1.0

Page {
id: page_Credentials
header: Label {
text: qsTr("Credentials")
font.pixelSize: Qt.application.font.pixelSize
padding: 10
}

CredentialsTableView{
anchors.fill: parent
}

}



CredentialsTableView.ui.qml


import QtQuick 2.12
import QtQuick.Controls 2.12

import credentials 1.0

TableView {
id: credentialsTableView
property alias credentialsTableView: credentialsTableView
anchors.fill: parent
columnSpacing: 2
rowSpacing: 2
clip: true

model: SqlCredentialsModel{}
delegate: Rectangle {
color: "lightblue"
implicitWidth: lbl_tableCell.width
implicitHeight: lbl_tableCell.height
Label {
id: lbl_tableCell
text: display
}
}
}


Thanks in advance

4k
5th May 2021, 15:36
This adds the missing headers

CredentialsView.ui.qml



import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3

import credentials 1.0

Page {
id: page_Credentials
header: Label {
text: qsTr("Credentials")
font.pixelSize: Qt.application.font.pixelSize
padding: 10
}

ColumnLayout{
RowLayout{
Rectangle{
color: "lightgray"

implicitWidth: page_Credentials.width/2
implicitHeight: lbl_cell_user.implicitHeight
Label{
id: lbl_cell_user
text: "user"
anchors.centerIn: parent
}
}
Rectangle{
color: "lightgray"

implicitWidth: page_Credentials.width/2
implicitHeight: lbl_cell_password.height
Label{
id: lbl_cell_password
text: "pass"
anchors.centerIn: parent
}
}
}
RowLayout{
CredentialsTableView{
model: SqlCredentialsModel{}

implicitWidth: page_Credentials.width
implicitHeight: page_Credentials.height
}
}
}
}



CredentialsTableView.ui.qml



import QtQuick 2.12
import QtQuick.Controls 2.12

import credentials 1.0

TableView {
id: dbTableView
columnSpacing: 5
rowSpacing: 1
clip: true

delegate: Rectangle{
implicitWidth: dbTableView.width/2;
implicitHeight: lb_cell.height;
color: "lightblue"
Label {
id: lb_cell
text: display
anchors.centerIn: parent
}
}
}




main.qml



import QtQuick 2.12
import QtQuick.Controls 2.5

ApplicationWindow {
visible: true
width: 100
height: 120
title: qsTr("Credentials")

SwipeView {
id: swipeView

CredentialsView{
id: credentialsView
}
}
}



Code is available in https://github.com/hstig/qt/tree/add...iteCredentials

How to get rid of following binding loops?
qrc:/main.qml:13:9: QML Page: Binding loop detected for property "implicitWidth"
qrc:/main.qml:13:9: QML Page: Binding loop detected for property "implicitWidth"
qrc:/main.qml:13:9: QML Page: Binding loop detected for property "implicitHeight"
qrc:/main.qml:13:9: QML Page: Binding loop detected for property "implicitWidth"
qrc:/main.qml:13:9: QML Page: Binding loop detected for property "implicitWidth"
qrc:/main.qml:13:9: QML Page: Binding loop detected for property "implicitHeight"