Qt3d QML:如何将文本作为覆盖添加到标准示例
Posted
技术标签:
【中文标题】Qt3d QML:如何将文本作为覆盖添加到标准示例【英文标题】:Qt3d QML: how to add Text as overlay to a standard example 【发布时间】:2020-01-25 19:01:16 【问题描述】:这里是长期程序员,但是 QML nube。
我希望从示例开始一个 Qt 项目:“Qt 3D: Shadow Map QML Example”,可以从 QtCreator 中列出的示例中轻松获得。这里还有一个链接:https://doc.qt.io/qt-5/qt3d-shadow-map-qml-example.html
我想首先通过添加 2d 文本对其进行自定义,理想情况下,该文本将保持在屏幕上的固定位置,并随着相机位置/角度的变化保持在视野中。我会满足于能够以任何方式在屏幕上添加一些简单的文本!
从那个例子开始,我添加了一个文件:
Title.qml
import Qt3D.Core 2.12
import Qt3D.Extras 2.13
Entity
id: titleText
components: [ Transform translation: Qt.vector3d(0.0, 10.0, 30.0) ]
Text2DEntity
font.family: "Sans Serif"
font.pointSize: 100
color: "white"
text: "MY TITLE"
width: text.length * font.pointSize*2
height: font.pointSize * 4
然后,在 main.qml 的底部,我尝试将其合并:
import QtQuick 2.1 as QQ2
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
Entity
id: sceneRoot
Camera
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: _window.width / _window.height
nearPlane: 0.1
farPlane: 1000.0
position: Qt.vector3d(0.0, 10.0, 20.0)
viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
upVector: Qt.vector3d(0.0, 1.0, 0.0)
FirstPersonCameraController camera: camera
ShadowMapLight
id: light
components: [
ShadowMapFrameGraph
id: framegraph
viewCamera: camera
lightCamera: light.lightCamera
,
// Event Source will be set by the Qt3DQuickWindow
InputSettings
]
AdsEffect
id: shadowMapEffect
shadowTexture: framegraph.shadowTexture
light: light
// Trefoil knot entity
Trefoil
material: AdsMaterial
effect: shadowMapEffect
specularColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
// Toyplane entity
Toyplane
material: AdsMaterial
effect: shadowMapEffect
diffuseColor: Qt.rgba(0.9, 0.5, 0.3, 1.0)
shininess: 75
// Plane entity
GroundPlane
material: AdsMaterial
effect: shadowMapEffect
diffuseColor: Qt.rgba(0.2, 0.5, 0.3, 1.0)
specularColor: Qt.rgba(0, 0, 0, 1.0)
// -------------------------------------
// Title entity
Title
// -------------------------------------
我确定Title
实体已包含在内。我已经为 onload 和 console.logs() 添加了声音效果来证明这一点(从这篇文章中删除)。我尝试过以各种方式操纵实体,但它从未出现。我认为其他组件必须隐藏它/阻止它/使其不兼容而无法显示...
【问题讨论】:
【参考方案1】:text2D 实体旨在将文本放入 3D 场景中(例如在特定对象上放置一些文本标签)。我认为您只是想将文本作为叠加层放在屏幕上。
这可以通过使用标准的 QML 文本类型来完成。
我修改了您的代码并用 //ADDED 标记了新行。不再需要的行标有 //REMOVED
专业文件:
您需要在 pro 文件中添加 3dextras 模块
QT += 3dextras
main.cpp
通过使用 QQuickView 而不是 Qt3DQuickWindow 来更改您的 main.cpp。原因是scene3D和Qt3DQuickWindow的渲染机制不同。 Scene3D 使用 QML 的渲染器进行渲染,而 Qt3DQuickWindow 将创建一个专用的渲染线程。换句话说:如果您的程序只需要显示 3D 环境,那么坚持使用 Qt3DQuickWindow。 如果您想将文本和按钮放在您的 3D 环境之上,请使用 QQuickView。
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DQuick/QQmlAspectEngine>
#include <QGuiApplication>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickView>//ADDED
int main(int argc, char* argv[])
QGuiApplication app(argc, argv);
//ADDED:
QQuickView view;
view.rootContext()->setContextProperty("_window", &view);
view.setSource(QUrl("qrc:/main.qml"));
view.setWidth(1600);
view.setHeight(900);
view.show();
//REMOVED:
// Qt3DExtras::Quick::Qt3DQuickWindow view;
// view.resize(1600, 800);
// view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
// view.setSource(QUrl("qrc:/main.qml"));
// view.show();
return app.exec();
main.qml
在以下示例中,我使用 Rectangle 作为根,Scene3D 与 Text(在左上角)和 Button 处于同一级别,以展示如何组合标准 QML 类型。
Rectangle
anchors.fill: parent
Scene3D
anchors.fill: parent
focus: true
aspects: ["input", "logic"]
Entity
id: sceneRoot
Camera
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: _window.width / _window.height
nearPlane: 0.1
farPlane: 1000.0
position: Qt.vector3d(0.0, 10.0, 20.0)
viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
upVector: Qt.vector3d(0.0, 1.0, 0.0)
FirstPersonCameraController camera: camera
ShadowMapLight
id: light
components: [
ShadowMapFrameGraph
id: framegraph
viewCamera: camera
lightCamera: light.lightCamera
,
// Event Source will be set by the Qt3DQuickWindow
InputSettings
]
AdsEffect
id: shadowMapEffect
shadowTexture: framegraph.shadowTexture
light: light
// Trefoil knot entity
Trefoil
material: AdsMaterial
effect: shadowMapEffect
specularColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
// Toyplane entity
Toyplane
material: AdsMaterial
effect: shadowMapEffect
diffuseColor: Qt.rgba(0.9, 0.5, 0.3, 1.0)
shininess: 75
// Plane entity
GroundPlane
material: AdsMaterial
effect: shadowMapEffect
diffuseColor: Qt.rgba(0.2, 0.5, 0.3, 1.0)
specularColor: Qt.rgba(0, 0, 0, 1.0)
Text
id: title
text: qsTr("TITLE")
font.family: "Arial"
font.pointSize: 30
color: "black"
anchors.top:parent.top
anchors.left:parent.left
anchors.leftMargin: 20
anchors.topMargin: 20
编辑
这是在 Windows10 上使用 Qt5.13.2 MSVC2015 64 位运行的示例的打印屏幕,也适用于 Qt5.14.0 MSVC2015 64 位
【讨论】:
这看起来是解决烦人问题的完美解决方案。我还没有机会确认这一点,但我会在接下来的几天里解决这个问题。感谢您的帮助! 我知道这种感觉。我一直处于同样的情况......所以你想要的只是将文本放在 Qt3D 场景之上?在那种情况下,它会。最好相应地更改您的第一篇文章的标题。 是的,这非常接近我想要的。我本来希望保留在 3d 世界中移动相机的能力。我不确定这种方法是否允许?如果没有,我会忍受这种损失。不幸的是,这对我来说不太有效。文本出现,但 QtQuick.Scene3D 未呈现。我更新了我的问题以包含我正在使用的确切 QML。如果可能,请为我测试一下?如果它对你有用,也许还有另一个因素在起作用。我希望,我只是有错误的代码。 我在之前的回答中添加了一个工作示例的完整源代码。我希望这有助于学习 Qt3D。 感谢大家的帮助!可以肯定我理解,你确实成功地运行了这个,对吧?好吧,我已经尝试了您的确切代码,但它在我的机器上不起作用。只需在蓝屏上显示 TITLE。我反复检查了 cpp、qml 和 pro。我可以将示例用于原始问题和 QML 3d 场景的标准问题。我已经删除并重新创建了 build 文件夹......在这里完全感到困惑。我最终需要它在合理的范围内跨平台(windows、linux、mac)和跨 Qt 版本工作。我从使用 Qt 5.14 的 Linux (Ubuntu) 开始,以防万一。以上是关于Qt3d QML:如何将文本作为覆盖添加到标准示例的主要内容,如果未能解决你的问题,请参考以下文章
Qt3D:如何将 Scene2D 缩放为与窗口相同的大小(逐像素)?