"visible" property forced to "false"
-
Hi all.
I'm working with Qt Creator 4.8.2 based on Qt 5.12.1
On the display I have to show a series of graphic pages. On each page there are some buttons. Each button is associated to a particular page. Pressing a button, the corresponding page is showed. Each page is loaded by means a "Loader" and "Component" items. The "main.qml" file is the following:ApplicationWindow { id: mainItem visibility: "FullScreen" flags: Qt.WindowFullScreen | Qt.WindowStaysOnTopHint visible: true width: 1024 height: 600 Loader { id:pageA_Loader sourceComponent: pageA_Component active: false visible: false } Component { id:pageA_Component PageA //PageA.qml file { id:idPageA visible: true; onSignalButton1Touched: { rectMain.state = "PageB_STATE" } onSignalButton2Touched: { rectMain.state = "PageC_STATE" } } } Loader { id:pageB_Loader sourceComponent: pageB_Component active: false visible: false } Component { id:pageB_Component PageB //PageB.qml file { id:idPageB visible: true; onSignalButton1Touched: { rectMain.state = "PageA_STATE" } onSignalButton2Touched: { rectMain.state = "PageC_STATE" } } } Loader { id:pageC_Loader sourceComponent: pageC_Component active: false visible: false } Component { id:pageC_Component PageC //PageC.qml file { id:idPageC visible: true; onSignalButton1Touched: { rectMain.state = "PageA_STATE" } onSignalButton2Touched: { rectMain.state = "PageB_STATE" } } } Rectangle { id:rectMain width: 1024 height: 600 color: "transparent" state: "PageA_STATE" // init whit A page states: [ State { name: "" PropertyChanges {target: pageA_Loader; active: false} PropertyChanges {target: pageB_Loader; active: false} PropertyChanges {target: pageC_Loader; active: false} PropertyChanges {target: pageA_Loader; visible: false} PropertyChanges {target: pageB_Loader; visible: false} PropertyChanges {target: pageC_Loader; visible: false} }, State { name: "PageA_STATE" PropertyChanges {target: pageA_Loader; active: true} PropertyChanges {target: pageB_Loader; active: false} PropertyChanges {target: pageC_Loader; active: false} PropertyChanges {target: pageA_Loader; visible: true} PropertyChanges {target: pageB_Loader; visible: false} PropertyChanges {target: pageC_Loader; visible: false} }, State { name: "PageB_STATE" PropertyChanges {target: pageA_Loader; active: false} PropertyChanges {target: pageB_Loader; active: true} PropertyChanges {target: pageC_Loader; active: false} PropertyChanges {target: pageA_Loader; visible: false} PropertyChanges {target: pageB_Loader; visible: true} PropertyChanges {target: pageC_Loader; visible: false} }, State { name: "PageC_STATE" PropertyChanges {target: pageA_Loader; active: false} PropertyChanges {target: pageB_Loader; active: false} PropertyChanges {target: pageC_Loader; active: true} PropertyChanges {target: pageA_Loader; visible: false} PropertyChanges {target: pageB_Loader; visible: false} PropertyChanges {target: pageC_Loader; visible: true} } ] } }
In my real application there are many pages, not only page A, B and C. Each qml file "PageA.qml", "PageB.qml", "PageC.qml", ... etc, has the item named "myHeader.qml" (qml file with some rectangles and images). I don't know why "myHeader.qml" is showed on all pages except one. In this page (where "myHeader.qml" is not showed), the "visible" property of "myHeader.qml" is forced to false even if I set the "visible" property to true.
Can someone tell me why this happens and what is the solution?
Many thanks -
It doesn't look like a Loader per page is necessary. One should be sufficient, and will simplify the design. Use a PropertyChange to alter the Loader.sourceComponent, or set it directly from the Button's clicked signal handler.
It would also likely be easier and cleaner to rename myHeader.qml to MyHeader.qml, and use it as an ordinary component. I can't be sure, because the example doesn't reference it. A simpler code snippet would also help. It's nearly 200 lines, but could probably be expressed in a quarter of that.
You can try defining a signal handler for the component instance's visible property, set a breakpoint on it, and then examine the stack trace.
-
In my real application there are several situation where is necessary to preserve data associated to other pages when a page is showed. For this reason I used a Loader for each Component. For example, supposing you want to preserve the PageB data when the PageC is showed, the code is the following:
State { name: "PageC_STATE" PropertyChanges {target: pageA_Loader; active: false} PropertyChanges {target: pageB_Loader; active: true} PropertyChanges {target: pageC_Loader; active: true} PropertyChanges {target: pageA_Loader; visible: false} PropertyChanges {target: pageB_Loader; visible: false} PropertyChanges {target: pageC_Loader; visible: true} }
The "myHeader.qml" name is an example, the real qml file is named "BloccoIntestazione1.qml" and its code is the following:
import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Controls 2.4 import QtQuick.Layouts 1.11 import QtQuick.Controls 2.4 as Controls import "MyConstants.js" as Constants //==================== // //==================== Rectangle { id: intestazione property alias image1Intestazione: iconImage1.source property alias text1Intestazione: label1.text property alias image2Intestazione: iconImage2.source property alias text2Intestazione: label2.text visible: true implicitWidth: parent.implicitWidth implicitHeight: 70 color: "#092946" anchors.top: parent.top anchors.topMargin: 0 anchors.left: parent.left anchors.leftMargin: 0 anchors.right: parent.right anchors.rightMargin: 0 //==================== // //==================== Rectangle { id: rect implicitWidth: parent.implicitWidth implicitHeight: parent.implicitHeight anchors.top: parent.top anchors.topMargin: 0 anchors.left: parent.left anchors.leftMargin: 0 anchors.right: parent.right anchors.rightMargin: 0 color: "#092946" //==================== // //==================== Image { id: iconImage2 fillMode: Image.PreserveAspectFit source: "" anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: parent.left anchors.leftMargin: 10 } RowLayout { id: rowLayout anchors.centerIn: parent spacing: 20 //==================== // //==================== Image { id: iconImage1 fillMode: Image.PreserveAspectFit source: "" Layout.preferredHeight: rect.height } //==================== // //==================== Text { id: label1 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter Layout.maximumHeight: rect.height color: "white" font.family: "Clearface Gothic LH 75" font.pixelSize: 50 minimumPixelSize: 10 font.bold: true fontSizeMode:Text.Fit text: "" lineHeight: 0.8 } } //==================== // //==================== Text { id: label2 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter Layout.maximumHeight: rect.height anchors.right: parent.right anchors.rightMargin: 10 anchors.verticalCenter: parent.verticalCenter color: "white" font.family: "Clearface Gothic LH 75" font.pixelSize: 50 minimumPixelSize: 10 font.bold: true fontSizeMode:Text.Fit text: "" lineHeight: 0.8 } } //==================== // //==================== Rectangle { id: line1 anchors.top: rect.bottom anchors.topMargin: 0 anchors.left: parent.left anchors.leftMargin: 10 anchors.right: parent.right anchors.rightMargin: 10 implicitWidth: intestazione.implicitWidth-20 implicitHeight: 3 border.color: "#FFFFFF" border.width: 3 radius: 0 } }
-
In my real application there are several situation where is necessary to preserve data associated to other pages when a page is showed. For this reason I used a Loader for each Component. For example, supposing you want to preserve the PageB data when the PageC is showed, the code is the following:
State { name: "PageC_STATE" PropertyChanges {target: pageA_Loader; active: false} PropertyChanges {target: pageB_Loader; active: true} PropertyChanges {target: pageC_Loader; active: true} PropertyChanges {target: pageA_Loader; visible: false} PropertyChanges {target: pageB_Loader; visible: false} PropertyChanges {target: pageC_Loader; visible: true} }
The "myHeader.qml" name is an example, the real qml file is named "BloccoIntestazione1.qml" and its code is the following:
import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Controls 2.4 import QtQuick.Layouts 1.11 import QtQuick.Controls 2.4 as Controls import "MyConstants.js" as Constants //==================== // //==================== Rectangle { id: intestazione property alias image1Intestazione: iconImage1.source property alias text1Intestazione: label1.text property alias image2Intestazione: iconImage2.source property alias text2Intestazione: label2.text visible: true implicitWidth: parent.implicitWidth implicitHeight: 70 color: "#092946" anchors.top: parent.top anchors.topMargin: 0 anchors.left: parent.left anchors.leftMargin: 0 anchors.right: parent.right anchors.rightMargin: 0 //==================== // //==================== Rectangle { id: rect implicitWidth: parent.implicitWidth implicitHeight: parent.implicitHeight anchors.top: parent.top anchors.topMargin: 0 anchors.left: parent.left anchors.leftMargin: 0 anchors.right: parent.right anchors.rightMargin: 0 color: "#092946" //==================== // //==================== Image { id: iconImage2 fillMode: Image.PreserveAspectFit source: "" anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: parent.left anchors.leftMargin: 10 } RowLayout { id: rowLayout anchors.centerIn: parent spacing: 20 //==================== // //==================== Image { id: iconImage1 fillMode: Image.PreserveAspectFit source: "" Layout.preferredHeight: rect.height } //==================== // //==================== Text { id: label1 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter Layout.maximumHeight: rect.height color: "white" font.family: "Clearface Gothic LH 75" font.pixelSize: 50 minimumPixelSize: 10 font.bold: true fontSizeMode:Text.Fit text: "" lineHeight: 0.8 } } //==================== // //==================== Text { id: label2 verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter Layout.maximumHeight: rect.height anchors.right: parent.right anchors.rightMargin: 10 anchors.verticalCenter: parent.verticalCenter color: "white" font.family: "Clearface Gothic LH 75" font.pixelSize: 50 minimumPixelSize: 10 font.bold: true fontSizeMode:Text.Fit text: "" lineHeight: 0.8 } } //==================== // //==================== Rectangle { id: line1 anchors.top: rect.bottom anchors.topMargin: 0 anchors.left: parent.left anchors.leftMargin: 10 anchors.right: parent.right anchors.rightMargin: 10 implicitWidth: intestazione.implicitWidth-20 implicitHeight: 3 border.color: "#FFFFFF" border.width: 3 radius: 0 } }
@naprile said in "visible" property forced to "false":
In my real application there are several situation where is necessary to preserve data associated to other pages when a page is showed.
Store it in an object dedicated to the purpose of holding state. That might be a QAbstractItemModel, or just a QtObject with a property containing an array of objects. Either way, having one object cover several states with a fan in / fan out pattern is easier to reason about than N objects potentially connecting with N-1 other objects. Unless there are multiple items to be dynamically loaded concurrently, having multiple Loader instances seems like a poor choice.
The "myHeader.qml" name is an example, the real qml file is named "BloccoIntestazione1.qml" and its code is the following:
Whatever you call it, presenting code that corresponds to the question is important. Code that is brief and focused is also critical. This is, again, nearly 200 lines of code. I'm presuming that the blank lines,
//===...
comments, font selection, etc are not part of the core question. Every line has a cost for the reader, important or not. -
I'm not an expert Qt programmer. Do you think my problem is due to having used one Loader for each page or can be due to another reason?
Thanks.@naprile said in "visible" property forced to "false":
I'm not an expert Qt programmer. Do you think my problem is due to having used one Loader for each page or can be due to another reason?
Thanks.It could be. Extra code is extra complexity to understand. Even if simplifying doesn't fix the issue, it should make it easier to spot.