当前位置: 首页 > news >正文

直播相关02-录制麦克风声音,QT 信号与槽,自定义信号和槽

一 信号与槽函数

#include "mainwindow.h"
#include <QPushButton>
#include <iostream>
using namespace std;//我们的目的是在 window中加入一个button,当点击这个button后,关闭 MainWindow 。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{//注意,这里是new 了一个 QpushButton的,那么理论上要 delete 这个loginButton 。这里为什么 没有呢?QPushButton * loginButton = new QPushButton();loginButton->setText("登陆");loginButton->setParent(this); // 将自己挂载到当前的 mianwindow上,这意味着,当 mainwindows 销毁的时候,loginbutton 会跟着销毁,因此不用手动的调用 elete loginbuttonloginButton->setFixedSize(100,30); // 设置button 为固定大小//我们将 loginbutton 的 clicked信号,给MainWindow 的 close槽函数。//qpushbutton 的clicked 信号,是qpushbutton 自带的信号//mainwindows 的close 槽函数,是 mainwindows 自带的槽函数connect(loginButton,&QPushButton::clicked,this,&MainWindow::close);}MainWindow::~MainWindow()
{
}

二 自定义信号和 自定义 槽函数

1.自定义信号,添加一个C++ 类,要继承 QObject

主要你要自定义信号与槽,就一定要 Add Q_OBJECT

sender.h 文件

#ifndef SENDER_H
#define SENDER_H#include <QObject>class Sender : public QObject
{//主要你要自定义信号与槽,就一定要 Add Q_OBJECT,这个取消了会有问题Q_OBJECT
public:explicit Sender(QObject *parent = nullptr);signals://自定义信号,只需要在.h文件中声明就可以了,不需要在.cpp中实现void exit();void start();
};#endif // SENDER_H

2.自定义槽函,添加一个C++类,要继承 QObject

在receiver.h 中定义这两个槽函数

在receiver.cpp中实现这两个槽函数

#ifndef RECEIVER_H
#define RECEIVER_H#include <QObject>class receiver : public QObject
{//主要你要自定义信号与槽,就一定要 Add Q_OBJECT,这个取消了会有问题Q_OBJECT
public:explicit receiver(QObject *parent = nullptr);signals://槽函数是要给别人调用的,因此在public slots 后 写 槽函数,在.cpp文件中写实现.
public slots:void handleExit();void handleStart();};#endif // RECEIVER_H

#include "receiver.h"
#include <iostream>
using namespace std;receiver::receiver(QObject *parent) : QObject(parent)
{}void receiver::handleExit(){cout<<"receiver handleExit method "<<endl;
}
void receiver::handleStart(){cout<<"receiver handleStart method "<<endl;
}

3.调用

这里为了方便期间,将上述两个类 重命名为 customerreceiver.h   和  customersender.h

    //将信号发送者 和 信号 接受者 建立关联
    //使用emit 发送信号, 实际上就是 调用 发送者的信号函数
 

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "customersender.h"
#include "customerreceiver.h"
#include <iostream>
using namespace std;MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{cout<<"qt custom single custom slot"<<endl;ui->setupUi(this);CustomerSender * customersender = new CustomerSender;CustomerReceiver * customerrecevier =  new CustomerReceiver();//将信号发送者 和 信号 接受者 建立关联connect(customersender,&CustomerSender::start,customerrecevier,&CustomerReceiver::handleStart);connect(customersender,&CustomerSender::exit,customerrecevier,&CustomerReceiver::handleExit);cout<<"00000 log for watch"<<endl;//使用emit 发送信号, 实际上就是 调用 发送者的信号函数emit customersender->start();cout<<"11111log for watch"<<endl;emit customersender->exit();cout<<"222"<<endl;//由于 customersender 和 customerrecevier 并没有挂载到当前mainwindows上,类似这样customersender->setParent(this);因此要手动deletedelete customersender;delete customerrecevier;
}MainWindow::~MainWindow()
{delete ui;
}

4. 当自定义信号 和 自定义槽函数 有参数或者返回值的时候

自定义信号 addmethodstart ,参数为 int a 和 int b

返回值double 目前不知道有啥用

signals://自定义信号,只需要在.h文件中声明就可以了,不需要在.cpp中实现void exit();void start();double addmethodstart(int a ,int b );

自定义槽函数

    int handleAddFuncation();double handleAddFuncation2(int n , int m);int CustomerReceiver::handleAddFuncation(){cout<<"CustomerReceiver handleAddFuncation method return 100"<<endl;return 100;
}double CustomerReceiver::handleAddFuncation2(int n , int m){cout<<"CustomerReceiver handleAddFuncation2 method return n+m "<< n+m << endl;return n+m;
}

当我们发送一个信号的时候,如果有槽函数有对应的 int,int 参数,则会接受 信号发送的2000,3000的值传递到槽函数中。

如果槽函数没有对应的int,int 参数,则不传递

    connect(customersender,&CustomerSender::addmethodstart,customerrecevier,&CustomerReceiver::handleAddFuncation);cout<< emit customersender->addmethodstart(200,300);//由于 handleAddFuncation 函数没有参数,因此这个200,300传递不到槽函数handleAddFuncation中cout<<"333"<<endl;connect(customersender,&CustomerSender::addmethodstart,customerrecevier,&CustomerReceiver::handleAddFuncation2);cout<< emit customersender->addmethodstart(2000,3000);//由于handleAddFuncation2 有int,int 的参数 ,因此这个2000,3000会传递给槽函数 handleAddFuncation2

返回值问题,信号的返回值目前没有发现意义是啥,

槽函数的返回值 可以通过 emit 信号函数返回。

例如:

cout<< emit customersender->addmethodstart(200,300);
会打印 100出来,这是因为 对应的槽函数 handleAddFuncation 返回值是100

5. 连接多个信号

connect 函数除了可以连接一个 信号和一个槽函数外,

还可以连接一个信号 和 另一个信号 .

类似于连锁反应

customersender2.h

#ifndef CUSTOMERSENDER2_H
#define CUSTOMERSENDER2_H#include <QObject>class customersender2 : public QObject
{Q_OBJECT
public:explicit customersender2(QObject *parent = nullptr);signals:void deletebutton2();
};#endif // CUSTOMERSENDER2_H

customersender3.h

#ifndef CUSTOMERSENDER3_H
#define CUSTOMERSENDER3_H#include <QObject>class customersender3 : public QObject
{Q_OBJECT
public:explicit customersender3(QObject *parent = nullptr);signals:void deletebutton3();
};#endif // CUSTOMERSENDER3_H

customerreceuver2.h
#ifndef CUSTOMERRECEUVER2_H
#define CUSTOMERRECEUVER2_H#include <QObject>class customerreceuver2 : public QObject
{Q_OBJECT
public:explicit customerreceuver2(QObject *parent = nullptr);signals:public slots:void handledeletebutton2();
};#endif // CUSTOMERRECEUVER2_H

customerreceuver3.h

#ifndef CUSTOMERRECEUVER3_H
#define CUSTOMERRECEUVER3_H#include <QObject>class customerreceuver3 : public QObject
{Q_OBJECT
public:explicit customerreceuver3(QObject *parent = nullptr);signals:public slots:void handledeletebutton3();
};#endif // CUSTOMERRECEUVER3_H

customerreceuver2.cpp
#include "customerreceuver2.h"
#include <iostream>
using namespace  std;customerreceuver2::customerreceuver2(QObject *parent) : QObject(parent)
{}void customerreceuver2::handledeletebutton2(){cout<<"customerreceuver2::handledeletebutton2"<<endl;
}

customerreceuver3.cpp

#include "customerreceuver3.h"
#include <iostream>
using namespace std;customerreceuver3::customerreceuver3(QObject *parent) : QObject(parent)
{}void customerreceuver3::handledeletebutton3(){cout<<"customerreceuver3::handledeletebutton3"<<endl;}

调用

        cout<<" single to single"<<endl;customersender2 *cus2 = new customersender2;customersender3 *cus3 = new customersender3;customerreceuver2 *cusre2 =  new customerreceuver2;customerreceuver3 *cusre3 =  new customerreceuver3;connect(cus2, &customersender2::deletebutton2,cusre2,&customerreceuver2::handledeletebutton2);emit cus2->deletebutton2();cout<<"111"<<endl;connect(cus3, &customersender3::deletebutton3,cusre3,&customerreceuver3::handledeletebutton3);emit cus3->deletebutton3();cout<<"222 "<<endl;cout<<"after this line will be test single to single"<<endl;//让 sender2 的信号deletebutton2 唤醒 sender3 的信号 deletebutton3connect(cus2, &customersender2::deletebutton2,cus3, &customersender3::deletebutton3);emit cus2->deletebutton2();cout<<"333333"<<endl;//    single to single
//    customerreceuver2::handledeletebutton2
//    111
//    customerreceuver3::handledeletebutton3
//    222 
//    after this line will be test single to single
//    customerreceuver2::handledeletebutton2
//    customerreceuver3::handledeletebutton3
//    333333

6.labmda 表达式

    //for test labmda,假设我们不想写receiverconnect(cus2, &customersender2::deletebutton2,[](){cout<<"labmda called"<<endl;});emit cus2->deletebutton2();cout<<"666666"<<endl;

三 当QT使用 genetate form 创建UI后,如何使用 信号和槽函数呢?

也就是说,我们使用了QT 的 generate form 来创建UI

我们在弄了两个pushbutton,一个登陆,一个注册,可以观察到 QT会给key 命名为 pushButton,一个为pushButton_2,当然可以改动这个key的值,

我们这里重新命名为 loginbutton和registerbutton

检查 编辑 下的 UI 的button,如下:

那么我们想要给这两个button 添加 信号和槽事件应该怎么弄呢?

点击 "转到槽" 做了两件事情

1. 点击那个信号  相当于 选择了那个 信号

2.然后生成 该信号 对应的 槽函数

例如我们点击了 clicked() 信号,就会生成  void on_loginbutton_clicked() 参函数

 

槽函数的位置

那么 emit 是在什么时候调用呢?实际上我们是看不到的,QT内部帮我们实现了,只要我们完成了上述的 button 的 转到槽函数, 就可以了

测试:

手动的写 槽函数,而不是通过自动生成

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 机器学习 第12章 计算学习理论
  • HTML和HTML5有什么区别
  • Note091201_OutLook签名设置
  • EE trade:5g黄金是不是纯黄金
  • Kafka的权限配置中,匹配模式
  • GPS 或数字导航之前使用什么进行导航
  • Jmeter模拟用户登录时获取token如何跨线程使用?
  • Druid连接池练习
  • css总结(记录一下...)
  • 管理员权限一键启动:Run-Command让高权限操作更简单
  • 在启智社区使用MindFormers本地部署大模型(未解决)
  • 海外云手机——跨国业务的高效工具
  • Day8 | Java框架 | Maven
  • 计算几何学习
  • python学习——对无人机影像有RGB转换到HSV
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • css系列之关于字体的事
  • Linux各目录及每个目录的详细介绍
  • node入门
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • swift基础之_对象 实例方法 对象方法。
  • SwizzleMethod 黑魔法
  • 爱情 北京女病人
  • 安卓应用性能调试和优化经验分享
  • 番外篇1:在Windows环境下安装JDK
  • 机器学习 vs. 深度学习
  • 聚类分析——Kmeans
  • 批量截取pdf文件
  • 普通函数和构造函数的区别
  • 如何优雅地使用 Sublime Text
  • 三分钟教你同步 Visual Studio Code 设置
  • 深度学习入门:10门免费线上课程推荐
  • 优化 Vue 项目编译文件大小
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #VERDI# 关于如何查看FSM状态机的方法
  • #宝哥教你#查看jquery绑定的事件函数
  • $forceUpdate()函数
  • (2)(2.10) LTM telemetry
  • (苍穹外卖)day03菜品管理
  • (二) 初入MySQL 【数据库管理】
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (每日一问)计算机网络:浏览器输入一个地址到跳出网页这个过程中发生了哪些事情?(废话少说版)
  • (十八)三元表达式和列表解析
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)Windows2003安全设置/维护
  • (转载)Google Chrome调试JS
  • .Net Core中的内存缓存实现——Redis及MemoryCache(2个可选)方案的实现
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .Net 基于.Net8开发的一个Asp.Net Core Webapi小型易用框架
  • @converter 只能用mysql吗_python-MySQLConverter对象没有mysql-connector属性’...
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构