每次在窗口内部单击时,我想在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";
}
}
答案 0 :(得分:2)
您在这里做错了几件事。
首先,我建议您继承Qt3DWindow
的子类,然后在此处放置场景的设置代码。毕竟那是意见的责任。主体应保持简单清洁。当然,不要在视图中放置任何重要的逻辑,但是设置代码应该在那里(坚持使用Model-View-Controller)。
接下来,您当然不会收到任何调试消息,因为您已经在此处进行了检查
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 ++类,即,您可以传输示例,有时在命名上进行较小的更改等。
答案 1 :(得分:0)
通常,“ 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()
。
如果您只想打印出“确定”,我建议您不要写任何关于mouseMoveEvent()
的内容。如果希望在移动鼠标时发生某些情况,则应覆盖视图的mouseMoveEvent()
。