首页 文章

QML ComboBox项目DropDownMenu样式

提问于
浏览
10

我想在我的项目中使用 ComboBox 类型 . 是否可以更改下拉菜单的外观(颜色,形状,文本样式),还是需要使用矩形, ListView 和其他类型的组合?

以下代码应用自定义,但没有为下拉菜单定义修改,该菜单仍为灰色:

ComboBox {
    currentIndex: 2
    activeFocusOnPress: true
    style: ComboBoxStyle {
        id: comboBox
        background: Rectangle {
            id: rectCategory
            radius: 5
            border.width: 2
            color: "#fff"

            Image {
                source: "pics/corner.png"
                anchors.bottom: parent.bottom
                anchors.right: parent.right
                anchors.bottomMargin: 5
                anchors.rightMargin: 5
            }
        }
        label: Text {
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            font.pointSize: 15
            font.family: "Courier"
            font.capitalization: Font.SmallCaps
            color: "black"
            text: control.currentText
        }
    }

    model: ListModel {
        id: cbItems
        ListElement { text: "Banana" }
        ListElement { text: "Apple" }
        ListElement { text: "Coconut" }
    }
    width: 200
}

3 回答

  • 14

    当前的公共API不允许自定义下拉菜单,如here所述 . Qt 5.4 ,即 Styles 1.3 ,刚刚介绍了一些属性来自定义字体和文本(docs here),但仍无法公开访问下拉式自定义 .

    此外,链接中提供的示例不适用于较新版本的Qt . 这是我用Qt 5.3,Qt 5.4和Qt 5.5测试的修改版本(记得在导入中添加 import QtQuick.Controls.Private 1.0 ):

    ComboBox {
        id: box
        currentIndex: 2
        activeFocusOnPress: true
        style: ComboBoxStyle {
            id: comboBox
            background: Rectangle {
                id: rectCategory
                radius: 5
                border.width: 2
                color: "#fff"
            }
            label: Text {
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                font.pointSize: 15
                font.family: "Courier"
                font.capitalization: Font.SmallCaps
                color: "black"
                text: control.currentText
            }
    
            // drop-down customization here
            property Component __dropDownStyle: MenuStyle {
                __maxPopupHeight: 600
                __menuItemType: "comboboxitem"
    
                frame: Rectangle {              // background
                    color: "#fff"
                    border.width: 2
                    radius: 5
                }
    
                itemDelegate.label:             // an item text
                    Text {
                    verticalAlignment: Text.AlignVCenter
                    horizontalAlignment: Text.AlignHCenter
                    font.pointSize: 15
                    font.family: "Courier"
                    font.capitalization: Font.SmallCaps
                    color: styleData.selected ? "white" : "black"
                    text: styleData.text
                }
    
                itemDelegate.background: Rectangle {  // selection of an item
                    radius: 2
                    color: styleData.selected ? "darkGray" : "transparent"
                }
    
                __scrollerStyle: ScrollViewStyle { }
            }
    
            property Component __popupStyle: Style {
                property int __maxPopupHeight: 400
                property int submenuOverlap: 0
    
                property Component frame: Rectangle {
                    width: (parent ? parent.contentWidth : 0)
                    height: (parent ? parent.contentHeight : 0) + 2
                    border.color: "black"
                    property real maxHeight: 500
                    property int margin: 1
                }
    
                property Component menuItemPanel: Text {
                    text: "NOT IMPLEMENTED"
                    color: "red"
                    font {
                        pixelSize: 14
                        bold: true
                    }
                }
    
                property Component __scrollerStyle: null
            }
        }
    
        model: ListModel {
            id: cbItems
            ListElement { text: "Banana" }
            ListElement { text: "Apple" }
            ListElement { text: "Coconut" }
        }
        width: 200
    }
    

    这里 __dropDownStyle 分配了MenuStyle类型 . 这种类型的一些属性被定制以获得期望的样式,特别是 itemDelegate (其定义组合框内的项目的外观)和 frame (整体背景) . 有关更多详细信息,请参阅链接的 MenuStyle API . 总体结果:

    enter image description here

    请注意,此方法在Windows和Android上完美运行,而在OSX上,代码完全被忽略 . 可以检查Qt安装中的qml样式文件(搜索类似 qml/QtQuick/Controls/Styles/Desktop 的子路径)以查看w.r.t的更改 . Windows并尝试调整提供的解决方案 . 这部分留给读者 .

  • 0

    非常感谢!我通过下一个代码解决了这个

    Item {
    id: app
    width: 200
    height: 150
    
    ListModel{
        id: dataModel
        ListElement{ name: "Day" }
        ListElement{ name: "Week" }
        ListElement{ name: "Month" }
        ListElement{ name: "Year" }
    }
    
    Button {
        id: comboButton
        width: parent.width
        height: parent.height / 5
        checkable: true
    
        style: ButtonStyle {
           background: Rectangle {
               color: control.pressed ? "#888" : "#fff"
               smooth: true
               radius: 5
               border.width: 2
    
               Image {
                   source: "pics/corner.png"
                   anchors.bottom: parent.bottom
                   anchors.right: parent.right
                   anchors.bottomMargin: 5
                   anchors.rightMargin: 5
               }
           }
           label: Text {
                renderType: Text.NativeRendering
                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter
                font.family: "Courier"
                font.capitalization: Font.SmallCaps
                font.pointSize: 15
                color: "black"
                text: "Day"
            }
        }
        onVisibleChanged: {
            if(!visible)
                checked = false
        }
    }
    
    TableView {
        id: tableView
        height: 120
        width: parent.width
        anchors.bottom: parent.bottom
        highlightOnFocus: true
        headerVisible: false
        visible: comboButton.checked ? true : false
    
        TableViewColumn {
            role: "name"
        }
        model: dataModel
    
        itemDelegate: Item {
            Rectangle {
                color: styleData.selected  ? "#888" : "#fff"
                height: comboButton.height - 0.5
                border.width: 0.5
                width: parent.width
    
                Text {
                    renderType: Text.NativeRendering
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.horizontalCenter: parent.horizontalCenter
                    font.family: "Courier"
                    font.capitalization: Font.SmallCaps
                    font.pointSize: 15
                    color: "black"
                    elide: styleData.elideMode
                    text: styleData.value
                }
            }
        }
    
        rowDelegate: Item {
            height: comboButton.height - 0.5
        }
    
        onClicked: {
           comboButton.checked = false
           tableView.selection.clear()
        }
    }
    }
    

    enter image description here

  • 5

    我一直在使用这样的方法,但它们在 focus 管理和 z-index 管理方面有很多限制 .

    我最终得到了 ComboBox 的实现,它由两部分组成:一个实际放在某处的 Headers 和一个动态创建的下拉组件 . 后者包括 Item 覆盖所有内容(和拦截鼠标活动)和一个小心地位于 Headers 下方的下拉列表 .

    代码非常庞大,因此您可以查看详细信息in my blogpost with all the code

相关问题