QSqlTableModel是用于从单个表读写数据库记录的高级接口。它构建在底层的QSqlQuery之上,可用于为视图类(比如QTableView)提供数据。
例如:
QSqlTableModel *model = new QSqlTableModel;
model->setTable("employee");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
model->setHeaderData(0, Qt::Horizontal, tr("Name"));
model->setHeaderData(1, Qt::Horizontal, tr("Salary"));
QTableView *view = new QTableView;
view->setModel(model);
view->hideColumn(0); // don't show the ID
view->show();
用起来很简单,如果想在视图上让某个单元格的显示文本 设置特定的格式:文字颜色、对齐方式等,那就难以下手了。
参考了网友的文章: QSqlTableModel配合QTableView设置单元格对齐方式和前景色等 ,文中开篇就讲:
"方法:
创造model类继承QSqlTableModel,然后重载data函数"
真是一语点醒梦中人,这篇文章解决了一个大疑惑,为啥不能设置文本对齐格式或者设置 Qt::TextAlignmentRole的数据,没有用处。
弄完程序后,回头再回顾QSqlTableModel的使用方法,总结一些经验:
1、QSqlTableModel::setData()函数详解,可以得知,该模型只设置Qt::EditRole的数据,其他角色的数据不管。如果要使用其他角色数据的功能,可以自定义代理或者自定义其子类。
bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
/*在描述的尾部有这么一段特殊的话:
Returns false if the role is not Qt::EditRole. To set data for roles other than EditRole, either use a custom proxy model or subclass QSqlTableModel.
意思是:如果角色不是Qt::EditRole,则返回false。要为EditRole以外的角色设置数据,可以使用自定义代理模型或子类QSqlTableModel。*/
2、再看QSqlTableModel::Data()函数,只是重写了QSqlQueryModel::data(),没有特殊说明
QVariant QSqlTableModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
/*
重新实现:QSqlQueryModel::data(const QModelIndex &item, int role)。
*/
3、为了设置一些自定义角色的数据,那就自定义QSqlTableModel类
class MySqlTableModel : public QSqlTableModel
{
Q_OBJECT
public:
explicit MySqlTableModel(QObject *parent = nullptr,QSqlDatabase db = QSqlDatabase());
QVariant data(const QModelIndex &idx, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
private:
QMap<QModelIndex,QVariant> textMap;
};
4、重写data函数
QVariant MySqlTableModel::data(const QModelIndex &idx, int role) const
{
QVariant value = QSqlTableModel::data(idx,role);
qDebug() << idx << role;
return value;
}
/*可以得到类似的以下数据>
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 13
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 6
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 7
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 9
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 10
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 1
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 0
QModelIndex(0,0,0x0,MySqlTableModel(0x1936840)) 8*/
5、如果想使用setData()这种方式,那就可以重写此函数,我用了map来存储特定角色类型的数据
bool MySqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if(role == Qt::TextAlignmentRole)
{
textMap.insert(index,value);
return true;
}
return QSqlTableModel::setData( index, value, role);
}
如果不想这么麻烦,可以像文中那篇 blog文章所示,在data函数直接处理,又或者如下所示
QVariant MySqlTableModel::data(const QModelIndex &idx, int role) const
{
QVariant value = QSqlTableModel::data(idx,role);
if(role == Qt::TextAlignmentRole)
{
// value = textMap.value(idx);
value = Qt::AlignCenter;
return value;
}
return value;
}