如何显示上面的ComboBox的Popup?
How to display Popup of ComboBox above?
我的自定义 ComboBox 工作正常,但我不明白如何使用组合框上方的元素列表弹出。
ComboBox {
id: pointsPositionComboBox
anchors.fill: parent
displayText: qsTr("Position point")
model: map.pointPositionModel
textRole: "name"
delegate: Row {
Rectangle {
id: delegateRect
width: pointsPositionRect.width - removePointRect.width
height: pointsPositionRect.height
color: {
if (!delegateRectMouseArea.containsMouse)
return "#25263C"
else if (delegateRectMouseArea.containsMouse
&& !delegateRectMouseArea.pressed) {
return "#5F8C6D"
} else if (delegateRectMouseArea.containsMouse
&& delegateRectMouseArea.pressed) {
return "#73AB84"
}
}
Text {
text: model.name
color: "white"
width: parent.width - removePointItem.width
font.pixelSize: pointsPositionComboBox.font.pixelSize
anchors.topMargin: pointsPositionRect.height / 3
anchors.left: parent.left
anchors.leftMargin: 5
}
MouseArea {
id: delegateRectMouseArea
anchors.fill: delegateRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
const latitude = model.position.latitude
const longitude = model.position.longitude
map.center.latitude = latitude
map.center.longitude = longitude
map.zoomLevel = model.zoomLevel
globalMapProperty.bearing = model.bearing
pointsPositionComboBox.popup.close()
}
}
}
Rectangle {
id: removePointRect
width: 30
height: 30
z: pointsPositionComboBox.z + 1
color: {
if (!removePointItemMouseArea.containsMouse)
return "#25263C"
else if (removePointItemMouseArea.containsMouse
&& !removePointItemMouseArea.pressed) {
return "#73A081"
} else if (removePointItemMouseArea.containsMouse
&& removePointItemMouseArea.pressed) {
return "#52785E"
}
}
Image {
id: removePointItem
anchors.centerIn: parent
source: removePointItemMouseArea.containsMouse ? "qrc:/icons/compass/remove_point_en.svg"
: "qrc:/icons/compass/remove_point_dis.svg"
}
MouseArea {
id: removePointItemMouseArea
anchors.fill: removePointRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
map.pointPositionModel.remove(map.pointPositionModel.index(index, 0))
}
}
}
}
}
Component.onCompleted: {
pointsPositionComboBox.popup.contentItem.implicitHeight = Qt.binding(function () {
// Делаем отображение только 10 элементов (остальные скроллом только)
return Math.min(pointsPositionRect.height * 10,
pointsPositionComboBox.popup.contentItem.contentHeight)
})
}
如何从顶部显示组合框元素列表,而不是像照片中那样从底部显示?
P.s。我设置 implicitHeight 用于在 Component.onCompleted 中显示组合框的元素
P.s.2 现在看起来像图片:
我使用 Popup
的 implicitHeight
来设置它的 y
属性。看看下面的来源。 Popup
的默认行为是,当它位于下方时,它将在下方打开,如果下方没有足够的 space,它将在 ComboBox
上方打开。以下代码是 Qt 文档中 Customizing ComboBox 示例的调整版本。
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
width: 400
height: 300
Row {
anchors.centerIn: parent
ComboBox {
id: control
model: ["First", "Second", "Third"]
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: 10
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: myCheckBox.checked ? -implicitHeight + 1 : 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
}
}
}
CheckBox {
id: myCheckBox
text: qsTr("above")
}
}
}
我的自定义 ComboBox 工作正常,但我不明白如何使用组合框上方的元素列表弹出。
ComboBox {
id: pointsPositionComboBox
anchors.fill: parent
displayText: qsTr("Position point")
model: map.pointPositionModel
textRole: "name"
delegate: Row {
Rectangle {
id: delegateRect
width: pointsPositionRect.width - removePointRect.width
height: pointsPositionRect.height
color: {
if (!delegateRectMouseArea.containsMouse)
return "#25263C"
else if (delegateRectMouseArea.containsMouse
&& !delegateRectMouseArea.pressed) {
return "#5F8C6D"
} else if (delegateRectMouseArea.containsMouse
&& delegateRectMouseArea.pressed) {
return "#73AB84"
}
}
Text {
text: model.name
color: "white"
width: parent.width - removePointItem.width
font.pixelSize: pointsPositionComboBox.font.pixelSize
anchors.topMargin: pointsPositionRect.height / 3
anchors.left: parent.left
anchors.leftMargin: 5
}
MouseArea {
id: delegateRectMouseArea
anchors.fill: delegateRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
const latitude = model.position.latitude
const longitude = model.position.longitude
map.center.latitude = latitude
map.center.longitude = longitude
map.zoomLevel = model.zoomLevel
globalMapProperty.bearing = model.bearing
pointsPositionComboBox.popup.close()
}
}
}
Rectangle {
id: removePointRect
width: 30
height: 30
z: pointsPositionComboBox.z + 1
color: {
if (!removePointItemMouseArea.containsMouse)
return "#25263C"
else if (removePointItemMouseArea.containsMouse
&& !removePointItemMouseArea.pressed) {
return "#73A081"
} else if (removePointItemMouseArea.containsMouse
&& removePointItemMouseArea.pressed) {
return "#52785E"
}
}
Image {
id: removePointItem
anchors.centerIn: parent
source: removePointItemMouseArea.containsMouse ? "qrc:/icons/compass/remove_point_en.svg"
: "qrc:/icons/compass/remove_point_dis.svg"
}
MouseArea {
id: removePointItemMouseArea
anchors.fill: removePointRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
map.pointPositionModel.remove(map.pointPositionModel.index(index, 0))
}
}
}
}
}
Component.onCompleted: {
pointsPositionComboBox.popup.contentItem.implicitHeight = Qt.binding(function () {
// Делаем отображение только 10 элементов (остальные скроллом только)
return Math.min(pointsPositionRect.height * 10,
pointsPositionComboBox.popup.contentItem.contentHeight)
})
}
如何从顶部显示组合框元素列表,而不是像照片中那样从底部显示?
P.s。我设置 implicitHeight 用于在 Component.onCompleted 中显示组合框的元素
P.s.2 现在看起来像图片:
我使用 Popup
的 implicitHeight
来设置它的 y
属性。看看下面的来源。 Popup
的默认行为是,当它位于下方时,它将在下方打开,如果下方没有足够的 space,它将在 ComboBox
上方打开。以下代码是 Qt 文档中 Customizing ComboBox 示例的调整版本。
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
width: 400
height: 300
Row {
anchors.centerIn: parent
ComboBox {
id: control
model: ["First", "Second", "Third"]
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: 10
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: myCheckBox.checked ? -implicitHeight + 1 : 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
}
}
}
CheckBox {
id: myCheckBox
text: qsTr("above")
}
}
}