简体   繁体   English

使用VTK和QT多线程时的访问冲突异常

[英]access violation exception when use VTK and QT multi-thread

I am using a QVtkWidget in my mainwindow. 我在QVtkWidget中使用了QVtkWidget。 I generate a vtkRenderer in a new thread and when it is done, I send a signal which connect a slot of mainwindow to send the renderer back and update the QVtkWidget. 我在新线vtkRenderer一个vtkRenderer ,完成后,我发送了一个signal ,该signal连接了mainwindow的一个slot ,以发送回渲染器并更新QVtkWidget。

Unfortunately, I got a "access violation" exception when I add the renderer to the vtkRenderWindow. 不幸的是,当我将渲染器添加到vtkRenderWindow时,出现了“访问冲突”异常。 Here is my code: 这是我的代码:

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 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();
}

I have tried to put all the code in mainwindow, and not use a new thread, it worked fun. 我试图将所有代码放入mainwindow中,而不使用新线程,它的工作很有趣。

So is there something wrong when I use the QT thread? 那么当我使用QT线程时有什么问题吗? Or something else I didn't notice? 还是我没注意到的其他事情?

I'm a newcomer to QT, and the version of QT and VTK is 5.7 and 7. 我是QT的新手,QT和VTK的版本是5.7和7。

OK, Finally I found it's a really stupid problem. 好的,最后我发现这是一个非常愚蠢的问题。 I created the renderer using vtkSmartPointer , but the parameters of signal and slots are regular Pointer. 我使用vtkSmartPointer创建了渲染器,但是signal和slot的参数是常规Pointer。 After changing the parameters to vtkSmartPointer format, the problem disappeared. 将参数更改为vtkSmartPointer格式后,问题消失了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM