QML StackView 没有啥可推送的
Posted
技术标签:
【中文标题】QML StackView 没有啥可推送的【英文标题】:QML StackView replace nothing to pushQML StackView 没有什么可推送的 【发布时间】:2017-02-10 02:19:18 【问题描述】:如何根据以下示例在页面之间正确切换:
import QtQuick 2.6
import QtQuick.Layouts 1.0
import Qt.labs.controls 1.0
ApplicationWindow
visible: true
width: 640
height: 480
title: qsTr("Hello World")
StackView
id: stack
anchors.fill: parent
initialItem: hal1
Pane
id: hal1
anchors.fill: parent
background: Rectangle
id: mystart
anchors.centerIn: parent
color: "#2196F3"
Pane
id: hal2
anchors.fill: parent
Label
text: qsTr("Second page")
anchors.centerIn: parent
footer: TabBar
id: tabBar
currentIndex: 0
TabButton
text: qsTr("First")
onClicked:
if(stack.currentItem==hal1)
console.log("dont switch hal1 !")
return
stack.replace(hal1)
TabButton
text: qsTr("Second")
onClicked:
if(stack.currentItem==hal2)
console.log("dont switch hal2 !!")
return
stack.replace(hal2)
每当单击第一个选项卡时,我想获得矩形,而第二个选项卡我想获得我的简单标签。 我正在使用 qt labs controls 5.6 谢谢
编辑: 看起来此代码仅适用于调试构建而不适用于发布构建。在 msvc2015 窗口上测试。我不知道为什么会发生这种情况,任何指针?
好的,我附加了另一个示例项目here 以使这个案例更清楚。这里有两个问题,第一件事是我收到警告消息“StackView replace nothing to push”以及调试和发布版本之间的不一致行为。调试构建工作正常,我在发布构建时得到了意外的结果。
【问题讨论】:
应用程序启动时hal1
已经在堆栈上。当您按First
时,您正试图用hal1
替换hal1
,这是没有意义的。
@folibis,感谢您指出这一点。我已经解决了这个问题,并且行为仍然相同。我在这里看到了非常奇怪的不一致行为。无论如何我已经在这里提交了关于这个案例的错误报告bugreports.qt.io/browse/QTBUG-58765
对我来说,我认为使用替换 StackView
并没有多大意义,因为堆叠容器的正确逻辑是推送。可能你需要SwipeView
或类似的东西。
我已经使用替换功能编写了许多 qml 东西,根据一些文档,这里的替换意味着简单的弹出“快捷方式”然后推送项目。我真的很喜欢这个:)。我想通过加载必要的页面来最小化内存消耗,而 StackView 是我真正的致命工具箱:)
正如@folibis 指出的那样,StackView
的使用似乎很奇怪,因为它看起来不像你堆叠任何东西。提到的SwipeView
还试图通过只加载最多三页来保持低内存消耗,以实现平滑过渡。你的 StackView
不是这样 - 对象是在开始时创建的,永远保持活动状态,只有父母身份由 StackView
控制
【参考方案1】:
虽然我不清楚您的问题,但由于 cmets 太有限,无法解决您的代码的许多问题,因此我尝试回答。
首先进行编辑:
编辑:看起来此代码仅适用于调试构建而不适用于发布构建。在 msvc2015 窗口上测试。我不知道为什么会发生这种情况,任何指针?
因此,您的两个构建设置之间需要存在一些实质性差异。 检查差异,尤其是在构建目录中。任何挥之不去的文件,可能不应该来自旧版本? 一切都正确编译了吗?
然后到你的分层:
您的第一层是 StackView 在上面你有 hal1 你上面有 hal2那么你就有了initialItem
集合,它将hal1
重生为StackView
hal2
保持在顶部,直到您将其显示在 StackView
中,因此您应该首先看到 hal2
。
然后是您对内存消耗的误解:StackView
不会最小化内存消耗。
当您在StackView
上推送某些内容时,它只会重新设置为它的父级,并设置为可见。将其弹出时,它会重新设置为原始父级,并变为不可见。要验证我的声明,请记录 Component.onCompleted
和 Component.onDestruction
。第一次发生在启动时,后者发生在应用程序关闭时,而不是在页面被推送或弹出时。因此内存消耗一直高。防止这种情况的唯一方法是动态创建它们。编辑正如 BaCaRoZzo 指出的那样,在使用 StackView
时保持低内存是重要的。可以做到,例如通过传递Component
而不是静态创建的Item
。在这种情况下,StackView
负责创建,一旦从堆栈中弹出,对象就会被销毁。
folibis 提到的SwipeView
让事情变得更容易一些。由于它的default property 是Component
类型,所以您编写的SwipeView ... here ...
的所有内容都不会立即实例化,而是存储为组件,仅在需要时才实例化。这是在显示时,或可能很快显示(currentItem 的左侧或右侧)。所以我们可以看到,从内存消耗的角度来看,...View
s 都可以有效地使用。不过,用法有不同的风格,SwipeView
和 StackView
的语义不同。通常SwipeView
看起来更自然,当有多个页面时并行 而StackView
是要走的路,当你完全按照它的名字所暗示的那样做时:stack Items
当谈到要走的路时:你为什么选择Qt.labs.controls
而不是QtQuick.Controls 2.0
?与labs
-version 相比,它们往往更稳定,并且行为应该不太可能因其他版本而改变。
现在,我希望我对您有所帮助,即使我可能无法解决您的问题,因为您尚未在问题中说明。
【讨论】:
因为我们现在只讨论 2 个对象,是的:内存消耗是相同的,因为SwipeView
在内存中最多可以容纳三个对象。但是SwipeView
的default property
似乎是default property Component
,即使您还没有这样做,它也将所有内容都包装在Component
中。这意味着:SwipeView ... Component Item ...
的结果与SwipeView ... Item ...
相同。在这两种情况下,Item
仅在需要时创建(显示,或显示的旁边)
我已经更新了我的问题以使其更清晰。这对你来说更有意义吗?以上是关于QML StackView 没有啥可推送的的主要内容,如果未能解决你的问题,请参考以下文章
QML StackView:动态更改replaceEnter/Exit动画