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
}
}
}