QT QML make invisible button in other Rectangle

Question:

I want to hide the button when navigating from the first page to the second page, But when I add this line button_1.visible: false in the code, it doesn’t work.

main.qml:

import QtQuick 2.15
import QtMultimedia 5.0
import QtQuick.Controls 2.15
import QtQuick.Dialogs 1.0
import QtQuick.Layouts 1.2
import Qt.labs.folderlistmodel 2.1
ApplicationWindow{
    title : qsTr("Swipe view")
    visible: true
    width : 800
    height: 480
    color: "black"
    /*------------------------- Swipe View -------------------------*/ 
    SwipeView {
        id: swipeView
        currentIndex: swipeView.currentIndex
        anchors.fill: parent

        Item {
            id: id_page_1
            Text {
                color: "white"
                text: qsTr("Page_1")
            }
        }
        Item {
            id: id_page_2
            Text {
                color: "white"
                text: qsTr("Page_2")
            }
            visible: id_page_2.visible
            
            button_1.visible: false
        }
    }
    /*------------------------- BOTTOM BAR-------------------------*/   
    Rectangle{
        id: id_toolButton
        width : parent.height/1.2
        height: 80
        x: parent.width/4
        y: parent.height-height
        color: "white"
        visible: true
        opacity: 0.5
        Row {
            id: rowToolButton
            anchors.left: parent.left
            anchors.verticalCenter: parent.verticalCenter
            Button {
                id: button_1
                visible : button_1.visible
                width: 60
                height: 60
                background: Rectangle {
                    color: "transparent"
                }
                Image {
                    anchors.centerIn: parent;
                    width: parent.width/1.25
                    height: parent.height/1.25
                    source: "icons/image_1.png"
                }
            }
        }
    }
}

main.py:

import sys
import os
from PySide2.QtQml import *
from PySide2.QtGui import *
from PySide2 import QtCore

def qt_message_handler(mode, context, message):
    if mode == QtCore.QtInfoMsg:
        mode = 'Info'
    elif mode == QtCore.QtWarningMsg:
        mode = 'Warning'
    elif mode == QtCore.QtCriticalMsg:
        mode = 'critical'
    elif mode == QtCore.QtFatalMsg:
        mode = 'fatal'
    else:
        mode = 'Debug'
    print("%s: %s (%s:%d, %s)" % (mode, message, context.file, context.line, context.file))


if __name__ == "__main__":
    os.environ["QT_QUICK_BACKEND"] = "software"
    QtCore.qInstallMessageHandler(qt_message_handler)
    application = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    engine.load(os.path.join(os.path.dirname(__file__),"application.qml"))
    if not engine.rootContext():
        sys.exit(-1)
    try :
        sys.exit(application.exex_())
    except:
        pass

Answers:

Are you perhaps missing an syntax error, an undefined reference error and/or an binding loop warning in your output? These could already have guided you a bit in the correct correction.

The way to set an item property is

  1. by assignment: button_1.visible = false in a function block, or

  2. by binding to another property:

    Button {
        id: button_1
        visible: id_page_2.SwipeView.isCurrentItem
    }
    

    You probably also meant to use that button to go back or something, which should be done with a onClicked handler:

    Button {
         onClicked: swipeView.currentIndex = id_page_1.SwipeView.index
    }
    

    See https://doc.qt.io/qt-6/qml-qtquick-controls2-swipeview.html for the attached properties that I here have used (isCurrentItem and index)


BTW, the SwipeView allows the user to move the pages, you can disable it with interactive: false, in which case you definitely need to use the above mention onClicked handler somehow.

Answered By: Amfasis

You can use visible: swipView.currentIndex === 0 on the Button to only make it visible when currentIndex of the SwipView is 0 which means page 1. You could also use visible: swipView.currentIndex !== 1 which would make the Button always visible except if the page 2 is shown.

You can’t write button_1.visible: false outside of a binding or JavaScript, because button_1 isn’t a property of the Item it is an id. As mentioned, you could write button_1.visible = false in JS.

You should also read about QML bindings. The way you are using them is basically binding the properties to them self, e.g.

currentIndex: swipeView.currentIndex
visible: id_page_2.visible
visible : button_1.visible

This example shows how to hide the button, if page 2 is visible. The SwipeView by default is interactive, so you can drag the page to the left and right to get to the next.

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    title : qsTr("Swipe view")
    visible: true
    width : 800
    height: 480
    color: "black"

    component MyPage : Item {

        property alias text: title.text

        Text {
            id: title
            anchors.centerIn: parent
            color: "white"
            font.pixelSize: 20
        }
    }

    SwipeView {
        id: swipView
        anchors.fill: parent
        currentIndex: 0

        Repeater {
            model: 5
            delegate: MyPage {
                text: qsTr("Page_%1".arg(index))
            }
        }
    }

    Rectangle {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        width: parent.height / 1.2
        height: 80
        color: "white"
        visible: true
        opacity: 0.5

        Row {
            anchors.fill: parent
            anchors.margins: 10

            Button {
                id: toolButton
                visible: swipView.currentIndex !== 1

                background: Rectangle {
                    anchors.centerIn: parent
                    implicitWidth: 60
                    implicitHeight: 60
                    color: "red"
                }
            }
        }
    }
}
Answered By: iam_peter
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.