You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt6/PySide6中关闭窗口后resizeGL的glViewport报‘Invalid operation’错误

解决PyQt6/PySide6中关闭窗口时resizeGL触发OpenGL无效操作错误

问题原因

窗口关闭流程中,OpenGL上下文可能已被销毁,但Qt仍会触发resizeGL事件。此时调用glViewport等OpenGL函数,因缺少有效上下文,会抛出Invalid operation错误。

修复方案

以下两种方式均可解决该问题:

方案1:在resizeGL中检查上下文有效性

修改resizeGL方法,先确认当前OpenGL上下文有效后再执行OpenGL操作:

import sys

from OpenGL.GL import *
from PyQt6.QtCore import Qt
from PyQt6.QtOpenGL import QOpenGLWindow
from PyQt6.QtWidgets import QApplication


class OpenGLWindow(QOpenGLWindow):

    def __init__(self):
        super().__init__()

    def initializeGL(self):
        glClearColor(0.2, 0.2, 0.2, 1)

    def resizeGL(self, w, h):
        # 检查OpenGL上下文是否有效
        if self.context().isValid():
            glViewport(0, 0, w, h)

    def paintGL(self):
        # 同样添加上下文检查,避免关闭时paintGL报错
        if self.context().isValid():
            glClear(GL_COLOR_BUFFER_BIT)

if __name__ == "__main__":
    QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
    app = QApplication(sys.argv)
    w = OpenGLWindow()
    w.show()
    sys.exit(app.exec())

方案2:通过关闭标志控制resizeGL执行

添加关闭状态标志,在closeEvent中标记窗口正在关闭,resizeGL中判断该标志后跳过操作:

import sys

from OpenGL.GL import *
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QCloseEvent
from PyQt6.QtOpenGL import QOpenGLWindow
from PyQt6.QtWidgets import QApplication


class OpenGLWindow(QOpenGLWindow):

    def __init__(self):
        super().__init__()
        self._is_closing = False

    def initializeGL(self):
        glClearColor(0.2, 0.2, 0.2, 1)

    def resizeGL(self, w, h):
        if not self._is_closing:
            glViewport(0, 0, w, h)

    def paintGL(self):
        if not self._is_closing:
            glClear(GL_COLOR_BUFFER_BIT)

    def closeEvent(self, event: QCloseEvent) -> None:
        self._is_closing = True
        super().closeEvent(event)

if __name__ == "__main__":
    QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL)
    app = QApplication(sys.argv)
    w = OpenGLWindow()
    w.show()
    sys.exit(app.exec())

说明

方案1直接检查上下文状态,贴合OpenGL操作的本质逻辑;方案2通过状态标志控制,代码逻辑更直观。两种方案都能有效避免窗口关闭时的无效OpenGL调用错误。

内容的提问来源于stack exchange,提问作者8Observer8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:42:51