我想让鼠标事件(如鼠标位置)在一个Qt3D窗口,每次我点击窗口内。
我见过这个问题 (在这个论坛上还有同样的问题),但是我的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";
}
}发布于 2018-07-21 08:46:17
你在这里做了一些错事。
首先,我建议您使用子类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();
}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类处理单击,并遵循这个示例这里,但在我看来,取决于您的应用程序,这似乎有点过头了。如果您只想接收2D屏幕坐标,我更喜欢上面的解决方案。如果您需要定制输入,例如单击一个对象,我回答了一个关于这个这里的问题,或者如果您只需要单击对象上的3D坐标,就可以使用QObjectPicker类。
如果您遇到任何QML代码,请记住,QML代码只是实例化C++类,也就是说,您可以传递示例,有时只需在命名方面做一些微小的更改,等等。
发布于 2018-07-20 04:11:57
通常,"mouseMoveEvent“是与一个Qwidget绑定的。
这是Qt3DInput::QmouseEvent的源代码
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()。
https://stackoverflow.com/questions/51422690
复制相似问题