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

程序的运行效果如下:
软件运行效果

  • 15
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: QMLQt Meta-Object Language)是一种用于构建用户界面的声明性语言,而C/C++是一种通用的编程语言。QML与C混合编程使用这两种语言结合开发应用程序的一种方式。 在QML,可以使用JavaScript进行逻辑编程和交互操作。而在C/C++,可以进行复杂的计算、算法实现和底层操作。通过将这两种语言结合在一起,可以充分发挥它们各自的优势,提高应用程序的开发效率和性能。 使用QML与C混合编程时,通常会有一些场景需要注意。首先,需要在C/C++编写一些类或者函数,然后在QML进行调用。这就需要进行跨语言的接口和数据传递。通常可以使用Qt提供的机制,如信号与槽(signal and slot)来进行跨语言的通信。 其次,在QML可以使用Qt的各种GUI组件来构建用户界面,而在C/C++则可以处理一些底层的计算和数据操作。例如,可以在C/C++使用Qt的数据结构和算法来处理复杂的数据逻辑,然后将结果传递给QML进行展示。 混合编程还可以提高应用程序的性能。QML的JavaScript运行速度相对较慢,而C/C++则可以通过编译优化和底层操作来提高执行效率。因此,在一些对性能要求较高的场景下,可以将一些计算密集型的任务交给C/C++来处理,提高整体应用程序的性能。 总结来说,QML与C混合编程可以充分发挥两种语言各自的优势,提高应用程序的开发效率、性能和用户体验。通过合理地利用QML和C/C++,可以开发出功能强大、界面美观且性能优异的应用程序。 ### 回答2: QMLQt Meta-Object Language)是一种用于快速构建用户界面的声明性编程语言,而C++是一种通用的编程语言。两者结合进行混合编程可以充分发挥各自的优势。 首先,QML具有直观易懂的语法,适合快速开发用户界面。它采用了类似于CSS的声明式风格,允许开发者通过组件和属性的方式构建用户交互界面。QML可以直接调用C++函数和对象,并通过信号槽机制进行通信,这使得在QML可以方便地使用C++的功能和库。 其次,C++是一种强大的编程语言,具有高效的性能和广泛的应用领域。通过与QML混合编程,我们可以利用C++的能力来处理复杂的业务逻辑和计算任务。例如,使用C++编写性能要求较高的算法,通过C++的多线程处理并发任务等。 混合编程可以通过QMLQt Quick Controls提供更丰富的用户界面控件和样式,通过C++编写的QML插件来实现一些复杂的界面逻辑或业务逻辑。这种结合可以在保持界面的灵活性和用户友好性的同时,实现高效的数据处理和计算。 总结来说,QMLC++混合编程方式可以在开发过程充分利用两者的优势,快速构建用户界面并处理复杂的业务逻辑。这种结合使得开发人员能够更有效地开发出高性能、用户友好的应用程序。 ### 回答3: qml与C混合编程是指在Qt框架,同时使用qml和C语言进行开发的一种方式。qmlQt Quick的一种声明式语言,用于快速构建用户界面,而C语言是一种通用的编程语言,在Qt常用于底层功能的实现。 qml与C混合编程的主要优点是可以充分利用qml的快速开发和灵活性和C语言的强大功能。qml具有直观的语法和简洁的代码风格,能够快速构建出美观且交互性强的用户界面。同时,qml也具有与C++进行无缝集成的能力,可以调用C++类和函数来实现一些高级的功能。而C语言作为一种通用的编程语言,具有底层的硬件控制和高性能的特点,适合用于一些需要高效计算和硬件交互的场景。通过qml与C混合编程,可以实现高效的用户界面和底层功能的结合,提供优秀的用户体验和性能。 在qml与C混合编程时,一般会使用Qt提供的接口和工具来实现qml与C语言的交互。Qt提供了QCoreApplication类和QObject类等接口,用于qml与C语言之间的通信和数据传递。可以通过qml提供的信号与槽机制,与C语言进行交互和传递数据。在qml,可以调用C语言的函数来实现一些底层操作,比如文件读写、网络通信等。而在C语言,可以通过Qt提供的接口,调用qml函数和属性,实现界面的更新和事件的处理。 总之,qml与C混合编程是一种灵活且强大的开发方式,可以充分发挥qml的优势和C语言的功能,实现高效的用户界面和底层功能的结合。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值