演示效果
1.定义C++类与方法
类继承关系
//继承QAbstractTableModel,而QAbstractTableModel继承于QAbstractItemModel
class QmlTableViewModel : public QAbstractTableModel
class Q_CORE_EXPORT QAbstractTableModel : public QAbstractItemModel
class Q_CORE_EXPORT QAbstractItemModel : public QObject
Q_OBJECT //供QML访问的类 QObject类的子类必须包含这个宏 QT会调用moc元对象编译器来编译该类
public:
explicit QmlTableViewModel(); //构造函数 只能显示转换,防止被隐藏转换
方法定义与基类方法重写
//Q_DECL_OVERRIDE 相当于C++中的override 重写基类相关函数
//类基于QAbstractItemModel声明的虚函数 rowCount columnCount data roleNames
//行数
int rowCount(const QModelIndex & parent = QModelIndex()) const Q_DECL_OVERRIDE; //重写基类函数
//列数
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;//重写基类函数
//数据 DisplayRole为单元格显示状态
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;//重写基类函数
//角色类
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE; //重写基类函数
//自定义函数 Q_INVOKABLE 定义的函数QML可调用
//增加
Q_INVOKABLE void Add(QString one, QString two, QString three);
//修改
Q_INVOKABLE void Set(int row, int column, QString text);
//删除
Q_INVOKABLE void Del();
//刷新
Q_INVOKABLE void Refresh();
2.实现方法
//实现重写函数rowCount
int QmlTableViewModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_aryData.size();
}
//实现重写函数columnCount
int QmlTableViewModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 3;
}
//实现重写函数data
QVariant QmlTableViewModel::data(const QModelIndex &index, int role) const
{
return m_aryData[index.row()][role];
}
//显示名
QHash<int, QByteArray> QmlTableViewModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Role1] = "DisplayRole1";
roles[Role2] = "DisplayRole2";
roles[Role3] = "DisplayRole3";
return roles;
}
//自定义函数实现Add
void QmlTableViewModel::Add(QString one, QString two, QString three)
{
beginInsertRows(QModelIndex(), m_aryData.size(), m_aryData.size());
QVector<QString> list;
list.push_back(one);
list.push_back(two);
list.push_back(three);
m_aryData.push_back(list);
endInsertRows();
}
//自定义函数实现Set
void QmlTableViewModel::Set(int row, int column, QString text)
{
if (row == -1){return;}
if (column == -1){return;}
beginResetModel();
m_aryData[row][column] = text;
endResetModel();
}
//自定义函数实现Del
void QmlTableViewModel::Del()
{
if (m_aryData.size() <= 0) return;
beginRemoveRows(QModelIndex(), m_aryData.size() - 1, m_aryData.size() - 1);
m_aryData.removeLast();
endRemoveRows();
}
//自定义函数实现Refresh
void QmlTableViewModel::Refresh()
{
beginResetModel();
endResetModel();
}
添加对象到QML引擎上下文
//C++原生对象
QmlTableViewModel model;
//调用对象方法
model.Add(QStringLiteral("初始化"), QStringLiteral("123"), QStringLiteral("456"));
添加原生对象实例到根上下文,供QML调用
engine.rootContext()->setContextProperty("CppDefindModelObject", &model);
3.在qml中调用
tableview中调用C++原生model
TableView {
property alias tableView: tableView
id: tableView
TableViewColumn {title: "表情"; role: "DisplayRole1"; width: 120}
TableViewColumn {title: "数值1"; role: "DisplayRole2"; width: 120}
TableViewColumn {title: "数值2"; role: "DisplayRole3"; width: 120}
model: CppDefindModelObject //使用C++注册到根据上下文件的原生对象
alternatingRowColors: false
backgroundVisible: false
}
在事件上调用原生类方法
onEditingFinished: {
//调用C++原生模块方法
CppDefindModelObject.Set(styleData.row, styleData.column, textField.text);
}
在按钮点击事件调用原生方法
Button{
text: qsTr("添加")
onClicked: {
//调用C++原生模块方法
CppDefindModelObject.Add("111",555,886.089);//调用原生对象方法
}
}
Button{
text: qsTr("删除")
onClicked: {
//调用C++原生模块方法
CppDefindModelObject.Del();//调用原生对象方法
}
}
Button{
text: qsTr("刷新")
onClicked: {
//调用C++原生模块方法
CppDefindModelObject.Refresh();//调用原生对象方法
}
}
C++完整代码: QmlTableView.cpp
#include "QmlTableView.h"
#include <QDebug>
//构造并初始化基类QAbstractTableModel
QmlTableViewModel::QmlTableViewModel() : QAbstractTableModel(0)
{
}
//实现重写函数rowCount
int QmlTableViewModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_aryData.size();
}
//实现重写函数columnCount
int QmlTableViewModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 3;
}
//实现重写函数data
QVariant QmlTableViewModel::data(const QModelIndex &index, int role) const
{
return m_aryData[index.row()][role];
}
//显示名
QHash<int, QByteArray> QmlTableViewModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[Role1] = "DisplayRole1";
roles[Role2] = "DisplayRole2";
roles[Role3] = "DisplayRole3";
return roles;
}
//自定义函数实现Add
void QmlTableViewModel::Add(QString one, QString two, QString three)
{
beginInsertRows(QModelIndex(), m_aryData.size(), m_aryData.size());
QVector<QString> list;
list.push_back(one);
list.push_back(two);
list.push_back(three);
m_aryData.push_back(list);
endInsertRows();
}
//自定义函数实现Set
void QmlTableViewModel::Set(int row, int column, QString text)
{
if (row == -1){return;}
if (column == -1){return;}
beginResetModel();
m_aryData[row][column] = text;
endResetModel();
}
//自定义函数实现Del
void QmlTableViewModel::Del()
{
if (m_aryData.size() <= 0) return;
beginRemoveRows(QModelIndex(), m_aryData.size() - 1, m_aryData.size() - 1);
m_aryData.removeLast();
endRemoveRows();
}
//自定义函数实现Refresh
void QmlTableViewModel::Refresh()
{
beginResetModel();
endResetModel();
}
QmlTableView.h
#pragma once
#include <QAbstractTableModel> //QAbstractTableModel定义所在头文件
#include <QVector>
//枚举
enum Role {
Role1,
Role2,
Role3
};
//继承QAbstractTableModel,而QAbstractTableModel继承于QAbstractItemModel
class QmlTableViewModel : public QAbstractTableModel
{
Q_OBJECT //供QML访问的类 QObject类的子类必须包含这个宏 QT会调用moc元对象编译器来编译该类
public:
explicit QmlTableViewModel(); //构造函数 只能显示转换,防止被隐藏转换
//Q_DECL_OVERRIDE 相当于C++中的override 重写基类相关函数
//类基于QAbstractItemModel声明的虚函数 rowCount columnCount data roleNames
//行数
int rowCount(const QModelIndex & parent = QModelIndex()) const Q_DECL_OVERRIDE; //重写基类函数
//列数
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;//重写基类函数
//数据 DisplayRole为单元格显示状态
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;//重写基类函数
//角色类
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE; //重写基类函数
//自定义函数 Q_INVOKABLE 定义的函数QML可调用
//增加
Q_INVOKABLE void Add(QString one, QString two, QString three);
//修改
Q_INVOKABLE void Set(int row, int column, QString text);
//删除
Q_INVOKABLE void Del();
//刷新
Q_INVOKABLE void Refresh();
private:
//用保存数据的私有变量
QVector<QVector<QString>> m_aryData;
};
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "QmlTableView.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
//C++原生对象
QmlTableViewModel model;
//调用对象方法
model.Add(QStringLiteral("test"), QStringLiteral("123"), QStringLiteral("456"));
添加原生对象实例到根上下文,供QML调用
engine.rootContext()->setContextProperty("CppDefindModelObject", &model);
//加载主QML
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
QML脚本完整源码:
QmlTableView.qml
import QtQuick 2.8
import QtQuick.Controls 1.4
TableView {
property alias tableView: tableView
id: tableView
TableViewColumn {title: "表情"; role: "DisplayRole1"; width: 120}
TableViewColumn {title: "数值1"; role: "DisplayRole2"; width: 120}
TableViewColumn {title: "数值2"; role: "DisplayRole3"; width: 120}
model: CppDefindModelObject //使用C++注册到根据上下文件的原生对象
alternatingRowColors: false
backgroundVisible: false
}
Main.qml
import QtQuick 2.8
import QtQuick.Controls 2.1
ApplicationWindow {
id: frmWindow
title: qsTr("基于QT的QML表格演示")
width: 400
height: 300
visible: true
onClosing: {qmlTableView.enabled = false;}
QmlTableView{
id: qmlTableView
height: frmWindow.height - 40
width: parent.width
tableView.itemDelegate:Rectangle {
TextField{
id: textField
height: 25
text: styleData.value
selectByMouse: true
onEditingFinished: {
//调用C++原生模块方法
CppDefindModelObject.Set(styleData.row, styleData.column, textField.text);
}
visible: (styleData.column !== 0)
}
Image{
id: image
height: 25
width: 25
source: "qrc:/wifi.png"
visible: (styleData.column === 0)
}
}
tableView.rowDelegate: Rectangle {
height: 25
}
}
Row{
anchors.bottom: parent.bottom
height: 40
width: parent.width
Button{
text: qsTr("添加")
onClicked: {
//调用C++原生模块方法
CppDefindModelObject.Add("111",555,886.089);//调用原生对象方法
}
}
Button{
text: qsTr("删除")
onClicked: {
//调用C++原生模块方法
CppDefindModelObject.Del();//调用原生对象方法
}
}
Button{
text: qsTr("刷新")
onClicked: {
//调用C++原生模块方法
CppDefindModelObject.Refresh();//调用原生对象方法
}
}
}
}