Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to auto-hide ApplicatioWindow menuBar?

Tags:

qt

qml

I'd like to have an ApplicationWindow have an auto-hiding menuBar, which shows up when mouse cursor is positioned on the uppermost part of the window. Is this possible in QML?

PS: I'm using Qt 5.3.

Thanks in advance.

like image 588
GabrielF Avatar asked Dec 04 '14 17:12

GabrielF


People also ask

How do I make Windows taskbar auto hide?

Automatically hide the taskbar You can hide the taskbar both in desktop mode and tablet mode. Press and hold or right-click any empty space on the taskbar, select Taskbar settings, select Taskbar behaviors, and select Automatically hide the taskbar.

Why is my taskbar not automatically hiding?

Answer: Make sure that the option – “Automatically hide the taskbar in desktop mode” in the Settings is enabled. Even after that, if the taskbar is not hiding in fullscreen, then it's probably because of some app that is providing notifications that do not allow the taskbar to hide during the full screen.


2 Answers

You can exploit internal properties, i.e. properties starting with "__". Since they are internal, functionality could break in future releases even if IMO it is unlikely in this case.

By using internal properties you can exploit __contentItem, the graphical container of the MenuBar and animate its properties to achieve the desired result. Here is a possible approach; it works with Qt 5.3/ Qt 5.4/ Qt 5.5 (the ones I could test it on):

ApplicationWindow {
    id: app
    visible: true
    width: 400
    height: 300

    property real hideValue: 0
    Behavior on hideValue {
        NumberAnimation {duration: 200}
    }

    menuBar:  MenuBar {
        id: menu
        //__contentItem.scale: value                        // (1)
        //__contentItem.opacity: hideValue                  // (2)
        __contentItem.transform: Scale {yScale: hideValue}  // (3)

        Menu {
            id: m1
            title: "File"
            MenuItem { text: "Open..."
                onTriggered: {
                   hideValue = 0                            // hide the bar
                }
            }
            MenuItem { text: "Close"
                onTriggered: {
                   hideValue = 0                            // hide the bar
                }
            }
        }
    }


    Button{
        id: b1
        anchors.centerIn: parent
        text: "CLICK ME!"
        width: 100
        height: 100
    }

    MouseArea {
        id: ma1
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        height: menu.__contentItem.implicitHeight
        hoverEnabled: true

        onEntered: {
            hideValue = 1                            // show the bar
        }
    }

    MouseArea {
        id: ma2
        anchors.fill: parent
        hoverEnabled: true
        z: -1

        onEntered: {
            m1.__dismissMenu()
            hideValue = 0                            // hide the bar
        }
    }
}

Summarizing the code:

  • Two MouseArea are defined: ma1 which covers the MenuBar and ma2 which fills the ApplicationWindow. The latter has a z negative to be positioned under any other element of the window, inclusing ma1: this way it cannot interfere with events related to any element added (such as the example button b1).
  • ma1 sets a property called hideValue to 1 whereas ma2 brings it back to 0. The property is used over a visual property of __contentItem (see (1), (2) and (3) in the code) to hide/show the MenuBar. A simple Behaviour over the hideValue property ensures that the transition is smooth.
  • Internal function __dismissMenu() is used to ensure that an opened Menu is closed when the MenuBar loses focus.
  • When a MenuItem is triggered the hideValue property is directly reset to ensure correct hiding.
like image 194
BaCaRoZzo Avatar answered Sep 20 '22 21:09

BaCaRoZzo


I managed to get some results with this code:

ApplicationWindow {
    id: app

    MenuBar {
        id: menu
        Menu {
            title: "Menu 1"
            MenuItem {
                text: "item 1"
            }
            MenuItem {
                action: "item 2"
            }
        }
    }

    MouseArea {
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        height: 20
        hoverEnabled: true

        onEntered: {
            if (app.menuBar === menu)
                app.menuBar = null;
            else
                app.menuBar = menu;
        }
    }
}

The change however is abruptly and QML debugging report errors when trying to access null.__contentItem when the bar is hidden. And, of course, there's an absolute size in the code which could cause problems.

like image 44
GabrielF Avatar answered Sep 17 '22 21:09

GabrielF