Qt C++与QML混合编程(2)- QML中使用C++的枚举、结构体、列表类型的函数

原创
2022-12-01
4572
35

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()
        }
    }
}

程序的运行效果如下:

不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:1.QML基础语法