vtk监听事件的几种方法

自定义交互样式

class MyInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
    static MyInteractorStyle* New();;
    vtkTypeMacro(MyInteractorStyle, vtkInteractorStyleTrackballCamera);

    // 重写鼠标左键按下事件
    void OnLeftButtonDown() override
    {
        int* pos = this->GetInteractor()->GetEventPosition();
        std::cout << "Left Button Pressed at (" << pos[0] << ", " << pos[1] << ")" << std::endl;

        // 保留原来的交互行为
        vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
    }

    // 你可以重写更多事件,如右键、滚轮、鼠标移动等:
    void OnRightButtonDown() override
    {
        std::cout << "Right button clicked!" << std::endl;
        vtkInteractorStyleTrackballCamera::OnRightButtonDown();
    }

    void OnMouseMove() override
    {
        //std::cout << "Mouse moved!" << std::endl;
        vtkInteractorStyleTrackballCamera::OnMouseMove();
    }
};
  vtkSmartPointer<MyInteractorStyle> style = vtkSmartPointer<MyInteractorStyle>::New();
  m_resliceViewers[i]->GetInteractor()->SetInteractorStyle(style);

自定义监听事件

class CameraRotateXZCallback : public vtkCommand {
public:
    static CameraRotateXZCallback* New() {
        return new CameraRotateXZCallback;
    }
    void Execute(vtkObject* caller, unsigned long eventId, void*) override {
        if (eventId != vtkCommand::TimerEvent) return;

        angle_ += deltaAngle_;

        double newX = center_[0] + radius_ * std::cos(angle_);
        double newZ = center_[2] + radius_ * std::sin(angle_);
        double newY = initPos_[1]; // y 不变

        vtkCamera* cam = renderer_->GetActiveCamera();
        cam->SetPosition(newX, newY, newZ);
        cam->SetFocalPoint(center_);
        cam->SetViewUp(0.0, 1.0, 0.0); // Y 轴向上(因为旋转平面是 XZ)
        renderer_->ResetCameraClippingRange();

        if (renderer_->GetRenderWindow()) {
            renderer_->GetRenderWindow()->Render();
        }
    }

    void Initialize(vtkRenderer* ren, const double center[3], const double initPos[3], double deltaAngle) {
        renderer_ = ren;
        center_[0] = center[0]; center_[1] = center[1]; center_[2] = center[2];
        initPos_[0] = initPos[0]; initPos_[1] = initPos[1]; initPos_[2] = initPos[2];

        double dx = initPos_[0] - center_[0];
        double dz = initPos_[2] - center_[2];
        radius_ = std::sqrt(dx*dx + dz*dz);
        angle_ = std::atan2(dz, dx); // 注意是 (z, x)
        deltaAngle_ = deltaAngle;
    }

private:
    vtkRenderer* renderer_ = nullptr;
    double center_[3];
    double initPos_[3];
    double radius_ = 1.0;
    double angle_ = 0.0;
    double deltaAngle_ = 0.01;
};
    auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    // 注册定时器
    interactor->AddObserver(vtkCommand::TimerEvent, cb);
    int timerId = interactor->CreateRepeatingTimer(16); // ~60fps -> 16 ms

快捷设置回调函数

  vtkSmartPointer<vtkCallbackCommand> leftClickCallback = vtkSmartPointer<vtkCallbackCommand>::New();
  // 可以使用lambda表达式也可以使用static 函数
  leftClickCallback->SetCallback([](vtkObject* caller, long unsigned int eventId, void* clientData, void* callData) {
      auto interactor = static_cast<vtkRenderWindowInteractor*>(caller);
      int* pos = interactor->GetEventPosition();
      std::cout << "Left click at (" << pos[0] << ", " << pos[1] << ")" << std::endl;
      // 防止后续处理被阻断
      // 停止事件传播(如不想让默认交互样式再处理)
      reinterpret_cast<vtkCommand*>(callData)->SetAbortFlag(1);
  });

  m_resliceViewers[i]->GetInteractor()->AddObserver(vtkCommand::LeftButtonPressEvent, leftClickCallback, 1.0);
Table of Contents