Qt 在线技术交流之C++ 与 QML 交互



  • 本周六晚七点半开讲

    内容:C++ 与 QML 交互

    地点上海Qt开发联盟 279906625 群视频。

    暂无其他直播平台。

    以下为本次交流会大纲:

    QML 与 C++ 的交互

    有人说 QML 与 C++ 的交互太麻烦了,由于 QML 本身是面向对象的,所以交互起来依赖于 Qt 本身的元对象系统,显得十分笨重。但是仔细研究就会明白这样做的意义了。

    QML 与 C++ 的数据交互

    Qt Type QML Basic Type
    bool bool
    unsigned int, int int
    double double
    float, qreal real
    QString string
    QUrl url
    QColor color
    QFont font
    QDate date
    QPoint, QPointF point
    QSize, QSizeF size
    QRect, QRectF rect
    QMatrix4x4 matrix4x4
    QQuaternion quaternion
    QVector2D, QVector3D, QVector4D vector2d, vector3d, vector4d
    Q_ENUM enumeration
    QVariant,QVariantMap,QVariantList,QJSValue var,jsObject,jsArray,variant
    QJsonValue,QJsonObject, QJsonArray var, JSONObject
    带有 Q_GADGET 声明的类 var
    QObject* id
    QQmlListProperty<T> list<T>

    经测试,QVariantQVariantMapQVariantList 可以处理var类型的属性。

    另外可以将 qml 对象的 id 传入,C++参数是 QObject*


    如果要将一个数组从 C++ 传给 QML,最好使用 QJsonArray,或者 QList<QString>QList<QVariant>QList<QJSValue>QQmlListProperty<T>


    注意,不同 QJSEngine 之间的 QJSValue 不同互相使用。

    QML 调用 C++ 对象方法

    全局单例

    qmlRegisterSingleton

    注册的单例有两类,一类 QObject*,一类 QJSValue

    QQmlContext::setContextProperty(QString, QObject*);

    这个注册到上下文时要注意他的生命还未开始。

    注册新类型到 QML

    QObject

    QQuickItem

    QQuickPaintItem

    QAbstractItemModel

    推荐使用 QAbstractListModel,省时间。

    如下诉代码:

    int rowCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    QHash<int, QByteArray> roleNames() const;
    
        enum Roles{
            NameRole = Qt::UserRole + 1,
            AgeRole
        };
    int rowCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;
    QHash<int, QByteArray> roleNames() const;
    
    int TestModel::rowCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return m_datas.length();
    }
    
    
    QVariant TestModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid() || index.row() < 0)
            return QVariant();
    
        if (index.row() >= m_datas.count()) {
            qWarning() << "SatelliteModel: Index out of bound";
            return QVariant();
        }
        const Dao &dao = m_datas.at(index.row());
        switch (role)
        {
        case NameRole:
            return dao.name();
        case AgeRole:
            return dao.age();
        default:
            break;
        }
        return QVariant();
    }
    
    
    QHash<int, QByteArray> TestModel::roleNames() const
    {
        QHash<int, QByteArray> roleNames;
        roleNames.insert(NameRole, "NameRole");
        roleNames.insert(AgeRole, "AgeRole");
        return roleNames;
    }
    

    Q_GADGET

    使用 Q_GADGET 可以支持注册枚举,属性,Q_INVOKABLE。但是不支持信号和槽。

    C++ 调用 QML 对象方法

    将 qml 对象的 id 以 QObject* 的方式进行传参

    在 C++ 代码中主动捕获 qml 对象

    属性系统

    invokeMethod

    具体两个实例。

    QmlThread

    qml 中的多线程。

    QmlNetwork

    qml 中的文件读写和网络


  • 网站研运

    强烈支持,并且我会在其他的地方转发的,让其它人知晓。


  • 网站研运

    我们开始转播了哦。
    为那些不是群里的朋友们转播了!
    地址是(全民TV):http://quanmin.tv/v/qtdream
    (斗鱼):http://www.douyutv.com/492592



  • 重置视频已经上线。



  • good video on bilibili



  • @qyvlik 谢谢



  • 支持楼主,楼主厉害


 

走马观花

最近的回复

  • @bladesero Blender 在角色建模和渲染这些方面的确比较强。😄

    我们的软件还在发展中呢。
    18da2116-2055-47c1-8317-1ccde17dfcc0-image.png

    阅读更多
  • untitled.jpg figure角色(WIP2).jpg
    TIM截图20190117184210.png
    使用的软件是blender,zbrush和substance painter

    阅读更多
  • 背景:如果需要qml显示循环list,一般是用3个ListView循环交替,实现伪循环,期间逻辑复杂,容易出错,PathView本身自带循环,所以考虑用PathView实现循环

    设计:PathView显示5条数据,按照垂直List一个个排好顺序,由于收尾移动时候会空白穿帮,所以用clip控制显示中间三条数据

    滚动控制:currentIndex,decrementCurrentIndex(),incrementCurrentIndex()

    代码:

    Item{ id: item1 property int myIndex: 0 property int onePageCount: 3 property real oneHeight: 72 property real oneWidth: 580 property int isCurrentListView: 1 //0,1,2 property bool isAdd: true //direction,down=true,up=false property int hightlightIndex: 0 property int currentIndexPathView: 0 //use this Item{ id: itemClip width: item1.oneWidth height: item1.oneHeight*3 clip: true PathView { id: listView1 width: item1.oneWidth model: listModelSpeedWarning delegate: delegeteLine pathItemCount: item1.onePageCount+2 interactive: false path: Path { startX: item1.oneWidth/2 startY: -item1.oneHeight/2 PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*0+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*0+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*1+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*1+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*2+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*2+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*3+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*3+item1.oneHeight/2 } PathQuad { x: item1.oneWidth/2; y: item1.oneHeight*4+item1.oneHeight/2; controlX: item1.oneWidth/2; controlY: item1.oneHeight*4+item1.oneHeight/2 } } Component.onCompleted: { listView1.currentIndex = -1 } } } }

    问题:windows下测试,按住按键不松手,list滚动会卡住,松手后恢复正常,看来list不能滚动太快

    阅读更多
  • H

    @青山白云 只是为了替换GIF,不过目前已经解决加载问题

    阅读更多

关注我们

微博
QQ群











召唤伊斯特瓦尔