Qt 小例子学习6 - QTableview:根据其他列中的值显示特定列中的数据

SqlTableModel是一个自定义的QSqlTableModel子类,扩展了标准的Qt数据模型以包含额外的列,这些列根据表格中'position'字段的值动态插入。它实现了数据和头数据的方法来支持这些额外的列,并且在'position'字段更改时能够自动更新。Dialog类使用此模型来显示和编辑SQLite数据库中的数据。
摘要由CSDN通过智能技术生成

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

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值