首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt -如何在Qt3DWindow上获取鼠标事件

Qt -如何在Qt3DWindow上获取鼠标事件
EN

Stack Overflow用户
提问于 2018-07-19 12:26:32
回答 2查看 2.4K关注 0票数 1

我想让鼠标事件(如鼠标位置)在一个Qt3D窗口,每次我点击窗口内。

我见过这个问题 (在这个论坛上还有同样的问题),但是我的Qt3DWindow不在任何小部件中,所以我不需要EventFilter。

我只是想学习C++和Qt,所以我试图使最简单的程序成为可能。在下面的代码中(我的所有程序都在这段代码中),每次单击Qt3D窗口时,我都想获得鼠标位置,但每次单击时都无法获得调试消息。

据我所知,当程序执行时,只调用一次mouseMoveEvent函数。如果Qt中有这样的东西,我如何在主循环中调用这个函数?

我需要这样做吗?

Qt3DInput::QMouseDevice *mouse = new Qt3DInput::QMouseDevice(scene);

但我该怎么用呢?

代码语言:javascript
复制
#include <QGuiApplication>

#include <Qt3DCore/QEntity>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraLens>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>

#include <Qt3DInput/QInputAspect>

#include <Qt3DRender/QRenderAspect>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/QGoochMaterial>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DExtras/QCuboidMesh>

#include <QMouseEvent>
#include <Qt3DInput/QMouseDevice>
#include <Qt3DInput/QMouseHandler>
#include <Qt3DInput/QMouseEvent>

#include <QDebug>

#include "qt3dwindow.h"

void mouseMoveEvent(Qt3DInput::QMouseEvent *event);

Qt3DCore::QEntity *createScene()
{
    // Root entity
    Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;

    // Material
    //Qt3DRender::QMaterial *material = new Qt3DExtras::QPhongMaterial(rootEntity);
    Qt3DRender::QMaterial *material = new Qt3DExtras::QGoochMaterial(rootEntity);

    //Cube
    Qt3DCore::QEntity *cubeEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QCuboidMesh *cubeMesh = new Qt3DExtras::QCuboidMesh;

    cubeEntity->addComponent(cubeMesh);
    cubeEntity->addComponent(material);

    return rootEntity;
}

int main(int argc, char* argv[])
{
    QGuiApplication app(argc, argv);
    Qt3DExtras::Qt3DWindow view;

    Qt3DCore::QEntity *scene = createScene();

    // Camera
    Qt3DRender::QCamera *camera = view.camera();
    camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
    camera->setPosition(QVector3D(5.0, 5.0, 5.0f));
    camera->setViewCenter(QVector3D(0, 0, 0));

    Qt3DInput::QMouseEvent *e;

    mouseMoveEvent(e);

    view.setRootEntity(scene);
    view.show();

    return app.exec();
}

void mouseMoveEvent(Qt3DInput::QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        qDebug() << "ok";
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-21 08:46:17

你在这里做了一些错事。

首先,我建议您使用子类Qt3DWindow并将场景的设置代码放在那里。这毕竟是视图的责任。主体应该保持简单和干净。当然,不要在视图中添加任何重要的逻辑,但是设置代码应该在视图中(坚持使用)。

接下来,您当然不会收到任何调试消息,因为这里有此检查

代码语言:javascript
复制
if (event->button() == Qt::LeftButton)

但是创建事件时不需要设置按钮,因此event->button()永远不会等同于Qt::LeftButton

我编写了一些示例代码,让您开始了解这些事件:

main.cpp:

代码语言:javascript
复制
#include <QApplication>
#include "clickwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ClickWindow clickWindow;
    clickWindow.show();
    return a.exec();
}

H(,我省略了标题保护以节省一些空间,):

代码语言:javascript
复制
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DCore/QEntity>

class ClickWindow : public Qt3DExtras::Qt3DWindow {
public:
    ClickWindow();
    // Here we say we want to have a custom handling of click events
    void mousePressEvent(QMouseEvent *eventPress) override;

private:
    Qt3DCore::QEntity *createScene();
};

clickwindow.cpp:

代码语言:javascript
复制
#include "clickwindow.h"
#include <QDebug>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QMaterial>
#include <Qt3DExtras/QGoochMaterial>
#include <Qt3DExtras/QCuboidMesh>

ClickWindow::ClickWindow() : Qt3DExtras::Qt3DWindow() {
    // You could also create a dedicated setup method
    setRootEntity(createScene());
    Qt3DRender::QCamera *camera = this->camera();
    camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
    camera->setPosition(QVector3D(5.0, 5.0, 5.0f));
    camera->setViewCenter(QVector3D(0, 0, 0));
}

void ClickWindow::mousePressEvent(QMouseEvent *eventPress) {
    // No need to pass it on to the parent! It will receive it
    // anyway. You can stop event propagation by calling
    // eventPress->accept();
    // This is where the click is received
    qDebug() << "Click!";
}


Qt3DCore::QEntity* ClickWindow::createScene() {
    // Root entity
    Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;

    // Material
    //Qt3DRender::QMaterial *material = new Qt3DExtras::QPhongMaterial(rootEntity);
    Qt3DRender::QMaterial *material = new Qt3DExtras::QGoochMaterial(rootEntity);

    //Cube
    Qt3DCore::QEntity *cubeEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QCuboidMesh *cubeMesh = new Qt3DExtras::QCuboidMesh;

    cubeEntity->addComponent(cubeMesh);
    cubeEntity->addComponent(material);

    return rootEntity;
}

您也可以使用Qt3D类处理单击,并遵循这个示例这里,但在我看来,取决于您的应用程序,这似乎有点过头了。如果您只想接收2D屏幕坐标,我更喜欢上面的解决方案。如果您需要定制输入,例如单击一个对象,我回答了一个关于这个这里的问题,或者如果您只需要单击对象上的3D坐标,就可以使用QObjectPicker类。

如果您遇到任何QML代码,请记住,QML代码只是实例化C++类,也就是说,您可以传递示例,有时只需在命名方面做一些微小的更改,等等。

票数 2
EN

Stack Overflow用户

发布于 2018-07-20 04:11:57

通常,"mouseMoveEvent“是与一个Qwidget绑定的。

这是Qt3DInput::QmouseEvent的源代码

代码语言:javascript
复制
class QT3DINPUTSHARED_EXPORT QMouseEvent : public QObject {
    Q_OBJECT 
private:
    QT_PREPEND_NAMESPACE(QMouseEvent) m_event;  
};

m_event已经包含了鼠标的信息,应该自动处理。

鼠标事件发生时,鼠标按钮被按下或释放在一个小部件,或当鼠标光标被移动。

所以,我不认为您需要创建一个新的Qt3DInput::QMouseDevice。您不应该执行Qt3DInput::QMouseEvent *e;因为小部件将自动获得它。

我不知道如何在不覆盖Qwidget的情况下使用mouseEvent,Qt3DExtras::Qt3DWindow视图应该包含一个默认的mouseMoveEvent()。如果你只想打印一个"ok",我建议你不要写任何关于mouseMoveEvent()的东西。如果您希望在鼠标移动时发生什么事情,则应该重写视图的mouseMoveEvent()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51422690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档