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

Python中在QGLWidget上叠加绘制2D图形:绘制bounding box后网格变色求助

Hey Bruno, this sounds like a classic OpenGL state leak issue—when you draw your 2D bounding boxes, you’re modifying OpenGL’s global state (like color, projection matrix, or render modes) and not restoring it, which messes up the parent class’s grid rendering afterward. Let’s break down the fixes step by step:

Common Causes & Solutions

1. Save and Restore OpenGL State Stack

OpenGL uses a state machine, so any changes you make (like setting a new color or switching to orthographic projection) stay active until you explicitly revert them. The fix is to wrap your 2D drawing code in state-saving calls to isolate it from the parent’s OpenGL rendering.

Here’s how to adjust your paintGL() method in your QGLWidget subclass:

from OpenGL.GL import *

def paintGL(self):
    # First let the parent class draw its OpenGL content
    super().paintGL()

    # Save critical OpenGL states (color, transforms, enabled features)
    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT | GL_ENABLE_BIT)

    # Switch to 2D orthographic projection to match screen coordinates
    glMatrixMode(GL_PROJECTION)
    glPushMatrix()
    glLoadIdentity()
    # Map OpenGL coordinates directly to widget pixels (adjust if needed)
    glOrtho(0, self.width(), self.height(), 0, -1, 1)

    glMatrixMode(GL_MODELVIEW)
    glPushMatrix()
    glLoadIdentity()

    # Optional: Disable depth testing so 2D boxes draw on top of 3D content
    glDisable(GL_DEPTH_TEST)
    # Optional: Enable blending if you want semi-transparent boxes
    # glEnable(GL_BLEND)
    # glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    # Draw your bounding box here
    glColor3f(1.0, 0.0, 0.0)  # Red color for the box
    glBegin(GL_LINE_LOOP)
    glVertex2f(50, 50)   # Top-left corner
    glVertex2f(200, 50)  # Top-right
    glVertex2f(200, 200) # Bottom-right
    glVertex2f(50, 200)  # Bottom-left
    glEnd()

    # Restore matrix states first
    glMatrixMode(GL_MODELVIEW)
    glPopMatrix()

    glMatrixMode(GL_PROJECTION)
    glPopMatrix()

    # Restore all saved OpenGL attributes
    glPopAttrib()

2. Explicitly Reset State If You Skip the Stack

If you don’t want to use glPushAttrib() for some reason, make sure to manually reset every state you change after drawing the box:

  • Reset the color back to whatever the parent class uses (e.g., glColor3f(0.0, 1.0, 0.0) for green grids)
  • Re-enable depth testing if you disabled it (glEnable(GL_DEPTH_TEST))
  • Switch back to perspective projection if your parent uses it

3. Verify Parent Class State Setup

Double-check that your parent class’s paintGL() method explicitly sets its own state (like color, projection, depth testing) at the start of each draw. If it relies on default OpenGL states, any changes from your subclass will break it. Good practice for OpenGL code is to always set the state you need, not assume it’s correct.

Quick Debug Tip

To confirm it’s a state leak, try commenting out the bounding box drawing code. If the grid color goes back to normal, you know the problem is in how your 2D code modifies state without cleaning up.

Hope this fixes your grid color issue—let me know if you need to tweak any part for your specific setup!

内容的提问来源于stack exchange,提问作者Bruno Santos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:12:45