前言

信号与槽机制是QT非常核心的东西,通过信号与槽我们可以将不同的部分有机的结合起来,使得各个组件之间的交互简单高效,信号与曹槽像是设计模式中的观察者模式(我自己觉得是这样),只关心信号何时发来,以及做如何相应,组件之间可以异步或者同步去处理事情。

信号(Signal):就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。

槽(Slot):就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

一、基本形式

官方文档弄下来的:
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection);
默认是五个参数,关于最后一个参数的具体使用说明参考:信号与槽的连接方式
这个函数的原型就这样,试着看了一下有8个该函数的重载,第一个参数发送者,第二个信号,第三个接收者,第四个接收者的响应函数。
发送者和接受者可以是同一个QObject,在GUI里面我们可以认为一个界面是一个QObject,注意信号与槽的参数要对应上。
界面:

为此我做个一个小demo,自己测试也通了:
如下头文件:

#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_pushButton_5_clicked(); //自动生成的槽函数void pushButon1_clicked();      //自定义的1-4按钮的槽函数void pushButon2_clicked();void pushButon3_clicked();void pushButon4_clicked(int i);
signals:// void onClicked();            //重载信号void sig_add(int i);
private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

.CPP文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qglobal.h"
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//第一种方式connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(pushButon1_clicked()));// connect(ui->pushButton,SIGNAL(clicked),ui->pushButton,SLOT(pushButon1_clicked()));//第二种方式connect(ui->pushButton_2,&QPushButton::clicked,this,&::MainWindow::pushButon2_clicked);// connect(ui->pushButton_2, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked), this, SLOT(pushButon2_clicked()));//第三种方式// connect(ui->pushButton_2, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked),   //            this,SLOT(pushButon2_clicked()));//第2参数转换其实是一个函数指针,等价下面的代码//void (QPushButton::*ff)(bool)=&QPushButton::clicked;// connect(ui->pushButton_2, ff, this, SLOT(pushButon2_clicked()));connect(ui->pushButton_3, QOverload<bool>::of(&QPushButton::clicked),this,&::MainWindow::pushButon3_clicked);//第四种方式connect(ui->pushButton_4, QOverload<bool>::of(&QPushButton::clicked),[=](bool check){ui->textBrowser->setText("按钮4信号绑定成功");});
//    connect(ui->pushButton_4, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked), this, [=](bool check){//                    ui->textBrowser->setText("按钮4信号绑定成功");
//            });}
MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_5_clicked()
{ui->textBrowser->setText(QString("按钮5系统生成信号绑定成功"));
}
void MainWindow::pushButon1_clicked()
{ui->textBrowser->setText("按钮1信号绑定成功");
}void MainWindow::pushButon2_clicked()
{ui->textBrowser->setText("按钮2信号绑定成功");
}void MainWindow::pushButon3_clicked()
{ui->textBrowser->setText("按钮3信号绑定成功");emit sig_add(4);
}void MainWindow::pushButon4_clicked(int i)
{ui->textBrowser->setText("按钮4信号绑定成功");
}

整个工程完整代码(一个积分)。

二、Connect几种方式

方式一

这应该是QT4.0最为传统的方法,其实很多时候用这个还是很清晰的:

    //第一种方式connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(pushButon1_clicked()));// connect(ui->pushButton,SIGNAL(clicked),ui->pushButton,SLOT(pushButon1_clicked()));

方式二

这应该是QT5.0之后退出来的绑定方法,去掉了之前的宏,感觉更清爽了,我用的还是比较多了

 connect(ui->pushButton_2,&QPushButton::clicked,this,&::MainWindow::pushButon2_clicked);

方式三

C++11出来之后,新的特性就出来,static_cast 用法

    //第三种方式// connect(ui->pushButton_2, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked),   //            this,SLOT(pushButon2_clicked()));//第2参数转换其实是一个函数指针,等价下面的代码//void (QPushButton::*ff)(bool)=&QPushButton::clicked;// connect(ui->pushButton_2, ff, this, SLOT(pushButon2_clicked()));connect(ui->pushButton_3, QOverload<bool>::of(&QPushButton::clicked),this,&::MainWindow::pushButon3_clicked);

方式四

目前我用得最多的方式,一开始对lamda表达式感觉困惑,用多了发现还真的很方便,最大的好处就是不需要去定义槽函数了,很简洁。

connect(ui->pushButton_4, QOverload<bool>::of(&QPushButton::clicked),[=](bool check){ui->textBrowser->setText("按钮4信号绑定成功");});
//    connect(ui->pushButton_4, static_cast<void (QPushButton::*)(bool)>(&QPushButton::clicked), this, [=](bool check){//                    ui->textBrowser->setText("按钮4信号绑定成功");
//            });

其实在正常使用过程中,比如添加一个按钮,需要点击按钮去执行相应的事情,就会右键,选择相对应的信号,系统会自动把你信号与槽函数对应上,很多情况下是不需要去手动去写的。但是在VS下开发QT的时候(有人喜欢VS的界面,同时VS在调试时候比QT更方便),信号与槽需要手动去绑定,这就需要在写槽函数的时候如果按照系统的规则命名,则会自动的帮你和对应的信号连接起来;如果我们在Qt中自定义信号与槽函数的时候最好不要按照系统的命名去做,省去可能绑定的不确定。

总结

QT在不断发展壮大中,其实内部有很多值得学习借鉴的地方,在跨平台编译过程中,Qt有着很大优势,在绑定信号与槽函数的时候一定要注意函数是不是带括号的问题。有可能就会出现不匹配的错误。

QT中connect函数的几种用法详解总结相关推荐

  1. matlab中采样函数,matlab采样相关函数用法详解

    matlab采样函数(降采样,过采样,减采样函数)用法详解 dyaddown 功能:对时间序列进行二元采样,每隔一个元素提取一个元素,得到一个降采样时间序列. 格式: 1.y = dyaddown(x ...

  2. decode函数的几种用法详解

    decode的几种用法 1:使用decode判断字符串是否一样 DECODE(value,if1,then1,if2,then2,if3,then3,...,else) 含义为 IF 条件=值1 TH ...

  3. Qt中线程同步的几种方法详解

    1.QMutex类 QMutex类就像一把锁,在互斥量以前上锁(QMutex::lock()),而后在使用完互斥量以后解锁(QMutex::unlock()).好比下面的代码:函数 void some ...

  4. python中rstrip用法_浅谈Python3中strip()、lstrip()、rstrip()用法详解

    简单来说,三种方法是为了删除字符串中不同位置的指定字符.其中,strip()用于去除字符串的首尾字符,同理,lstrip()用于去除左边的字符,rstrip()用于去除右边的字符 Python中有三个 ...

  5. python字符串strip的作用_Python字符串函数strip()原理及用法详解

    Python字符串函数strip()原理及用法详解 strip:用于移除字符串头尾指定的字符(默认为空格)或字符序列.注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符. 语法:str.s ...

  6. java return返回值_java中关于return返回值的用法详解

    我们输入一个条件时,系统就会对这个条件进行判断,然后给出一个返回时的结论,我们把这个结果看做是返回值.在java里可以使用return语句来进行返回,从字面意思就能很好的理解它的用法了.下面我们就re ...

  7. python多个strip_python 格式化多个Python3中strip()、lstrip()、rstrip()用法详解

    Python中有三个去除头尾字符.空白符的函数,它们依次为: strip: 用来去除头尾字符.空白符(包括n.r.t.' ',即:换行.回车.制表符.空格) lstrip:用来去除开头字符.空白符(包 ...

  8. linux cp -r 参数,Linux系统中cp命令的参数及用法详解

    Linux系统中cp命令主要是用来复制文件或者目录.下面由学习啦小编为大家整理了Linux系统中cp命令的参数及用法详解的相关知识,希望对大家有帮助! Linux系统中cp命令的参数及用法详解:参数说 ...

  9. 站长在线Python精讲:在Python中格式化字符串的两种方法详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中格式化字符串的两种方法详解>.本知识点主要内容有:使用%操作符格式化字符串和使用format()方法格式化字 ...

最新文章

  1. Windows与Linux区别3
  2. Hibernate(九)一对多双向关联映射
  3. 深入浅出JMS(一)——JMS简单介绍
  4. ACM之【运算符重载结合STL】
  5. gzip, gunzip, zcat - 压缩或展开文件
  6. ArrayBlockingQueue原理分析
  7. java设计模式之责任链模式以及在java中作用
  8. 说一下output子句
  9. 链表逆序(JAVA实现)
  10. Python import导入模块与函数方法 Python语言基础【1】
  11. 玛丽卡(codevs 1021)
  12. 盲人浏览网页辅助工具之一
  13. Linux cat 命令用法
  14. 忽略git项目上的任何#39;bin#39;目录
  15. ubuntu php oracle,Oracle数据库之php在ubuntu上安装oracle的扩展
  16. 3500常用字+字母+数字+表单符号
  17. kindle paperwhite 使用说明
  18. 考研英语 - word-list-17
  19. window7 安装grldr
  20. 惊艳全网的裸眼3D巨屏,竟是一场视觉骗局?

热门文章

  1. 中国移动M5310 nbiot开发板连接onenet平台全过程
  2. Pygame实现推箱子
  3. 【网页报404,域名可以PING通,但是网址就是打不开】
  4. C++笔试题(一)【高级C++开发工程师综合测试题(风林火山)】
  5. 用ArcMap画一个彩虹风格的蜂窝
  6. 金蝶KIS旗舰版基础档案资料建立,金蝶盘点机PDA仓库条码管理
  7. mysql备份工具_MySQL常用的备份方式与备份工具简介
  8. mysql创建数据库整数五种整形_mysql 整型数据类型
  9. php preg_split spit 丢弃解决方法是preg_aplit()
  10. 惠普HP Deskjet 5552 打印机驱动