【发布时间】:2026-02-12 22:15:01
【问题描述】:
我有一个旧版 C++ Qt 应用程序,该应用程序已通过许多 Qt 版本进行了升级。我最近将它从 Qt 5.10.0 升级到 5.12.1,现在,突然之间,我的两个 OpenGL 显示器都遇到了问题,我不知道为什么。
问题的快速总结:
第一个显示绘制 3d 表面图。它非常旧(包含一个使用 glew 的旧控件)并且它使用现在已过时的 QGLWidget。我无法改变这一点。
class GLAdapterWidget : public QGLWidget
{
// ...A whole lot of legacy code which has not changed...
public:
// How I update the display
void doUpdate()
{
someLegacyGLDrawingFunction();
updateGL(); // fails if attribute Qt::WA_Mapped not set
}
};
现在的问题是,一旦它被加载,它仍然显示为完全黑色,直到我真正在其边界内的某处单击鼠标。然后突然间它的 GL 绘图完美地出现了。这在 Qt 5.10.0 中没有发生。
调试我至少能够跟踪到小部件属性 Qt::WA_Mapped 。该属性未在我的小部件上设置,因此 Qt 在我单击它之前不会绘制它。一旦我在其边界内单击 Qt 设置该属性,它就可以正常工作。但是我尝试解决方法(例如调用 show() 或尝试在软件中设置该属性)没有效果。
第二个显示器更现代,使用 QOpenGLWidget。它显示了一个不断更新的实时摄像头图像。
class VideoDisplay : public QOpenGLWidget,
protected QOpenGLFunctions_3_3_Core
{
virtual void initializeGL() override
{
initializeOpenGLFunctions();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-width()/2, width()/2, height()/2, -height()/2, -1, 1);
glClearColor(0.25f,0.25f,0.25f,1.0f);
}
virtual void paintGL() override
{
// Legacy Code that draws a live image using glDrawPixels and which has not changed.
}
virtual void resizeGL(int w, int h) override
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-w/2, w/2, h/2, -h/2, -1, 1);
}
};
这个一开始似乎很好用。图像显示并更新。但是,如果我去显示一个较旧的 GLAdapterWidget 的实例,然后再回到这个显示 (VideoDisplay),它会突然显示为黑色,并且没有任何东西可以让它重绘。调试我看到paintGL仍在被调用并且它有一个有效的图像。所有参数看起来都不错。但什么都没有显示。
我意识到这不是很多事情要做。这段代码是如此古老和庞大,以至于我觉得发布大块代码并不会起到太大的作用,但会使事情变得混乱。
而且我意识到,在这两种情况下,罪魁祸首可能都是基于旧 QGLWidget 的显示器。但是当我说我不能放弃该代码时,我并不是在开玩笑,无论我多么想这样做
所以我(拼命地)关注这在 5.10.0 中有效而在 5.12.1 中无效的事实 我希望对 Qt 有更好了解的人可以识别任何特定的关键架构 Qt 在 5.10.0 和 5.12.1 之间发生了变化,这可能是为我提供调查途径或尝试变通方法的罪魁祸首。
我需要创可贴。我不介意做这项工作,我只是不知道从哪里开始。
【问题讨论】:
-
所以这就是你要做的:在你的存储库中创建一个 bug-reproducer 分支,切换到该分支,然后开始丢弃与问题无关的所有内容。您应该只剩下几百行散布在几个源和标题中,然后您将挤入一个以
#include <QtOpenGL>(可能没有其他内容)开头的main.cpp,以#include "main.moc"结尾,并且适合 SO 格式 :)