请教一个问题 日语关于信号槽的问题

FinderCheng 的BLOG
用户名:FinderCheng
文章数:123
评论数:1044
访问量:4627653
注册日期:
阅读量:5863
阅读量:12276
阅读量:358874
阅读量:1055000
51CTO推荐博文
信号槽的实现实例&& Qt 和 Boost
Qt 的信号槽和 Boost.Signals 由于有着截然不同的设计目标,因此二者的实现、强度也十分不同。将二者混合在一起使用也不是不可能的,我们将在本系统的最后一部分来讨论这个问题。
使用信号槽
信号槽是伟大的工具,但是如何能更好的使用它们?相比于直接函数调用,有三点值得我们的注意。一个信号槽的调用:
或许会比直接函数调用耗费更多的时间/空间;
可能不能使用 inline;
对于代码阅读者来说可能并不友好。
使用信号槽进行解耦,我们获得的最大的好处是,连接两端的对象不需要知道对方的任何信息。Button 同动作的连接是一个很典型的案例。例如如下信息:
class Elevator
enum Direction
{ DownDirection=-1, NoDirection=0, UpDirection=1 };
enum State
{ IdleState, LoadingState, MovingState };
// signals:
void floorChanged( int newFloor );
void stateChanged( State newState );
void directionChanged( Direction newDirection );
Elevator 类,也就是电梯,不需要知道有多少显示器正在监听它的信号,也不需要知道这些显示器的任何信息。每一层可能有一个屏幕和一组灯,用于显示电梯的当前位置和方向,另外一些远程操控的面板也会显示出同样的信息。电梯并不关心这些东西。当它穿过(或者停在)某一层的时候,它会发出一个 floorChanged(int) 信号。或许,交通信号灯是更合适的一个例子。
你也可以实现一个应用程序,其中每一个函数调用都是通过信号来触发的。这在技术上说是完全没有问题的,然而却是不大可行的,因为信号槽的使用无疑会丧失一部分代码可读性和系统性能。如何在这其中做出平衡,也是你需要考虑的很重要的一点。
了解 Qt 信号槽最好的莫过于 Qt 的文档。不过,这里我们从一个小例子来了解信号槽的 Qt 方式的使用。
// Qt Signals and Slots
class Button : public QObject
Q_SIGNALS:
void clicked();
class Page : public QObject
public Q_SLOTS:
void reload();
// given pointers to an actual Button and Page:
connect(button, SIGNAL(clicked()), page, SLOT(reload()));
Boost.Signals 方式
了解 Boost.Signals 的最好方式同样是 Boost 的文档。这里,我们还是先从代码的角度了解一下它的使用。
// Boost.Signals
class Button
boost::signal& void() & clicked;
class Page
void reload();
// given pointers to an actual Button and Page:
button-&clicked.connect( boost::bind(&Page::reload, page) );
或许你已经注意到上面的例子中,无论是 Qt 的实现方式还是 Boost 的实现方式,除了必须的 Button 和 Page 两个类之外,都不需要额外的类。两种实现都解决了类爆炸的问题。下面让我们对照着来看一下我们前面的分析。现在我们有:
两个不同的术语以及各自的动作:信号和槽;
在一个地方(信号)可以连接零个或者多个回调函数(槽),同时也是多对多的;
焦点在于连接本身,而不是提供者或者消费者;
不需要手工为了一个连接创建新的类;
连接仍旧是类型安全的。
这五点是信号槽系统的核心,Qt 和 boost 都拥有这些特性。下面则是二者的不同之处:
Boost.Signals
Qt Signals 和 Slots
一个信号就是一个对象
信号是具有名字的成员函数的签名
发出信号类似于函数调用
发出信号类似于函数调用,Qt 提供了一个 emit 关键字来完成这个操作
信号可以是全局的、局部的或者是成员对象
信号只能是成员函数
任何能够访问到信号对象的代码都可以发出信号
只有信号的拥有者才能发出信号
槽是任何可被调用的函数或者函数对象
槽是经过特别设计的成员函数
可以有返回值,返回值可以在多个槽中使用
没有返回值
同步的或者队列的
非线程安全
线程安全,可以跨线程使用
当且仅当槽是可追踪的时候,槽被销毁时,连接自动断开
槽被销毁时,连接都会自动断开(因为所有槽都是可追踪的)
类型安全(编译器检查)
类型安全(运行期检查)
参数列表必须完全一致
槽可以忽略信号中多余的参数
信号、槽可以是模板
信号、槽不能是模板
C++ 直接实现
通过由 moc 生成的元对象实现(moc 以及元对象系统都是 C++ 直接实现的)
没有内省机制
可以通过内省发现
可以通过元对象调用
连接可以从资源文件中自动推断出
最重要的是,Qt 的信号槽机制已经深深地植入到框架之中,成为不可分割的一部分。它们可以使用 Qt 专门的开发工具,例如 QtCreator,通过拖拽的方式很轻松的创建、删除、修改。它们甚至可以通过动态加载资源文件,由特定命名的对象自动动态生成。这些都是 boost 作为一个通用库所不可能提供的。本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)新手请教跨线程信号槽问题
来源:csdn
【版本4.7.4 手边没有代码 不贴了 简要描述一下 有点急 感谢提供帮助 先谢过
实现功能GUI线程接收用户指令,利用信号槽知通讯线程发送数据
我的做法是在主线程中创建窗口对象,创建并启动通讯线程
在通讯线程的run()中使用一个窗口对象的全局指针进行连接(QUEUE方式),运行发现连接成功,但始终无法正确送出信号,信号槽没有传递参数,折腾了许久没找到原因
做了一个实验,讲窗口对象改在通讯线程中创建,信号能正确发出,但是由于是在GUI线程外创建的,显示出现了一些莫名其妙的问题
请高手帮忙分析下,是哪里出了问题,或是提供更可行方案】
dbzhang800:
描述的不够清楚。比如你提到的queue连接,信号和槽各属于哪一个线程。
如果你的槽属于次线程,次线程内有没有启动事件循环?
肯定是GUI 发送信号,还是贴下相关代码吧
class dialer : public QWidget
void BtTXTrigger(const QString);
extern Bt_Snd_Task *pBtSndT
pDialerWin = NULL;
int main(int argc, char *argv[])
if (NULL == pDialerWin)
pDialerWin = new dialer();
pDialerWin-&move(FRAME_DIALER_X, FRAME_DIALER_Y);
if (NULL == pBtSndTsk)
pBtSndTsk = new Bt_Snd_Task();
pBtSndTsk-&start();
class Bt_Snd_Task : public QThread
protected slots:
void BtTxProc(const QString txBuf);
protected:
void run();
extern dialer*
Bt_Snd_Task *pBtSndTsk
void Bt_Snd_Task::run()
connect(pDialerWin, SIGNAL(BtTXTrigger(const QString)), this, SLOT(BtTxProc(const QString)), Qt::QueuedConnection);
this-&exec();
void Bt_Snd_Task::BtTxProc(const QString txBuf)
这样应该差不多能看明白了
开始我也怀疑是没有进入事件循环所以收不到信号,找了下帖子,貌似是说4.4之后默认启动事件循环的
dbzhang800:
恩,但是这是对不派生QThread并重现实现的run() 的用户说的。
你现在给出的精简后的例子,看起来没什么问题,但是不排除 出现问题的地方被你直接忽略掉了(程序的问题通常都在你认为没有问题的地方,不是么?)。
你可以给出一个最小的,别人可以直接编译运行的例子(通常只需要一个.cpp 文件,里面有几十行代码)。
可以参考这儿的例子风格: http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
dbzhang800:
刚忘了说了,你的代码表明:你的信号 和 槽 都在主线程中,你只是把 connect 放置到了次线程中。 也就是说,你的信号槽 和 多线程无关。
但是这不应该造成 信号和槽不工作。
你的意思是说我的槽虽然是在次线程定义的
实际也是在主线程中执行的吗
谢谢你提供的链接
我正在尝试使用不子类化Qthread的方法试试
看能否正常工作
zhangsongtao123:
我遇到过类似的问题,
建议你去看看QT帮助文档里面 connect函数的第五个参数的说明,直接用默认的值得话,多线程信号 槽机制会出问题
你可以试试 第五个参数 设置为 Qt::BlockingQueuedConnection
谢谢两位的热心帮助
问题已经解决
子类化Qthread和不子类化QThread都已能正常接收信号
dbzhang800大神提醒信号和槽实际在同一线程里执行 使我意识到连接类型可能有问题 果然改为DirectConnect 后能正常收到信号了 通过阅读大神提供的链接 了解到虽然这种方法不可取
但至少能正常工作了
同样感谢zhangsongtao123犀利指出参数错误
还没有试BlockingQueuedConnection有效 迟点试试 对连接类型参数的理解不够深刻
再次感谢2位的帮助 分不多请笑纳
免责声明:本站部分内容、图片、文字、视频等来自于互联网,仅供大家学习与交流。相关内容如涉嫌侵犯您的知识产权或其他合法权益,请向本站发送有效通知,我们会及时处理。反馈邮箱&&&&。
学生服务号
在线咨询,奖学金返现,名师点评,等你来互动qt小白请教 信号和槽的问题_qt吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:29,690贴子:
qt小白请教 信号和槽的问题收藏
再用qt做一个嵌入式的背光控制,遇到一些问题,求教如果一个槽接受到信号,正在执行的时候(还没执行完),这时又发来同样一个信号,请问槽能捕捉到这个信号吗
缺牙要及时修复,揭秘种植牙如何做到几十年不掉?
如果在一个函数里做了死循环,会发现整个程序都卡住了...我认为没有任何响应当然如果在程序里放入了各种响应函数...比如QApplication:: processEvents()但是也没反应...后来强制调用可以~不过在内部delete的时候报错了...
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或关于信号和槽 小问题 是否会打断呢_qt吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:29,690贴子:
关于信号和槽 小问题 是否会打断呢收藏
某个信号出现 然后执行一个槽函数
这时候又有信号来了 要进入另一个槽函数 会打断前一个正在执行的槽函数吗 ?
缺牙要及时修复,揭秘种植牙如何做到几十年不掉?
默认在一个线程里,函数应该是串行执行的。
如果你没有使用线程的话这种情况根本不会发生,整个程序同一时间只会存在一个信号,执行一个槽函数,只有在一个槽函数执行完毕后才可能会出现另一个信号.在槽函数执行期间是绝对不会出现另一个信号的,所以不用担心.
所以说槽不适合大规模运算…
同线程的话,emit信号会立即调用信号槽,阻塞原函数,等信号槽返回再继续回到原函数。不同线程的话,Qt使用队列来维护信号和信号槽,信号被发送后会存到消息队列中,各个线程使用消息循环来处理消息队列。不会发生同现成两个函数并行执行的现象。
同线程只相当于直接调用,你看哪里有一个线程能同时调用两个的,两个线程理所当然是并行
根据楼主的描述,相当于我在一个函数中同时发送2个信号去关联两个槽函数,这样是不冲突的,如下示例:void test() { emit signalTest1();sleep(1);emit signalTest2();}// 整个函数的执行顺序是由上往下的,2个信号不干涩,可同时执行。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或查看: 131|回复: 16
阅读权限47
Lv.46, 积分 46, 距离下一级还需 1 积分
UID5796176U币39446 UB钱包上限62310 UB体力224510 精华0种子1115 筐主题帖子性别男在线时间2491 小时最后登录注册时间
3G(TDSCDMA、CDMA2000)和4G(TDLTE)的信号模块是不是可以并在一起?
这是不是意味着我手机插了两张卡,一张电信3G占用了信号模块,另一张移动4G就没有4G信号了?
阅读权限20自我介绍ggQQ生日1980 年 1 月 1 日
Lv.19, 积分 19, 距离下一级还需 1 积分
UID105259U币15600 UB钱包上限15600 UB体力199347 精华1种子1509 筐主题帖子性别男生日1980 年 1 月 1 日在线时间3612 小时最后登录注册时间
不是。双卡双待手机都是两个待机模块和无线模块
s_k_911 路过 JayStar 的蛋糕店,买了一块蛋糕后拍照留念发PLU论坛,受到大家的表扬,获得 32 UB
欢迎收看911星际直播/sk2
阅读权限47
Lv.46, 积分 46, 距离下一级还需 1 积分
UID5796176U币39446 UB钱包上限62310 UB体力224510 精华0种子1115 筐主题帖子性别男在线时间2491 小时最后登录注册时间
s_k_911 发表于
不是。双卡双待手机都是两个待机模块和无线模块
求推荐同时电信3G和移动4G的手机。。
阅读权限20自我介绍ggQQ生日1980 年 1 月 1 日
Lv.19, 积分 19, 距离下一级还需 1 积分
UID105259U币15600 UB钱包上限15600 UB体力199347 精华1种子1509 筐主题帖子性别男生日1980 年 1 月 1 日在线时间3612 小时最后登录注册时间
エンジェル 发表于
求推荐同时电信3G和移动4G的手机。。
自己taobao找啊。。。
欢迎收看911星际直播/sk2
阅读权限47
Lv.46, 积分 46, 距离下一级还需 1 积分
UID5796176U币39446 UB钱包上限62310 UB体力224510 精华0种子1115 筐主题帖子性别男在线时间2491 小时最后登录注册时间
s_k_911 发表于
自己taobao找啊。。。
我两个号称全网通的手机都不行啊,现在已经迷茫了
因为经常在PLU论坛写错别字,エンジェル 被罚了 199 UB
阅读权限31QQ生日1986 年 10 月 28 日
Lv.30, 积分 30, 距离下一级还需 1 积分
UID229212U币239693 UB钱包上限300499 UB体力 精华0种子746 筐主题帖子性别男生日1986 年 10 月 28 日在线时间232474 小时最后登录注册时间
双卡的手机都是用一个4G另一个就是2G了啊 ,只能在两个卡之间切换用哪个4G,不能两个同时4G,吧?- -||
反正我的华为就是可以切换两个卡的4G但是不能同时4G,卡1是4G的时候卡 2就是2G,反之亦然,我是这样的情况
以前用红米note的时候是虽然支持双卡但是只有卡1可以3G,卡2无论如何都是2G
神奇的签名:20级以下水友只能看到“高&&都在PLU”
阅读权限31QQ生日1986 年 10 月 28 日
Lv.30, 积分 30, 距离下一级还需 1 积分
UID229212U币239693 UB钱包上限300499 UB体力 精华0种子746 筐主题帖子性别男生日1986 年 10 月 28 日在线时间232474 小时最后登录注册时间
再说了,你如果要求两个卡同时开启4G,你怎么选择什么时候用哪张卡的流量?
0772boy 捡到萝莉 PLU_糖小幽 的钱包,天降横财,获得 41 UB
神奇的签名:20级以下水友只能看到“高&&都在PLU”
阅读权限46自我介绍QQ
Lv.45, 积分 45, 距离下一级还需 1 积分
UID146567U币3289 UB钱包上限60060 UB体力41712 精华0种子1225 筐主题帖子性别保密在线时间6214 小时最后登录注册时间
两个同时4G,那上个网算那个卡的流量呢?
难道还要做个程序自动分流?
阅读权限20自我介绍ggQQ生日1980 年 1 月 1 日
Lv.19, 积分 19, 距离下一级还需 1 积分
UID105259U币15600 UB钱包上限15600 UB体力199347 精华1种子1509 筐主题帖子性别男生日1980 年 1 月 1 日在线时间3612 小时最后登录注册时间
エンジェル 发表于
我两个号称全网通的手机都不行啊,现在已经迷茫了
全网通是指 可以适配任何sim卡吧
欢迎收看911星际直播/sk2
阅读权限200
我不猥琐谁猥琐
UID67465U币75138 UB钱包上限76650 UB体力6332 精华0种子1479 筐主题帖子性别男在线时间4564 小时最后登录注册时间
enjoyd 发表于
两个同时4G,那上个网算那个卡的流量呢?
难道还要做个程序自动分流?
需要你设置用卡1还是卡2的数据,只有华为新出的mate手机支持双卡数据下载加速黑科技,其他的所有手机都是只能同时用一个卡的移动数据功能。。。
绝对骨灰菜鸟
阅读了王建康 的《开课了!开课了!电锯课》系列,似懂非懂地点了点头,获得了 66 UB
阅读权限47
Lv.46, 积分 46, 距离下一级还需 1 积分
UID5796176U币39446 UB钱包上限62310 UB体力224510 精华0种子1115 筐主题帖子性别男在线时间2491 小时最后登录注册时间
<font color="#72boy 发表于
双卡的手机都是用一个4G另一个就是2G了啊 ,只能在两个卡之间切换用哪个4G,不能两个同时4G,吧?- -||
现在问题是 对我某个手机而言 用了移动4G 电信连电话都不能打了
阅读权限47
Lv.46, 积分 46, 距离下一级还需 1 积分
UID5796176U币39446 UB钱包上限62310 UB体力224510 精华0种子1115 筐主题帖子性别男在线时间2491 小时最后登录注册时间
绝对骨灰菜鸟 发表于
需要你设置用卡1还是卡2的数据,只有华为新出的mate手机支持双卡数据下载加速黑科技,其他的所有手机都是 ...
没这么简单,我昨天打电话问了酷派的客服,他们说卡1插了电信的3G卡,卡2的移动4G卡就无法接受4G信号
而且由于大小/卡槽问题,卡1和卡2暂时无法在物理上更换
阅读权限200
我不猥琐谁猥琐
UID67465U币75138 UB钱包上限76650 UB体力6332 精华0种子1479 筐主题帖子性别男在线时间4564 小时最后登录注册时间
エンジェル 发表于
没这么简单,我昨天打电话问了酷派的客服,他们说卡1插了电信的3G卡,卡2的移动4G卡就无法接受4G信号
你跟我说的不是一回事。。。。电信是天然的坑爹,没听过一句话么:一入电信深似海从此手机不好买
很多全网通手机都是移动联通可以双4G随意切换,但是一旦其中的一张卡是电信,那么另一张卡绝对不能是电信,如果另一张卡是联通或者移动那么只能是电信作为主卡用4G,不然另一张卡都没法注册网络。。。总之,电信买手机坑爹
阅读权限47
Lv.46, 积分 46, 距离下一级还需 1 积分
UID5796176U币39446 UB钱包上限62310 UB体力224510 精华0种子1115 筐主题帖子性别男在线时间2491 小时最后登录注册时间
绝对骨灰菜鸟 发表于
你跟我说的不是一回事。。。。电信是天然的坑爹,没听过一句话么:一入电信深似海从此手机不好买
很多全 ...
没听过。。。看来我太年轻
阅读权限42居住地广西 南宁市QQ生日1982 年 1 月 12 日
Lv.41, 积分 41, 距离下一级还需 1 积分
UID224148U币29676 UB钱包上限51460 UB体力6342 精华0种子518 筐主题帖子性别男生日1982 年 1 月 12 日在线时间4021 小时最后登录注册时间
小米4c~~~~~~~~~
alang4 22人口,优势很大地冲向了对方200人口,勇气可嘉,奖励 286 UB
平和一点,你也可以做一只出色的癞蛤蟆
阅读权限22QQ
Lv.21, 积分 21, 距离下一级还需 1 积分
UID418111U币8589 UB钱包上限28060 UB体力354692 精华0种子1108 筐主题帖子性别保密在线时间6299 小时最后登录注册时间
没有手机能两个网络同时在线吧
阅读权限52
我有点小困!~
Lv.51, 积分 51, 距离下一级还需 1 积分
UID340507U币58908 UB钱包上限74160 UB体力20932 精华0种子923 筐主题帖子性别保密在线时间4809 小时最后登录注册时间
总之,电信买手机坑爹
piginlove 和林志玲喜结良缘,获得由PLU论坛送上的红包 77 UB
开通PLU高清频道的PLU忠实观众
Powered by

我要回帖

更多关于 qt自定义信号和槽 的文章

 

随机推荐