Right menu bar glitch



  • Hello,

    My application is a menu bar that can be on the left or right of the screen. When the user hovers over the bar, it extends to show more options. This works very well when the menu bar is on the left of the screen. My application window is then located at x=5 and I extend the width of the window when hovered. I am using Qt on Windows with MinGW 5.7

    The problem is when the menu bar is on the right. Things are more complex since the application window gets filled towards the right. I mean that we must give an "x" position and a width which will fill from "x" to "x+width". However, in this case, I would like to give an "x" and fill to the left. Unfortunately, we can't give negative width.

    I thought of using a transformation : "transform: Scale { origin.x: 0; origin.y: 0; xScale: -1}" but we can't do that on an application window.

    So what I did was to use set the position to "x:Screen.width-mainwin.width" to auto-adjust the position. However, it create glitches as you can see on the following video. It works when the bar is on the left but not when it's on the right (in fact it's worse than we see on the video, I think the screen capture did not get everything but you can seee the flickering). At some times, we can see the red bar momentarily going to the middle of the screen.
    https://drive.google.com/open?id=0B5jjRZXY3i_zeTdqWjlpMTE5dkk

    The blue area is the application window. The red area is the bar containing the shortcuts (it should not move). The green area is the additional information.

    Here are the two codes:
    LEFT MENU BAR

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    import QtQuick.Window 2.0
    
    ApplicationWindow
    {
        id: mainwin
        visible: true
        width: 100
        height: Screen.height*0.8
        title: qsTr("Hello World")
        flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
        color:"blue"
    
        y:5
        x:5
    
        Rectangle
        {
            anchors.left: parent.left
            anchors.top:parent.top
            anchors.bottom: parent.bottom
            width:80
    
            id:rect1
            color:"red"
            MouseArea
            {
                anchors.fill:parent
                hoverEnabled: true
                z:2
                id:marea1
    
                propagateComposedEvents: true
                onClicked: mouse.accepted = false;
                onPressed: mouse.accepted = false;
                onReleased: mouse.accepted = false;
                onDoubleClicked: mouse.accepted = false;
                onPositionChanged: mouse.accepted = false;
                onPressAndHold: mouse.accepted = false;
    
                onEntered:
                {
                    mainwin.width=500
                    rect2.visible=true
                }
                onExited:
                {
                    mainwin.width=100
                    rect2.visible=false
                }
            }
    
            Rectangle
            {
                id:rect2
                visible:false
                anchors.left:rect1.right
                anchors.top:rect1.top
                anchors.bottom:rect1.bottom
                width:400
                color:"green"
            }
        }
    }
    

    RIGHT MENU BAR

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    import QtQuick.Window 2.0
    
    ApplicationWindow
    {
        id: mainwin
        visible: true
        width: 100
        height: Screen.height*0.8
        title: qsTr("Hello World")
        flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
        color:"blue"
    
        y:5
        x:Screen.width-mainwin.width-5
    
        Rectangle
        {
            anchors.right: parent.right
            anchors.top:parent.top
            anchors.bottom: parent.bottom
            width:80
    
            id:rect1
            color:"red"
            MouseArea
            {
                anchors.fill:parent
                hoverEnabled: true
                z:2
                id:marea1
    
                propagateComposedEvents: true
                onClicked: mouse.accepted = false;
                onPressed: mouse.accepted = false;
                onReleased: mouse.accepted = false;
                onDoubleClicked: mouse.accepted = false;
                onPositionChanged: mouse.accepted = false;
                onPressAndHold: mouse.accepted = false;
    
                onEntered:
                {
                    mainwin.width=500
                    rect2.visible=true
                }
                onExited:
                {
                    mainwin.width=100
                    rect2.visible=false
                }
            }
    
            Rectangle
            {
                id:rect2
                visible:false
                anchors.right:rect1.left
                anchors.top:rect1.top
                anchors.bottom:rect1.bottom
                width:400
                color:"green"
            }
        }
    }
    

    Thank you so much !

    Alex



  • Hi,

    I think that changing the dimension of the main window while moving its x coordinate is the problem.
    In fact you are moving everything, even your MouseArea! So the state of your MouseArea is rapidly changing between the "onEntered" and "onExited" state while your main window is moving. That's why it's glitching.

    What I propose as a possible solution is to enable only one of the two states at a time. So when the window is closed only the "onEntered" signal will be processed, while when it is open the "onExited" code will run.

    Switching from one state to the other cannot be instant, of course, otherwise your system will be glitchy as now. So I propose to set a Timer which in some milliseconds will switch your state from one to the other.

    Here's my code for your right menu bar:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    import QtQuick.Window 2.0
    
    ApplicationWindow
    {
        id: mainwin
        visible: true
        width: 100
        height: Screen.height*0.8
        title: qsTr("Hello World")
        flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
        color:"blue"
    
        y:5
        x:Screen.width-mainwin.width-5
    
        Rectangle
        {
            property bool opened: false // this is your window state
    
            anchors.right: parent.right
            anchors.top:parent.top
            anchors.bottom: parent.bottom
            width:80
    
            id:rect1
            color:"red"
            MouseArea
            {
                anchors.fill:parent
                hoverEnabled: true
                z:2
                id:marea1
    
                propagateComposedEvents: true
                onClicked: mouse.accepted = false;
                onPressed: mouse.accepted = false;
                onReleased: mouse.accepted = false;
                onDoubleClicked: mouse.accepted = false;
                onPositionChanged: mouse.accepted = false;
                onPressAndHold: mouse.accepted = false;
    
                onEntered:
                {
                    if(rect1.opened === false) // here check the state
                    {
                        mainwin.width=500
                        rect2.visible=true
                        move_window.running=true // run the timer
                    }
                }
                onExited:
                {
                    if(rect1.opened === true) // here check the state
                    {
                        mainwin.width=100
                        rect2.visible=false
                        move_window.running=true // run the timer
                    }
                }
            }
    
            Rectangle
            {
                id:rect2
                visible:false
                anchors.right:rect1.left
                anchors.top:rect1.top
                anchors.bottom:rect1.bottom
                width:400
                color:"green"
            }
    
            Timer
            {
                id: move_window
                interval: 250
                running: false
                onTriggered: // when the timer starts, it will switch your state
                {
                    if(rect1.opened === true)
                        rect1.opened = false
                    else
                        rect1.opened = true
                }
            }
        }
    }
    

    If changing the main window width is not mandatory for your project, I would suggest to set it as fixed, and change the width of your rectangles with respect to the MouseArea signals. In this way you can assure that the MouseArea will not be moved from its location.

    That's my trivial example:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    import QtQuick.Window 2.0
    
    ApplicationWindow
    {
        id: mainwin
        visible: true
        width: Screen.width*0.8
        height: Screen.height*0.8
        title: qsTr("Hello World")
        flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
        color:"transparent"
    
        y:5
        x:Screen.width - mainwin.width - 5
    
        Rectangle
        {
            anchors.right: parent.right
            anchors.top:parent.top
            anchors.bottom: parent.bottom
            width:80
    
            id:rect1
            color:"red"
    
            MouseArea
            {
                anchors.fill:parent
                hoverEnabled: true
                z:2
                id:marea1
    
                onEntered:
                {
                    rect2.width=500
                }
                onExited:
                {
                    rect2.width=0
                }
            }
        }
    
        Rectangle
        {
            anchors.right: rect1.left
            anchors.top:parent.top
            anchors.bottom: parent.bottom
            width:0
    
            id:rect2
            color:"green"
        }
    
        Rectangle
        {
            anchors.right: rect2.left
            anchors.top:parent.top
            anchors.bottom: parent.bottom
            width:20
    
            id:rect3
            color:"blue"
        }
    }
    

    Of course the main window will cover part of your screen, even if it is transparent.



  • @Marco-Pellin Thank you very much for your answer.
    I tried your first code but it has the same glitch. You can see it better if you set "blue" and "green" to "transparent". But in fact, my code does not change the MouseArea. The MouseArea is supposed to remain over the red rectangle which is supposed to always remains at the same place and with the same width. This red rectangle is attached to the rigght of the application window (anchors.right: parent.right). However, what is stange is that when we hover on the red rectangle, it momentarily switch to the left of the application window.

    As four your second code, I really need to modify the width of the application window. Otherwise, even if it's transparent, the user won't have access to the content under it (he will see it but won't be able to interact with it...).

    Thank you very much !

    Alex


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.