1. 程式人生 > >Qt C++與QML混合程式設計(2)- QML中使用C++的列舉、結構體、列表型別的函式

Qt C++與QML混合程式設計(2)- QML中使用C++的列舉、結構體、列表型別的函式

C++中返回函式返回的列舉型別、結構體型別、列表型別的函式是不能直接作為QML使用的。下面介紹C++中使用這些型別作為返回值的函式使用。

1. 使用列舉型別

C++的列舉型別如果要在QML中使用,需要在使用Q_ENUMS去修飾這個列舉型別。

#include <QObject>
#include <QVariant>
#include <QVariantMap>
#include <QVariantList>
class MixCppDemo : public QObject
{
    Q_OBJECT
    Q_ENUMS(SkinStyle)
public
: enum SkinStyle { SKIN_DARK_STYLE, SKIN_LIGHT_STYLE }; public: MixCppDemo(QObject *parent = nullptr); ~MixCppDemo(); Q_INVOKABLE void setCurrentSkinStyle(SkinStyle style); Q_INVOKABLE SkinStyle getCurrentSkinStyle(void); private: SkinStyle m_CurrentSkinStyle; }

2. 使用結構體型別

如果QML不能使用結構體,必須將結構體型別轉換為QVariantMapQVariant,下面只貼出了關鍵程式碼

#include <QObject>
#include <QVariant>
#include <QVariantMap>
#include <QVariantList>

class MixCppDemo : public QObject
{
    Q_OBJECT

public:
    struct WeatherInfo
    {
        float tmp;              // 溫度
int day_code; // 白天天氣程式碼 QString day_text; // 白天天氣情況 int night_code; // 夜間天氣程式碼 QString night_text; // 夜間天氣情況 }; public: MixCppDemo(QObject *parent = nullptr); ~MixCppDemo(); // 獲取天氣資訊 Q_INVOKABLE QVariantMap getCurrentWeatherInfo(void); private: // 天氣資訊 WeatherInfo m_WeatherInfo; }; // 獲取天氣資訊 QVariantMap MixCppDemo::getCurrentWeatherInfo(void) { QVariantMap map; map.clear(); map.insert("tmp", m_WeatherInfo.tmp); map.insert("day_code", m_WeatherInfo.day_code); map.insert("day_text", m_WeatherInfo.day_text); map.insert("night_code", m_WeatherInfo.night_code); map.insert("night_text", m_WeatherInfo.night_text); return map; }

3. 使用列表型別

同結構體型別相同,需要將列表轉變為QVariantList型別,下面僅列出關鍵的程式碼

// 獲取城市列表
Q_INVOKABLE QVariantList getCityNameList(void);

// 獲取城市列表
QVariantList MixCppDemo::getCityNameList(void)
{
    QVariantList varList;
    varList.clear();

    for (int i=0; i<m_CityNameList.count(); ++i)
    {
        varList.push_back(m_CityNameList.at(i));
    }

    return varList;
}

下面是程式的完成程式碼:
標頭檔案,MixCppDemo.h

#ifndef MIX_CPPDEMO_H
#define MIX_CPPDEMO_H

#include <QObject>
#include <QVariant>
#include <QVariantMap>
#include <QVariantList>

class MixCppDemo : public QObject
{
    Q_OBJECT
    Q_ENUMS(SkinStyle)

public:
    enum SkinStyle
    {
       SKIN_DARK_STYLE,
       SKIN_LIGHT_STYLE
    };

    struct WeatherInfo
    {
        float tmp;              // 溫度
        int day_code;           // 白天天氣程式碼
        QString day_text;       // 白天天氣情況
        int night_code;         // 夜間天氣程式碼
        QString night_text;     // 夜間天氣情況
    };

public:
    MixCppDemo(QObject *parent = nullptr);
    ~MixCppDemo();

    Q_INVOKABLE void setCurrentSkinStyle(SkinStyle style);
    Q_INVOKABLE SkinStyle getCurrentSkinStyle(void);

    // 獲取天氣資訊
    Q_INVOKABLE QVariantMap getCurrentWeatherInfo(void);
    // 獲取城市列表
    Q_INVOKABLE QVariantList getCityNameList(void);

private:
    SkinStyle m_CurrentSkinStyle;
    // 天氣資訊
    WeatherInfo m_WeatherInfo;
    // 城市列表
    QList<QString> m_CityNameList;
};

#endif

原始檔,MixCppDemo.cpp

#include "MixCppDemo.h"

MixCppDemo::MixCppDemo(QObject *parent)
    :QObject(parent)
{
    m_CurrentSkinStyle = SKIN_LIGHT_STYLE;
    m_WeatherInfo.tmp = 23;
    m_WeatherInfo.day_code = 100;
    m_WeatherInfo.day_text = "晴";
    m_WeatherInfo.night_code = 200;
    m_WeatherInfo.night_text = "小雨";
    m_CityNameList.clear();
    m_CityNameList << "北京" << "天津" << "上海" << "大連";
}

MixCppDemo::~MixCppDemo()
{

}

void MixCppDemo::setCurrentSkinStyle(SkinStyle style)
{
    m_CurrentSkinStyle = style;
}

MixCppDemo::SkinStyle MixCppDemo::getCurrentSkinStyle(void)
{
    return m_CurrentSkinStyle;
}

// 獲取天氣資訊
QVariantMap MixCppDemo::getCurrentWeatherInfo(void)
{
    QVariantMap map;
    map.clear();

    map.insert("tmp", m_WeatherInfo.tmp);
    map.insert("day_code", m_WeatherInfo.day_code);
    map.insert("day_text", m_WeatherInfo.day_text);
    map.insert("night_code", m_WeatherInfo.night_code);
    map.insert("night_text", m_WeatherInfo.night_text);

    return map;
}

// 獲取城市列表
QVariantList MixCppDemo::getCityNameList(void)
{
    QVariantList varList;
    varList.clear();

    for (int i=0; i<m_CityNameList.count(); ++i)
    {
        varList.push_back(m_CityNameList.at(i));
    }

    return varList;
}

main.cpp

#include <QApplication>
#include <QFile>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include "Demos/MixCppDemo.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFile nFile("./styles/DarkStyle.css");
    if (nFile.open(QFile::ReadOnly))
    {
        QString styleSheetString = nFile.readAll().data();
        a.setStyleSheet(styleSheetString);
        nFile.close();
    }

    qmlRegisterType<MixCppDemo>("Demos.MixCppDemo", 1, 0, "MixCppDemo");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/QML/main.qml")));
    if (engine.rootObjects().isEmpty())
            return -1;

    return a.exec();
}

main.qml

import QtQuick 2.0
import QtQuick.Window 2.0
import Demos.MixCppDemo 1.0
import QtQuick.Controls 1.4

Window {
    width: 800
    height: 600
    visible: true

    Rectangle {
        id: rootRect
        anchors.fill: parent

        function changeCurrentStyle(){
            if (minxCppDemo.getCurrentSkinStyle() === MixCppDemo.SKIN_DARK_STYLE)
                minxCppDemo.setCurrentSkinStyle(MixCppDemo.SKIN_LIGHT_STYLE)
            else
                minxCppDemo.setCurrentSkinStyle(MixCppDemo.SKIN_DARK_STYLE)

            if (minxCppDemo.getCurrentSkinStyle() === MixCppDemo.SKIN_LIGHT_STYLE){
                rootRect.color = '#5BADCC'
                infoText.color = '#202020'
            }
            else{
                rootRect.color = '#202020'
                infoText.color = '#AAAAAA'
            }
        }

        MixCppDemo {
            id: minxCppDemo
        }

        // 顯示資訊文字
        Text {
            id: infoText
            text: ''
            font.pixelSize: 20
            color: '#202020'
            anchors.centerIn: parent

            Component.onCompleted: {
                var textString = ''
                // 顯示天氣資訊
                var currentWeatherInfo = minxCppDemo.getCurrentWeatherInfo()
                textString += '溫度:' + currentWeatherInfo.tmp.toString() + '\n';
                textString += '白天天氣程式碼: ' + currentWeatherInfo.day_code.toString() + '\n'
                textString += '白天天氣情況: ' + currentWeatherInfo.day_text + '\n'
                textString += '夜間天氣程式碼: ' + currentWeatherInfo.night_code.toString() + '\n'
                textString += '夜間天氣情況: ' + currentWeatherInfo.night_text + '\n\n'

                // 顯示城市資訊
                var cityList = minxCppDemo.getCityNameList()
                textString += '城市列表:'
                for (var i=0; i<cityList.length; ++i)
                    textString += cityList[i] + ' '

                infoText.text = textString
            }
        }

        Button {
            id: changeButton
            text: 'ChangeStyle'
            anchors.right: parent.right
            anchors.rightMargin: 10
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 10

            onClicked: {
                rootRect.changeCurrentStyle()
            }
        }

        Component.onCompleted: {
            rootRect.changeCurrentStyle()
        }
    }
}

程式的執行效果如下:
軟體執行效果