qt qt wineventfilterr 会不会disconnect信号和槽

信号槽是QT中用于对象间通信的一种机制,也是QT的核心机制。在GUI编程中,我们经常需要在改变一个组件的同时,通知另一个组件做出响应。例如:
一开始我们的Find按钮是未激活的,用户输入要查找的内容后,查找按钮就被激活,这就是输入框与Find按钮这两个组件间通信的例子。
早期,对象间的通信采用回调来实现。回调实际上是利用函数指针来实现,当我们希望某件事发生时处理函数能够获得通知,就需要将回调函数的指针传递给处理函数,这样处理函数就会在合适的时候调用回调函数。回调有两个明显的缺点:
它们不是类型安全的,我们无法保证处理函数传递给回调函数的参数都是正确的。
回调函数和处理函数紧密耦合,源于处理函数必须知道哪一个函数被回调。
在QT中,我们有回调技术之外的选择,也即是信号槽机制。所谓的信号与槽,其实都是函数。当特定事件被触发时(如在输入框输入了字符)将发送一个信号,而与该信号建立的连接槽,则可以接收到该信号并做出反应(激活Find按钮)。
QT组件预定义了很多信号和槽,而在GUI编程中,我们习惯于继承那些组件,继承后添加我们自己的槽,以便以我们的方式来处理信号。槽和普通的C++成员函数几乎是一样的,它可以是虚函数,可以被重载,可以是共有、私有或是保护的,也同样可以被其他成员函数调用。它的函数参数也可以是任意类型的。唯一不同的是:槽还可以和信号连接在一起。
与回调不同,信号槽机制是类型安全的。这体现在信号的函数签名与槽的函数签名必须匹配上,才能够发生信号的传递。实际上,槽的参数个数可以比信号的参数个数少,因为槽能够忽略信号形参中多出来的参数。信号和槽是松耦合的:发出信号的类不关心哪些类将接收它的信号。QT的信号槽机制吧哦这里在正确的时间,槽能够接收到信号的参数并调用。信号和槽都可以有任意个数的参数,它们都是类型安全的。
自定义信号和槽的一个例子
首先我们要知道的是,所有继承自QObject或者它的子类(如QWidget)都可以包含信号槽。我们写的类须继承自QObject(或其子类)。所有包含了信号槽的类都必须在声明的上部含有Q_OBJECT宏。
一个基于QObject的C++简单类:
#include&QObject&
#include&QString&
class MyStr :public QObject
Q_OBJECT //必须包含的宏
MyStr (){m_value = &zero&;}
QString value() const {return
public slots :
void setValue(QString value );
signals: //信号
void valueChanged(QString newValue);
QString m_
在这个简单的类中,我们可以看到,使用slots来表示槽,而使用signals来表示信号。实际上没有那么神秘,它们都是宏定义,甚至signals只是public的宏定义:
define signals public
Signal的代码会由 moc 自动生成,开发人员一定不能在自己的C++代码中实现它。
反之,槽应该由编程人员来实现,下面提供MyStr::setVaule()的一种可能实现
#include&MyStr.h&
void MyStr::setValue(QString value)
if(value != m_value)
emit valueChanged(value);
setValue函数首先比较新参的值与数据成员的值是否是一样的(后面有解释为何这样做),如果不是,则设置好数据成员m_value的值,然后,把信号valueChanged()发送出去。发送给谁?类并没有写,这并不是类设计者所关心的,也不是类所关心的,它只管把信号发送出去就行。然后,我们再来设置谁来接收这个信号。
int main(int argc, char *argv[])
QObject::connect(&a,SIGNAL(valueChanged(QString)),&b,SLOT(setValue(QString)));
a.setValue(&this is A&);
我们定义了两个类对象a/b,使用 QObject::connect()函数指定了发送方、信号、接收方、槽等信息,connect函数的格式如下:
QObject::connect(
SIGNAL(...),
当我们调用a的成员函数setValue时,该函数除了把a.m_value设置为&this is A&,也把信号valueChanged()发送出去,被b.setValue所接收,从而,把b.m_value设置为&this is A&,同时b.setValue又把valueChanged信号发射出去,然而该信号并没有对象接收,因为我们没有建立以b为发送方的任何连接。此时你应该明白,为何在emit前需要判断value != m_value,因为如果没有此步骤,且恰巧设置了
QObject::connect(&b,SIGNAL(valueChanged(QString)),&a,SLOT(setValue(QString)));
则b的信号被a接收,a又发送信号被b接收,如此进入死循环。
int main(int argc, char *argv[])
QApplication app(argc, argv);
QObject::connect(&a,SIGNAL(valueChanged(QString)),&b,SLOT(setValue(QString)));
a.setValue(&this is A&);
QLabel* label = new QLabel;
label-&setText( b.value());
label-&show();
return app.exec();
我们使用label输出来看看b是否接收到a的信号,如果是,则b的内容应该是&this is A&,输出在label上,程序运行结果:
这个例子展示了对象之间通信的一种方式。对象间可以一起工作,而不需要知道彼此的任何信息。为了达到通信的目的,只需要将它们连接起来,而这只需要通过 调用 QObject::connect() 函数指定一些简单信息就好。
要把信号成功连接到槽,它们的参数必须具有相同的顺序和相同的类型,或者允许信号的参数比槽多,槽会自动忽略掉多出来的参数而进行调用。
一个信号可以连接多个槽
使用QObject::connect可以把一个信号连接到多个槽,而当信号发射时,将按声明联系时的顺序依次调用槽。
//信号连接到两个槽
QObject::connect(&a,SIGNAL(valueChanged(QString)),&b,SLOT(setValue(QString)));
QObject::connect(&a,SIGNAL(valueChanged(QString)),&c,SLOT(setValue(QString)));
a.setValue(&this is A&);
//依次调用b.setValue()、c.setValue()
多个信号可以连接同一个槽
同样的,可以让多个信号连接到同一个槽上 ,而且其中的每一个信号的发送,都会调用了那个槽。
//两个信号连接到同一个槽
QObject::connect(&a,SIGNAL(valueChanged(QString)),&c,SLOT(setValue(QString)));
QObject::connect(&b,SIGNAL(valueChanged(QString)),&c,SLOT(setValue(QString)));
//下面的操作皆会调用到槽c.setValue()
a.setValue(&this is A&);
b.setValue(&this is B&);
一个信号可以和另外一个信号相连接
当发射第一个信号的时候,也会把第二个信号一个发送出去。
//两个信号相连接
QObject::connect(&a,SIGNAL(valueChanged(QString)),&b,SIGNAL(valueChanged(QString)));
//再建立b与c的连接
QObject::connect(&b,SIGNAL(valueChanged(QString)),&c,SLOT(setValue(QString)));
//下面的操作同时发送了信号a.valueChanged与b.valueChanged
a.setValue(&this is A&);
//从而信号b.valueChanged被槽c.setValue所接收
连接可以被移除
//移除b 与 c之间的连接
QObject::disconnect(&b,SIGNAL(valueChanged(QString)),&c,SLOT(setValue(QString)));
实际上当对象被delete时,其关联的所有链接都会失效,QT会自动移除和这个对象的所有链接。
感谢您耐心的阅读。
阅读(...) 评论()关于信号和槽 小问题 是否会打断呢【qt吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:36,904贴子:
关于信号和槽 小问题 是否会打断呢收藏
某个信号出现 然后执行一个槽函数
这时候又有信号来了 要进入另一个槽函数 会打断前一个正在执行的槽函数吗 ?
默认在一个线程里,函数应该是串行执行的。
如果你没有使用线程的话这种情况根本不会发生,整个程序同一时间只会存在一个信号,执行一个槽函数,只有在一个槽函数执行完毕后才可能会出现另一个信号.在槽函数执行期间是绝对不会出现另一个信号的,所以不用担心.
所以说槽不适合大规模运算…
同线程的话,emit信号会立即调用信号槽,阻塞原函数,等信号槽返回再继续回到原函数。不同线程的话,Qt使用队列来维护信号和信号槽,信号被发送后会存到消息队列中,各个线程使用消息循环来处理消息队列。不会发生同现成两个函数并行执行的现象。
同线程只相当于直接调用,你看哪里有一个线程能同时调用两个的,两个线程理所当然是并行
根据楼主的描述,相当于我在一个函数中同时发送2个信号去关联两个槽函数,这样是不冲突的,如下示例:void test() { emit signalTest1();sleep(1);emit signalTest2();}// 整个函数的执行顺序是由上往下的,2个信号不干涩,可同时执行。
登录百度帐号推荐应用关于QT信号槽与线程问题,小白求助_百度知道
关于QT信号槽与线程问题,小白求助
我有更好的答案
比如BlockingQueuedConnection模式,就会出现你说的多次触发信号阻塞问题,他只有等到上一个触发完成才能继续,槽函数运行的线程通常是异步调用,但是还有一个所谓的事件中心一直run着在处理,就是一个信号队列,没触发一个信号就入队列,那么要看信号和槽是否属于同一个线程(这里,你可以简单理解为是否是同一个类),然后根据connect的第五个属性来判断是否是同步还是异步,在同一个线程里面是同步的,你此时可以理解为普通调用,如果在不同线程里面。槽函数不会产生新线程,他是决定了槽函数声明在哪个线程中,如果默认情况下,实际上还有第五个参数(可以自己看SDK的介绍),哥大致给你介绍一下Qt的信号槽既可以同步触发,也可以异步触发。当你进行connect的时候关于QT信号槽与线程问题进程肯定不会产生了。Qt的信号槽是个很复杂的机制。如果说是默认的
采纳率:95%
来自团队:
为您推荐:
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。}

我要回帖

更多关于 qt wineventfilter 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信