class QVolumeViewWidget(QWidget):
    def __init__(self, parent=None):
        super(QVolumeViewWidget, self).__init__(parent)
        # set up vtk pipeline and create vtkWidget
        self.renw = vtk.vtkRenderWindow()
        self.iren = vtk.vtkGenericRenderWindowInteractor()
        self.iren.SetRenderWindow(self.renw)
        kw = {'rw': self.renw, 'iren': self.iren}
        self.vtkWidget = QVTKRenderWindowInteractor(parent, **kw)
        self.MainLayout = QVBoxLayout()
        self.MainLayout.addWidget(self.vtkWidget)
        self.setLayout(self.MainLayout)
        # self.vtkWidget = QVTKRenderWindowInteractor()
        self.ren = vtk.vtkRenderer()
        self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)

        # add the orientation marker widget
        self.axes = vtk.vtkAxesActor()
        self.widget = vtk.vtkOrientationMarkerWidget()
        xyzLabels = ['R', 'A', 'S']
        self.axes.SetXAxisLabelText(xyzLabels[0])
        self.axes.SetYAxisLabelText(xyzLabels[1])
        self.axes.SetZAxisLabelText(xyzLabels[2])
        self.widget.SetOrientationMarker(self.axes)
        self.widget.SetInteractor(self.vtkWidget)
        self.widget.SetViewport(0.8, 0.0, 1, 0.3)
        self.widget.SetEnabled(True)
        self.widget.InteractiveOn()
        self.picker = vtk.vtkVolumePicker()

    def set_data_reader(self, reader):
        volumeMapper = vtk.vtkFixedPointVolumeRayCastMapper()
        # volumeMapper.SetBlendModeToMaximumIntensity()
        volumeMapper.SetInputData(reader.GetOutput())
        volume = vtk.vtkVolume()
        volume.SetMapper(volumeMapper)
        self.ren.AddVolume(volume)

    def start_render(self):
        # start render and interactor
        self.vtkWidget.Initialize()
        self.vtkWidget.Start()
        self.ren.SetBackground(1, 1, 1)
        self.ren.ResetCamera()
class QSliceViewWidget(QWidget):
    """
    sagittal
    coronal
    transverse
    """
    def __init__(self, orientation='transverse', parent=None):
        super(QSliceViewWidget, self).__init__(parent)
        # set up vtk pipeline and create vtkWidget
        colors = vtk.vtkNamedColors()
        self.orientation = orientation
        self.viewer = vtk.vtkImageViewer2()
        self.orientations = {'coronal': 0, 'sagittal': 1, 'transverse': 2}
        self.viewer.SetSliceOrientation(self.orientations[self.orientation])
        # get&set the camera
        self.camera = self.viewer.GetRenderer().GetActiveCamera()
        ras = [[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0]]
        self.camera.SetPosition(ras[self.orientations[self.orientation]])
        self.camera.ParallelProjectionOn()
        self.iren = vtk.vtkGenericRenderWindowInteractor()
        self.iren.SetRenderWindow(self.viewer.GetRenderWindow())
        kw = {'rw': self.viewer.GetRenderWindow(), 'iren': self.iren}
        self.vtkWidget = QVTKRenderWindowInteractor(parent, **kw)

        # create QSlider
        self.sliderWidget = QSlider(Qt.Horizontal)
        # create the MainLayout of the whole widget
        self.MainLayout = QVBoxLayout()
        self.MainLayout.addWidget(self.sliderWidget)
        self.MainLayout.addWidget(self.vtkWidget)
        self.setLayout(self.MainLayout)
        # set the signal and slot
        self.sliderWidget.valueChanged.connect(self.slider_changed)

    def set_data_reader(self, reader, use_port=False):
        self.viewer.SetInputData(reader.GetOutput())
        matrix = reader.GetSFormMatrix()
        self.viewer.GetImageActor().PokeMatrix(matrix)

    def slider_offset(self, offset):
        self.sliderWidget.setMaximum(self.viewer.GetSliceMax())
        self.sliderWidget.setMinimum(self.viewer.GetSliceMin())
        mid = (self.viewer.GetSliceMax() - self.viewer.GetSliceMin()) / 2
        self.sliderWidget.setValue(mid)

    def start_render(self):
        # initiate slider
        self._init_slider()

        # set InteractorStyle
        interactor_style = vtk.vtkInteractorStyleImage()
        self.vtkWidget.SetInteractorStyle(interactor_style)

        # start render and interactor
        self.vtkWidget.Initialize()
        self.vtkWidget.Start()
        # set camera
        self.viewer.GetRenderer().ResetCamera()

    def _init_slider(self):
        self.sliderWidget.setMaximum(self.viewer.GetSliceMax())
        self.sliderWidget.setMinimum(self.viewer.GetSliceMin())
        mid = (self.viewer.GetSliceMax() - self.viewer.GetSliceMin()) / 2
        self.sliderWidget.setValue(mid)

    # signal and slot
    def slider_changed(self):
        self.viewer.SetSlice(self.sliderWidget.value())