QML调用C++类对象与方法

演示效果 

 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();//调用原生对象方法
            }
        }
    }
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林鸿群

有你的鼓励,我会更加努力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值