[英]Qt - How to get mouse events on Qt3DWindow
每次我在窗口內單擊時,我都希望在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";
}
}
您在這里做錯了幾件事。
首先,我建議您將Qt3DWindow
子類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
類處理點擊,並在此處遵循此示例,但對我而言,根據您的應用程序,這似乎有點過頭。 如果您只想接收2D屏幕坐標,則希望使用上述解決方案。 如果您需要自定義輸入,例如單擊對象,我在這里回答了有關此問題,或者您只需要單擊對象的3D坐標,則可以使用QObjectPicker類。
如果遇到任何QML代碼,請記住,QML代碼只是將C ++類實例化,即,您可以傳輸示例,有時在命名上進行較小的更改等。
通常,“ 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
; 因為小部件將自動獲取它。
我不知道如何使用mouseEvent而不在Qwidget中覆蓋它,並且Qt3DExtras :: Qt3DWindow視圖應該包含默認的mouseMoveEvent()
。 如果您只想打印一個“確定”,建議您不要寫任何有關mouseMoveEvent()
。 如果希望在移動鼠標時發生某些情況,則應重寫視圖的mouseMoveEvent()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.