如何在 QtQuick / QML 中创建动画、可变大小的手风琴组件
How to create an animated, variable size accordion component in QtQuick / QML
我想创建一个在点击时展开的动画 accordion-like 元素。这是它应该如何工作。
当用户单击其中一个红色矩形时,作为实际内容的绿色矩形应该展开。我希望这个扩展是动画的。每个红色的绿色矩形内容的高度可能不同 header.
我已经能够实现 click-to-expand 行为,但是没有动画。这是我目前拥有的代码。
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
}
}
这就是它在 parent 元素中的用法:
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
}
}
这会产生以下结果(展开所有矩形时):
理想情况下,我希望绿色矩形从红色矩形中滚出(就像打印机中的纸一样)。但我坚持如何做到这一点。我尝试了几种使用 height
属性 的方法,绿色矩形消失了,但白色 space 仍然在红色矩形下方。
如有任何帮助,我们将不胜感激。有没有我缺少的方法?
这是一个快速简单的示例:
// 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
}
}
}
您不必要地使用锚点和布局使它过于复杂。似乎没有任何问题需要这些。
更新:我稍微改进了实现,与最初的相比,内容实际上会像纸从打印机中滑出一样从页眉中滑出,而不是简单地被揭开,并且还删除了误报绑定循环警告的来源.
我想创建一个在点击时展开的动画 accordion-like 元素。这是它应该如何工作。
当用户单击其中一个红色矩形时,作为实际内容的绿色矩形应该展开。我希望这个扩展是动画的。每个红色的绿色矩形内容的高度可能不同 header.
我已经能够实现 click-to-expand 行为,但是没有动画。这是我目前拥有的代码。
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
}
}
这就是它在 parent 元素中的用法:
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
}
}
这会产生以下结果(展开所有矩形时):
理想情况下,我希望绿色矩形从红色矩形中滚出(就像打印机中的纸一样)。但我坚持如何做到这一点。我尝试了几种使用 height
属性 的方法,绿色矩形消失了,但白色 space 仍然在红色矩形下方。
如有任何帮助,我们将不胜感激。有没有我缺少的方法?
这是一个快速简单的示例:
// 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
}
}
}
您不必要地使用锚点和布局使它过于复杂。似乎没有任何问题需要这些。
更新:我稍微改进了实现,与最初的相比,内容实际上会像纸从打印机中滑出一样从页眉中滑出,而不是简单地被揭开,并且还删除了误报绑定循环警告的来源.