我有一个全尺寸的QGLWidget,使用QPainter绘制应用程序背景(可能将来会改用本机openGL命令)。
在这个QGLWidget上面,我使用QWidgets(非GL)作为用户界面元素。例如,这些是QLineEdits和QPushButtons。我将它们放入自定义绘制的QWidget中,该QWidget使用半透明背景绘制。 QLineEdit和QPushButton的paintEvents被覆盖,并且也使用半透明背景。
整个UI应该看起来像下面的样子(这是一张截图,我禁用了OpenGL并使用QWidget替换了QGLWidget作为背景。请注意半透明的顶部栏,它还绘制了阴影(在其自己的区域内)):
当QLineEdit具有焦点时,它应该具有更高的不透明度,但仍然不是完全不透明的:
所以现在,启用OpenGL(背景是QGLWidget),上面的半透明小部件不会绘制在背景上,而是绘制在(似乎是)未初始化的数据上。穿过顶部栏的图像有时是整个窗口本身,有时是当前在我的桌面上的其他窗口。
目前看起来像下面这样(在此屏幕截图中,半透明绘制操作所绘制的数据似乎是小部件本身的图像,具有偏移量。):
当我在行编辑器中写入文本(这里是“这是之前存在的一些文本!”),将其删除并将焦点设置回背景小部件时(因此放大镜图标和占位符文本出现),以前绘制的内容仍然会显现出来(请注意,可见边框应该不再可见,但也仍然显现出来):
问题是:半透明小部件不是绘制在底层小部件的上方,而是绘制在旧结果的上方,最初是类似“未初始化内存”的东西。
为什么会发生这种情况?我如何解决这个问题?
回答前应该知道的事情:
在这个QGLWidget上面,我使用QWidgets(非GL)作为用户界面元素。例如,这些是QLineEdits和QPushButtons。我将它们放入自定义绘制的QWidget中,该QWidget使用半透明背景绘制。 QLineEdit和QPushButton的paintEvents被覆盖,并且也使用半透明背景。
整个UI应该看起来像下面的样子(这是一张截图,我禁用了OpenGL并使用QWidget替换了QGLWidget作为背景。请注意半透明的顶部栏,它还绘制了阴影(在其自己的区域内)):
当QLineEdit具有焦点时,它应该具有更高的不透明度,但仍然不是完全不透明的:
所以现在,启用OpenGL(背景是QGLWidget),上面的半透明小部件不会绘制在背景上,而是绘制在(似乎是)未初始化的数据上。穿过顶部栏的图像有时是整个窗口本身,有时是当前在我的桌面上的其他窗口。
目前看起来像下面这样(在此屏幕截图中,半透明绘制操作所绘制的数据似乎是小部件本身的图像,具有偏移量。):
当我在行编辑器中写入文本(这里是“这是之前存在的一些文本!”),将其删除并将焦点设置回背景小部件时(因此放大镜图标和占位符文本出现),以前绘制的内容仍然会显现出来(请注意,可见边框应该不再可见,但也仍然显现出来):
问题是:半透明小部件不是绘制在底层小部件的上方,而是绘制在旧结果的上方,最初是类似“未初始化内存”的东西。
为什么会发生这种情况?我如何解决这个问题?
回答前应该知道的事情:
- 背景场景是由瓷砖组成的,这些瓷砖被离屏渲染。因此,可以非常快速地绘制,并且对于覆盖层的每一个小变化重新绘制背景不会有问题。
- 顶部栏是一个自定义的QWidget,具有手动绘制和排列所包含的两个小部件(按钮和行编辑器)。
- 这两个小部件重写了paintEvent,只在它们获得焦点时绘制自己的(半透明)背景,并且不使用Qt已提供的框架。因此,第二个截图中的白色边框是在我的自定义paintEvent中绘制的。
- 我希望能够分别实现背景和叠加小部件的组合。背景是一个AbstractMapView,其中包含一些具体的地图视图类。整个窗口是一个AbstractView(也有多个具体视图),它包含一个具体的地图视图和叠加小部件,以一种自身决定的方式组合。因此,我不希望叠加小部件的逻辑成为底层地图视图的一部分。(希望您理解这一点,因为它有点复杂。)