如何在QML中限制ComboBox下拉列表的大小

时间:2015-07-14 16:07:32

标签: qt combobox qml qtquick2

我在QML中使用ComboBox,当填充了大量数据时,它超出了我的主要Windows底层边框。通过谷歌搜索,我了解到ComboBox的下拉列表放在当前应用程序窗口的顶部,因此它不遵守其边界。

理想情况下,我希望ComboBox永远不会超过主应用程序边界,但我在documentation中找不到任何属性。

另一种方法是限制下拉列表中可见项的数量,使其不超过给定窗口几何的窗口限制。我在文档中也找不到这个,但我的想法已经用完了。

3 个答案:

答案 0 :(得分:2)

查看ComboBox源代码,弹出窗口属于Menu类型,并且它没有任何属性来限制其大小。此外,z的{​​{1}}属性为Menu,即总是

如果你发现没有办法,只能使用Qt的ComboBox你可以创建两个模型,一个用于视觉目的,我将其称为视觉模型,你将在你的ComboBox和完整的模型中显示它,它将是参考模型。 VisualModel中的项目数将等于您声明的某个int属性maximumComboBoxItemsCount。你需要找到一种方法,onHovered在visualmodel中找到鼠标下的索引,如果它是最大的,则可以使用visualModel.remove(0)和visualModel.add(referenceModel.add(referenceModel.get)达到maximumComboBoxIemsCount .. + 1)并且你需要另一个属性minimumComboBoxIemsCount,相同的逻辑但是对于Scroll Up,我不知道它是否会起作用。但它是一个想法

我认为没有使用内置组件的解决方案,您应该创建自己的comboBox。您可以从以下代码开始。

ComboBox.qml

infinite

ComboBoxButton.qml

import QtQuick 2.0 

Item {
    id: comboBox

    property string initialText
    property int maxHeight
    property int selectedItem:0
    property variant listModel
    signal expanded
    signal closed
    //    signal sgnSelectedChoice(var choice)
    width: 100
    height: 40
    ComboBoxButton {
        id: comboBoxButton
        width: comboBox.width
        height: 40
        borderColor: "#fff"
        radius: 10
        margin: 5
        borderWidth: 2
        text: initialText
        textSize: 12

        onClicked: {
            if (listView.height == 0)
            {
                listView.height = Math.min(maxHeight, listModel.count*comboBoxButton.height)
                comboBox.expanded()
                source = "qrc:/Images/iconUp.png"
            }
            else
            {
                listView.height = 0
                comboBox.closed()
                source = "qrc:/Images/iconDown.png"
            }
        }
    }

    Component {
        id: comboBoxDelegate

        Rectangle {
            id: delegateRectangle
            width: comboBoxButton.width
            height: comboBoxButton.height
            color: "#00000000"
            radius: comboBoxButton.radius
            border.width: comboBoxButton.borderWidth
            border.color: comboBoxButton.borderColor



            Text {
                color: index == listView.currentIndex ? "#ffff00" : "#ffffff"
                anchors.centerIn: parent
                anchors.margins: 3
                font.pixelSize: 12
                text: value
                font.bold: true
            }


            MouseArea {
                anchors.fill: parent

                onClicked: {
                    listView.height = 0
                    listView.currentIndex = index
                    comboBox.selectedItem = index
                    tools.writePersistence(index,5)
                    comboBoxButton.text = value
                    comboBox.closed()
                }
            }
        }
    }

    ListView {
        id: listView
        anchors.top: comboBoxButton.bottom
        anchors.left: comboBoxButton.left
        width: parent.width
        height: 0
        clip: true
        model: listModel
        delegate: comboBoxDelegate
        currentIndex: selectedItem
    }
    onClosed:  comboBoxButton.source = "qrc:/Images/iconDown.png"
    Component.onCompleted: {
        var cacheChoice = tools.getPersistence(5);
        listView.currentIndex = tools.toInt(cacheChoice)
        selectedItem = listView.currentIndex
        comboBoxButton.text = cacheModel.get(selectedItem).value
    }
}

我已经在我的某些软件中使用它,因此它可能无法正常工作"开箱即用"。我这样用它:

    import QtQuick 2.0 

Item {
    id: container
    signal clicked
    property string text
    property alias source : iconDownUp.source
    property string color: "#ffffff"
    property int textSize: 12
    property string borderColor: "#00000000"
    property int borderWidth: 0
    property int radius: 0
    property int margin: 0

    Rectangle {
        id: buttonRectangle
        anchors.fill: parent
        color: "#00000000"
        radius: container.radius
        border.width: container.borderWidth
        border.color: container.borderColor

        Image {
            id: image
            anchors.fill:  parent
            source: "qrc:/Images/buttonBackground.png"

            Image {
                id: iconDownUp
                source: "qrc:/Images/iconDown.png"
                sourceSize.height:20
                sourceSize.width: 20
                anchors.verticalCenter: parent.verticalCenter
            }
        }

        Text {
            id:label
            color: container.color
            anchors.centerIn: parent
            font.pixelSize: 10
            text: container.text
            font.bold: true
        }

        MouseArea {
            id: mouseArea;
            anchors.fill: parent
            onClicked: {
                container.clicked()
                buttonRectangle.state = "pressed"
                startTimer.start()
            }
        }
        Timer{
            id:startTimer
            interval: 200
            running: false;
            repeat: false
            onTriggered: buttonRectangle.state = ""
        }
        states: State {
            name: "pressed"
            when: mouseArea.pressed
            PropertyChanges { target: image; scale: 0.7 }
            PropertyChanges { target: label; scale: 0.7 }
        }

        transitions: Transition {
            NumberAnimation { properties: "scale"; duration: 200; easing.type: Easing.InOutQuad }
        }
    }
}

答案 1 :(得分:1)

可以访问MenuStyle组件中隐藏的ComboBoxStyle。在那里,您可以使用MenuStyle内的所有内容和隐藏的内容,包括其最大高度。

事情看起来大致如此。 不漂亮,但它运作良好。

ComboBox {
  id: comboBox

  style: ComboBoxStyle {

    // drop-down customization here
    property Component __dropDownStyle: MenuStyle {
      __maxPopupHeight: 400
      __menuItemType: "comboboxitem" //not 100% sure if this is needed
  }
}

答案 2 :(得分:0)

如果您正在使用Qt Quick Controls 2中的ComboBox,则为它的源代码:

https://github.com/qt/qtquickcontrols2/blob/5.12/src/imports/controls/ComboBox.qml

基于此,对行为的这种覆盖可将高度限制在合理范围内:

    myComboBox.popup.contentItem.implicitHeight = Qt.binding(function () {
        return Math.min(250, myComboBox.popup.contentItem.contentHeight);
    });