qt没法在 QThread::run() 或者QObject::moveToThread 里面创建ui吗? (不是操作MainWindow)

baidu_28726667 2019-08-05 11:49:55
1.功能是接收到别人发来的tcp消息,需要处理信息后弹出其它界面(自定义的Widget ,Dialog,并非原来的MainWindow).

2.原本想用main函数里面创建MainWindow前, 创建一个继承了QThread的对象, 然后Start()执行 QThread::run() 处理消息后弹框, 等待用户点击按钮后销毁线程和窗口. 实际发现弹出窗口就已经卡死动不了....

3. 然后是在Tcp接收消息的函数里面用QObject::moveToThread 弹出窗口后不久就崩溃了...


4.解决方法我知道可以用QObject::moveToThread 处理消息数据, 处理结束后通过信号槽返回主界面创建自定义窗口. 但是这样消息类型越多. 我要在MainWindow里面至少为每个类型写两个信号槽.导致这个文件异常臃肿. 而且跟处理消息这个功能耦合很大.. 所以又没有方法能在线程里面使用ui ?

5.另外在 MainWindow类里面放了一个 A a对象 和一个QThread Mythread对象, 收到Tcp消息后进行 a.moveToThread(&Mythread); Mythread.start();发送signal emit(ToThreadMission); 在Slot ThreadMisson()里面打印线程id 发现多次接收tcp消息后重复执行上面的moveToThread和Start() 实际上也只有一条线程而已. 问题我想随意甚至同时创建线程,用完后销毁, 而这个方法一个线程需要事先在类里面放一个对象明显不合适阿...

6.如果把 A a和 QThread Mythread 放到接收Tcp消息的函数里面. 这样直接报 QThread: Destroyed while thread is still running, 估计是函数结束后东西都清了...所以线程非法结束了吧....

所以到底有什么方法很好解决了 tcp收到消息后, 把内容移到别的线程里面处理并且可以创建自定义的界面?!(因为需要创建的线程数和时机是未知的, 可能需要短时间内创建多条线程处理消息)




...全文
1110 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
诺水城子 2019-08-08
  • 打赏
  • 举报
回复
不能在子线程中操作UI,可以在子线程向主线程发送信号,主线程对应的槽函数来处理UI
baidu_28726667 2019-08-07
  • 打赏
  • 举报
回复
引用 12 楼 走好每一步 的回复:
怎么去实现方法各种各样,但是你ui和业务没分开就是不大好。 建议楼主有时间去学习下设计模式,对照着QT的接口好好体会一下。 有时间的话QT源码也看看。 不然你没有基础,去谈什么耦合和臃肿,都有点难以自圆其说。 说的不好听点就是自说自话,当然每个人都经历过这样的阶段,我也一样。
经过了改动,把Tcp单独开来异步接收消息了, 不过收到消息后的多线程处理因为涉及界面显示.所以的确要看看 QThreadPool了...
走好每一步 2019-08-07
  • 打赏
  • 举报
回复
怎么去实现方法各种各样,但是你ui和业务没分开就是不大好。 建议楼主有时间去学习下设计模式,对照着QT的接口好好体会一下。 有时间的话QT源码也看看。 不然你没有基础,去谈什么耦合和臃肿,都有点难以自圆其说。 说的不好听点就是自说自话,当然每个人都经历过这样的阶段,我也一样。
走好每一步 2019-08-07
  • 打赏
  • 举报
回复
引用 10 楼 baidu_28726667 的回复:
[quote=引用 8 楼 走好每一步 的回复:] [quote=引用 7 楼 baidu_28726667 的回复:] [quote=引用 3 楼 走好每一步 的回复:] [quote=引用 2 楼 baidu_28726667 的回复:] [quote=引用 1 楼 未狂 的回复:] 不能在子线程中创建ui,也不能在子线程中对控件进行操作
很想把一种要处理的tcp消息类型封装成一个类, 然后继承QThread. 里面可能会创建界面或者不需要创建界面.觉得这样程序逻辑清晰多了... 刚试了下在run() 里面加QEventLoop 还是崩溃了...[/quote] 业务逻辑线程不要带ui操作,发送信号出来。 UI界面接收信号在槽里处理, 你说的臃肿我不太明白是什么意思,没有源码说再多别人也不明白你的意思,起码写个伪代码。 [/quote] 按照业务逻辑不带ui操作完成一个业务逻辑需要两步: mainwindow类收到tcp消息 发送信号给 业务逻辑类 处理... 业务逻辑类 处理完后 发信号给 mainwindow, 我这个mainwindow 因为需求原因需要创建 dialog或者widget来显示结果 按照上两个connect() 为一个完整的业务逻辑. 这样如果有10个不同的业务逻辑就有20个这些connect和对应的信号槽函数了,而且这些信号槽函数还不包含业务处理,所以我会觉得很臃肿 ----------------------------------------------------------- 我的想法是包装好一个个的业务逻辑类, mainwindow收到 tcp消息后, 直接创建对应的业务逻辑类::run() . 这就不需要在mainwindow弄那么多信号槽了..[/quote] mainwindow就是ui类了,tcp消息让ui类接收,就是没把ui和业务逻辑分开。。 ui类-》启动tcpserver类侦听某个端口-》accept得到客户端链接后启动一个线程去处理-》得到处理信息 -》抛给tcpserver类-》ui类 或者 ui类-》启动tcpserver类侦听某个端口-》accept得到客户端链接后启动一个线程去处理-》得到处理信息 -》ui类 [/quote] 我这个东西实际并不是服务器, 反而是个客户端. 在mainwindow类里面放了一个QTcpsocket mytcp对象, mainwindow构造函数里面mytcp.connectToHost()了... 服务器会不定时通过这个连接下发消息到客户端处理. 目前通过connect(&mytcp, SIGNAL(readyRead()),this,Slot(OnReceive()))在mainwindow处理消息. 按照你说的不在 mainwindow 里面处理消息,那我得把QTcpsocket封装成一个MYQTcpsocket类,在 main.cpp里面创建? 或者直接在main里面使用QTcpsocket mytcp, 然后mytcp. connectToHost()?? 不过SLOT可以在main.cpp这个非类文件里面写吗? [/quote] slot可以的,只要继承了QObject的类都可以,楼主可以系统的去学下QT
走好每一步 2019-08-07
  • 打赏
  • 举报
回复
引用 13 楼 baidu_28726667 的回复:
[quote=引用 12 楼 走好每一步 的回复:] 怎么去实现方法各种各样,但是你ui和业务没分开就是不大好。 建议楼主有时间去学习下设计模式,对照着QT的接口好好体会一下。 有时间的话QT源码也看看。 不然你没有基础,去谈什么耦合和臃肿,都有点难以自圆其说。 说的不好听点就是自说自话,当然每个人都经历过这样的阶段,我也一样。
经过了改动,把Tcp单独开来异步接收消息了, 不过收到消息后的多线程处理因为涉及界面显示.所以的确要看看 QThreadPool了...[/quote] 多线程跟界面没关系的,你可能还不太明白我的意思。 业务就是业务,界面就是界面。
走好每一步 2019-08-06
  • 打赏
  • 举报
回复
ui类和业务类 输入输出尽量不要过多, 也就是说信号和槽不宜过多 逻辑类的数量也不宜过多
走好每一步 2019-08-06
  • 打赏
  • 举报
回复
引用 7 楼 baidu_28726667 的回复:
[quote=引用 3 楼 走好每一步 的回复:] [quote=引用 2 楼 baidu_28726667 的回复:] [quote=引用 1 楼 未狂 的回复:] 不能在子线程中创建ui,也不能在子线程中对控件进行操作
很想把一种要处理的tcp消息类型封装成一个类, 然后继承QThread. 里面可能会创建界面或者不需要创建界面.觉得这样程序逻辑清晰多了... 刚试了下在run() 里面加QEventLoop 还是崩溃了...[/quote] 业务逻辑线程不要带ui操作,发送信号出来。 UI界面接收信号在槽里处理, 你说的臃肿我不太明白是什么意思,没有源码说再多别人也不明白你的意思,起码写个伪代码。 [/quote] 按照业务逻辑不带ui操作完成一个业务逻辑需要两步: mainwindow类收到tcp消息 发送信号给 业务逻辑类 处理... 业务逻辑类 处理完后 发信号给 mainwindow, 我这个mainwindow 因为需求原因需要创建 dialog或者widget来显示结果 按照上两个connect() 为一个完整的业务逻辑. 这样如果有10个不同的业务逻辑就有20个这些connect和对应的信号槽函数了,而且这些信号槽函数还不包含业务处理,所以我会觉得很臃肿 ----------------------------------------------------------- 我的想法是包装好一个个的业务逻辑类, mainwindow收到 tcp消息后, 直接创建对应的业务逻辑类::run() . 这就不需要在mainwindow弄那么多信号槽了..[/quote] mainwindow就是ui类了,tcp消息让ui类接收,就是没把ui和业务逻辑分开。。 ui类-》启动tcpserver类侦听某个端口-》accept得到客户端链接后启动一个线程去处理-》得到处理信息 -》抛给tcpserver类-》ui类 或者 ui类-》启动tcpserver类侦听某个端口-》accept得到客户端链接后启动一个线程去处理-》得到处理信息 -》ui类
baidu_28726667 2019-08-06
  • 打赏
  • 举报
回复
引用 8 楼 走好每一步 的回复:
[quote=引用 7 楼 baidu_28726667 的回复:] [quote=引用 3 楼 走好每一步 的回复:] [quote=引用 2 楼 baidu_28726667 的回复:] [quote=引用 1 楼 未狂 的回复:] 不能在子线程中创建ui,也不能在子线程中对控件进行操作
很想把一种要处理的tcp消息类型封装成一个类, 然后继承QThread. 里面可能会创建界面或者不需要创建界面.觉得这样程序逻辑清晰多了... 刚试了下在run() 里面加QEventLoop 还是崩溃了...[/quote] 业务逻辑线程不要带ui操作,发送信号出来。 UI界面接收信号在槽里处理, 你说的臃肿我不太明白是什么意思,没有源码说再多别人也不明白你的意思,起码写个伪代码。 [/quote] 按照业务逻辑不带ui操作完成一个业务逻辑需要两步: mainwindow类收到tcp消息 发送信号给 业务逻辑类 处理... 业务逻辑类 处理完后 发信号给 mainwindow, 我这个mainwindow 因为需求原因需要创建 dialog或者widget来显示结果 按照上两个connect() 为一个完整的业务逻辑. 这样如果有10个不同的业务逻辑就有20个这些connect和对应的信号槽函数了,而且这些信号槽函数还不包含业务处理,所以我会觉得很臃肿 ----------------------------------------------------------- 我的想法是包装好一个个的业务逻辑类, mainwindow收到 tcp消息后, 直接创建对应的业务逻辑类::run() . 这就不需要在mainwindow弄那么多信号槽了..[/quote] mainwindow就是ui类了,tcp消息让ui类接收,就是没把ui和业务逻辑分开。。 ui类-》启动tcpserver类侦听某个端口-》accept得到客户端链接后启动一个线程去处理-》得到处理信息 -》抛给tcpserver类-》ui类 或者 ui类-》启动tcpserver类侦听某个端口-》accept得到客户端链接后启动一个线程去处理-》得到处理信息 -》ui类 [/quote] 我这个东西实际并不是服务器, 反而是个客户端. 在mainwindow类里面放了一个QTcpsocket mytcp对象, mainwindow构造函数里面mytcp.connectToHost()了... 服务器会不定时通过这个连接下发消息到客户端处理. 目前通过connect(&mytcp, SIGNAL(readyRead()),this,Slot(OnReceive()))在mainwindow处理消息. 按照你说的不在 mainwindow 里面处理消息,那我得把QTcpsocket封装成一个MYQTcpsocket类,在 main.cpp里面创建? 或者直接在main里面使用QTcpsocket mytcp, 然后mytcp. connectToHost()?? 不过SLOT可以在main.cpp这个非类文件里面写吗?
baidu_28726667 2019-08-05
  • 打赏
  • 举报
回复
引用 3 楼 走好每一步 的回复:
[quote=引用 2 楼 baidu_28726667 的回复:] [quote=引用 1 楼 未狂 的回复:] 不能在子线程中创建ui,也不能在子线程中对控件进行操作
很想把一种要处理的tcp消息类型封装成一个类, 然后继承QThread. 里面可能会创建界面或者不需要创建界面.觉得这样程序逻辑清晰多了... 刚试了下在run() 里面加QEventLoop 还是崩溃了...[/quote] 业务逻辑线程不要带ui操作,发送信号出来。 UI界面接收信号在槽里处理, 你说的臃肿我不太明白是什么意思,没有源码说再多别人也不明白你的意思,起码写个伪代码。 [/quote] 按照业务逻辑不带ui操作完成一个业务逻辑需要两步: mainwindow类收到tcp消息 发送信号给 业务逻辑类 处理... 业务逻辑类 处理完后 发信号给 mainwindow, 我这个mainwindow 因为需求原因需要创建 dialog或者widget来显示结果 按照上两个connect() 为一个完整的业务逻辑. 这样如果有10个不同的业务逻辑就有20个这些connect和对应的信号槽函数了,而且这些信号槽函数还不包含业务处理,所以我会觉得很臃肿 ----------------------------------------------------------- 我的想法是包装好一个个的业务逻辑类, mainwindow收到 tcp消息后, 直接创建对应的业务逻辑类::run() . 这就不需要在mainwindow弄那么多信号槽了..
baidu_28726667 2019-08-05
  • 打赏
  • 举报
回复
引用 4 楼 走好每一步 的回复:
“所以到底有什么方法很好解决了 tcp收到消息后, 把内容移到别的线程里面处理并且可以创建自定义的界面?!(因为需要创建的线程数和时机是未知的, 可能需要短时间内创建多条线程处理消息)” TcpserverThread { Start Stop OnConnect() { QThreadPool.run(TcpClient); } } 楼主需要去了解下线程池设计模式,百度一下看下QThreadPool的用法。
暂时还没看QThreadPool...不过我以前用别的线程池, 是需要初始化线程池里面有多少条线程的, 这样也资源有限或者浪费...(毕竟我这个不是服务器,不会有稳定数量消息到来处理...)
走好每一步 2019-08-05
  • 打赏
  • 举报
回复
界面里了不要做这种线程的业务逻辑处理, 像MFC那种写法的界面和逻辑耦合很强的代码是很可怕,那种代码没有可扩展性。
走好每一步 2019-08-05
  • 打赏
  • 举报
回复
“所以到底有什么方法很好解决了 tcp收到消息后, 把内容移到别的线程里面处理并且可以创建自定义的界面?!(因为需要创建的线程数和时机是未知的, 可能需要短时间内创建多条线程处理消息)” TcpserverThread { Start Stop OnConnect() { QThreadPool.run(TcpClient); } } 楼主需要去了解下线程池设计模式,百度一下看下QThreadPool的用法。
走好每一步 2019-08-05
  • 打赏
  • 举报
回复
引用 2 楼 baidu_28726667 的回复:
[quote=引用 1 楼 未狂 的回复:] 不能在子线程中创建ui,也不能在子线程中对控件进行操作
很想把一种要处理的tcp消息类型封装成一个类, 然后继承QThread. 里面可能会创建界面或者不需要创建界面.觉得这样程序逻辑清晰多了... 刚试了下在run() 里面加QEventLoop 还是崩溃了...[/quote] 业务逻辑线程不要带ui操作,发送信号出来。 UI界面接收信号在槽里处理, 你说的臃肿我不太明白是什么意思,没有源码说再多别人也不明白你的意思,起码写个伪代码。
baidu_28726667 2019-08-05
  • 打赏
  • 举报
回复
引用 1 楼 未狂 的回复:
不能在子线程中创建ui,也不能在子线程中对控件进行操作
很想把一种要处理的tcp消息类型封装成一个类, 然后继承QThread. 里面可能会创建界面或者不需要创建界面.觉得这样程序逻辑清晰多了... 刚试了下在run() 里面加QEventLoop 还是崩溃了...
未狂 2019-08-05
  • 打赏
  • 举报
回复
不能在子线程中创建ui,也不能在子线程中对控件进行操作

16,215

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧