【问题标题】: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 控制

标签: javascript qt qml qtquick2 qt5.6


【解决方案1】:

虽然我不清楚您的问题,但由于 cmets 太有限,无法解决您的代码的许多问题,因此我尝试回答。

首先进行编辑:

编辑:看起来此代码仅适用于调试构建而不适用于发布构建。在 msvc2015 窗口上测试。我不知道为什么会发生这种情况,任何指针?

因此,您的两个构建设置之间需要存在一些实质性差异。 检查差异,尤其是在构建目录中。任何挥之不去的文件,可能不应该来自旧版本? 一切都正确编译了吗?

然后到你的分层:

  • 您的第一层是 StackView
  • 在上面你有 hal1
  • 你上面有 hal2

那么你就有了initialItem 集合,它将hal1 重生为StackView hal2 保持在顶部,直到您将其显示在 StackView 中,因此您应该首先看到 hal2

然后是您对内存消耗的误解:
StackView 不会最小化内存消耗。 当您在StackView 上推送某些内容时,它只会重新设置为它的父级,并设置为可见。将其弹出时,它会重新设置为原始父级,并变为不可见。要验证我的声明,请记录 Component.onCompletedComponent.onDestruction。第一次发生在启动时,后者发生在应用程序关闭时,而不是在页面被推送弹出时。因此内存消耗一直。防止这种情况的唯一方法是动态创建它们。
编辑正如 BaCaRoZzo 指出的那样,在使用 StackView 时保持低内存是重要的。可以做到,例如通过传递Component 而不是静态创建的Item。在这种情况下,StackView 负责创建,一旦从堆栈中弹出,对象就会被销毁。

folibis 提到的SwipeView 让事情变得更容易一些。由于它的default propertyComponent 类型,所以您编写的SwipeView { ... here ...} 的所有内容都不会立即实例化,而是存储为组件,仅在需要时才实例化。这是在显示时,或可能很快显示(currentItem 的左侧或右侧)。所以我们可以看到,从内存消耗的角度来看,...Views 都可以有效地使用。不过,用法有不同的风格,SwipeViewStackView 的语义不同。通常SwipeView 看起来更自然,当有多个页面时并行StackView 是要走的路,当你完全按照它的名字所暗示的那样做时:stack Items

当谈到要走的路时:你为什么选择Qt.labs.controls而不是QtQuick.Controls 2.0?与labs-version 相比,它们往往更稳定,并且行为应该不太可能因其他版本而改变。

现在,我希望我对您有所帮助,即使我可能无法解决您的问题,因为您尚未在问题中说明。

【讨论】:

  • 因为我们现在只讨论 2 个对象,是的:内存消耗是相同的,因为SwipeView 在内存中最多可以容纳三个对象。但是SwipeViewdefault property 似乎是default property Component,即使您还没有这样做,它也将所有内容都包装在Component 中。这意味着:SwipeView { ... Component { Item {} } ... } 的结果与SwipeView { ... Item {} ...} 相同。在这两种情况下,Item 仅在需要时创建(显示,或显示的旁边)
  • 我已经更新了我的问题以使其更清晰。这对你来说更有意义吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多