Important: Please read the Qt Code of Conduct -

PySide QGLWidget returned as QWidget, grabFrameBuffer() alternative ?

  • Hi !
    I'm working with Nuke which UI use an embed Python 2.6.4 and PySide 1.07
    I'm trying to grab the content of a Qwidget (a 3d viewport) in a thread to stream the content over lan to show in a distant Qwidget

    @for widget in QtGui.QApplication.allWidgets():
    if widget.metaObject().className() == "Viewer_Window":
    for child in widget.children():
    if child.metaObject().className() == "QGLWidget":
    print child.metaObject().className()
    print type(child)
    @# Result:
    <type 'PySide.QtGui.QWidget'>
    Traceback (most recent call last):
    File "<string>", line 7, in <module>
    AttributeError: 'PySide.QtGui.QWidget' object has no attribute 'grabFrameBuffer'@

    I tried:

    @# Qwidget.render(QImage)

    image = QtGui.QImage(child.width(),child.height(),QtGui.QImage.Format_RGB32)
    child.render(image) '/Volumes/LaCie_Work/_TMP/test/test0.png', 'PNG')@

    Result : !!
    Problem : Miss lot of elements

    @# Qwidget.render(QPixmap)

    image = QtGui.QPixmap(child.size())
    child.render(image) '/Volumes/LaCie_Work/_TMP/test/test1.png', 'PNG')@

    Result : !!
    Problem : No ! (see further below)

    @# QPixmap.grabWidget(QWidget)

    image = QtGui.QPixmap.grabWidget(child) '/Volumes/LaCie_Work/_TMP/test/test2.png', 'PNG')@

    Result : !!
    Problem : Not exactly but ok.. (see further below)

    @# QPixmap.grabWindow(QWidget.winId())

    image = QtGui.QPixmap.grabWidget(child) '/Volumes/LaCie_Work/_TMP/test/test2.png', 'PNG')@

    Result : !!
    Problem : WTF ?!

    All these methods are "threadable", BUT in a thread or not, if I create a simple sphere (or whatever) in this viewport the software (Nuke again) crash. I don't know why...

    I decided to try with pyOpenGl:

    @# pyOpenGl glReadPixel

    buffer = glReadPixels(0, 0, child.width(), child.height(), GL_RGB, GL_UNSIGNED_BYTE)
    image = PIL.Image.fromstring(mode="RGB", size=(child.width(),child.height()), data=buffer)
    image = image.transpose(PIL.Image.FLIP_TOP_BOTTOM) '/Volumes/LaCie_Work/_TMP/test/test.png', 'PNG')@

    Result : !!
    Problem : Any !! :)


    glReadPixels need to be called in the main thread to get the right context and that hang the software... (12 to 24 frames per second) :(
    And, glReadPixels capture the GL buffer of the focused widget, if I click on an other widget of the UI, glReadPixels capture this one..

    With Qt :

    1. Why my QGLWidget is recognize like QWidget ? (pyside bug ?)
    2. Here is a way to force grabFrameBuffer() ?
    3. Can I live stream the QWidget content to a QGLWidget and grab it ?

    With PyOpenGL :
    4) Could I access a specific Qwidget Framebuffer from a thread ?

    Any help or suggestion is very welcome ! :)


Log in to reply