一、信号与槽
1、什么是信号与槽?
信号和槽是用于对象之间的通信,它是Qt的核心机制,在Qt编程中有着广泛的应用。如果想学好Qt,一定要充分掌握信号的槽的概念与使用。
2、信号和槽的代码实例
在Qt中,发送对象、发送的信号、接收对象、槽可以通过很多种方式连接。下面通过一些例子逐一做演示,如下:
2.1、connect+宏实现信号与槽绑定
connect(发送对象,信号,接收对象,槽函数),其中发送信号和槽函数需要用 SIGNAL() 和 SLOT() 来进行声明。connect函数声明如下:
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
比如点击登录按键完成登录的例子,代码可以这样写:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// 槽函数声明
private slots:
void login();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
通过connect绑定槽函数,如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 登录按键绑定槽函数
connect(this->ui->btn_ok, SIGNAL(clicked(bool)), this, SLOT(login()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::login()
{
QString username = ui->lineEdit_username->text();
QString password = ui->lineEdit_password->text();
if (username == "jack" && password == "12345") {
qDebug() << "login success";
} else {
qDebug() << "login fail";
}
}
2.2、槽函数的特点
2.2.1、声明槽函数需要使用private slots关键字
声明槽函数时,需要使用private slots关键字,如下:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// 槽函数声明
private slots:
void login();
private:
Ui::MainWindow *ui;
};
2.2.2、信号和槽参数不能包含任何变量名,只能包含类型
下面声明的槽函数是错误的,例如:
QObject::connect(scrollBar, SIGNAL(valueChanged(int value)),
label, SLOT(setNum(int value)));
2.3、使用Qt Creator添加信号的槽函数
通过Qt Creator 界面来完成发送信号和槽函数的连接,比如右键点击一个按钮,然后选择“转到槽”:
Qt Creator会自动生成如下代码,首先是槽函数的声明:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// 槽函数声明
private slots:
void on_btn_cancel_clicked(bool checked);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
槽函数实现,如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btn_cancel_clicked(bool checked)
{
}
使用这种方法不需要使用connect函数将信号与槽函数做连接。 这里槽函数的命名有一定的规则,一般是 on_objectname_signal 这样来命名的。这种方法优点是减少了手动敲代码的工作量,缺点是究竟有哪些信号与槽函数做了连接不易被发现,没有connect 函数看起来直观。