Qt C++与QML混合编程(1)- QML中使用C++的类和函数

原创
2022-11-30
4940
1

1. 设置QML的上下文属性

为QML的节点设置上下文属性,在QML文件中可以之间使用这个属性的函数。

QQuickView view;
view.rootContext()->setContextProperty("g_WeatherInterface", g_WeatherInterface);
view.setSource(QUrl("qrc:/QML/main.qml"));
view.resize(1000, 800);
view.show();

这里使用的代码为天气系统的代码,之前使用QWidgets写的界面,现在使用QML改写; 原版的天气系统可见 Qt实战小工具 – 日丽天气V1.0

g_WeatherInterface 为一个单例,它的原型为
#define g_WeatherInterface WeatherInterface::getInstance()

如果要c++中的函数在QML中能够使用,必须在函数前面加上关键字Q_INVOKABLE

// 获取当前控制质量的颜色
Q_INVOKABLE QColor getAirQualityCityColor(void);

getAirQualityCityColor()函数为WeatherInterface类中的成员函数
QML中就可以直接使用函数g_WeatherInterface.getAirQualityCityColor()

QML中相关函数的引用,这里只贴出了相关的代码

Text {
    id: airQuality
    anchors.top: centerText.bottom
    anchors.topMargin: 5
    anchors.horizontalCenter: centerRect.horizontalCenter
    font.pixelSize: 30
    color: '#E6E6E6'
    text: '37 优'

    Component.onCompleted: {
        airQuality.color = g_WeatherInterface.getAirQualityCityColor()
        var airQualityInfo = g_WeatherInterface.getAirQualityCity2()
        airQuality.text = airQualityInfo.aqi.toString() + " " + airQualityInfo.qlty
    }
}

2. 注册QML的类型

注册一个C++的类到QML中使用。使用函数qmlRegisterType注册QML的类型,函数的原型如下:

  • int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
  • uri: 为QML中引用模块的名称。
  • versionMajor: 为主版本号。
  • versionMinor: 为次版本号。
  • qmlName: 为QML中使用得当组件名称。

下面是使用的一个简单示例:

c++中的

#ifndef UICHINACITY_H
#define UICHINACITY_H

#include <QObject>
#include <QMap>
#include <QVariant>
#include <QVariantList>
class UIChinaCity : public QObject
{
    Q_OBJECT

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

    struct CityInfo
    {
        QString cityName;                   // 城市名字
        QList<QString> regionName;          // 城市下的区的名字
    };

    // 获取所有的省份
    QList<QString> getProvinceName(void);
    Q_INVOKABLE QVariantList getProvinceName2(void);
    // 获取某个省下的所有的城市
    QList<QString> getCitysName(QString);
    Q_INVOKABLE QVariantList getCitysName2(QString);
    // 获取某个省下的某个市下的所有的县
    QList<QString> getRegionsName(QString, QString);
    Q_INVOKABLE QVariantList getRegionsName2(QString, QString);

private:
    // 解析城市列表
    void disposeCityList(void);

    QMap<QString, QList<CityInfo>> m_ChinaCityInfo;
    // QList<String> 转换为QVariantList
    QVariantList stringListToVariantList(QList<QString>);
};

#endif

qmlRegisterType<UIChinaCity>("WeatherSystem.ChinaCityInfo", 1, 0, "ChinaCityInfo");

QML中的使用

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import WeatherSystem.ChinaCityInfo 1.0

Window {
    id: changeCityWindow
    visible: false

    width: 500
    height: 200

    Rectangle {
        id: mainRect
        anchors.fill: parent
        color: '#505050'

        Column {
            id: mainColumn
            width: mainRect.width
            height: mainRect.height

            Row {
                id: topRow
                width: mainColumn.width
                //height: mainColumn.height / 3
                spacing: 2

                Rectangle {
                    width: mainColumn.width / 3
                    height: mainColumn.height / 3
                    color: '#505050'
                    Text {
                        anchors.centerIn: parent
                        color: '#FFFFFF'
                        text: '省/直辖市'
                    }
                }

                Rectangle {
                    width: mainColumn.width / 3
                    height: mainColumn.height / 3
                    color: '#505050'
                    Text {
                        anchors.centerIn: parent
                        color: '#FFFFFF'
                        text: '城市/直辖市区'
                    }
                }


                Rectangle {
                    width: mainColumn.width / 3
                    height: mainColumn.height / 3
                    color: '#505050'
                    Text {
                        anchors.centerIn: parent
                        color: '#FFFFFF'
                        text: '区/县'
                    }
                }
            }

            ChinaCityInfo {
                id: chinaCityInfo
            }

            Row {
                id: middleRect
                Rectangle {
                    width: mainColumn.width / 3
                    height: mainColumn.height / 3
                    color: '#505050'

                    ComboBox {
                        id: mainCity
                        anchors.centerIn: parent
                        model: ['北京']

                        Component.onCompleted: {
                            mainCity.model = chinaCityInfo.getProvinceName2()
                        }
                    }
                }

                Rectangle {
                    width: mainColumn.width / 3
                    height: mainColumn.height / 3
                    color: '#505050'

                    ComboBox {
                        anchors.centerIn: parent
                        model: ['昌平']
                    }
                }

                Rectangle {
                    width: mainColumn.width / 3
                    height: mainColumn.height / 3
                    color: '#505050'

                    ComboBox {
                        anchors.centerIn: parent
                        model: []
                    }
                }
            }
        }
    }
}

import WeatherSystem.ChinaCityInfo 1.0 ,导入模块,

ChinaCityInfo {
    id: chinaCityInfo
 }

上面的语句使用c++中的模块,mainCity.model = chinaCityInfo.getProvinceName2()为使用C++中的函数。

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

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