how to display the data contents in TableModel
-
Hi all, I have been struggling in this tablemodel for almost a week.
here's my .cpp file#include "tablemodel.h" #include "qsqlrecord.h" #include <QSqlQueryModel> #include <QSqlQuery> #include <QDebug> QString uin_number; TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) { qDebug()<<"constructor----->"; QSqlQuery query1("USE Name"); QSqlQuery query2("SELECT * FROM Record"); int nameNo = query2.record().indexOf("Name"); int ageNo = query2.record().indexOf("Age"); int sexNo = query2.record().indexOf("Sex"); int countryNo = query2.record().indexOf("Country"); while (query2.next()) { QString name = query2.value(nameNo).toString(); QString age = query2.value(ageNo).toString(); QString sex = query2.value(sexNo).toString(); QString country = query2.value(countryNo).toString(); namelist.append(name); agelist.append(age); sexlist.append(sex); countrylist.append(country); qDebug()<<"constructor end----->"; } } int TableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return namelist.count(); qDebug()<<"rowCount----->"; } int TableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 4; qDebug()<<"columnCount----->"; } QVariant TableModel::data(const QModelIndex & index, int role) const { qDebug()<<"data enter----->"; if (index.row() < 0 || index.row() >= namelist.count()) return QVariant(); else if (role== NameRole){ return namelist[index.row()]; //.isEnabled(); } else if (role== AgeRole){ return agelist[index.row()]; } else if (role== SexRole){ return sexlist[index.row()]; } else if (role== countryRole){ return countrylist[index.row()]; } else { return QVariant(); } qDebug()<<"data exit----->"; } QHash<int, QByteArray> TableModel::roleNames() const { qDebug()<<"roleNames----->"; QHash<int, QByteArray> roles; roles[CheckBoxRole] = "checkbox"; roles[NameRole] = "name"; roles[AgeRole] = "age"; roles[SexRole] = "sex"; roles[CountryRole] = "country"; return roles; qDebug()<<"roleNames exit ----->"; }
and here's my .h file
#ifndef TABLEMODEL_H #define TABLEMODEL_H #include <QObject> #include <QAbstractTableModel> class TableModel : public QAbstractTableModel { Q_OBJECT public: enum Roles { CheckBoxRole = Qt::UserRole + 1, nameRole, ageRole, sexRole, countryRole, }; explicit TableModel(QObject *parent = 0); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex & parent = QModelIndex()) const; Q_INVOKABLE QVariant data (const QModelIndex & index, int role) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<QString> namelist; QList<QString> agelist; QList<QString> sexlist; QList<QString> countrylist; QHash<int, QByteArray> m_roleNames; }; #endif // TABLEMODEL_H
.qml file
import QtQuick 2.15 import QtQuick.Window 2.15 import Qt.labs.qmlmodels 1.0 import QtQuick.Controls 1.5 import QtQuick.Controls 2.12 import TableModel 1.0 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") TableModel{ id: display_model } TableView { id: table anchors.fill: parent model: display_model //TableModel TableViewColumn { role: "checkbox" delegate: CheckBox { id: delegate_checkbox } } TableViewColumn { title: "Name" role: "name" } TableViewColumn{ title: "Name" role: "age" } TableViewColumn{ title: "Name" role: "sex" } TableViewColumn{ title: "Name" role: "country" } } }
It works and displays fine in the tablemodel if i give the query in constructor in .cpp file. But when i created a new function(callsql) and write those query from constructor to the new function(callsql), it does not display the contents. like this...
changed .cpp file
#include "tablemodel.h" #include "qsqlrecord.h" #include <QSqlQueryModel> #include <QSqlQuery> #include <QDebug> QString uin_number; TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) { } int TableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return namelist.count(); qDebug()<<"rowCount----->"; } int TableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 4; qDebug()<<"columnCount----->"; } QVariant TableModel::data(const QModelIndex & index, int role) const { qDebug()<<"data enter----->"; if (index.row() < 0 || index.row() >= namelist.count()) return QVariant(); else if (role== NameRole){ return namelist[index.row()]; //.isEnabled(); } else if (role== AgeRole){ return agelist[index.row()]; } else if (role== SexRole){ return sexlist[index.row()]; } else if (role== countryRole){ return countrylist[index.row()]; } else { return QVariant(); } qDebug()<<"data exit----->"; } void TableModel::callsql(QString querystring, QString querystring1) { QSqlQuery query1(querystring) QSqlQuery query2(querystring1); int nameNo = query2.record().indexOf("Name"); int ageNo = query2.record().indexOf("Age"); int sexNo = query2.record().indexOf("Sex"); int countryNo = query2.record().indexOf("Country"); while (query2.next()) { QString name = query2.value(nameNo).toString(); QString age = query2.value(ageNo).toString(); QString sex = query2.value(sexNo).toString(); QString country = query2.value(countryNo).toString(); namelist.append(name); agelist.append(age); sexlist.append(sex); countrylist.append(country); qDebug()<<"constructor end----->"; } } QHash<int, QByteArray> TableModel::roleNames() const { qDebug()<<"roleNames----->"; QHash<int, QByteArray> roles; roles[CheckBoxRole] = "checkbox"; roles[NameRole] = "name"; roles[AgeRole] = "age"; roles[SexRole] = "sex"; roles[CountryRole] = "country"; return roles; qDebug()<<"roleNames exit ----->"; }
and also added the component.onCompleted in .qml file after the TableModel
Component.onCompleted: { display_model.callsql("Use Name","select * from Record") }
I don't know what is the exact reason why it does not show anything. is there anything i missed, or did i do anything wrong? I would appreciate the hlep or suggestions.
Regards. -
Hi all, I have been struggling in this tablemodel for almost a week.
here's my .cpp file#include "tablemodel.h" #include "qsqlrecord.h" #include <QSqlQueryModel> #include <QSqlQuery> #include <QDebug> QString uin_number; TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) { qDebug()<<"constructor----->"; QSqlQuery query1("USE Name"); QSqlQuery query2("SELECT * FROM Record"); int nameNo = query2.record().indexOf("Name"); int ageNo = query2.record().indexOf("Age"); int sexNo = query2.record().indexOf("Sex"); int countryNo = query2.record().indexOf("Country"); while (query2.next()) { QString name = query2.value(nameNo).toString(); QString age = query2.value(ageNo).toString(); QString sex = query2.value(sexNo).toString(); QString country = query2.value(countryNo).toString(); namelist.append(name); agelist.append(age); sexlist.append(sex); countrylist.append(country); qDebug()<<"constructor end----->"; } } int TableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return namelist.count(); qDebug()<<"rowCount----->"; } int TableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 4; qDebug()<<"columnCount----->"; } QVariant TableModel::data(const QModelIndex & index, int role) const { qDebug()<<"data enter----->"; if (index.row() < 0 || index.row() >= namelist.count()) return QVariant(); else if (role== NameRole){ return namelist[index.row()]; //.isEnabled(); } else if (role== AgeRole){ return agelist[index.row()]; } else if (role== SexRole){ return sexlist[index.row()]; } else if (role== countryRole){ return countrylist[index.row()]; } else { return QVariant(); } qDebug()<<"data exit----->"; } QHash<int, QByteArray> TableModel::roleNames() const { qDebug()<<"roleNames----->"; QHash<int, QByteArray> roles; roles[CheckBoxRole] = "checkbox"; roles[NameRole] = "name"; roles[AgeRole] = "age"; roles[SexRole] = "sex"; roles[CountryRole] = "country"; return roles; qDebug()<<"roleNames exit ----->"; }
and here's my .h file
#ifndef TABLEMODEL_H #define TABLEMODEL_H #include <QObject> #include <QAbstractTableModel> class TableModel : public QAbstractTableModel { Q_OBJECT public: enum Roles { CheckBoxRole = Qt::UserRole + 1, nameRole, ageRole, sexRole, countryRole, }; explicit TableModel(QObject *parent = 0); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex & parent = QModelIndex()) const; Q_INVOKABLE QVariant data (const QModelIndex & index, int role) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<QString> namelist; QList<QString> agelist; QList<QString> sexlist; QList<QString> countrylist; QHash<int, QByteArray> m_roleNames; }; #endif // TABLEMODEL_H
.qml file
import QtQuick 2.15 import QtQuick.Window 2.15 import Qt.labs.qmlmodels 1.0 import QtQuick.Controls 1.5 import QtQuick.Controls 2.12 import TableModel 1.0 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") TableModel{ id: display_model } TableView { id: table anchors.fill: parent model: display_model //TableModel TableViewColumn { role: "checkbox" delegate: CheckBox { id: delegate_checkbox } } TableViewColumn { title: "Name" role: "name" } TableViewColumn{ title: "Name" role: "age" } TableViewColumn{ title: "Name" role: "sex" } TableViewColumn{ title: "Name" role: "country" } } }
It works and displays fine in the tablemodel if i give the query in constructor in .cpp file. But when i created a new function(callsql) and write those query from constructor to the new function(callsql), it does not display the contents. like this...
changed .cpp file
#include "tablemodel.h" #include "qsqlrecord.h" #include <QSqlQueryModel> #include <QSqlQuery> #include <QDebug> QString uin_number; TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) { } int TableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return namelist.count(); qDebug()<<"rowCount----->"; } int TableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 4; qDebug()<<"columnCount----->"; } QVariant TableModel::data(const QModelIndex & index, int role) const { qDebug()<<"data enter----->"; if (index.row() < 0 || index.row() >= namelist.count()) return QVariant(); else if (role== NameRole){ return namelist[index.row()]; //.isEnabled(); } else if (role== AgeRole){ return agelist[index.row()]; } else if (role== SexRole){ return sexlist[index.row()]; } else if (role== countryRole){ return countrylist[index.row()]; } else { return QVariant(); } qDebug()<<"data exit----->"; } void TableModel::callsql(QString querystring, QString querystring1) { QSqlQuery query1(querystring) QSqlQuery query2(querystring1); int nameNo = query2.record().indexOf("Name"); int ageNo = query2.record().indexOf("Age"); int sexNo = query2.record().indexOf("Sex"); int countryNo = query2.record().indexOf("Country"); while (query2.next()) { QString name = query2.value(nameNo).toString(); QString age = query2.value(ageNo).toString(); QString sex = query2.value(sexNo).toString(); QString country = query2.value(countryNo).toString(); namelist.append(name); agelist.append(age); sexlist.append(sex); countrylist.append(country); qDebug()<<"constructor end----->"; } } QHash<int, QByteArray> TableModel::roleNames() const { qDebug()<<"roleNames----->"; QHash<int, QByteArray> roles; roles[CheckBoxRole] = "checkbox"; roles[NameRole] = "name"; roles[AgeRole] = "age"; roles[SexRole] = "sex"; roles[CountryRole] = "country"; return roles; qDebug()<<"roleNames exit ----->"; }
and also added the component.onCompleted in .qml file after the TableModel
Component.onCompleted: { display_model.callsql("Use Name","select * from Record") }
I don't know what is the exact reason why it does not show anything. is there anything i missed, or did i do anything wrong? I would appreciate the hlep or suggestions.
Regards.@postbox If you are using a DB as source, I think it would be much easier using QSqlTableModel as base class of your
TableModel
.Also why replicating the data in the model if they are already stored in the DB ?
Just another comment, how you manage your data here is quite complicated and hard to maintain:
QList<QString> namelist; QList<QString> agelist; QList<QString> sexlist; QList<QString> countrylist;
I would recommend to use only one list of object containing your data. Something like:
struct Data{ QString name; QString age; QString sex; QString country; } # in your model QList<Data> m_data;
-
Hi all, I have been struggling in this tablemodel for almost a week.
here's my .cpp file#include "tablemodel.h" #include "qsqlrecord.h" #include <QSqlQueryModel> #include <QSqlQuery> #include <QDebug> QString uin_number; TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) { qDebug()<<"constructor----->"; QSqlQuery query1("USE Name"); QSqlQuery query2("SELECT * FROM Record"); int nameNo = query2.record().indexOf("Name"); int ageNo = query2.record().indexOf("Age"); int sexNo = query2.record().indexOf("Sex"); int countryNo = query2.record().indexOf("Country"); while (query2.next()) { QString name = query2.value(nameNo).toString(); QString age = query2.value(ageNo).toString(); QString sex = query2.value(sexNo).toString(); QString country = query2.value(countryNo).toString(); namelist.append(name); agelist.append(age); sexlist.append(sex); countrylist.append(country); qDebug()<<"constructor end----->"; } } int TableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return namelist.count(); qDebug()<<"rowCount----->"; } int TableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 4; qDebug()<<"columnCount----->"; } QVariant TableModel::data(const QModelIndex & index, int role) const { qDebug()<<"data enter----->"; if (index.row() < 0 || index.row() >= namelist.count()) return QVariant(); else if (role== NameRole){ return namelist[index.row()]; //.isEnabled(); } else if (role== AgeRole){ return agelist[index.row()]; } else if (role== SexRole){ return sexlist[index.row()]; } else if (role== countryRole){ return countrylist[index.row()]; } else { return QVariant(); } qDebug()<<"data exit----->"; } QHash<int, QByteArray> TableModel::roleNames() const { qDebug()<<"roleNames----->"; QHash<int, QByteArray> roles; roles[CheckBoxRole] = "checkbox"; roles[NameRole] = "name"; roles[AgeRole] = "age"; roles[SexRole] = "sex"; roles[CountryRole] = "country"; return roles; qDebug()<<"roleNames exit ----->"; }
and here's my .h file
#ifndef TABLEMODEL_H #define TABLEMODEL_H #include <QObject> #include <QAbstractTableModel> class TableModel : public QAbstractTableModel { Q_OBJECT public: enum Roles { CheckBoxRole = Qt::UserRole + 1, nameRole, ageRole, sexRole, countryRole, }; explicit TableModel(QObject *parent = 0); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex & parent = QModelIndex()) const; Q_INVOKABLE QVariant data (const QModelIndex & index, int role) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<QString> namelist; QList<QString> agelist; QList<QString> sexlist; QList<QString> countrylist; QHash<int, QByteArray> m_roleNames; }; #endif // TABLEMODEL_H
.qml file
import QtQuick 2.15 import QtQuick.Window 2.15 import Qt.labs.qmlmodels 1.0 import QtQuick.Controls 1.5 import QtQuick.Controls 2.12 import TableModel 1.0 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") TableModel{ id: display_model } TableView { id: table anchors.fill: parent model: display_model //TableModel TableViewColumn { role: "checkbox" delegate: CheckBox { id: delegate_checkbox } } TableViewColumn { title: "Name" role: "name" } TableViewColumn{ title: "Name" role: "age" } TableViewColumn{ title: "Name" role: "sex" } TableViewColumn{ title: "Name" role: "country" } } }
It works and displays fine in the tablemodel if i give the query in constructor in .cpp file. But when i created a new function(callsql) and write those query from constructor to the new function(callsql), it does not display the contents. like this...
changed .cpp file
#include "tablemodel.h" #include "qsqlrecord.h" #include <QSqlQueryModel> #include <QSqlQuery> #include <QDebug> QString uin_number; TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) { } int TableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return namelist.count(); qDebug()<<"rowCount----->"; } int TableModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); return 4; qDebug()<<"columnCount----->"; } QVariant TableModel::data(const QModelIndex & index, int role) const { qDebug()<<"data enter----->"; if (index.row() < 0 || index.row() >= namelist.count()) return QVariant(); else if (role== NameRole){ return namelist[index.row()]; //.isEnabled(); } else if (role== AgeRole){ return agelist[index.row()]; } else if (role== SexRole){ return sexlist[index.row()]; } else if (role== countryRole){ return countrylist[index.row()]; } else { return QVariant(); } qDebug()<<"data exit----->"; } void TableModel::callsql(QString querystring, QString querystring1) { QSqlQuery query1(querystring) QSqlQuery query2(querystring1); int nameNo = query2.record().indexOf("Name"); int ageNo = query2.record().indexOf("Age"); int sexNo = query2.record().indexOf("Sex"); int countryNo = query2.record().indexOf("Country"); while (query2.next()) { QString name = query2.value(nameNo).toString(); QString age = query2.value(ageNo).toString(); QString sex = query2.value(sexNo).toString(); QString country = query2.value(countryNo).toString(); namelist.append(name); agelist.append(age); sexlist.append(sex); countrylist.append(country); qDebug()<<"constructor end----->"; } } QHash<int, QByteArray> TableModel::roleNames() const { qDebug()<<"roleNames----->"; QHash<int, QByteArray> roles; roles[CheckBoxRole] = "checkbox"; roles[NameRole] = "name"; roles[AgeRole] = "age"; roles[SexRole] = "sex"; roles[CountryRole] = "country"; return roles; qDebug()<<"roleNames exit ----->"; }
and also added the component.onCompleted in .qml file after the TableModel
Component.onCompleted: { display_model.callsql("Use Name","select * from Record") }
I don't know what is the exact reason why it does not show anything. is there anything i missed, or did i do anything wrong? I would appreciate the hlep or suggestions.
Regards.@postbox said in how to display the data contents in TableModel:
if i give the query in constructor in .cpp file. But when i created a new function(callsql) and write those query from constructor to the new function(callsql), it does not display the contents.
I know nothing about QML and how
display_model.callsql(...)
works. But although yourcallsql()
executes a SQL query and fills the internal arrays on yourQAbstractTableModel
it does not do anything to tell Qt that the model's contents have changed. So the view does not know to update.Look again at QAbstractTableModel, Subclassing.
Models that provide interfaces to resizable data structures can provide implementations of insertRows(), removeRows(), insertColumns(), and removeColumns(). When implementing these functions, it is important to call the appropriate functions so that all connected views are aware of any changes:
You are going to need to implement at least
insertRows()
to correspond to where youappend()
to your lists.You get away without it in the constructor because the view only gets attached after the model has been filled initially.
For the rest of it as @Gojir4 says. Since you are using SQL table queries derive from
QSqlTableModel
, notQAbstractTableModel
, you won't have to do your ownQSqlQuery::next()
s, and get rid of your lists. Usedata()
orQSqlRecord
to access the rows populated into the model. -