从线程中的QWidget记录opengl内容

时间:2013-11-02 00:57:55

标签: multithreading pyside pyopengl

我在PySide中使用了一些带有GUI的软件(Nuke),我想通过PySide获取QWidget中识别的QGLWidget的内容(很奇怪)并将其编码为视频。

所以,我不能使用QGLWidget.grabFrameBuffer():

AttributeError: 'PySide.QtGui.QWidget' object has no attribute 'grabFrameBuffer'

我试过了:

# 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')

结果:http://i.imgur.com/YwTtR2q.png - 问题:错过很多元素

# Qwidget.render(QPixmap)

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

结果:http://i.imgur.com/DqO1PBS.png - 问题:不! (见下文)

# QPixmap.grabWidget(QWidget)

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

结果:http://i.imgur.com/9n9Hofy.png - 问题:不完全正常......(见下文)

# QPixmap.grabWindow(QWidget.winId())

image = QtGui.QPixmap.grabWindow(child.winId())
image.save( '/Volumes/LaCie_Work/_TMP/test/test2.png', 'PNG')

结果:http://i.imgur.com/ewwDdZW.png - 问题:WTF?!

所有这些方法都是“可线程的”,但是在一个线程中,如果我在这个视口中创建一个简单的球体(或其他),软件(Nuke再次)崩溃。我不知道为什么......

我决定尝试使用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')

结果:http://i.imgur.com/7oBEAgj.png - 问题:任何!! :)

但是...

glReadPixels需要在主线程中调用以获得正确的上下文并挂起软件...(每秒12到24帧):(

使用Qt: 1)为什么我的QGLWidget被识别为QWidget? (pyside bug?) 2)这是一种强制使用grabFrameBuffer()的方法吗? 3)我可以将QWidget内容直播到QGLWidget并抓住它吗?

使用PyOpenGL: 4)我可以从线程访问特定的Qwidget帧缓冲区吗? 5)将FBO绑定在另一个新线程中?

非常欢迎任何帮助或建议!

0 个答案:

没有答案