Custom Drawer Qt/QML || Mobile App Like Drawer || Custom Drawer In QML

 Custom Drawer Qt/QML  || Mobile App Like Drawer || Custom Drawer In QML

 


PageDrawer.qml 

import QtQuick 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0

Drawer {
    id: drawer

    //
    // Default size options
    //
    implicitHeight: parent.height
    implicitWidth: Math.min (parent.width > parent.height ? 320 : 280,
                             Math.min (parent.width, parent.height) * 0.90)

    //
    // Icon properties
    //
    property string iconTitle: ""
    property string iconSource: ""
    property string iconSubtitle: ""
    property size iconSize: Qt.size (72, 72)
    property color iconBgColorLeft: "#de6262"
    property color iconBgColorRight: "#ffb850"

    //
    // List model that generates the page selector
    // Options for selector items are:
    //     - spacer: acts an expanding spacer between to items
    //     - pageTitle: the text to display
    //     - separator: if the element shall be a separator item
    //     - separatorText: optional text for the separator item
    //     - pageIcon: the source of the image to display next to the title
    //
    property alias items: listView.model
    property alias index: listView.currentIndex

    //
    // Execute appropiate action when the index changes
    //
    onIndexChanged: {
        var isSpacer = false
        var isSeparator = false
        var item = items.get (index)

        if (typeof (item) !== "undefined") {
            if (typeof (item.spacer) !== "undefined")
                isSpacer = item.spacer

            if (typeof (item.separator) !== "undefined")
                isSpacer = item.separator

            if (!isSpacer && !isSeparator)
                actions [index]()
        }
    }

    //
    // A list with functions that correspond with the index of each drawer item
    // provided with the \a pages property
    //
    // For a string-based example, check this SO answer:
    //     https://stackoverflow.com/a/26731377
    //
    // The only difference is that we are working with the index of each element
    // in the list view, for example, if you want to define the function to call
    // when the first item of the drawer is clicked, you should write:
    //
    //     actions: {
    //         0: function() {
    //             console.log ("First item clicked!")
    //         },
    //
    //         1: function() {}...,
    //         2: function() {}...,
    //         n: function() {}...
    //     }
    //
    property var actions

    //
    // Main layout of the drawer
    //
    ColumnLayout {
        spacing: 0
        anchors.margins: 0
        anchors.fill: parent

        //
        // Icon controls
        //
        Rectangle {
            z: 1
            height: 120
            id: iconRect
            Layout.fillWidth: true

            Rectangle {
                anchors.fill: parent

                LinearGradient {
                    anchors.fill: parent
                    start: Qt.point (0, 0)
                    end: Qt.point (parent.width, 0)

                    gradient: Gradient {
                        GradientStop { position: 0; color: iconBgColorLeft }
                        GradientStop { position: 1; color: iconBgColorRight }
                    }
                }
            }

            RowLayout {
                spacing: 16

                anchors {
                    fill: parent
                    centerIn: parent
                    margins: 16
                }

                Image {
                    source: iconSource
                    sourceSize: iconSize
                }

                ColumnLayout {
                    spacing: 8
                    Layout.fillWidth: true
                    Layout.fillHeight: true

                    Item {
                        Layout.fillHeight: true
                    }

                    Label {
                        color: "#fff"
                        text: iconTitle
                        font.weight: Font.Medium
                        font.pixelSize: 16
                    }

                    Label {
                        color: "#fff"
                        opacity: 0.87
                        text: iconSubtitle
                        font.pixelSize: 12
                    }

                    Item {
                        Layout.fillHeight: true
                    }
                }

                Item {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                }
            }
        }

        //
        // Page selector
        //
        ListView {
            z: 0
            id: listView
            currentIndex: -1
            Layout.fillWidth: true
            Layout.fillHeight: true
            Component.onCompleted: currentIndex = 0

            delegate: DrawerItem {
                model: items
                width: parent.width
                pageSelector: listView

                onClicked: {
                    if (listView.currentIndex !== index)
                        listView.currentIndex = index

                    drawer.close()
                }
            }

            ScrollIndicator.vertical: ScrollIndicator { }
        }
    }
}


DrawerItem.qml
 
 

import QtQuick 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.0

ItemDelegate {
    //
    // Do not allow user to click spacers and separators
    //
    enabled: !isSpacer (index) && !isSeparator (index)

    //
    // Alias to parent list view
    //
    property ListModel model
    property ListView pageSelector

    //
    // Returns true if \c spacer is defined and is equal to \c true
    //
    function isSpacer (index) {
        if (typeof (model.get (index).spacer) !== "undefined")
            return model.get (index).spacer

        return false
    }

    //
    // Returns true if \c link is defined and is equal to \c true
    //
    function isLink (index) {
        if (typeof (model.get (index).link) !== "undefined")
            return model.get (index).link

        return false
    }

    //
    // Returns true if \c separator is defiend and is equal to \c true
    //
    function isSeparator (index) {
        if (typeof (model.get (index).separator) !== "undefined")
            return model.get (index).separator

        return false
    }

    //
    // Returns the icon for the drawer item
    //
    function iconSource (index) {
        if (typeof (model.get (index).pageIcon) !== "undefined")
            return model.get (index).pageIcon

        return ""
    }

    //
    // Returns the title for the drawer item
    //
    function itemText (index) {
        if (typeof (model.get (index).pageTitle) !== "undefined")
            return model.get (index).pageTitle

        return ""
    }

    //
    // Returns \c true if separatoText is correctly defined
    //
    function hasSeparatorText (index) {
        return isSeparator (index) && typeof (model.get (index).separatorText) !== "undefined"
    }

    //
    // Decide if we should highlight the item
    //
    highlighted: ListView.isCurrentItem ? !isLink (index) : false

    //
    // Calculate height depending on the type of item that we are
    //
    height: {
        if (isSpacer (index)) {
            var usedHeight = 0
            for (var i = 0; i < model.count; ++i) {
                if (!isSpacer (i)) {
                    if (!isSeparator (i) || hasSeparatorText (i))
                        usedHeight += 48
                    else
                        usedHeight += 8
                }
            }

            return Math.max (8, pageSelector.height - usedHeight)
        }

        if (enabled || hasSeparatorText (index))
            return 48

        return 8
    }


    //
    // Separator layout
    //
    ColumnLayout {
        spacing: 8
        anchors.fill: parent
        visible: isSeparator (index)
        anchors.verticalCenter: parent.verticalCenter

        Item {
            Layout.fillHeight: true
        }

        Rectangle {
            height: 0.5
            opacity: 0.20
            color: "#000000"

            anchors {
                left: parent.left
                right: parent.right
            }
        }

        Label {
            opacity: 0.54
            color: "#000000"
            font.pixelSize: 14
            font.weight: Font.Medium
            text: hasSeparatorText (index) ? separatorText : ""

            anchors {
                margins: 16
                left: parent.left
                right: parent.right
            }
        }

        Item {
            Layout.fillHeight: true
        }
    }

    //
    // Normal layout
    //
    RowLayout {
        spacing: 16
        anchors.margins: 16
        anchors.fill: parent
        visible: !isSpacer (index)

        Image {
            smooth: true
            opacity: 0.54
            fillMode: Image.Pad
            source: iconSource (index)
            sourceSize: Qt.size (24, 24)
            verticalAlignment: Image.AlignVCenter
            horizontalAlignment: Image.AlignHCenter
            anchors.verticalCenter: parent.verticalCenter
        }

        Item {
            width: 36 - (2 * spacing)
        }

        Label {
            opacity: 0.87
            font.pixelSize: 14
            text: itemText (index)
            Layout.fillWidth: true
            font.weight: Font.Medium
            anchors.verticalCenter: parent.verticalCenter
        }
    }
}
 
 
 
SvgImage.qml 
 
 

import QtQuick 2.0

//
// Used to avoid showing blurry SVG images on hDPI screens
// Taken from: https://stackoverflow.com/a/38636816
//
Item {
    property alias image: img
    property alias source: img.source
    property alias fillMode: img.fillMode
    property alias sourceSize: img.sourceSize
    property alias verticalAlignment: img.verticalAlignment
    property alias horizontalAlignment: img.horizontalAlignment

    implicitWidth: sourceSize.width
    implicitHeight: sourceSize.height

    Image {
        id: img
        anchors.centerIn: parent
        sourceSize.width: width * DevicePixelRatio
        sourceSize.height: height * DevicePixelRatio
    }
}


Main.qml
 

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import "./"
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Custom Drawer In QML ")
    Button{
        width: 100
        height: 60
        onClicked: {
            drawer.open()
        }
    }

    PageDrawer {
        id: drawer

        //
        // Icon properties
        //
        iconTitle: "Qt Drawer App"
        iconSource: "qrc:/qt-logo.svg"
        iconSubtitle: qsTr ("Version 1.0 Beta")

        //
        // Define the actions to take for each drawer item
        // Drawers 5 and 6 are ignored, because they are used for
        // displaying a spacer and a separator
        //
        actions: {
            0: function() { console.log ("Item 1 clicked!") },
            1: function() { console.log ("Item 2 clicked!") },
            2: function() { console.log ("Item 3 clicked!") },
            3: function() { console.log ("Item 4 clicked!") },
            4: function() { console.log ("Item 5 clicked!") },
            7: function() { console.log ("Item 6 clicked!") },
            8: function() { console.log ("Item 7 clicked!") }
        }

        //
        // Define the drawer items
        //
        items: ListModel {
            id: pagesModel

            ListElement {
                pageTitle: qsTr ("Home")
                pageIcon: "qrc:/house-user-solid.svg"
            }

            ListElement {
                pageTitle: qsTr ("Scores Table")
                pageIcon: "qrc:/mobile-screen-solid.svg"
            }

            ListElement {
                pageTitle: qsTr ("Charts")
                pageIcon: "qrc:/chart-line-solid.svg"
            }

            ListElement {
                pageTitle: qsTr ("Leaderboard")
                pageIcon: "qrc:/cash-register-solid.svg"
            }

            ListElement {
                pageTitle: qsTr ("Settings")
                pageIcon: "qrc:/sliders-solid.svg"
            }

            ListElement {
                spacer: true
            }

            ListElement {
                separator: true
            }

            ListElement {
                pageTitle: qsTr ("Learn Romanian Whist")
                pageIcon: "qrc:/star-half-stroke-solid.svg"
            }

            ListElement {
                pageTitle: qsTr ("Feature Requests / Bugs")
                pageIcon: "qrc:/bug-solid.svg"
            }
        }
    }
}


 

 Note : Download Icons From Fontawsome website and change icons Name