如何在QtQuick / QML中创建一个动画,可变大小的手风琴组件

时间:2017-03-29 12:16:53

标签: qt user-interface qml qt-quick qtquickcontrols

我想创建一个类似动画的手风琴式元素,可以在点击时展开。这是它应该如何运作的。

Accordion animation

当用户点击其中一个红色矩形时,应该展开作为实际内容的绿色矩形。我希望这个扩展能够生动。每个红色标题的绿色矩形内容的高度可能不同。

我已经能够实现点击扩展行为,但没有动画。这是我目前的代码。

AccordionElement.qml

import QtQuick 2.5
import QtQuick.Layouts 1.1

ColumnLayout {
    id: rootElement

    property string title: ""
    property bool isOpen: false
    default property alias accordionContent: contentPlaceholder.data

    anchors.left: parent.left; anchors.right: parent.right

    // Header element
    Rectangle {
        id: accordionHeader
        color: "red"
        anchors.left: parent.left; anchors.right: parent.right
        height: 50
        MouseArea {
            anchors.fill: parent
            Text {
                text: rootElement.title
                anchors.centerIn: parent
            }
            cursorShape: Qt.PointingHandCursor
            onClicked: {
                rootElement.isOpen = !rootElement.isOpen
            }
        }
    }

    // This will get filled with the content
    ColumnLayout {
        id: contentPlaceholder
        visible: rootElement.isOpen
        anchors.left: parent.left; anchors.right: parent.right
    }
}

这就是从父元素中使用它的方式:

Accordion.qml

ColumnLayout {
    Layout.margins: 5

    visible: true

    AccordionElement {
        title: "Title1"
        accordionContent: Rectangle {
            anchors.left: parent.left; anchors.right: parent.right
            height: 20
            color: "green"
        }
    }
    AccordionElement {
        title: "Title2"
        accordionContent: Rectangle {
            anchors.left: parent.left; anchors.right: parent.right
            height: 50
            color: "green"
        }
    }

    AccordionElement {
        title: "Title3"
        accordionContent: Rectangle {
            anchors.left: parent.left; anchors.right: parent.right
            height: 30
            color: "green"
        }
    }

    // Vertical spacer to keep the rectangles in upper part of column
    Item {
        Layout.fillHeight: true
    }
}

这会产生以下结果(当展开所有矩形时):

Expanded

理想情况下,我希望绿色矩形从红色矩形中滚出(就像打印机中的纸一样)。但我仍然坚持如何做到这一点。我尝试了几种使用height属性的方法,我得到了绿色矩形消失但白色空间仍在红色矩形下面。

任何帮助将不胜感激。我缺少一种方法吗?

1 个答案:

答案 0 :(得分:1)

这是一个简单快速的例子:

// AccItem.qml
Column {
  default property alias item: ld.sourceComponent
  Rectangle {
    width: 200
    height: 50
    color: "red"
    MouseArea {
      anchors.fill: parent
      onClicked: info.show = !info.show
    }
  }
  Rectangle {
    id: info
    width: 200
    height: show ? ld.height : 0
    property bool show : false
    color: "green"
    clip: true
    Loader {
      id: ld
      y: info.height - height
      anchors.horizontalCenter: info.horizontalCenter
    }
    Behavior on height {
      NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
    }
  }
}

// Acc.qml
Column {
  spacing: 5
  AccItem {
    Rectangle {
      width: 50
      height: 50
      radius: 50
      color: "blue"
      anchors.centerIn: parent
    }
  }
  AccItem {
    Rectangle {
      width: 100
      height: 100
      radius: 50
      color: "yellow"
      anchors.centerIn: parent
    }
  }
  AccItem {
    Rectangle {
      width: 75
      height: 75
      radius: 50
      color: "cyan"
      anchors.centerIn: parent
    }
  }
}

你不必要地用锚和布局过度复杂化了。似乎问题并不是要求任何这些问题。

更新:我稍微改进了实现,与最初的实现相比,内容实际上会从打印机中滑出标题,而不是简单地被揭开,并且还删除了误报率循环警告的来源。 / p>

enter image description here