使用vtkTimerCallback和QVTKRenderWindowInteractor无法正常工作。

3

我遇到了一个与vtk(8.1)和pyqt5(5.10.1)相关的问题。如果我使用"原始" vtk.vtkRenderWindowInteractor() 和vtkCallBackTimer,一切都很好运行。但是如果我使用vtk.qt.QVTKRenderWindowInteractor.QVTKRenderWindowInteractor(),回调函数会连续执行而没有暂停。以下是示例:

import sys
from PyQt5 import QtWidgets
import vtk
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from mainwindow import Ui_MainWindow

class vtkTimerCallback():
    def __init__(self):
        self.timer_count = 0

    def execute(self, obj, event):
        print(self.timer_count)
        self.actor.SetPosition(self.timer_count, self.timer_count, 0)
        iren = obj
        iren.GetRenderWindow().Render()
        self.timer_count += 1

class ExampleApp(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super (ExampleApp, self).__init__(parent)
        self.setupUi(self)
        sphereSource = vtk.vtkSphereSource()
        sphereSource.SetCenter(0.0, 0.0, 0.0)
        sphereSource.SetRadius(5)
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(sphereSource.GetOutputPort())
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
        renderer = vtk.vtkRenderer()
        renderWindow = vtk.vtkRenderWindow()
        renderWindow.AddRenderer(renderer)
        renderWindowInteractor = vtk.vtkRenderWindowInteractor # <-- WOKRING
        renderWindowInteractor = QVTKRenderWindowInteractor(self.frame) # <-- NOT WORKING (self.frame is a QFrame in the mainwindow.ui)
        renderWindowInteractor.SetRenderWindow(renderWindow)
        renderer.AddActor(actor)
        renderer.SetBackground(1, 1, 1)  # Background color white
        renderWindow.Render()
        renderWindowInteractor.Initialize()
        cb = vtkTimerCallback()
        cb.actor = actor
        renderWindowInteractor.AddObserver('TimerEvent', cb.execute)
        #****************
        renderWindowInteractor.CreateRepeatingTimer(1000) #Pause between new function call in millisecs,
        # with the QVTKRenderWindowInteractor the pause is ignored ?????
        #****************
        renderWindowInteractor.Start()

def main():
    app = QtWidgets.QApplication(sys.argv)
    trudeUI = ExampleApp()
    trudeUI.show()
    app.exec_()

if __name__ =='__main__':
    main()

我希望有人能够帮忙。我需要一个RepeatingTimer来进行动画处理。如果有其他的替代方案也可以,但请不要使用QtCore.QTimer。应该是vtk相关的东西... 我已经尝试了4个小时,欢迎任何帮助...

1个回答

1

我遇到了同样的问题。经过深入调查,发现这是由于 QVTKRenderWindowInteractor 类中的一个 bug 导致的。 在创建重复定时器时,持续时间参数(在你的示例中为1000)没有被考虑进去,而是使用了默认参数(10)。

因此,为了解决这个问题,我创建了一个子类 MyQVTKRenderWindowInteractor 并覆盖了我需要的方法:

class MyQVTKRenderWindowInteractor(QVTKRenderWindowInteractor):
   def __init__(self, *arg):
       super(MyQVTKRenderWindowInteractor, self).__init__(*arg)
       self._TimerDuration = 10 # default value

   def CreateTimer(self, obj, event):
       self._Timer.start(self._TimerDuration) # self._Timer.start(10) in orginal

   def CreateRepeatingTimer(self, duration):
       self._TimerDuration = duration
       super(MyQVTKRenderWindowInteractor, self).GetRenderWindow().GetInteractor().CreateRepeatingTimer(duration)
       self._TimeDuration = 10

现在,renderWindowInteractor = MyQVTKRenderWindowInteractor(self.frame) 应该可以工作了。
希望答案没有来得太晚 ++

你是否也观察到,如果在渲染窗口内单击,计时器会停止?(另请参见此帖子)。 - normanius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接