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

本章主要介绍一下在QML中使用C++的类的两种方法


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 Quick有基本了解的读者。首先回答一个比较常会被问到的问题:什么是QML,它与Quick的关系是什么? Qt Quick是Qt User Interface Creation Kit的缩写,而QMLQt Quick最重要的组成部分,Qt Quick结合了如下技术: 组件集合,其大部分是关于图形界面的 基于JavaScript陈述性语言:QMLQt Meta-Object Language的缩写) 用于管理组件并与组件交互的C++ API - QtDeclarative模块 言归正传:通过Qt Creator,我们可以轻松生成一个Qt Quick的应用工程,从而为QML生成应用程序框架。具体操作详见:创建qt quick (qml) 应用程序。 C++QML的交互是通过注册C++对象给QML环境得以实现的: 在C++实现,非可视化的型别均为QObject的子,可视化的型均为QDeclarativeItem的子。注意:QDeclarativeItem等同于QML的Item。 如果用户想要定义自己的型别,做法如下: 在C++,实现派生于QObject或QDeclarativeItem的子,它是新定义item的实体对象; 在C++,将1实现的新item型注册给QML; 在QML,导入含有1定义的新item的模块; 在QML,向使用标准的item一样使用新定义的item 现举例说明,我们现尝试使用Qt C++实现的MyButton对象(如下qml代码),它有自己的属性、方法以及信号的handler。用法如下(它与使用其它标准的QML item一样),所需要做的是 需要导入包含MyButton的对应模块名称及其版本“MyItems 1.0 ”。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值