Home > Software engineering >  QT QML make invisible button in other Rectangle
QT QML make invisible button in other Rectangle

Time:01-06

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

CodePudding user response:

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.

CodePudding user response:

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.

But the bigger issue here is that you need to 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"

    /*------------------------- Swipe View -------------------------*/
    SwipeView {
        id: swipView
        //currentIndex: swipeView.currentIndex
        anchors.fill: parent
        currentIndex: 0

        Item {
            Text {
                color: "white"
                text: qsTr("Page_1")
            }
        }

        Item {
            Text {
                color: "white"
                text: qsTr("Page_2")
            }
        }
    }
    /*------------------------- BOTTOM BAR-------------------------*/
    Rectangle {
        id: toolButton
        width: parent.height / 1.2
        height: 80
        x: parent.width / 4
        y: parent.height - toolButton.height
        color: "white"
        visible: true
        opacity: 0.5

        Row {
            anchors.left: parent.left
            anchors.verticalCenter: parent.verticalCenter

            Button {
                visible: swipView.currentIndex === 0
                width: 60
                height: 60
                background: Rectangle {
                    color: "transparent"
                }
                Rectangle {
                    anchors.centerIn: parent
                    width: parent.width / 1.25
                    height: parent.height / 1.25
                    color: "red"
                }
            }
        }
    }
}
  • Related