BestMPRBaseVtk-11-Qt交互器QVTKInteractor
Posted DreamLife.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BestMPRBaseVtk-11-Qt交互器QVTKInteractor相关的知识,希望对你有一定的参考价值。
BestMPRBaseVtk 交互
这两天折腾了好几个交互方式,但是终究还是没有理解其中的奥,所以决定好好看看vtkQt 的交互。
关键字:
QVTKInteractor
、交互器
、Qt
、vtk
、关键字5
1 源码分析
void QVTKOpenGLNativeWidget::setRenderWindow(vtkGenericOpenGLRenderWindow* win)
if (this->RenderWindow == win)
return;
// this will release all OpenGL resources associated with the old render
// window, if any.
if (this->RenderWindowAdapter)
this->makeCurrent();
this->RenderWindowAdapter.reset(nullptr);
this->RenderWindow = win;
if (this->RenderWindow)
this->RenderWindow->SetReadyForRendering(false);
// if an interactor wasn't provided, we'll make one by default
if (!this->RenderWindow->GetInteractor())
// create a default interactor
vtkNew<QVTKInteractor> iren;
// iren->SetUseTDx(this->UseTDx);
this->RenderWindow->SetInteractor(iren);
iren->Initialize();
// now set the default style
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
if (this->isValid())
// this typically means that the render window is being changed after the
// QVTKOpenGLNativeWidget has initialized itself in a previous update
// pass, so we emulate the steps to ensure that the new vtkRenderWindow is
// brought to the same state (minus the actual render).
this->makeCurrent();
this->initializeGL();
this->updateSize();
重点
if (!this->RenderWindow->GetInteractor())
// create a default interactor
vtkNew<QVTKInteractor> iren;
// iren->SetUseTDx(this->UseTDx);
this->RenderWindow->SetInteractor(iren);
iren->Initialize();
// now set the default style
vtkNew<vtkInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
翻译官方源码注释,这段代码意思就是创建一个默认的交互器QVTKInteractor
类型的。并调用当前RenderWindow
的SetInteractor()
接口,把创建的QVTKInteractor
类型的交互器传给RenderWindow
,完成后交互器调用自己的Initialize()
进行初始化。完后创建一个vtkInteractorStyleTrackballCamera
类型的交互器样式,并将这个样式通过交互器的SetInteractorStyle()
接口传输给交互器。
2 QVTKInteractor
官网给的说明很少,只是说QVTKInteractor
是QVTKOpenGLNativeWidget
和(QVTKWiget)的交互器。将Qt 的事件中继到vtk中。
从下图可以看出,QVTKInteractor是直接继承于vtkRenderWindowInteractor
的一个分支,而 vtkRenderWindowInteractor
是一个独立于平台的渲染窗口交互器,包括拾取和帧速率控制等。详细的后面再扒拉。今天重点还是研究QVTKInteractor
.
3 QVTKInteractor 源代码
QVTKInteractor 源代码如下,大致看了一下,完全搞不懂事干啥,大致感觉就是分几个平台,来监听硬件信号。不过在代码里面我到时发现了一个能认识的东西QEvent
,我们前面使用的wheelEvent
时间就是继承他的。所以底层的原理应该一样的吧。
QVTKInteractor.h
#ifndef Q_VTK_INTERACTOR_H
#define Q_VTK_INTERACTOR_H
#include "QVTKWin32Header.h"
#include "vtkGUISupportQtModule.h" // For export macro
#include <QtCore/QObject>
#include <vtkCommand.h>
#include <vtkRenderWindowInteractor.h>
#include "vtkTDxConfigure.h" // defines VTK_USE_TDX
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
class vtkTDxWinDevice;
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
class vtkTDxMacDevice;
#endif
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
class vtkTDxDevice;
class vtkTDxUnixDevice;
#endif
class QVTKInteractorInternal;
/**
* @class QVTKInteractor
* @brief - an interactor for QVTKOpenGLNativeWidget (and QVTKWiget).
*
* QVTKInteractor handles relaying Qt events to VTK.
* @sa QVTKOpenGLNativeWidget
*/
class VTKGUISUPPORTQT_EXPORT QVTKInteractor : public vtkRenderWindowInteractor
public:
static QVTKInteractor* New();
vtkTypeMacro(QVTKInteractor, vtkRenderWindowInteractor);
/**
* Enum for additional event types supported.
* These events can be picked up by command observers on the interactor.
*/
enum vtkCustomEvents
ContextMenuEvent = vtkCommand::UserEvent + 100,
DragEnterEvent,
DragMoveEvent,
DragLeaveEvent,
DropEvent
;
/**
* Overloaded terminate app, which does nothing in Qt.
* Use qApp->exit() instead.
*/
void TerminateApp() override;
/**
* Overloaded start method does nothing.
* Use qApp->exec() instead.
*/
void Start() override;
void Initialize() override;
/**
* Start listening events on 3DConnexion device.
*/
virtual void StartListening();
/**
* Stop listening events on 3DConnexion device.
*/
virtual void StopListening();
/**
* timer event slot
*/
virtual void TimerEvent(int timerId);
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
virtual vtkTDxUnixDevice* GetDevice();
virtual void SetDevice(vtkTDxDevice* device);
#endif
protected:
// constructor
QVTKInteractor();
// destructor
~QVTKInteractor() override;
// create a Qt Timer
int InternalCreateTimer(int timerId, int timerType, unsigned long duration) override;
// destroy a Qt Timer
int InternalDestroyTimer(int platformTimerId) override;
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
vtkTDxWinDevice* Device;
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
vtkTDxMacDevice* Device;
#endif
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
vtkTDxUnixDevice* Device;
#endif
private:
QVTKInteractorInternal* Internal;
QVTKInteractor(const QVTKInteractor&) = delete;
void operator=(const QVTKInteractor&) = delete;
;
#endif
QVTKInteractor.cpp
#ifdef _MSC_VER
// Disable warnings that Qt headers give.
#pragma warning(disable : 4127)
#pragma warning(disable : 4512)
#endif
#include "QVTKInteractor.h"
#include "QVTKInteractorInternal.h"
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
#include "vtkTDxWinDevice.h"
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
#include "vtkTDxMacDevice.h"
#endif
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
#include "vtkTDxUnixDevice.h"
#endif
#include <QEvent>
#include <QResizeEvent>
#include <QSignalMapper>
#include <QTimer>
#include "vtkCommand.h"
#include "vtkObjectFactory.h"
#include "vtkRenderWindow.h"
QVTKInteractorInternal::QVTKInteractorInternal(QVTKInteractor* p)
: Parent(p)
this->SignalMapper = new QSignalMapper(this);
QObject::connect(this->SignalMapper, SIGNAL(mapped(int)), this, SLOT(TimerEvent(int)));
QVTKInteractorInternal::~QVTKInteractorInternal()
void QVTKInteractorInternal::TimerEvent(int id)
Parent->TimerEvent(id);
/*! allocation method for Qt/VTK interactor
*/
vtkStandardNewMacro(QVTKInteractor);
/*! constructor for Qt/VTK interactor
*/
QVTKInteractor::QVTKInteractor()
this->Internal = new QVTKInteractorInternal(this);
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
this->Device = vtkTDxWinDevice::New();
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
this->Device = vtkTDxMacDevice::New();
#endif
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
this->Device = 0;
#endif
void QVTKInteractor::Initialize()
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
if (this->UseTDx)
// this is QWidget::winId();
HWND hWnd = static_cast<HWND>(this->GetRenderWindow()->GetGenericWindowId());
if (!this->Device->GetInitialized())
this->Device->SetInteractor(this);
this->Device->SetWindowHandle(hWnd);
this->Device->Initialize();
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
if (this->UseTDx)
if (!this->Device->GetInitialized())
this->Device->SetInteractor(this);
// Do not initialize the device here.
#endif
this->Initialized = 1;
this->Enable();
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
// ----------------------------------------------------------------------------
vtkTDxUnixDevice* QVTKInteractor::GetDevice()
return this->Device;
// ----------------------------------------------------------------------------
void QVTKInteractor::SetDevice(vtkTDxDevice* device)
if (this->Device != device)
this->Device = static_cast<vtkTDxUnixDevice*>(device);
#endif
/*! start method for interactor
*/
void QVTKInteractor::Start()
vtkErrorMacro(<< "QVTKInteractor cannot control the event loop.");
/*! terminate the application
*/
void QVTKInteractor::TerminateApp()
// we are in a GUI so let's terminate the GUI the normal way
// qApp->exit();
// ----------------------------------------------------------------------------
void QVTKInteractor::StartListening()
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
if (this->Device->GetInitialized() && !this->Device->GetIsListening())
this->Device->StartListening();
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
if (this->UseTDx && !this->Device->GetInitialized())
this->Device->Initialize();
#endif
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
if (this->UseTDx && this->Device != 0)
this->Device->SetInteractor(this);
#endif
// ----------------------------------------------------------------------------
void QVTKInteractor::StopListening()
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
if (this->Device->GetInitialized() && this->Device->GetIsListening())
this->Device->StopListening();
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
if (this->UseTDx && this->Device->GetInitialized())
this->Device->Close();
#endif
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
if (this->UseTDx && this->Device != 0)
// this assumes that a outfocus event is emitted prior
// a infocus event on another widget.
this->Device->SetInteractor(0);
#endif
/*! handle timer event
*/
void QVTKInteractor::TimerEvent(int timerId)
if (!this->GetEnabled())
return;
this->InvokeEvent(vtkCommand::TimerEvent, (void*)&timerId);
if (this->IsOneShotTimer(timerId))
this->DestroyTimer(timerId); // 'cause our Qt timers are always repeating
/*! constructor
*/
QVTKInteractor::~QVTKInteractor()
delete this->Internal;
#if defined(VTK_USE_TDX) && defined(Q_OS_WIN)
this->Device->Delete();
#endif
#if defined(VTK_USE_TDX) && defined(Q_OS_MAC)
this->Device->Delete();
#endif
#if defined(VTK_USE_TDX) && (defined(Q_WS_X11) || defined(Q_OS_LINUX))
this->Device = 0;
#endif
/*! create Qt timer with an interval of 10 msec.
*/
int QVTKInteractor::InternalCreateTimer(
int timerId, int vtkNotUsed(timerType), unsigned long duration)
QTimer* timer = new QTimer(this->Internal);
timer->start(duration);
this->Internal->SignalMapper->setMapping(timer, timerId);
QObject::connect(timer, SIGNAL(timeout()), this->Internal->SignalMapper, SLOT(map()));
int platformTimerId = timer->timerId();
this->Internal->Timers.insert(
QVTKInteractorInternal::TimerMap::value_type(platformTimerId, timer));
return platformTimerId;
/*! destroy timer
*/
int QVTKInteractor::InternalDestroyTimer(int platformTimerId)
QVTKInteractorInternal::TimerMap::iterator iter = this->Internal->Timers.find(platformTimerId);
if (iter != this->Internal->Timers.end())
iter->second->stop();
iter->second->deleteLater();
this->Internal->Timers.erase(iter);
return 1;
return 0;
☞ 源码
源码链接:GitHub仓库自取
使用方法:☟☟☟
以上是关于BestMPRBaseVtk-11-Qt交互器QVTKInteractor的主要内容,如果未能解决你的问题,请参考以下文章
ionic (webApp)软qv键盘打开时视口高度变小导致样式问题的解决方案
在树莓派上原生构建 qt5.7.1 得到错误:/usr/lib/arm-linux-gnueabihf/libQt5Quick.so.5: 未定义对 `QV8Engine::toVariant 的引用