• 3338阅读
  • 13回复

[提问]qmqtt收不到信号? [复制链接]

上一主题 下一主题
离线foxgod
 

只看楼主 倒序阅读 楼主  发表于: 2019-05-24
使用qmqtt的过程里面本来一切都正常,原来代码是
  1. connect(m_mqClient,SIGNAL(ReciverMessage(QByteArray)),this,SLOT(ReciverMsg(QByteArray)));
  2. 此信号为qmqtt收到一个消息就的信号
  3. 主界面
  4. 通过ReciverMsg(QByteArray)这个槽函数收到消息。然后处理。
  5. 但是因为在gui界面想一个个处理消息,不想收到消息就处理,也就是不想多线程处理,所以在ReciverMsg(QByteArray)槽函数里面把收到的消息保存起来,放一个队列里面,在gui界面里面有个死循环
  6. while(true)
  7.     {
  8.         QByteArray  rebackdata;
  9.         if(!m_bIsBusy)
  10.         {
  11.             if(ww->ReadControlMessage(rebackdata))//保存在队列里面的一个函数,从这个函数里面一个个读取消息
  12.             {
  13.                 m_bIsBusy = true;
  14.                 WriteFile(rebackdata);
  15.             }
  16.             else
  17.             {
  18.                 QCoreApplication::processEvents(QEventLoop::AllEvents, 100);//处理其他消息、事件。
  19.             }
  20.         }
  21.         else
  22.         {
  23.              QCoreApplication::processEvents(QEventLoop::AllEvents, 100);//处理其他消息、事件。
  24.         }
  25. 这样做后,信号和槽函数都没有办法相应了,这是怎么回事呢?把这个死循环去掉,是可以相应的?有什么解决办法




在线20091001753

只看该作者 1楼 发表于: 2019-05-24
你可以简单理解为 Qt 自带了一个循环,就是事件循环。

如果你再自创一个死循环,你就成功地把 Qt 的事件循环给锁死了。自然也就收不到信号。

(づ ̄ 3 ̄)づ
离线angelus

只看该作者 2楼 发表于: 2019-05-24
首先,界面gui事件循环就是程序的主循环,可以理解为主进程循环,如果在主进程循环中自己创建一个子循环,这样是不对了,因为会阻碍主循环运行,特别是用while这样的程序锁死循环,更是不可取,可以尝试下qt提供的QEventLoop,可以更优雅的在主循环中创建子循环,创建的子循环有参数可以选择,但是在一些平台下,是有限制的,如果仅仅是win下,没有任何问题的,QEventLoop的子循环可以全部阻塞事件,也可以只阻塞部分类型的事件,但是,像网络事件你这种要求一直阻塞去接收的建议开启线程去处理,不要阻塞主循环
离线foxgod

只看该作者 3楼 发表于: 2019-05-24
回 20091001753 的帖子
20091001753:你可以简单理解为 Qt 自带了一个循环,就是事件循环。
如果你再自创一个死循环,你就成功地把 Qt 的事件循环给锁死了。自然也就收不到信号。
(2019-05-24 09:06)

那请教下,如果我想实现类似这样的功能怎么做呢,可以用定时器吗?
离线foxgod

只看该作者 4楼 发表于: 2019-05-24
回 angelus 的帖子
angelus:首先,界面gui事件循环就是程序的主循环,可以理解为主进程循环,如果在主进程循环中自己创建一个子循环,这样是不对了,因为会阻碍主循环运行,特别是用while这样的程序锁死循环,更是不可取,可以尝试下qt提供的QEventLoop,可以更优雅的在主循环中创建子循环,创建的子循环有参 .. (2019-05-24 09:24) 

除了那个办法,还有别的办法没
在线20091001753

只看该作者 5楼 发表于: 2019-05-24
就是用信号槽啊,自己定义信号与槽函数,你已经这么做了:
connect(m_mqClient,SIGNAL(ReciverMessage(QByteArray)),this,SLOT(ReciverMsg(QByteArray)))
(づ ̄ 3 ̄)づ
离线angelus

只看该作者 6楼 发表于: 2019-05-24
如果你只是想把收到的信息,放在一个容器队列里,然后用其他方式去处理,没必要开启子循环,就在接收到数据后把数据 压到容器队列中,就行了,不要阻塞主线程,至于你想怎么处理容器消息,何时去处理,可以自己决定,到底是用定时器去间隔逐条处理,还是用户在gui主界面手动点击处理,还是开启子线程去自动化逐条处理,都是很好实现的
离线foxgod

只看该作者 7楼 发表于: 2019-05-24
回 angelus 的帖子
angelus:如果你只是想把收到的信息,放在一个容器队列里,然后用其他方式去处理,没必要开启子循环,就在接收到数据后把数据 压到容器队列中,就行了,不要阻塞主线程,至于你想怎么处理容器消息,何时去处理,可以自己决定,到底是用定时器去间隔逐条处理,还是用户在gui主界面手动点击处 .. (2019-05-24 09:42) 

我想问的是,为什么在gui线程里面调用了QCoreApplication::processEvents()函数,这个函数不是去执行其他的信号和槽函数吗,为什么会阻止了我的socket的信号呢
离线foxgod

只看该作者 8楼 发表于: 2019-05-24
回 20091001753 的帖子
20091001753:就是用信号槽啊,自己定义信号与槽函数,你已经这么做了:
connect(m_mqClient,SIGNAL(ReciverMessage(QByteArray)),this,SLOT(ReciverMsg(QByteArray))) (2019-05-24 09:34) 

QCoreApplication::processEvents()这个函数不是去执行其他的信号和槽函数吗,为什么会阻止了我的socket的信号呢
离线foxgod

只看该作者 9楼 发表于: 2019-05-24
回 angelus 的帖子
angelus:如果你只是想把收到的信息,放在一个容器队列里,然后用其他方式去处理,没必要开启子循环,就在接收到数据后把数据 压到容器队列中,就行了,不要阻塞主线程,至于你想怎么处理容器消息,何时去处理,可以自己决定,到底是用定时器去间隔逐条处理,还是用户在gui主界面手动点击处 .. (2019-05-24 09:42) 

如果是非gui界面,可以用while(1)这样的用法吗??
在线20091001753

只看该作者 10楼 发表于: 2019-05-24
使用 Qt 编程千万不要用 while(1) 这样的句子
你目前对 Qt 的事件机制有些误解,建议你先停下来
去淘宝买 Qt5 的入门书籍,跟着书练习一些 Demo
(づ ̄ 3 ̄)づ
离线angelus

只看该作者 11楼 发表于: 2019-05-24
回 foxgod 的帖子
foxgod:如果是非gui界面,可以用while(1)这样的用法吗?? (2019-05-24 11:12)

你还没明白嘛,和gui没有太大关系,即使没有gui界面,主循环依然存在,有gui仅仅是因为gui是运行在主事件循环上的。

建议你修改你的代码流程模型,不要依赖QCoreApplication::processEvents 处理其他事件,这东西仅仅是为了在后台繁忙的时候不至于让你的gui失去响应,而你把这种不确定的辅助方式作为 支撑逻辑,是很不可靠的!
离线foxgod

只看该作者 12楼 发表于: 2019-05-27
回 angelus 的帖子
angelus:你还没明白嘛,和gui没有太大关系,即使没有gui界面,主循环依然存在,有gui仅仅是因为gui是运行在主事件循环上的。
建议你修改你的代码流程模型,不要依赖QCoreApplication::processEvents 处理其他事件,这东西仅仅是为了在后台繁忙的时候不至于让你的gui失去响应,而你把这种 .. (2019-05-24 16:02) 

咨询个问题,就是我有一个函数,我想用计时器,每隔多长时间去执行这个函数操作,,我想的是这个函数里面可以获取东西就执行,获取不到东西就类似挂起这样的操作,有办法做到吗
离线angelus

只看该作者 13楼 发表于: 2019-05-28
回 foxgod 的帖子
foxgod:咨询个问题,就是我有一个函数,我想用计时器,每隔多长时间去执行这个函数操作,,我想的是这个函数里面可以获取东西就执行,获取不到东西就类似挂起这样的操作,有办法做到吗 (2019-05-27 15:55) 

周期执行的函数,没有东西执行,就让这个函数结束就好了,不用挂起
快速回复
限100 字节
 
上一个 下一个