qt - 如果还没有另一个具有 ObjectPicker 的实体,则 ObjectPicker 不适用于动态创建的实体
问题描述
我有一个我通过这个助手类的插槽Scene3D
动态添加一个实体的地方:ObjectPicker
Scene3DViewHelper::addCuboid()
场景3dviewhelper.h:
#ifndef SCENE3DVIEWHELPER_H
#define SCENE3DVIEWHELPER_H
#include <Qt3DCore/QEntity>
class Scene3DViewHelper : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(Qt3DCore::QEntity * rootEntity READ rootEntity WRITE setRootEntity NOTIFY rootEntityChanged)
explicit Scene3DViewHelper(QObject *parent = nullptr);
Qt3DCore::QEntity * rootEntity() const;
public slots:
void setRootEntity(Qt3DCore::QEntity *rootEntity);
void addCuboid();
signals:
void rootEntityChanged(Qt3DCore::QEntity *rootEntity);
private:
Qt3DCore::QEntity *rootEntity_;
};
#endif // SCENE3DVIEWHELPER_H
scene3dviewhelper.cpp:
#include "scene3dviewhelper.h"
#include <Qt3DCore>
#include <Qt3DRender>
#include <Qt3DExtras>
Scene3DViewHelper::Scene3DViewHelper(QObject *parent) : QObject(parent) {}
Qt3DCore::QEntity * Scene3DViewHelper::rootEntity() const { return rootEntity_; }
void Scene3DViewHelper::setRootEntity(Qt3DCore::QEntity *rootEntity)
{
auto old = rootEntity_;
rootEntity_ = rootEntity;
if(rootEntity_ != old) emit rootEntityChanged(rootEntity);
}
void Scene3DViewHelper::addCuboid()
{
if(!rootEntity_) return;
auto cuboidEntity = new Qt3DCore::QEntity(rootEntity_);
auto mat = new Qt3DExtras::QPhongMaterial(cuboidEntity);
mat->setDiffuse(QColor(217, 217, 255));
auto t = new Qt3DCore::QTransform(cuboidEntity);
auto mesh = new Qt3DExtras::QCuboidMesh(cuboidEntity);
auto picker = new Qt3DRender::QObjectPicker(cuboidEntity);
connect(picker, &Qt3DRender::QObjectPicker::clicked, [=] {
qDebug() << "clicked entity" << cuboidEntity;
});
mesh->setXExtent(1);
mesh->setYExtent(1);
mesh->setZExtent(1);
cuboidEntity->addComponent(mat);
cuboidEntity->addComponent(t);
cuboidEntity->addComponent(mesh);
cuboidEntity->addComponent(picker);
}
Scene3DView.qml:
import QtQuick.Scene3D 2.0
import Qt3D.Core 2.0
import Qt3D.Render 2.14
import Qt3D.Input 2.0
import Qt3D.Logic 2.0
import Qt3D.Extras 2.0
import Qt3DUtils 1.0
Scene3D {
id: scene3d
aspects: ["render", "logic", "input"]
hoverEnabled: true // needed for ObjectPickers to handle hover events
property alias helper: helper
data: Scene3DViewHelper {
id: helper
rootEntity: rootEntity
}
entity: Entity {
id: rootEntity
components: [
RenderSettings {
ForwardRenderer {
id: forwardRenderer
camera: mainCamera
}
pickingSettings.pickMethod: PickingSettings.TrianglePicking
pickingSettings.pickResultMode: PickingSettings.AllPicks
pickingSettings.faceOrientationPickingMode: PickingSettings.FrontAndBackFace
},
InputSettings {}
]
Camera {
id: mainCamera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16/9
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d(0.0, 0.0, -4.0)
upVector: Qt.vector3d(0.0, 1.0, 0.0)
viewCenter: Qt.vector3d(0.0, 0.5, 0.0)
}
/*Entity {
id: cuboid0
components: [
CuboidMesh {
xExtent: 1
yExtent: 1
zExtent: 1
},
Transform {
translation.x: -1.5
},
PhongMaterial {
diffuse: Qt.rgba(0.85, 0.85, 1, 1)
},
ObjectPicker {
onClicked: console.log("clicked entity", cuboid0)
}
]
}*/
}
}
main.qml:
import QtQuick.Window 2.13 as QtQuick
ApplicationWindow {
id: mainWindow
visible: true
width: 1000
height: 700
MainMenu {
onAddCuboid: scene3d.helper.addCuboid()
}
Scene3DView {
id: scene3d
anchors.fill: parent
}
}
主.cpp:
#include <QApplication>
#include <QQmlApplicationEngine>
#include "scene3dviewhelper.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
qmlRegisterType<Scene3DViewHelper>("Qt3DUtils", 1, 0, "Scene3DViewHelper");
const QUrl mainUrl(QStringLiteral("qrc:/main.qml"));
QQmlApplicationEngine engine;
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [&](QObject *obj, const QUrl &objUrl) {
if(!obj && mainUrl == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(mainUrl);
return app.exec();
}
问题是它ObjectPicker
不起作用:当我单击长方体时,我应该在控制台上看到“单击的实体 Qt3DCore::QEntity(0x7fa19f005300)”消息,但我没有看到它。
如果我取消对cuboid0
实体的注释,则选取对cuboid0
实体和动态创建的长方体都有效:
qml: 点击实体 Qt3DCore::Quick::Quick3DEntity(0x7fa0d7c025e0)
点击实体 Qt3DCore::QEntity(0x7fa0d6527f10)
在 QML 中创建实体有什么我没有做的void Scene3DViewHelper::addCuboid()
?
解决方案
推荐阅读
- angular - 角度数组数据绑定
- azure - 将静态网站返回到函数代理
- sql-server - SFTP 问题 SSIS
- html - Select2 发布文本而不是值
- javascript - 如何在 React 组件中强制设置属性?
- javascript - 移相器游戏未加载
- string - 使用 JMeter 从响应头中提取位置
- spring-boot - Spring boot 应用程序部署在本地外部 tomcat 9.13 服务器上,但未能在实时 tomcat 服务器 9.13 上部署
- c# - 水晶报表在安装后无法在客户端 PC 上运行
- spring-boot - 将 liquibase 添加到现有 Spring Boot 项目的正确方法