QObject::sender()的用法

先从官方文档开始看起:

 [protected] QObject *QObject::sender() const

Returns a pointer to the object that sent the signal, if called in a
slot activated by a signal; otherwise it returns nullptr. The pointer
is valid only during the execution of the slot that calls this
function from this object’s thread context. The pointer returned by
this function becomes invalid if the sender is destroyed, or if the
slot is disconnected from the sender’s signal.

首先是告诉我们QObject::sender()获得的QObject *指针的有效性,在什么情况有效,什么情况下失效。

下面是两个Warning,写程序的时候,要注意Warning,看帮助文档也是这样:
(1)Warning: This function violates the object-oriented principle of modularity. However, getting access to the sender might be useful when many signals are connected to a single slot.
(2)Warning: As mentioned above, the return value of this function is not valid when the slot is called via a Qt::DirectConnection from a thread different from this object’s thread. Do not use this function in this type of scenario.
解读:
对第一个Warning的解读:这个函数违反了面向对象的模块化原则。然而,当许多信号连接到一个槽函数时,访问发送方可能是有用的。
警告的原因是这样做违反了面向对象的原则,直接可以获得发送这个信号的对象的指针(在槽函数中),当多个信号连接到一个槽函数的时候,槽函数要区分是谁发送的,这个就QObject::sender()就比较有效。

第二个Warning的解读:当通过Qt::DirectConnection从与此对象的线程不同的线程调用信号与槽时,此函数的返回值无效。不要在这种情况下使用此函数。这个又引出了另外一个问题,就是在跨线程连接的信号与槽时,第五个参数的作用。

[static] QMetaObject::Connection QObject::connect(
		const QObject *sender, 
		const char *signal, 
		const QObject *receiver, 
		const char *method,
 		Qt::ConnectionType type = Qt::AutoConnection)

第五个参数Qt::ConnectionType type = Qt::AutoConnection
默认是Qt::AutoConnection,当发送信号与槽函数处于同一个线程时,这个是

ConstantValueDescription
Qt::AutoConnection0(Default) If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.
Qt::DirectConnection1The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.
Qt::QueuedConnection2The slot is invoked when control returns to the event loop of the receiver’s thread. The slot is executed in the receiver’s thread.

Qt::AutoConnection的处理也很巧妙,当信号与槽函数都是在同一个线程中时,是Qt::DirectConnection直接相连,如果是不同线程,则是Qt::QueuedConnection。这个第五参数还有其他的枚举类型,这里就不展开了,在另外一篇博文里再详细理清它的用法,现在知道这些就足够了。
看看QObject::sender()怎么用:
例子一:

//在槽函数中,可以获得和这个槽函数相连的对象的指针
QTimeEdit *editor = qobject_cast<QTimeEdit *>(sender());

参考:https://blog.csdn.net/u013394556/article/details/39965667

这里插一句:qobject_cast()和C++标准中的dynamic_cast()作用类似,但是qobject_cast的速度要快,具体应用范围参考Qt帮助手册。

例子二:

qlonglong YHHttp::get(QString url, int timeout)
{
    QUrl u = QUrl::fromUserInput(url);
    if(u.path().isEmpty()){
        u.setPath("/");
    }
    QNetworkRequest request(u);
    setheader(&request);

    QNetworkReply *reply = d->manager.get(request);

    connect(reply, SIGNAL(finished()),
            this, SLOT(slotFinished()));

    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(slotError(QNetworkReply::NetworkError)));

    if(timeout!=0){
        QTimer* timer = new QTimer(reply);
        connect(timer,SIGNAL(timeout()),this,SLOT(slot_requestTimeout()));//超时信号
        timer->start(timeout);

    }
    return (qlonglong)reply;
}


void YHHttp::slot_requestTimeout()
{
    QNetworkReply *reply = static_cast<QNetworkReply*>(sender()->parent());
    emit_deviceevent("Timeout(qlonglong)", (qlonglong)(reply));
    reply->abort();
    reply->deleteLater();
    QNetworkSession(d->manager.configuration()).stop();
}

参考:https://www.cnblogs.com/warmSnowFY/p/11769834.html

这个例子就不得不说了,首先是用到的parent指针

 QTimer* timer = new QTimer(reply);
 connect(timer,SIGNAL(timeout()),this,SLOT(slot_requestTimeout()));//超时信号
timer->start(timeout);

//然后是在槽函数中
void YHHttp::slot_requestTimeout()
{
    QNetworkReply *reply = static_cast<QNetworkReply*>(sender()->parent());
	...
}

通过

QNetworkReply *reply = static_cast<QNetworkReply*>(sender()->parent());

有点奇技淫巧的感觉。

参考:
Qt工作笔记-对*QObject::sender()的认识
Qt中QObject::sender()的用法
https://www.cnblogs.com/warmSnowFY/p/11769834.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值