在同一个UI中使用QVTKWidget和QOpenGLWidget? [英] Using QVTKWidget and QOpenGLWidget in the same UI?

查看:5845
本文介绍了在同一个UI中使用QVTKWidget和QOpenGLWidget?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个项目,使用 QOpenGLWidget 的自定义子类来显示一些渲染。在 paintGL()方法的结尾,它调用小部件的 update()方法来触发重绘事件可见。
现在我想添加一个额外的 QVTKWidget 给我的Ui,我这样做使用这样:

  QVBoxLayout * layout = findChild< QVBoxLayout *>(layout_simulation); 
QVTKWidget * widget = new QVTKWidget();

//设置箭头
vtkSmartPointer< vtkArrowSource> arrowSource = vtkSmartPointer< vtkArrowSource> :: New();

[更多VTK stuff ...]

widget-> GetRenderWindow() - > AddRenderer(renderer);
renderer-> AddActor(arrowActor);
renderer-> ResetCamera();

//将小部件添加到ui
layout-> addWidget(widget);

VTK小部件被添加到ui并按预期工作。问题是,一旦我使用 layout-> addWidget()方法所有我的其他 QOpenGLWidget 对象变黑,不显示任何内容。此外,此黑色不是 VTKRenderer 的背景颜色,因为其他小部件仍然是黑色的,即使我更改了VTK窗口小部件的背景颜色。我检查和 paintGL()仍然在循环中调用,但它只是不显示任何东西。我确定我没有使用任何坏的OpenGL代码在我的小部件子类,所以我想它有一些与内部初始化 QOpenGLWidget QVTKWidget 。如果我省略所有的VTK调用并添加新创建的 QVTKWidget ,同样会发生。



有趣的是如果我省略 layout-> addWidget()调用,VTK在一个单独的窗口中打开渲染器,所有的OpenGL小部件工作没有问题。但是,我当然想把渲染器嵌入我的ui。



有没有人有这方面的经验,或者你知道任何陷阱我可能已经进入或有任何共同可能会导致这个问题?



BTW:我使用一个OpenGL 3.3核心配置文件和自定义着色器为我的 QOpenGLWidget



编辑:我删除了我对3.3核心配置文件的请求,现在它使用4.4兼容性配置文件。我想它现在使用与 VTKRenderer 相同的配置文件,因此这可以排除作为错误的源。

解决方案

所以我不知道究竟是什么原因导致的问题,但我解决了。起初,我发现VTK有一个第二个widget类名为 QVTKWidget2 但不幸的是它不完全兼容Qt 5.4,因为它使用旧的QGL类(如 QGLWidget 而不是 QOpenGLWidget )。所以我开始重新实现它作为 QOpenGLWidget 的子类,这是相当简单。下面是我的类 QVTKWidget3 的源文件,它适用于任何感兴趣的人Qt 5.4。我只是有限的测试(因为我仍然在学习VTK),但简单的例子,如显示一个球体工作。



再次:这只适用于 Qt 5.4

头文件:qvtkwidget3.h
/ p>

  #ifndef QVTKWIDGET3_H 
#define QVTKWIDGET3_H

#includevtkSmartPointer.h
#includevtkGenericOpenGLRenderWindow.h
#includevtkEventQtSlotConnect.h

#includeQVTKInteractorAdapter.h
#includeQVTKInteractor.h

#include< QOpenGLWidget>
#include< QSurfaceFormat>

class QVTKWidget3:public QOpenGLWidget
{
Q_OBJECT

public:
QVTKWidget3(QWidget * parent = NULL,Qt :: WindowFlags f = 0,QSurfaceFormat format = QSurfaceFormat :: defaultFormat());
virtual〜QVTKWidget3();

//!设置自定义渲染窗口
virtual void SetRenderWindow(vtkGenericOpenGLRenderWindow *);
//!返回curren渲染窗口(如果没有存在则创建一个)
virtual vtkGenericOpenGLRenderWindow * GetRenderWindow();

//!返回当前渲染窗口的交互器
virtual QVTKInteractor * GetInteractor();

公开位置:
//!插槽,使这个vtk渲染窗口当前
virtual void MakeCurrent();
//!当vtk想知道上下文是否为当前时调用槽
virtual void IsCurrent(vtkObject * caller,unsigned long vtk_event,void * client_data,void * call_data);
//!插槽调用时,vtk要框架窗口
virtual void Frame();
//!当vtk想要开始渲染时槽调用
virtual void Start();
//!当vtk想要结束渲染时调用槽
virtual void End();
//!当vtk想知道一个窗口是否是直接的时候调用槽
virtual void IsDirect(vtkObject * caller,unsigned long vtk_event,void * client_data,void * call_data);
//!插槽调用时vtk想知道一个窗口是否支持OpenGL
virtual void SupportsOpenGL(vtkObject * caller,unsigned long vtk_event,void * client_data,void * call_data);

protected:
//!初始化处理程序
virtual void initializeGL();
//!绘制处理程序
virtual void paintGL();
//!调整处理程序的大小
virtual void resizeGL(int,int);
//!移动处理程序
virtual void moveEvent(QMoveEvent * event);

虚拟无效mousePressEvent(QMouseEvent * event);
virtual void mouseMoveEvent(QMouseEvent * event);
virtual void mouseReleaseEvent(QMouseEvent * event);
virtual void keyPressEvent(QKeyEvent * event);
virtual void keyReleaseEvent(QKeyEvent * event);
virtual void enterEvent(QEvent *);
virtual void leaveEvent(QEvent *);
virtual void wheelEvent(QWheelEvent *);

virtual void contextMenuEvent(QContextMenuEvent *);
virtual void dragEnterEvent(QDragEnterEvent *);
virtual void dragMoveEvent(QDragMoveEvent *);
virtual void dragLeaveEvent(QDragLeaveEvent *);
virtual void dropEvent(QDropEvent *);

virtual bool focusNextPrevChild(bool);

//会员
vtkGenericOpenGLRenderWindow * m_renWin;
QVTKInteractorAdapter * m_irenAdapter;
vtkSmartPointer< vtkEventQtSlotConnect> m_connect;

private:
//!未实现的运算符=
QVTKWidget3 const& operator =(QVTKWidget3 const&);
//!未实现的副本
QVTKWidget3(const QVTKWidget3&);
};

#endif // QVTKWIDGET3_H

源文件:qvtkwidget3。 cpp

  #includeqvtkwidget3.h

#include vtkRenderWindowInteractor.h
#includevtkInteractorStyle.h
#includevtkInteractorStyleTrackballCamera.h

#include< QResizeEvent>

QVTKWidget3 :: QVTKWidget3(QWidget * parent,Qt :: WindowFlags f,QSurfaceFormat format)
:QOpenGLWidget(parent,f)
,m_renWin(nullptr)
{
// VTK需要兼容性配置文件
format.setProfile(QSurfaceFormat :: CompatibilityProfile);
setFormat(format);

//初始化交互器
m_irenAdapter = new QVTKInteractorAdapter(this);
m_connect = vtkSmartPointer< vtkEventQtSlotConnect> :: New();
}

//析构函数
QVTKWidget3 ::〜QVTKWidget3()
{
//不需要下面的行。
//摆脱VTK窗口
// this-> SetRenderWindow(NULL);
}

// GetRenderWindow
vtkGenericOpenGLRenderWindow * QVTKWidget3 :: GetRenderWindow()
{
if(this-> m_renWin == nullptr)
{
//创建一个默认的vtk窗口
vtkGenericOpenGLRenderWindow * win = vtkGenericOpenGLRenderWindow :: New();
this-> SetRenderWindow(win);
}

return this-> m_renWin;
}

// SetRenderWindow
void QVTKWidget3 :: SetRenderWindow(vtkGenericOpenGLRenderWindow * w)
{
//如果我们不需要
if(w == this-> m_renWin){
return;
}

//注销以前的窗口
if(this-> m_renWin!= nullptr){
this-> m_renWin-> Finalize
this-> m_renWin-> SetMapped(0);

m_connect->断开连接(m_renWin,vtkCommand :: WindowMakeCurrentEvent,this,SLOT(MakeCurrent()));
m_connect-> Disconnect(m_renWin,vtkCommand :: WindowIsCurrentEvent,this,SLOT(IsCurrent(vtkObject *,unsigned long,void *,void *)));
m_connect-> Disconnect(m_renWin,vtkCommand :: WindowFrameEvent,this,SLOT(Frame()));
m_connect->断开连接(m_renWin,vtkCommand :: StartEvent,this,SLOT(Start()));
m_connect->断开连接(m_renWin,vtkCommand :: EndEvent,this,SLOT(End()));
m_connect-> Disconnect(m_renWin,vtkCommand :: WindowIsDirectEvent,this,SLOT(IsDirect(vtkObject *,unsigned long,void *,void *)));
m_connect-> Disconnect(m_renWin,vtkCommand :: WindowSupportsOpenGLEvent,this,SLOT(SupportsOpenGL(vtkObject *,unsigned long,void *,void *)));
}

//现在设置窗口
this-> m_renWin = w;

if(this-> m_renWin!= nullptr){
//如果它映射到其他地方,取消映射
this-> m_renWin-> Finalize ;
this-> m_renWin-> SetMapped(1);

//告诉vtk窗口这个窗口的大小是
this-> m_renWin-> SetSize(this-> width(),this-> height );
this-> m_renWin-> SetPosition(this-> x(),this-> y());

//如果没有提供交互器,我们将默认创建一个
if(this-> m_renWin-> GetInteractor()== NULL)
{
//创建一个默认的交互器
QVTKInteractor * iren = QVTKInteractor :: New();
iren-> SetUseTDx(false);
this-> m_renWin-> SetInteractor(iren);
iren-> Initialize();

//现在设置默认样式
vtkInteractorStyle * s = vtkInteractorStyleTrackballCamera :: New();
iren-> SetInteractorStyle(s);

iren-> Delete();
s-> Delete();
}

//告诉交互器此窗口的大小
this-> m_renWin-> GetInteractor() - > SetSize(this-> width ,this-> height());

m_connect-> Connect(m_renWin,vtkCommand :: WindowMakeCurrentEvent,this,SLOT(MakeCurrent()));
m_connect-> Connect(m_renWin,vtkCommand :: WindowIsCurrentEvent,this,SLOT(IsCurrent(vtkObject *,unsigned long,void *,void *)));
m_connect-> Connect(m_renWin,vtkCommand :: WindowFrameEvent,this,SLOT(Frame()));
m_connect-> Connect(m_renWin,vtkCommand :: StartEvent,this,SLOT(Start()));
m_connect-> Connect(m_renWin,vtkCommand :: EndEvent,this,SLOT(End()));
m_connect-> Connect(m_renWin,vtkCommand :: WindowIsDirectEvent,this,SLOT(IsDirect(vtkObject *,unsigned long,void *,void *)));
m_connect-> Connect(m_renWin,vtkCommand :: WindowSupportsOpenGLEvent,this,SLOT(SupportsOpenGL(vtkObject *,unsigned long,void *,void *)));
}
}

// GetInteractor
QVTKInteractor * QVTKWidget3 :: GetInteractor()
{
return QVTKInteractor :: SafeDownCast(this- > GetRenderWindow() - > GetInteractor());
}

//初始化
void QVTKWidget3 :: initializeGL()
{
if(this-> m_renWin == nullptr){
return;
}

this-> m_renWin-> OpenGLInitContext();
}

// Paint
void QVTKWidget3 :: paintGL()
{
vtkRenderWindowInteractor * iren = nullptr;
if(this-> m_renWin!= nullptr){
iren = this-> m_renWin-> GetInteractor();
}

if(iren == nullptr ||!iren-> GetEnabled()){
return;
}

iren-> Render();
}

//调整大小
void QVTKWidget3 :: resizeGL(int w,int h)
{
if(this-> m_renWin == nullptr){
return;
}

this-> m_renWin-> SetSize(w,h);

//并更新交互器
if(this-> m_renWin-> GetInteractor()!= NULL){
QResizeEvent e(QSize(w,h) QSize());
m_irenAdapter-> ProcessEvent(& e,this-> m_renWin-> GetInteractor());
}
}

//移动
void QVTKWidget3 :: moveEvent(QMoveEvent * e)
{
QWidget :: moveEvent );

if(this-> m_renWin == nullptr){
return;
}

this-> m_renWin-> SetPosition(this-> x(),this-> y());
}


// --------
//插槽
// --------

void QVTKWidget3 :: Start()
{
makeCurrent();
m_renWin-> PushState();
m_renWin-> OpenGLInitState();
}

void QVTKWidget3 :: End()
{
m_renWin-> PopState();
}

void QVTKWidget3 :: MakeCurrent()
{
return;
//由QOpenGLWidget自动处理
// this-> makeCurrent();
}

void QVTKWidget3 :: IsCurrent(vtkObject *,unsigned long,void *,void * call_data)
{
bool * ptr = reinterpret_cast< bool * ;(call_data);
* ptr =(int)true;
}

void QVTKWidget3 :: IsDirect(vtkObject *,unsigned long,void *,void * call_data)
{
int * ptr = reinterpret_cast< int * ;(call_data);
* ptr =(int)true;
}

void QVTKWidget3 :: SupportsOpenGL(vtkObject *,unsigned long,void *,void * call_data)
{
int * ptr = reinterpret_cast< int * ;(call_data);
* ptr =(int)true;
}

void QVTKWidget3 :: Frame()
{
if(m_renWin-> GetSwapBuffers()){
this-> update );
}

//这个回调函数会为我们调用swapBuffers()
//因为有时VTK没有渲染这个paintGL()

// FOLLOWING NOT TESTED FOR QOPENGLWIDGET
//如果你想要每次VTK渲染
时总是调用paintGL 1.关闭交互器上的EnableRender,
// 2。关闭渲染窗口上的SwapBuffers
// 3.为来自交互器的RenderEvent添加一个观察器
// 4.在观察器上实现回调以调用此widget上的updateGL()
// 5.重载QVTKWidget3 :: paintGL()调用m_renWin-> Render()而不是iren-> Render()
}

// ----- -----------------
//交互处理程序
// ------------------- ---

/ *!处理鼠标按事件
* /
void QVTKWidget3 :: mousePressEvent(QMouseEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}

}

/ *!处理鼠标移动事件
* /
void QVTKWidget3 :: mouseMoveEvent(QMouseEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

/ *!句柄输入事件
* /
void QVTKWidget3 :: enterEvent(QEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter - > ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

/ *!处理离开事件
* /
void QVTKWidget3 :: leaveEvent(QEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter - > ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

/ *!处理鼠标释放事件
* /
void QVTKWidget3 :: mouseReleaseEvent(QMouseEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

/ *!句柄键按事件
* /
void QVTKWidget3 :: keyPressEvent(QKeyEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

/ *!句柄键释放事件
* /
void QVTKWidget3 :: keyReleaseEvent(QKeyEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

void QVTKWidget3 :: wheelEvent(QWheelEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

void QVTKWidget3 :: contextMenuEvent(QContextMenuEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

void QVTKWidget3 :: dragEnterEvent(QDragEnterEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

void QVTKWidget3 :: dragMoveEvent(QDragMoveEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

void QVTKWidget3 :: dragLeaveEvent(QDragLeaveEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

void QVTKWidget3 :: dropEvent(QDropEvent * e)
{
if(this-> m_renWin)
{
m_irenAdapter-> ProcessEvent(e,this-> m_renWin-> GetInteractor());
}
}

bool QVTKWidget3 :: focusNextPrevChild(bool)
{
return false;
}


I'm working on a project that uses a custom subclass of QOpenGLWidget to display some renderings. At the end of the paintGL() method it calls the widget's update() method to trigger a repaint event if it's visible. Now I want to add an additional QVTKWidget to my Ui and I do so by using something like this:

QVBoxLayout* layout = findChild<QVBoxLayout*>("layout_simulation");
QVTKWidget* widget = new QVTKWidget();

// Setup arrow
vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New();

[more VTK stuff...]

widget->GetRenderWindow()->AddRenderer(renderer);
renderer->AddActor(arrowActor);
renderer->ResetCamera();

// Add widget to ui
layout->addWidget(widget);

The VTK widget is added to the ui and is working as intended. The problem is that as soon as I use the layout->addWidget() method all my other QOpenGLWidget objects turn black and don't display anything. Also this black is not the background color of the VTKRenderer because the other widgets are still black even if I change the background color of the VTK widget. I checked and the paintGL() still gets called in a loop but it just doesn't display anything. I'm pretty sure that I didn't use any bad OpenGL code in my widget subclass so I guess it has something to do with the internal initialization of QOpenGLWidget and QVTKWidget. The same happens if I omit all the VTK calls and just add the newly created QVTKWidget.

The funny thing is that if I omit the layout->addWidget() call, VTK opens the renderer in a seperate window and all the OpenGL widgets work without a problem. But of course I want to embed the renderer in my ui.

Does anyone have experience with this or do you know any pitfalls I might have stepped into or are there any common problems that may cause this?

BTW: I use a OpenGL 3.3 core profile with custom shaders for my QOpenGLWidget subclass.

EDIT: I removed my request for a 3.3 core profile and now it uses a 4.4 compatibility profile. I guess it's now using the same profile as the VTKRenderer so this can be ruled out as a source for the error.

解决方案

So I don't know what exactly caused the problem but I solved it. At first I found out that there is a second widget class for VTK called QVTKWidget2 but unfortunately it isn't fully compatible to Qt 5.4 because it uses the old QGL classes (like QGLWidget instead of QOpenGLWidget). So I started to re-implement it as a subclass of QOpenGLWidget which was quite straight forward. Below are the source files for my class QVTKWidget3 that works with Qt 5.4 for anyone who is interested. I did only limited testing (because I'm still learning VTK) but simple examples like displaying a sphere work.

Again: this only works with Qt 5.4 (beta) because older versionen don't provide the QOpenGLWidget class!

Header file: qvtkwidget3.h

#ifndef QVTKWIDGET3_H
#define QVTKWIDGET3_H

#include "vtkSmartPointer.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "vtkEventQtSlotConnect.h"

#include "QVTKInteractorAdapter.h"
#include "QVTKInteractor.h"

#include <QOpenGLWidget>
#include <QSurfaceFormat>

class QVTKWidget3 : public QOpenGLWidget
{
    Q_OBJECT

public:
    QVTKWidget3(QWidget *parent = NULL, Qt::WindowFlags f = 0, QSurfaceFormat format = QSurfaceFormat::defaultFormat());
    virtual ~QVTKWidget3();

    //! Set a custom render window
    virtual void SetRenderWindow(vtkGenericOpenGLRenderWindow*);
    //! Returns the curren render window (creates one if none exists)
    virtual vtkGenericOpenGLRenderWindow* GetRenderWindow();

    //! Returns interactor of the current render window
    virtual QVTKInteractor* GetInteractor();

public slots:
    //! Slot to make this vtk render window current
    virtual void MakeCurrent();
    //! Slot called when vtk wants to know if the context is current
    virtual void IsCurrent(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data);
    //! Slot called when vtk wants to frame the window
    virtual void Frame();
    //! Slot called when vtk wants to start the render
    virtual void Start();
    //! Slot called when vtk wants to end the render
    virtual void End();
    //! Slot called when vtk wants to know if a window is direct
    virtual void IsDirect(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data);
    //! Slot called when vtk wants to know if a window supports OpenGL
    virtual void SupportsOpenGL(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data);

protected:
    //! Initialize handler
    virtual void initializeGL();
    //! Paint handler
    virtual void paintGL();
    //! Resize handler
    virtual void resizeGL(int, int);
    //! Move handler
    virtual void moveEvent(QMoveEvent* event);

    virtual void mousePressEvent(QMouseEvent* event);
    virtual void mouseMoveEvent(QMouseEvent* event);
    virtual void mouseReleaseEvent(QMouseEvent* event);
    virtual void keyPressEvent(QKeyEvent* event);
    virtual void keyReleaseEvent(QKeyEvent* event);
    virtual void enterEvent(QEvent*);
    virtual void leaveEvent(QEvent*);
    virtual void wheelEvent(QWheelEvent*);

    virtual void contextMenuEvent(QContextMenuEvent*);
    virtual void dragEnterEvent(QDragEnterEvent*);
    virtual void dragMoveEvent(QDragMoveEvent*);
    virtual void dragLeaveEvent(QDragLeaveEvent*);
    virtual void dropEvent(QDropEvent*);

    virtual bool focusNextPrevChild(bool);

    // Members
    vtkGenericOpenGLRenderWindow* m_renWin;
    QVTKInteractorAdapter* m_irenAdapter;
    vtkSmartPointer<vtkEventQtSlotConnect> m_connect;

private:
    //! unimplemented operator=
    QVTKWidget3 const& operator=(QVTKWidget3 const&);
    //! unimplemented copy
    QVTKWidget3(const QVTKWidget3&);
};

#endif // QVTKWIDGET3_H

Source file: qvtkwidget3.cpp

#include "qvtkwidget3.h"

#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyle.h"
#include "vtkInteractorStyleTrackballCamera.h"

#include <QResizeEvent>

QVTKWidget3::QVTKWidget3(QWidget *parent, Qt::WindowFlags f, QSurfaceFormat format)
    : QOpenGLWidget(parent, f)
    , m_renWin(nullptr)
{
    // VTK requires a compatibility profile
    format.setProfile(QSurfaceFormat::CompatibilityProfile);
    setFormat(format);

    // Initialize interactors
    m_irenAdapter = new QVTKInteractorAdapter(this);
    m_connect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
}

// Destructor
QVTKWidget3::~QVTKWidget3()
{
  // Following line is not needed.
  // get rid of the VTK window
  // this->SetRenderWindow(NULL);
}

// GetRenderWindow
vtkGenericOpenGLRenderWindow* QVTKWidget3::GetRenderWindow()
{
    if (this->m_renWin == nullptr)
    {
        // create a default vtk window
        vtkGenericOpenGLRenderWindow* win = vtkGenericOpenGLRenderWindow::New();
        this->SetRenderWindow(win);
    }

    return this->m_renWin;
}

// SetRenderWindow
void QVTKWidget3::SetRenderWindow(vtkGenericOpenGLRenderWindow* w)
{
    // do nothing if we don't have to
    if(w == this->m_renWin) {
        return;
    }

    // unregister previous window
    if(this->m_renWin != nullptr) {
        this->m_renWin->Finalize();
        this->m_renWin->SetMapped(0);

        m_connect->Disconnect(m_renWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent()));
        m_connect->Disconnect(m_renWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*)));
        m_connect->Disconnect(m_renWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame()));
        m_connect->Disconnect(m_renWin, vtkCommand::StartEvent, this, SLOT(Start()));
        m_connect->Disconnect(m_renWin, vtkCommand::EndEvent, this, SLOT(End()));
        m_connect->Disconnect(m_renWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*)));
        m_connect->Disconnect(m_renWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*)));
    }

    // now set the window
    this->m_renWin = w;

    if(this->m_renWin != nullptr) {
        // if it is mapped somewhere else, unmap it
        this->m_renWin->Finalize();
        this->m_renWin->SetMapped(1);

        // tell the vtk window what the size of this window is
        this->m_renWin->SetSize(this->width(), this->height());
        this->m_renWin->SetPosition(this->x(), this->y());

        // if an interactor wasn't provided, we'll make one by default
        if(this->m_renWin->GetInteractor() == NULL)
        {
            // create a default interactor
            QVTKInteractor* iren = QVTKInteractor::New();
            iren->SetUseTDx(false);
            this->m_renWin->SetInteractor(iren);
            iren->Initialize();

            // now set the default style
            vtkInteractorStyle* s = vtkInteractorStyleTrackballCamera::New();
            iren->SetInteractorStyle(s);

            iren->Delete();
            s->Delete();
        }

        // tell the interactor the size of this window
        this->m_renWin->GetInteractor()->SetSize(this->width(), this->height());

        m_connect->Connect(m_renWin, vtkCommand::WindowMakeCurrentEvent, this, SLOT(MakeCurrent()));
        m_connect->Connect(m_renWin, vtkCommand::WindowIsCurrentEvent, this, SLOT(IsCurrent(vtkObject*, unsigned long, void*, void*)));
        m_connect->Connect(m_renWin, vtkCommand::WindowFrameEvent, this, SLOT(Frame()));
        m_connect->Connect(m_renWin, vtkCommand::StartEvent, this, SLOT(Start()));
        m_connect->Connect(m_renWin, vtkCommand::EndEvent, this, SLOT(End()));
        m_connect->Connect(m_renWin, vtkCommand::WindowIsDirectEvent, this, SLOT(IsDirect(vtkObject*, unsigned long, void*, void*)));
        m_connect->Connect(m_renWin, vtkCommand::WindowSupportsOpenGLEvent, this, SLOT(SupportsOpenGL(vtkObject*, unsigned long, void*, void*)));
    }
}

// GetInteractor
QVTKInteractor* QVTKWidget3::GetInteractor()
{
    return QVTKInteractor::SafeDownCast(this->GetRenderWindow()->GetInteractor());
}

// Initialize
void QVTKWidget3::initializeGL()
{
    if(this->m_renWin == nullptr) {
        return;
    }

    this->m_renWin->OpenGLInitContext();
}

// Paint
void QVTKWidget3::paintGL()
{
    vtkRenderWindowInteractor* iren = nullptr;
    if(this->m_renWin != nullptr) {
        iren = this->m_renWin->GetInteractor();
    }

    if(iren == nullptr || !iren->GetEnabled()) {
        return;
    }

    iren->Render();
}

// Resize
void QVTKWidget3::resizeGL(int w, int h)
{
    if(this->m_renWin == nullptr) {
        return;
    }

    this->m_renWin->SetSize(w,h);

    // and update the interactor
    if(this->m_renWin->GetInteractor() != NULL) {
        QResizeEvent e(QSize(w,h), QSize());
        m_irenAdapter->ProcessEvent(&e, this->m_renWin->GetInteractor());
    }
}

// Move
void QVTKWidget3::moveEvent(QMoveEvent* e)
{
    QWidget::moveEvent(e);

    if(this->m_renWin == nullptr) {
        return;
    }

    this->m_renWin->SetPosition(this->x(), this->y());
}


// --------
//  Slots
// --------

void QVTKWidget3::Start()
{
    makeCurrent();
    m_renWin->PushState();
    m_renWin->OpenGLInitState();
}

void QVTKWidget3::End()
{
    m_renWin->PopState();
}

void QVTKWidget3::MakeCurrent()
{
    return;
    // Automaticly handled by QOpenGLWidget
    // this->makeCurrent();
}

void QVTKWidget3::IsCurrent(vtkObject*, unsigned long, void*, void* call_data)
{
    bool* ptr = reinterpret_cast<bool*>(call_data);
    *ptr = (int)true;
}

void QVTKWidget3::IsDirect(vtkObject*, unsigned long, void*, void* call_data)
{
    int* ptr = reinterpret_cast<int*>(call_data);
    *ptr = (int)true;
}

void QVTKWidget3::SupportsOpenGL(vtkObject*, unsigned long, void*, void* call_data)
{
    int* ptr = reinterpret_cast<int*>(call_data);
    *ptr = (int)true;
}

void QVTKWidget3::Frame()
{
    if(m_renWin->GetSwapBuffers()) {
        this->update();
    }

    // This callback will call swapBuffers() for us
    // because sometimes VTK does a render without coming through this paintGL()

    // FOLLOWING NOT TESTED FOR QOPENGLWIDGET
    // if you want paintGL to always be called for each time VTK renders
    // 1. turn off EnableRender on the interactor,
    // 2. turn off SwapBuffers on the render window,
    // 3. add an observer for the RenderEvent coming from the interactor
    // 4. implement the callback on the observer to call updateGL() on this widget
    // 5. overload QVTKWidget3::paintGL() to call m_renWin->Render() instead iren->Render()
}

// ----------------------
//  Interaction handlers
// ----------------------

/*! handle mouse press event
 */
void QVTKWidget3::mousePressEvent(QMouseEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }

}

/*! handle mouse move event
 */
void QVTKWidget3::mouseMoveEvent(QMouseEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

/*! handle enter event
 */
void QVTKWidget3::enterEvent(QEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

/*! handle leave event
 */
void QVTKWidget3::leaveEvent(QEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

/*! handle mouse release event
 */
void QVTKWidget3::mouseReleaseEvent(QMouseEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

/*! handle key press event
 */
void QVTKWidget3::keyPressEvent(QKeyEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

/*! handle key release event
 */
void QVTKWidget3::keyReleaseEvent(QKeyEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

void QVTKWidget3::wheelEvent(QWheelEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

void QVTKWidget3::contextMenuEvent(QContextMenuEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

void QVTKWidget3::dragEnterEvent(QDragEnterEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

void QVTKWidget3::dragMoveEvent(QDragMoveEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

void QVTKWidget3::dragLeaveEvent(QDragLeaveEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

void QVTKWidget3::dropEvent(QDropEvent* e)
{
    if(this->m_renWin)
    {
        m_irenAdapter->ProcessEvent(e, this->m_renWin->GetInteractor());
    }
}

bool QVTKWidget3::focusNextPrevChild(bool)
{
    return false;
}

这篇关于在同一个UI中使用QVTKWidget和QOpenGLWidget?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆