Selecting Overloaded Signals and Slots
With the string-based syntax, parameter types are explicitly specified. As a result, the desired instance of an overloaded signal or slot is unambiguous.
In contrast, with the functor-based syntax, an overloaded signal or slot must be casted to tell the compiler which instance to use.
For example, QLCDNumber has three versions of the display()
slot:
QLCDNumber::display(int)
QLCDNumber::display(double)
QLCDNumber::display(QString)
To connect the int
version to QSlider::valueChanged(), the two syntaxes are:
auto slider = new QSlider(this);
auto lcd = new QLCDNumber(this);
// String-based syntax
connect(slider, SIGNAL(valueChanged(int)),lcd, SLOT(display(int)));
// Functor-based syntax, first alternative
connect(slider, &QSlider::valueChanged,lcd, static_cast<void (QLCDNumber::*)(int)>(&QLCDNumber::display));
// Functor-based syntax, second alternative
void (QLCDNumber::*mySlot)(int) = &QLCDNumber::display;
connect(slider, &QSlider::valueChanged,lcd, mySlot);
// Functor-based syntax, third alternative
connect(slider, &QSlider::valueChanged,lcd, QOverload<int>::of(&QLCDNumber::display));
// Functor-based syntax, fourth alternative (requires C++14)
connect(slider, &QSlider::valueChanged,lcd, qOverload<int>(&QLCDNumber::display));
See also qOverload().
Widgets and Dialogs with Auto-Connect
Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
void treat();
void treat(QString food);
};
#endif // STUDENT_H
Student.cpp
#include "Student.h"
#include <QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat()
{
qDebug()<<"请老师吃饭"<<endl;
}
void Student::treat(QString food)
{
//qDebug()<<"请老师吃"<<food<<endl;
//QString 转char*
//QByteArray toUtf8() const
//const char * data() const
qDebug()<<"请老师吃"<<food.toUtf8().data()<<endl;
}
Teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
void hungry();
void hungry(QString food);
};
#endif // TEACHER_H
Teacher.cpp
#include "Teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "Teacher.h"
#include "Student.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void classOver();
private:
Teacher* teacherZhang;
Student* studentWang;
};
#endif // WIDGET_H
Widget.cpp
#include "Widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
teacherZhang = new Teacher(this);
studentWang = new Student(this);
/*可以这么些
*connect(teacherZhang,SIGNAL(hungry(QString)),studentWang,SLOT(treat(QString)));
*connect(teacherZhang,SIGNAL(hungry()),studentWang,SLOT(treat()));
*/
//也可以这么写
//当信号和槽出现函数重载,需要使用函数指针来明确指明函数地址
//void Teacher::hungry(QString food);带参数函数指针
void (Teacher::* teacherNoSignal)(void) = &Teacher::hungry;
//void Student::treat(QString food);带参数函数指针
void (Student::* studentNoSlot)(void) = &Student::treat;
connect(teacherZhang,teacherNoSignal,studentWang,studentNoSlot);
//当信号和槽出现函数重载,需要使用函数指针来明确指明函数地址
//void Teacher::hungry(QString food);带参数函数指针
void (Teacher::* teacherSignal)(QString) = &Teacher::hungry;
//void Student::treat(QString food);带参数函数指针
void (Student::* studentSlot)(QString) = &Student::treat;
connect(teacherZhang,teacherSignal,studentWang,studentSlot);
classOver();
}
Widget::~Widget()
{
}
void Widget::classOver()
{
emit teacherZhang->hungry();
emit teacherZhang->hungry("apple");//因为函数指针是带参数的,只有这个被执行
}
main.cpp
#include "Widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
使用自动连接来试试
Teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
void hungry();
void hungry(QString food);
};
#endif // TEACHER_H
Teacher.cpp
#include "Teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "Teacher.h"
#include "Student.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void classOver();
private:
Teacher* teacherZhang;
Student* studentWang;
public slots:
void on_teacherZhang_hungry(void);
void on_teacherZhang_hungry(QString food);
};
#endif // WIDGET_H
Widget.cpp
#include "Widget.h"
#include <QPushButton>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
teacherZhang = new Teacher(this);
teacherZhang->setObjectName(QStringLiteral("teacherZhang"));
QMetaObject::connectSlotsByName(this);
classOver();
}
void Widget::classOver()
{
emit teacherZhang->hungry();
emit teacherZhang->hungry("apple");
}
void Widget::on_teacherZhang_hungry()
{
qDebug()<<"请老师吃饭"<<endl;
}
void Widget::on_teacherZhang_hungry(QString food)
{
qDebug()<<"请老师吃"<<food.toUtf8().data()<<endl;
}
#include "Widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}