示例#1
0
class CinemolCanvas(QGLWidget):
    # Singleton thread for all OpenGL actions
    
    def __init__(self, parent=None):
        QGLWidget.__init__(self, parent)
        self.setAutoBufferSwap(False)
        self.resize(640, 480)
        self.opengl_thread = QThread()
        QCoreApplication.instance().aboutToQuit.connect(self.clean_up_before_quit)
        self.trackball = Trackball()
        self.preferredSize = None
        self.setFocusPolicy(Qt.WheelFocus)
        
    # delegate opengl tasks to separate non-qt-gui Renderer object
    def set_gl_renderer(self, renderer):
        self.renderer = renderer
        self.renderer.set_gl_widget(self)
        bUseSeparateOpenGLThread = False
        if bUseSeparateOpenGLThread:
            self.renderer.moveToThread(self.opengl_thread)
            self.opengl_thread.start()
        self.trackball.rotation_incremented.connect(self.renderer.increment_rotation)
        self.trackball.zoom_incremented.connect(self.renderer.increment_zoom)
        self.trackball.pixel_translated.connect(self.renderer.translate_pixel)
        self.trackball.pixel_centered.connect(self.renderer.center_pixel)

    def paintEvent(self, event):
        self.doneCurrent()
        self.paint_requested.emit()
        
    def resizeEvent(self, event):
        self.doneCurrent()
        sz = event.size()
        self.resize_requested.emit(sz.width(), sz.height())
        
    def sizeHint(self):
        if self.preferredSize is None:
            return QGLWidget.sizeHint(self)
        return self.preferredSize
        
    @QtCore.Slot(int, int)
    def special_resize(self, w, h):
        self.preferredSize = QSize(w, h)
        self.resize(w, h)

    @QtCore.Slot()
    def clean_up_before_quit(self):
        self.opengl_thread.quit()
        self.opengl_thread.wait()

    paint_requested = QtCore.Signal()
    resize_requested = QtCore.Signal(int, int)
    save_image_requested = QtCore.Signal(str)
    save_lenticular_series_requested = QtCore.Signal(str, float, int)
    
    def save_image(self, file_name):
        self.save_image_requested.emit(file_name)
        
    def save_lenticular_series(self, file_name, angle, count=18):
        self.save_lenticular_series_requested.emit(file_name, angle, count)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Left:        
            r = Rotation().set_from_angle_about_unit_vector(-0.05, [0, 0, -1])
            self.trackball.rotation_incremented.emit(r)
        elif event.key() == Qt.Key_Right:
            r = Rotation().set_from_angle_about_unit_vector( 0.05, [0, 0, -1])
            self.trackball.rotation_incremented.emit(r)
        elif event.key() == Qt.Key_Up:
            self.trackball.pixel_translated.emit(0, 0, 50);
        elif event.key() == Qt.Key_Down:
            self.trackball.pixel_translated.emit(0, 0, -50);
        QGLWidget.keyPressEvent(self, event) # not my event
        
    # Delegate mouse events to trackball class
    def mouseMoveEvent(self, event):
        self.trackball.mouseMoveEvent(event, self.size())
        
    def mousePressEvent(self, event):
        self.trackball.mousePressEvent(event)
        
    def mouseReleaseEvent(self, event):
        self.trackball.mouseReleaseEvent(event)
        
    def mouseDoubleClickEvent(self, event):
        self.trackball.mouseDoubleClickEvent(event, self.size())
        
    def wheelEvent(self, event):
        self.trackball.wheelEvent(event)