Qt中何时使用paintEvent和paintGL?

2024-02-24

我在用QOpenGL控件 https://doc.qt.io/qt-5/qopenglwidget.html并且不明白我应该把绘图代码放在哪里:在覆盖的内部paintGL https://doc.qt.io/qt-5/qopenglwidget.html#paintGL或内部覆盖绘制事件 https://doc.qt.io/qt-5/qopenglwidget.html#paintEvent.

我应该调用这些函数的基类版本吗?

这些功能是如何连接的? PaintGL 启动paintEvent 或反之亦然?也许它们是由于非相交原因而启动的(即恢复窗口、绘制一些 3D 几何图形、更改窗口大小)?那么这些原因是什么呢?

最后,当我更改几何图形时如何强制重新渲染图形?我应该调用什么方法?


简短的回答:Open GL 绘图QOpenGLWidget应该发生在QOpenGLWidget::paintGL().

当调用 OpenGL 命令时,一个前提条件是相应的命令。 OpenGL 上下文之前已被激活。这是什么QOpenGLWidget::paintGL() https://doc.qt.io/qt-5/qopenglwidget.html#paintGL确保:

无需致电makeCurrent() https://doc.qt.io/qt-5/qopenglwidget.html#makeCurrent因为当这个函数被调用时,这已经完成了。

在调用此函数之前,上下文和帧缓冲区已绑定,并且通过调用 glViewport() 设置视口。

顺便提一句。另一个先决条件是分别。 OpenGL 上下文已经创建完毕。


为了了解更多相关信息,我进行了更深入的研究——QOpenGLWidget::paintEvent() https://code.woboq.org/qt5/qtbase/src/widgets/kernel/qopenglwidget.cpp.html#_ZN13QOpenGLWidget10paintEventEP11QPaintEvent(在 woboq.org 上):

void QOpenGLWidget::paintEvent(QPaintEvent *e)
{
    Q_UNUSED(e);
    Q_D(QOpenGLWidget);
    if (!d->initialized)
        return;
    if (updatesEnabled())
        d->render();
}
  1. 只要初始化尚未完成,绘制事件就不会执行任何操作。 (我没有深入挖掘,但我确信初始化涉及调用QOpenGLWidget::initializeGL().)

  2. 绘制事件请求渲染。

眼睛跟随代码(严格来说:鼠标点击),d->render() calls QOpenGLWidgetPrivate::render()这又调用finallyQOpenGLWidgetPrivate::invokeUserPaint()我们在这里:

void QOpenGLWidgetPrivate::invokeUserPaint()
{
    Q_Q(QOpenGLWidget);
    QOpenGLContext *ctx = QOpenGLContext::currentContext();
    Q_ASSERT(ctx && fbo);
    QOpenGLFunctions *f = ctx->functions();
    QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbo->handle();
    f->glViewport(0, 0, q->width() * q->devicePixelRatioF(), q->height() * q->devicePixelRatioF());
    inPaintGL = true;
 // vvvvvvvvvvvv
    q->paintGL();
 // ^^^^^^^^^^^^
    inPaintGL = false;
    flushPending = true;
    QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = 0;
}

(评论是我的。)

So, if QOpenGLWidget::paintEvent()超载,那么它应该调用paintEvent()基类的。 (否则OpenGL渲染肯定会中断。​​)


最后,当我更改几何图形时如何强制重新渲染图形?我应该调用什么方法?

这实际上在描述中得到了回答QOpenGLWidget:

如果您需要从paintGL()以外的地方触发重绘(一个典型的例子是使用计时器来动画场景),您应该调用小部件的update() https://doc.qt.io/qt-5/qwidget.html#update安排更新的功能。


万一我误解了OP的意图,实际的问题是放在哪里QPainter画入QOpenGLWidget– 我曾经写过一个答案SO:在特定时间在 qglwidget 上绘制一个矩形 https://stackoverflow.com/a/42420804/7478597关于混合 OpenGL 命令和QPainter画入paintGL().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt中何时使用paintEvent和paintGL? 的相关文章

随机推荐

  • 急切地评估 Prolog 中的所有谓词调用

    正在阅读有关元谓词的 SWI Prolog 文档 http www swi prolog org pldoc man section metapred 我最初假设call f 相当于f where f是一些谓词 但我观察到 在某些情况下 两
  • 是否可以用 Java 构建这样的自定义 GUI?

    我在 Photoshop 中制作了这个 我计划将其用于我的文件共享应用程序 我想知道是否可以为我的应用程序创建具有这种外观和感觉的 GUI 如果我无法仅使用 eclipse 或 NetBeans 来构建它 还有其他工具可以帮助我吗 哦 亲爱
  • 我何时以及为什么需要supportedRuntime元素和sku属性?

    在 Visual Studio 中创建的大多数 如果不是全部 C 以及 F 和 VB 库和可执行项目中 都会自动添加app config指定运行时版本和目标框架名称 TFM 的文件
  • Laravel 4.1:雄辩的偏移和限制

    如何限制 Eloquent 返回的数据 我尝试过这个 data Product all gt take 4 gt skip 3 它返回错误消息 Call to undefined method Illuminate Database Elo
  • 如何使用 sendmessage 发送 win32 中具有计时器过程的 wm_timer

    我有一个计时器 ID 1 它有一个timerproc作为回调函数 我正在 timeproc 中制作其他计时器 ID 2 3 它们使用WM TIMER事件 而不是另一个计时器进程 创建窗口时 我想立即生成定时器事件 ID 1 所以我像这样使用
  • wxWidgets - 事件表与 Connect()?

    我刚刚开始使用 C 学习 wxWidgets 3 0 版 我已经注意到 wxWidgets 中的事件处理是由事件表完成的 但一篇教程也提到了 Connect 实际上它只是说 本教程将使用事件表 而不是 Connect 我想知道事件表和 Co
  • 在标点符号前动态添加 标签

    我正在尝试弄清楚如何添加
  • WPEngine 备份中 WordPress 项目中的 PHP 解析错误

    我继承了一个 Wordpress 项目 并且正在尝试对其进行设置 我对 WordPress 的经验为零 也可以说我对 PHP 的经验为零 到目前为止 我已经成功在本地计算机上设置了环境 但我遇到了 PHP 解析错误 无法通过谷歌搜索找到解决
  • 为什么我的 RxJS 倒计时时钟不显示?

    我正在开发一个 Angular 9 测验应用程序 我正在使用 RxJS 作为倒计时器 在container scoreboard time time component ts 中 并且计时器似乎没有显示 stopTimer 函数应在计时器停
  • Visual Studio 团队服务与 GitHub

    我正在寻找为我的内部 闭源 项目设置 CI 工作流程 我目前正在使用 GitHub 进行 git 问题跟踪 我的应用程序是桌面应用程序 没有云 服务器部署 因此工作流程应该是 在 github 上提交 master 通过以下方式通知 CIg
  • NullInjectorError:没有 InjectionToken DocumentToken 的提供者

    我正在为所有 Angular 5 项目设置一个通用库 库是 GitHub 存储库的克隆角度库入门套件 https github com zurfyx angular library starter kit 一切正常 直到我尝试使用HttpC
  • 使用配置文件启动redis-server

    我的配置文件位于 root config redis rb 我这样启动redis redis server 如何启动 redis 以便它使用我的配置文件 另外 我讨厌乱搞ps grep尝试找到一个 pid 来关闭它 如何通过 cd 进入根目
  • ReplaceWith 自动关闭标签

    我有 3 个 div 我想用另一个 div 的开始标签替换第一个 div 用结束标签替换第三个 div 这就是我的意思 div 1 div div 2 div div 3 div 当我尝试替换 使用replaceWith 第一个div时 d
  • YouTube 数据 API v3 允许浏览器应用密钥的引荐来源网址未按预期工作

    我正在努力尝试正确配置新的 YouTube Data API v3 我需要从 Google Chrome 扩展程序访问 API 我已经创建了一个 API 密钥Google API 控制台 https code google com apis
  • 提交按钮正在下载 php 而不是运行它

    我正在尝试为我的网站制作联系表单 但是当我按提交时 会下载 php 文件而不是运行 我正在使用 chrome 但我认为这并不重要 我认为存在语法错误 但我已经搞乱了删除 添加等内容 即使没有语法错误 它仍然会下载文件而不是运行它 而且 是的
  • 如果输入值为空,则使用 Javascript 指定值“空”

    所以我有一个输入字段 如果它是空白的 我希望它的值是 空 一词 但是如果输入了任何值 我希望该值是输入的值 我想为此使用 javascript 知道如何做到这一点吗 UPDATE 抱歉 我认为我解释得不太好 我的意思不是占位符文本 我的意思
  • Airflow Worker 没有监听默认的 RabbitMQ 队列

    我已经使用rabbitmq代理配置了Airflow 服务 airflow worker airflow scheduler airflow webserver 正在运行 没有任何错误 调度程序正在推动任务执行default兔子MQ队列 即使
  • JAVA Android APK发布模式错误无法下载kotlin-compiler.jar

    当我在发布模式下构建新的 APK 或生成签名的 APK 时 出现以下错误 无法下载 kotlin compiler jar com android tools external com intellij kotlin compiler 26
  • C# 中的开源 C 编译器? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Qt中何时使用paintEvent和paintGL?

    我在用QOpenGL控件 https doc qt io qt 5 qopenglwidget html并且不明白我应该把绘图代码放在哪里 在覆盖的内部paintGL https doc qt io qt 5 qopenglwidget h