0

I've seen that with the following code:

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
            }
        }
    }
}

(The ComboBox example from Qt documentation, at the bottom of the window)

If you click on the ComboBox, the popup its shown above the control (because its out of space below). I would like to know which signal or variable makes this automatic behaviour, so that i can capture it and trigger a different action.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

0

I'm not sure I fully understand the question, but hopefully this answers it.

The code within popup uses a ternary to navigate the popup visibility. See this post regarding QML conditional bindings (ternary operators)

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

"If popup visible, set model equal to delegate model. Else set popup model null"

Lets talk about signals and slots. If you want to easily view all of the signal/slots on a qml object type go within the block and type 'on'. Then view all of the code fillins from there. You can check the QT documentation as well.

If I were to implement this, I may have done it differently using the popup signals: open(), close(). It will add more lines of code, but improve readability and utilize the signal/slot mechanism. The current method creates very tight coupling between QML components.


Hey, thanks for your answer! Basically what I need to do is work with popup y-coordinate. More specifically evaluate a condition to assign the y property of popup, depending on how much space is left to open it below the control... like this: popup.y = some_condition? control.height - 1 : popup.implicitHeight + 1 QML already has some way to know if the space is enough... and then readjust the popup y-coordinate. I would like to know which inner-mechanism handles this.

Three ways to tackle it come to mind:

Layouts

Wrap all of your components inside of a column layout. Have your column layout fill up the space of both components combined. Then you can set minimum, preferred, and maximum width/heights of each component. In addition, you could set the preferred size for one component. Then call Layout.fill width/column to have it automatically take up the rest of the space.

Component attributes/member data

Mathmatically calculate the .y data using all of your other components.

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

Anchors

Anchor your popup component to another component. So suppose you wanted a popup underneath some rectangle component.

Anchors.top = myRect.bottom

I'm a huge fan of using nested layouts to create dnyamic screens that always fill up spaces in the way I expect them to. It prevents tightly coupled components and lets Qt do the hard work.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Frebreeze
  • 202
  • 3
  • 10
  • Hey, thanks for your answer! Basically what I need to do is work with popup y-coordinate. More specifically evaluate a condition to assign the y property of popup, depending on how much space is left to open it below the control... like this: popup.y = some_condition? control.height - 1 : popup.implicitHeight + 1 QML already has some way to know if the space is enough... and then readjust the popup y-coordinate. I would like to know which inner-mechanism handles this. – msalichs Oct 06 '21 at 13:44
  • See edited post for answer – Frebreeze Oct 06 '21 at 15:36
  • This code does the trick, but it is in C++: https://code.woboq.org/qt5/qtquickcontrols2/src/quicktemplates2/qquickpopuppositioner.cpp.html Check this: void QQuickPopupPositioner::reposition() – Ponzifex Oct 07 '21 at 21:15