Drawer as child inside a SwipeView
-
So, I have found a strange behavior when I was trying to use a Drawer inside a interface with SwipeView-based navigation.
The goal was to have a side menu but on only one page inside of the SwipeView, so that it would not appear when other pages are shown to the user. Here is a sample project that is based on Qt Creator's "Application Qt Quick - Swipe" template (Page1/2Form.ui.qml are not used).
main.qml:
import QtQuick 2.9 import QtQuick.Controls 2.2 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Tabs") SwipeView { id: swipeView anchors.fill: parent currentIndex: tabBar.currentIndex MyPage { Label { anchors.centerIn: parent text: "Page 1" color: "white" } Item { id: drawerContainer anchors.fill: parent Drawer { id: drawer width: 0.33 * parent.width height: parent.height parent: drawerContainer background: Rectangle { color: "red" } Label { text: "Content goes here!" anchors.centerIn: parent } } } } MyPage { Label { anchors.centerIn: parent text: "Page 2" color: "white" } } MyPage { Label { anchors.centerIn: parent text: "Page 3" color: "white" } } } footer: TabBar { id: tabBar currentIndex: swipeView.currentIndex TabButton { text: qsTr("Page 1") } TabButton { text: qsTr("Page 2") } TabButton { text: qsTr("Page 3") } } }
MyPage.qml:
import QtQuick 2.9 import QtQuick.Controls 2.2 Page { id: root // Title in status bar for navigation title: qsTr("Main page") background: Rectangle { color: "black" } // Top status bar for service info output header: Rectangle { color: "red" } }
So, the key line is
parent: drawerContainer
which re-parents Drawer element to an Item that is a child of the page that is a child of the SwipeView. Without that line, drawer paints itself over the whole window and can be called with side gesture from any page of the swipe view. On the other hand, when it is a child of an items it draws only over that item.But, the problem comes with the side gestures when that item is hidden from the user (it is not currentItem of the SwipeView). In that case, as far as I can tell, the GUI thread (main one) freezes for indefinite time (other threads still work). The same happens if you try to change the currentIndex of the swipe view when the Drawer is shown (use TabBar buttons below).
As a hot-fix I just disable (
enabled: false
) the whole page that contains the Drawer while it is out of the user view, and bound the Drawer'sinteractive
property to the enabled property of the parent item.But is this an expected behavior or am I doing something wrong here? Why this happens? Maybe, if this is somehow goes against framework rules, it probably should show me some kind of an error message when attempting to do so?