前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qml获取某个控件的全局坐标

Qml获取某个控件的全局坐标

作者头像
Qt君
发布2023-03-17 14:20:30
2.5K0
发布2023-03-17 14:20:30
举报
文章被收录于专栏:跟Qt君学编程

源于一个Qml项目需求。需要在界面显示菜单栏,但菜单栏需要根据控件的所在位置显示。如下演示:

  点击详情(detail)按钮调出菜单列表。菜单栏的位置需要定位详情按钮的下面,那么就需要知道具体坐标。

  由于Qml控件的坐标是相对坐标(相对于父控件的坐标),既然是相对父控件的坐标,那么我们遍历所有父控件的坐标进行累加就可以计算出该控件的全局坐标了。

实现代码

代码语言:javascript
复制
function getGlobalPosition(targetObject) {
    var positionX = 0 
    var positionY = 0
    var obj = targetObject
    
    /* 遍历所有的父窗口 */
    while (obj != null) {
        /* 累加计算坐标 */
        positionX += obj.x
        positionY += obj.y
        
        obj = obj.parent
    }
    
    return {"x": positionX, "y": positionY}
}

演示例子代码

代码语言:javascript
复制
import QtQuick 2.0

Rectangle {
    id: root
    anchors.fill: parent
    color: "white"

    /* 网格视图 */
    GridView {
        id: gridView
        anchors.centerIn: parent
        width: parent.width / 2
        height: parent.height / 2
        
        /* 设置单元格大小 */
        cellWidth: width / 2
        cellHeight: height / 2
        
        model: 4
        
        delegate: Item {
            id: itemDelegate
            width: gridView.cellWidth
            height: gridView.cellHeight
            
            Column {
                id: column
                anchors.centerIn: parent
                width: parent.width - 20
                height: parent.height - 20
                spacing: 10
                
                /* 内容方框 */
                Rectangle {
                    width: parent.width
                    height: parent.height * 3 / 4
                    
                    color: "#00000000"
                    border.color: "#d5d5d5"
                    
                    Column {
                        x: 10; y: 10
                        
                        Text {
                            text: "Title1"
                            font.pixelSize: 15
                        }
                        
                        Text {
                            text: "Sub title2"
                            font.pixelSize: 13
                        }
                    } 
                    
                    Text {
                        anchors.right: parent.right
                        anchors.bottom: parent.bottom
                        anchors.rightMargin: 8
                        anchors.bottomMargin: 8
                        
                        text: "==="
                        font.pixelSize: 13
                    }
                    
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {}
                    }
                }
                
                /* 圆形详情按钮,点击可调出菜单栏 */
                Row {
                    spacing: 10
                    
                    Rectangle {
                        width: 20
                        height: 20
                        radius: 10
                        color: "gray"
                        
                        MouseArea {
                            anchors.fill: parent
                            onClicked: {
                                /* 触发“详情按钮”,动态调整菜单栏的位置 */
                                menu.x = getGlobalPosition(this).x + this.width
                                menu.y = getGlobalPosition(this).y + this.height
                                
                                menu.visible = !menu.visible
                            }
                        }
                    }
                    
                    Text {
                        text: "detail"
                    }
                }

            }
        }
    }
    
    /* 获取相对于根窗口的全局的坐标,输入参数为需要获取全局坐标的对象 */
    function getGlobalPosition(targetObject) {
        var positionX = 0 
        var positionY = 0
        var obj = targetObject
        
        /* 遍历所有的父窗口 */
        while (obj != null) {
            /* 累加计算坐标 */
            positionX += obj.x
            positionY += obj.y
            
            obj = obj.parent
        }
        
        return {"x": positionX, "y": positionY}
    }
    
    /* 菜单栏 */
    Rectangle {
        id: menu
        visible: false
        width: 90
        height: 90
        border.width: 1
        border.color: "#d5d5d5"
        
        ListView {
            id: listView
            width: menu.width - 2
            height: menu.height -2 
            anchors.centerIn: parent
            interactive: false
            
            model: ["Title1", "Title2", "Title2"]
            
            delegate:
                Rectangle {
                    width: listView.width 
                    height: listView.height / 3
                    color: mouseArea.pressed || mouseArea.isEntered ? "#0078d8" : "white"
                    
                    MouseArea {
                        id: mouseArea
                        property bool isEntered: false
                        
                        anchors.fill: parent
                        hoverEnabled: true
                        onEntered: isEntered = true
                        onExited: isEntered = false
                        onClicked: menu.visible = false
                    }
                
                    Text {
                        anchors.centerIn: parent
                        text: modelData
                        color: mouseArea.pressed || mouseArea.isEntered ? "white" : "black"
                    }
                
                    Rectangle { 
                        visible: index !== 0
                        width: menu.width
                        height: 1
                        color: menu.border.color
                    }
                }
        }
    }
}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现代码
  • 演示例子代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档