• C++传递数据到QML-setContextProperty


    一、适用情况

    在C++里将数据生成,然后将这个数据设置为qml的上下文属性,在qml里就能使用了

    二、传递基础类型

    1、main.cpp

    QQuickWidget *m_widget = new QQuickWidget(this);
    m_widget->setGeometry(0, 0, this->width(), this->height());
    //关键代码
    QString str = "zhuxy";
    m_widget->rootContext()->setContextProperty("Zhuxy",str);
    m_widget->setSource(QUrl("./main.qml"));
    m_widget->show();

    2、main.qml

    import QtQuick 2.0
    Rectangle
    {
        id: mainWindow
        x: 30; y: 80;  1000; height: 800;
        Component.onCompleted: {
            console.log(Zhuxy);
        }
    }

    这里直接能用Zhuxy这个上下文属性

    三、ListView+QStringList作为model

    1、main.cpp

    QStringList list;
    list << "1" << "2";
    m_widget->rootContext()->setContextProperty("Zhuxy",QVariant::fromValue(list));//不能是Test??
    m_widget->setSource(QUrl("./test.qml"));
    m_widget->show();

    2、test.qml

    import QtQuick 2.0
    ListView {
    100; height: 100 model: myModel delegate: Rectangle { height: 25 100 Text { text: modelData } } }

    注意:经过测试这个上下文属性不能取名为Test(可能已经是内置上下文属性)

    四、ListView+qml可访问的C++类

    1、

    mydata.h

    #ifndef MYDATA_H
    #define MYDATA_H
    
    #include <QObject>
    
    class Mydata : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString value READ value WRITE setValue NOTIFY valueChanged)
        Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
      public:
        Mydata(QObject *parent = nullptr);
        Mydata(const QString &value, const QString &name, QObject *parent = nullptr);
        QString value()const;
        void setValue(const QString &value);
        QString name()const;
        void setName(const QString& name);
      signals:
        void valueChanged();
        void nameChanged();
      private:
        QString m_value;
        QString m_name;
    };
    
    #endif // MYDATA_H

    value和name就是qml可访问的值

    mydata.cpp

    #include "mydata.h"
    
    Mydata::Mydata(QObject *parent) : QObject(parent)
    {
    
    }
    
    Mydata::Mydata(const QString &value, const QString &name, QObject *parent)
        : QObject(parent),m_value(value),m_name(name)
    {
    
    }
    
    QString Mydata::value() const
    {
        return m_value;
    }
    
    void Mydata::setValue(const QString &value)
    {
        if(this->m_value != value) {
            this->m_value = value;
            emit valueChanged();
        }
    
    }
    
    QString Mydata::name() const
    {
        return m_name;
    }
    
    void Mydata::setName(const QString &name)
    {
        if(this->m_name != name) {
            this->m_name = name;
            emit nameChanged();
        }
    }

    2、test.qml

    import QtQuick 2.0
    
    Rectangle
    {
        id: mainWindow
        x: 30; y: 80;  1000; height: 800;
        ListView {
            anchors.fill: parent;
            model: ParaListModel;
            delegate: delegate_list
            spacing: 20;
            orientation: ListView.Horizontal
    
            //委托
            Component {
                id: delegate_list;
                Rectangle {
                    id: rect;
                     80;
                    height: width;
                    color: "green";
                    Text {
                        id: text1;
                        text: value;
                        horizontalAlignment: Text.AlignHCenter;
                        verticalAlignment: Text.AlignVCenter;
                        font.pixelSize: 16;
                        anchors.horizontalCenter: parent.horizontalCenter;
                        anchors.top: parent.top;
                        anchors.topMargin: 10;
                        color: "white";
                    }
                    Text {
                        id: text2;
                        text: name;
                        horizontalAlignment: Text.AlignHCenter;
                        verticalAlignment: Text.AlignVCenter;
                        font.pixelSize: 16;
                        anchors.horizontalCenter: parent.horizontalCenter;
                        anchors.bottom: parent.bottom;
                        anchors.bottomMargin: 10;
                        color: "white";
                    }
                }
            }
        }
    
    }

    3、main.cpp

    QList<QObject*> datalist;
    datalist.append(new Mydata("item1", "red"));
    datalist.append(new Mydata("item2", "green"));
    datalist.append(new Mydata("item3", "blue"));
    datalist.append(new Mydata("item4", "yellow"));
    m_widget->rootContext()->setContextProperty("ParaListModel",QVariant::fromValue(datalist));

    注意必须是QObject指针类型才能放进list等容器里,因为QObject的赋值构造函数是delete的

    五、ListView+QAbstractListModel子类

    上面的几种不支持动态更新数据,现在这种方式支持动态更新数据,当时当list的个数增加或减少是不支持更新的。

    1、C++模型类ParaListModel.h

    #ifndef PARALISTMODEL_H
    #define PARALISTMODEL_H
    
    #include <QAbstractListModel>
    
    struct ParaModel
    {
        ParaModel()
        {
            value = "";
            nodeName = "";
            nodeType = "";
            tableName = "";
            fieldName = "";
            module = "";
            location = "";
            rectRadius = -1;
        }
        //核心属性
        QString value;
        QString nodeName;
        QString nodeType;
        QString tableName;
        QString fieldName;
        //附加属性
        QString module;
        QString location;
        int rectRadius;
    };
    
    class ParaListModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        ParaListModel(QObject* parent = 0);
        enum Roles//qml用来识别别名的规则
        {
            valueRole = Qt::UserRole + 1,
            nodeNameRole,
            nodeTypeRole,
            tableNameRole,
            fieldNameRole,
            moduleRole,
            locationRole,
            rectRadiusRole
        };
        void addModel(const ParaModel &deviceList);//C++设置值
        void update(int index, const ParaModel &paraModel);//C++更新
        int  rowCount(const QModelIndex &parent = QModelIndex()) const;//qml内部调用,不用多管直接重写即可
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;//qml内部调用,不用多管直接重写即可
    
    
    protected:
        QHash<int, QByteArray> roleNames() const;//qml内部调用,不用多管直接重写即可
    
    private:
        QList<ParaModel> m_data;
    };
    
    #endif // PARALISTMODEL_H

    C++模型类ParaListModel.cpp

    #include "paralistmodel.h"
    
    ParaListModel::ParaListModel(QObject *parent)
        : QAbstractListModel(parent)
    {
    
    }
    
    void ParaListModel::addModel(const ParaModel &paraModel)
    {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_data << paraModel;
        endInsertRows();
    }
    
    
    
    int ParaListModel::rowCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent);
        return m_data.count();
    }
    
    QVariant ParaListModel::data(const QModelIndex &index, int role) const
    {
        if (index.row() < 0 || index.row() >= m_data.count())
            return QVariant();
    
        const ParaModel &paraModel = m_data[index.row()];
        switch (role)
        {
        case valueRole:
            return paraModel.value;
            break;
        case nodeNameRole:
            return paraModel.nodeName;
            break;
        case nodeTypeRole:
            return paraModel.nodeType;
            break;
        case tableNameRole:
            return paraModel.tableName;
            break;
        case fieldNameRole:
            return paraModel.fieldName;
            break;
        case moduleRole:
            return paraModel.module;
            break;
        case locationRole:
            return paraModel.location;
            break;
        case rectRadiusRole:
            return paraModel.rectRadius;
            break;
        default:
            break;
        }
        return QVariant();
    }
    
    void ParaListModel::update(int index, const ParaModel &paraModel)
    {
        if (index < 0 || index >= m_data.count())
            return;
        ParaModel &srcModel = m_data[index];
        if(paraModel.value != "")
        {
            srcModel.value = paraModel.value;
        }
        if(paraModel.nodeName != "")
        {
            srcModel.nodeName = paraModel.nodeName;
        }
        if(paraModel.nodeType != "")
        {
            srcModel.nodeType = paraModel.nodeType;
        }
        if(paraModel.tableName != "")
        {
            srcModel.tableName = paraModel.tableName;
        }
        if(paraModel.fieldName != "")
        {
            srcModel.fieldName = paraModel.fieldName;
        }
        if(paraModel.module != "")
        {
            srcModel.module = paraModel.module;
        }
        if(paraModel.location != "")
        {
            srcModel.location = paraModel.location;
        }
        if(paraModel.rectRadius != -1)
        {
            srcModel.rectRadius = paraModel.rectRadius;
        }
    }
    
    //qml通过这里的QByteArray来访问数据
    QHash<int, QByteArray> ParaListModel::roleNames() const
    {
        QHash<int, QByteArray> roles;
        roles[valueRole] = "value";
        roles[nodeNameRole] = "nodeName";
        roles[nodeTypeRole] = "nodeType";
        roles[tableNameRole] = "tableName";
        roles[fieldNameRole] = "fieldName";
        roles[moduleRole] = "module";
        roles[locationRole] = "location";
        roles[rectRadiusRole] = "rectRadius";
        return roles;
    }

    qml通过3个重写的函数来获取每个model的值:

    首先通过rouCount获取model个数;

    再通过roleNames获取每个变量名和其role的值;

    最后根据role的值访问data函数,获取到真实值

    2、test.qml

    import QtQuick 2.0
    
    Rectangle {
         800;
        height: 300;
        color: "#222648";//背景色
        property int rect_ 80;//参数宽度
        property color text_color: "white";//字体颜色
        ListView {
             parent.width;
            height: rect_width;
            anchors.centerIn: parent;
            model: ParaListModel;
            delegate: delegate_list
            spacing: 20;
            orientation: ListView.Horizontal
        }
        //委托
        Component {
            id: delegate_list;
            Rectangle {
                id: rect;
                 rect_width;
                height: width;
                radius: rectRadius;
                color: bkColor;
                property string q_tableName: tableName;//其他不用显示的属性
                property string q_fieldName: fieldName;
                Text {
                    id: text1;
                    text: value;
                    horizontalAlignment: Text.AlignHCenter;
                    verticalAlignment: Text.AlignVCenter;
                    font.pixelSize: 16;
                    anchors.horizontalCenter: parent.horizontalCenter;
                    anchors.top: parent.top;
                    anchors.topMargin: 10;
                    color: text_color;
                }
                Text {
                    id: text2;
                    text: nodeName;
                    horizontalAlignment: Text.AlignHCenter;
                    verticalAlignment: Text.AlignVCenter;
                    font.pixelSize: 16;
                    anchors.horizontalCenter: parent.horizontalCenter;
                    anchors.bottom: parent.bottom;
                    anchors.bottomMargin: 10;
                    color: text_color;
                }
                MouseArea {
                    anchors.fill: parent;
                    hoverEnabled: true;
                    cursorShape: (containsMouse? (pressed? Qt.ClosedHandCursor: Qt.OpenHandCursor): Qt.ArrowCursor);//设置鼠标样式
                    onDoubleClicked: {
                        console.log(q_tableName,q_fieldName);
                    }
                }
            }
        }
    
    }

    3、main.cpp

    m_widget = new QQuickWidget(this);
    m_widget->setGeometry(0, 0, this->width(), this->height());
    //关键代码
    ParaListModel modelList;
    for(int i=0;i<5;i++)
    {
        ParaModel model;
        model.value = "value:"+QString::number(i);
        model.nodeName = "nodeName:"+QString::number(i);
        model.nodeType = "nodeType:"+QString::number(i);
        model.tableName = "tableName:"+QString::number(i);
        model.fieldName = "fieldName:"+QString::number(i);
        model.rectRadius = 40;
        modelList.addModel(model);
    }
    m_widget->rootContext()->setContextProperty("ParaListModel",&modelList);
    
    //测试实时更新qml中的值
    ParaModel model;
    model.value = "new";
    model.nodeName = "new";
    model.rectRadius = 10;
    modelList.update(4,model);

  • 相关阅读:
    Qt 4套件的组成适用于Qt 4.5以后的版本
    GTK+, Qt, wxWidgets compare
    为什么选择Qt
    [转]零基础学Qt 4编程实例之四:理解并正确使用名字空间
    [转]Qt 4常见的IDE及其优缺点比较推荐Qt Creator和Eclipse
    *nix系统下验证Qt 4安装正确与否的方法和步骤
    Debian install matlab2010—also ok for ubuntu series!
    我推荐的Qt资源网站、论坛、博客等来自《零基础学Qt 4编程》一书的附录
    ubuntu debian fedora Mac install pgplot steps!!
    64位WIN7 配置IIS遇到问题
  • 原文地址:https://www.cnblogs.com/judes/p/13460913.html
Copyright © 2020-2023  润新知