Qt从入门到放弃
知识点
信号和槽的概念
信号和槽机制是QT自行定义的一种通信机制,实现对象之间的数据交互,当某个对象状态发生改变时将会发送信号,该函数可以被其他对象接收,接收后会执行一个指定的操作(槽)
信号和槽的定义
class QXX:public QObject{
Q_OBJECT //元对象编译器(moc)
signals:
void mySignal(...);//信号
访问控制限定符 slots:
void mySlot(...){...}//槽
};
注意:
1>使用信号和槽机制必须是QObject的直接子类或间接子类
2>信号函数只需要声明,不能定义
3>槽可以被某个信号触发执行,也可以像普通成员函数一样直接调用
信号
-
信号声明时使用
signals:
关键字 -
信号的返回值是
void
-
信号可以有参数,也可以发生重载
-
信号只需要声明,不需要定义
-
信号的触发使用
emit
关键字
槽
- 槽需要声明也需要定义,可以带参数,可以重载
- 槽函数在早期要写在
public slots:
下,5.6以及高版本可以直接写在public:
里,或者是全局函数(建议还是写在public slots:
中,代码可读性高,后期维护方便) - 槽函数可以作为普通函数调用
信号和槽的连接
connect
函数原型
[static] QMetaObject::Connection QObject::connect(
const QObject *sender,
const QMetaMethod &signal,
const QObject *receiver,
const QMetaMethod &method,
Qt::ConnectionType type = Qt::AutoConnection);
参数:
sender: 信号的发送对象(QObject任何子类对象)
signal: 信号函数()
注:SIGNAL(信号函数(参数))//将信号函数转换为const char*
receiver: 要执行槽函数的接收对象(OBject任何子类对象)
method: 槽函数
注:SLOT(槽函数(参数))//将槽函数转换为const char*
- 调用格式
connect(信号发送的对象,SIGNAL(信号函数(参数)),信号接收对象,SLOT(槽函数(参数)));
信号和槽的连接注意事项
- 信号函数的参数和槽函数的参数要保持一致
QObject::connect(A,SIGNAL(sigfunc(int)),B,SLOT(slotfunc(int)));//ok
//QObject::connect(A,SIGNAL(sigfunc(void)),B,SLOT(slotfunc(int)));//error
- 槽函数可以带有缺省参数
class B:public QObject{
public slots:
void slotfunc(int = 0){}
};
QObject::connect(A,SIGNAL(sigfunc(void)),B,SLOT(slotfunc(void)));
- 信号函数的参数可以多于槽函数的参数,多于的参数将会被槽函数忽略
QObject::connect(A,SIGNAL(sigfunc(int)),B,SLOT(slotfunc(void)));//ok
- 一个信号可以同时连接多个槽函数
QObject::connect(A,SIGNAL(sigfunc(int)),B1,SLOT(slotfunc1(int)));//ok
QObject::connect(A,SIGNAL(sigfunc(int)),B2,SLOT(slotfunc2(int)));//ok
//注:当A信号被发送时,连接的B1,B2两个槽函数都将会被执行
- 多个信号连接到同一个槽函数上
QObject::connect(A1,SIGNAL(sigfunc1(int)),B,SLOT(slotfunc(int)));//ok
QObject::connect(A2,SIGNAL(sigfunc2(int)),B,SLOT(slotfunc(int)));//ok
//注:不论多个信号中的哪一个发送了信号,都会触发槽函数
- 两个信号可以直接连接作用相当于触发一个信号后另一个信号也被触发
QObject::connect(A1,SIGNAL(sigfunc1(int)),A2,SIGNAL(sigfunc2(int)));//ok
//注:当一个信号被发送后所连接的另外的信号也将会被发送
信号的触发
-
信号的触发使用
emit
关键字
-
信号的触发要在信号和槽函数连接之后才会有效果
demo运行效果
程序运行时将在widget类的构造函数中调用老师类中的信号触发函数,从而触发信号的发送,再由学生类中的绑定的相应的槽函数来打印相关信息
文件结构
代码
signalAndSlot.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
student.cpp \
teacher.cpp \
widget.cpp
HEADERS += \
student.h \
teacher.h \
widget.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
头文件
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();
};
#endif // WIDGET_H
teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class teacher : public QObject
{
Q_OBJECT
public:
explicit teacher(QObject *parent = nullptr);
void classover();
signals:
void hungry();
};
#endif // TEACHER_H
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 feast();
};
#endif // STUDENT_H
.cpp文件
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
teacher* t = new teacher;
student* s = new student;
connect(t,&teacher::hungry,s,&student::feast);
t->classover();
}
Widget::~Widget()
{
}
teacher.cpp
#include "teacher.h"
teacher::teacher(QObject *parent) : QObject(parent)
{
}
void teacher::classover()
{
emit hungry();
}
student.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}