SqlTableModel.h
#ifndef SQLTABLEMODEL_H
#define SQLTABLEMODEL_H
#include <QSqlTableModel>
class SqlTableModel : public QSqlTableModel
{
const QString stateName = "state";
const QString positionName = "position";
public:
int columnCount(const QModelIndex& parent = QModelIndex()) const;
void setTable(const QString& tableName);
QVariant data(const QModelIndex& idx, int role = Qt::DisplayRole) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex& index) const;
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
private:
int max_position;
int index_position;
int index_state;
void reset();
};
#endif // SQLTABLEMODEL_H
SqlTableModel.cpp
#include "SqlTableModel.h"
#include <QBrush>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlTableModel>
#include <QTimer>
int SqlTableModel::columnCount(const QModelIndex& parent) const
{
return QSqlTableModel::columnCount(parent) + max_position;
}
void SqlTableModel::setTable(const QString& tableName)
{
QSqlTableModel::setTable(tableName);
index_position = fieldIndex(positionName);
index_state = fieldIndex(stateName);
reset();
}
QVariant SqlTableModel::data(const QModelIndex& idx, int role) const
{
if(role == Qt::ForegroundRole)
{
return QBrush(Qt::black);
}
const int number_of_columns = QSqlTableModel::columnCount();
if(idx.column() >= number_of_columns)
{
if(role == Qt::DisplayRole)
{
int position = QSqlTableModel::data(this->index(idx.row(), index_position), Qt::DisplayRole).toInt();
if(idx.column() == number_of_columns + position + 1)
{
return QSqlTableModel::data(this->index(idx.row(), index_state), Qt::DisplayRole)
.toString();
}
}
}
return QSqlTableModel::data(idx, role);
}
QVariant SqlTableModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
if(orientation == Qt::Horizontal &&
role == Qt::DisplayRole &&
section >= QSqlTableModel::columnCount())
{
return section - QSqlTableModel::columnCount() + 1;
}
return QSqlTableModel::headerData(section, orientation, role);
}
Qt::ItemFlags SqlTableModel::flags(const QModelIndex& index) const
{
if(index.column() >= QSqlTableModel::columnCount())
{
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
}
return QSqlTableModel::flags(index);
}
bool SqlTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if(role == Qt::EditRole)
{
const int number_of_columns = QSqlTableModel::columnCount();
if(index.column() >= number_of_columns)
{
bool result = QSqlTableModel::setData(this->index(index.row(), index_position),
index.column() - number_of_columns + 1, role);
bool result2 = QSqlTableModel::setData(this->index(index.row(), index_state), value, role);
return result & result2;
}
if(index.column() == index_position)
{
QTimer::singleShot(0, this, &SqlTableModel::reset);
}
}
return QSqlTableModel::setData(index, value, role);
}
void SqlTableModel::reset()
{
QSqlQuery q;
q.exec(QString("SELECT MAX(%1) FROM %2").arg(positionName).arg(tableName()));
int val;
while(q.next())
{
val = q.value(0).toInt();
}
if(val != max_position)
{
beginResetModel();
max_position = val;
endResetModel();
}
}
Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <SqlTableModel.h>
QT_BEGIN_NAMESPACE
namespace Ui
{
class Dialog;
}
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public: Dialog(QWidget* parent = nullptr);
~Dialog();
private:
Ui::Dialog* ui;
SqlTableModel* model;
QSqlDatabase db;
};
#endif // DIALOG_H
Dialog.cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <SqlTableModel.h>
QT_BEGIN_NAMESPACE
namespace Ui
{
class Dialog;
}
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public: Dialog(QWidget* parent = nullptr);
~Dialog();
private:
Ui::Dialog* ui;
SqlTableModel* model;
QSqlDatabase db;
};
#endif // DIALOG_H
main.cpp
#include "dialog.h"
#include <QMessageBox>
#include <QApplication>
#include <QSqlQuery>
static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(":memory:");
if(!db.open())
{
QMessageBox::critical(
0, qApp->tr("Cannot open database"),
qApp->tr("Unable to establish a database connection.\n"
"This example needs SQLite support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
"Click Cancel to exit."),
QMessageBox::Cancel
);
return false;
}
QSqlQuery query;
query.exec("create table TableExample (id INTEGER NOT NULL PRIMARY KEY "
"AUTOINCREMENT, "
"Field1 varchar(20), position INTEGER, Field2 varchar(20), state "
"varchar(20), Field3 varchar(20))");
query.exec("insert INTO TableExample (Field1, position, Field2, state, "
"Field3) values('Danny', 3. 'Young', 'A', 'aaa')");
query.exec("insert INTO TableExample (Field1, position, Field2, state, "
"Field3) values('Christine', 4, 'Holand', 'B', 'bbb')");
query.exec("insert INTO TableExample (Field1, position, Field2, state, "
"Field3) values('Lars', 1, 'Gordon', 'C', 'ccc')");
query.exec("insert INTO TableExample (Field1, position, Field2, state, "
"Field3) values('Roberto', 5, 'Robitaille', 'D', 'ddd')");
query.exec("insert INTO TableExample (Field1, position, Field2, state, "
"Field3) values('Maria', 2, 'Papadopoulos', 'E', 'eee')");
return true;
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
if(!createConnection())
{
return 1;
}
Dialog w;
w.show();
return a.exec();
}