Qt5 - QML:触发后按钮不显示 [英] Qt5 - QML: Button does not show up after triggered

查看:78
本文介绍了Qt5 - QML:触发后按钮不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个使用 Qt5-QML 的项目.为了缩小问题,我准备了一个复制问题的小例子.

1) 我在 Page1 上有一个应用程序.它带有一个 Button,如下面的打印屏幕所示:

2) 用户按下按钮后,将进入下图所示的 Page2,其中带有不同的 Buttons.假设 Button A 这是用户的选择:

3)Page1代表的最终画面是正确的选择,也就是被选中的按钮

问题我的问题是,在用户选择第 2 点上的选项并返回 Page1 后,Button 应该出现在Page1 位于打开对话框窗口的 Page1 中间,在我的例子中,一个 WebEngineView 只与那个 Button 相关>.当然,如果用户在 Page2 上选择 Button 3,回到 Page1 应该有另一个 Button 打开另一个与 Button 3 相关的对话框,它总是一个 WebEngineView.

我看不到 Button 和相关对话框.

预期的结果是下面的打印屏幕:

在出现问题的代码片段下方:

ma​​in.qml

导入QtQuick 2.12导入 QtQuick.Controls 2.12应用程序窗口{可见:真实宽度:640高度:480标题:qsTr("Conn")属性 Page1 page1:Page1 {}属性 Page2 page2:Page2 {}Component.onCompleted:{page2.onButtonClicked.connect(function(buttonId, buttonName) {page1.mytext.text = buttonId;page1.mytext.text = buttonName;mystackview.pop();});}//只有在用户选择了`Page2` 上的选项后,这些按钮才会出现按钮 {id:对话ALayout.fillWidth: 真文本:打开对话框 A"}按钮 {id:对话框BLayout.fillWidth: 真文本:打开对话框 B"}按钮 {id:对话CLayout.fillWidth: 真文本:打开对话框 C"}堆栈视图{编号:mystackviewanchors.fill:父级初始项目:第 1 页}}

page1.qml

导入QtQuick 2.12导入 QtQuick.Controls 2.12页 {属性别名 mytext: mytext按钮 {编号:按钮 1文字:选择"anchors.left: parent.leftanchors.right: parent.rightanchors.top: parent.top已点击:{mystackview.push(page2);}}文本 {编号:我的文本anchors.top: button1.bottomanchors.left: parent.leftanchors.right: parent.rightanchors.bottom: parent.bottomfont.bold: 真font.pointSize: 30}}

page2.qml

导入QtQuick 2.12导入 QtQuick.Controls 2.12导入 QtQuick.Layouts 1.12页 {信号 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");});}列布局{id:我的按钮anchors.fill:父级间距:5按钮 {编号:按钮 1Layout.fillWidth: 真Layout.fillHeight: 真文字:A"}按钮 {编号:button2Layout.fillWidth: 真Layout.fillHeight: 真文字:B"}按钮 {编号:button3Layout.fillWidth: 真Layout.fillHeight: 真文字:C"}}

到目前为止我尝试过的:

1) 我遇到了以下

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.

解决方案

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

这篇关于Qt5 - QML:触发后按钮不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆