QT: QML调用c++代码

目的

本文简述如何在qml中调用c++代码。通过qml调用c++主要有两种方法:使用qmlRegisterType()与setContextProperty()。下面依次介绍

qmlRegisterType

新建Qt工程后,编辑mainwindow.h如下。程序运行后,会调用 CallMe.hello()函数输出相关信息

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>

class CallMe : public QObject {
   Q_OBJECT
public:
    explicit CallMe (QObject* parent = 0) : QObject(parent) {}

    Q_INVOKABLE void hello() {
        qDebug() << "Hello,World";
    }
};

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};
#endif // MAINWINDOW_H

编辑mainwindow.cpp如下:

#include "mainwindow.h"

#include <QHBoxLayout>
#include <QQmlEngine>
#include <QQuickWidget>
#include <QQmlContext>
#include <QQuickItem>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent) {
    QQmlEngine *engine = new QQmlEngine(this);
    QQuickWidget *view = new QQuickWidget(engine, this);
    setCentralWidget(view);

    view->setSource(QUrl("qrc:/main.qml"));
    view->setResizeMode(QQuickWidget::SizeRootObjectToView);
}

MainWindow::~MainWindow() {
}

编辑main.cpp如下,在main函数的开始将CallMe类注册到QML中,以便在QML中可以创建此类的对象

#include "mainwindow.h"

#include <QApplication>
#include <QDebug>

#include "qqml.h"

int main(int argc, char *argv[]) {
    qmlRegisterType<CallMe>("com.test", 1, 0, "CallMe");

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

编辑main.qml内容如下,main.qml的第三行导入了com.test命名空间,在第8行创建了CallMe的对象,id为callMe。这样在button按下后就可以调用callMe.hello()函数。

import QtQuick 2.0
import QtQuick.Controls 2.12
import com.test 1.0

Rectangle {
    color: "red"

    CallMe {
        id: callMe
    }

    Button {
        text: qsTr("Hello, World")
        anchors.centerIn: parent
        onClicked: callMe.hello()
    }
}

如果顺利的话,运行Demo后点击按钮就可以看到打印输出,表明可以通过QML调用cpp的代码。
在这里插入图片描述

setContextProperty

第二种方法个人感觉要简单点儿,mainwindow.h代码如下,最终会调用MainWindow.hello() 方法,在QT中被标注为一个slot。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>

class MainWindow : public QMainWindow {
    Q_OBJECT

public slots:
    void hello();

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};
#endif // MAINWINDOW_H

mainwindow.cpp代码如下,在构造函数的最后调用setContextProperty()将MainWindow的对象注册为QML中的对象

#include "mainwindow.h"

#include <QHBoxLayout>
#include <QQmlEngine>
#include <QQuickWidget>
#include <QQmlContext>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent) {
    QQmlEngine *engine = new QQmlEngine(this);
    QQuickWidget *view = new QQuickWidget(engine, this);
    setCentralWidget(view);

    view->setSource(QUrl("qrc:/main.qml"));
    view->setResizeMode(QQuickWidget::SizeRootObjectToView);

    view->rootContext()->setContextProperty("mainWindow", this);
}

MainWindow::~MainWindow() {
}

void MainWindow::hello() {
    qDebug() << "Hello, World";
}

main.cpp代码如下:

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

最后看看main.qml调用MainWindow.hello()的过程:

import QtQuick 2.0
import QtQuick.Controls 2.12

Rectangle {
    color: "red"

    Button {
        text: qsTr("Hello, World")
        anchors.centerIn: parent
        onClicked: mainWindow.hello()
    }
}

总结

  • 上述两种方法都可以通过QML调用c++代码。
  • 方法一调用的对象是在QML中创建的(callMe),第二种方法在c++中(mainWindow)。
  • c++中声明的slots方法可以直接被QML调用。

引用

https://stackoverflow.com/questions/9500280/access-c-function-from-qml
https://stackoverflow.com/questions/26399368/calling-c-function-from-qml-code

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值