我正在使用复选框构建自定义QML ComboBox。它显示得很好,但我无法控制弹出结束事件。
我想组合框弹出窗口保持打开状态,所以我可以检查多个项目。只有当我点击我父母外面或点击逃生时才关闭。 目前我检查一个项目时立即关闭。
我正在使用CheckDelegate,因此我可以覆盖组合框弹出窗口。但是,它不会让我一次性检查多个项目。
以下是自定义组合框的示例代码
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 { }
}
}
}
对于组合框弹出框(checkbox_popup),我尝试将closePolicy设置为NoAutoClose,但没有运气。
所以我觉得在CheckDelegate的某个地方我需要捕获close事件或者处理它。但不确定我到底是怎么回事? 就QML而言,相当新手。
答案 0 :(得分:0)
这似乎是对Combobox代表的一个复杂的重写,也许不是正确的方法。
CheckDelegate继承了ItemDelegate,它负责您试图避免的行为(单击后关闭弹出窗口)。如果您使用其他项目覆盖代理,例如Rectangle,MouseArea或Item,然后自动关闭行为就会消失。
此外,组合框设计为一次选择一个currentItem。当currentItem发生变化时,它通常会返回一个currentIndex。为了改变这种行为,我觉得这是一场艰难的斗争,你可能更好的只是使用一个带有listview的弹出窗口,而不是一个Combobox。
然而,你的挑战看起来很有趣,所以这是修复你的组合框的一种方法:
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()
}
}
}
}
}
答案 1 :(得分:0)
我同意Mark的说法:ComboBox
用于在关闭时显示单个选定项目,因此选择多个项目没有意义。
但我也同意无论如何尝试它都很有趣。 :D这是一种利用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
}
}
}
}