QGLWidget上的半透明QWidget:奇怪的结果

时间:2012-07-22 21:18:47

标签: qt opengl overlay transparency

我有一个全尺寸的QGLWidget,它使用QPainter绘制应用程序背景(将来可能会更改为原生的openGL命令)。

在这个QGLWidget之上,我使用QWidgets(非GL)作为用户界面元素。例如,这些是QLineEdits和QPushButtons。我将它们放入一个使用半透明背景画的自定义绘制的QWidget中。 QLineEdit和QPushButton的paintEvents也会被覆盖并使用半透明背景。

整个UI 应该如下所示(这是我禁用OpenGL并使用QWidget而不是QGLWidget作为背景的屏幕截图。请注意半透明的顶部条也会绘制阴影(在其自己的区域内)):

Screenshot

当QLineEdit具有焦点时,它应该具有更高的不透明度但仍然不完全不透明:

Screenshot

所以现在,启用OpenGL(背景是QGLWidget),上面的半透明小部件不会在背景上绘制,而是在(似乎是)未初始化的数据上绘制。通过顶栏发光的图像有时是整个窗口本身,有时其他窗口当前在我的桌面上。

目前看起来如下(在此屏幕截图中,绘制半透明绘画操作的数据似乎是小部件本身的图像,具有偏移量。):

Screenshot

当我在行编辑中写入文本时(此处:“这是以前曾经存在的某些文本!”),将其删除并将焦点设置回背景小部件(因此放大镜图标和占位符文本出现) ,之前画过的东西仍然闪耀着(请注意,可见边框应该再次可见,但仍然可以透过):

Screenshot

所以问题是:半透明小部件不是被绘制在底层小部件之上,而是绘制在旧结果之上,最初类似于“未初始化的内存”。< / p>

为什么会这样?我该如何解决这个问题呢?

回答之前你应该知道的事情:

  • 背景场景是在屏幕外渲染的图块组合。所以它可以非常快速地绘制,并且对于叠加的每一个小变化重新绘制背景都没有问题。
  • 顶部栏是一个自定义QWidget,带有手动绘画和所包含的两个小部件的排列(按钮和行编辑)。
  • 这两个小部件会覆盖paintEvent,只有在有焦点时才会绘制自己的(半透明)背景,并且不使用Qt已经提供的帧。因此,第二个屏幕截图中的白色边框是在我的自定义paintEvent中绘制的。
  • 我希望叠加小部件的背景和组合可以单独实现。背景是AbstractMapView,它有一些具体的地图视图类。整个窗口是一个AbstractView(也有多个具体视​​图),它包含一个具体的地图视图和覆盖小部件,它们以自己决定的方式组成。因此,我不希望覆盖小部件的逻辑成为底层地图视图的一部分。 (我希望你理解这一点,因为它有点复杂。)

2 个答案:

答案 0 :(得分:3)

这听起来像GL内容(即你的背景,即QGLWidget)不在Qt上下文中的问题。虽然我不是使用Qt进行GL绘画的专业人士,但您可能需要查看有关GL绘画的讨论以及针对某些方向/潜在提示的QLabel。

http://www.qtcentre.org/threads/40335-QLabel-on-top-of-a-QGLWidget-background-issue

简而言之,我们办公室使用OpenGL绘画和地图的离线渲染,确保Qt知道像素非常重要,这样前景窗口小部件可以将半透明度应用于他们的背景

我们使用的特定产品还在tile中呈现地图并支持在缓冲区中提供GL输出(即它调用快照并作为位图提供),此时我们使用常规的paintEvent用于绘制缓冲区的QWidget,以便绘制的像素位于Qt上下文中。

答案 1 :(得分:-1)

您可以使用Qt :: SplashScreen标志定义Qframe作为搜索框并设置其不透明度。将您的小部件放在其中,例如搜索文本框,并将其放置在主窗口上应显示的位置。当主窗口被移动或调整大小覆盖其moveEvent时,重新定位它也是一个好主意。