0
点赞
收藏
分享

微信扫一扫

C++和QML混合编程


QML中使用C++对象

官方文档:​​http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html​​

创建一个新类型

创建C++对象

piechart.h

#ifndef PIECHART_H
#define PIECHART_H
#include <QtQuick/QQuickPaintedItem>
#include <QColor>
#include <QPainter>

class PieChart : public QQuickPaintedItem
//为了使用信号和槽系统和QML交互
Q_OBJECT
//Q_PROPERTY是QObject的宏定义,具体的含义可以去QObject中去查看
//这里的意思是PieChart有一个属性name,获取属性的函数名是name,设置属性的函数名是setName
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QColor color READ color WRITE setColor)
public:
PieChart(QQuickItem *parent=0);
QString name() const;
void setName(const QString &name);
QColor color() const;
void setColor(const QColor &color);
void paint(QPainter *painter);
private:
QString myName;
QColor myColor;
};

#endif // PIECHART_H

piechart.cpp

#include "piechart.h"
#include <QPainter>

PieChart::PieChart(QQuickItem *parent)
:QQuickPaintedItem(parent)
{

}
QString PieChart::name() const
{
return myName;
}
void PieChart::setName(const QString &name)
{
myName = name;
}
QColor PieChart::color() const
{
return myColor;
}
void PieChart::setColor(const QColor &color)
{
myColor = color;
}
void PieChart::paint(QPainter *painter)
{
QPen pen(myColor, 2);
painter->setPen(pen);
painter->setRenderHints(QPainter::Antialiasing, true);
painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16);
}

将C++对象注册到QML中

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <piechart.h>

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
//4个参数的含义是,包名,主版本号,此版本好,QML类型名
qmlRegisterType<PieChart>("Charts",1,0,"PieChart");
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return

在QML中使用C++注册到QML中的对象

main.qml

import QtQuick 2.7
import QtQuick.Controls 1.4
import Charts 1.0

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")

PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
name: "A simple pie chart"
//这里自动转换为C++中的QColor类型
color: "red"
}

Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: aPieChart.name
}
}

C++和QML混合编程_i++


QML和C++数据类型转换

​​http://doc.qt.io/qt-5/qtqml-cppintegration-data.html​​

连接C++的方法和信号

点击控件,图形消失,并且在QML中处理chartCleared信号
piechart.h增加的代码

public:
//将这个方法注册到元对象系统中,这样QML就能直接调用这个方法
Q_INVOKABLE void clearChart();
signals:
void

piechart.cpp增加的代码

void PieChart::clearChart()
{
setColor(QColor(Qt::transparent));
update();
emit chartCleared();
}

main.qml的代码变为如下

import QtQuick 2.7
import QtQuick.Controls 1.4
import Charts 1.0

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")

PieChart {
id: aPieChart
anchors.centerIn: parent
width: 100; height: 100
color: "red"
onChartCleared: console.log("The chart has been cleared")
}

MouseArea {
anchors.fill: parent
onClicked: aPieChart.clearChart()
}

Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: "Click anywhere to clear the chart"

属性绑定

2个图形A和B,B的颜色就是A的颜色,点击整个控件,A的颜色变化,如果属性不绑定,就只有A的颜色发生变化,因为B不知道A的颜色发生变化,属性绑定后A和B的颜色会一起变化
piechart.h增加和修改的代码

//当color这个属性发生变化时,发送colorChanged这个信号,更新这个属性
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY

piechart.cpp修改的代码如下

void PieChart::setColor(const QColor &color)
{
if (color != myColor)
{
myColor = color;
update(); // repaint with the new color
emit

main.qml

import QtQuick 2.7
import QtQuick.Controls 1.4
import Charts 1.0

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Row {
anchors.centerIn: parent
spacing: 20

PieChart {
id: chartA
width: 100; height: 100
color: "red"
}

PieChart {
id: chartB
width: 100; height: 100
color: chartA.color
}
}

MouseArea {
anchors.fill: parent
onClicked: { chartA.color = "blue" }
}

Text {
anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter; bottomMargin: 20 }
text: "Click anywhere to change the chart color"

C++和QML混合编程_#include_02

使用自定义属性类型

C++中使用QML对象

官方文档:​​http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html​​

从C++中加载QML对象

按照官方文档写一直不对,也不知道问题出在哪里,就按照Qt Quick核心编程上的例子写了
通过C++改变QML文档中Item的宽度
main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

ApplicationWindow {
objectName: "window"
visible: true
width: 640
height: 480
title: qsTr("Hello World")

Item {
objectName: "item"
width: 100
height: 100

Rectangle {
anchors.fill: parent
border.width: 1

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QList>

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
QList<QObject*> rootObjects = engine.rootObjects();
int count = rootObjects.size();
QObject *root = NULL;
for(int i=0; i<count; i++)
{
if(rootObjects.at(i)->objectName() == "window")
{
root = rootObjects.at(i);
break;
}
}
QObject *item = root->findChild<QObject*>("item");
//判断是否是空指针
if(item)
{
item->setProperty("width","200");
}
return

QML中定义的是正方形,显示出来是长方形

C++和QML混合编程_c++_03

从C++获取QML对象的成员

属性

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0


ApplicationWindow {
objectName: "window"
visible: true
width: 640
height: 480
property int someNumber: 100

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlProperty>
#include <QList>
#include <QDebug>

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
QList<QObject*> rootObjects = engine.rootObjects();
int count = rootObjects.size();
QObject *root = NULL;
for(int i=0; i<count; i++)
{
if(rootObjects.at(i)->objectName() == "window")
{
root = rootObjects.at(i);
break;
}
}
qDebug() << "Property value:" << QQmlProperty::read(root, "someNumber").toInt();
QQmlProperty::write(root, "someNumber", 5000);

qDebug() << "Property value:" << root->property("someNumber").toInt();
root->setProperty("someNumber", 100);
return

C++和QML混合编程_c++_04

调用QML方法

在C++中调用QML中的方法
main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

ApplicationWindow {
objectName: "window"
visible: true
width: 640
height: 480
title: qsTr("Hello World")

function myQmlFunction(msg) {
console.log("Got Message",msg)
return "some return value"

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QDebug>
#include <QMetaObject>

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));

QList<QObject*> rootObjects = engine.rootObjects();
int count = rootObjects.size();
QObject *root = NULL;
for(int i=0; i<count; i++)
{
if(rootObjects.at(i)->objectName() == "window")
{
root = rootObjects.at(i);
break;
}
}
QVariant returnedValue;
QVariant msg = "Hello from C++";
//参数含义:被调用对象的指针,方法名字,返回值,参数
QMetaObject::invokeMethod(root, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));

qDebug() << "QML function returned:" << returnedValue.toString();
//这个是运行完毕删除图形界面
delete root;
return

C++和QML混合编程_#include_05

连接QML的信号

在C++中接收QML中发出的信号
myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QDebug>
class MyClass : public QObject
Q_OBJECT
public slots:
void cppSlot(const QString &msg) {
qDebug() << "Called the C++ slot with message:" << msg;
}
};
#endif // MYCLASS_H

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QDebug>
#include <QMetaObject>
#include <myclass.h>
#include <QQuickView>
#include <QQuickItem>

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));

QList<QObject*> rootObjects = engine.rootObjects();
int count = rootObjects.size();
QObject *root = NULL;
for(int i=0; i<count; i++)
{
if(rootObjects.at(i)->objectName() == "window")
{
root = rootObjects.at(i);
break;
}
}
MyClass myClass;
QObject::connect(root, SIGNAL(qmlSignal(QString)),
&myClass, SLOT(cppSlot(QString)));
return

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
objectName:"window"
id: window
visible: true
width: 640
height: 480
title: qsTr("Hello World")

signal qmlSignal(string msg)

MouseArea {
anchors.fill: parent
onClicked: window.qmlSignal("Hello from QML")}
}

C++和QML混合编程_#include_06


举报

相关推荐

0 条评论