【问题标题】:How to anchor a dialog to a button in listview qt qml如何将对话框锚定到listview qt qml中的按钮
【发布时间】:2020-10-24 13:17:36
【问题描述】:

我有一排带有按钮的列表视图委托。单击按钮时,我需要在该按钮下方打开一个对话框。我尝试了 mapToItem 属性并部分成功,但此列表视图是可滚动的,并且在滚动对话框时,它会保持在其初始位置。不确定如何让它工作。此外,发布问题的新手。如果我含糊不清,请忽略并帮助我。

我要打开的对话框位于此委托之外。我提供了我的代码的简短大纲。

Listview{
delegate: Row{
  Button1{
   }
  Button2{
   id: button2Id
   onCheckedChanged{
    var coords = button2Id.mapToItem(null,0,0)
    dialogId.x = coords.x
    dialogId.y= coords.y 
    dialogId.visible = true
    }
  }
 }
}

//dialog rect outside of my listview
Rectangle{
id: dialogId
}

【问题讨论】:

    标签: qt listview scroll qml


    【解决方案1】:

    您可以将对话框添加到列表的突出显示项。我对您的示例进行了一些修改,以便可以对其进行测试。我将您的Rectangle 封装在Item 中,因为ListView 控制突出显示的根对象的大小和位置。然后Rectangle 只需锚定到Item 的底部。

        ListView {
            id: lv
            width: 200
            height: parent.height
            model: 50
            spacing: 1
            currentIndex: -1
            delegate: Row {
                spacing: 1
                height: 40
                Button {
                    text: index
                }
                Button {
                    id: button2Id
                    text: ">"
                    onClicked: {
                        lv.currentIndex = index;
                    }
                }
            }
    
            highlight: Item {  // ListView controls the size/pos of this Item
                z: 1
    
                Rectangle {
                    id: dialogId
                    anchors.top: parent.bottom  // Anchor to bottom of parent
                    width: 200
                    height: 100
                    color: "red"
                }
            }
        }
    

    更新:

    这是一种使对话框直接位于按钮下方而不计算边距的方法。我把它放在Loader 中,这样列表中的每个项目并不总是随身携带整个对话框。它可能会产生性能差异。

    这个解决方案的丑陋部分是 z 排序。列表中的每个项目都绘制在它之前的项目之后。 (我实际上不确定这是否得到保证。)这意味着对话框会被绘制在列表中它之后的任何项目下方。我可以通过将列表中每个项目的 z 值更改为小于它之前的项目来解决这个问题。

    ListView {
        id: lv
        width: 200
        height: parent.height
        model: 50
        spacing: 1
        currentIndex: -1
        delegate: Row {
            z: lv.count - index // <<- z-value fix
            spacing: 1
            height: 40
            Button {
                text: index
            }
            Button {
                id: button2Id
                text: ">"
                onClicked: {
                    lv.currentIndex = index;
                }
    
                Loader {
                    anchors.top: parent.bottom
                    asynchronous: true
                    sourceComponent: (index === lv.currentIndex) ? dialogComp : null
                }
            }
        }
    }
    
    Component {
        id: dialogComp
        Rectangle {
            id: dialogId
            width: 200
            height: 100
            color: "red"
        }
    }
    

    【讨论】:

    • 谢谢。有效!只是想知道是否有任何方法可以将对话框直接放在按钮下方而不是使用边距?
    • 您只能将对象锚定到其直接父级或兄弟级。因此,理论上您可以使对话框成为按钮的子级或兄弟级,但我不推荐这样做。这意味着列表中的每个项目都会有一个对话框实例。
    • 我想这可以通过Loader 来改进。我将进行更新,展示如何完成。
    • 我一直在尝试使对话框在单击按钮时可见。除了您的代码之外,我还添加了 Button2{ onClicked{ dialogId.visible = true } } 并为 dialogId 设置了 visible: false 。但是,即使在定义别名时,我也会收到属性未定义错误。为什么会这样?
    • 当您单击按钮时,我的代码已经显示了对话框。我不确定你错过了什么。
    猜你喜欢
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    相关资源
    最近更新 更多