一.QML发送信号C++部分响应槽函数
1.首先注册一个响应槽函数的类对象
1.创建一个继承自Qbject类的类
2. 我们需要使他让QML能认识,加入下面两句即可
①包含头文件#include <QtQML>
②在类属性中加入QML_ELEMENT
3.添加槽函数,权限设置为公有的public slots:
4.注册类型 加入 qmlRegisterType<MyObject>("MyObj",1,0,"MyObject");
MyObject 是类名, MyObj是模块名 ,1版本号,0是此版本号,MyObject是类名
5.在qml文件中引入类型模块
注册完成
2.获取QML对象
在main.cpp中 加入下面的代码,要在load函数之后
auto list = engine.rootObjects(); // 获取qml的对象
auto window = list.first(); // 拿到根对象
MyObject* test = new MyObject; // 实例化我们cpp响应槽函数的对象
// 下面链接信号与槽,没啥说的
QObject::connect(window,SIGNAL(getcontentsig(QString)),test,SLOT(CppSlotAccept(QString)));
3.编写QML代码
1.添加信号,添加发送信号的按钮
import QtQuick
import MyObj 1.0
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
objectName: "window"
id:mywindow
signal getcontentsig(string str)
Button{
width:60
height: 60
x:50
y:100
onClicked: {
mywindow.getcontentsig("发送数据");
}
}
}
到这一步就完成了!!
objectName
objectName: "window" 我们每个qml生成的控件都可以拥有自己的objectName
通过以下代码
auto list = engine.rootObjects();
auto objName= list.first()->findChildren<QObject* >("MyRectangle");
//通过这种方法我们可以找到objectname 是MyRectangle控件
二.C++发送信号QML部分响应槽函数
1.创建一个继承自Qbject类的类
2.我们需要使他让QML能认识 ,同上面的方法
3.添加信号
发送信号代码
4.在main函数正常加入注册类型
qmlRegisterType<MyObject>("MyObj",1,0,"MyObject");
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myobject.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyObject* test = new MyObject;
qmlRegisterType<MyObject>("MyObj",1,0,"MyObject"); // 加入这句话
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("TestProject", "Main");
return app.exec();
}
5.在QML中引入模块 import MyObj 1.0
QML部分代码 通过按钮触发func函数,func函数里面发送信号进而触发qml中的槽函数
import QtQuick
import MyObj 1.0
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
objectName: "window"
id:mywindow
function putcontentslot(str)
{
console.log("QML: "+str)
}
Button{
width:60
height: 60
x:50
y:100
onClicked: {
myobj.func()
}
}
MyObject{
id:myobj
}
Connections{
target: myobj
function onCppSig(str)
{
putcontentslot(str)
}
}
}
完成了
方法二:使用connect在cpp部分绑定需要注意的点是Cpp信号参数必须是QVariant
1.按照上述方法创建一个C++ 类继承自QObject
2.注册一个单例
// .h 文件
public:
static MySerialPort* GetInstance();
// .cpp 文件
// 单例模式
MySerialPort *MySerialPort::GetInstance()
{
static MySerialPort * instance = new MySerialPort();
return instance;
}
// 之后在main函数中加入
//qmlRegisterSingletonInstance<类名>
//("qml引入模块名",版本号,次版本号,"类名",实例化对象);
qmlRegisterSingletonInstance<MySerialPort>("MySerial",1,0,"MySerialPort",MySerialPort::GetInstance());
3.定义信号,这部分我卡了很长时间,最后才发现参数必须是QVariant
signals:
void cppSig(QVariant str,QVariant index); // 定义的信号
4.绑定信号
// 绑定信号与槽
QObject::connect(MySerialPort::GetInstance(), SIGNAL(cppSig(QVariant, QVariant)), window, SLOT(iniport(QVariant, QVariant)));
附完整代码
.h 文件
#ifndef MYSERIALPORT_H
#define MYSERIALPORT_H
#include <QObject>
#include <QDebug>
class MySerialPort : public QObject
{
Q_OBJECT
public:
explicit MySerialPort(QObject *parent = nullptr);
~MySerialPort();
static MySerialPort* GetInstance();
void receiveHander(QString str, int index); // 发射信号的函数
signals:
void cppSig(QVariant str,QVariant index); // 发射信号
};
.cpp
MySerialPort::MySerialPort(QObject *parent)
: QObject{parent}
{
}
// 单例模式
MySerialPort *MySerialPort::GetInstance()
{
static MySerialPort * instance = new MySerialPort();
return instance;
}
// 这部分函数发射信号
void MySerialPort::receiveHander(QString str, int index)
{
//qDebug()<<str<<index;
emit cppSig(str,index);
qDebug()<<"myser:"<<str<<" "<<index;
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myserialport.h"
#include <QObject>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterSingletonInstance<MySerialPort>("MySerial",1,0,"MySerialPort",MySerialPort::GetInstance());
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("fireProject", "Main");
auto list = engine.rootObjects(); // 获取qml的对象
auto window = list.first(); // 拿到根对象
// 绑定信号与槽 iniport QML 执行槽函数
QObject::connect(MySerialPort::GetInstance(), SIGNAL(cppSig(QVariant, QVariant)), window, SLOT(iniport(QVariant, QVariant)));
return app.exec();
}
.qml部分
import QtQuick
import QtQuick.Controls 2.15
import MySerial 1.0
Window {
id:root
width: 800
height: 480
visible: true
title: qsTr("Hello World")
//初始化部分检测指令绑定部分
function iniport(str,index){
console.log(str,index);
}
}
方法三:使用Connects连接 直接上代码
.h
#include <QObject>
class MyObj : public QObject
{
Q_OBJECT
public:
explicit MyObj(QObject *parent = nullptr);
static MyObj* getinstance();
signals:
void cppSig(QString str, int index);
};
.cpp
#include "myobj.h"
MyObj::MyObj(QObject *parent)
: QObject{parent}
{}
MyObj *MyObj::getinstance()
{
static MyObj* my = new MyObj;
return my;
}
.qml
import QtQuick
import MyObj123 1.0
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
function qmlslot(str,index){
console.log(str,index);
}
Button{
width: 50
height: 50
x:100
y:100
onClicked: {
MyObj.cppSig("Test",123);
}
}
Connections{
target: MyObj
function onCppSig(ii,ss){
qmlslot(ii,ss)
}
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "myobj.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterSingletonInstance("MyObj123",1,0,"MyObj",MyObj::getinstance());
QQmlApplicationEngine engine;
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.loadFromModule("Testconnect1", "Main");
return app.exec();
}
但是我自己多线程去写代码的时候,发现这种方法貌似有些问题,无法触发我想要的结果
三.QML如何直接调用C++部分的代码
1.注册C++类方法上面已经说了
2.在C++类中加入调用函数
3.在调用函数前加入关键字Q_INVOKABLE
qml部分代码我直接粘贴了
import QtQuick
import MyObj 1.0
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
MyObject{
id:myo
}
Button{
width:60
height: 60
x:50
y:100
onClicked: {
myo.func();
}
}
}