zoukankan      html  css  js  c++  java
  • C++和QML联合编程

      项目用C++和qml联合编程有段时间了,今天抽时间再次复习了,特写下笔记。

      在QML中使用C++类型或是属性,有两种方法:

        a.C++实现一个类,继承自QObject或是是QObject的派生类,并使用Q_OBJECT宏,注册为qml的一个类型。

        b.C++中构造一个对象,这个对象继承自QObject或是是QObject的派生类,并使用Q_OBJECT宏,将这个对象设置为qml的上下文属性。

      关于更多在QML中访问C++类型的内容,我们可以百度或是买本书看看,下面我们来具体看看如何将类、类的方法、类的属性、枚举注册到QML的元对象系统,既可以在QML中访问。

      1)注册到方法到QML。定义一个成员函数,在申明时,在方法前面加上Q_INVOKABLE宏即可,如:

      Q_INVOKABLE void requestChangedLanguage(LANGUAGE_TYPE type);    //注册一个方法到QMl

      2)注册一个枚举到QML。首先定义一个枚举,使用Q_ENUMS将枚举注册到QML元对象中即可。如:

    typedef enum
        {
            LANGUAGE_CH,
            LANGUAGE_EN,
            LANHUAGE_NUM,
        }LANGUAGE_TYPE;
        Q_ENUMS(LANGUAGE_TYPE) //注册枚举到QML

      3)注册一个属性到QML。通过Q_PROPERTY宏定义一个属性到QML即可,如:

        Q_PROPERTY(QString strTag READ getStrTag  NOTIFY strTagChanged) //注册有个属性到QML,Q_PROPERTY有多个参数,我们只说我们常用参数

      4)注册一个C++类到QML和注册一个对象为QML上下文属性。我们注册一个一个类型到QML,有多种方法,我们就说比较常用的通过qmlRegisterType,这是个模板函数,注册方式如下:

        qmlRegisterType<CLanguuage>("Test.Com", 1, 0, "ZH"); //将C++类CLanguuage注册到QML

    同样,注册一个对象对qml,也很简单,直接代码

     QQmlApplicationEngine* engine = new QQmlApplicationEngine(); 
     m_pRoot->rootContext()->setContextProperty("myLanguage", this); //将C++对象作为属性注册到QML

      其实说来说去,都很简单,下面是Demo代码,看起来很直观:

    clanguage.h

    #ifndef CLANGUUAGE_H
    #define CLANGUUAGE_H
    
    #include <QObject>
    #include <QTranslator>
    #include <QtQml>
    #include <QQmlEngine>
    #include <QDebug>
    #include <QCoreApplication>
    #include <QQmlApplicationEngine>
    #include <QString>
    
    class CLanguuage : public QObject
    {
        Q_OBJECT
    public:
        typedef enum
        {
            LANGUAGE_CH,
            LANGUAGE_EN,
            LANHUAGE_NUM,
        }LANGUAGE_TYPE;
        Q_ENUMS(LANGUAGE_TYPE) //注册枚举到QML
    
        explicit CLanguuage(QObject *parent = 0);
        explicit CLanguuage(QQmlEngine* engine, QObject *parent = 0);
        ~CLanguuage();
    
        Q_PROPERTY(QString strTag READ getStrTag  NOTIFY strTagChanged) //注册有个属性到QML,Q_PROPERTY有多个参数,我们只说我们常用参数
        Q_INVOKABLE void requestChangedLanguage(LANGUAGE_TYPE type);    //注册一个方法到QMl
    
        QString getStrTag(void);
    signals:
        void strTagChanged(void);
    public slots:
    
    private:
        QQmlEngine*         m_pRoot;
        QTranslator*        m_tran;
    };
    
    #endif // CLANGUUAGE_H

    clanguage.cpp

    #include "clanguage.h"
    
    CLanguuage::CLanguuage(QObject *parent) :
        QObject(parent)
      ,m_pRoot(NULL)
    {
        m_tran = new QTranslator();
        m_pRoot->rootContext()->setContextProperty("myLanguage", this); //将C++对象作为属性注册到QML
    }
    
    CLanguuage::CLanguuage(QQmlEngine* engine, QObject *parent) :
        QObject(parent)
      ,m_pRoot(engine)
    {
        m_tran = new QTranslator();
        m_pRoot->rootContext()->setContextProperty("myLanguage", this); //将C++对象作为属性注册到QML
    }
    
    CLanguuage::~CLanguuage()
    {
        if(NULL != m_tran)
        {
            delete m_tran;
            m_tran = NULL;
        }
    }
    
    void CLanguuage::requestChangedLanguage(LANGUAGE_TYPE type)
    {
        qDebug()<<" [zhaohui] void CLanguuage::requestChangedLanguage() type = "<<type;
        QString strPath;
        switch(type)
        {
        case CLanguuage::LANGUAGE_CH:
            strPath = "language_ch.qm";
            break;
        case CLanguuage::LANGUAGE_EN:
            strPath = "language_en.qm";
            break;
        default:
            strPath = "language_en.qm";
            break;
        }
    
        if(NULL != m_tran)
        {
            bool ret = false;
            qDebug()<<" void CLanguuage::requestChangedLanguage() strPath = "<<strPath;
            ret = m_tran->load(strPath);
    
            qDebug()<<" void CLanguuage::requestChangedLanguage() A ret = "<<ret;
            ret = false;
            ret = QCoreApplication::installTranslator(m_tran);
            emit strTagChanged();
            qDebug()<<" void CLanguuage::requestChangedLanguage() B ret = "<<ret;
        }
    }
    
    QString CLanguuage::getStrTag(void)
    {
        return "";
    }

    main.cpp

    #include <QGuiApplication>
    #include "clanguage.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine* engine = new QQmlApplicationEngine();
        qmlRegisterType<CLanguuage>("Test.Com", 1, 0, "ZH"); //将C++类CLanguuage注册到QML
        CLanguuage lang(engine);
        lang.requestChangedLanguage(CLanguuage::LANGUAGE_CH );
        engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        return app.exec();
    }

    main.qml

    import QtQuick 2.3
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.2
    import Test.Com 1.0
    
    Window {
        visible: true
         440
        height: 360
      Button
      {
         id:chineseBtn
         220
         height:30
         text:qsTrId("CON_TXT002")+myLanguage.strTag
         onClicked:
         {
            myLanguage.requestChangedLanguage(ZH.LANGUAGE_CN)//qml中访问C++方法
            console.log(" zh chinese button clicked")
         }
      }
    
      Button
      {
          id:englishBtn
          x:220
          220
          height:30
          text:qsTrId("CON_TXT003")+myLanguage.strTag
          onClicked:
          {
              myLanguage.requestChangedLanguage(ZH.LANGUAGE_EN)//qml中访问C++枚举
              console.log(" zh english button clicked.")
          }
      }
    
    
      Text {
          font.pixelSize: 24
          text: qsTrId("CON_TXT001")+myLanguage.strTag//qml中访问C++属性
          color: "#6e16e0"
          anchors.centerIn: parent
      }
    }

      上面代码在Qt5.6.2和Qt5.3.2上运行OK,但是有几个需要注意的地方:
    1)上面代码运行是没有问题的,这个Demo是做的一个跨平台(window/linux)的多语言的Demo,要实现中文切换还需要几个.ts和.qm文件,具体将在下一篇笔记中详细描述。

    2)本文仅实现如何讲C++注册到QML,怎么样在C++中访问QML对象,这个可以自己百度下,也很简单,但从项目维护性角度看,一般不建议既可以在C++中访问QML对象,同时又可以在QML中访问C++。建议仅仅在QML中访问C++就可以了,这样其实完全可以满足项大多数项目需求。 

      

  • 相关阅读:
    wireshark1
    攻防世界Crypto高手进阶区部分Writeup
    flag_in_your_hand1
    扩展GridView之添加单选列
    C#关于日期月天数和一年有多少周及某年某周时间段的计算
    C# 开发和使用中的32个技巧
    TSQL编程的全局变量
    计算当前月底天数
    存储过程编写经验和优化措施
    ASP.NET 程序中常用的三十三种代码
  • 原文地址:https://www.cnblogs.com/huiz/p/8120614.html
Copyright © 2011-2022 走看看