2016-06-28 2 views
0

vtkChartParallelCoordinates와 vtkContextView를 Pyqt 응용 프로그램과 병렬로 실행하는 다른 그래프를 구해야합니다. 문제는 둘 다 사용자 마우스 상호 작용을 위해 무한 루프를 사용하며 한 번에 하나만 실행할 수 있다는 것입니다. view.GetInteractor(). Start()에 의해 vtk 인터랙터를 시작할 때 vtk 창을 닫을 때까지 PyQt 애플리케이션이 나타나지 않는다. VTK interactor와 PyQt가 병렬로 실행됩니다.

  • 이 PyQt는 응용 프로그램
  • 내부의 VTK 그래프를 렌더링 수동으로 PyQt는의 루프에서 VTK 개체의 사용자 상호 작용의

    1. 관한주의 사항 : 나는 그것을 수행하는 방법의 두 가지 옵션이 있다고 가정

      두 번째 옵션에 대해 : QVTKRenderWindowInteractor를 사용할 수 없습니다. vtkContextView 그래프에서 작동하지 않는 것 같습니다. Kitware가 작성한 문서를 찾았습니다. http://www.na-mic.org/Wiki/images/1/18/NA-MIC-VTK-Charts-2011.pdf 22 페이지의 QVTKWidget을 사용하지만 vtk의 제 컴파일에는이 문서가 없습니다.

      나는 아무런 성공도하지 않고 옵션 1에 관해 뭔가 해보려고했지만 관련있는 예제는 없다.

      아래의 코드에서 "view.GetInteractor(). Start()"를 주석 처리 할 때 PyQt 창이 나타나 대화 형입니다.

      저는 리눅스에서 python 버전 2.7.11, vtk 버전 7.0.0을 사용하고 있습니다.

      어떤 도움을 주셔서 감사합니다.

      from PyQt4 import QtCore, QtGui 
      import vtk 
      import math 
      
      
      
      
      class Ui_widgetParallel(object): 
          def setupUi(self, widgetParallel): 
           widgetParallel.setObjectName("widgetParallel") 
           widgetParallel.resize(802, 651) 
           #button 
           self.button = QtGui.QPushButton(widgetParallel) 
           self.button.setGeometry(QtCore.QRect(180, 100, 75, 23)) 
           self.button.setText("Click on me") 
      
           QtCore.QMetaObject.connectSlotsByName(widgetParallel) 
           self.button.clicked.connect(self.testClick) 
      
          def testClick(self): 
           print('I was clicked on') 
      
      
      
      
      def selectionCallback(caller, event): 
          #executes when new data is selected by the user 
          #prints row numbers of all selected data rows 
           annSel = annotationLink.GetCurrentSelection() 
           if annSel.GetNumberOfNodes() > 0: 
            idxArr = annSel.GetNode(0).GetSelectionList() 
            if idxArr.GetNumberOfTuples() > 0: 
             for ii in range(idxArr.GetNumberOfTuples()): 
              print(idxArr.GetValue(ii)) 
      
      
      
      
      if __name__ == "__main__": 
          import sys 
      
      
          ############################ 
          # CREATE A DATA TABLE 
          ############################ 
      
          arrX = vtk.vtkFloatArray() 
          arrX.SetName("XAxis") 
      
          arrC = vtk.vtkFloatArray() 
          arrC.SetName("Cosine") 
      
          arrS = vtk.vtkFloatArray() 
          arrS.SetName("Sine") 
      
          arrS2 = vtk.vtkFloatArray() 
          arrS2.SetName("Tan") 
      
          numPoints = 20 
          inc = 0.2/(numPoints-1) 
      
          for i in range(numPoints): 
           arrX.InsertNextValue(i * inc) 
           arrC.InsertNextValue(math.cos(i * inc) + 0.0) 
           arrS.InsertNextValue(math.sin(i * inc) + 0.0) 
           arrS2.InsertNextValue(math.tan(i * inc) + 0.5) 
      
          table = vtk.vtkTable() 
          table.AddColumn(arrX) 
          table.AddColumn(arrC) 
          table.AddColumn(arrS) 
          table.AddColumn(arrS2) 
      
      
          ############################ 
          # STARTS THE QtGui application 
          ############################ 
          app = QtGui.QApplication(sys.argv) 
          widgetParallel = QtGui.QWidget() 
          ui = Ui_widgetParallel() 
          ui.setupUi(widgetParallel) 
          widgetParallel.show() 
      
      
          ############################ 
          # PARALLEL COORDINATES VIEW AND ANNOTATION 
          ############################ 
          #render contextView and parallel coordinates view 
          view = vtk.vtkContextView() 
          view.GetRenderer().SetBackground(1.0, 1.0, 1.0) 
          view.GetRenderWindow().SetSize(600,300) 
          chart = vtk.vtkChartParallelCoordinates() 
          view.GetScene().AddItem(chart) 
          # Create a annotation link to access selection in parallel coordinates view 
          annotationLink = vtk.vtkAnnotationLink() 
          annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1)  # Point 
          annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4) # 1 = GlobalIds, 2 = PedigreeIds, 4 = Indices 
          chart.SetAnnotationLink(annotationLink) 
          annotationLink.AddObserver("AnnotationChangedEvent", selectionCallback) 
      
          #link input data and refresh attributes view 
          chart.GetPlot(0).SetInputData(table) 
          chart.GetPlot(0).SetScalarVisibility(1) 
          chart.GetPlot(0).SetScalarVisibility(1) 
          chart.GetPlot(0).SetWidth(5) 
          chart.GetPlot(0).SetOpacity(0) 
          #render view 
          view.ResetCamera() 
          view.GetRenderWindow().SetMultiSamples(0) 
          view.Render() 
          view.GetInteractor().Start() 
      
          ############################ 
          # EXITS THE APPLICATION WHEN GUI LOOP IS CLOSED 
          ############################ 
          sys.exit(app.exec_()) 
      

    답변

    0

    첫 번째 질문을 완전히 이해했는지 확신 할 수 없습니다. 그러나, 나는 QT 주류 창에서 QVTKRenderWindowInteractor 클래스를 사용하여 vtk 그래프를 표시하기 위해 파이썬 프로토 타입을 첨부합니다. 첫 번째 질문에 관해서는 첨부 된 메서드를 사용하면 pyQt 이벤트를 vtk 이벤트에 쉽게 연결할 수 있다고 생각합니다.

    from PyQt4 import QtCore, QtGui 
    from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor 
    import vtk 
    import math 
    import sys 
    
    
    class test(QtGui.QMainWindow): 
    
        def __init__(self, parent=None): 
         QtGui.QMainWindow.__init__(self, parent) 
         self._initUI() 
    
        def _initUI(self): 
         self.setWindowTitle(self.tr("PyQt4 widgetParallel")) 
         self.workspace = QtGui.QWorkspace() 
         self.setCentralWidget(self.workspace) 
         self.frame1 = QtGui.QFrame(self.workspace) 
         self.hbox1 = QtGui.QHBoxLayout() 
         self.frame2 = QtGui.QFrame(self.workspace) 
    
         self.frame1.resize(600, 600) 
         self.frame2.resize(600, 600) 
         self.frame2.move(QtCore.QPoint(600, 0)) 
    
         self.hbox2 = QtGui.QHBoxLayout() 
    
         self.widgetParallel = Ui_widgetParallel(self.frame2) 
    
         self.widget = QVTKRenderWindowInteractor(self.frame1) 
         self.iren = self.widget.GetRenderWindow().GetInteractor() 
    
         self.arrX = vtk.vtkFloatArray() 
         self.arrX.SetName("XAxis") 
    
         self.arrC = vtk.vtkFloatArray() 
         self.arrC.SetName("Cosine") 
    
         self.arrS = vtk.vtkFloatArray() 
         self.arrS.SetName("Sine") 
    
         self.arrS2 = vtk.vtkFloatArray() 
         self.arrS2.SetName("Tan") 
    
         numPoints = 20 
         inc = 0.2/(numPoints-1) 
    
         for i in range(numPoints): 
          self.arrX.InsertNextValue(i * inc) 
          self.arrC.InsertNextValue(math.cos(i * inc) + 0.0) 
          self.arrS.InsertNextValue(math.sin(i * inc) + 0.0) 
          self.arrS2.InsertNextValue(math.tan(i * inc) + 0.5) 
    
         self.table = vtk.vtkTable() 
         self.table.AddColumn(self.arrX) 
         self.table.AddColumn(self.arrC) 
         self.table.AddColumn(self.arrS) 
         self.table.AddColumn(self.arrS2) 
    
         self.view = vtk.vtkContextView() 
         self.view.SetInteractor(self.iren) 
         self.widget.SetRenderWindow(self.view.GetRenderWindow()) 
    
         self.ren = self.view.GetRenderer() 
         self.ren.SetBackground(1.0, 1.0, 1.0) 
         self.renWin = self.widget.GetRenderWindow() 
    
         self.iren.SetRenderWindow(self.widget.GetRenderWindow()) 
    
         self.chart = vtk.vtkChartParallelCoordinates() 
         self.view.GetScene().AddItem(self.chart) 
         # Create a annotation link to access selection in parallel coordinates 
         # view 
         self.annotationLink = vtk.vtkAnnotationLink() 
         # Point 
         self.annotationLink.GetCurrentSelection().GetNode(0).SetFieldType(1) 
         # 1 = GlobalIds, 2 = PedigreeIds, 4 = Indices 
         self.annotationLink.GetCurrentSelection().GetNode(0).SetContentType(4) 
         self.chart.SetAnnotationLink(self.annotationLink) 
         self.annotationLink.RemoveObservers("AnnotationChangedEvent") 
         self.annotationLink.AddObserver("AnnotationChangedEvent", 
                 self.selectionCallback) 
    
         # link input data and refresh attributes view 
         self.chart.GetPlot(0).SetInputData(self.table) 
         self.chart.GetPlot(0).SetScalarVisibility(1) 
         self.chart.GetPlot(0).SetScalarVisibility(1) 
         self.chart.GetPlot(0).SetWidth(5) 
         self.chart.GetPlot(0).SetOpacity(0) 
    
         self.renWin.AddRenderer(self.ren) 
         self.renWin.SetMultiSamples(0) 
    
         self.hbox1.addWidget(self.widget) 
         self.hbox2.addWidget(self.widgetParallel) 
    
         self.frame1.setLayout(self.hbox1) 
         self.frame2.setLayout(self.hbox2) 
    
         self.workspace.addWindow(self.frame1) 
         self.workspace.addWindow(self.frame2) 
    
         self.widget.show() 
    #  self.widgetParallel.show() 
         self.iren.Initialize() 
    
        def selectionCallback(self, caller, event): 
         # executes when new data is selected by the user 
         # prints row numbers of all selected data rows 
         annSel = self.annotationLink.GetCurrentSelection() 
         if annSel.GetNumberOfNodes() > 0: 
          idxArr = annSel.GetNode(0).GetSelectionList() 
          if idxArr.GetNumberOfTuples() > 0: 
           for ii in range(idxArr.GetNumberOfTuples()): 
            print(idxArr.GetValue(ii)) 
    
    
    class Ui_widgetParallel(QtGui.QWidget): 
    
        def __init__(self, parent): 
         super(Ui_widgetParallel, self).__init__(parent) 
         self._setupUi() 
    
        def _setupUi(self): 
         self.setObjectName("widgetParallel") 
         self.resize(802, 651) 
         # button 
         self.button = QtGui.QPushButton(self) 
         self.button.setGeometry(QtCore.QRect(180, 100, 75, 23)) 
         self.button.setText("Click on me") 
    
         layout = QtGui.QHBoxLayout() 
         layout.addWidget(self.button) 
    
         self.setLayout(layout) 
    
    #  QtCore.QMetaObject.connectSlotsByName(self) 
         self.button.clicked.connect(self.testClick) 
    
         self.show() 
    
        def testClick(self): 
         print('I was clicked on') 
    
    
    if __name__ == "__main__": 
        app = QtGui.QApplication(sys.argv) 
        mainwindow = test() 
        mainwindow.show() 
        sys.exit(app.exec_()) 
    

    p.s. QWidgets 대신에 QDockWidgets을 사용할 수도 있습니다.

    +0

    그게 바로 내가 뭘 찾고 있었는지, 많이 고마워! – Kubik