class Video(QWidget): def __init__(self): # init the widget QWidget.__init__(self) # set up the scene self.scene=QGraphicsScene() self.scene.setSceneRect(0,0,800,600) # add a view of that scene self.view = QGraphicsView() self.view.setScene(self.scene) self.view.setRenderHint(QPainter.Antialiasing) self.view.setFixedSize(800,600) self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # set the screen sync val = "1" # Set for nVidia linux os.environ["__GL_SYNC_TO_VBLANK"] = val # Set for recent linux Mesa DRI Radeon os.environ["LIBGL_SYNC_REFRESH"] = val qglf = QGLFormat() qglf.setSampleBuffers(True) #qglf.setSwapInterval(1) self.glw = QGLWidget(qglf) self.glw.setAutoBufferSwap(False) self.view.setViewport(self.glw) QTimer.singleShot(0,self.glw.swapBuffers) def swapBuffers(self): # first call the swap on the QGLWidget self.glw.swapBuffers() self.glw.makeCurrent() # The following is taken from the PsychToolbox # Draw a single pixel in left-top area of back-buffer. # This will wait/stall the rendering pipeline # until the buffer flip has happened, aka immediately after the VBL has started. # We need the pixel as "synchronization token", so the following glFinish() really # waits for VBL instead of just "falling through" due to the asynchronous nature of # OpenGL: glDrawBuffer(GL_BACK) # We draw our single pixel with an alpha-value of zero - so effectively it doesn't # change the color buffer - just the z-buffer if z-writes are enabled... glColor4f(0.0,0.0,0.0,0.0) glBegin(GL_POINTS) glVertex2i(10,10) glEnd() # This glFinish() will wait until point drawing is finished, ergo backbuffer was ready # for drawing, ergo buffer swap in sync with start of VBL has happened. glFinish() def show(self): # shows the viewer widget self.view.show()
class Figure(QGraphicsView): def __init__(self, *args, **kwargs): super(Figure, self).__init__(*args, **kwargs) # Creation of the Plotting class: # Then we add it as background of the View: self._context = QGLWidget(QGLFormat(QGL.NoAccumBuffer)) self.setViewport(self._context) # create the context for Opengl self._context.makeCurrent() # And we set it as scene for the View: self.scene = OGLWidget() self.setScene(self.scene) self.scene.initializeGL() # Set some properties and palette to have a black background: color = QColor() color.black() self.background_color = color # unset the context ??? self._context.doneCurrent() @property def background_color(self): return self._background_color @background_color.setter def background_color(self, background_color): self._background_color = background_color self.setAutoFillBackground(True) self.setPalette( QPalette( self._background_color ) ) def addWidget(self, wid): tmp = self.scene.addWidget(wid, Qt.Window) tmp.setFlag( QGraphicsItem.ItemIsMovable ) tmp.setFlag( QGraphicsItem.ItemIsSelectable ) tmp.setCacheMode( QGraphicsItem.DeviceCoordinateCache ) def resizeEvent(self, event): if self.scene: self.scene.resizeGL(event.size().width(), event.size().height()) super(Figure, self).resizeEvent(event) def keyPressEvent(self, event): super(Figure, self).keyPressEvent(event) if ( event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_W ) or event.key() == Qt.Key_Escape: print("Quiting!") self.close() else: event.ignore() def __getitem__(self, ind): return self.scene.lines[ind] def __delitem__(self, ind): pass @property def axes(self): return self.scene.lines @axes.setter def axes(self, value): # store the instance for plots self.scene.lines = value # create shaders if there is one self._context.makeCurrent() try: value.createShaders(self._context) except AttributeError: pass self._context.doneCurrent() # add widget created by user try: wid = value.createWidget() if wid: self.addWidget(wid) except AttributeError: pass