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)
child.grabFrameBuffer()@
@# Result:
QGLWidget
<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)
image.save( '/Volumes/LaCie_Work/_TMP/test/test0.png', 'PNG')@Result : !http://i.imgur.com/YwTtR2q.png(http://i.imgur.com/YwTtR2q.png)!
Problem : Miss lot of elements@# Qwidget.render(QPixmap)
image = QtGui.QPixmap(child.size())
child.render(image)
image.save( '/Volumes/LaCie_Work/_TMP/test/test1.png', 'PNG')@Result : !http://i.imgur.com/DqO1PBS.png(http://i.imgur.com/DqO1PBS.png)!
Problem : No ! (see further below)@# QPixmap.grabWidget(QWidget)
image = QtGui.QPixmap.grabWidget(child)
image.save( '/Volumes/LaCie_Work/_TMP/test/test2.png', 'PNG')@Result : !http://i.imgur.com/9n9Hofy.png(http://i.imgur.com/9n9Hofy.png)!
Problem : Not exactly but ok.. (see further below)@# QPixmap.grabWindow(QWidget.winId())
image = QtGui.QPixmap.grabWidget(child)
image.save( '/Volumes/LaCie_Work/_TMP/test/test2.png', 'PNG')@Result : !http://i.imgur.com/ewwDdZW.png(http://i.imgur.com/ewwDdZW.png)!
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)
image.save( '/Volumes/LaCie_Work/_TMP/test/test.png', 'PNG')@Result : !http://i.imgur.com/7oBEAgj.png(http://i.imgur.com/7oBEAgj.png)!
Problem : Any !! :)But...
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 :
- Why my QGLWidget is recognize like QWidget ? (pyside bug ?)
- Here is a way to force grabFrameBuffer() ?
- 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 ! :)
Thanks,
G.