QTableview:根据其他列中的值显示特定列中的数据
Posted
技术标签:
【中文标题】QTableview:根据其他列中的值显示特定列中的数据【英文标题】:QTableview: display data in specific column based on value in other column 【发布时间】:2017-09-12 06:28:45 【问题描述】:我有一个包含(除其他外)“position
”和“state
”字段的 sqlite 表。
我想在QTableView
中显示此表,位置作为标题列,状态在右列中,如下所示:
id | 1 | 2 | 3
1 | A | |
2 | | | E
代表以下数据库条目:
id | position | state
1 | 1 | A
2 | 3 | E
做这样的事情最好的方法是什么?
编辑:不确定这是否会改变任何东西,但我需要 QTableView
也可以编辑(通过覆盖 QSqlQueryModel
的 setData()
方法)
【问题讨论】:
使用 QTableWidget ! 您可以共享数据库,以便您可以将其作为测试。 :P @NicolasA。 QTableView 是这些情况的最佳选择。 我已经通过删除放置索引的依赖来更新我的答案,现在它会自动解决。当您说它应该是可编辑的时,您可以向我解释您的意思,例如带有id = 2, position = 2 and state = S
的记录,因为您想编辑该记录。
非常感谢您的时间和更新。效果更好!如果我有任何问题,我会玩它并回复你。
【参考方案1】:
这种情况下最简单的选择是创建一个继承自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找到
【讨论】:
您的代码似乎有问题:columnCount 用于在视图中绘制正确数量的列,但它也用于获取模型中两个不同的列数事物。在我的例子中,你所说的 position_col 是 6(我为示例简化了数据库)。当我尝试获取此列中的值时,我得到一个无效的 QVariant,因为它优于 columnCount 返回的 max_position。 无论如何,将显示表中的列与查询返回的实际列数混合在一起似乎是错误的。以上是关于QTableview:根据其他列中的值显示特定列中的数据的主要内容,如果未能解决你的问题,请参考以下文章