Friday, June 24, 2011

Marquee text element with Qt Quick (QML)

Currently I am adding new feature to one of my QML application. While doing so I created marquee text element for QML.

I had created such component for Symbian long time ago when I was working on Avkon. Using similar logic I created similar component for QML as well.

I needed this component because while displaying one line text item in QML, sometime text is much larger than display area.

Following is code which I created my purpose, I tried to make it as much reusable as I can without putting much effort. Hope this will be to helpful to someone.

In following code whenever someone touch text element, it start scrolling its content. To scroll I am using text's actual width and display width. On timer event I am increasing x position of text so new text can be displayed. But I am subtracting same x delta from text's x location so text element remain on same position. And as I have enabled clipping on item element text which is outside of visible area will not be displayed.

import QtQuick 1.0

Item {
    id:marqueeText
    height: scrollingText.height
    clip: true    
    property int tempX: 0
    property alias text: scrollingText.text
    Text {        
        x: tempX
        id:scrollingText        
    }

    MouseArea {
        id:mouseArea
        anchors.fill: parent
        onClicked: {                            
            tempX = 0;
            timer.running = true;            
        }
    }

    Timer {
        id:timer
        interval: 200; running: false; repeat: true
        onTriggered:{            
            tempX = tempX + 5
            scrollingText.x = -tempX;

            if( tempX + marqueeText.width > scrollingText.width ) {
                timer.running = false
                pauseTimer.running = true
            }
        }
    }

    Timer {
        id:pauseTimer
        interval: 500; running: false; repeat: false
        onTriggered: {
            scrollingText.x = 0
        }
    }
}

Following is code, how above code can be used.
Rectangle {
        border.width: 2
        border.color: "black"
        color: "lightsteelblue"
        anchors.horizontalCenter: parent.horizontalCenter
        width: 250
        height: text.height + 10
        y:100
        MarqueeText {
            id:text
            width: 200
            anchors.verticalCenter: parent.verticalCenter
            anchors.horizontalCenter: parent.horizontalCenter
            text: "start ------ abcdefghijklmnopqrtaksdjfkdfjklsdjflksdjfklsjadfkljsad;flasjdlfjasdfjldsdfljf---- end"
        }
    }

Following output from above code.

2 comments:

  1. Hi Kunal, nice component, you could use a "Behavior on x" to, maybe its more simple.

    ReplyDelete
  2. Thank you for comment, I will try your suggestion.

    ReplyDelete