在VTK中显示二维图片时,若在程序中使用vtkBorderWidget,交互方式采用vtkInteractorStyleImage,则会出现窗宽窗位的调节功能丢失,但是其他交互功能并未失去的问题。

    以下采用vtkImageViewer2显示图像,并在RenderWindow中建立两层Renderer,代码如下:

 
  
  1. vtkImageViewer2* viewer = vtkImageViewer2::New(); 
  2.     viewer->SetInputConnection(reader->GetOutputPort()); 
  3.  
  4.     vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New(); 
  5.     viewer->SetupInteractor(iren); 
  6.     viewer->GetRenderWindow()->SetNumberOfLayers(2); 
  7.     viewer->GetRenderer()->SetLayer(0); 
  8.     viewer->GetRenderer()->InteractiveOff(); 
  9.  
  10.     vtkImageActor* actor = vtkImageActor::New(); 
  11.     actor->GetMapper()->SetInputConnection(reader->GetOutputPort()); 
  12.     vtkRenderer* renderer = vtkRenderer::New(); 
  13.     renderer->SetLayer(1); 
  14.     renderer->InteractiveOn(); 
  15.     renderer->AddActor(actor); 
  16.  
  17.     viewer->GetRenderWindow()->AddRenderer(renderer); 
  18.  
  19.     vtkInteractorStyleImage* style = vtkInteractorStyleImage::New(); 
  20.     iren->SetInteractorStyle(style); 
  21.  
  22.     vtkBorderWidget* borderWidget = vtkBorderWidget::New(); 
  23.     borderWidget->SetInteractor(iren); 
  24.     static_cast<vtkBorderRepresentation*>(borderWidget->GetRepresentation())->GetBorderProperty()->SetColor(0,1,0); 
  25.     borderWidget->SelectableOff(); 
  26.     borderWidget->On(); 

    程序运行结果如下:

           调试程序发现,必须将borderWidget->On()置于viewer->GetRenderWindow()->AddRenderer(renderer)之前,才能恢复窗宽窗位的调节能力,具体原因尚不清楚。由此可见,在使用其他由vtkAbstractWidget继承而来的窗口类也必须实行上述操作,才能正确的显示图像。

     代码如下:

 
  
  1. vtkImageViewer2* viewer = vtkImageViewer2::New(); 
  2.     viewer->SetInputConnection(reader->GetOutputPort()); 
  3.  
  4.     vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New(); 
  5.     viewer->SetupInteractor(iren); 
  6.     viewer->GetRenderWindow()->SetNumberOfLayers(2); 
  7.     viewer->GetRenderer()->SetLayer(0); 
  8.     viewer->GetRenderer()->InteractiveOff(); 
  9.      
  10.     vtkBorderWidget* borderWidget = vtkBorderWidget::New(); 
  11.     borderWidget->SetInteractor(iren); 
  12.     static_cast<vtkBorderRepresentation*>(borderWidget->GetRepresentation())->GetBorderProperty()->SetColor(0,1,0); 
  13.     borderWidget->SelectableOff(); 
  14.     borderWidget->On(); 
  15.  
  16.     vtkImageActor* actor = vtkImageActor::New(); 
  17.     actor->GetMapper()->SetInputConnection(reader->GetOutputPort()); 
  18.     vtkRenderer* renderer = vtkRenderer::New(); 
  19.     renderer->SetLayer(1); 
  20.     renderer->InteractiveOn(); 
  21.     renderer->AddActor(actor); 
  22.  
  23.     viewer->GetRenderWindow()->AddRenderer(renderer);//此行代码必须放在这里,不能放在borderWidget->On()之前,否者renderer将失去调窗能力 
  24.  
  25.     vtkInteractorStyleImage* style = vtkInteractorStyleImage::New(); 
  26.     iren->SetInteractorStyle(style); 

   程序运行截图:

 

    到此,窗宽窗位能正确调节,但是出现了另一个问题,也就是border置于renderer之下,由viewer、border、renderer的添加顺序可以发现:在第一种情况下,三者添加的顺序是viewer的renderer置于第0层,renderer置于第二层,再添加border,此时失去调窗能力;而第二种情况则是:viewer的renderer置于第0层,添加border,再添加renderer。由此笔者猜测,在第一种情况下border覆盖了renderer使其失去调窗能力,但是此时border位于renderer之上;而在第二种情况下,renderer覆盖了border,使border在renderer下面,但是renderer获得了调窗功能。