VTK и PyQt5: как обновить отображение после изменения значения радиуса с помощью ползунка - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь написать код Python с VTK и PyQt5, которые отображают сферу VTK, настраиваемую пользователем с помощью ползунков.Концепция окон и виджетов в порядке, проблема в том, что когда я изменяю значение радиуса сферы с помощью ползунков, окна рендеринга нуждаются в щелчке, чтобы обновить вид.Мне бы хотелось, чтобы сцена автоматически обновлялась при перемещении слайдера.Я пробовал некоторые методы, такие как .reinitialize (), .Update (), .CameraReset (), но либо он не существует, либо он работает неправильно

Вот код:

    import sys
from PyQt5.QtWidgets import QApplication, QWidget, QSlider, QLCDNumber
from PyQt5.QtWidgets import (QApplication, QCheckBox, QGridLayout, QGroupBox,
                             QMenu, QPushButton, QRadioButton, QVBoxLayout, QWidget, QSlider,QLineEdit,QLabel)
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import *
import vtk
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt5 import Qt

def window():

   source = vtk.vtkSphereSource()
   source.SetCenter(0, 0, 0)
   source.SetRadius(5.0)

   app = QApplication(sys.argv)
   win = QWidget()

   Display_1 = QLCDNumber(3)
   Display_2 = QLCDNumber(3)
   Display_3 = QLCDNumber(3)

   Display_1.setSegmentStyle(QLCDNumber.Flat)
   Display_2.setSegmentStyle(QLCDNumber.Flat)
   Display_3.setSegmentStyle(QLCDNumber.Flat)

   Display_1.display(128)
   Display_2.display(128)
   Display_3.display(128)

   Slider_1 = QSlider(QtCore.Qt.Horizontal)
   Slider_1.setMinimum(0)
   Slider_1.setMaximum(255)
   Slider_1.setValue(128)
   Slider_1.valueChanged.connect(Display_1.display)
   Slider_1.valueChanged.connect(source.SetRadius)
   source.Update()
   source.Modified()




   Slider_2 = QSlider(QtCore.Qt.Horizontal)
   Slider_2.setMinimum(0)
   Slider_2.setMaximum(255)
   Slider_2.setValue(128)
   Slider_2.valueChanged.connect(Display_2.display)


   Slider_3 = QSlider(QtCore.Qt.Horizontal)
   Slider_3.setMinimum(0)
   Slider_3.setMaximum(255)
   Slider_3.setValue(128)
   Slider_3.valueChanged.connect(Display_3.display)

   label_1 = QLabel("Label_1")
   label_1.setAlignment(QtCore.Qt.AlignCenter)

   label_2 = QLabel("Label_2")
   label_2.setAlignment(QtCore.Qt.AlignCenter)

   label_3 = QLabel("Label_3")
   label_3.setAlignment(QtCore.Qt.AlignCenter)  

   vbox = QtWidgets.QVBoxLayout()


   vbox.addWidget(label_1)
   vbox.addWidget(Display_1)
   vbox.addWidget(Slider_1)

   vbox.addWidget(label_2)
   vbox.addWidget(Display_2)
   vbox.addWidget(Slider_2)

   vbox.addWidget(label_3)
   vbox.addWidget(Display_3)
   vbox.addWidget(Slider_3)

   vbox.addStretch()






   hbox = QtWidgets.QHBoxLayout()

   frame = QtWidgets.QFrame()
   frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
   frame.setFrameShape(QtWidgets.QFrame.StyledPanel) # Application de la forme
   frame.setFrameShadow(QtWidgets.QFrame.Raised) # application d'une ombre
   frame.setObjectName("frame") # Appellation du cadre

   #b3 = QtWidgets.QPushButton("Button3")
   #b4 = QtWidgets.QPushButton("Button4")
   hbox.addWidget(frame)
   hbox.addStretch()
   #hbox.addWidget(b4)

   vbox.addStretch()
   hbox.addLayout(vbox)
   win.setLayout(hbox)



   vtkWidget = QVTKRenderWindowInteractor(frame)
   vl = Qt.QVBoxLayout()
   vl.addWidget(vtkWidget)

   ren = vtk.vtkRenderer()
   vtkWidget.GetRenderWindow().AddRenderer(ren)
   iren = vtkWidget.GetRenderWindow().GetInteractor()



  # Create a mapper
   mapper = vtk.vtkPolyDataMapper()
   mapper.SetInputConnection(source.GetOutputPort())
   mapper.Update()

  # Create an actor
   actor = vtk.vtkActor()
   actor.SetMapper(mapper)

   ren.AddActor(actor)
   ren.ResetCamera()
   frame.setLayout(vl)
   #setCentralWidget(self.frame)
   #show()
   iren.Initialize()

   iren.Start()
   iren.Render()

   win.setWindowTitle("PyQt")
   win.resize(743, 430)
   win.show()
   sys.exit(app.exec_())




if __name__ == '__main__':
   window()

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 15 июля 2019

Попробуйте:
1) изменить:

...
from PyQt5 import Qt

def chgdValue(iren):
    iren.GetRenderWindow().Render()

def window():
...

2) изменить:

...
Slider_1.valueChanged.connect(source.SetRadius)
Slider_1.valueChanged.connect(lambda x: chgdValue(iren))
source.Update()
...

.CameraReset () тоже работает, но масштабировать сцену,Вы должны добавить что-то для сравнения.

0 голосов
/ 17 декабря 2018

Я использую повторную инициализацию в окне интерактивного рендера всякий раз, когда я хочу принудительно обновить его после программного (неинтерактивного) изменения.В вашем случае, поскольку ползунок является частью остальной части вашего приложения, а не взаимодействует с самим интерактором окна рендеринга, вам необходимо вызвать reinitialize, чтобы заставить его обновиться.

Вызовите iren.ReInitialize () (обратите внимание на заглавные буквы).Документация для VTKRenderWindowInteractor находится здесь:

https://www.vtk.org/doc/release/7.1/html/classvtkRenderWindowInteractor.html

Этот ответ также появляется в виде комментариев, связанных с вопросом:

pyqt и VTK: проблемаподключить слайдер к объекту vtk

...