Qt5 - QML: кнопка не отображается после запуска

Я пишу проект, в котором используется Qt5-QML. Чтобы уменьшить проблему, я подготовил небольшой пример, который воспроизводит проблему.

1) У меня есть приложение наPage1. Это несетButton как показано на приведенном ниже экране печати:

запускать

2) После того, как пользователь нажмет, кнопка загоритсяPage2 показано ниже, которое несет разные Buttons. СкажемButton A это выбор пользователя:

кнопки

3) Последний экран представленPage1 правильный выбор, это кнопка, выбранная

правильный выбор

У меня проблема в том, что после того, как пользователь выберет вариант в пункте 2) и вернется кPage1 а Button должен появиться на Page1 в середине Page1 который открывает диалоговое окно, в моем случае WebEngineView только в связи с этим Button. Конечно, если пользователь выбираетButton 3 на Page2, обратно Page1 должен быть другой Button который открывает другой диалог, связанный с Button 3 и это всегда WebEngineView.

Я не вижу Button и соответствующий диалог.

Ожидаемый результат - это экран печати ниже:

Ниже фрагмент кода, в котором содержится проблема:

main.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Conn")
    property Page1 page1: Page1 {}
    property Page2 page2: Page2 {}
    Component.onCompleted: {
        page2.onButtonClicked.connect(function(buttonId, buttonName) {
            page1.mytext.text = buttonId;
            page1.mytext.text = buttonName;
            mystackview.pop();
        });
    }

// These buttons should appear only after the user selects the choices on `Page2` 
    Button {
        id: dialogA
        Layout.fillWidth: true
        text: "Open Dialog A"
    }
    Button {
        id: dialogB
        Layout.fillWidth: true
        text: "Open Dialog B"
    }
    Button {
        id: dialogC
        Layout.fillWidth: true
        text: "Open Dialog C"
    }

    StackView {
        id: mystackview
        anchors.fill: parent
        initialItem: page1
    }
}

page1.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
Page {
    property alias mytext: mytext
    Button {
        id: button1
        text: "Select"
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.top: parent.top
        onClicked: {
            mystackview.push(page2);
        }
    }
    Text {
        id: mytext
        anchors.top: button1.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        font.bold: true
        font.pointSize: 30
    }
}

page2.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

Page {
    signal onButtonClicked(var buttonId, var buttonName)

    Component.onCompleted: {
        button1.clicked.connect(function() {
            onButtonClicked(1, "A");
        });
        button2.clicked.connect(function() {
            onButtonClicked(2, "B");
        });
        button3.clicked.connect(function() {
            onButtonClicked(3, "C");
        });
    }

    ColumnLayout {
        id: mybuttons
        anchors.fill: parent
        spacing: 5
        Button {
            id: button1
            Layout.fillWidth: true
            Layout.fillHeight: true
            text: "A"
        }
        Button {
            id: button2
            Layout.fillWidth: true
            Layout.fillHeight: true
            text: "B"
        }
        Button {
            id: button3
            Layout.fillWidth: true
            Layout.fillHeight: true
            text: "C"
        }
    }

Что я пробовал до сих пор:

1) Я наткнулся на следующий источник, который был полезен для пониманияstyleкомпонента. И по этой причине я использовалComponent.onCompleted:по моему коду. Что хорошо поработало с запуском кнопок наPage2. Я думал, что могу использовать ту же философию и для других, но они не появляются.

2) Этот источник был полезен для меня, чтобы понять свойства компонентов, в частности в примере, как выделить при щелчке. Я думаю, что это самое близкое, что я могу найти для того, что я делаю.

3) Копаясь больше в том, чего я пытаюсь достичь, я пошел дальше и просмотрел официальную документацию, которая, кажется, подталкивает к использованию свойства. onCurrentItemChanged который может быть выбором, поскольку запускает emit свойства сигнала.

ОБНОВЛЕНИЯ

Следующая часть в main.qml используется, чтобы показать, что как только пользователь нажимает одну из трех кнопок, затемpage1 показана буква Buttonто, что было нажито, фактически можно увидеть в пункте 3) процедуры.

Component.onCompleted: {
        page2.onButtonClicked.connect(function(buttonId, buttonName) {
            page1.mytext.text = buttonId;
            page1.mytext.text = buttonName;
            mystackview.pop();
        });

Это связано с signalна page2.qml, как показано ниже:

signal onButtonClicked(var buttonId, var buttonName)

Почему я не вижу Button после того, как я вернусь Page1 моего QMLприменение? Большое спасибо за то, что указали верное направление для решения этой проблемы.

1 ответ

Решение

Как уже упоминалось в моем комментарии, кнопки "Открыть диалог" в любом случае всегда скрыты стеком. Если бы они не были скрыты этим, им в любом случае понадобился бы какой-то флаг, чтобы указать, должны ли они быть видимыми или нет, на основе выбора, сделанного наPage2.

Придерживаясь существующей структуры вашего MRE, вот один из способов, как это могло бы работать. Я переместил кнопки "Открыть диалог" наPage1потому что это кажется наиболее разумным, но они также могут быть на какой-то отдельной странице или включены в main.qml, если там есть какой-то макет, позволяющий это. Также я сделал подключение сигнала / слота отPage1 вызвать Page2загрузить в main.qml (вместо того, чтобы напрямую пытаться получить доступ к объектам в main.qml, что является плохой практикой). Я также удалил текстовую метку изPage1 для упрощения кода. Page2 код остается без изменений, поэтому я его не включаю.

main.qml

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Conn")
    property Page1 page1: Page1 {}
    property Page2 page2: Page2 {}

    Component.onCompleted: {
        page1.selectDialog.connect(function()  {
            mystackview.push(page2);
        });

        page2.onButtonClicked.connect(function(buttonId, buttonName) {
            page1.dialogId = buttonId;
            mystackview.pop();
        });
    }

    StackView {
        id: mystackview
        anchors.fill: parent
        initialItem: page1
    }
}

Page1.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

Page {

    property int dialogId: -1;

    signal selectDialog()

    ColumnLayout {
        anchors.fill: parent
        spacing: 5

        Button {
            id: button1
            text: "Select"
            onClicked: selectDialog()
            Layout.fillWidth: true
        }

        // These buttons should appear only after the user selects the choices on `Page2`
        Button {
            id: dialogA
            text: "Open Dialog A"
            visible: dialogId === 1
            Layout.fillWidth: true
        }
        Button {
            id: dialogB
            text: "Open Dialog B"
            visible: dialogId === 2
            Layout.fillWidth: true
        }
        Button {
            id: dialogC
            text: "Open Dialog C"
            visible: dialogId === 3
            Layout.fillWidth: true
        }
    }
}

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