如何防止QWidget绘画,但仍然可以响应事件?

时间:2013-06-11 18:00:11

标签: qt opengl paint qwidget

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

似乎处理此类事情的推荐方法是overpaint the 2D content after drawing the OpenGL scene。只要您只是绘制简单的形状,链接的示例似乎非常简单。相反,我想要做的是推迟在QWidget的paint事件中绘制一些子QGLWidget个对象。

所以,我的问题归结为:

  1. 防止叠加QWidget在正常的2D环境中绘画。
  2. QGLWidget的绘图事件处理程序中,在绘制构成背景的3D场景后绘制叠加层。
  3. 此列表中的第二项似乎很简单:我可以在QWidget::render()的paint事件中使用QGLWidget在视口顶部绘制所需的小部件。这很好用。

    第一项更棘手:我需要一种方法来阻止小部件在正常的事件过程中绘画,并且只在QGLWidget的绘图处理程序中绘制它们。一种显而易见的方法是使用QWidget::hide()隐藏叠加层。这允许我按照我的意愿在OpenGL场景上绘制小部件。但是,由于窗口小部件是隐藏的,因此它们不响应鼠标或键盘事件。例如,我正在使用带有几个按钮的QToolBar,并且工具栏已正确绘制,但不起作用(按钮没有响应点击)。因此,如果沿着这条路走下去,似乎我需要一种方法来强制小部件仍然响应事件,即使它被隐藏。

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

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

1 个答案:

答案 0 :(得分:13)

我完全不理解你的问题,但我会尝试回答标题中提到的问题。您应该使用事件过滤器。使用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)暂时禁用绘画。完成后别忘了重新启用它。