我正在尝试将VTK
回调连接到Qt
插槽,因此当回调发生时将触发该插槽。
我正在使用 aQVTKWidget
来渲染已添加到 aPCLVisualizer
中的点云(来自点云库,PCL)。
让我们展示一些代码:
点云.h
class PointCloud: public QObject {
Q_OBJECT
private:
static void loadStartCallback(
vtkObject *caller,
unsigned long eventId,
void *clientData,
void *callData
);
static void loadEndCallback(
vtkObject *caller,
unsigned long eventId,
void *clientData,
void *callData
);
void load(void);
// more funcs and methods
private:
QVTKWidget* widget;
pcl::visualization::PCLVisualizer* visualizer;
unsinged long observerStartTag;
unsinged long observerEndTag;
// more attributes
}
点云.cpp
void PointCloud::loadStartCallback(
vtkObject* caller,
unsigned long eventId,
void* clientData,
void* callData
) {
qDebug() << "\t\tPointCloud - loadCallback started\n";
if(clientData) {
PointCloud* self = reinterpret_cast<PointCloud*>( clientData );
self->widget->GetRenderWindow()->RemoveObserver(self->observerStartTag);
}
void PointCloud::loadEndCallback(
vtkObject* caller,
unsigned long eventId,
void* clientData,
void* callData
) {
qDebug() << "\t\tPointCloud - loadCallback ended\n";
if(clientData) {
PointCloud* self = reinterpret_cast<PointCloud*>( clientData );
self->widget->GetRenderWindow()->RemoveObserver(self->observerEndTag);
}
}
void load(void) {
vtkSmartPointer<vtkRenderWindow> renderWindow = visualizer->getRenderWindow();
vtkSmartPointer<vtkCallbackCommand> startCallback = vtkSmartPointer<vtkCallbackCommand>::New();
startCallback->SetCallback( loadStartCallback );
startCallback->SetClientData(this);
observerStartTag = renderWindow->AddObserver(vtkCommand::StartEvent, startCallback );
vtkSmartPointer<vtkCallbackCommand> endCallback = vtkSmartPointer<vtkCallbackCommand>::New();
endCallback->SetCallback( loadEndCallback );
endCallback->SetClientData(this);
observerEndTag = renderWindow->AddObserver(vtkCommand::EndEvent, endCallback );
// more processing. local_cloud is already populated
// and functional at this point
widget->SetRenderWindow( renderWindow );
visualizer->addPointCloud<pcl::PointXYZ>(local_cloud, "local_cloud");
widget->Show();
widget->Update();
}
这很好用,一旦云渲染开始,将打印PointCloud - loadCallback started,当渲染结束并显示云时,将打印消息PointCloud - loadCallback end。
现在,除了打印结束消息之外,我还想触发一个Qt
插槽。我正在尝试为此使用vtkEventQtSlotConnect
该类,因为这似乎是将回调连接到插槽的正确选择:
PointCloud.h 中的新功能
private slots:
void test(void);
PointCloud.cpp 中的新功能
void PointCloud::test(void) { qDebug() << "\t\tThis is a test\n; }
在调用 Visualizer->addPointCloud 之前添加到 PointCloud::load()
vtkEventQtSlotConnect* vtk_qt_connector = vtkEventQtSlotConnect::New();
vtk_qt_connector->Connect(
renderWindow,
vtkCommand::EndEvent,
this,
SLOT(test(void)),
0,
1.0
);
// AFTER widget->Update()
vtk_qt_connector->Disconnect(); // NO PARAM: disconnects ALL slots
vtk_qt_connector->Delete();
} // End of PointCloud::load()
通过这些添加,回调中的消息被打印,但test()
插槽内的消息永远不会显示。
知道我做错了什么吗?
编辑
在VTK
我见过的回调示例中,avtkRendeWindowInteractor
用于管理回调。但是,如果我向其中添加回调观察者,则不如直接将它们添加到渲染窗口准确。