Как установить currentIndex SwipeView в currentIndex TabBar "по ссылке" после перехода на конкретную страницу?

Я начинаю с 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();
}

2 ответа

Решение

Чтобы перейти на следующую или предыдущую страницу, не нарушая currentIndex привязки, вы можете позвонить incrementCurrentIndex() или же decrementCurrentIndex() соответственно. Эти методы были введены в Qt Quick Controls 2.1 в Qt 5.8.

Учитывая, что currentIndex сеттер ака. QQuickContainer::setCurrentIndex() это слот, вы также можете позвонить setCurrentIndex() из QML, чтобы перейти на произвольную страницу. Это также не нарушит существующие привязки.

Button {
    onClicked: tabBar.setCurrentIndex(1)
}

Вы могли бы искать сигналы. Из документации Qt:

Обработчики сигналов об изменении свойств

Сигнал генерируется автоматически при изменении значения свойства QML. Этот тип сигнала является сигналом изменения свойства, и обработчики сигналов для этих сигналов записываются в виде вChanged, где - это имя свойства, с первой заглавной буквой.

Итак, для вашего примера:

SwipeView {
    id: swipeView
    ...
    currentIndex: tabBar.currentIndex
    onCurrentIndexChanged: {
        tabBar.currentIndex = currentIndex
    }
...
footer: TabBar {
    id: tabBar
    currentIndex: swipeView.currentIndex
    onCurrentIndexChanged: {
        swipeView.currentIndex = currentIndex
    }
    ...

И таким образом вы можете просто установить currentIndex любого из них и быть уверенным, что они останутся "связанными" из-за обработчиков сигнала.

Редактировать:

Как указывает jpnurmi, вы также можете использовать Qt.binding вот так:

onClicked: {
    swipeView.currentIndex = 1;
    swipeView.currentIndex = Qt.binding(function() {return tabBar.currentIndex})
}

Это восстановит привязку после назначения статического значения.

Другие вопросы по тегам