Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Moving contents on MouseArea hover
Qt 6.11 is out! See what's new in the release blog

Moving contents on MouseArea hover

Scheduled Pinned Locked Moved QML and Qt Quick
qmlqtquickqt 5.4mouse
4 Posts 2 Posters 2.9k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Spez
    wrote on last edited by
    #1

    Hi there!

    On this screenshot I have a big image (3840x2160) in a small window (640x480) and those dark spots on the sides. Moving the mouse inside these areas should move the picture either to the left or to the right until either the right or the left border of the image hits the corresponding border of the window. The speed of the movement should depend on how close the mouse is to the border of the window.

    I got this code now:

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Window 2.2
    import QtQuick.Dialogs 1.2
    
    ApplicationWindow {
        title: qsTr("Hello World")
        width: 640
        height: 480
        visible: true
    
        Image {
            id: image
            width: 3840
            height: 2160
            sourceSize: Qt.size(3840, 2160)
            source: "qrc:/image.jpg"
        }
    
        Rectangle {
            id: leftIndicator
            width: 64
            anchors.left: parent.left
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            color: Qt.rgba(0,0,0,0.25)
        }
    
        Rectangle {
            id: rightIndicator
            width: 64
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            color: Qt.rgba(0,0,0,0.25)
        }
    
        MouseArea {
            anchors.fill: leftIndicator
            hoverEnabled: true
            onEntered: {
                while(containsMouse) {
                    /* this is an Infinite loop */
                }
            }
        }
    
        MouseArea {
            anchors.fill: rightIndicator
            hoverEnabled: true
        }
    }
    

    I thought that when the mouse enters the MouseArea it should change the pictures position until it reaches it's end (the pictures transformation should not be bigger than the difference between the width of the window and the width of the whole picture) while the mouse is hovering that area.

    I end up having an infinite loop blocking the update of the the mouse position and the containsMouse property. The whole application becomes unresponsive.

    Could somebody tell me how this problem could be solved correctly?

    Thank you in advance!

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      This is what I would do. In implrementation of onEntered, start a Timer. In the timer's onTriggered slot, push the flickable. You can modify how often the view is pushed by modifying the timer's interval.

      (Z(:^

      S 1 Reply Last reply
      0
      • sierdzioS sierdzio

        This is what I would do. In implrementation of onEntered, start a Timer. In the timer's onTriggered slot, push the flickable. You can modify how often the view is pushed by modifying the timer's interval.

        S Offline
        S Offline
        Spez
        wrote on last edited by
        #3

        @sierdzio

        Now I got it, thank you!
        here is the code:

        import QtQuick 2.4
        import QtQuick.Controls 1.3
        import QtQuick.Window 2.2
        
        ApplicationWindow {
        	title: qsTr("Flickable")
        	width: 1024
        	height: 768
        	visible: true
        
        	Flickable {
        		id: flickable
        		anchors.fill: parent
        		interactive: true
        		contentWidth: image.width
        		contentHeight: image.height
        		flickableDirection: Flickable.HorizontalFlick
        		boundsBehavior: Flickable.StopAtBounds
        		Image {
        			id: image
        			width: 3840
        			height: 768
        			sourceSize: Qt.size(3840, 768)
        			source: "qrc:/image.jpg"
        		}
        	}
        
        	MouseArea {
        		id: leftTrigger
        		width: 256
        		anchors.left: parent.left
        		anchors.top: parent.top
        		anchors.bottom: parent.bottom
        		hoverEnabled: true
        
        		Timer {
        			id: moveLeftTimer
        			interval: 1
        			repeat: true
        			onTriggered: {
        				if(flickable.contentX - (parent.width - parent.mouseX) / 32 > 0) {
        					flickable.contentX -= (parent.width - parent.mouseX) / 32
        				} else {
        					flickable.contentX = 0
        				}
        			}
        		}
        
        		onEntered: {
        			moveLeftTimer.start()
        		}
        		onExited: {
        			moveLeftTimer.stop()
        		}
        	}
        
        	MouseArea {
        		id: rightTrigger
        		width: 256
        		anchors.right: parent.right
        		anchors.top: parent.top
        		anchors.bottom: parent.bottom
        		hoverEnabled: true
        
        		Timer {
        			id: moveRightTimer
        			interval: 1
        			repeat: true
        			onTriggered: {
        				if(flickable.contentX + parent.mouseX / 32 < flickable.contentWidth - flickable.width) {
        					flickable.contentX += parent.mouseX / 32
        				} else {
        					flickable.contentX = flickable.contentWidth - flickable.width
        				}
        			}
        		}
        
        		onEntered: {
        			moveRightTimer.start()
        		}
        		onExited: {
        			moveRightTimer.stop()
        		}
        	}
        }
        

        Still I think this is rather a hack than a clean solution, because of the weak animation performance due to the 1 millisecond timer interval (micro stuttering)

        There must be a better solution to this, don't you think so?

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          OK, here are my suggestions:

          • use Flickable's flick() method link. It should work better than your solution, be more fluid and natural-looking
          • 1ms timer resolution is completely useless: QtQuick updates the screen (paints a new frame) every 16.6 ms to achieve constant 60 Hz refresh rate. So you are wasting time and CPU power by invoking it 16 times more often than the software can pain it ;-) I'd suggest setting it to at least 16ms, but in reality I would probably use 50-100ms and tweak it to look good using flick() method mentioned above

          (Z(:^

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved