一.信号和槽机制
信号和槽:是对象之间通信的一种机制
信号classA不关心有多少槽函数与之绑定,它只管触发信号,具体要触发哪些槽函数,是由Qt的信号和槽机制来实现的。这样的话就充分的体现了面向对象的解耦原则了,因为对于classA来说,他的任务就是将信号发出去,而这个信号发生了什么与classA无关,各自完成各自的事情,
1.信号和槽是如何建立连接的?
元对象编译器(moc)在编译过程中会对包含Q_OBJECT宏的类进行处理,生成额外的代码来实现信号和槽的连接和调用。
2.信号的声明与实现:
在类的定义中,信号使用signals关键字进行声明。例如:signals: void mySignal();。信号的声明类似于函数声明,但它们没有实现部分,并且返回类型必须为void或者没有返回类型。 当一个对象发出信号时,实际上是调用了一个由元对象编译器生成的函数。这个函数会遍历所有连接到该信号的槽,并调用它们。
3.槽的声明与实现
槽是普通的成员函数,可以在任何继承自QObject的类中声明和实现。槽函数的声明和普通函数类似,但可以使用slots关键字进行标记。例如:public slots: void mySlot();。 槽函数可以有任意的参数和返回类型,但必须与连接的信号的参数和返回类型相匹配。
4.连接信号和槽:
在 Qt 中,可以使用connect函数来连接信号和槽。例如:connect(sender, SIGNAL(mySignal()), receiver, SLOT(mySlot()));。这里sender和receiver是指向QObject对象的指针,SIGNAL和SLOT是宏,用于将信号和槽的函数名转换为字符串。 connect函数的底层实现会在元对象系统中查找信号和槽的信息,并建立连接。连接信息会被存储在一个内部的数据结构中,以便在信号发出时能够快速地找到并调用相应的槽函数。
5.信号的发射:
当一个对象需要发出信号时,可以使用emit关键字来调用信号。例如:emit mySignal();。 当信号被发射时,元对象系统会根据连接信息找到所有连接到该信号的槽函数,并依次调用它们。调用的顺序是不确定的,除非使用Qt::DirectConnection连接方式,此时槽函数会在发出信号的线程中立即执行。
6.connect第五个参数的几种类型?
其中第五个参数是Qt::ConnectionType类型,用于指定连接的类型,主要有以下几种: 1.Qt::AutoConnection:这是默认的连接类型。如果信号和槽在同一线程中,它的行为类似于Qt::DirectConnection;如果信号和槽在不同线程中,它的行为类似Qt::QueuedConnection。
2.Qt::DirectConnection:当信号发出时,槽函数会立即在发出信号的线程中执行。这种连接方式类似于普通的函数调用。
3.Qt::QueuedConnection:当信号发出时,槽函数会在接收对象所在的线程的事件循环中执行。如果接收对象所在的线程没有事件循环,那么这个连接将无法工作。这种连接方式允许在不同线程之间进行安全的信号和槽连接。
4.Qt::BlockingQueuedConnection:与Qt::QueuedConnection类似,但发出信号的线程会阻塞,直到槽函数返回。这种连接方式应该谨慎使用,因为它可能导致死锁。 5/Qt::UniqueConnection:这个标志可以通过按位或与其他连接类型组合使用。它可以防止重复连接相同的信号和槽,如果已经存在相同的连接,connect函数将返回false。