Qml使用cpp文件的信号槽

文章目录

  • 一、C++文件Demo
  • 二、使用步骤
    • 1. 初始化C++文件和QML文件,并建立信号槽
    • 2.在qml中调用


一、C++文件Demo

Q_INVOKABLE是一个Qt元对象系统中的宏,用于将C++函数暴露给QML引擎。具体来说,它使得在QML代码中可以直接调用C++类中被标记为Q_INVOKABLE的成员函数。

public:
    SerialPort();
    // 返回可用串口
    Q_INVOKABLE QStringList availablePorts();
    // 打开串口
    Q_INVOKABLE bool open(QString portName, QString buadRate, QString dataBits, QString stopBits,QString parity, QString flowControl);
    // 关闭串口
    Q_INVOKABLE void close();
    // 直接调用接口
    Q_INVOKABLE void say();

signals:
    //返回串口打开信息
    Q_INVOKABLE void openMsg(bool open, QString error);
    //接口,用于多线程
    Q_INVOKABLE void sendMsg(QString msg);

public slots:
    //
    void sendMsgSlot(QString msg);

private:
    QThread* m_thread;

    QSerialPort* m_port;

    QMutex m_mutex;
m_port = new QSerialPort();
connect(this, &SerialPort::sendMsg, this, &SerialPort::sendMsgSlot);

tts = new QTextToSpeech(this);

m_thread = new QThread;
m_thread->setObjectName("串口线程");
this->moveToThread(m_thread);
connect(m_thread, &QThread::finished, this, &QThread::deleteLater);
connect(m_thread, &QThread::finished, this, &SerialPort::deleteLater);
m_thread->start();
QStringList SerialPort::availablePorts()
{
    QStringList list;
    foreach(auto info, QSerialPortInfo::availablePorts()) list.append(info.portName());
    list<<"COM11"<<"COM22";
    return list;
}
bool SerialPort::open(QString portName, QString buadRate, QString dataBits, QString stopBits,QString parity, QString flowControl)
{
    bool ok = false;
    QString errstr = "m_port异常";
    {
        QMutexLocker locker(&m_mutex);
        if(!m_port)
        {
            emit openMsg(false, errstr);
            locker.unlock();
            return false;
        }
        m_port->setPortName(portName);
        m_port->setBaudRate(buadRate.toInt());
        m_port->setDataBits((QSerialPort::DataBits)dataBits.toInt());
        m_port->setStopBits((QSerialPort::StopBits)stopBits.toInt());
        m_port->setParity((QSerialPort::Parity)parity.toInt());
        m_port->setFlowControl((QSerialPort::FlowControl)flowControl.toInt());
        ok = m_port->open(QIODevice::ReadWrite);
        errstr = m_port->errorString();
    }
    emit openMsg(ok, errstr);
    return ok;
}
void SerialPort::close()
{
    QMutexLocker locker(&m_mutex);
    if(m_port && m_port->isOpen()) m_port->close();
}
void SerialPort::say()
{
    qDebug()<<"SerialPort CurrrntThread = "<< QThread::currentThread();
    qDebug()<<"---------------------------------------------------------";
    QString text = "2,8,k,1,0";
    tts->say(text);
}
void SerialPort::sendMsgSlot(QString msg)
{
    qDebug()<<"SerialPort CurrrntThread = "<< QThread::currentThread();
    qDebug()<<msg;
    qDebug()<<"---------------------------------------------------------";
}

二、使用步骤

1. 初始化C++文件和QML文件,并建立信号槽

qml中的槽函数也是定义成signal, 所以connect时,槽函数也是SIGNAL()

serial = new SerialPort;
//serial 类向 QML 对象的上下文公开数据
ui->quickWidget_2->rootContext()->setContextProperty("serial", serial);
//根据窗口大小调整QML大小
ui->quickWidget_2->setResizeMode(QQuickWidget::SizeRootObjectToView);
// 
ui->quickWidget_2->setSource(QUrl("qrc:/Form02.qml"));
//
QObject* obj = ui->quickWidget_2->rootObject();
// 调用qml中信号或者槽函数,调用成功返回true,否则false
// 根节点,被调用信号或槽,连接方式,被调用信号或槽的参数1, 被调用信号或槽的参数2(最多10个参数)
if(QMetaObject::invokeMethod(obj, "slotOpenSerial", Qt::DirectConnection, Q_ARG(bool, true), Q_ARG(QString, "")))
    connect(serial, SIGNAL(openMsg(bool,QString)), obj, SIGNAL(slotOpenSerial(bool,QString)));

2.在qml中调用

QGroupButton 自定义的按钮组

Item {
    id: item
    Layout.fillWidth: true
    Layout.preferredHeight: 36

    property alias checkedButton: btngroup.checkedButton

    property int btnIndexChanged: 0

    onBtnIndexChangedChanged: {
        if(btnIndexChanged == 0) {
            checkedButton = ok
        }
        else {
            checkedButton = cancle
        }
    }

    ButtonGroup {
        id: btngroup
        exclusive: true
        buttons: row.children

        onCheckedButtonChanged:
        {
            console.log("button text: ", checkedButton.text)
            btnIndexChanged = checkedButton == ok ? 0 : 1;
        }
    }

    Rectangle{
        id: rect
        anchors.fill: parent

        RowLayout {
            id: row
            anchors.fill: rect
            spacing: 6
            QButton{id: ok; text: "OK"}
            QButton{id: cancle; text: "Cancle"}
        }
    }
}
signal slotOpenSerial(bool isOpen, string error)

onSlotOpenSerial: {
    //console.log(isOpen, error)
    if(!isOpen)
    {
        group.btnIndexChanged = 1
    }
}

qrc:/Form02.qml

//自定义的按钮组
QGroupButton{
	id: group
	Layout.columnSpan: 2
	Layout.fillWidth: true
	onCheckedButtonChanged:
	{
		if(checkedButton.text == "OK"){
			open =  serial.open(portName.currentText, cboxBuad.currentText, dataBits.currentText,stopBits.currentText, parity.currentText, flowControl.currentText);
			console.log("serial return: ", open)
		}
		else
		{
			serial.close()
		}
	}
}

下面代码仅看这段:
QButton{
text: "1";
onClicked: {
//直接调用接口
serial.say();
//通过信号调用
serial.sendMsg("TTTT");
}
}

Rectangle {
    Layout.columnSpan: 2
    Layout.fillWidth: true
    Layout.fillHeight: true
    color: "#156448"
    Flow {
        anchors.fill: parent
        anchors.margins: 9
        spacing: 6
        QButton{
            text: "1";
            onClicked: {
                serial.say();
                serial.sendMsg("TTTT");
            }
        }
        QButton{text: "2"}
        QButton{text: "3"}
        QButton{text: "4"}
        QButton{text: "5"}
        QButton{text: "6"}
        QButton{text: "7"}
        QButton{text: "8"}
        QButton{text: "9"}
        QButton{text: "10"}
        QButton{text: "11"}
        QButton{text: "12"}
        QButton{text: "13"}
        QButton{text: "14"}
        QButton{text: "15"}
        QButton{text: "16"}
        QButton{text: "17"}
        QButton{text: "18"}
        QButton{text: "19"}
        Rectangle {
            width:60
            height: 26
            color: "green"
            property alias text: in1.text
            onTextChanged: console.log(text)
            TextInput {
                id: in1
                anchors.fill: parent
                text: "input"
                color: "red"
                KeyNavigation.tab: in2
                selectByMouse: true
            }
        }
        Rectangle {
            width:60
            height: 26
            color: "green"
            TextInput {
                id: in2
                anchors.fill: parent
                text: "input"
                color: "red"

                KeyNavigation.tab: in1
                KeyNavigation.up: in1
            }
        }
        Loader {
            sourceComponent: testComponent
        }

    }
}

结果如图:
//---------------------------------------------------------
MainWindow CurrentThread = QThread(0x24ce850) //主线程
//---------------------------------------------------------
qml: button text: OK // 点击OK按钮打印
qml: button text: Cancle // 打开串口失败,取消OK按钮,默认Cancle按钮被点击打印
qml: serial return: false // serial.open(…)返回值打印
SerialPort CurrrntThread = QThread(0x24ce850) // serial.say() 函数运行的线程
//---------------------------------------------------------
SerialPort CurrrntThread = QThread(0xfcc9f0, name = “串口线程”) // serial.sendMsg(“TTTT”)运行的线程
“TTTT” // 槽函数打印
//---------------------------------------------------------

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/171263.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Sql】sql server还原数据库的时候,提示:因为数据库正在使用,所以无法获得对数据库的独占访问权。

【问题描述】 sql server 还数据库的时候&#xff0c;提示失败。 点击左下角进度位置&#xff0c;可以得到详细信息&#xff1a; 因为数据库正在使用&#xff0c;所以无法获得对数据库的独占访问权。 【解决方法】 针对数据库先后执行下述语句&#xff0c;获得独占访问权后&a…

Python 和 Ruby 谁是最好的Web开发语言?

Python 和 Ruby 都是目前用来开发 websites、web-based apps 和 web services 的流行编程语言之一。 【这个时候又人要说PHP是世界上最好的语言了】 我就不说PHP 最好的方法 VS 以人为本的语言 社区: 稳定与创新 尽管特性和编程哲学是选择一个语言的首要驱动因素&#xff0c…

stack和queue简单实现(容器适配器)

容器适配器 stack介绍stack模拟实现queue 介绍queue模拟实现deque stack介绍 stack模拟实现 以前我们实现stack&#xff0c;需要像list,vector一样手动创建成员函数&#xff0c;成员变量。但是stack作为容器适配器&#xff0c;我们有更简单的方法来实现它。 可以利用模板的强大…

C语言生成dll与lib文件

环境要求 新建一个空白项目&#xff0c;可以是exe的&#xff0c;也可以直接是dll的&#xff0c;也可以是啥都没有的空项目&#xff0c;推荐创建空项目&#xff0c;项目创建好以后进行配置&#xff0c;共两步 第一步&#xff0c;打开项目属性 第二步&#xff0c;设置配置类型…

基础课10——自然语言生成

自然语言生成是让计算机自动或半自动地生成自然语言的文本。这个领域涉及到自然语言处理、语言学、计算机科学等多个领域的知识。 1.简介 自然语言生成系统可以分为基于规则的方法和基于统计的方法两大类。基于规则的方法主要依靠专家知识库和语言学规则来生成文本&#xff0…

java中的抽象

1.当一个类中给出的信息不够全面时&#xff0c;&#xff08;比方说有无法确定的行为&#xff09;&#xff0c;它给出的信息不足以描绘出一个具体的对象&#xff0c;这时我们往往不会实例化该类&#xff0c;这种类就是抽象类。 2. 在Java中&#xff0c;我们通过在类前添加关键字…

Redis篇---第九篇

系列文章目录 文章目录 系列文章目录前言一、如果有大量的 key 需要设置同一时间过期,一般需要注意什么?二、什么情况下可能会导致 Redis 阻塞?三、缓存和数据库谁先更新呢?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击…

南京--ChatGPT/GPT4 科研实践应用

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

MySQL 数据库下载

1 最新版 MySQL :: Download MySQL Community Server 2 存档版本(Archived Versions)-历史版本 MySQL :: Download MySQL Community Server (Archived Versions) 3 下载(样例: zip 方式) tip1&#xff1a; 可以下载安装文件的方式&#xff0c;也可以使用压缩包方式&#xff…

Git详解

Git是一个开源的分布式版本控制系统&#xff0c;常用于软件开发中对代码版本管理。Git具有版本控制、协作开发、分支管理、代码审查等功能&#xff0c;能够记录每次代码修改的内容和时间&#xff0c;并能够回滚到任意历史版本&#xff0c;方便团队协作和代码维护。 Git的基本概…

腾讯云5年服务器2核4G和4核8G配置租用价格表

腾讯云百科整理五年云服务器优惠活动 txybk.com/go/txy 配置可选2核4G和4核8G&#xff0c;公网带宽可选1M、3M或5M&#xff0c;系统盘为50G高性能云硬盘&#xff0c;标准型S5实例CPU采用主频2.5GHz的Intel Xeon Cascade Lake或者Intel Xeon Cooper Lake处理器&#xff0c;睿频3…

SQL 中的 NULL 值:定义、测试和处理空数据,以及 SQL UPDATE 语句的使用

SQL NULL 值 什么是 NULL 值&#xff1f; NULL 值是指字段没有值的情况。如果表中的字段是可选的&#xff0c;那么可以插入新记录或更新记录而不向该字段添加值。此时&#xff0c;该字段将保存为 NULL 值。需要注意的是&#xff0c;NULL 值与零值或包含空格的字段不同。具有 …

大数据Doris(二十五):Stream Load数据导入演示和其他导入案例

文章目录 数据导入演示和其他导入案例 一、数据导入演示

万字解析设计模式之 装饰者模式

一、装饰者模式 1.1概述 装饰者模式是一种结构型设计模式&#xff0c;它允许在运行时动态地为一个对象添加额外的职责。它以一种透明的方式来扩展对象的功能&#xff0c;而不需要通过子类来实现。在装饰者模式中&#xff0c;有一个基本对象&#xff0c;也称为组件&#xff0c;…

2023年亚太杯数学建模思路 - 案例:感知机原理剖析及实现

文章目录 1 感知机的直观理解2 感知机的数学角度3 代码实现 4 建模资料 # 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 感知机的直观理解 感知机应该属于机器学习算法中最简单的一种算法&#xff0c;其…

鸿蒙原生应用/元服务开发-AGC分发如何编译打包应用

软件包规范 在正式打包应用前&#xff0c;请确保已了解HarmonyOS应用软件包规范。 操作步骤 1.打开DevEco Studio&#xff0c;菜单选择“Build > Build Hap(s)/APP(s) > Build APP(s)”。 2.等待编译构建。编译完成后&#xff0c;将在工程目录“build > outputs >…

Vue2问题:分享一个通用多文件类型预览库

前端功能问题系列文章&#xff0c;点击上方合集↑ 序言 大家好&#xff0c;我是大澈&#xff01; 本文约2000字&#xff0c;整篇阅读大约需要3分钟。 本文主要内容分三部分&#xff0c;第一部分是需求分析&#xff0c;第二部分是实现步骤&#xff0c;第三部分是问题详解。 …

一文详看大模型长文本如何评估:四大主流评测数据集的任务设计、数据集构建方案

大语言模型&#xff08;LLM&#xff09;尽管在各种语言任务中表现抢眼&#xff0c;但通常仅限于处理上下文窗口大小范围内的文本。 有越来越多的基准被提出来测试LLM的长文本理解能力。 当前具有代表性的长文本评测主要包括Zero-SCROLLS、L-Eval、LongBench以及loogle四个基准…

Ansys Lumerical|菲涅尔透镜设计

附件下载 联系工作人员获取附件 在这个例子中&#xff0c;我们研究一个球面菲涅尔透镜。透镜的曲率半径为100cm&#xff0c;直径为4.8cm。由于该结构的尺寸较大&#xff0c;我们必须使用该结构的二维近似。透镜的焦点可以用FDTD远场投影函数来研究。 镜头设计和设置 我们将考…

希亦ACE和RUUFFY内衣洗衣机选哪个好?内衣洗衣机大对比

这两年&#xff0c;内衣洗衣机算是一种很受欢迎的小家电了&#xff0c;尽管它的体积很小&#xff0c;但是它的作用很大&#xff0c;一键就能启动洗、漂、脱三种自动操作&#xff0c;在提高多功能和性能的同时&#xff0c;也能让我们在洗衣服的时候&#xff0c;解放了我们的手。…
最新文章