从另一个 QML 文件打开新的 QML 文件
Posted
技术标签:
【中文标题】从另一个 QML 文件打开新的 QML 文件【英文标题】:Open new QML file from Another QML file 【发布时间】:2020-11-23 15:40:52 【问题描述】:当用户单击test1.qml
内的按钮时,我正在尝试打开test2.qml
文件。
我可以使用 qml StackLayout
、Static Loading
文件和使用 qml Loader
来做到这一点。
// main.qml
Window
width: 400
height: 400
StackLayout
id: myStack
anchors.fill: parent
Test1
Test2
// Test1.qml
Item
width: 400
height: 400
Button
text: "Move Test2"
onClicked:
myStack.currentIndex = 1 // Move to page 2
// Test2.qml
Item
width: 400
height: 400
Button
text: "Move Test1"
onClicked:
myStack.currentIndex = 0 // Move to page 1
但是有没有一种方法可以在不使用 StackLayout 或 Loader 甚至静态包含文件并设置可见性的情况下从另一个 QML 文件打开 .qml 文件?
有没有办法可以使用 QT Quick C++ API 或直接从 QML 加载文件?
【问题讨论】:
"或直接来自 QML" -- 不清楚这意味着什么。StackLayout
和 Loader
都是直接加载其他组件的 QML 方式。您到底在寻找什么?
也许您正在寻找 dynamically 从 JS 代码创建对象?
如果您使用堆栈布局,则很少有限制,例如堆栈中加载的视图无法查看全屏或超出其父级堆栈布局的范围。同样使用加载器并设置可见性,代码不可读。我可以在运行时使用加载器和加载视图。但在我们有任何其他选择之前,它也不能令人信服。
【参考方案1】:
我想你可能正在寻找这个: https://doc.qt.io/qt-5/qtqml-modules-qmldir.html
让我们看一下他们的示例代码:
//Style.qml with custom singleton type definition
pragma Singleton
import QtQuick 2.0
QtObject
property int textSize: 20
property color textColor: "green"
上面是我们想要导入到其他 qml 文件中的自定义类型。
// qmldir declaring the singleton type
module CustomStyles
singleton Style 1.0 Style.qml
上面是我们放入 qmldir 文件的内容。您必须创建一个单独的模块,然后该模块将具有此 qmldir 文件。您必须使用 QtCreator 向导创建一个空文件并将其命名为 qmldir。这是 Qt 模块的一个特性。你说,“这是我的模块的名称,它在 Style.qml 中定义了这个类型”在那个 qmldir 文件中。这几乎就是它所做的一切。您可以在其中定义任意数量的 qml 类型。
// singleton type in use
import QtQuick 2.0
import CustomStyles 1.0
Text
font.pixelSize: Style.textSize
color: Style.textColor
text: "Hello World"
在这里,我们从 CustomStyles 模块导入样式,并在需要的地方使用它。
所以这里发生了什么
创建了一个模块。一个模块基本上就是一个文件夹,里面有一个 .pro 文件和一个 qmldir 文件。您将使用 import 语句导入您的模块。您可能想使用TEMPLATE = subdirs
来创建一个包含多个模块的项目。
Style.qml(仅作为示例)被创建,然后从该模块导出(设置为公共)。您使用模块中的 qmldir 文件设置为 public。
在qml中你要导入qml文件到你里面做
import CustomStyles 1.0
或您在项目中使用的任何模块名称,
然后您可以引用 qmldir 文件中定义的任何 QML 类型,因为它已设置为 public 并且您导入了模块。
因此,不要像在 C++ 中那样考虑 #include 文件,而是更像在 python 中导入模块,然后可以引用该模块中的任何公共类或函数。
如果您想进一步了解如何创建模块,请随时发表评论。您需要创建一个模块,因为导入语句导入模块而不是单个文件。导入模块可以访问从 qmldir 文件中的模块导出的所有文件。
【讨论】:
【参考方案2】:您可以使用JS创建QML对象,参见示例https://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html#creating-a-component-dynamically
【讨论】:
【参考方案3】:首先,我认为不可能以不同于使用 Loader 或静态导入的方式加载 QML 文件。
我能想到的唯一其他方法是直接使用 QML 字段作为一个简单的组件,当它在项目中的相同前缀中时。
所以为了解释: 如果您有一个简单的项目,其中所有 QML 文件都在同一个前缀中。
当您拥有此结构中的所有文件时,您可以直接在此处动态使用其他 QMl 文件。据我所知,这是有效地做到这一点的唯一方法。
代码如下: main.qml
import QtQuick 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.3
Window
width: 400
height: 400
StackLayout
id: myStack
anchors.fill: parent
Test1
Test2
Test1.qml
import QtQuick 2.15
import QtQuick.Controls 2.12
Item
width: 400
height: 400
Button
text: "Move Test2"
onClicked:
myStack.currentIndex = 1 // Move to page 2
Test2.qml
import QtQuick 2.15
import QtQuick.Controls 2.5
Item
width: 400
height: 400
Button
text: "Move Test1"
onClicked:
myStack.currentIndex = 0 // Move to page 1
当我拥有如上图所示的结构时,此代码对我有用。我希望这有点帮助。
【讨论】:
以上是关于从另一个 QML 文件打开新的 QML 文件的主要内容,如果未能解决你的问题,请参考以下文章
如何从另一个 QML 文件调用 QML 文件中定义的 Javascript 函数?
如何在 Cascades、Blackberry 10 中使用 Qt/QML/C++ 从另一个 qml 文件中更改一个 qml 文件中的标签文本?
如何从另一个 QML 访问和控制 ListModel 的内容