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
    评论
### 回答1: QObject::connect函数可以用来建立对象之间的信号和槽的连接,可以使一个对象的信号触发另一个对象的槽函数。它的用法是:QObject::connect(sender, signal, receiver, slot)。 ### 回答2: QObject::connect函数是Qt中用于建立信号与槽连接的函数,它的语法如下: QObject::connect(sender, signal, receiver, slot, connectionType); 其中,sender是发送信号的对象,signal是发出的信号,receiver是接收信号的对象,slot是处理信号的槽函数。connectionType是一个可选参数,用于指定连接的类型,默认为Qt::AutoConnection。 使用QObject::connect函数,首先需要确定信号和槽函数的声明,然后可以在程序的任意位置调用该函数进行连接。例如,假设有一个按钮对象button和一个槽函数slotFunction,可以使用以下代码连接信号与槽: QObject::connect(button, SIGNAL(clicked()), this, SLOT(slotFunction())); 在这个例子中,当按钮被点击时,会触发一个clicked信号,然后会调用槽函数slotFunction来处理该信号。 连接时还可以使用lambda表达式来代替槽函数,例如: QObject::connect(button, &QPushButton::clicked, [](){ qDebug() << "Button clicked"; }); 这里使用了C++11的lambda表达式作为槽函数,当按钮被点击时,会输出一条调试信息。 需要注意的是,QObject::connect函数只能连接QObject或其子类的实例之间的信号与槽,且槽函数必须是可调用的(可以是普通函数、成员函数、静态函数等)。 总结而言,QObject::connect函数是Qt中用于建立信号与槽连接的重要函数,它的使用需要理解信号与槽的声明,并进行正确的参数传递。 ### 回答3: QObject::connect函数用于建立信号和槽之间的连接,使得当信号触发时,槽函数会被自动调用。 函数的基本语法如下: connect(sender, signal, receiver, slot, Qt::ConnectionType); 其中,sender是发送信号的对象,signal是发送的信号,receiver是接收信号的对象,slot是接收信号调用的槽函数。 例子: 我们有一个名为button的QPushButton对象,我们想在用户点击按钮时触发一个名为myFunction的槽函数。 首先,我们需要在Qt头文件中声明和定义槽函数myFunction。 然后,在我们的代码中,我们可以连接按钮的clicked信号和myFunction槽函数,如下所示: QObject::connect(button, &QPushButton::clicked, this, &MyClass::myFunction); 在这个例子中,button是发送clicked信号的对象,&QPushButton::clicked表示clicked信号,this是接收信号的对象,&MyClass::myFunction表示myFunction槽函数。 最后一个参数Qt::ConnectionType是可选的,默认为Qt::AutoConnection,会根据发送和接收对象的线程自动选择信号的连接方式。你可以根据需要使用其他连接方式。 总结起来,QObject::connect函数简单地描述了信号和槽之间的连接关系,使得当信号发出时,槽函数会被自动调用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值