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 谢谢



  • 支持楼主,楼主厉害


 

最近的回复

  • Qt for Python终于发布了!
    以前的我,可能接触了一点Python,但是都没有坚持下来,现在Python水平还很弱呢。不过我基本语法还是了解一点的。所以我打算借着Qt for Python的东风,来尝试一下Python的开发。

    1、去Python 官网安装Python。地址是:

    https://www.python.org/downloads/mac-osx
    0_1529422911935_1.png
    我下载的版本是3.6.5

    2、双击pkg安装包进行安装,按照提示安装即可,不必做什么设置。
    0_1529422932496_2.png
    3、安装pip。pip是一个类似npm的快速安装器,非常适合python安装。由于Mac的安全策略,这个时候要输入的命令以sudo开始:

    sudo python get-pip.py

    4、需要安装Qt官网提供的python安装包。Qt的Python安装包并没有放入Pypi的地址,因为Qt库本身就偏大。
    但是依然能够通过pip安装。只是安装的命令稍微长:

    sudo pip install --index-url=https://download.qt.io/official_releases/QtForPython/ pyside2

    然后输出的结果是:
    daxiongtekiMacBook-Air:~ jiangcaiyang$ sudo pip install --index-url=https://download.qt.io/official_releases/QtForPython/ pyside2
    Password:
    The directory '/Users/jiangcaiyang/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
    The directory '/Users/jiangcaiyang/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
    Looking in indexes: https://download.qt.io/official_releases/QtForPython/
    Collecting pyside2
    Downloading https://download.qt.io/official_releases/QtForPython/pyside2/PySide2-5.11.0-5.11.0-cp27-cp27m-macosx_10_11_intel.whl (125.7MB)
    100% |████████████████████████████████| 125.7MB 1.0MB/s
    matplotlib 1.3.1 requires nose, which is not installed.
    matplotlib 1.3.1 requires tornado, which is not installed.
    Installing collected packages: pyside2
    Successfully installed pyside2-5.11.0
    安装成功。

    5、安装成功了,开始写一个测试的程序吧!
    最简单的,当然是Hello Qt for Python啦。很简单,使用Qt Creator,很方便地可以创建这样的Python脚本,使用方法也和C++版本的Qt应用相同:

    #!/usr/bin/env python # -*- coding: utf-8 -*- from PySide2.QtWidgets import QApplication, QLabel app = QApplication( [ ] ) label = QLabel( "您好 Qt for Python!" ) label.show( ) app.exec_( )

    0_1529422962008_4.jpg
    其中第一行表示用/usr/bin/python 来解析,大家可以在命令提示符输入“which python”来看结果:
    第二行则是在Python 3.x下不用写了,设定的是utf-8编码格式。大家最好也是使用这样的格式,因为这样遇到编码的坑最少。
    因为Python没有main()函数的说法,所以直接从上往下运行就可以了。Python是弱语言,所以不用声明类型,这里还有一点不一样,就是
    app.exec_( ),和C++版本不同的是,添加上了一个下划线。可能和Python内置的函数冲突了?我还需要再调查一下。

    接下来我就仿照例子写了一个更加复杂的Python程序,大致是这样的:

    #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import random from PySide2.QtCore import Qt from PySide2.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, QVBoxLayout ) class MyWidget( QWidget ): def __init__( self ): QWidget.__init__( self ) self.hello = [ "Hallo welt!", "Ciao mondo", "Hei maailma", "Hola mundo", "Hei verden!" ] self.button = QPushButton( "Click me!" ) self.text = QLabel( "Hello World" ) self.text.setAlignment( Qt.AlignCenter ) self.layout = QVBoxLayout( ) self.layout.addWidget( self.text ) self.layout.addWidget( self.button ) self.setLayout( self.layout ) self.button.clicked.connect( self.magic ) def magic( self ): self.text.setText( random.choice( self.hello ) ) if __name__ == "__main__": app = QApplication( sys.argv ) widget = MyWidget( ) widget.resize( 640, 480 ) widget.show( ) sys.exit( app.exec_( ) )

    程序运行起来还行吧!
    0_1529422988117_5.png

    阅读更多
  • @jiangcaiyang 如果需要自动化测试,也用的上

    阅读更多
  • @青山白云 这个可能有点用,但是可能更多局限于爬虫领域吧。

    阅读更多
  • https://blog.csdn.net/huilan_same/article/details/51896672

    python制作爬虫时候使用selenium进行自动化
    使用chromedriver时候需要对应版本

    chromedriver版本 支持的Chrome版本 v2.39 v66-68 v2.38 v65-67 v2.37 v64-66 v2.36 v63-65 v2.35 v62-64 v2.34 v61-63 v2.33 v60-62 v2.32 v59-61 v2.31 v58-60 v2.30 v58-60 v2.29 v56-58 v2.28 v55-57 v2.27 v54-56 v2.26 v53-55 v2.25 v53-55 v2.24 v52-54 v2.23 v51-53 v2.22 v49-52 v2.21 v46-50 v2.20 v43-48 v2.19 v43-47 v2.18 v43-46 v2.17 v42-43 v2.13 v42-45 v2.15 v40-43 v2.14 v39-42 v2.13 v38-41 v2.12 v36-40 v2.11 v36-40 v2.10 v33-36 v2.9 v31-34 v2.8 v30-33 v2.7 v30-33 v2.6 v29-32 v2.5 v29-32 v2.4 v29-32 查谷歌浏览器版本

    地址栏输入chrome://settings/help

    0_1528459921154_16bbaf4d-0e8e-42cd-9e52-f8fc43932871-image.png

    所有chromedriver均可在下面链接中下载到:

    http://chromedriver.storage.googleapis.com/index.html

    阅读更多

关注我们

微博
QQ群











召唤伊斯特瓦尔