problem with 'FourPaneViewer' example by pyqt+vtk

I need to slice the volume in any direction, so I replicated FourPaneViewer project where on vtk examples directions in Python in my project. But when I ran it, the scan didn’t show up and the program exited with error code code -1073740791 (0xC0000409).

Here is my code as show below about how I replicated the example. And vtk_data is my data ,vtkWidget2D_YZ is created by QVTKRenderWindowInteractor function.

class vtkResliceCursorCallback(vtk.vtkCommand):
    def __init__(self):
        self.IPW[3] = [vtk.vtkImagePlaneWidget(), vtk.vtkImagePlaneWidget(), vtk.vtkImagePlaneWidget()]
        self.RCW[3] = [vtk.vtkResliceCursorWidget, vtk.vtkResliceCursorWidget, vtk.vtkResliceCursorWidget]

    # def vtkResliceCursorCallback(self):
    #     return vtkResliceCursorCallback()

    def Execute(self, caller, ev, callData):
        if ev == vtk.vtkResliceCursorWidget.WindowLevelEvent or ev == vtk.vtkCommand.WindowLevelEvent or ev == vtk.vtkResliceCursorWidget.ResliceThicknessChangedEvent:
          #Render everything
            for i in range(3):
                self.RCW[i].Render()
            self.IPW[0].GetInteractor().GetRenderWindow().Render()
            return

        ipw = vtk.vtkImagePlaneWidget(caller)
        if ipw:
            wl = callData
            if ipw == self.IPW[0]:
                self.IPW[1].SetWindowLevel(wl[0], wl[1], 1)
                self.IPW[2].SetWindowLevel(wl[0], wl[1], 1)
            elif ipw == self.IPW[1]:
                self.IPW[0].SetWindowLevel(wl[0], wl[1], 1)
                self.IPW[2].SetWindowLevel(wl[0], wl[1], 1)

            elif ipw == self.IPW[2]:
                self.IPW[0].SetWindowLevel(wl[0], wl[1], 1)
                self.IPW[1].SetWindowLevel(wl[0], wl[1], 1)

        rcw = vtk.vtkResliceCursorWidget(caller)
        if rcw:
            rep = vtk.vtkResliceCursorLineRepresentation(rcw.GetRepresentation())
            #Although the return value is not used, we keep the get calls
            #in case they had side-effects
            rep.GetResliceCursorActor().GetCursorAlgorithm().GetResliceCursor()
            for i in range(3):
                ps = vtk.vtkPlaneSource(self.IPW[i].GetPolyDataAlgorithm())
                ps.SetOrigin(self.RCW[i].GetResliceCursorRepresentation().GetPlaneSource().GetOrigin())
                ps.SetPoint1(self.RCW[i].GetResliceCursorRepresentation().GetPlaneSource().GetPoint1())
                ps.SetPoint2(self.RCW[i].GetResliceCursorRepresentation().GetPlaneSource().GetPoint2())

            #If the reslice plane has modified, update it on the 3D widget
            self.IPW[i].UpdatePlacement()

        #Render everything
        for i in range(3):
            self.RCW[i].Render()

        self.IPW[0].GetInteractor().GetRenderWindow().Render()

    def show2D(self, vtk_data, level1, level2):
        for i in range(3):
            self.riw[i] = vtk.vtkResliceImageViewer()
            renderWindow = vtk.vtkGenericOpenGLRenderWindow()
            self.riw[i].SetRenderWindow(renderWindow)

        self.vtkWidget2D_YZ.SetRenderWindow(self.riw[0].GetRenderWindow())
        self.riw[0].SetupInteractor(self.vtkWidget2D_YZ.renderWindow().GetInteractor())

        self.vtkWidget2D_XZ.SetRenderWindow(self.riw[1].GetRenderWindow())
        self.riw[1].SetupInteractor(self.vtkWidget2D_XZ.renderWindow().GetInteractor())

        self.vtkWidget2D_XY.SetRenderWindow(self.riw[2].GetRenderWindow())
        self.riw[2].SetupInteractor(self.vtkWidget2D_XY.renderWindow().GetInteractor())

        dimension = vtk_data.GetDimensions()
        for i in range(3):
            # make them all share the same reslice cursor object.
            rep = vtk.vtkResliceCursorLineRepresentation.SafeDownCast(self.riw[i].GetResliceCursorWidget().GetRepresentation())
            self.riw[i].SetResliceCursor(self.riw[i].GetResliceCursor())
            rep.GetResliceCursorActor().GetCursorAlgorithm().SetReslicePlaneNormal(i)

            self.riw[i].SetInputData(vtk_data)
            self.riw[i].SetSliceOrientation(i)
            print(1)
            self.riw[i].SetResliceModeToAxisAligned()

        picker = vtk.vtkCellPicker()
        picker.SetTolerance(0.005)

        ipwProp = vtk.vtkProperty()
        ren = vtk.vtkRenderer()
        # renderWindow = vtk.vtkGenericOpenGLRenderWindow()
        # self.vtkWidget3D.setRenderWindow(renderWindow)
        # self.vtkWidget3D.renderWindow().AddRenderer(ren)
        # vtkRenderWindowInteractor * iren = this->ui->view4->interactor();

        iren = self.vtkWidget2D_YZ.GetRenderWindow().GetInteractor()

        for i in range(3):
            self.planeWidget[i] = vtk.vtkImagePlaneWidget()
            self.planeWidget[i].SetInteractor(iren)
            self.planeWidget[i].SetPicker(picker)
            self.planeWidget[i].RestrictPlaneToVolumeOn()
            color = [0, 0, 0]
            color[i] = 1
            self.planeWidget[i].GetPlaneProperty().SetColor(color)

            self.riw[i].GetRenderer().SetBackground(color)

            self.planeWidget[i].SetTexturePlaneProperty(ipwProp)
            self.planeWidget[i].TextureInterpolateOff()
            self.planeWidget[i].SetResliceInterpolateToLinear()
            self.planeWidget[i].SetInput(vtk_data)
            self.planeWidget[i].SetPlaneOrientation(i)
            self.planeWidget[i].SetSliceIndex(dimension[i] // 2)
            self.planeWidget[i].DisplayTextOn()
            self.planeWidget[i].SetDefaultRenderer(ren)
            self.planeWidget[i].SetWindowLevel(1358, -27)
            self.planeWidget[i].On()
            self.planeWidget[i].InteractionOn()

        cbk = vtkResliceCursorCallback()

        for i in range(3):
            cbk.IPW[i] = self.planeWidget[i]
            cbk.RCW[i] = self.riw[i].GetResliceCursorWidget()       
            self.riw[i].GetResliceCursorWidget().AddObserver(vtk.vtkResliceCursorWidget.
ResliceAxesChangedEvent, cbk)
            self.riw[i].GetResliceCursorWidget().AddObserver(vtk.vtkResliceCursorWidget.
WindowLevelEvent, cbk)
            self.riw[i].GetResliceCursorWidget().AddObserver(vtk.vtkResliceCursorWidget.
ResliceThicknessChangedEvent, cbk)
            self.riw[i].GetResliceCursorWidget().AddObserver(vtk.vtkResliceCursorWidget.
ResetCursorEvent, cbk)
            self.riw[i].GetInteractorStyle().AddObserver(vtk.vtkCommand.WindowLevelEvent, cbk)
            self.riw[i].AddObserver(vtk.vtkResliceImageViewer.SliceChangedEvent, cbk)

            #Make them all share the same color map.
            self.riw[i].SetLookupTable(self.riw[0].GetLookupTable())
            self.planeWidget[i].GetColorMap().SetLookupTable(self.riw[0].GetLookupTable())
            self.planeWidget[i].SetColorMap(self.riw[i].GetResliceCursorWidget().
GetResliceCursorRepresentation().GetColorMap())
        self.vtkWidget2D_YZ.Show()
        self.vtkWidget2D_XZ.Show()
        self.vtkWidget2D_XY.Show()
        self.vtkWidget2D_YZ.Initialize()
        self.vtkWidget2D_XZ.Initialize()
        self.vtkWidget2D_XY.Initialize()
        self.vtkWidget2D_YZ.Start()
        self.vtkWidget2D_XZ.Start()
        self.vtkWidget2D_XY.Start()

I’m not entirely sure where the problem is, I would greatly appreciate it if you could tell me.

@lassoan Can you help me solve this problem? I have searched a lot of information, but it is all about C++.

The example may be a good starting point for a very, very basic medical image viewer. However, such viewers are no longer acceptable on desktop, because users demand to do simple things in their web browser, on the cloud, without installing anything. They would only install a desktop software for something that offers substantially more features, but it would be a very long way to get there if you start from a simple VTK example.

I would recommend to use VTK example to learn best practices to use certain classes, but use an extensible, open-source medical imaging framework to start your application. For desktop, I would recommend 3D Slicer, for web you can check out Kitware’s VolView.

Thank you for your reply.
But the reason I need this example is that my project requirements happen to overlap with this example. So I want to use this example in my project, but now I can’t find where I went wrong. Do you have any suggestions for modifying my code?This is very necessary for me.

What I described above is the best advice I can give. You can learn a lot from struggling with modifying examples to achieve some small specific goals, but you should also spend time with studying work of experienced developers that already implemented all you need.