QT里面信号与槽问题

QT里面信号与槽问题,第1张

两个参数不同不能直接用connect来连接。 你可以先定义一个AAAslot(OrderId orderId,const Contract& contract,const Order& order,const OrderState& ostate ) 连接:connect(this, SIGNAL(send(OrderId orderId,const Contract& contract,const Order& order,const OrderState& ostate),this, SLOT(AAAslot(OrderId orderId,const Contract& contract,const Order& order,const OrderState& ostate )))); void AAA::AAAslot(OrderId orderId,const Contract& contract,const Order& order,const OrderState& ostate){ ///然后在这里再用emit发送一个跟receive(OrderId orderId,const Contract& contract,const Order& order)对面的信号。 }

我们知道Qt以他的signal和slot机制独步天下。但大家在用的时候有没有注意过,signal和slot是异步的,还是同步的呢?为此我问过不少Qt的使用者,有人说是同步的,有人说是异步的,也有人说着要看Qt的当时心情了¥%&

其实是异步还是同步,是用户决定的。如果大家仔细看过connect函数的介绍就知道,connect最后的有一个参数Qt::ConnectionType type 他将决定是异步还是同步(具体的类型可以参见帮助)。只不过平常我们使用的时候,他默认成了Qt::AutoConnection。有的兄台看到这里的时候,就会问,啥是Auto模式。其实Auto模式,就是看Qt的心情来决定是异步还是同步。而决定这个心情的就是,sender和receiver的他们分别所处的线程。如果是同一线程则就是同步调用,如果不在同一线程就是异步调用。

但真相果真如此吗?正像青春永驻的柯南君所指出的,真相永远都隐藏在表面之下。

请各位看官思考以下案例:

class A : public QObject

emit是发射信号用的

signal 信号关键字

例如类中定义了一个信号

class A{

signals:

void changed(bool);

void test();

};

然后在类中的其它成员函数中可以发射这个信号

void A::text(){

emit changed(true); //信号changed会被发射出去

}

有人说用function+lambda

我想说Qt5开始已经支持将一个信号直连(不支持队列连)到一个或者多个lambda

至少现在看,用Qt开发的程序有充分理由用signal+slot,比如说线程安全、和moc充分融合、使用方便、可以使函数具备元对象信息(这也是受益于moc)等等优点

但是signal+slot也不是万能的,抛弃signal+slot最有可能的就是少数情况下的性能考虑。比如说一个一秒钟要调用几十万次的函数,这个就要考虑用其他方式来实现了。

总结说,用Qt开发的程序尽管使用signal+slot的组合就行。除非做一些优化。

如果不是Qt开发的程序,额,那怎么会用signal+slot呢。。。

        使用QT开发时,我们一般要使用到信号槽机制,这个机制由三部分组成:信号、槽、连接函数connect,我们主要 说下connect函数,了解清楚此函数,信号槽机制也基本上懂了。我们一般情况下我们使用connect函数只传递四个参数:

connect(Sender,SIGNAL(signal),Receiver,SLOT(slot));

        这四个参数分别是发送者对象、发送者对象发送的信号、接收者对象、接收者对象响应该信号的槽函数,所以我们有可能认为该函数就只有四个参数,但实际上是有第五个参数的,只是通常该函数已经给第五个参数赋值了而已,我们所使用的是默认值。实际上connect函数应该是如下形式:

bool QObject::connect ( const QObject sender, const char signal, const QObject receiver, const char method, Qt::ConnectionType type = Qt::AutoConnection )

Qt::DirectConnection参数 参数含义

Qt::AutoConnection 默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。

Qt::DirectConnection 槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成奔溃。

Qt::QueuedConnection 槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。

Qt::BlockingQueuedConnection 槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。

Qt::UniqueConnection 这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。

sender和receiver是QObject对象指针,函数里面我们用到了Qt提供的两个宏SIGNAL()和SLOT();这是Qt要求的,要关联信号和槽必须借助于这两个宏,两个宏的定义如下:

#define SLOT(name) "1"#name

#define SIGNAL(name) "2"#name

        通过这两个宏,就可以把我们传递进去的槽和信号的名字转化成字符串,并在这两个字符串前面加上附加的字符。Qt5又在此基础上扩展了一种写法不必用到两个宏SIGNAL()和SLOT(),而是直接写&类名::信号或者&类名::槽函数。一个信号可以和多个槽相连;也可以多个信号可以连接一个槽;也有一个信号可以连接到另一个信号;一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽,有时候我们需要手动去断开连接,如下情况:

        有时我们程序中某些情况下某个 *** 作需要断开这个信号槽连接, *** 作结束后有需要重新连接,断开连接时,那我们需要调用函数

bool QObject::disconnect ( const QObject sender, const char signal, const QObject receiver, const char method )

用法和connect大致相同。

以上就是关于QT里面信号与槽问题全部的内容,包括:QT里面信号与槽问题、Qt的signal和slot是同步的,还是异步的、qt中emit与signal区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9630720.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存