Наведите курсор на текстовое поле, выделите анимацию QML QtQuick.Контроль 2.15

#javascript #qt #qml

Вопрос:

У меня есть текстовое поле, и я пытаюсь выделить его фон при наведении курсора. Я использую a PropertyAnimation , и он на самом деле не делает анимацию:

 import QtQuick 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15

TextField {
    id: txtfield

    height: 40
    width: 250

    QtObject{
        id: internal

//        property var dynamicWidth: {if(txtfield.hovered){
//                                   console.log('Damn')
//                                   bg.border.width = 1.5
//                               }else{
//                                   bg.border.width = 0
//                               }
//        }
    }
    color: '#ffffff'
    placeholderTextColor: "#7fffffff"
    selectedTextColor: '#000000'
    selectionColor: '#ffffff'
    font.family: "Verdana"
    font.pointSize: 10
    placeholderText: qsTr('Enter full name...')
    hoverEnabled: true

    background: Rectangle{
        id: bg
        color: "#2c313c"
        border.color: "#aa0000"
//        border.width: internal.dynamicWidth
        radius: 10

        PropertyAnimation{
            id: widthAnimation
            target: bg // rectangle
            property: 'border.width'
            to: if(txtfield.hovered){
                    return 10
                }else{
                    return 0
                }
            duration: 500
            easing.type: Easing.InOutQuint
        }    }
}
 

Я новичок и только учусь JS, заранее спасибо 😀

Комментарии:

1. Это не то, как вы должны запускать анимацию. Замените if-else на просто 10 и используйте onHoveredChanged слот в своем TextField , чтобы фактически запустить анимацию ( widthAnimation.start() ). Вы также можете захотеть иметь две анимации — когда мышь входит и выходит. Это будет проще сделать с помощью состояний и переходов: doc.qt.io/qt-5/qml-tutorial3.html

2. Только что понял, что в текстовом поле нет onHoveredChanged слота. Вместо этого вы все равно используете MouseArea.

3. @splaytreez Не могли бы вы привести пример того, что вы имеете в виду?

4. @CoolClound Я опубликую код

Ответ №1:

Анимация не начнется, когда txtfiled.hovered свойство изменится так, как вы ожидаете. Чтобы запустить анимацию, вы должны использовать этот start() метод. Решение 1:

     TextField {
        id: txtfield

        anchors.centerIn: parent

        height: 40
        width: 250

        QtObject{

        }
        color: '#ffffff'
        placeholderTextColor: "#7fffffff"
        selectedTextColor: '#000000'
        selectionColor: '#ffffff'
        font.family: "Verdana"
        font.pointSize: 10
        placeholderText: qsTr('Enter full name...')

        MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            onHoveredChanged: {
                if (containsMouse) {
                    widthAnimation.start();
                } else {
                    bg.border.width = 0;
                }
            }
            onClicked: {
                txtfield.forceActiveFocus();
            }
        }

        background: Rectangle{
            id: bg
            color: "#2c313c"
            border.color: "#aa0000"
            //        border.width: internal.dynamicWidth
            radius: 10

            PropertyAnimation{
                id: widthAnimation
                target: bg // rectangle
                property: 'border.width'
                to: 10
                duration: 500
                easing.type: Easing.InOutQuint
            }
        }
    }
 

Теперь вам может понадобиться анимация, когда мышь покидает текстовую область. Это лучше делать с помощью состояний и переходов:

     TextField {
        id: txtfield

        anchors.centerIn: parent

        height: 40
        width: 250

        QtObject{
            id: internal
        }
        color: '#ffffff'
        placeholderTextColor: "#7fffffff"
        selectedTextColor: '#000000'
        selectionColor: '#ffffff'
        font.family: "Verdana"
        font.pointSize: 10
        placeholderText: qsTr('Enter full name...')

        MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            onHoveredChanged: {
                if (containsMouse) {
                    bg.state = "hovered"
                } else {
                    bg.state = "unhovered"
                }
            }
            onClicked: {
                txtfield.forceActiveFocus();
            }
        }

        background: Rectangle{
            id: bg
            color: "#2c313c"
            border.color: "#aa0000"
            radius: 10

            states: [
                State {
                    name: "hovered"
                    PropertyChanges {
                        target: bg
                        border.width: 10
                    }
                },
                State {
                    name: "unhovered"
                    PropertyChanges {
                        target: bg
                        border.width: 0
                    }
                }
            ]
            transitions: [
                Transition {
                    from: "*"
                    to: "*"
                    PropertyAnimation {
                        property: "border.width"
                        duration: 300
                        easing.type: Easing.InOutQuint
                    }
                }
            ]
        }
    }
 

Подробнее о состояниях и переходах: https://doc.qt.io/qt-5/qml-tutorial3.html

Комментарии:

1. Хорошо, это действительно работает. Не могли бы вы сказать мне, что from: "*" это значит?

2. @CoolCloud Обычно у вас есть несколько переходов между разными состояниями. from и to свойства указывают, к каким изменениям состояния (из какого состояния и в какое состояние) должен применяться переход. Здесь анимация для отображения границы такая же, как анимация для скрытия границы, поэтому достаточно иметь только один переход, который применяется к любому изменению состояния-для этого * и предназначен. Это было очень плохое объяснение, поэтому вам следует прочитать документацию; это станет намного более ясным

3. Это прекрасно, я понимаю. Спасибо за ответ 😀

4. Я действительно заметил, в решении 2. Граница уже подсвечивается при выполнении кода. Есть идеи, почему?

5. @CoolCloud к элементу фона