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 1Option 2),Rect2 用于“可移动”部分(Option 3Option 4)。 Rect2Rect1 (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“自定义菜单”选项向上移动的主要内容,如果未能解决你的问题,请参考以下文章

Android中的自定义选项菜单栏问题

微信公众平台开发(24) 自定义菜单功能开发

《C#微信开发系列-自定义菜单管理》

微信公众号里面的自定义菜单限制字数不超过8个汉字或16个字母

在浏览器右键添加自定义菜单

怎么获得微信公众号(订阅号)自定义菜单接口权限?