简体   繁体   English

重绘小部件时Qt崩溃

[英]Qt crash when redrawing Widget

I have a custom-built player which can "play" recoded media samples (sensor data with timestamps). 我有一个定制播放器,可以“播放”重新编码的媒体样本(带有时间戳的传感器数据)。

What I am trying to do is couple this player to an Qt UI. 我想做的就是将此播放器耦合到Qt UI。 I have created a Widget and coupled the Player and the Widget through Signals and slots (Qt::DirectConnection). 我创建了一个小部件,并通过信号和插槽(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). 我尝试使用二进制信号量来限制对它的访问(如果信号量为true,则立即返回;否则,请继续)。 The error still doesn't go away. 错误仍然无法消除。

My question is: is the Qt Painter running on the same thread as the Widget updater? 我的问题是:Qt Painter是否与Widget更新程序在同一线程上运行? 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. 但是,我附上了崩溃的屏幕截图。

Cheers, Mihai 干杯,米海

在此处输入图片说明

Thank you for your precious feedback. 感谢您的宝贵意见。 I have managed to find the root cause for the problem. 我设法找到了问题的根本原因。 It was tied to the Qt::DirectConnection . 它被绑定到Qt::DirectConnection As described in the API documentation, this will be executed: 如API文档中所述,将执行以下操作:

"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. 就我而言,发射器是Player,接收器是UI线程。 Which means I'm manipulating elements in the UI outside of the UI Thread. 这意味着我正在UI线程之外的UI中操作元素。 This is the root cause. 这是根本原因。

I have changed the implementation to used Qt::QueuedConnection and now it runs smoothly. 我已将实现更改为使用Qt::QueuedConnection ,现在它可以平稳运行。

As to why the original implementation with Qt::QueuedConnection did not work initially, I put a bool status = connect() which always returned false , meaning the connection failed. 至于为什么Qt::QueuedConnection的原始实现最初无法正常工作,我将bool status = connect()始终返回false ,这意味着连接失败。 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. 我将信号方法的名称更改为与插槽1的名称不同(最初它们是相同的),并且+将所有输入参数默认设置为标准类型( unsigned int而不是tUInt32 ),并且可以正常工作。 connect() now returns true . connect()现在返回true I suspect that somehow the connect() got confused as to the wiring.. 我怀疑以某种方式将connect()弄不清楚了接线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM