如何防止QWidget绘制,但仍然响应事件?



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

似乎建议处理这种事情的方法是在绘制OpenGL场景后覆盖2D内容。链接的例子看起来很简单,只要你只是画简单的形状。相反,我想做的是推迟一些子QWidget对象的绘制,以便在QGLWidget的paint事件中完成。

所以,我的问题归结为:

  1. 防止覆盖QWidget s在正常的2D环境中绘制。
  2. QGLWidget的paint事件处理程序中,在绘制构成背景的3D场景后绘制叠加。

这个列表中的第二项似乎很简单:我可以在QGLWidget的paint事件中使用QWidget::render()在视窗顶部绘制所需的小部件。

第一项更棘手:我需要一种方法来防止小部件在正常事件过程中绘制,并且只在QGLWidget的绘制处理程序中绘制它们。一个明显的方法是使用QWidget::hide()隐藏叠加。这确实允许我在OpenGL场景上画出我想要的小部件。但是,由于小部件是隐藏的,因此它们不会响应鼠标或键盘事件。作为一个例子,我使用一个QToolBar上面有几个按钮,工具栏是正确绘制的,但没有功能(没有按钮响应点击)。所以,如果沿着这条路走下去,我似乎需要一种方法来强制小部件仍然响应事件,即使它是隐藏的。

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

有什么方法可以让我实现我的目标吗?

我不完全理解你的问题,但我会尽力回答标题中提出的问题。您应该使用事件过滤器。使用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时,事件被过滤,paint不会发生。

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

相关内容

  • 没有找到相关文章

最新更新