Qt5 - QML:触发后按钮不显示
Qt5 - QML: Button does not show up after triggered
我正在编写一个使用 Qt5-QML
的项目。为了缩小问题,我准备了一个复制问题的小例子。
1) 我在 Page1
上有一个应用程序。它带有一个 Button
,如下面的打印屏幕所示:
2) 用户按下按钮后继续 Page2
,如下所示,其中包含不同的 Buttons
。假设 Button A
这是用户的选择:
3)最终画面Page1
是正确的选择,也就是选择的按钮
我遇到的问题是,在用户选择第 2) 点的选项并返回 Page1
后,Button
应该出现在 Page1
在 Page1
中间打开一个对话框 window,在我的例子中 WebEngineView
只与那个 Button
相关。
当然,如果用户在 Page2
上选择 Button 3
,返回 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) 我遇到了以下 source 这对理解组件的 style
很有用。这就是我在代码中使用 Component.onCompleted:
的原因。这在触发 Page2
处的按钮方面做得很好。我以为我也可以对其他人使用相同的哲学,但他们没有出现。
2) This source 对我理解组件的属性很有用,特别是在如何在单击时突出显示的示例中。我认为这是我能找到的最接近我正在做的事情。
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();
});
这连接到page2.qml上的signal
如下图:
signal onButtonClicked(var buttonId, var buttonName)
为什么我在 QML
应用程序的 Page1
上返回后看不到 Button
?
非常感谢您指出正确的方向来解决这个问题。
正如我在评论中提到的,"Open Dialog" 按钮总是被堆栈视图隐藏。如果他们没有被隐藏,他们无论如何都需要一些标志来指示他们是否应该可见,基于 Page2
.
上的选择。
与您的 MRE 的现有结构保持一致,这是一种可行的方法。我已将 "Open Dialog" 按钮移动到 Page1
,因为这似乎最有意义,但它们也可以在某个单独的页面上,或者如果那里有一些布局,则并入 main.qml这允许。我还从 Page1
建立了一个 signal/slot 连接以触发 main.qml 中的 Page2
加载(而不是直接尝试访问 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
}
}
}
我正在编写一个使用 Qt5-QML
的项目。为了缩小问题,我准备了一个复制问题的小例子。
1) 我在 Page1
上有一个应用程序。它带有一个 Button
,如下面的打印屏幕所示:
2) 用户按下按钮后继续 Page2
,如下所示,其中包含不同的 Buttons
。假设 Button A
这是用户的选择:
3)最终画面Page1
是正确的选择,也就是选择的按钮
我遇到的问题是,在用户选择第 2) 点的选项并返回 Page1
后,Button
应该出现在 Page1
在 Page1
中间打开一个对话框 window,在我的例子中 WebEngineView
只与那个 Button
相关。
当然,如果用户在 Page2
上选择 Button 3
,返回 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) 我遇到了以下 source 这对理解组件的 style
很有用。这就是我在代码中使用 Component.onCompleted:
的原因。这在触发 Page2
处的按钮方面做得很好。我以为我也可以对其他人使用相同的哲学,但他们没有出现。
2) This source 对我理解组件的属性很有用,特别是在如何在单击时突出显示的示例中。我认为这是我能找到的最接近我正在做的事情。
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();
});
这连接到page2.qml上的signal
如下图:
signal onButtonClicked(var buttonId, var buttonName)
为什么我在 QML
应用程序的 Page1
上返回后看不到 Button
?
非常感谢您指出正确的方向来解决这个问题。
正如我在评论中提到的,"Open Dialog" 按钮总是被堆栈视图隐藏。如果他们没有被隐藏,他们无论如何都需要一些标志来指示他们是否应该可见,基于 Page2
.
与您的 MRE 的现有结构保持一致,这是一种可行的方法。我已将 "Open Dialog" 按钮移动到 Page1
,因为这似乎最有意义,但它们也可以在某个单独的页面上,或者如果那里有一些布局,则并入 main.qml这允许。我还从 Page1
建立了一个 signal/slot 连接以触发 main.qml 中的 Page2
加载(而不是直接尝试访问 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
}
}
}