转到特定页面后,如何“通过引用”将 SwipeView 的 currentIndex 设置为 TabBar 的 currentIndex?
Posted
技术标签:
【中文标题】转到特定页面后,如何“通过引用”将 SwipeView 的 currentIndex 设置为 TabBar 的 currentIndex?【英文标题】:How to set currentIndex of SwipeView to currentIndex of TabBar "by reference" after going to specific page? 【发布时间】:2017-04-24 00:27:30 【问题描述】:我开始使用 QtQuick Controls 2.0。我有 C++ 的经验和少量的 Qt 经验,但我之前没有使用过 QML。
我有一个TabBar
和一个SwipeView
,它们相互关联。我的意思是,当您在TabBar
上选择一个页面时,SwipeView
会转到该页面。当您从 SwipeView
滑动到页面时,TabBar
会自行更新以反映这一点。
作为学习练习,我决定创建一个按钮,将用户引导至第二页。问题是,我似乎无法找到一种方法来不搞乱TabBar
和SwipeView
之间的链接。
以下代码是我想出的最好的。它正确地转到第二页,当我用TabBar
更改当前页面时,SwipeView
仍然更新。但是,滑动 到新页面不再更新TabBar
。似乎将tabBar.currentIndex
设置为swipeView.currentIndex
仅在使用冒号初始化时具有通过引用设置的效果。这样做是通过值设置等号。如何在保持swipeView.currentIndex == tabBar.currentIndex
不变的同时移动到特定页面?
// main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow
visible: true
width: 640
height: 480
title: qsTr("Hello World")
SwipeView
id: swipeView
anchors.fill: parent
currentIndex: tabBar.currentIndex
Page
Button
text: qsTr("Continue to Page 2")
onClicked:
tabBar.currentIndex = 1;
// this next line merely sets tabBar.currentIndex to 1
tabBar.currentIndex = swipeView.currentIndex
anchors.centerIn: parent
width: text.implicitWidth
height: text.implicitHeight
Page
Label
text: qsTr("Second page")
anchors.centerIn: parent
footer: TabBar
id: tabBar
currentIndex: swipeView.currentIndex
TabButton
text: qsTr("First")
TabButton
text: qsTr( "Second")
C++ 代码只是 Qt Creator 为我提供的默认代码:
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
【问题讨论】:
【参考方案1】:为了在不破坏currentIndex
绑定的情况下移动到下一页或上一页,您可以分别调用incrementCurrentIndex()
或decrementCurrentIndex()
。这些方法是在 Qt 5.8 的 Qt Quick Controls 2.1 中引入的。
鉴于currentIndex
setter 又名。 QQuickContainer::setCurrentIndex()
是一个 slot,你也可以从 QML 中调用 setCurrentIndex()
来跳转到任意页面。这也不会破坏现有的绑定。
Button
onClicked: tabBar.setCurrentIndex(1)
【讨论】:
谢谢。例如,在想要转到第 20 页的情况下,是否最好简单地使用 for 循环和一些基于currentIndex
的数学来到达正确的页面,或者最好像我一样做在我的回答中做了吗?
跳转到任意页面确实需要更复杂的解决方案。它可以是双向信号处理程序,也可以使用Qt.binding()
来恢复绑定。这个讨论让我意识到我们可以简单地允许从 QML 调用setCurrentIndex()
。
原来setCurrentIndex()
实际上是一个槽,所以你已经可以从QML调用它而不会破坏绑定。我们会将其添加到文档中以使其正式化。
这就是我正在寻找的简单解决方案!谢谢;)【参考方案2】:
您可能正在寻找Signals。来自 Qt 文档:
属性更改信号处理程序
当 QML 属性的值出现时,会自动发出信号 变化。这类信号是属性变化信号和信号 这些信号的处理程序以 on
Changed 的形式编写 其中是属性的名称,带有第一个字母 大写。
因此,对于您的示例:
SwipeView
id: swipeView
...
currentIndex: tabBar.currentIndex
onCurrentIndexChanged:
tabBar.currentIndex = currentIndex
...
footer: TabBar
id: tabBar
currentIndex: swipeView.currentIndex
onCurrentIndexChanged:
swipeView.currentIndex = currentIndex
...
这样您就可以简单地设置任何一个的 currentIndex 并放心,由于信号处理程序,它们将保持“链接”。
编辑:
As pointed out by jpnurmi,你也可以像这样使用Qt.binding
:
onClicked:
swipeView.currentIndex = 1;
swipeView.currentIndex = Qt.binding(function() return tabBar.currentIndex)
这将在分配静态值后恢复绑定。
【讨论】:
以上是关于转到特定页面后,如何“通过引用”将 SwipeView 的 currentIndex 设置为 TabBar 的 currentIndex?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 UIPageViewController 跳转到特定页面?
Qt/QML:在加载程序加载后访问 ListView 以跳转到特定项目/页面