QSqlQueryModel TableView custom delegate

415 views Asked by At

I have a QSqlQueryModel and a TableView to display the data from the model. The code and output data results are fine. But, I just want to display an image in front of each row in the TableView. However, with my current QML code, the image is repeated along with the elements in my table columns. I have added example screenshots for reference

Current Output (Screenshot)

enter image description here

What I want

enter image description here

My Code is as below

Test.qml

import QtQuick 2.12
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3

Page {

    id : somepageid

    TableView{
        id: testTable
        model: QueryModel
        height: 500
        width: 400
        delegate:
            Row{

            Image {
                id: statusImg
                height: 18
                width: 18
                source: "../../../Images/icons/tick.png"
            }

            Text {
                text: display
            }
        }
    }

}

QueryModel.cpp

#include "querymodel.h"


QueryModel::QueryModel(QObject *parent): QSqlQueryModel(parent)
{

}

void QueryModel::setQuery(const QString &query, const QSqlDatabase &db)
{
    QSqlQueryModel::setQuery(query, db);
    generateRoleNames();
}

void QueryModel::setQuery(const QSqlQuery &query)
{
    QSqlQueryModel::setQuery(query);
    generateRoleNames();
}

QVariant QueryModel::data(const QModelIndex &index, int role) const
{
    QVariant value;

    if(role < Qt::UserRole) {
        value = QSqlQueryModel::data(index, role);
    }
    else {
        int columnIdx = role - Qt::UserRole - 1;
        QModelIndex modelIndex = this->index(index.row(), columnIdx);
        value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
    }
    return value;
}

QHash<int, QByteArray> QueryModel::roleNames() const
{
    return {{Qt::DisplayRole, "display"}};
}

void QueryModel::callSql()
{
    QSqlDatabase dbMysql = QSqlDatabase::database();
    this->setQuery(this->tmpSql(), dbMysql);
}

QString QueryModel::tmpSql() const
{
    return m_tmpSql;
}

void QueryModel::setTmpSql(QString tmpSql)
{
    if (m_tmpSql == tmpSql)
        return;

    m_tmpSql = tmpSql;
    emit tmpSqlChanged(m_tmpSql);
}

void QueryModel::generateRoleNames()
{
    m_roleNames.clear();
    for( int i = 0; i < record().count(); i ++) {
        m_roleNames.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
    }
}
1

There are 1 answers

0
eyllanesc On BEST ANSWER

A possible solution is to use a Loader:

// ...
delegate: Row{
    Loader{
        active: model.column === 0
        sourceComponent: Image {
            id: statusImg
            height: 18
            width: 18
            source: "../../../Images/icons/tick.png"
        }
    }
    Text {
        text: model.display
    }
}
// ...