QML "self' scrolling text



  • Hi all,

    I'm currently trying to develop a component which will be integrate in a QWidget as QDeclarativeView.
    That component is supposed to scroll different texts at a specific speed. The loop is an infinite one (as long as the QWidget exists), the different texts to display are given in a QStringList.

    Whereas I've been developping using QT for a few years, I'm very new to QML. I first wrote the following codes that seemed to work:
    @

    import Qt 4.7

    Rectangle{
    id : root
    color : Context.backgroundColor
    width: 1000
    height: 200

    property int indiceT : -1
    
    function changeSettings()
    {
        if(root.indiceT==Context.stringList.length-1 || root.indiceT==-1)
            root.indiceT=0;
        else
            root.indiceT++;
    
        if(Context.stringList.length == 0)
        {
            idText.text=" "
            numberAnimation.duration=1;
            numberAnimation.to=0
            numberAnimation.from= idText.width
        }
        else
        {
            idText.text=Context.stringList[root.indiceT]
            numberAnimation.duration=Math.round((idText.paintedWidth+root.width)*1000./Context.pixelsPerSecondScrollingSpeed);
            numberAnimation.to=-idText.paintedWidth
            numberAnimation.from= root.width
        }
    }
    
    Text{
        id : idText
        height : parent.height
        text : " "
        verticalAlignment : Text.AlignVCenter
        style: Text.Normal;
        font: Context.font
        color: Context.fontColor
        styleColor : Context.textColor
    
        SequentialAnimation {
            id: animation
            loops: 1
            running: true
    
    
            NumberAnimation {
                alwaysRunToEnd: true
                id: numberAnimation
                targets: idText
                from: 1
                to:0
                duration: 1000
                property: "x"
            }
    
            //new Context settings are taken into account
            //only if I restart the animation
            ScriptAction { script: {changeSettings();animation.restart();} }
        }
    }
    

    }
    @

    Problem is that I need to restart the animation to take the dynamic settings into account. BUT restarting the animation seems to create a new animation and thus never ending the first animation. Well, it increase a lot the memory without never ending...

    Does anyone have an idea to detect the animation end and starting it again?
    Or is there a solution to take the settings into account into the infinite loop?

    Thanks in advance for your help, I've been trying a lot of things during the last week..


  • Moderators

    Use "onRunningChanged" slot like that:
    @
    NumberAnimation { // or any other animation
    /* your code here */
    onRunninChanged: {
    if (!running) {
    // Means that animation stopped.
    // Logic here.
    }
    }
    }
    @

    I'm not sure how that behaves in a loop though, you'll have to check.



  • Thanks, but I just tried that:
    @
    SequentialAnimation {
    id: animation
    loops: 1
    running: true
    onRunningChanged:
    if (!running)
    {
    console.log("right here");
    start();
    }

            NumberAnimation {
                alwaysRunToEnd: true
                id: numberAnimation
                targets: idText
                from: 1
                to:0
                duration: 1000
                property: "x"
            }
    
            ScriptAction { script: {changeSettings();} }
        }
    

    @

    and the onRunningChanged is never called.


  • Moderators

    It might be that line 4 is the problem. Try setting it from elsewhere (declaratively or imperatively). For example:
    @
    NumberAnimation { // or any other animation
    Component.onCompleted {
    start(); // or running = true;
    }
    onRunninChanged: {
    if (!running) {
    console.log("right here");
    start(); // this might raise an error, I remember having problems with that method.
    }
    }
    }
    @



  • It does not seem to work :
    I'm surprised as I really supposed that having a scrolling text would be easy in QML..
    Actually, I don't have any log displayed in my console, do you have any idea of the reason?


  • Moderators

    The standard approach is to use QML Flickable element. This enables any child object (or objects, see also GridView, and and many others) to be moved with your fingers (or mouse on non-mobile), and supports clipping. You may try with that, actually - it might make the job easier.
    @
    Flickable {
    Text {
    // your text element
    }
    }
    @

    As for log being not displayed - that is indeed strange and might point to an error located elsewhere in the code.

    I actually have some problems with logging on Android, but I have not found the cause (logs sometimes get displayed, and sometimes not). You are probably trying it out on PC anyway.



  • Well....

    using the following code:
    @
    SequentialAnimation {
    id: animation
    loops: 1

            Component.onCompleted:{
                running = true;
                }
    
    
            onRunningChanged:
            {
                if (running)
                {
                    console.log("changed: running");
                 }
                else
                {
                    console.log("changed: not running");
                    start();
                }
            }
    
            NumberAnimation {
                alwaysRunToEnd: true
                id: numberAnimation
                targets: idText
                from: 1
                to:0
                duration: 1000
                property: "x"
            }
    
            ScriptAction { script: {changeSettings();console.log("end of animation");animation.running = false;} }
        }
    

    @

    the animation finally works : it previously did not cause I did not precise "Component." for onCompleted function and "animation." for running false...

    BUT: the memory still increase very fast without never being released (using 7 times the widget -> 1 MB per 2 minutes... :)

    When start() in onRunningChanged() function is commented, the memory usage is stable..

    Maybe flickable could help me but I have no human interaction: the text has to scroll itself..



  • Hey,

    thanks to you, it finally seems to work using the following code:
    @
    Text{
    id : idText
    height : parent.height
    text : " "
    verticalAlignment : Text.AlignVCenter
    style: Text.Normal;
    font: Context.font
    color: Context.fontColor
    styleColor : Context.textColor

        NumberAnimation {
            alwaysRunToEnd: true
            id: numberAnimation
            targets: idText
            from: 1
            to:0
            duration: 1000
            property: "x"
    
            Component.onCompleted:{
                running = true;
                }
    
            onRunningChanged:
                if (!running)
                {
                    //load the next text, speed and colors
                    changeSettings();
                    //restart the animation
                    running=true;
                }
          }
     }
    

    @

    I don't use the SequentialAnimation anymore and I prefered to use running=true instead of start(). It seems to be OK now, no memory increases anymore.

    Thanks again.


  • Moderators

    Ah, thats nice. You are welcome. If everything is OK, please modify the topic's subjects and add "[SOLVED]" at the beginning.

    Console logs works now, too?


Log in to reply
 

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