2016-09-29 124 views
0

我在主窗口中使用QVtkWidget。我在一个新线程中生成了一个vtkRenderer,当它完成时,我发送一个signal,它连接主窗口的slot以将渲染器发回并更新QVtkWidget。使用VTK和QT多线程时的访问冲突异常

不幸的是,当我将渲染器添加到vtkRenderWindow时,出现“访问冲突”异常。这里是我的代码:

threadobject.h

class ThreadObject : public QObject 
{ 
    Q_OBJECT 

public: 
    ThreadObject(); 
    ~ThreadObject(); 
signals: 
    void startShowPointSignal(QString filepath); 
    void endShowPointSignal(vtkRenderer* render); 

public slots: 
    void showPoint(QString filepath); 
}; 

threadobject.cpp

#include "threadobject.h" 

ThreadObject::ThreadObject(){} 
ThreadObject::~ThreadObject(){} 


void ThreadObject::showPoint(QString filepath) 
{ 
    //qDebug() << filepath << QThread::currentThreadId(); 

    std::ifstream filestream(filepath.toLocal8Bit()); 
    std::string line; 
    int pointCounts = 0; 
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); 
    vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); 
    colors->SetNumberOfComponents(3); 
    colors->SetName("Colors"); 
    while (std::getline(filestream, line)) 
    { 
     double x, y, z, r, g, b; 
     std::stringstream linestream; 
     linestream << line; 
     linestream >> x >> y >> z >> r >> g >> b; 
     points->InsertNextPoint(x, y, z); 
     colors->InsertNextTuple3(r, g, b); 
    } 
    filestream.close(); 

    // Add the grid points to a polydata object 
    vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New(); 
    polydata->SetPoints(points); 
    polydata->GetPointData()->SetScalars(colors); 

    vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New(); 
    glyphFilter->SetInputData(polydata); 
    glyphFilter->Update(); 

    vtkSmartPointer<vtkCleanPolyData> cleaner = vtkSmartPointer<vtkCleanPolyData>::New(); 
    cleaner->SetInputConnection(glyphFilter->GetOutputPort()); 
    cleaner->Update(); 

    // Create a mapper and actor 
    vtkSmartPointer<vtkPolyDataMapper> pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); 
    pointMapper->SetInputConnection(cleaner->GetOutputPort()); 
    vtkSmartPointer<vtkActor> pointActor = vtkSmartPointer<vtkActor>::New(); 
    pointActor->SetMapper(pointMapper); 

    // Create a renderer 
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); 

    // Add the actor to the scene 
    renderer->AddActor(pointActor); 
    renderer->ResetCamera(); 
    renderer->SetBackground(0.1, 0.1, 0.1); 

    //send the renderer back to my qt window 
    emit endShowPointSignal(renderer);  
    //delete this; 
} 

mainwindow.cpp

void MainWindow::test() 
{ 
    QThread* thr1 = new QThread(); 
    ThreadObject* obj = new ThreadObject(); 
    obj->moveToThread(thr1); 
    connect(obj, SIGNAL(startShowPointSignal(QString)), obj, SLOT(showPoint(QString)), Qt::QueuedConnection); 
    connect(obj, SIGNAL(endShowPointSignal(vtkRenderer*)), this, SLOT(updateVTK(vtkRenderer*)), Qt::QueuedConnection); 
    thr1->start(); 
    obj->startShowPointSignal("D:/WorkSpace/VS Project/Plane/Datas/1.xyz"); 
} 

void MainWindow::updateVTK(vtkRenderer* renderer) 
{ 
    double test[3]; 
    renderer->GetBackground(test); 

    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); 
    renderWindow->AddRenderer(renderer); // I GOT THE ACCESS VIOLATION THIS LINE!!!!! 

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); 
    vtkSmartPointer<vtkInteractorStyleTrackballCamera> istyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New(); 
    renderWindowInteractor->SetInteractorStyle(istyle); 
    renderWindowInteractor->SetRenderWindow(renderWindow); 

    ui.qvtkWidget->SetRenderWindow(renderWindow); 

    renderWindow->Render(); 
    renderWindowInteractor->Start(); 
} 

我试图把所有的代码放在mainwindow中,而不是使用新的线程,它的工作很有趣。

所以当我使用QT线程时有什么问题吗?还是别的我没有注意到?

我是一个新人,QT,和QT的版本和VTK为5.7和7

+0

确保所有对'vtkRenderer'方法的调用都发生在它的线程中。 –

回答

1

OK,最后,我发现这是一个非常愚蠢的问题。我使用vtkSmartPointer创建了渲染器,但信号和插槽的参数是常规指针。将参数更改为vtkSmartPointer格式后,问题消失。