我有一个全尺寸的 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
(也有多个具体视图),它包含一个具体的地图视图和覆盖小部件,它们以自己决定的方式组成。因此,我不希望覆盖小部件的逻辑成为底层地图视图的一部分。(我希望你明白这一点,因为它有点复杂。)