[QT] Signals and slots can automatically pass parameters

img

1. Pre-sample code

  1. main.cpp
#include "widget.h"

#include <QApplication>

// argc, argv receive mouse and keyboard commands and pass them to the QApplication object.
int main(int argc, char *argv[])
{<!-- -->
    QApplication a(argc, argv); // Application object a, in Qt, there is only one application object.
    Widget w; // Window object w, Widget parent class -> QWidget
    w.show(); // Window object w will not be displayed by default. You must call the show method to display the window.
    return a.exec(); // Let application object a enter the message loop --> while(true);

// while(true)
// {<!-- -->
// if (click the fork)
// {<!-- -->
// break;
// }
// }
}

argc, argv receive mouse and keyboard commands and pass them to the QApplication object.

  1. widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{<!-- -->
    Q_OBJECT //Macro, allows the use of signals and slots mechanisms in classes.

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

signals:
    void isSignal(int signal = 0);
public slots:
    void isSlot(int slot);

};
#endif // WIDGET_H

The Q_OBJECT macro allows the use of signals and slots in classes.

  1. widget.cpp
#include "widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) : QWidget(parent)
{<!-- -->
    // Binding of signals and slots:
    connect(this, & amp;Widget::isSignal, this, & amp;Widget::isSlot);

    //Send signal:
    emit isSignal(1);
}

Widget::~Widget()
{<!-- -->
}


// Implementation of slot function:
void Widget::isSlot(int slot){<!-- -->
    QString qString;
    qDebug()<< "I am the slot function, and the signal I received is:" << qString.number(slot);
}

Program output:

I am a slot function, and the signal I received is: "1"

Note: We do not directly assign a value to the variable slot of the slot function. ==The value of the slot of the slot function is passed from the signal of the signal==.

2. How to pass parameters in signal slots

  1. The parameters of the signal and slot functions must be in one-to-one correspondence. For example, if the parameters of the signal are int, the parameters of the slot function should also be int.

Signal:

signals:
    void isSignal(int signal = 0);

Slot definition:

public slots:
    void isSlot(int slot);

Slot implementation:

void Widget::isSlot(int slot){<!-- -->
    QString qString;
    qDebug()<< "I am the slot function, and the signal I received is:" << qString.number(slot);
}

Send signal:

emit isSignal(1);

Program output:

I am a slot function, and the signal I received is: "1"

It can be seen that after the signal is sent, the parameter value “1” of the signal function’s signal has been successfully passed to the slot function’s receiving variable slot, slot = 1.

  1. When the number of parameters of the signal and the number of parameters of the slot function are different, the number of parameters of the signal can only be greater than the number of parameters of the slot function. And the same number of parameters in the front should be of the same type. The excess parameters in the signal should be the same. will be ignored.

Signal:

signals:
    void isSignal(int signal = 0, QString s = "I am a signal");

Slot definition:

public slots:
    void isSlot(int slot);

Slot implementation:

void Widget::isSlot(int slot){<!-- -->
    QString qString;
    qDebug()<< "I am the slot function, and the signal I received is:" << qString.number(slot);
}

Send signal:

emit isSignal(2, "Hello");

Program output:

I am a slot function, and the signal I received is: "2"

It can be seen that after the signal is sent, the parameter value “2” of the signal function’s signal is successfully passed to the slot function’s receiving variable slot, slot = 2. And s = “hello” is ignored.

3. Signals and slots are overloaded

  1. teacher.h
signals:
    void hungry();

    void hungry(QString foodName);

  1. student.h & amp; & amp; student.cpp
public slots:
    void treat();

    void treat(QString foodName);


    
void Student::treat(){<!-- -->
    qDebug()<<"Invite the teacher to dinner";
}

void Student::treat(QString foodName){<!-- -->
     qDebug()<<"Invite the teacher to dinner, eat:" << foodName.toUtf8().data();
}

  1. widget.h
#include "teacher.h"
#include "student.h"

class Widget : public QWidget
{<!-- -->
public:
    Teacher * ls;
    Student * st;
};

  1. widget.cpp
#include "widget.h"
#include <QPushButton>
#include <QDebug>

//Teacher class teacher class
//student class student class
//After class, the teacher will trigger a signal. If they are hungry, the students will respond to the signal and treat them to dinner.


Widget::Widget(QWidget *parent) : QWidget(parent)
{<!-- -->
    //Create a teacher object
    this->ls = new Teacher(this);
    //Create a student object
    this->st = new Student(this);

     //Connect signals and slots without parameters--1
    void (Teacher:: * teacherSignal_void)(void) = & amp;Teacher::hungry;
    void (Student:: * studentSlot_void)(void) = & amp;Student::treat;
    connect(ls,teacherSignal_void,st,studentSlot_void);
    emit ls->hungry();

    qDebug()<<"---------------";

    //Connect signals and slots with parameters--2
    void (Teacher:: * teacherSignal)(QString) = & amp;Teacher::hungry;
    void (Student:: * studentSlot)(QString) = & amp;Student::treat;
    connect(ls,teacherSignal,st,studentSlot);
    emit ls->hungry("Gongbao Chicken");
}

Widget::~Widget()
{<!-- -->
}

Program output:

Invite the teacher to dinner
---------------
Invite the teacher to dinner and eat: Kung Pao Chicken

In addition, we can set a parent object for the QObject object through the setParent function.

//Create a teacher object
this->ls = new Teacher(this);
//Create a student object
this->st = new Student(this);

When a parent object is destroyed, it automatically destroys all of its child objects. This means that there is no need to manually manage the destruction of child objects, reducing the burden on developers and ensuring that these child objects are properly released when they are no longer needed.

4. How to connect signals and slots before QT4 version

Bottom SIGNAL(“”hungry””), SLOT(“treat”)

connect( zt, SIGNAL( hungry() ), st, SLOT( treat() ) );

Advantages: The parameters are intuitive. Disadvantages: The type is not detected.

5. The parameters of signals and slots do not correspond – use Lambda expressions

widget.cpp

#include "widget.h"
#include <QPushButton>
#include <QDebug>
 
//Teacher class teacher class
//student class student class
//After class, the teacher will trigger a signal. If they are hungry, the students will respond to the signal and treat them to dinner.
 
 
Widget::Widget(QWidget *parent) : QWidget(parent)
{<!-- -->
    //Create a teacher object
    this->zt = new Teacher(this);
    //Create a student object
    this->st = new Student(this);
    //Click a button to finish class
    QPushButton * btn = new QPushButton("get out of class is over",this);
    setFixedSize(600,400);
 
    //Connect signals and slots with parameters
    //Pointer->address, function pointer->function address
    void (Teacher::*teacherSignal)(QString) = & amp;Teacher::hungry;
    void (Student::*studentSlot)(QString) = & amp;Student::treat;
    connect(zt,teacherSignal,st,studentSlot);
 
    //Signal connection signal One signal triggers another signal
    //------------------------------------------------ -----
 
    connect(btn, & amp;QPushButton::clicked,zt,teacherSignal);
 
    //------------------------------------------------ -----
}
 
 
Widget::~Widget()
{<!-- -->
}
 

Key Analysis:

Widget(QWidget *parent = nullptr);

Widget::Widget(QWidget *parent) : QWidget(parent)
{<!-- -->
QPushButton * btn = new QPushButton("get out of class is over",this);
}

parent = 0, indicating that the Widget is a top-level window. ·new QPushButton(this)· is to make the btn object depend on the myWidget window.

Program error:

static assertion failed: Signal and slot arguments are not compatible

The prototype of the clicked signal is:

void clicked(bool checked = false)

The prototype of the hungry slot is:

 void hungry(QString foodName);

The reason is that the parameters of the signal do not correspond to the parameters of the slot function. The types of bool and QString are different.

Correct way to write:

Will

connect(btn, & amp;QPushButton::clicked,zt,teacherSignal);

Change to:

connect(btn, & amp;QPushButton::clicked, this, [this](){<!-- -->
     emit ls->hungry("Gongbao Chicken");
});

or:

connect(btn, & amp;QPushButton::clicked, [this](){<!-- -->
     emit this->ls->hungry("Gongbao Chicken");
});

The connect has only three parameters. In the case of three parameters, the default object of the third slot function is this class, that is, the third parameter this is omitted.

If the third parameter is this and the fourth parameter is a Lambda expression, the third parameter this can be omitted.

Personal measurement, the third parameter can also be written as ls:

connect(btn, & amp;QPushButton::clicked, ls, [this](){<!-- -->
     emit ls->hungry("Gongbao Chicken");
});

Program output:

Invite the teacher to dinner and eat: Gongbao Chicken
Invite the teacher to dinner and eat: Kung Pao Chicken
Invite the teacher to dinner and eat: Kung Pao Chicken
Invite the teacher to dinner and eat: Kung Pao Chicken

Reference connection:

“Qt5: Examples of using signals and slots”

Qt error: static assertion failed: Signal and slot arguments are not compatible

How signals and slots pass parameters (or signal slots with parameters)