文章目录
- QML与C++混和编程
- 在QML中使用C++类
- 1、首先在cpp注册QML类型
- 2、在QML文件中包含自定义QML类型
- 3、类要继承自Q_OBJECT
- 4、Q_PROPERTY属性说明
- 5、Q_INVOKABLE宏
- 6、自定义属性Q_INVOKABLE宏说明
- 在C++中使用QML类
- 全部代码
QML与C++混和编程
在QT编程中界面开发往往是很重要的,界面也是乙方第一观感。
所以它的重要性不言而喻。一开始时我是用贴图来做界面,PPT做界
面是个不错的选择,后来想用QSS来做界面,QSS类似CSS,可以说是
CSS的一个简写版,但是我并没有学的太好,因为我一直想尝试下使
QML来做界面,主要是想法是QML做前端,C++来写后端,这也是现在
QT官方推荐的。硬着头皮学了几天,真的感觉到QML的强大与语言的
简洁高效,在与C++交叉编写时也认识到QT原对象系统的强大。
向万能的Q_OBJECT致敬!
在QML中使用C++类
1、首先在cpp注册QML类型
qmlRegisterType<Colors>("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
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 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])
在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.horizontalCenter
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: colorRect3
width: 20 * 2
height: width
radius: 20
border.color: "blue"
//锚点在text1的右边,距离为10,以text1的垂直剧中
anchors.right: text1.left
anchors.rightMargin: 10
anchors.verticalCenter: text1.verticalCenter
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
}
}
}
import QtQuick 2.12
import QtQuick.Window 2.12
import MyCppObject 1.0
Window {
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 = 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)
}
}
#ifndef COLORS_H
#define COLORS_H
#include
class Colors : public QObject
{
Q_OBJECT
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 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 yearChanged(int year);
public slots:
void cppSlotA();
void cppSlotmy();
void cppSlotB(const QString &str,int value);
private:
QString myName;
int myYear;
};
#endif
#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")
#endif
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<Colors>("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"<<name;
myName=name;
}
QString Colors::getName() const
{
qDebug()<<"cpp getName";
return myName;
}
void Colors::setYear(int year)
{
qDebug()<<"cpp setYear"<<year;
if(year!=myYear){
qDebug()<<"cpp emit yearChanged";
myYear=year;
emit yearChanged(myYear);
}
}
int Colors::getYear() const
{
qDebug()<<"cpp getYear";
return myYear;
}
void Colors::cppSlotA()
{
qDebug()<<"cpp slot a";
}
void Colors::cppSlotmy()
{
qDebug()<<"AAAAAAAAAAAAAAAAAAAAAAAAAAA";
}
void Colors::cppSlotB(const QString &str, int value)
{
qDebug()<<"cpp slot b"<<str<<value;
}