qml接收c++信号
在qml代码中接收信号时,不需要再写槽函数,直接在目标信号前加on即可。如发送过来的信号为nameChanged(const QString &name),则在qml中这样写即可:
// 针对于类名中
TestData { // qmlRegisterType注册的类名
id: testData;
onNameChanged: {
// 需要执行的操作
console.log("Received the signal: " + name);
}
}
// 针对于实例化后的对象
Connections {
target: testData
onNameChanged: {
// 需要执行的操作
console.log("Received the signal: " + name)
}
}
示例代码如下:
#include <QObject>
#include <QDateTime>
class testObject : public QObject
{
Q_OBJECT
// 注册属性,通过Q_PROPERTY注册到元对象系统
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
public:
testObject(QObject *parent = Q_NULLPTR)
{
};
~testObject() { };
void setName(const QString &name)
{
m_name = name;
emit nameChanged(name);
}
QString getName()
{
return m_name;
}
signals:
void nameChanged(const QString name);
private:
QString m_name = "Initial Text";
};
#include "widget.h"
#include "ui_widget.h"
#include "testObject.h"
#include <QQmlContext>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
qmlRegisterType<testObject>("com.qt.testcomponent", 1, 0, "TestData");
ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
ui->quickWidget->setSource(QUrl("qrc:/main.qml"));
}
Widget::~Widget()
{
delete ui;
}
import QtQuick 2.9
import com.qt.testcomponent 1.0
Item {
visible: true
width: 640
height: 480
Rectangle {
id: bg1;
width: parent.width;
height: 50;
radius: height / 8;
color: "blue";
anchors.top: parent.top;
Text {
id: namer;
text: testData.name;
font.pixelSize: 30
anchors.centerIn: bg1;
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if(mouse.button === Qt.LeftButton){
testData.name = "Mouse Clicked!";
console.log(testData.name);
}
}
}
// 针对于实例化后的对象
Connections {
target: testData
onNameChanged: {
console.log("Received the signal: " + name)
}
}
}
// 针对于类名中
TestData {
id: testData;
onNameChanged: {
console.log("Received the signal: " + name);
}
}
}
c++接收qml信号
(testObject.h并未改变,参照上文即可)
#include "widget.h"
#include "ui_widget.h"
#include "testObject.h"
#include <QQmlContext>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
qmlRegisterType<testObject>("com.qt.testcomponent", 1, 0, "TestData");
ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
ui->quickWidget->setSource(QUrl("qrc:/main.qml"));
// QML使用arg()函数扩展了JavaScript String类型,以支持值替换;
// 与C++集成时,从C++传递到QML的任何QString值都会自动转换为string,反之亦然;
connect((QObject*)ui->quickWidget->rootObject(), SIGNAL(qmlSignal(QString)), this, SLOT(recQmlSignal(QString)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::recQmlSignal(QString text)
{
qDebug() << "Received the qml signal: " + text << endl;
}
import QtQuick 2.9
import com.qt.testcomponent 1.0
Item {
visible: true
width: 640
height: 480
signal qmlSignal(string text)
Rectangle {
id: bg1;
width: parent.width;
height: 50;
radius: height / 8;
color: "blue";
anchors.top: parent.top;
Text {
id: namer;
text: testData.name;
font.pixelSize: 30
anchors.centerIn: bg1;
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if(mouse.button === Qt.LeftButton){
testData.name = "Mouse Clicked!";
qmlSignal(testData.name);
}
}
}
TestData {
id: testData;
}
}
其他
c++调用qml中函数
QMetaObject::invokeMethod((QObject*)ui->quickWidget->rootObject(), "qml中的函数名");
qml中的信号触发qml的函数
Component.onCompleted: // 相当于qml中的构造函数,一般用以初始化
{
qmlSignal.connect(qmlFunction);
}