First, basic use

  • Signal: Clicking a button, for example, sends a click Signal
  • Slot: Also called Slot function, it is used to process signals
  • Official documentation: Signals & Slots

  • The image above looks like this:
    • Object1 sends signal signal1 to sloT1 and SLOT2 of Object2 for processing
      • Object1 is the sender of the signal, and Object2 is the receiver of the signal
    • Object1 sends signal signal2 to sloT1 of Object4 for processing
      • Object1 is the sender of the signal and Object4 is the receiver of the signal
    • Object3 sends signal signal1 to slot SLOt3 of Object4 for processing
      • Object3 is the signal sender and Object4 is the signal receiver
    • One signal can be processed by multiple slots, and one slot can process multiple signals
  • throughconnectThe function can take the signalThe sender,signal,Receiver of a signal,slotJoin together.
connect(sender of a signal, signal, receiver of a signal, slot)Copy the code

1. Use cases

  • Add one in the main windowShut downbutton
#include "mainwindow.h"
#include <QPushButton>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QPushButton *btn = new QPushButton;
    btn->setText("Closed");
    btn->setFixedSize(100.50);
    btn->setParent(this);

    this->setFixedSize(500.500);
}
Copy the code
  • After running, the picture is as follows

  • useCommand + Left mouse buttonClick on theQPushButton, you can viewQPushButtonThe header file

  • inQPushButtonWas not found in the header filesignalThe definition of
  • Continue to look at the parent classQAbstractButtonThe header file

  • inQAbstractButtonIn the header file, scroll down to see that four are definedSignal (Q_SIGNALS)

  • Using the same method, can be inQMainWindowThe parent classQWidgetFound in theSlot function (Q_SLOTS)

  • throughconnectFunctions, linksQPushButtonandsignalwithQMainWindowtheChannel function
#include "mainwindow.h" #include <QDebug> #include <QPushButton> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QPushButton *btn = new QPushButton; BTN - > setText (" close "); btn->setFixedSize(100, 50); btn->setParent(this); this->setFixedSize(500, 500); connect(btn, &QPushButton::clicked, this, &MainWindow::close); } MainWindow::~MainWindow() {qDebug(" MainWindow is closed "); }Copy the code
  • Run the program again

  • Click the close button and you can seeThe main windowIs closed with a printout

  • Can be achieved bydisconnectFunction to disconnectSignals and slotsA link to the
// Disconnect can be used to disconnect
disconnect(btn, &QPushButton::clicked, this, &MainWindow::close);
Copy the code

Two, custom signal and slot

  • Both sender and receiver of a signal must inherit fromQObjectControls in Qt are ultimately inherited from QObject, such as QMainWindow and QPushButton.

1. The sender of the signal

  • The new filesenderTo defineSenderClass as aThe sender of a signal

  • View the generated file

  • sender.h
    • Q_OBJECT supports custom signals and slots
    • Custom signals need to be written insignals:The following
    • Custom signals only need to be declared, not implemented
#ifndef SENDER_H
#define SENDER_H

#include <QObject>

class Sender : public QObject
{
    Q_OBJECT
public:
    explicit Sender(QObject *parent = nullptr);
    
signals:
    // To define a signal, just add a declaration, no need to add an implementation
    void exit(a);
};

#endif // SENDER_H
Copy the code

  • sender.cpp
#include "sender.h"

Sender::Sender(QObject *parent) : QObject(parent)
{

}
Copy the code

2. The receiver of the signal

  • createreceiverTo defineReceiverClass, asReceiver of a signal, andsenderThe file creation methods are the same

  • receiver.h
    • You are advised to write custom slots inpublic slots:The following
#ifndef RECEIVER_H
#define RECEIVER_H

#include <QObject>

class Receiver : public QObject
{
    Q_OBJECT
public:
    explicit Receiver(QObject *parent = nullptr);
    
// Custom slot
public slots:
    void handleExit(a);
};

#endif // RECEIVER_H
Copy the code

  • receiver.cpp
    • Custom slot function, must be written implementation
#include "receiver.h"
#include <QDebug>

Receiver::Receiver(QObject *parent) : QObject(parent)
{

}

// Implement slot function, write signal processing code
void Receiver::handleExit(a)
{
    qDebug() < <"Receiver::handleExit()";
}
Copy the code

3, connection

  • useconnectFunction to connectsenderandreceiver
  • mainwindow.cpp
#include "mainwindow.h"
#include "sender.h"
#include "receiver.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    Sender *sender = new Sender;
    Receiver *receiver = new Receiver;

    connect(sender, &Sender::exit, receiver, &Receiver::handleExit);

    // sender sends a signal
    emit sender->exit(a); } MainWindow::~MainWindow() {}Copy the code

  • Run, view print

  • If you’re not using sender and Receiver, remember to destroy the object
#include "mainwindow.h"
#include "sender.h"
#include "receiver.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    Sender *sender = new Sender;
    Receiver *receiver = new Receiver;

    connect(sender, &Sender::exit, receiver, &Receiver::handleExit);

    // sender sends a signal
    emit sender->exit(a);// If you are not using sender and receiver, remember to destroy the object
    delete sender;
    delete receiver;
}
Copy the code

Parameter and return value

  • Both signals and slots can have parameters and return values:
    • The parameters of the signal are passed to the slot
    • The return value of the slot is returned to the signal location
// Custom signal
signals:
    int exit(int a, int b);
 
// Custom slot
public slots:
    int handleExit(int a, int b);
 
int Receiver::handleExit(int a, int b)
{
    // Receiver::handleExit() 10 20
    qDebug() < <"Receiver::handleExit()" << a << b;
    return a + b;
}
 
// Send a signal
int a = emit sender->exit(10.20);
/ / 30
qDebug() << a;
Copy the code

  • Note that the number of signal parameters must be greater than or equal to the number of slot parameters. For example, the following is incorrect:
// Custom signal
signals:
    void exit(int a);
 
// Custom slot
public slots:
    void handleExit(int a, int b);
Copy the code
  • Connect two signals
    • For example, Signal 1A for Object 1 and Signal 2A for Object 2 are connected
    • When Object 1 sends Signal 1A, Slot X and Slot Y are triggered
    • When Object 2 sends Signal 2A, only Slot Y is fired, not Slot X

  • createsender2File, definitionSender2Class as the sender of the second signal

  • Add the signal
#ifndef SENDER2_H
#define SENDER2_H

#include <QObject>

class Sender2 : public QObject
{
    Q_OBJECT
public:
    explicit Sender2(QObject *parent = nullptr);

signals:
    // To define a signal, just add a declaration, no need to add an implementation
    int exit2(int a, int b);
};

#endif // SENDER2_H
Copy the code

  • receiver.hAdd a new slot function to the
#ifndef RECEIVER_H
#define RECEIVER_H

#include <QObject>

class Receiver : public QObject
{
    Q_OBJECT
public:
    explicit Receiver(QObject *parent = nullptr);

// Custom slot
public slots:
    int handleExit(int num1, int num2);
    int handleExit2(int num1, int num2);
};

#endif // RECEIVER_H
Copy the code

  • receiver.cppAdd the implementation of slot function
#include "receiver.h"
#include <QDebug>

Receiver::Receiver(QObject *parent) : QObject(parent)
{

}

// Implement slot function, write signal processing code
int Receiver::handleExit(int num1, int num2)
{
    qDebug() < <"Receiver::handleExit()" << num1 << num2;
    return num1 + num2;
}

int Receiver::handleExit2(int num1, int num2)
{
    qDebug() < <"Receiver::handleExit2()" << num1 << num2;
    return num1 - num2;
}
Copy the code

  • inmainwindow.cppIn the connectionsenderandsender2The signal of
#include "mainwindow.h"
#include "sender.h"
#include "sender2.h"
#include "receiver.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    Sender *sender = new Sender;
    Sender2 *sender2 = new Sender2;
    Receiver *receiver = new Receiver;

    // connect sender to sender2
    connect(sender, &Sender::exit, sender2, &Sender2::exit2);
    // Connect sender and receiver
    connect(sender, &Sender::exit, receiver, &Receiver::handleExit);
    // Connect sender2 to receiver
    connect(sender2, &Sender2::exit2, receiver, &Receiver::handleExit2);

    // sender sends a signal
    int res = emit sender->exit(100.200);

    qDebug() << res;

    // If you are not using sender, sender2, and receiver, remember to destroy the object
    delete sender;
    delete sender2;
    delete receiver;
}
Copy the code
  • senderSend a signal

5, Lambda

  • LambdaIs a block of function code that can be used for event handling
connect(sender, &Sender::exit, [](int a, int b) {
    qDebug() < <"lambda handle exit";
    return a + b;
});
Copy the code
#include "mainwindow.h"
#include "sender.h"
#include "sender2.h"
#include "receiver.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    Sender *sender = new Sender;
    connect(sender, &Sender::exit, [](int a, int b) {
        qDebug() < <"lambda handle exit";
        return a + b;
    });

    int res = emit sender->exit(10.20);
    qDebug() << res;
}
Copy the code

3. Signals and slots in UI

1. UI binding slot

  • Create a new project and select UI

  • Build in projectmainwindow.uifile

  • Double click on themainwindow.uifile

  • Add two buttons labeled asThe loginandregistered

  • The right mouse buttonClick the Login button

  • chooseGo to the bath

  • chooseclicked, can be inmainwindow.handmainwindow.cppThe file automatically generates slot functions

  • inChannel functionTo add a print code
#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_pushButton_clicked(a)
{
    qDebug() < <"Login";
}
Copy the code
  • To execute the program, clickThe loginButton, you can see that the console has printout

2. Naming rules of UI binding slots

  • Naming rules for UI binding slots:Variable name of on_ control _ event name
  • The aboveThe loginButton, which in the UI file is calledpushButton, the selected event isclicked

  • Modify theregisteredThe name of the button in UI isregisterButton

  • inmainwindow.hFile, manually addregisterButtonTriggered slot function declaration

  • inmainwindow.cppFile, manually addregisterButtonTriggered slot function implementation

  • To execute the program, clickregisteredButton to see a printout from the console

The controls in the UI file will automatically connect to the slot functions that follow the naming rules.

3. Get the controls in the UI file by code

  • Controls in UI files can be passed through codeThe UI - > variable namesAccess.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Access the 2 buttons in the UI file via UI ->
    ui->pushButton->setFixedSize(200.50);
    ui->registerButton->setFixedSize(200.50);
}
Copy the code