详解如何在 QML 中调用 C++ 中的内容

一只小鹿
一只小鹿
发布时间:2026-10-15| 5人浏览过
原创

在 Qt 开发中,经常需要在 QML 界面中访问 C++ 定义的逻辑或数据。核心方法是使用 QQmlContext 的 setContextProperty 将 C++ 对象或值注入引擎上下文。本文将基于 Qt5.12 环境,演示如何传递基本数据类型以及如何通过 QObject 派生类、Q_INVOKABLE 方法和信号槽机制实现 QML 对 C++ 功能的动态调用。

环境与前置条件

本教程基于以下环境进行验证:

  • 操作系统/IDE:Windows (Visual Studio 2017) x64
  • 框架版本:Qt 5.12

核心 API 为 QQmlContext::setContextProperty,它支持两种赋值方式:设置基本兼容类型或设置 QObject* 指针。前者仅用于静态数据显示,后者可用于触发 C++ 逻辑和响应信号。

第1步:在 QML 中引用 C++ 基本类型数据

如果仅需在 QML 中显示固定的 C++ 变量值,可以直接将该变量添加到引擎上下文中。

操作入口:C++ 应用程序入口文件(如 main.cpp)。

具体动作:

  1. 创建 QQmlEngine 实例。
  2. 准备需要共享的数据对象(如 QDateTime)。
  3. 调用 engine.rootContext()->setContextProperty("name", &value) 将其注册到全局上下文。
// main.cpp
#include <QDateTime>
#include <QQmlEngine>

void main() {
    // ... 其他初始化代码 ...
    QQmlEngine engine;
    
    // 1. 获取当前时间
    QDateTime dateTime = QDateTime::currentDateTime();
    
    // 2. 将变量名 "dateTime" 绑定到 cpp 变量地址
    engine.rootContext()->setContextProperty("dateTime", &dateTime);
    
    // ... 加载 QML 文件 ...
}

在 QML 中使用:

Rectangle {
    id: window
    Text {
        // 直接引用名称 "dateTime"
        text: dateTime.toString()
    }
}

注意:这种方式获取的是快照数据。如果在 C++ 后续修改了变量值,QML 端不会自动刷新,因为它没有建立对象间的信号连接。

第2步:在 QML 中调用 C++ 对象方法与属性

若需在 QML 中触发 C++ 逻辑(如计算、网络请求)并实时更新界面,需创建一个继承自 QObject 的类,并将其实例指针注入上下文。

1. 定义 C++ 数据类

创建派生自 QObject 的类,必须包含 Q_OBJECT 宏。对于需要在 QML 调用的方法,需标记 Q_INVOKABLE;对于需要通知 QML 变化的数据变动,需定义 signals 和 slots。

// applicationdata.h
#ifndef APPLICATIONDATA_H
#define APPLICATIONDATA_H

#include <QObject>
#include <QDateTime>
#include <QTimer>

class ApplicationData : public QObject
{
    Q_OBJECT

public:
    explicit ApplicationData(QObject *parent = nullptr) : QObject(parent) {
        // 启动定时器模拟数据源更新
        QTimer *timer = new QTimer(this);
        connect(timer, &QTimer::timeout, this, &ApplicationData::slt_timeout);
        timer->start(1000); // 每秒更新一次
    }

    // 声明该方法可被元对象系统调用(QML 可见)
    Q_INVOKABLE QDateTime getCurrentDateTime() const {
        return m_currentDateTime;
    }

signals:
    void sig_dataTimeUpdated();

private slots:
    void slt_timeout() {
        m_currentDateTime = QDateTime::currentDateTime();
        emit sig_dataTimeUpdated(); // 发射信号通知 QML
    }

private:
    QDateTime m_currentDateTime;
};

#endif // APPLICATIONDATA_H

2. 将对象指针注入引擎

在 main.cpp 中实例化该类,并将其指针设置给上下文。

// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "applicationdata.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    
    // 实例化 C++ 业务对象
    ApplicationData data;
    
    // 将实例指针以名字 "currentDateTime" 暴露给 QML
    engine.rootContext()->setContextProperty("currentDateTime", &data);
    
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

3. 在 QML 中接收信号并调用方法

使用 Connections 元素监听 C++ 对象的信号。当信号触发时,调用之前在 C++ 中标记为 Q_INVOKABLE 的方法获取最新数据。

// main.qml
import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("QML Call C++ Demo")

    Text {
        id: name_id
        anchors.centerIn: parent
        font.pixelSize: 24
    }

    // 连接到 C++ 对象 "currentDateTime"
    Connections {
        target: currentDateTime
        
        // 响应 C++ 发出的信号
        onSig_dataTimeUpdated: {
            // 调用 C++ 的 Q_INVOKABLE 方法获取实时数据
            name_id.text = currentDateTime.getCurrentDateTime().toString();
        }
    }
}

通过上述配置,QML 界面将每秒动态刷新由 C++ 后端产生的时间数据。这种模式避免了 UI 线程阻塞,同时实现了前后端逻辑的解耦。

以上就是通过 setContextProperty 实现 QML 调用 C++ 内容的详细内容。这种方法适用于从简单的参数传递到复杂的服务层交互。更多关于 Qt QML 与 C++ 混合编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。