我正在开发一个软件,我想在该软件中添加一个 OpenGL可视化窗口,以便当用户按下某些按钮(例如单击以渲染Triangle)时可以在此窗口中渲染某些东西应该绘制一个三角形,或者当他单击球体时,应该绘制一个球体。
实际上我想将opengl东西渲染为搅拌器的整体性等。
我正在 PyQt5 中完成所有这些操作。任何人都可以建议我或为我提供完善的建议。
我看过Qt官方文档,但是它们都很混乱。
我认为所有这些都可以使用 QWindow,QPainter,QOpenGLWindow 完成,但是我无法实现,任何人都可以为我提供代码吗?
这是可以正常工作的代码,但不允许在按下的按钮上绘制内容。
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
.
.
.
self.openGLWidget = OGLWidget(self.main)
self.openGLWidget.setObjectName("openGLWidget")
self.verticalLayout.addWidget(self.openGLWidget)
.
.
.
self.show()
def retranslateUi(self):
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("self", "self"))
self.pushButton.setText(_translate("self", "PushButton"))
def keyPressEvent(self, e):
print(e.key())
class OGLWidget(QtWidgets.QOpenGLWidget):
def initializeGL(self):
glClearColor(0.2,0.2,0.2,0)
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
.
.
.
def resizeGL(self,w,h):
.
.
.
if __name__ == "__main__":
.
.
.
这是我使用QWindow和QOpenGLWindow的代码,但是它不起作用
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
.
.
.
self.openGLWidget = ChocoWindow(self.main)
self.openGLWidget.setObjectName("openGLWidget")
.
.
.
self.show()
def retranslateUi(self):
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("self", "self"))
self.pushButton.setText(_translate("self", "PushButton"))
def keyPressEvent(self, e):
print(e.key())
class OpenGLWindow(QtGui.QWindow):
def __init__(self, parent=None):
super(OpenGLWindow, self).__init__(parent)
self.m_update_pending = False
self.m_animating = False
self.m_context = None
self.m_gl = None
self.setSurfaceType(QtGui.QWindow.OpenGLSurface)
def initialize(self):
pass
def setAnimating(self, animating):
self.m_animating = animating
if animating:
self.renderLater()
def renderLater(self):
if not self.m_update_pending:
self.m_update_pending = True
QtGui.QGuiApplication.postEvent(self, QtCore.QEvent(QtCore.QEvent.UpdateRequest))
def renderNow(self):
if not self.isExposed():
return
self.m_update_pending = False
needsInitialize = False
if self.m_context is None:
self.m_context = QtGui.QOpenGLContext(self)
self.m_context.setFormat(self.requestedFormat())
self.m_context.create()
needsInitialize = True
self.m_context.makeCurrent(self)
if needsInitialize:
version = QtGui.QOpenGLVersionProfile()
version.setVersion(2, 0)
self.m_gl = self.m_context.versionFunctions(version)
self.m_gl.initializeOpenGLFunctions()
self.initialize(self.m_gl)
self.render(self.m_gl)
self.m_context.swapBuffers(self)
if self.m_animating:
self.renderLater()
def event(self, event):
print(event)
print(event.type())
if event.type() == QtCore.QEvent.UpdateRequest:
self.renderNow()
return True
return super(OpenGLWindow, self).event(event)
def exposeEvent(self, event):
self.renderNow()
def resizeEvent(self, event):
self.renderNow()
def triangle(self):
glBegin(GL_TRIANGLES)
glColor3f(1.0, 0.0, 0.0)
glVertex3f(-0.5, -0.5, 0)
glColor3f(0.0, 1.0, 0.0)
glVertex3f( 0.5, -0.5, 0)
glColor3f(0.0, 0.0, 1.0)
glVertex3f( 0.0, 0.5, 0)
glEnd()
glViewport(0, 0, self.width(), self.height())
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, 1, 1, 100.0)
gluLookAt(0,0,5,0,0,0,0,1,0)
class ChocoWindow(OpenGLWindow):
def __init__(self, parent=None):
super(ChocoWindow, self).__init__(parent)
def initialize(self, gl):
glClearColor(0.2,0.2,0.2,0)
def render(self, gl):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
triangle(self)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = Ui_MainWindow()
sys.exit(app.exec_())
这不起作用,这表明出现以下错误
Traceback (most recent call last):
File "code.py", line 181, in <module>
window = Ui_MainWindow()
File "code.py", line 29, in __init__
self.openGLWidget = ChocoWindow(self.main)
File "code.py", line 150, in __init__
super(ChocoWindow, self).__init__(parent)
File "code.py", line 62, in __init__
super(OpenGLWindow, self).__init__(parent)
TypeError: arguments did not match any overloaded call:
QWindow(screen: QScreen = None): argument 1 has unexpected type 'QWidget'
QWindow(QWindow): argument 1 has unexpected type 'QWidget'
我想将opengl东西呈现为搅拌器的整体性等。
答案 0 :(得分:0)
QWidget仅允许其他QWidget作为子对象,因此针对您的情况的解决方案是使用方法QWidget::createWindowContainer()
将QWindow转换为QWidget:
from PyQt5 import QtCore, QtGui, QtWidgets
from OpenGL import GL, GLU
class OpenGLWindow(QtGui.QWindow):
def __init__(self, parent=None):
super(OpenGLWindow, self).__init__(parent)
self.m_update_pending = False
self.m_animating = False
self.m_context = None
self.m_gl = None
self.setSurfaceType(QtGui.QWindow.OpenGLSurface)
def initialize(self):
pass
def setAnimating(self, animating):
self.m_animating = animating
if animating:
self.renderLater()
def renderLater(self):
if not self.m_update_pending:
self.m_update_pending = True
QtGui.QGuiApplication.postEvent(
self, QtCore.QEvent(QtCore.QEvent.UpdateRequest)
)
def renderNow(self):
if not self.isExposed():
return
self.m_update_pending = False
needsInitialize = False
if self.m_context is None:
self.m_context = QtGui.QOpenGLContext(self)
self.m_context.setFormat(self.requestedFormat())
self.m_context.create()
needsInitialize = True
self.m_context.makeCurrent(self)
if needsInitialize:
version = QtGui.QOpenGLVersionProfile()
version.setVersion(2, 0)
self.m_gl = self.m_context.versionFunctions(version)
self.m_gl.initializeOpenGLFunctions()
self.initialize(self.m_gl)
self.render(self.m_gl)
self.m_context.swapBuffers(self)
if self.m_animating:
self.renderLater()
def event(self, event):
if event.type() == QtCore.QEvent.UpdateRequest:
self.renderNow()
return True
return super(OpenGLWindow, self).event(event)
def exposeEvent(self, event):
self.renderNow()
def resizeEvent(self, event):
self.renderNow()
def triangle(self):
GL.glBegin(GL.GL_TRIANGLES)
GL.glColor3f(1.0, 0.0, 0.0)
GL.glVertex3f(-0.5, -0.5, 0)
GL.glColor3f(0.0, 1.0, 0.0)
GL.glVertex3f(0.5, -0.5, 0)
GL.glColor3f(0.0, 0.0, 1.0)
GL.glVertex3f(0.0, 0.5, 0)
GL.glEnd()
GL.glViewport(0, 0, self.width(), self.height())
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GLU.gluPerspective(45, 1, 1, 100.0)
GLU.gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0)
class ChocoWindow(OpenGLWindow):
def initialize(self, gl):
GL.glClearColor(0.2, 0.2, 0.2, 0)
def render(self, gl):
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
triangle(self)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
label = QtWidgets.QLabel("ChocoWindow", alignment=QtCore.Qt.AlignCenter)
label.setSizePolicy(
QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum
)
window = ChocoWindow()
widget = QtWidgets.QWidget.createWindowContainer(window)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(label)
lay.addWidget(widget)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())