2017-07-13 1 views
0

Ich bin ein benutzerdefiniertes QML ComboBox mit Kontrollkästchen erstellen. Es zeigt alles gut an, aber ich bin nicht in der Lage, das Popup-Abschlussereignis zu steuern.Steuerelement schließen von Popup für QML ComboBox mit Kontrollkästchen

Ich möchte die Combobox Popup geöffnet bleiben, so dass ich mehrere Elemente überprüfen konnte. Und schließe nur, wenn ich außerhalb meines Elternteils klicke oder auf Flucht klicke. Momentan schließt es, sobald ich einen Gegenstand überprüfe.

Ich benutze das CheckDelegate, so dass ich die Combobox-Popup-Darstellung überschreiben konnte. Warten Sie nicht, lassen Sie mich mehrere Artikel auf einmal überprüfen.

Hier ist mein Beispielcode für die benutzerdefinierte 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 { } 
    } 
} 

} 

Für die Combobox Popup (checkbox_popup), habe ich versucht, die closePolicy zu NoAutoClose Einstellung, aber kein Glück.

So fühle ich mich irgendwo in der CheckDelegate Ich muss das nahe Ereignis oder so zu fangen und damit umgehen. Aber nicht genau, wie oder fehlt mir etwas? Ziemlich Neuling so weit wie QML betroffen ist.

Antwort

0

ich mit Mark einverstanden hier: ComboBox sollte ein einzelnes ausgewähltes Element angezeigt wird, wenn es geschlossen ist, so hat Mehrfachselektionen machen keinen Sinn.

Aber ich stimme auch zu, dass es Spaß macht, es trotzdem zu versuchen. : D Hier ist ein Weg, der die Tatsache ausnutzt, dass 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 
      } 
     } 
    } 
} 
+0

Super! Danke Mitch. Das funktioniert. Guter Trick!! Nun, wie @Mark erwähnt, wenn ComboBox für einzelne Auswahl verwendet werden soll, muss ich vielleicht ein wenig nachdenken. Ich hatte gehofft, ich könnte die Auswahl als eine elide Text in der Combo-Box anzeigen (contentItem). – pappachino

0

Dies scheint eine ziemlich komplizierte Überschreibung des Combobox Delegaten, und vielleicht nicht der richtige Ansatz.

CheckDelegate erbt ItemDelegate, das für genau das Verhalten verantwortlich ist, das Sie vermeiden möchten (Schließen des Popups nach einem einzigen Klick). Wenn Sie den Delegaten mit einem anderen Element überschreiben, z. Rectangle, MouseArea oder Item, dann würde das Autoclosing-Verhalten verschwinden.

Die Combobox ist so konzipiert, dass ein currentItem gleichzeitig ausgewählt wird. Wenn das currentItem geändert wird, gibt es normalerweise einen einzelnen currentIndex zurück. Um dieses Verhalten zu ändern, habe ich das Gefühl, dass es ein harter Kampf ist, und Sie könnten besser ein Popup mit einer Listenansicht anstelle einer Combobox verwenden.

jedoch Ihre Herausforderung sah Spaß, hier so ist eine Möglichkeit, Ihre Combobox der Befestigung:

ComboBox { 
    id: control 

    property bool forceOpen: false 

    model: ["alpha", "beta", "gamma"] 

    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 

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

    popup: Popup { 

     id: checkbox_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 { } 
     } 

     onClosed: if (control.forceOpen) open() 
    } 

    background: Rectangle { 
     implicitWidth: 120 
     implicitHeight: 40 

     border.width: !control.editable && control.visualFocus ? 2 : 0 
     visible: !control.flat || control.down 

     MouseArea { 
      anchors.fill: parent 
      onClicked: { 
       if (control.popup.visible) { 
        control.forceOpen = false 
        control.popup.close() 
       } else { 
        control.forceOpen = true 
        control.popup.open() 
       } 
      } 
     } 
    } 
} 
+0

Dank @mark für die Antwort. Ja, ich habe gelesen, dass der Delegierte ein ItemDelegate sein muss, aber ich dachte, dass es eine Möglichkeit geben würde, das Popup-Schließen zu deaktivieren. Ich habe versucht, Ihre Lösung, aber versuchen, es als Post-hook des Klicks geöffnet, fügt einen flackernden Effekt. – pappachino

+0

@pappachino oh richtig, ich fragte mich, ob es flimmern würde, aber es schien nicht, als ich auf Windows versuchte. Naja. –

Verwandte Themen