信号和槽的概念
什么是信号和槽,就是说通过connect函数将信号和槽函数连接起来,当信号发出的时候回触发槽函数自动执行。
QObject::connect(const QObject *sender,
const char *signal,
const QObject *receiver,
const char *method,
Qt::ConnectionType type = Qt::AutoConnection)
一般就只用前四个参数
需要注意的是,信号和槽函数的参数类型要一致。如果不一致,信号的参数要比槽函数的参数多。即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。
这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少),但是不能说信号根本没有这个数据,你就要在槽函数中使用(就是槽函数的参数比信号的多,这是不允许的)。
如何自定义信号和槽?
- 创建接收和发送的类,类都需要继承QObject这个类
- 信号发送者,在类中添加signals代码块,信号就放到这个函数中(信号实际上也是个带参数的函数,不过是void类型的)。
- 信号接收者,创建好槽函数,在public slots代码块中
- 通过connect来连接信号和槽
- 通过emit语句来发送信号
只有继承了QObject类的类,才具有信号槽的能力。 所以,为了使用信号槽,必须继承QObject。 凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT 。
信号就是一个个的函数名,返回值是 void(因为无法获得信号的返回值,所以也就无需返回任何值),参数是该类需要让外界知道的数据。信号作为函数名,不需要在 cpp 函数中添加任何实现。
Qt 5 中,任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数。l
与信号函数不同,槽函数必须自己完成实现代码。槽函数就是普通的成员函数,因此作为成员函数,也会受到 public、private 等访问控制符的影响。(如果信号是 private 的,这个信号就不能在类的外面连接,也就没有任何意义。)
自定义信号和槽的注意事项
- 发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
- 使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;
- 槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
- 使用 emit 在恰当的位置发送信号;
- 使用QObject::connect()函数连接信号和槽。
- 任何成员函数、static 函数、全局函数和Lambda 表达式都可以作为槽函数
信号和槽的更多用法
-
一个信号可以和多个槽相连
如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。
-
多个信号可以连接到一个槽
只要任意一个信号发出,这个槽就会被调用
-
一个信号可以连接到另外的一个信号
当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。
-
槽可以被取消链接
这种情况并不经常出现,因为 当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽 。
-
使用Lambda 表达式
QObject::connect(&newspaper, static_cast<void (Newspaper:: *) (const QString &)>(&Newspaper::newPaper), [=](const QString &name) { /* Your code here. */ });
Lambda表达式,一般常用的就是
[=](参数列表){函数体}
即可,一般方括号内就填=就好,就是值传递的意思
随手记录
-
QApplication是干什么的?
这个QApplication是用于管理GUI程序和控制流的主要设置。
对于用Qt写的任何一个GUI应用,不管这个应用有没有窗口或多少个窗口,有且只有一个QApplication对象。
而对于用Qt写的非GUI应用,则有且只有一个QCoreApplication对象,并且这个应用不依赖QtGui库。
它必须在创建其他与用户界面相关的类之前创建可以把这个QApplication理解为是一个进程,其中该进程中可以有多个线程
-
可以常见在QT中有.show的操作
这种操作是干嘛的?
实际上show方法就是将对象的窗口及其子对象的窗口全都显示出来。