【问题标题】:QGLWidget for graphics and QT for GUIQGLWidget 用于图形和 QT 用于 GUI
【发布时间】:2011-12-30 00:47:07
【问题描述】:

我正在尝试实现自定义 OpenGL 场景(包装在 QGLWidget 中),但仍然使用 QT 控件(例如滑动条和按钮)。我试图让我的主要小部件成为一个 QGLWidget,它有 QWidgets 作为孩子。子小部件似乎可以工作(当我单击下拉菜单时,会出现其选项),但小部件无法绘制(我看到一个白色方块)。我将我的子小部件的基类从 QWidget 更改为 QGLWidget,现在 QPainter 调用工作,但 QT GUI 的东西仍然没有显示......

有些人声称 QGLWidget 不能将 QWidgets 作为孩子...我不确定,我也不愿意放弃。顺便说一句,我正在使用可视化库来绘制 OpenGL 场景,但它只是一个 OpenGL 包装器......

问题可能出在哪里的任何线索?此外,当我将子小部件添加到 GQLWidget 时,由于某种原因停止处理关键事件。

更新: 我尝试了小部件和布局的各种组合。似乎 QGLWidget 只是被绘制在任何东西之上。我什至尝试使用 raise() 来安排小部件的 Z 深度,但无济于事。 overlayGL() 是在 OpenGL 小部件上绘制的唯一方法吗?

更新 2 经过几个月的尝试,我发现它与 QT 有关。每当一个 QGLWidget 被绘制在另一个 QGLWidget 之上时,第一个的 background() 函数不会被调用。所以一个按钮在那里并且可以被点击,但它没有被绘制。我的解决方法是使用 QPainter 自己绘制所有内容 - 这很有效。我发现好奇的是,必须使用 QPainter::startNativePainting() 才能使用它进行绘制。人们会期望,只要 QGLWidget 是绘画设备,他们就会在 QPainter 中重载 start() 以调用 startNativePainting()...

另一个(可能有用的)事实是 QPainter 调用 CHANGE Opengl 上下文。因此,如果您有另一个与 QPainter 合作的工具(在我的情况下为可视化库),其中一个可能会崩溃(在我的情况下,VL 会检查是否在每一帧之前清除了上下文状态)。

【问题讨论】:

  • 你不能创建一个非 GL 小部件作为主窗口,并创建一个 GL 小部件作为它的子窗口吗?因此,您希望窗口中的其他控件将是 GL 窗口的兄弟和表亲,而不是子窗口。
  • 我先试过了——它抱怨一些 GL_SRC_ALPHA 问题失败了。 QGLWidget 由 VLlink 构建,非常复杂,因此很难调试...
  • 你想让 QWidget 派生的对象漂浮在 QGLWidget 的顶部吗?
  • 这正是我想要做的!

标签: qt opengl


【解决方案1】:

有一个渲染 Qt widgets using opengl 的实验室示例,它有点旧,我还没有尝试使用 4.8 中改进的 qglwidget

在全屏 QGLwidget 的顶部绘图也存在问题 - 这应该是 NVidia 的 openGL 驱动程序中的一个错误。好像没有解决 https://bugreports.qt-project.org/browse/QTBUG-7556

【讨论】:

    【解决方案2】:

    如果我是你,我会使用QGLWidget 作为QGraphicsScene 的视口,然后你可以使用QGraphicsProxyWidget 绘制小部件。通过这种方式,您可以获得适当的 OpenGL 视口,并且能够将小部件放入并轻松操作它们。

    【讨论】:

    • 我也试过了,它有效,但不适用于我的场景。我将 QGLWidget 作为 GGraphicsView 的视口(它呈现了我的 QGraphicsScene),但它失败并出现错误(本质上,QGraphicsScene 抱怨 GLContext 为空)。我认为这与我的 QGLWidget 具有自定义上下文的事实有关...
    • 可能是 Qt 需要 OpenGL 支持,而你没有。您能发布您的 QGLContext 代码以及您正在运行的 OpenGL 版本吗?
    • QGLContext* glctx = new QGLContext(context()->format(), this); QGLFormat fmt = context()->format(); //setting various format marameters in fmt glctx->setFormat(fmt); glctx->create(shareContext); setContext(glctx);
    • 格式已被破坏,请编辑您的帖子以添加此内容,以便每个人都注意到它。重要的是您在 context()->format() 中请求的 OpenGL 功能实际上已被使用,为此请使用 glctx->format()。还有你的显卡支持什么OpenGL版本?
    • 我试图编辑它,但它说帖子已经被编辑...我要求的功能正在使用中。我找到了问题的根源,并将其添加到主要问题中。在我看来,这显然是一个 QT 问题......
    【解决方案3】:

    您是否尝试显式调用 update()?我发现有时 QGLWidget 更新显示的东西有点慢。

    【讨论】:

    • 是的,QGLWidgets 显式调用 update()。我怀疑绘图顺序不正确,但我不知道 QT 如何处理小部件绘图以及它如何/必须受到影响......
    • 你能用一些简单的opengl func来绘制一些基本的几何图形,比如球体或茶壶吗?只是为了确保 QGLWidget 将正确绘制一些东西。如果有效,则表示您使用的 lib 存在一些错误。
    • 问题不在于openGL场景没有绘制。问题在于它是在普通 QWidgets 的 顶部 绘制的。
    【解决方案4】:

    这是一个老问题,但我最近遇到了很多麻烦,这对我有帮助 -

    使用 QML/QT Quick。 QML 是一种类似 javascript 的语言,它允许您在窗口上布局小部件元素并对鼠标单击等事件进行基本处理。还有一些其他很酷的功能,但与这个问题最相关的是您可以从 C++ 代码中导入 qt 小部件。

    因此,您可以制作自定义 QGLWidget,将其导入 QML 窗口,然后在其顶部随意设置大小/位置/棒状小部件,非常轻松。 QT 的Scenegraph 示例很好地解释了这一点。 Scenegraph 的代码也作为示例包含在至少 Qt Creator 3.2.1 Open Source 中(反正我有这个版本)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 2014-10-20
      相关资源
      最近更新 更多