QT|QML与C++混和编程


文章目录

  • QML与C++混和编程
    • 在QML中使用C++类
      • 1、首先在cpp注册QML类型
      • 2、在QML文件中包含自定义QML类型
      • 3、类要继承自Q_OBJECT
      • 4、Q_PROPERTY属性说明
      • 5、Q_INVOKABLE宏
      • 6、自定义属性Q_INVOKABLE宏说明
    • 在C++中使用QML类
      • 1、使用QQmlComponent创建QML对象
    • 全部代码
【QT|QML与C++混和编程】
QML与C++混和编程
在QT编程中界面开发往往是很重要的,界面也是乙方第一观感。 所以它的重要性不言而喻。一开始时我是用贴图来做界面,PPT做界 面是个不错的选择,后来想用QSS来做界面,QSS类似CSS,可以说是 CSS的一个简写版,但是我并没有学的太好,因为我一直想尝试下使 QML来做界面,主要是想法是QML做前端,C++来写后端,这也是现在 QT官方推荐的。硬着头皮学了几天,真的感觉到QML的强大与语言的 简洁高效,在与C++交叉编写时也认识到QT原对象系统的强大。 向万能的Q_OBJECT致敬!

在QML中使用C++类 1、首先在cpp注册QML类型
//qmlRegisterType注册C++类型至QML //arg1:import时模块名 //arg2:主版本号 //arg3:次版本号 //arg4:QML类型名 qmlRegisterType("MyCppObject",1,0,"CppObject");

2、在QML文件中包含自定义QML类型
import MyCppObject 1.0

3、类要继承自Q_OBJECT
4、Q_PROPERTY属性说明
5、Q_INVOKABLE宏
#include class Colors : public QObject { Q_OBJECT//注册属性,使之可以在QML中访问--具体语法请参考其他资料 Q_PROPERTY(QString name READ getName WRITE setName) Q_PROPERTY(int year READ getYear WRITE setYear NOTIFY yearChanged)public: explicit Colors(QObject *parent = nullptr); //通过Q_INVOKABLE宏标记的public函数可以在QML中访问 Q_INVOKABLE void sendSignal(); //功能为发送信号

6、自定义属性Q_INVOKABLE宏说明
Q_PROPERTY(type name READ getFunction [WRITE setFunction] [RESET resetFunction] [NOTIFY notifySignal] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] [USER bool] [CONSTANT] [FINAL]) /* 下面是一些典型的声明属性的示例: Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue) Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation) Q_PROPERTY(QColor barColor READ getBarColor WRITE setBarColor) */ /* Q_PROPERTY(类型名称 读getFunction (写setFunction) (重置resetFunction) (通知notifySignal) (可被识别的bool) (脚本bool) (存储bool) (用户bool) (常量) [最终]) */

在C++中使用QML类 1、使用QQmlComponent创建QML对象
QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/main.qml"))); QObject* object = component.create(); Colors *col = new Colors(); QObject::connect(object, SIGNAL(qmlSignalA()), col, SLOT(cppSlotmy()));

全部代码
//**ColorText.qml** Item { id: root property string colorText //定义一个属性传递给外部 property alias textFont1: text1.font //使用属性别名将内部的属性暴露给外部 signal clicked(string buttonColor)//定义一个信号 信号的第一个字母必须先写//动画持续时间函数 function changeDuration(duration) { animation.duration = duration animation1.duration = duration/10 }Text { id: text1 text: colorText anchors.centerIn: parent Behavior on rotation { NumberAnimation { id: animation duration: 500 } } }Rectangle { id: colorRect width: 20 * 2 height: width //radius: 20 border.color: "green"//锚点在text1的右边,距离为10,以text1的垂直剧中 anchors.left: text1.right anchors.leftMargin: 10 anchors.verticalCenter: text1.verticalCenter//定义一个默认是的行为动作 Behavior on width { NumberAnimation { id: animation1 duration: 50 } }MouseArea { anchors.fill: parent onClicked: { console.debug("colorRect: ", parent.border.color) text1.rotation += 360 text1.color = parent.border.color root.clicked(parent.border.color)//触发自定义的信号 并传入参数 }hoverEnabled: true onEntered: { parent.width = 32 parent.color = "black" } onExited: { parent.width = 40 parent.color = "white" } }Rectangle { width: 12 * 2 height: width radius: 12 color: parent.border.color anchors.centerIn: parent } }Rectangle { id: colorRect2 width: 20 * 2 height: width radius: 20 border.color: "red"//锚点在text1的右边,距离为10,以text1的垂直剧中 anchors.bottom: text1.top anchors.bottomMargin: 10 anchors.horizontalCenter: text1.horizontalCenterMouseArea { anchors.fill: parent onClicked: { console.debug("colorRect: ", parent.border.color) text1.rotation += 360 text1.color = parent.border.color root.clicked(parent.border.color) }hoverEnabled: true onEntered: { parent.width = 32 parent.color = "black" } onExited: { parent.width = 40 parent.color = "white" } }Rectangle { width: 12 * 2 height: width radius: 12 color: parent.border.color anchors.centerIn: parent } }Rectangle { id: colorRect3 width: 20 * 2 height: width radius: 20 border.color: "blue"//锚点在text1的右边,距离为10,以text1的垂直剧中 anchors.right:text1.left anchors.rightMargin: 10 anchors.verticalCenter: text1.verticalCenterMouseArea { anchors.fill: parentonClicked: { console.debug("colorRect: ", parent.border.color) text1.rotation += 360 text1.color = parent.border.color root.clicked(parent.border.color) }hoverEnabled: true onEntered: { parent.width = 32 parent.color = "black" } onExited: { parent.width = 40 parent.color = "white" } }Rectangle { width: 12 * 2 height: width radius: 12 color: parent.border.color anchors.centerIn: parent } } }

import QtQuick 2.12 import QtQuick.Window 2.12 import MyCppObject 1.0Window { id: root visible: true width: 640 height: 480 title: qsTr("Hello World")signal qmlSignalA() signal qmlSignalB(string str,int value)Image { id: backImg source: "qrc:/img/press.png" width: parent.width height: parent.height anchors.bottom: parent.bottom fillMode: Image.PreserveAspectFit // 填充模式;缩放时保持比例 }ColorText { anchors.centerIn: parent onClicked: { colorText = qsTr("我爱你!")console.log("colorButton: ", buttonColor) var value = https://www.it610.com/article/buttonColor switch (value) { case"#ff0000": backImg.source = "qrc:/img/ok.jpg" changeDuration(2000) break case "#0000ff": backImg.source = "qrc:/img/press.png" changeDuration(1000) break default: changeDuration(500) backImg.source = "qrc:/img/bg1.png" } } }MouseArea { anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton //测试从点击开始 //左键--Cpp发射信号 //右键--Qml发射信号 onClicked: { if(mouse.button===Qt.LeftButton){ console.log('----clicked left button') cpp_obj.name="gongjianbo" cpp_obj.year=1992 cpp_obj.sendSignal() //调用Q_INVOKABLE宏标记的函数 }else{ console.log('----clicked right button') root.qmlSignalA() root.qmlSignalB('0000',9999) } } }//作为一个QML对象 CppObject{ id:cpp_obj //也可以像原生QML对象一样操作 property int counts: 0 //onYearChanged: { //counts++ //console.log('qml name changed process') //} //onCountsChanged: { //console.log('qml counts changed process') //} }Component.onCompleted: { //关联信号与信号处理函数的方式同QML中的类型 //cpp object connect qml object cpp_obj.onCppSignalA.connect(function(){console.log('qml signal a process')}) cpp_obj.onCppSignalB.connect(processB) //qml object connect cpp object root.onQmlSignalA.connect(cpp_obj.cppSlotA) root.onQmlSignalB.connect(cpp_obj.cppSlotB) }function processB(str,value) { console.log('qml signal b process',str,value) }}/*##^## Designer { D{i:1; anchors_height:78; anchors_width:172; anchors_x:274; anchors_y:584}D{i:2; anchors_height:578; anchors_width:308; anchors_x:64; anchors_y:390} } ##^##*/

#ifndef COLORS_H #define COLORS_H#include class Colors : public QObject { Q_OBJECT//注册属性,使之可以在QML中访问--具体语法请参考其他资料 Q_PROPERTY(QString name READ getName WRITE setName) Q_PROPERTY(int year READ getYear WRITE setYear NOTIFY yearChanged)public: explicit Colors(QObject *parent = nullptr); //通过Q_INVOKABLE宏标记的public函数可以在QML中访问 Q_INVOKABLE void sendSignal(); //功能为发送信号//给类属性添加访问方法--myName void setName(const QString &name); QString getName() const; //给类属性添加访问方法--myYear void setYear(int year); int getYear() const; signals: //信号可以在QML中访问 void cppSignalA(); //一个无参信号 void cppSignalB(const QString &str,int value); //一个带参数信号 void yearChanged(int year); public slots: //public槽函数可以在QML中访问 void cppSlotA(); //一个无参槽函数 void cppSlotmy(); //一个无参信号 void cppSlotB(const QString &str,int value); //一个带参数槽函数private: //类的属性 QString myName; int myYear; }; #endif // COLORS_H

#include #include #include "colors.h" #include "QDebug" #include "QQuickView" #include "QObject" #include #include #include #include #include "QQmlApplicationEngine"#define cout qDebug()<< "[" <<__FILE__ <<":"<<__FUNCTION__<<":"<<__LINE__ <<"]" #if _MSC_VER >= 1600 #pragma execution_character_set("utf-8") #endifint main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); //qmlRegisterType注册C++类型至QML //arg1:import时模块名 //arg2:主版本号 //arg3:次版本号 //arg4:QML类型名 qmlRegisterType("MyCppObject",1,0,"CppObject"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); QQuickView view(QUrl("qrc:/main.qml")); view.show(); QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/main.qml"))); QObject* object = component.create(); Colors *col = new Colors(); QObject::connect(object, SIGNAL(qmlSignalA()), col, SLOT(cppSlotmy())); return app.exec(); }

#include "colors.h" #include Colors::Colors(QObject *parent) : QObject(parent) {}void Colors::sendSignal() { //测试用,调用该函数后发送信号 qDebug()<<"cpp sendSignal method"; emit cppSignalA(); emit cppSignalB(myName,myYear); }void Colors::setName(const QString &name) { qDebug()<<"cpp setName"<

    推荐阅读