I am new here. Here are my specs: Mac OS X, python 3.7.4, VTK 8.1.2, and PyQt 5.13.1
I am trying to build, in python, and application using PyQT5 where I can run the following example:
https://vtk.org/Wiki/VTK/Examples/Python/Interaction/HighlightAPickedActor
where there is a bunch of spheres in a 3D space where one could pick one sphere turning red.
Here is my code:
import sys
import vtk
try:
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtWidgets import QWidget, QSizePolicy, QPushButton, QVBoxLayout, QFrame
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, pyqtSignal, QTimer, QObject, QSize, QEvent
except ImportError:
raise ImportError("Cannot load either PyQt5")
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
NUMBER_OF_SPHERES = 10
class MouseInteractorHighLightActor(vtk.vtkInteractorStyleTrackballCamera):
def __init__(self,parent=None):
self.AddObserver("LeftButtonPressEvent",self.leftButtonPressEvent)
self.LastPickedActor = None
self.LastPickedProperty = vtk.vtkProperty()
def leftButtonPressEvent(self,obj,event):
clickPos = self.GetInteractor().GetEventPosition()
picker = vtk.vtkPropPicker()
picker.Pick(clickPos[0], clickPos[1], 0, self.GetDefaultRenderer())
# get the new
self.NewPickedActor = picker.GetActor()
# If something was selected
if self.NewPickedActor:
# If we picked something before, reset its property
if self.LastPickedActor:
self.LastPickedActor.GetProperty().DeepCopy(self.LastPickedProperty)
# Save the property of the picked actor so that we can
# restore it next time
self.LastPickedProperty.DeepCopy(self.NewPickedActor.GetProperty())
# Highlight the picked actor by changing its properties
self.NewPickedActor.GetProperty().SetColor(1.0, 0.0, 0.0)
self.NewPickedActor.GetProperty().SetDiffuse(1.0)
self.NewPickedActor.GetProperty().SetSpecular(0.0)
# save the last picked actor
self.LastPickedActor = self.NewPickedActor
self.OnLeftButtonDown()
return
class Menu(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
exitAct = QAction(QIcon('exit.png'), ' &Quit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(qApp.quit)
self.statusBar()
menubar = self.menuBar()
menubar.setNativeMenuBar(False)
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAct)
bar = self.menuBar()
file = bar.addMenu("Edit")
file.addAction("New")
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Simple menu')
self.show()
self.frame = QFrame()
self.vl = QVBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.vl.addWidget(self.vtkWidget)
self.renderer = vtk.vtkRenderer()
self.renderer.SetBackground(.3, .4, .5 )
self.renwin = vtk.vtkRenderWindow()
self.renwin.AddRenderer(self.renderer)
# An interactor
self.inter = vtk.vtkRenderWindowInteractor()
self.inter.SetRenderWindow(self.renwin)
# add the custom style
self.style = MouseInteractorHighLightActor()
self.style.SetDefaultRenderer(self.renderer)
self.vtkWidget.GetRenderWindow().AddRenderer(self.renderer)
#self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.inter.SetInteractorStyle(self.style)
#self.iren.SetInteractorStyle(self.inter)
#self.iren = self.vtkWidget.GetRenderWindow().SetInteractor(self.inter)
# Add spheres to play with
for i in range(NUMBER_OF_SPHERES):
source = vtk.vtkSphereSource()
# random position and radius
x = vtk.vtkMath.Random(-5,5)
y = vtk.vtkMath.Random(-5,5)
z = vtk.vtkMath.Random(-5,5)
radius = vtk.vtkMath.Random(.5, 1.0)
source.SetRadius(radius)
source.SetCenter(x, y, z)
source.SetPhiResolution(11)
source.SetThetaResolution(21)
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(source.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
r = vtk.vtkMath.Random(.4, 1.0)
g = vtk.vtkMath.Random(.4, 1.0)
b = vtk.vtkMath.Random(.4, 1.0)
actor.GetProperty().SetDiffuseColor(r, g, b)
actor.GetProperty().SetDiffuse(.8)
actor.GetProperty().SetSpecular(.5)
actor.GetProperty().SetSpecularColor(1.0,1.0,1.0)
actor.GetProperty().SetSpecularPower(30.0)
#renderer.AddActor(actor)
self.renderer.AddActor(actor)
self.renderer.ResetCamera()
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
self.show()
self.inter.Initialize()
self.inter.Start()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Menu()
sys.exit(app.exec_())
However, though I get my code running, I get two separate windows: the "menu" on one side and the vtk renderer as a different window. I would like to know what I am doing wrong, if you are eager to help me.
Thank you in advance