在Pyqt窗口中使用glfw窗口

python-3.x pyqt4 glfw pyopengl

368 观看

1回复

35 作者的声誉

我有一个使用QT设计器设计并使用pyqt4转换的用户界面。在此用户界面中,我有表格,标签和更多内容...

我还要在该用户界面内添加一个glfw窗口,该窗口将与这些表进行交互并绘制一些3D对象。因此,我将在此glfw窗口中使用pyopengl。我知道如何在单独的窗口中执行此操作,但是该窗口必须位于其中。有什么办法吗?

谢谢

作者: BjkOcean 的来源 发布者: 2017 年 9 月 15 日

回应 1


1

1757 作者的声誉

决定

Qt有一个用于OpenGL上下文的内置控件,称为QGLWidget,您可以使用它来使用典型的PyOpenGL命令。您可能要尝试在应用程序中使用它,而不是在GLFW上下文中使用虚假信息。这个答案应该可以帮助您正常运行。如果您已经编写了3D可视化部分,则可能需要进行一些重组,但是,由于要使用此小部件,您需要实现某些功能,例如initializeGLpaintGL

编辑:

至于您在注释中有关处理鼠标事件以启用颜色选择的问题,其技巧是实现QGLWidget从继承QWidget。这意味着您可以访问mousePressEvent可以实现的功能。这是我编写的简洁演示(带有一些有用的评论),它告诉用户单击的位置以及该像素的颜色:

from OpenGL.GL import *
from OpenGL.GLU import *
from PyQt4 import QtGui
from PyQt4.QtGui import QColor, QStatusBar, QSizePolicy
from PyQt4.QtOpenGL import *
import sys

class MainWindow(QtGui.QWidget):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.widget = GLWidget(self)
        self.statusbar = QStatusBar()
        self.statusbar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.statusbar.showMessage("Click anywhere on the QGLWidget to see a pixel's RGBA value!")
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.widget)
        layout.addWidget(self.statusbar)
        layout.setContentsMargins(5, 5, 5, 5)
        self.setLayout(layout)

class GLWidget(QGLWidget):

    def __init__(self, parent):
        QGLWidget.__init__(self, parent)
        self.setMinimumSize(640, 480)
        #LMB = left mouse button
        #True: fires mouseMoveEvents even when not holding down LMB
        #False: only fire mouseMoveEvents when holding down LMB
        self.setMouseTracking(False)

    def initializeGL(self):
        glClearColor(0, 0, 0, 1)
        glClearDepth(1.0)
        glEnable(GL_DEPTH_TEST)

    def resizeGL(self, width, height):
        #glViewport is needed for proper resizing of QGLWidget
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, width, 0, height, -1, 1)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

    def paintGL(self):
        #Renders a triangle... obvious (and deprecated!) stuff
        w, h = self.width(), self.height()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glBegin(GL_TRIANGLES)
        glColor3f(1, 0, 0)
        glVertex3f(0, 0, 0)
        glColor3f(0, 1, 0)
        glVertex3f(w/2.0, h, 0)
        glColor3f(0, 0, 1)
        glVertex3f(w, 0, 0)
        glEnd()

    def mousePressEvent(self, event):
        x, y = event.x(), event.y()
        w, h = self.width(), self.height()
        #required to call this to force PyQt to read from the correct, updated buffer 
        #see issue noted by @BjkOcean in comments!!!
        glReadBuffer(GL_FRONT)
        data = self.grabFrameBuffer()#builtin function that calls glReadPixels internally
        data.save("test.png")
        rgba = QColor(data.pixel(x, y)).getRgb()#gets the appropriate pixel data as an RGBA tuple
        message = "You selected pixel ({0}, {1}) with an RGBA value of {2}.".format(x, y, rgba)
        statusbar = self.parent().statusbar#goes to the parent widget (main window QWidget) and gets its statusbar widget
        statusbar.showMessage(message)

    def mouseMoveEvent(self, event):
        pass

    def mouseReleaseEvent(self, event):
        pass

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.setWindowTitle("Color Picker Demo")
    window.show()
    app.exec_()

结果看起来像这样:

在此处输入图片说明

作者: CodeSurgeon 发布者: 2017 年 9 月 17 日
32x32