我有一个sqlite表,其中包含一个" position
"和" state
"领域。
我希望在QTableView
中显示此表,其中位置为标题列,右列中的状态如下:
id | 1 | 2 | 3
1 | A | |
2 | | | E
表示以下数据库条目:
id | position | state
1 | 1 | A
2 | 3 | E
做这样的事情最好的方法是什么?
修改:不确定这是否会发生任何变化,但我也需要QTableView
进行编辑(通过覆盖setData()
的{{1}}方法)
答案 0 :(得分:2)
这种情况最简单的选择是创建一个继承自QSqlTableModel
的类并修改必要的函数,如下所示:
<强> 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 &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
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 <QSqlTableModel>
#include <QSqlRecord>
#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 &index, int role) const
{
if(role == Qt::ForegroundRole){
return QBrush(Qt::black);
}
const int number_of_columns = QSqlTableModel::columnCount();
if(index.column()>= number_of_columns){
if(role==Qt::DisplayRole){
int position = QSqlTableModel::data(this->index(index.row(), index_position), Qt::DisplayRole).toInt();
if(index.column() == number_of_columns + position - 1){
return QSqlTableModel::data(this->index(index.row(), index_state), Qt::DisplayRole).toString();
}
}
}
return QSqlTableModel::data(index, 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 result1 = 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 result1 && 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();
}
}
<强>输入:强>
id |position |state
1 |1 |A
2 |2 |S
3 |1 |C
4 |4 |B
5 |3 |V
<强>输出:强>
完整示例可在以下link
中找到