VTK
コールバックをスロットに接続しようとしているQt
ので、コールバックが発生したときにスロットが起動されます。
(ポイントクラウドライブラリ、PCLから)QVTKWidget
に追加されたポイントクラウドをレンダリングするためにを使用しています。PCLVisualizer
いくつかのコードを示しましょう:
PointCloud.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
}
PointCloud.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 startが出力され、レンダリングが終了してクラウドが表示されると、メッセージPointCloud--loadCallbackendedが出力されます。
さて、終了メッセージを印刷するだけでなく、Qt
スロットも発射したいと思います。vtkEventQtSlotConnect
コールバックをスロットに接続するための正しい選択であると思われるので、私はそのためにクラスを使用しようとしています。
PointCloud.hの新機能
private slots:
void test(void);
PointCloud.cppの新機能
void PointCloud::test(void) { qDebug() << "\t\tThis is a test\n; }
ビジュアライザー->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
私が見たコールバックの例でvtkRendeWindowInteractor
は、コールバックを管理するためにaが使用されています。ただし、コールバックオブザーバーを追加すると、レンダリングウィンドウに直接追加するほど正確ではありません。