10

我有一个QGLWidget在 Qt 应用程序中呈现 OpenGL 场景的程序。我想添加一些其他半透明的 Qt 小部件,它们覆盖在QGLWidget. 这比使用标准小部件更困难,因为 Qt 的画家类不知道 OpenGL 绘图上下文。因此,如果我只是做显而易见的事情并在例如顶部放置一个透明工具栏,QGLWidget则工具栏的透明部分会呈现黑色(绘画时它无法访问 OpenGL 帧缓冲区)。

似乎处理这种事情的推荐方法是在绘制 OpenGL 场景后重绘 2D 内容。只要您只是绘制简单的形状,链接的示例似乎非常简单。相反,我想做的是将一些子QWidget对象的绘制推迟到QGLWidget.

所以,我的问题归结为:

  1. 防止 overlay QWidgets 在正常的 2D 上下文中绘制。
  2. 在 的绘制事件处理程序中QGLWidget,在绘制构成背景的 3D 场景后绘制叠加层。

此列表中的第二项似乎很简单:我可以QWidget::render()QGLWidget's 的绘制事件中使用在视口顶部绘制所需的小部件。这工作得很好。

第一项更棘手:我需要一种方法来防止小部件在正常的事件过程中进行绘制,并且只在QGLWidget' 的绘制处理程序中绘制它们。一种明显的方法是使用QWidget::hide(). 这确实允许我根据需要在 OpenGL 场景顶部绘制小部件。但是,由于小部件是隐藏的,它们不会响应鼠标或键盘事件。例如,我正在使用QToolBar带有几个按钮的 a ,并且工具栏已正确绘制,但无法正常工作(所有按钮均不响应点击)。所以,如果沿着这条路走下去,我似乎需要一种方法来强制小部件即使它被隐藏也仍然响应事件。

我尝试过的另一种方法是QToolBar使用事件过滤器拦截 's 绘制事件,目的是防止工具栏自行绘制。但是,工具栏仍然被渲染;我假设这是因为工具栏上的各种按钮都是仍在绘制的子小部件,即使我拦截了父级的绘制事件。

关于我可以实现目标的任何想法?

4

1 回答 1

15

我不完全理解您的问题,但我会尝试回答标题中所述的问题。您应该使用事件过滤器。使用 安装事件过滤器widget->installEventFilter(object),其中widget是您要阻止绘画的小部件,并且object是您的任何 QObject 派生类的对象。重新实现eventFilter这个类:

bool MyClass::eventFilter(QObject* object, QEvent* event) {
  if (event->type() == QEvent::Paint) { return true; }
  return false;
}

当您从 eventFilter 返回 true 时,该事件被过滤并且不会发生绘制。

您也可以尝试使用widget->setUpdatesEnabled(false)暂时禁用绘画。完成后不要忘记重新启用它。

于 2013-06-12T09:47:05.487 回答