- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
据我了解,QOpenGlWidget
使用与任何其他小部件相同的窗口上下文。我认为使用 keyPressEvent
来处理绘图命令是个好主意。
不幸的是,它没有按预期工作。当我处理 Key_Escape
退出应用程序时,它可以工作,但是当我尝试处理 OpenGL 绘图函数的 Key_W
或 Key_F
时,它不起作用不要 react 。
这是 GL 函数的问题还是我以错误的方式进行事件处理?
UPD:我还尝试在事件中更新小部件,它完全搞乱了屏幕上的所有内容。我对我的 GLFW 项目做了同样的事情,效果很好。
import numpy as np
from OpenGL.GL import *
from PySide2 import QtOpenGL, QtWidgets, QtCore, QtGui
class Viewport(QtWidgets.QOpenGLWidget):
def __init__(self, width: int, height: int, title :str="Qt OpenGl Window",
r: int=0.2, g: int=0.3, b: int=0.3, a: int=1.0):
super().__init__()
self.width = width
self.height = height
self.bg_color = (r, g, b, a)
self.setWindowTitle(title)
self.resize(self.width, self.height)
self.bool_shaded = True
self.vertices = np.array([], dtype=np.float32)
# Should be OpenGL.GL.shaders.ShaderProgram
self.shader_program = None
# Should be int to be used in "layout (location = attr_position)..."
self.attr_position = None
def initializeGL(self):
VBO = self.__createVBO(self.vertices)
# Create and bind here once because we have only one VAO that there's no need to bind every time
VAO = self.__createVAO()
self.shader_program = self.__compileShaders(path_vertex="shaders/triangle.vs",
path_fragment="shaders/triangle.fs")
self.attr_position = self.createAttribute(self.shader_program, "a_position", 0)
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT)
glClearColor(self.bg_color[0], self.bg_color[1],
self.bg_color[2], self.bg_color[3])
glUseProgram(self.shader_program)
glDrawArrays(GL_TRIANGLES, 0, 3)
def resizeGL(self, w: int, h: int):
glViewport(0, 0, w, h)
def keyPressEvent(self, event: QtGui.QKeyEvent):
if event.key() == QtCore.Qt.Key_Escape:
app.exit()
if event.key() == QtCore.Qt.Key_W:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
if event.key() == QtCore.Qt.Key_F:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
if event.key() == QtCore.Qt.Key_P:
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)
event.accept()
def __createVBO(self, vertices :np.ndarray):
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)
return VBO
def __createVAO(self):
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)
return VAO
def __compileShaders(self, path_vertex: str, path_fragment: str):
with open(path_vertex, "r") as source:
vertex = compileShader(source.read(), GL_VERTEX_SHADER)
with open(path_fragment, "r") as source:
fragment = compileShader(source.read(), GL_FRAGMENT_SHADER)
shader_program = compileProgram(vertex, fragment)
return shader_program
def createAttribute(self, shader, attrib_name: str, stride:
attribute = glGetAttribLocation(shader, attrib_name)
glEnableVertexAttribArray(attribute)
glVertexAttribPointer(attribute, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(0))
return attribute
def setVertices(self, vertex_list: list):
vertices = np.array(vertex_list, dtype=np.float32)
self.vertices = vertices
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Viewport(1280, 720)
vertices = [-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0]
window.setVertices(vertices)
window.show()
window.printDebugInfo()
sys.exit(app.exec_())
最佳答案
在执行 OpenGL 指令之前,必须将 [OpenGL 上下文](OpenGL 上下文) 设置为当前。系统会在 paintGL
或 resizeGL
之前自动将上下文设为当前上下文,但在 keyPressEvent
之前则不会。因此 keyPressEvent
中的 OpebGL 指令无效。
使用多边形模式的状态并在keyPressEvent
中更改状态,但在paintGL
中调用glPolygonMode
来解决问题。例如:
class Viewport(QtWidgets.QOpenGLWidget):
# [...]
def initializeGL(self):
self.polygonmode = GL_FILL
# [...]
def paintGL(self):
glPolygonMode(GL_FRONT_AND_BACK, self.polygonmode)
# [...]
def keyPressEvent(self, event: QtGui.QKeyEvent):
if event.key() == QtCore.Qt.Key_Escape:
app.exit()
if event.key() == QtCore.Qt.Key_W:
self.polygonmode = GL_LINE
if event.key() == QtCore.Qt.Key_F:
self.polygonmode = GL_FILL
if event.key() == QtCore.Qt.Key_P:
self.polygonmode = GL_POINT
event.accept()
关于python - PySide2 QOpenGLWidget按键事件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60061714/
与my other question相关,我正在尝试渲染分割蒙版以启用对象拾取。但是我无法达到预期的结果。 选项 1 根本不起作用。我无法检索颜色附件 1 的内容,也无法检查它是否存在(我仅使用 na
我只是想知道 Qt 上的 QOpenGLWidget(我使用的是 5.4 版)是否可以在没有子类化的情况下使用。 在 Qt Creator 表单编辑器中,有一个 Display 小部件可以插入到名为“
以前我用 opengl 创建 qt 应用程序有困难,我总是设法用 SDL 或 glfw + glew 创建一个纯 opengl 应用程序。 但我按照大家在视频中所做的程序,创建了一个派生自 QOpen
我正在使用 Qt 和 OpenGL 开发 3D 应用程序。该应用程序由 QMainWindow 和 QOpenGLWidget 作为中央小部件和 QML UI 作为停靠小部件组成。我意识到用户输入和
我在 QMainWindow 实例 w 中嵌入了一个 QOpenGLWidget。编译正常。但是在调试时,程序在 w.show() 处崩溃。 错误对话框显示: Exception thrown at
我正在尝试使用四边形作为纹理,使用 QOpenGLWidget 渲染一个简单的二维图像。但无论我尝试什么,我总是得到一个黑盒子。 我看了很多教程,我有一个像这样的简单像素缓冲区 uchar* m_pD
你是我解决这个问题的最后手段,因为我没有想法。所以首先,我已经完成了一些 openGL 的工作,但没有使用 Qt 库。 由于 Qt Android 编译器,我必须使用 Qt 库来完成它,所以我别无选择
我对QOpenGLWidget和它的背景颜色有一点小问题。。当我想使用QPainter在我的自定义QOpenGLWidget上创建半透明的RECT时,有两种不同的结果:。以下是QPainter的代码示
我想将第二个渲染目标添加到 QOpenGLWidget 的默认帧缓冲区。 原因是我想通过将分割掩码渲染到 gl_FragData[1] 来实现对象拾取并检查用户是否击中对象。不幸的是,您只能从小部件中
我正在尝试使用 QOpenGLWidget 来显示一些图像,而不是使用 QLabel。但我对如何做到这一点感到有点困惑。 为了让小部件完成工作,我知道我需要重新实现 initializeGL() 方法
我有一个隐藏的 QOpenGLWidget(Qt 5.4.2,不是 QGLWidget),我想基本上不断地执行grab()或grabFramebuffer()来获取其内容(并将其写入磁盘)。该小部件在
我正在尝试编写一个使用 QOpenGLWidget 的 C++ 应用程序,但是 Qt Creator 在这一行给出了“‘QOpenGLWidget’文件未找到”错误: #include 文档说 QO
我正在尝试使用 QOpenGLWidget 而无需子类化。 当我尝试在 QOpenGLWidget 的方法或信号之外进行 OpenGL 调用时,似乎什么也没有发生。例如,尽管我设置了 glClearC
你好,我有一个基于 Qt 使用 QOpenGLWidget 的应用程序。在 OpenGL 小部件(在我的代码中名为 oglwidget)中,我使用 opengl 函数绘制网格和线条。然后我使用 QPa
我想解决我仍在处理的问题..那就是在不同的顶级窗口中使用共享着色器程序等同时渲染 2 个 QOpenGLWidgets。 我的第一次尝试是使用一个上下文,但没有成功。 目前 QOpenGLWidget
我一直在使用带有 QOpenGLWindow 的着色器文件并使用版本 330 着色器,一切正常。但是想要切换为 Widget 以便能够将其停靠在我的应用程序主窗口中。从那以后,我一直在努力获得正确的上
我们有一个基于 QWidget 的应用程序,它以前使用 QWindow 进行 OpenGL 渲染。为了在我们的应用程序中适应该窗口,我们必须使用 QWidget QWidget::createWind
我正在尝试使用 QOpenGLWidget 在 Qt 内部使用 OpenGL,但我很难找到任何相关示例。我是 OpenGL 的新手,所以我想学习如何使用它,但我发现的教程似乎在 QOpenGLWidg
我想在 QOpenGLWidget 上绘制文本标签。我尝试使用 QPainter 来完成此任务,但没有成功 - 文本看起来很丑陋且没有抗锯齿。它在 Qt OpenGL/2dpainting 示例中看起
调试时的确切崩溃是: The inferior stopped because it triggered an exception. Stopped in thread 0 by: Exception
我是一名优秀的程序员,十分优秀!