信号和槽
Qt信号的三个要素。
信号源:由哪个控件发出的信号。
信号的类型:用户进行不同的操作,就可能触发不同的信号。
信号的处理方式:槽(slot) 差不多等于函数
Qt中可以使用connect这样的函数,把一个信号和一个槽关联起来。
后续只要信号出发了,Qt就会自动的执行槽函数。
所谓的槽函数本质就是一种回调函数(callback)。
Qt中,一定是先关联信号和槽,然后再触发这个信号,顺序不能颠倒,否则就不知道如何处理了。
connect
是QObject提供的静态的成员函数
在Qt中提供的这些类,本身是存在一定的继承关系的。
比如QWidget由以下子类,QPushButton,QLineEdit。
QWidget的父类是QObject。
QObject就是其他Qt内置累的“祖宗”。
在java中也存在类似的设定。比如所有的类都是继承自Object类。
connect具体使用方式
在qt5中重载了这个connect函数。
第二个参数和第四个参数在qt5中,用的都是泛型参数,可以传递任意的函数指针。
connect (const QObject *sender,
const char * signal ,
const QObject * receiver ,
const char * method ,
Qt::ConnectionType type = Qt::AutoConnection )
sender:信号源,描述了当前信号是哪个控件发出来的。
signal:描述了信号的种类是什么。
receiver:信号的接受对象。哪个对象负责处理
method:这个对象该怎么处理
**ctrl+左键跳转到函数定义的地方。**alt+左箭头返回。
QPushButton中的信号
QPushButton继承自他的父类QAbastractButton,这个父类里面有个clicked的信号。
自定义槽函数
开发当中大部分情况都是需要自定义槽函数的。
实际上和自己自定义成员函数没什么区别。
但是在以前的Qt版本中,必须将槽函数放到public slots中。
qmake使用元编程技术,构建Qt项目的时候,使用qmake会自动扫描关键字,比如slots从而,生成一些qt的代码。
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton* btn = new QPushButton(this);
btn->setText("按钮");
btn->move(200, 300);
connect(btn, &QPushButton::clicked, this, &Widget::hanld);
}
Widget::~Widget()
{
delete ui;
}
void Widget::hanld()
{
this->setWindowTitle("按钮已经按下了");
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void hanld();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
通过ui界面生成自定义槽
qt生成的函数形同
on_pushButton_clicked()
在Qt中不仅可以通过connect来连接信号槽,还可以通过函数名字来实现槽会进行自动连接。
pushButton是ui的objectname的名字。
自定义信号
自定义信号,比较少见,实际开发中很少会需要自定义信号。
Qt的内置型号,基本上已经覆盖到了上述所有可能的用户操作。
所谓的Qt的信号本质是一个函数。
但是是一个特殊的函数,程序员只需要写出函数声明,并且告诉Qt,这是一个信号即可。
函数的定义在编译过程会自动生成。
signals
这是Qt自己扩展出来的关键字。
qmake的时候,扫描到类中包含signals的时候。
会自动把下面的函数声明认为是信号,并且给这些信号函数自动的生成函数定义。
比如信号只需这样声明即可。
class
{
signals:
void mySignal();
};
emit关键字
自定义的信号需要通过手动发射。
可以通过emit mySignal();发送出自定义信号。
带参数的信号和槽
void handleMySignal(const QString& text);
signals:
void mySignal(const QString& text);
private slots:
void on_pushButton_clicked();
信号和槽的参数必须一致
可以不一致,但是信号的参数必须比槽的函数多。
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(this, &Widget::mySignal, this , &Widget::handleMySignal);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handleMySignal(const QString & text)
{
this->setWindowTitle(text);
}
//这个槽函数会自动连接
void Widget::on_pushButton_clicked ()
{
emit mySignal("带参数的信号");
}
带参数的clicked信号
这个bool参数的意思对于QPushButton没啥意义,
对于QCheckBox复选框,就很有用了。