其他分享
首页 > 其他分享> > c – Qt – 如何在Qt3DWindow上获取鼠标事件

c – Qt – 如何在Qt3DWindow上获取鼠标事件

作者:互联网

我希望每次在窗口内单击时,在Qt3D窗口上获取鼠标事件(如鼠标位置).

我见过this question(also the same question on this forum),但我的Qt3DWindow不在任何小部件内,所以我认为我不需要EventFilter.

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

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

我需要做这样的事情吗?

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

但是我该如何使用它呢?

#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";
    }
}

解决方法:

你在这里犯了一些错误.

首先,我建议你继承Qt3DWindow并在那里放置场景的设置代码.毕竟那是观点责任.主要应该保持简单和干净.当然不要在视图中放置任何重要的逻辑,但设置代码应该在那里(坚持模型 – 视图 – 控制器).

接下来,当然你没有得到任何调试消息,因为你有这个检查

if (event->button() == Qt::LeftButton)

但是你创建事件时没有设置按钮,所以event-> button()永远不会等于Qt :: LeftButton.

我写了一些示例代码来帮助您开始这些事件:

main.cpp中:

#include <QApplication>
#include "clickwindow.h"

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

clickwindow.h(我省略了标题保护以节省一些空间):

#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:

#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类处理点击并按照这个例子here,但对我来说,根据你的应用程序,这似乎有点过头了.如果您只是想接收2D屏幕坐标,我更喜欢上面的解决方案.如果您需要自定义输入,例如点击一个对象我回答了有关此here的问题,或者如果您只需要点击一个对象的3D坐标就可以使用QObjectPicker类.

如果您遇到任何QML代码,请记住QML代码只是简单地实例化C类,即您可以传输示例,有时在命名方面稍有微小变化等.

标签:c,qt,qt3d
来源: https://codeday.me/bug/20191003/1847319.html