学习一个新的框架,想要快速上手只要掌握其核心的东西即可,其余的积累积累就可以了。
信号与槽(Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。
信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。
GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
一、 标准信号与槽
下面是信号与槽连接的格式:
connect(sender, signal, receiver, slot);
参数:
sender:发出信号的对象
signal:发送对象发出的信号
receiver:接收信号的对象
slot:接收对象在接收到信号之后所需要调用的函数
注意:
信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。如果不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。
接下来看例子:实现的功能很简单,就是点击‘点我按钮’,出现‘我叫唐永’。
代码:
TyWidget::TyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::TyWidget)
{
ui->setupUi(this);
//1.使用connect
connect(ui->pushButton,&QPushButton::clicked,this,&TyWidget::onbtnTySlot);
}
//2.槽函数
void TyWidget::onbtnTySlot()
{
ui->lineEdit->setText("我叫唐永");
}
TyWidget::~TyWidget()
{
delete ui;
}
结果:
二、 自定义信号与槽
先看看效果:
点击按钮‘获取儿子’,然后弹出一个‘我是儿子’的对话框,然后再点击按钮‘点我呀!’,就会回到‘我是爸爸的窗口’,并且在label标签中将发送的内容显示。
主窗口:
头文件:
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QPushButton>
#include "childwidget.h"
#include <QLabel>
namespace Ui {
class MyWidget;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
~MyWidget();
private:
Ui::MyWidget *ui;
public:
QPushButton *m_btntt;
childwidget m_child;
QLabel *m_label;
public slots:
void childToParentSlot(QString str,int a);
};
#endif // MYWIDGET_H
Cpp文件:
#include "mywidget.h"
#include "ui_mywidget.h"
#include <QMessageBox>
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWidget)
{
ui->setupUi(this);
resize(500,400);
setWindowTitle("我是爸爸");
m_btntt = new QPushButton(this);
m_btntt->resize(100,40);
m_btntt->move(100,200);
m_btntt->setText("获取儿子");
m_label = new QLabel("这是一个label",this);
m_label->resize(120,40);
connect(m_btntt,&QPushButton::clicked,this,[=](){
//隐藏自己
this->hide();
//显示孩子
m_child.show();
});
connect(&m_child,&childwidget::mySignals,this,childToParentSlot);
}
void MyWidget::childToParentSlot(QString str,int a)
{
QString str1;
str1.sprintf("%d",a);
this->show();
m_label->setText(str+str1);
// QMessageBox::information(this,"提示",str+str1);
}
MyWidget::~MyWidget()
{
delete ui;
}
子窗口:
头文件:
#ifndef CHILDWIDGET_H
#define CHILDWIDGET_H
#include <QWidget>
#include <QPushButton>
class childwidget : public QWidget
{
Q_OBJECT
public:
explicit childwidget(QWidget *parent = 0);
signals:
void mySignals(QString,int nsalary);
public slots:
public:
QPushButton *m_btn;
};
#endif // CHILDWIDGET_H
CPP文件:
#include "childwidget.h"
childwidget::childwidget(QWidget *parent) : QWidget(parent)
{
resize(400,300);
setWindowTitle("我是儿子");
m_btn = new QPushButton(this);
m_btn->setText("点我呀!");
m_btn->resize(100,40);
m_btn->move(140,200);
connect(m_btn,&QPushButton::clicked,this,[=]{
emit mySignals("发如雪",521);
});
}
3.信号重载
在子窗口:
发送信号:
在主窗口中:
槽函数