首页 > 解决方案 > QVTKOpenGLWidget 不响应信号,而同一 .ui 中的其他小部件会响应它

问题描述

我正在尝试在 QVTKOpenGLWidget 中绘制一个圆柱体。我使用 Qt Creator,qt 版本 5.12.0 (msvc2017_64)。QVTKOpenGLWidget 是从 QWidget 升级而来的,我在 VTK 包含文件夹中使用 QVTKOpenGLWidget.h。

当我像大多数可用示例一样在构造函数中创建圆柱体、渲染器、vtkGenericOpenGLRenderWindow 等时,没有任何问题,圆柱体显示在 QVTKOpenGLWidget 中。代码如下:

mainui::mainui(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainui)
{
    ui->setupUi(this);

    auto cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
    cylinderSource->SetCenter(0, 0, 0);
    cylinderSource->SetRadius(5.0);
    cylinderSource->SetHeight(7.0);
    cylinderSource->SetResolution(100);

    auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(cylinderSource->GetOutputPort());

    auto actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    auto renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);

    auto win = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
    win->AddRenderer(renderer);
    ui->display3d->SetRenderWindow(win);
}

在这种情况下,结果如下: 在此处输入图像描述

但是,当我添加一个带有函数“triggered()”作为信号的动作,在函数中添加与 VTK 相关的代码并将该函数添加为插槽函数并连接它们时,QVTKOpenGLWidget 似乎不起作用(全黑,没有圆柱体) . 但其他小部件似乎运行良好。代码如下:

void mainui::paint() {
    ui->textEdit->append("Hello vtk!");

    auto cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
    cylinderSource->SetCenter(0, 0, 0);
    cylinderSource->SetRadius(5.0);
    cylinderSource->SetHeight(7.0);
    cylinderSource->SetResolution(100);

    auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(cylinderSource->GetOutputPort());

    auto actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    auto renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);

    auto win = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
    win->AddRenderer(renderer);
    ui->display3d->SetRenderWindow(win);

    ui->textEdit->append("textEdit respond to trigger signal");
}

构造函数:

mainui::mainui(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainui)
{
    ui->setupUi(this);
}

连接器: 在此处输入图像描述

并运行结果: 在此处输入图像描述

标签: c++qtopenglvtk

解决方案


我注意到当您与 交互时会绘制您的圆柱体QVTKOpenGLWidgetaction_open触发后,您移动 3D 显示并且圆柱体将出现)。这是因为QVTKOpenGLWidget在您创建渲染器、窗口等时不会更新。因此,您需要ui->display3d->update();在退出void mainui::paint()功能之前添加以强制更新display3d小部件:

void mainui::paint()
{
  ui->textEdit->append("Nope");

  auto cylinderSource = vtkSmartPointer<vtkCylinderSource>::New();
  cylinderSource->SetCenter(0, 0, 0);
  cylinderSource->SetRadius(5.0);
  cylinderSource->SetHeight(7.0);
  cylinderSource->SetResolution(100);

  auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(cylinderSource->GetOutputPort());

  auto actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

  auto renderer = vtkSmartPointer<vtkRenderer>::New();
  renderer->AddActor(actor);

  auto win = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
  win->AddRenderer(renderer);

  ui->display3d->SetRenderWindow(win);
  ui->display3d->update();//This is the new line
}

QWidget::update()在构造函数中创建圆柱体时不需要手动调用,因为小部件是在构造函数之后绘制的。

在这里你可以看到它的工作:

在此处输入图像描述

注意:我在 pcl 教程中学到了这一点:使用 cmake 在 Qt 中创建 PCL 可视化器


推荐阅读