Qt崩溃时重绘Widget [英] Qt crash when redrawing Widget

查看:367
本文介绍了Qt崩溃时重绘Widget的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义播放器,可以播放重新编码的媒体示例(具有时间戳的传感器数据)。

I have a custom-built player which can "play" recoded media samples (sensor data with timestamps).

我想做的是耦合这个播放器到Qt UI。我创建了一个Widget,并通过信号和插槽(Qt :: DirectConnection)耦合播放器和Widget。

What I am trying to do is couple this player to an Qt UI. I have created a Widget and coupled the Player and the Widget through Signals and slots (Qt::DirectConnection).

我遇到的问题是程序崩溃时抛出异常。它崩溃的时刻是完全随机的,有时它可能不会崩溃。据我所知,问题在于微件部分的更新不是线程安全的。我试着用一个二进制信号量限制访问它(立即返回如果信号量真的,如果不是继续)。错误仍然不消失。

The problem I'm experiencing is that the program crashes with an exception thrown. The moment when it crashes is completely random, and sometimes it may not crash. As far as I can tell, the problem lies in that the update in the widget part is not thread-safe. I have tried restricting access to it with a binary semaphore (immediately return if semaphore true, continue if not). The error still doesn't go away.

我的问题是:Qt Painter是否与Widget updater运行在同一个线程上?我怀疑我在之前的绘画操作完成之前调用画家,这就是为什么它仍然崩溃。我怀疑小部件只是以某种方式发布一个事件给画家(非阻塞)..

My question is: is the Qt Painter running on the same thread as the Widget updater? I suspect I'm calling the painter before the previous paint operation has finished, which is why it still crashes. I suspect the widget only somehow posts an event to the painter (non-blocking)..

还有什么可能是问题?不幸的是,代码太复杂,无法粘贴到这里。

What else could be the problem? Unfortunately, the code is too complex to paste here. However, I am attaching a screenshot of the crash.

干杯,
米海

推荐答案

感谢您的宝贵意见。我设法找到问题的根本原因。它被绑定到Qt :: DirectConnection。如API文档中所述,这将在发射器的线程中执行,这不一定是接收器的线程。在我的情况下,发射器是播放器和接收器是UI线程。这意味着我在UI线程之外的UI中操作元素。这是根本原因。

thank you for your precious feedback. I have managed to find the root cause for the problem. It was tied to the Qt::DirectConnection. As described in the API documentation, this will be executed "in the emitter's thread, which is not necessarily the receiver's thread." In my case, the emitter is the Player and the receiver is the UI thread. Which means I'm manipulating elements in the UI outside of the UI Thread. This is the root cause.

我已经将实现更改为使用Qt :: QueuedConnection,现在它运行顺畅。

I have changed the implementation to used Qt::QueuedConnection and now it runs smoothly.

至于为什么Qt :: QueuedConnection的原始实现没有工作initialy,我把一个bool status = connect()总是返回false,意味着连接失败。我改变了信号方法的名称不同于槽的名称(最初,他们是相同的),+我默认所有的输入参数标准类型(unsigned int而不是tUInt32),它的工作。 connect()现在返回true。我怀疑,不知何故connect()被困惑的布线。

As to why the original implementation with Qt::QueuedConnection did not work initialy, I put a bool status = connect() which always returned false, meaning the connection failed. I changed the name of the signal method to be different from the name of the slot one (initially, they were the same), + I defaulted all the input parameters to standard types (unsigned int instead of tUInt32) and it worked. connect() now returns true. I suspect that somehow the connect() got confused as to the wiring..

这篇关于Qt崩溃时重绘Widget的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆