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
    

然后,在 ma​​in.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

ma​​in.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();

ma​​in.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:如何将文本作为覆盖添加到标准示例的主要内容,如果未能解决你的问题,请参考以下文章

如何使用qml qt3d(qt)将对象旋转一个角度?

如何在标准GUI应用程序中使用Qt3D进行渲染?

C ++中的Qt3d输入

Qt3D:如何将 Scene2D 缩放为与窗口相同的大小(逐像素)?

覆盖 QML 行的 MouseArea(或自动调整大小的图像+文本)

如何在 Qt3D 中创建撤消/重做操作? [关闭]