QGLWidget RenderText() 崩溃和文本混乱

Posted

技术标签:

【中文标题】QGLWidget RenderText() 崩溃和文本混乱【英文标题】:QGLWidget RenderText () crashes and text mess up 【发布时间】:2015-12-18 06:51:48 【问题描述】:

我将我的 Qt 应用程序从 Qt4.8.6 移植到 Qt 5.5.1

移植 GUI 后,在 renderText(x, y,z, font) 处随机崩溃。有时文本也会混乱,而不是字母和数字,而是显示不同大小的粗体黑色矩形。这段代码曾经在 QT 4.8 上运行良好。

我的调用堆栈如下:- ig7icd64.dll!000007fedbeeed17()

[Frames below may be incorrect and/or missing, no symbols loaded for ig7icd64.dll]  

ig7icd64.dll!000007fedbdbcbe1()     

ig7icd64.dll!000007fedbf3aa39()     

ig7icd64.dll!000007fedbf3a751() 

Qt5Guid.dll!QOpenGLFunctions::glDrawElements(unsigned int mode=5, int count=60, unsigned int type=5123, const void * indices=0x000000e2cd2459c8)  Line 730  C++
Qt5OpenGLd.dll!QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFormat=Format_A8, QStaticTextItem * staticTextItem=0x000000e2fe3a3dd0)  Line 1902   C++

Qt5OpenGLd.dll!QGL2PaintEngineEx::drawTextItem(const QPointF & p=..., const QTextItem & textItem=...)  Line 1591    C++

Qt5Guid.dll!QPainterPrivate::drawTextItem(const QPointF & p=..., const QTextItem & _ti=..., QTextEngine * textEngine=0x0000000000000000)  Line 6501 C++

Qt5Guid.dll!QPainter::drawTextItem(const QPointF & p=..., const QTextItem & ti=...)  Line 6372  C++

Qt5Guid.dll!QPainter::drawText(const QPointF & p=..., const QString & str=..., int tf=0, int justificationPadding=0)  Line 5913 C++

Qt5Guid.dll!QPainter::drawText(const QPointF & p=..., const QString & str=...)  Line 5697   C++

Qt5Guid.dll!QPainter::drawText(int x=427, int y=175, const QString & s=...)  Line 884 C++

Qt5OpenGLd.dll!qt_gl_draw_text(QPainter * p=0x000000e2ca3c2ee0, int x=427, int y=175, const QString & str=..., const QFont & font=...)  Line 4776   C++

Qt5OpenGLd.dll!QGLWidget::renderText(double x=8.0000000000000000, double y=0.00000000000000000, double z=0.00000000000000000, const QString & str=..., const QFont & font=...)  Line 4960   C++

请帮助我。如果有人遇到过类似的问题。我正在使用 Windows 8 并且驱动程序已更新。崩溃不会在 Ubuntu 14 上复制,但在 Ubuntu 上也会出现文本混乱。

【问题讨论】:

你能显示代码吗? Qt 4.8 代码是否也在 Windows 8 上?您需要获得每种情况下使用的有效 opengl 和 glsl 版本。使用opengl,相同的缺陷可能会根据驱动程序产生不同的错误,这解释了为什么Ubuntu不会崩溃。 代码如下:- 不需要代码。罪魁祸首在堆栈跟踪中。 你有一个英特尔 GPU。具体是哪一个?一般建议是:立即升级其驱动程序!但是,其中一些已损坏,您不应该使用 OpenGL。 【参考方案1】:

QGLWidget is obsolete in Qt5, you must not use it anymore. End of the story

这种过时的原因以及为什么会有这种奇怪的行为是因为 opengl 已弃用其直接模式渲染 api,这是一个 Qt4 opengl 元素过去依赖的 api。实际上,已弃用的功能可能会或可能不会保留在新驱动程序中,具体取决于供应商。

Opengl 文本渲染技术使用矩形来渲染文本。为此,必须启用 Alpha 混合。来自this tutorial on opengl,可以看到窗口如何

没有启用混合看起来像:

第二张图片很符合你的描述

而不是字母和数字加粗不同的黑色矩形 显示尺寸。

【讨论】:

谢谢@UmNyobe 是的,我渲染了类似的文本。所以我需要用 QOpenGLWidget 完全替换 QGLWidget 吗?在我处理遗留代码时是否有一些解决方法,这将是一个很大的变化。 如果你想成为未来的证明,我知道没有解决办法。很容易看出 QGLWidget 方法、旧的 nativeopengl 方法及其替代方法之间的映射。这不是一个复杂的过程,但你需要知道 opengl 是如何工作的。我自己也不得不经历类似的阶段。如果您尝试移植,请查看How to render text with QOpenGLWidget 之类的问题。您还可以破解本机代码来替换文本渲染,但这将是提前调试的地狱- 其实QOpenGLFunctions和QGLWidget方法很相似。从那里开始。 我已更新代码以使用 QOpenGLWidget 并使用链接 [link] ***.com/questions/28216001/… 中建议的 renderText api。但是,问题仍在复制。如果有人有任何建议,请告诉我。 我们的应用程序中可以有很多 QOpenGlWidgets/QGLwidgets。我们使用了 QOpenGLContext/QGLcontext 的单个实例,它由所有 QOpenGLwidgets/QGLwidgets 共享并且永远不会被删除。当我删除 QOpenGLWidget/QGLwidget 并尝试在另一个 QOpenGlwidget 上呈现文本时,问题会重现。

以上是关于QGLWidget RenderText() 崩溃和文本混乱的主要内容,如果未能解决你的问题,请参考以下文章

QGLWidget::renderText 边界框

QGLWidget 添加到布局时崩溃

如何使用 QOpenGLWidget 渲染文本

在 Qt 4.8.0 中使用 QGlWidget 更改 QWidget

在 R 中使用 renderText() 输出多行文本

如何在 Graphics32 中检索 RenderText 的确切文本宽度