问题
I am writing a project that is using Qt5-QML
. In order to shrink the problem I prepared a small example that replicates the problem.
1) I have an application on a Page1
. That carries a Button
as shown in the below print screen below:
2) After the user pushes the button goes on Page2
shown below which carries different Buttons
. Let's say Button A
it is the user's choice:
3) The final screen represented by Page1
is the correct choice, which is the the button selected
The problem I have is that after the user selects the choice on point 2) and goes back on Page1
a Button
should appear on Page1
in the middle of the Page1
that opens a dialog window, in my case a WebEngineView
only related to that Button
.
Of course if the user selcts Button 3
on Page2
, back on Page1
there should be another Button
that opens another dialog related to Button 3
and that is always a WebEngineView
.
I can't see the Button
and the related dialog.
The expected result is the print screen below:
Below the snippet of code that carries the problem:
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"
}
}
What I tried so far:
1) I came across the following source which was useful to understand the style
of a component. And that is for this reason that I used Component.onCompleted:
on my code. Which did a good job in triggering the buttons at Page2
. I thought that I could use the same philosophy also for the others but they are not showing up.
2) This source was useful for me to understand the properties of a components, in particular in the example how to highlight on a click. I think this is the most close that I can find for what I am doing.
3) Digging more in what I am trying to achieve I went ahead and went through the official documentation which seems to push for the use of the property onCurrentItemChanged
which could be a choice as triggers the emit
properties of a signal.
UPDATES
The following part in the main.qml is used to show that once the user triggers one of the three buttons, then on page1
it is shown the letter of the Button
that was clicked, in fact it is possible to see it on point 3) of the procedure.
Component.onCompleted: {
page2.onButtonClicked.connect(function(buttonId, buttonName) {
page1.mytext.text = buttonId;
page1.mytext.text = buttonName;
mystackview.pop();
});
This is connected to the signal
on the page2.qml as shown below:
signal onButtonClicked(var buttonId, var buttonName)
Why I can't see the Button
after I go back on Page1
of my QML
application?
Thank you very much for pointing in the right direction to solve this problem.
回答1:
As mentioned in my comment, the "Open Dialog" buttons are always hidden by the stack view anyway. If they weren't hidden by that, they'd in any case need some flag to indicate whether they should be visible or not, based on the selection made on Page2
.
Keeping with the existing structure of your MRE, here's one way it could work. I've moved the "Open Dialog" buttons to Page1
because that seems to make the most sense, but they could also be on some separate page, or incorporated into main.qml if there were some layout there which allowed that. Also I made a signal/slot connection from Page1
to trigger the Page2
load in main.qml (instead of directly trying to access objects in main.qml, which is bad practice). I also removed the text label from Page1
to simplify the code. Page2
code remains unchanged so I do not include it.
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
}
}
}
来源:https://stackoverflow.com/questions/58943381/qt5-qml-button-does-not-show-up-after-triggered