osgWidget::Box 和窗口移动的案例

osgWidget::Box 是 OpenSceneGraph 中的一个小部件,用于在场景图中显示 GUI 元素。下面的示例代码演示了如何使用 osgWidget::Box 在场景图中添加一个简单的按钮,并实现根据鼠标位置自动调整窗口位置。

#include <osg/Node>
#include <osgViewer/Viewer>
#include <osgWidget/WindowManager>
#include <osgWidget/Box>
#include <QPushButton>

int main(int argc, char** argv)
{
    // 创建 OpenSceneGraph 视窗和场景图
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Group> root = new osg::Group();
    viewer.setSceneData(root.get());

    // 创建 osgWidget 窗口管理器
    osg::ref_ptr<osgWidget::WindowManager> wm = new osgWidget::WindowManager(&viewer, 800, 600);

    // 创建一个 osgWidget::Box,作为容器放置 Qt 按钮
    osg::ref_ptr<osgWidget::Box> box = new osgWidget::Box();
    box->setAbsorbEvents(true);
    box->setColor(osg::Vec4(1.0, 1.0, 1.0, 0.8));
    box->setOrigin(100, 100);               // 初始位置
    box->setHorizAlign(osgWidget::Box::HA_LEFT);
    box->setVertAlign(osgWidget::Box::VA_BOTTOM);
    box->setSize(200, 100);
    wm->addChild(box);

    // 创建一个 Qt 按钮,并将其添加到 osgWidget::Box 容器中
    QPushButton* button = new QPushButton("Click me!", box.get());
    button->setGeometry(50, 25, 100, 50);

    // 根据鼠标位置自动调整窗口位置
    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    viewer.addEventHandler(new osgViewer::StatsHandler());
    viewer.addEventHandler(new osgWidget::MouseHandler(wm.get()));
    viewer.addEventHandler(new osgWidget::ResizeHandler(wm.get()));

    osgWidget::MouseMoveCallback* callback = new osgWidget::MouseMoveCallback(box.get(), wm.get());
    viewer.addEventHandler(callback);

    // 将 osgWidget 窗口管理器添加到场景图中
    root->addChild(wm);

    // 运行 OpenSceneGraph 视窗
    return viewer.run();
}

上述代码中,我们创建了一个名为 box 的 osgWidget::Box 容器,并使用 osgViewer::WindowSizeHandler、osgViewer::StatsHandler、osgWidget::MouseHandler 和 osgWidget::ResizeHandler 来处理窗口大小变化和鼠标事件。然后创建了一个名为 button 的 Qt 按钮,并将其设置为 box 的子控件。

接下来,我们定义了一个名为 callback 的 osgWidget::MouseMoveCallback 对象,并将其作为事件处理程序添加到场景图中。该回调函数会在鼠标移动时被调用,根据当前鼠标位置自动调整窗口的位置。

class MouseMoveCallback : public osgGA::GUIEventHandler
{
public:
    MouseMoveCallback(osgWidget::Box* box, osgWidget::WindowManager* wm)
        : m_box(box), m_wm(wm) {}

    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
    {
        if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE)
        {
            // 获取鼠标位置
            int mx = ea.getX();
            int my = m_wm->getScreenHeight() - ea.getY();

            // 调整窗口位置
            int bx = mx + 50;
            int by = my - 25;
            m_box->setOrigin(bx, by);

            return true;
        }
        return false;
    }

private:
    osgWidget::Box* m_box;
    osgWidget::WindowManager* m_wm;
};

上述代码中,我们定义了一个名为 MouseMoveCallback 的类,继承自 osgGA::GUIEventHandler,并实现了 handle 函数。该函数会在鼠标移动时被调用,根据当前鼠标位置计算出新的窗口位置,并通过 m_box->setOrigin 函数来设置窗口位置。

需要注意的是,osgWidget::Box 的坐标系统是相对于屏幕左上角的,因此需要将鼠标位置 y 坐标从屏幕顶部转换到底部。同时,还需要将按钮的大小(本例中为 100x50)考虑在内,以确保窗口不会覆盖按钮。

猜你喜欢

转载自blog.csdn.net/vcit102/article/details/130315294
Box