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