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对象
- 全部代码
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"<
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 第326天
- Shell-Bash变量与运算符
- 逻辑回归的理解与python示例
- Guava|Guava RateLimiter与限流算法
- opencv|opencv C++模板匹配的简单实现
- 我和你之前距离
- CGI,FastCGI,PHP-CGI与PHP-FPM