ComboBox 组件如何确定弹出窗口是不是需要超出控制范围?

Posted

技术标签:

【中文标题】ComboBox 组件如何确定弹出窗口是不是需要超出控制范围?【英文标题】:How is ComboBox component able to determine if the popup needs to be above of control?ComboBox 组件如何确定弹出窗口是否需要超出控制范围? 【发布时间】:2021-10-06 11:50:38 【问题描述】:

我已经通过以下代码看到了这一点:

Window 
    width: 440
    height: 280
    visible: true
    
    ComboBox 
        id: control
        model: ["First", "Second", "Third"]
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 10

        delegate: ItemDelegate 
            width: control.width
            contentItem: Text 
                text: modelData
                color: "#21be2b"
                font: control.font
                elide: Text.ElideRight
                verticalAlignment: Text.AlignVCenter
            
            highlighted: control.highlightedIndex === index
        

        indicator: Canvas 
            id: canvas
            x: control.width - width - control.rightPadding
            y: control.topPadding + (control.availableHeight - height) / 2
            width: 12
            height: 8
            contextType: "2d"

            Connections 
                target: control
                function onPressedChanged()  canvas.requestPaint(); 
            

            onPaint: 
                context.reset();
                context.moveTo(0, 0);
                context.lineTo(width, 0);
                context.lineTo(width / 2, height);
                context.closePath();
                context.fillStyle = control.pressed ? "#17a81a" : "#21be2b";
                context.fill();
            
        

        contentItem: Text 
            leftPadding: 0
            rightPadding: control.indicator.width + control.spacing

            text: control.displayText
            font: control.font
            color: control.pressed ? "#17a81a" : "#21be2b"
            verticalAlignment: Text.AlignVCenter
            elide: Text.ElideRight
        

        background: Rectangle 
            implicitWidth: 120
            implicitHeight: 40
            border.color: control.pressed ? "#17a81a" : "#21be2b"
            border.width: control.visualFocus ? 2 : 1
            radius: 2
        

        popup: Popup 
            y: control.height - 1
            width: control.width
            implicitHeight: contentItem.implicitHeight
            padding: 1

            contentItem: ListView 
                clip: true
                implicitHeight: contentHeight
                model: control.popup.visible ? control.delegateModel : null
                currentIndex: control.highlightedIndex

                ScrollIndicator.vertical: ScrollIndicator  
            

            background: Rectangle 
                border.color: "#21be2b"
                radius: 2
            
        
    

(Qt 文档中的 ComboBox 示例,位于窗口底部)

如果您单击 ComboBox,弹出窗口将显示在控件上方(因为其下方空间不足)。我想知道是哪个信号或变量产生了这种自动行为,以便我可以捕获它并触发不同的操作。

【问题讨论】:

【参考方案1】:

我不确定我是否完全理解这个问题,但希望这能回答它。

弹出窗口中的代码使用三元组来导航弹出窗口的可见性。 See this post regarding QML conditional bindings (ternary operators)

model: control.popup.visible ? control.delegateModel : null

"如果弹出可见,设置模型等于委托模型。否则设置弹出模型为空"

让我们谈谈信号和插槽。如果您想轻松查看 qml 对象类型上的所有信号/插槽,请在块中输入“on”。然后从那里查看所有代码填充。您也可以查看 QT 文档。

如果我要实现这一点,我可能会使用弹出信号以不同的方式完成它:open()、close()。它将添加更多代码行,但会提高可读性并利用信号/槽机制。当前的方法在 QML 组件之间创建了非常紧密的耦合。


您好,谢谢您的回答!基本上我需要做的是与 弹出 y 坐标。更具体地说,评估要分配的条件 popup 的 y 属性,取决于还剩多少空间可以打开 它在控制之下......像这样:popup.y = some_condition? control.height - 1 : popup.implicitHeight + 1 QML 已经有办法了 要知道空间是否足够...然后重新调整弹出窗口 y 坐标。我想知道哪个内部机制处理这个问题。

想到了三种解决方法:

Use Layouts Use Component attributes/member data Use anchors

布局

将所有组件包装在列布局中。让您的列布局填满两个组件的组合空间。然后您可以设置每个组件的最小、首选和最大宽度/高度。此外,您可以为一个组件设置首选大小。然后调用 Layout.fill width/column 让它自动占用剩下的空间。

组件属性/成员数据

使用所有其他组件以数学方式计算 .y 数据。

popup.y = appWindow.y - componentWindow.y
or
popup.y = doMath(some property var of component X)

锚点

将您的弹出组件锚定到另一个组件。所以假设你想在某个矩形组件下方弹出一个弹出窗口。

Anchors.top = myRect.bottom

我非常喜欢使用嵌套布局来创建动态屏幕,这些屏幕总是以我期望的方式填充空间。它可以防止紧密耦合的组件,让 Qt 完成繁重的工作。

【讨论】:

您好,谢谢您的回答!基本上我需要做的是使用弹出 y 坐标。更具体地说,评估一个条件以分配弹出窗口的 y 属性,具体取决于在控件下方打开它的剩余空间量......就像这样:popup.y = some_condition? control.height - 1 : popup.implicitHeight + 1 QML 已经有办法知道空间是否足够……然后重新调整弹出的 y 坐标。我想知道哪个内部机制处理这个问题。 查看已编辑的帖子以获得答案 这段代码可以解决问题,但它是用 C++ 编写的:code.woboq.org/qt5/qtquickcontrols2/src/quicktemplates2/… 检查这个:void QQuickPopupPositioner::reposition()

以上是关于ComboBox 组件如何确定弹出窗口是不是需要超出控制范围?的主要内容,如果未能解决你的问题,请参考以下文章

C#中的combobox组件应该怎么用?

C#winform问题 datagridview中combobox选项改变触发事件用哪个方法

AWTK 设置下拉选择框 (combo box) 弹出窗口/列表项的样式

WPF在固定位置的切换按钮下方弹出窗口

C# 重写ComboBox实现下拉任意组件

HTML+CSS+JS实现点击超链接弹出文本框效果