QML“自定义菜单”选项向上移动
Posted
技术标签:
【中文标题】QML“自定义菜单”选项向上移动【英文标题】:QML 'Custom Menu' option moving upwards 【发布时间】:2016-11-24 11:31:30 【问题描述】:我正在尝试在 QML 中创建一个“菜单”,每个选项中都有自定义数据
对于我的应用程序的要求,我需要显示它动态加载 QML 文件 (Qt.createComponent
)。我需要的是在底部显示一些固定选项,当单击顶部时,另一个选项会出现在该顶部选项下方,该选项保持在顶部
一个简单的例子。我有这个菜单:
Option 4
Option 2
Option 1
当点击Option 4
时,菜单变为
Option 4
Option 3
Option 2
Option 1
所以Option 4
向上移动并出现Option 3
。
我想在我的所有菜单周围都有一个“阴影”(为此我添加了一个DropShadow
组件)。
我有这个简单的测试代码,我有一个主要的Rectangle
(被阴影包围),里面有2个矩形。
Rect1
用于固定部分(Option 1
,Option 2
),Rect2
用于“可移动”部分(Option 3
,Option 4
)。
Rect2
在Rect1
(z: -1
) 后面,并且位于Option 2
上方只有Option 4
可见。点击Option 4
时,Rect2
向上移动,所有选项都可见。
为此,我必须更新Rect2
可见高度和主窗口位置(y
值),因为主窗口高度取决于此Rect2
可见高度。
我可以正常工作,但由于 2 个变量发生了变化(“固定面板”向上和向后移动),所以它经常闪烁。
我也尝试使用 ParallelAnimation
获取 2 个值,但没有成功。
有什么想法让这个菜单动作流畅吗?
Main.qml
:
import QtQuick 2.0
Rectangle
id: window
property variant win: undefined;
Component.onCompleted:
var component = Qt.createComponent("TestMenu.qml");
win = component.createObject(window, "x": 500, "y": 500);
win.show();
TestMenu.qml:
import QtQuick 2.0
import QtQuick.Window 2.1
import QtGraphicalEffects 1.0
Window
id: window
flags: Qt.Tool | Qt.FramelessWindowHint
height: panel.height
color: "transparent"
property int radiusShadow: 20
property int iOptionHeight: 30
Rectangle
id: panel
anchors centerIn: parent
height: menu1.height + menu2.heightVisible + 2*radiusShadow
width: window.width - 2*radiusShadow
color: "transparent"
Rectangle
id: menu1
anchors bottom: parent.bottom; bottomMargin: radiusShadow
width: parent.width
height: column1.children.length * iOptionHeight
Column
id: column1
anchors.fill: parent
Rectangle
color: "red";
Text text: qsTr("option 2")
height: iOptionHeight; width: parent.width
Rectangle
color: "green";
Text text: qsTr("option 1")
height: iOptionHeight; width: parent.width
Rectangle
id: menu2
property int heightVisible: iOptionHeight
anchors top: parent.top; topMargin: radiusShadow; left: menu1.left
width: parent.width
height: column2.children.length * iOptionHeight
z: -1
Column
id: column2
anchors.fill: parent
Rectangle
id: blue
property bool bOpen: false
color: "blue";
height: iOptionHeight; width: parent.width
Text text: qsTr("option 4")
MouseArea
anchors.fill: parent
onClicked:
blue.bOpen = !blue.bOpen;
panel.showHideMenu2(blue.bOpen);
Rectangle
color: "pink";
Text text: qsTr("option 3")
height: iOptionHeight; width: parent.width
function showHideMenu2(bShow)
if (bShow)
window.y -= iOptionHeight
menu2.heightVisible += iOptionHeight;
else
window.y += iOptionHeight
menu2.heightVisible -= iOptionHeight;
DropShadow
id: dropShadow
visible: true
anchors.fill: panel
radius: radiusShadow
samples: 24
color: "#40000000"
source: panel
【问题讨论】:
【参考方案1】:作为对您问题的快速回答,您可以使用Behavior
动画来获得所需的属性更改。
这里,Behavior
动画将用于y
(位置)更改您的window
,以及height
更改各个矩形。
这是我建议您应用的代码补丁以查看平滑运动:
@@ -10,6 +10,9 @@
property int radiusShadow: 20
property int iOptionHeight: 30
+ property int animationDuration: 500 // ms
+
+ Behavior on y NumberAnimation duration: window.animationDuration
Rectangle
id: panel
@@ -18,6 +21,7 @@
height: menu1.height + menu2.heightVisible + 2*radiusShadow
width: window.width - 2*radiusShadow
color: "transparent"
+ Behavior on height NumberAnimation duration: window.animationDuration
Rectangle
id: menu1
@@ -25,6 +29,7 @@
anchors bottom: parent.bottom; bottomMargin: radiusShadow
width: parent.width
height: column1.children.length * iOptionHeight
+ Behavior on height NumberAnimation duration: window.animationDuration
Column
id: column1
@@ -52,6 +57,8 @@
width: parent.width
height: column2.children.length * iOptionHeight
+ Behavior on height NumberAnimation duration: window.animationDuration
+
z: -1
Column
@@ -64,6 +71,7 @@
color: "blue";
height: iOptionHeight; width: parent.width
Text text: qsTr("option 4")
+ Behavior on height NumberAnimation duration: window.animationDuration
MouseArea
anchors.fill: parent
@@ -77,6 +85,7 @@
color: "pink";
Text text: qsTr("option 3")
height: iOptionHeight; width: parent.width
+ Behavior on height NumberAnimation duration: window.animationDuration
@@ -105,4 +114,4 @@
color: "#40000000"
source: panel
-+
【讨论】:
非常感谢您的帮助,但添加这些行为并不能解决我的问题。点击选项4的时候,所有的选项都移动了一点,效果真的很差……:( 这是您的计算错误,但不是平滑移动。当您尝试描述您的问题时,请更加具体。 对不起,如果我没有正确解释我的问题...你的意思是什么错误?我找不到什么问题。非常感谢 Diego,请尝试准确描述您想要获得的内容(如果需要,请添加图片/视频)。似乎需要质疑,因为关于平滑运动的问题已经得到解答。 我将尝试解释我想要什么:我希望 menu2 向上(查看选项 3 和选项 4),因此主窗口必须增加其高度(并且默认情况下也会向上移动以避免这种情况向下增加其高度)。在进行这些更改时,Menu1 应位于窗口底部。也许我使用的代码不是实现它的最佳方法。使用 Behaviour 时,我的 menu2 会平稳移动,但 menu1 会闪烁。也许有些计算不正确,但不是很复杂,我找不到问题出在哪里。感谢您的耐心【参考方案2】:我尝试过使用模型和 ListView(代码现在更简单),但我不知道在哪里以及如何插入“动画”或“行为”来实现我的目标,如果可以的话(我尝试了几个选项都没有成功...)
预期的效果是,当第二个矩形出现时,第一个矩形向上移动,因此底部的矩形保持在其位置(底部)。但是当我向模型添加元素时的默认行为是列表向下增加高度
也许任何人都可以帮忙...
我的代码:
import QtQuick 2.0
import QtQuick.Controls 1.4
Rectangle
id: rootItem
width: 400
height: list.height
ListModel
id: modelRects
ListElement rectColor: "green"
ListElement rectColor: "orange"
ListView
id: list
height: modelRects.count * 30
model: modelRects
delegate: Rectangle
id: delegate
height: 30
width: rootItem.width
color: rectColor
MouseArea
anchors.fill: parent
onClicked: onRectClicked(index);
function onRectClicked(index)
if (index == 0)
if (modelRects.count == 2)
modelRects.insert(1, "idRect": 2, "rectColor": "red");
else
modelRects.remove(1, 1);
【讨论】:
以上是关于QML“自定义菜单”选项向上移动的主要内容,如果未能解决你的问题,请参考以下文章