Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control closing of popup for QML ComboBox with checkboxes

I'm building a custom QML ComboBox with checkboxes. It displays all well, but I am not able to control the popup closing event.

I would like the combobox popup to stay open, so I could check multiple items. And close only if I click outside my parent or hit escape. Currently it closes as soon as I check one item.

I am using the CheckDelegate so I could override the combobox popup appearance. However it doesn't wait allow me to check multiple items in one go.

Here is my sample code for the custom combobox

import QtQuick 2.7
import QtQuick.Controls 2.1

ComboBox {
id: control

property alias combo_box_model: control.model
property string combo_box_displayText: control.displayText
property var combo_box_height

model: combo_box_model

delegate: CheckDelegate {
    id: checkbox_control

    width: control.width
    contentItem: Text {
        leftPadding: checkbox_control.indicator.width + control.leftPadding

        text: modelData
        font: control.font
        elide: Text.ElideRight
        verticalAlignment: Text.AlignVCenter
    }
    highlighted: control.highlightedIndex === index
//        checked: combo_box_model.isChecked(index)

    indicator: Rectangle {
            implicitWidth: 26
            implicitHeight: 26
            x: control.leftPadding
            anchors.verticalCenter: parent.verticalCenter

            radius: 3
            color: "transparent"
            border.color: checkbox_control.down ? "#17a81a" : "#21be2b"

            Rectangle {
                width: 14
                height: 14
                x: 6
                y: 6
                radius: 2
                color: checkbox_control.down ? "#17a81a" : "#21be2b"
                visible: checkbox_control.checked
            }
    }

//        onClicked: {
//            combo_box_model.setChecked(index, checked)
//        }

}

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

    text: control.displayText
    font: control.font
    horizontalAlignment: Text.AlignLeft
    verticalAlignment: Text.AlignVCenter
    elide: Text.ElideRight
}

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

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

        ScrollIndicator.vertical: ScrollIndicator { }
    }
}

}

For the combobox popup (checkbox_popup), I tried setting the closePolicy to NoAutoClose, but no luck.

So I feel somewhere in the CheckDelegate I need to catch the close event or so and handle it. But not sure exactly how or am I missing something ? Quite a newbie as far as QML is concerned.

like image 969
pappachino Avatar asked Oct 18 '25 07:10

pappachino


1 Answers

I agree with Mark here: ComboBox is meant to display a single selected item when it is closed, so having multiple selections doesn't make sense.

But I also agree that it's fun to try it anyway. :D Here's a way that exploits the fact that ComboBox relies on the delegate being an AbstractButton:

import QtQuick 2.6
import QtQuick.Controls 2.0

ApplicationWindow {
    id: window
    visible: true
    width: 640
    height: 480

    ComboBox {
        id: comboBox
        model: ListModel {
            ListElement {
                name: "A"
                checked: false
            }
            ListElement {
                name: "B"
                checked: false
            }
            ListElement {
                name: "C"
                checked: false
            }
        }

        delegate: Item {
            width: parent.width
            implicitHeight: checkDelegate.implicitHeight

            CheckDelegate {
                id: checkDelegate
                width: parent.width
                text: model.name
                highlighted: comboBox.highlightedIndex === index
                checked: model.checked
                onCheckedChanged: model.checked = checked
            }
        }
    }
}
like image 126
Mitch Avatar answered Oct 21 '25 06:10

Mitch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!