8

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

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

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

截屏

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

截屏

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

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

截屏

当我将文本写入行编辑时(此处:“这是一些以前存在的文本!”),将其删除并将焦点设置回背景小部件(因此出现放大镜图标和占位符文本),之前涂漆的东西仍然会发光(请注意,可见边框不应可见,但仍会发光):

截屏

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

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

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

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

2 回答 2

3

这听起来像是 GL 内容(即您的背景,也就是 QGLWidget)不在 Qt 上下文中的问题。虽然我不是使用 Qt 进行 GL 绘画的专家,但您可能希望查看有关 GL 绘画和 QLabel 的讨论,以获得一些方向/潜在的提示。

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

简而言之,我们在办公室使用 OpenGL 绘画和地图的屏幕外渲染,确保 Qt 了解像素非常重要,这样您的前景小部件可以将半透明应用于其背景。

我们使用的特定产品还可以在瓦片中渲染地图,并支持在缓冲区中提供 GL 输出(即,它称为快照并以位图的形式提供),此时我们使用常规 QWidget 的paintEvent 来绘制缓冲区,以便绘制的像素在 Qt 上下文中。

于 2012-07-23T02:13:11.060 回答
-1

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

于 2013-05-08T07:44:12.633 回答