OSGEarth嵌入Qt的QGraphicsView框架(一)

原创 2015年07月08日 21:27:48

近期在学习OSGEarth,看example,自己结合Qt写了一些小例子,特此记录一下。

首先,考虑到OE(OSGEarth)嵌入到QGraphicsView中,首先收到按键、鼠标事件的就是QGraphicsView,因此,我们需要先把这一庞大的事件进行处理。
代码如下:eventadapter .h

class EventAdapter : public QGraphicsView
{
public:
    EventAdapter();
    ~EventAdapter();

protected:
    // 处理按键事件
    virtual void keyPressEvent(QKeyEvent* event);
    virtual void keyReleaseEvent(QKeyEvent* event);

    // 处理鼠标单击事件
    virtual void mousePressEvent(QMouseEvent* event);
    virtual void mouseReleaseEvent(QMouseEvent* event);

    // 处理鼠标双击事件
    virtual void mouseDoubleClickEvent(QMouseEvent* event);
    virtual void mouseMoveEvent(QMouseEvent* event);

    // 处理鼠标中轮滑动事件
    virtual void wheelEvent(QWheelEvent* event);

    // 处理窗口大小改变事件
    virtual void resizeEvent(QResizeEvent *event);

    // 处理鼠标移动事件
    virtual void moveEvent(QMoveEvent* event);

    // timerEvent事件
    virtual void timerEvent(QTimerEvent *event);

private:
    void setKeyboardModifiers(QInputEvent* event);

protected:
    osgViewer::GraphicsWindow* m_pGraphicsWindow;
};

实现文件如下:eventadapter .cpp

void EventAdapter::keyPressEvent(QKeyEvent* event)
{
    QPoint pos = QCursor::pos();
    QList<QGraphicsItem*> listItems = items(mapToScene(pos.x(), pos.y()).toPoint());
    if (listItems.size() <= 0)
    {
        setKeyboardModifiers(event);
        m_pGraphicsWindow->getEventQueue()->keyPress(
            (osgGA::GUIEventAdapter::KeySymbol)*(event->text().toLatin1().data()));
    }
    QGraphicsView::keyPressEvent(event);
}

void EventAdapter::keyReleaseEvent(QKeyEvent* event)
{
    setKeyboardModifiers(event);
    m_pGraphicsWindow->getEventQueue()->keyRelease(
        (osgGA::GUIEventAdapter::KeySymbol)*(event->text().toLatin1().data()));

    QGraphicsView::keyReleaseEvent(event);
}

void EventAdapter::mousePressEvent(QMouseEvent* event)
{
    QPoint pos = event->pos();
    QList<QGraphicsItem*> listItems = items(mapToScene(pos.x(), pos.y()).toPoint());
    if (listItems.size() > 0)
    {
        QGraphicsView::mousePressEvent(event);
    }
    else
    {
        int button = 0;
        switch (event->button())
        {
        case Qt::LeftButton: button = 1; break;
        case Qt::MidButton: button = 2; break;
        case Qt::RightButton: button = 3; break;
        case Qt::NoButton: button = 0; break;
        default: button = 0; break;
        }
        setKeyboardModifiers(event);
        m_pGraphicsWindow->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
    }
}

void EventAdapter::mouseReleaseEvent(QMouseEvent* event)
{
    int button = 0;
    switch (event->button())
    {
    case Qt::LeftButton: button = 1; break;
    case Qt::MidButton: button = 2; break;
    case Qt::RightButton: button = 3; break;
    case Qt::NoButton: button = 0; break;
    default: button = 0; break;
    }
    setKeyboardModifiers(event);
    m_pGraphicsWindow->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);

    QGraphicsView::mouseReleaseEvent(event);
}

void EventAdapter::mouseDoubleClickEvent(QMouseEvent* event)
{
    QPoint pos = QCursor::pos();
    QList<QGraphicsItem*> listItems = items(mapToScene(pos.x(), pos.y()).toPoint());
    if (listItems.size() > 0)
    {
        return;
    }
    int button = 0;
    switch (event->button())
    {
    case Qt::LeftButton: button = 1; break;
    case Qt::MidButton: button = 2; break;
    case Qt::RightButton: button = 3; break;
    case Qt::NoButton: button = 0; break;
    default: button = 0; break;
    }
    setKeyboardModifiers(event);
    m_pGraphicsWindow->getEventQueue()->mouseDoubleButtonPress(event->x(), event->y(), button);

    QGraphicsView::mouseDoubleClickEvent(event);
}

void EventAdapter::mouseMoveEvent(QMouseEvent* event)
{
    setKeyboardModifiers(event);
    m_pGraphicsWindow->getEventQueue()->mouseMotion(event->x(), event->y());
    QGraphicsView::mouseMoveEvent(event);
}

void EventAdapter::wheelEvent(QWheelEvent* event)
{
    setKeyboardModifiers(event);
    m_pGraphicsWindow->getEventQueue()->mouseScroll(
        event->orientation() == Qt::Vertical ?
        (event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) :
        (event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT));
    QGraphicsView::wheelEvent(event);
}

void EventAdapter::resizeEvent(QResizeEvent *event)
{
    if (scene())
    {
        scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
    }

    const QSize& size = event->size();
    m_pGraphicsWindow->resized(x(), y(), size.width(), size.height());
    m_pGraphicsWindow->getEventQueue()->windowResize(x(), y(), size.width(), size.height());
    m_pGraphicsWindow->requestRedraw();

    const QSize& oldSize = event->oldSize();
    int oldWidth = oldSize.width();
    int oldHeight = oldSize.height();

    int newWidth = size.width();
    int newHeight = size.height();

    double widthChangeRatio = double(newWidth) / double(oldWidth);
    double heigtChangeRatio = double(newHeight) / double(oldHeight);
    double aspectRatioChange = widthChangeRatio / heigtChangeRatio;
    QGraphicsView::resizeEvent(event);
}

void EventAdapter::moveEvent(QMoveEvent* event)
{
    const QPoint& pos = event->pos();
    m_pGraphicsWindow->resized(pos.x(), pos.y(), width(), height());
    m_pGraphicsWindow->getEventQueue()->windowResize(pos.x(), pos.y(), width(), height());

    QGraphicsView::moveEvent(event);
}

void EventAdapter::timerEvent(QTimerEvent *event)
{
    scene()->update();
}

另,若需要触屏操作,则需要重新实现虚函数virtual bool viewportEvent(QEvent* event);

版权声明:本文为博主原创文章,未经博主允许不得转载。

第1课时《Qt osgEarth 编程入门》

1.首先编译osg /osgEarth 源码,配置环境变量,将osg及osgEarth 对应的bin目录加入系统环境中。 2.在QT中的pro文件中进行引用: include(deployment....

利用 MSYS2 及osgEarth 构建三维地球模型(2) osgEarth 与 Qt的结合

上一篇中,我们已经使用傻瓜化的 pacman -S 安装了 openSceneGraph 与 osgEarth 。为了在Qt中导入osgEarth 的窗口,需要安装 osgQt 模块。 注意,这个包...

QT5.4.1+VS2012+OSG3.2.3+osgearth2.7编译问题总结

问题1:在cmake中配置QT变量的时候出现如下问题: CMake Warning at CMakeLists.txt:5 (FIND_PACKAGE):   By not providing "...

osgEarth嵌入QT的QWidget

一直比较推崇QT这个界面库,所以打算把osg嵌入到QT里面做一个QWidget的子控件。 在查阅了官方的osgViewerQT后,决定写一个子类,同时继承osgViewer::Viewer和QGLW...

OSGEarth嵌入Qt的QGraphicsView框架(二)

上一篇处理了QGraphicsView的鼠标、按键事件,本篇接着嵌入OSGEarth。 新建一继承自EventAdapter(一)的类GraphicsView,完成OSGEarth的嵌入工作。...
  • chlk118
  • chlk118
  • 2015年07月08日 21:52
  • 4985

将OSG嵌入QT窗口系统中,实现拖拽界面

将OSG嵌入QT窗口系统中,实现拖拽界面 一、原理 OSG底层使用的是OpenGL图形系统,QT也增加了对OpenGL的支持,因此,可以通过QT的OpenGL模块,实现将OSG窗口嵌入到Q...

osgEarth开发之三维矢量数据的鼠标选择功能

首先,为了可以实现矢量数据的选择,在矢量数据的加载过程中earth文件需要包含 true 否则,选择不成功 或者在程序中添加代码 osgEarth::Features::FeatureSource...

OSGEarth嵌入Qt的QGraphicsView框架(二)

上一篇处理了QGraphicsView的鼠标、按键事件,本篇接着嵌入OSGEarth。 新建一继承自EventAdapter(一)的类GraphicsView,完成OSGEarth的嵌入工作。...
  • chlk118
  • chlk118
  • 2015年07月08日 21:52
  • 4985

OSG嵌入Qt的第二种方式:使用QOpenGLWidget/QGLWidget

几天前有朋友问OSG嵌入Qt的思路。我说整体思路就是用OpenGL的方式来进行OSG的绘制,而正好Qt已经整合了OpenGL的功能,我们可以以此为依托来进行OSG的渲染绘制工作。而在Qt中却有QWid...
  • chlk118
  • chlk118
  • 2015年07月18日 21:00
  • 5687

Qt:Drag-Drop操作在QGraphicsView及Model/View框架下的实现

最近使用到Qt的Drag Drop功能,结合自己的例子写下来给大家分享一下。实现从QTreeView拖动Node到QGraphicsView上,以及QGraphicsView上item之间的拖动。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OSGEarth嵌入Qt的QGraphicsView框架(一)
举报原因:
原因补充:

(最多只允许输入30个字)