问题描述
我正在尝试使用 QVTKRenderWindowInteractor 将vtk渲染代码嵌入PyQt5中。当我尝试在其中使用vtkBoxWidget时,程序崩溃了。没有vtkBoxWidget(在下面的代码中包含在两行中),它的工作正常。您能帮我找到问题吗?我试图在vtkBoxWidget的帮助下使用边界框手动裁剪渲染的对象。
代码:
from PyQt5.QtWidgets import QApplication,QWidget,QMainWindow,qframe,QVBoxLayout
import sys
import vtk
from PyQt5 import QtGui
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
class MainWindow(QMainWindow):
def __init__(self,parent=None):
QMainWindow.__init__(self,parent)
self.frame = qframe()
self.vl = QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.vl.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer()
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.iren.SetInteractorStyle(vtk.vtkInteractorStyletrackballCamera())
# Create source
source = vtk.vtkSphereSource()
source.SetCenter(0,0)
source.SeTradius(5.0)
# Create a mapper
mapper = vtk.vtkpolyDataMapper()
mapper.SetInputConnection(source.GetoutputPort())
# Create an actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
###################################################################################
BoxWidget = vtk.vtkBoxWidget()
BoxWidget.SetInteractor(self.iren)
BoxWidget.SetPlaceFactor(1.0)
BoxWidget.SetRotationEnabled(0)
planes = vtk.vtkPlanes()
def ClipVolumeRender(obj,event):
obj.GetPlanes(planes)
mapper.SetClippingPlanes(planes)
BoxWidget.SetProp3D(actor)
BoxWidget.PlaceWidget()
BoxWidget.InsideOutOn()
BoxWidget.Addobserver("InteractionEvent",ClipVolumeRender)
BoxWidget.On()
###################################################################################
self.ren.AddActor(actor)
self.ren.ResetCamera()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
self.iren.Initialize()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
解决方法
问题在于boxWidget是被python消除的局部变量,因此此后应用程序尝试访问该对象,但它不再分配产生 Segmentation fault 的内存。解决方案是通过将boxWidget
更改为self.boxWidget
来扩展范围。