? 由于QtQuick Controls 1 里的TableView存在严重的性能问题,且事实上QtQuick Controls 1已经处于废弃状态,在Qt5.12中,QtQuick Controls 2更新了 TableView 组件,但新的TableView现在没有定义表头的接口,需要开发者自己实现,这方面资料比较少。在Qt creator的实例中有几个TableView的示例,但都不是sql数据模型的。这里给出了一种使用QSqlQueryModel作为模型在qml实现表格的方法。
代码有两部分构成,一=是自定义的TableView组件,而是作为model的c++模型,这里继承自QSqlQueryModel
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.12
import com.appSql 1.0
Item {
id: root
property string tableName: "学生表"
property int verHeaderHeight: 30
property int verHeaderWidth: 30
property int horHeaderHeight: 30
property variant columnWidthArr: [200,100,100,100,100,100] //定义列宽数组
TableView {
id: tableView
columnSpacing: 1
columnWidthProvider: function (column) {
return root.columnWidthArr[column];
}
rowHeightProvider: function (row) {
return root.verHeaderHeight;
}
Layout.margins: 15
anchors{
fill: parent
leftMargin: root.verHeaderWidth
topMargin: root.horHeaderHeight
}
model: TableModel{ id: table_model ;m_tableName: tableName}
clip: true
delegate: Rectangle { //这里是定义表格内容
width: tableView.columnWidthProvider(model.row)
height: horHeaderHeight
Label {
id: label
text: model.value
anchors.fill: parent
anchors.margins: 10
color: "black"
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
//定义横向表头
Item{
id: header_horizontal
anchors{
left: parent.left
right: parent.right
leftMargin: root.verHeaderWidth
}
height: root.horHeaderHeight
z: 2
Row {
id: header_horizontal_row
anchors.fill: parent
leftPadding: -tableView.contentX
clip: true
spacing: 0
Repeater {
model: tableView.columns > 0 ? tableView.columns : 0
Rectangle {
id: header_horizontal_item
width: tableView.columnWidthProvider(index)+tableView.columnSpacing
height: root.horHeaderHeight
color: "#1C77C3"
Text {
anchors.centerIn: parent
text: table_model.headerData(index, Qt.Horizontal)
color: "white"
}
Rectangle{
width: 1
height: parent.height
anchors.right: parent.right
color: "black"
opacity: 0.5
}
}
}
}
}
//定义纵向表头
Column {
id: header_verical
anchors{
top: parent.top
bottom: parent.bottom
topMargin: root.horHeaderHeight
}
topPadding: -tableView.contentY
z: 2
clip: true
spacing: 1
Repeater {
model: tableView.rows > 0 ? tableView.rows : 0 //返回模型的行数,这里需要覆写rowCount函数
Rectangle {
width: root.verHeaderWidth
height: tableView.rowHeightProvider(index)
color: "#1C77C3"
Text {
anchors.centerIn: parent
text: table_model.headerData(index, Qt.Vertical)
color: "white"
}
}
}
}
onTableNameChanged: {
console.log("tablename changed!")
tableView.forceLayout()
}
}
//tablemodel.h
#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QSqlQueryModel>
#include <QSqlQuery>
class tableModel:public QSqlQueryModel
{
Q_OBJECT
Q_PROPERTY(QString m_tableName READ tableName WRITE setTableName NOTIFY tableNameChanged)
public:
tableModel(QSqlQueryModel* parent = nullptr);
Q_INVOKABLE QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QString tableName() const;
void setTableName(const QString _tableName);
signals:
void tableNameChanged();
private:
QString m_tableName;
QVector<QString> m_tableTitle;
QSqlQuery* m_query;
QHash<int, QByteArray> m_roleNames;
};
#endif // TABLEMODEL_H
//tablemodel.cpp
#include "tablemodel.h"
#include <QDebug>
#include <QSqlDriver>
#include <QSqlError>
#include <QSqlRecord>
tableModel::tableModel(QSqlQueryModel* parent)
:QSqlQueryModel(parent), m_tableName(""), m_query(new QSqlQuery(QSqlDatabase::database()))
{
m_roleNames[Qt::DisplayRole] = "value";
m_roleNames[Qt::EditRole] = "edit";
qDebug()<<QSqlDatabase::database().connectionNames();
connect(this, &tableModel::tableNameChanged,
[&]{
qDebug()<<"tableNameChanged";
QString queryser;
if(m_tableName == "选课表")
{
queryser= QString("select "
"学生表.学号, 学生表.姓名, 选课表.课程号, 课程表.课程名, 成绩 "
"from "
"选课表, 学生表, 课程表 "
"where "
"课程表.课程号 = 选课表.课程号 and 学生表.学号 = 选课表.学号");
qDebug()<<queryser;
}
else{
queryser = QString("select * from %1").arg(m_tableName);
}
if(!m_query->exec(queryser))
qDebug()<<m_query->lastError();
this->setQuery(*m_query);
int columns = this->columnCount();
m_tableTitle.clear();
for(int i = 0; i < columns; ++i)
{
m_tableTitle.append(m_query->record().fieldName(i));//获取字段名
}
});
}
QVariant tableModel::data(const QModelIndex &index, int role) const
{
QVariant v;
// the index returns the requested row and column information.
int row = index.row();
int column = index.column();
// boundary check for the row and column
if(row < 0 || row >= this->rowCount()
||column < 0 || column >= this->columnCount())
{
return v;
}
if (role & ~(Qt::DisplayRole | Qt::EditRole))
return v;
qDebug()<<m_query->at();
qDebug()<<"row :"<<row<<"colum: "<<column<<"role: "<<role;
m_query->seek(row);
qDebug()<<m_query->value(column);
return m_query->value(column);
}
QHash<int, QByteArray> tableModel::roleNames() const
{
return m_roleNames;
}
QString tableModel::tableName() const
{
return m_tableName;
}
void tableModel::setTableName(const QString _tableName)
{
if(_tableName != m_tableName )
{
m_tableName = _tableName;
emit tableNameChanged();
}
}
QVariant tableModel::headerData(int section, Qt::Orientation orientation, int role) const
{//这个函数获取表头数据
if(role != Qt::DisplayRole)
return QVariant();
if(orientation == Qt::Horizontal)
{
return m_tableTitle.at(section);
}
else if(orientation == Qt::Vertical)
{
return QString::number(section);
}
return QVariant();
}
int tableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_query->size();
}
int tableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_query->record().count();
}
用QtQuick Controls 2 中的TableView构建表格
原文:https://www.cnblogs.com/Redwarx008/p/13996863.html