在现代软件开发中,图形用户界面(GUI)是用户与程序交互的重要组成部分。Qt框架提供了一种强大的方式来构建跨平台的GUI应用程序,其中QML(Qt Meta-Object Language)和C++的交互是一个重要的主题。本篇博文将深入探讨如何在QML中创建和操作C++对象,实现双向的交互。
在Qt中,任何QML代码都可以访问QObject派生类实例的属性、方法和信号。以下是一个简单的C++类CppObject,演示了如何在QML中创建并操作该类的对象。
C++类定义(CppObject.h)
cpp
Copy code
#ifndef CPPOBJECT_H
#define CPPOBJECT_H
#include <QObject>
class CppObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
Q_PROPERTY(int year READ getYear WRITE setYear NOTIFY yearChanged)
public:
explicit CppObject(QObject *parent = nullptr);
Q_INVOKABLE void sendSignal();
void setName(const QString &name);
QString getName() const;
void setYear(int year);
int getYear() const;
signals:
void cppSignalA();
void cppSignalB(const QString &str, int value);
void nameChanged(const QString name);
void yearChanged(int year);
public slots:
void cppSlotA();
void cppSlotB(const QString &str, int value);
private:
QString myName;
int myYear;
};
#endif // CPPOBJECT_H
C++类实现(CppObject.cpp)
#include "CppObject.h"
#include <QDebug>
CppObject::CppObject(QObject *parent)
: QObject(parent),
myName("none"),
myYear(0)
{
}
void CppObject::sendSignal()
{
qDebug() << "CppObject::sendSignal";
emit cppSignalA();
emit cppSignalB(myName, myYear);
}
// ...(其他成员函数实现)
主函数及QML注册(main.cpp)
cpp
Copy code
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "CppObject.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
//qmlRegisterType注册C++类型至QML
//arg1:import时模块名
//arg2:主版本号
//arg3:次版本号
//arg4:QML类型名 (import MyCppObject 1.0)
qmlRegisterType<CppObject>("MyCppObject", 1, 0, "CppObject");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
QML文件(main.qml)
import QtQuick 2.9
import QtQuick.Window 2.9
import MyCppObject 1.0
Window {
id: root
visible: true
width: 500
height: 300
title: qsTr("QML调用Cpp对象:by 龚建波1992")
color: "green"
// ...(鼠标点击区域及其他组件)
CppObject {
id: cpp_obj
property int counts: 0
onYearChanged: {
counts++
console.log('qml onYearChanged', counts)
}
onCountsChanged: {
console.log('qml onCountsChanged', counts)
}
}
// ...(信号关联及其他操作)
}
在上述代码中,我们创建了一个名为CppObject的C++类,通过qmlRegisterType注册到QML中。在QML文件中,我们可以像操作原生QML对象一样创建和使用CppObject的实例,通过属性、方法和信号进行交互。
在QML文件中,我们可以通过信号和槽的方式实现QML与C++的双向交互。以下是在QML中与CppObject进行交互的示例:
// ...(在main.qml中的其他代码)
Component.onCompleted: {
cpp_obj.onCppSignalA.connect(() => console.log('qml signalA process'))
cpp_obj.onCppSignalB.connect(processB)
root.onQmlSignalA.connect(cpp_obj.cppSlotA)
root.onQmlSignalB.connect(cpp_obj.cppSlotB)
}
// ...(在main.qml中的其他代码)
function processB(str, value) {
console.log('qml function processB', str, value)
}
通过上述代码,我们成功地将C++对象的信号与QML中的函数关联,同时也将QML对象的信号与C++中的槽函数关联,实现了跨语言的交互。
通过本篇博文的介绍,你已经了解了如何在Qt中使用QML与C++进行交互。这种方式使得开发人员可以在GUI应用程序中更灵活地利用QML的声明性语法和C++的底层逻辑,提高了开发效率和代码可维护性。希望这篇博文对你理解Qt中的QML与C++交互有所帮助。