QT使用信号与槽注意事项

版权声明:本文为itas109原创文章,未经允许不得转载引用或用于商业用途。【http://blog.csdn.net/itas109】【[email protected]】 https://blog.csdn.net/itas109/article/details/84592695

QT使用信号与槽注意事项


如需转载请标明出处:http://blog.csdn.net/itas109
QQ技术交流群:129518033

目录

环境:
QT版本:5.6.2
VS版本:VS2013
系统版本:windows 7 64bit


前言

Qt 信号槽一直以来都是QT的核心之一。但是,大家真的对信号的槽非常了解吗?下面介绍的一些内容,你可能并不知道。

1.基本用法

QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect(lineEdit, &QLineEdit::textChanged,label,  &QLabel::setText);

2.slots的函数用法

函数原型:

QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)

使用:

void someFunction();

QPushButton *button = new QPushButton;
QObject::connect(button, &QPushButton::clicked, someFunction);

3.slots的lambda表达式

QByteArray page = ...;
QTcpSocket *socket = new QTcpSocket;
socket->connectToHost("qt-project.org", 80);
QObject::connect(socket, &QTcpSocket::connected, [=] () {socket->write("GET " + page + "\r\n");});

4.断开连接到对象信号的所有Object

disconnect(myObject, 0, 0, 0);

等同于

myObject->disconnect();

5.断开连接到特定信号的所有Object

    disconnect(myObject, SIGNAL(mySignal()), 0, 0);

等同于

myObject->disconnect(SIGNAL(mySignal()));

6.断开特定接收者

disconnect(myObject, 0, myReceiver, 0);

等同于

myObject->disconnect(myReceiver);

7.connect函数的第5参数Qt::ConnectionType

参数 说明
Qt::AutoConnection 0 (默认)如果接收者位于发出信号的线程中,则使用Qt :: DirectConnection。 否则,使用Qt :: QueuedConnection。 连接类型在发出信号时确定
Qt::DirectConnection 1 发出信号时立即调用插槽。 插槽在信号线程中执行。相当于槽函数直接执行,执行完之后,才继续执行信号的后续内容
Qt::QueuedConnection 2 槽函数在控制回到接收者所在线程的事件循环时被调用。 槽函数在接收者的线程中执行。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用
Qt::BlockingQueuedConnection 3 与Qt :: QueuedConnection相同,除了信号线程阻塞直到槽返回。 如果接收者与信号位于同一线程中,则不得使用此连接,否则程序将会死锁
Qt::UniqueConnection 0x80 这是一个可以使用按位OR与上述任何一种连接类型组合的标志。 当设置Qt :: UniqueConnection时,如果连接已经存在,QObject :: connect()将失败(即,如果相同的信号已连接到同一对对象的相同插槽)。 这个标志是在Qt 4.6中引入的

这里需要注意的是一般我们都是采用默认参数Qt::AutoConnection。但是,需要注意有时可能会出现问题。
例如,我们要在登录成功后关闭当前界面。实现如下:

void login()
{
...
//验证完毕,返回登录成功信号
emit loginSuccess();
this->hide();
}

如果此时我们采用Qt::AutoConnection,并且信号与槽位于同一线程,那么QT会自动为我们选择为Qt::DirectConnection方式。也就是必须等待信号对应的槽函数执行完,才能执行hide操作。这是如果槽函数是一个耗时操作,那么就会出现无法hide的情况,这种情况下,我们需要手动设置Qt::QueuedConnection或者将hide函数在emit之前执行。

总结一下就是emit函数之后的内容的执行顺序与信号与槽的连接方式有关。如果需要立即执行emit之后的函数,就需要设置为Qt::QueuedConnection,如果要立即执行槽函数,就需要设置为Qt::QueuedConnection。

8.QObject::connect: Cannot queue arguments of type ‘XXX’

出现这个错误是由于对于Qt::QueuedConnection连接,参数必须是Qt的元对象系统已知的类型,因为Qt需要复制参数以将它们存储在幕后的事件中。
在建立连接之前,请调用qRegisterMetaType()注册数据类型。

9.QTimer的 singleShot

函数原型:

[static] void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
QTimer::singleShot(100,this, &A::function());
QTimer::singleShot(100,[=]{qDebug() << "time out"; });

Reference:

  1. http://doc.qt.io/qt-5.6/qobject.html#connect-2
  2. http://doc.qt.io/qt-5.6/qt.html#ConnectionType-enum

觉得文章对你有帮助,可以用微信扫描二维码捐赠给博主,谢谢!
微信
如需转载请标明出处:http://blog.csdn.net/itas109
QQ技术交流群:129518033

猜你喜欢

转载自blog.csdn.net/itas109/article/details/84592695