【问题标题】:QML ComboBox item DropDownMenu styleQML ComboBox 项目 DropDownMenu 样式
【发布时间】:2015-01-21 06:38:01
【问题描述】:

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

以下代码应用了自定义,但没有为保持灰色的下拉菜单定义修改:

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
}

【问题讨论】:

    标签: c++ qt user-interface qml


    【解决方案1】:

    当前的公共 API 不允许自定义下拉菜单,如 here 所述。 Qt 5.4,即Styles 1.3,刚刚引入了一些属性来自定义字体和文本(文档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。总体结果:

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

    【讨论】:

    • 我刚刚在 Mac OS X 10.9 上测试了这段代码,想知道它对我不起作用。您能否建议我进行一些与 OS X 相关的编辑以使其正常工作。不过,在 Windows 平台上一切正常。
    • 好吧,我当时只在 Windows/Android 上尝试过代码,抱歉。 :) 您可以检查 Qt 安装中的 qml 样式文件(搜索像 qml/QtQuick/Controls/Styles/Desktop 这样的子路径)以查看 w.r.t 的变化。 Windows 并尝试调整解决方案。在我这边,我将在我的 Mac 上测试代码以提供解决这个特定问题的编辑(显然因为我有空闲时间)。
    • 这非常有用!谢谢!
    【解决方案2】:

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

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

    【讨论】:

    • 这是更好的答案。谢谢!
    【解决方案3】:

    使用当前 Qt(截至 2020 年),可以通过指定 backgroundcontentItemindicatordelegate 开箱即用地自定义 ComboBox: https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-combobox

    【讨论】:

      【解决方案4】:

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

      我已经完成了ComboBox 的实现,它由两部分组成:一个您实际放置在某处的标题和一个您动态创建的下拉组件。后者由一个覆盖所有内容(并拦截鼠标活动)的Item 和一个小心放置在标题下方的下拉列表组成。

      此处包含大量代码,因此您可以查看详细信息in my blogpost with all the code

      【讨论】:

        猜你喜欢
        • 2018-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-02
        • 1970-01-01
        • 2017-06-15
        • 2023-04-09
        相关资源
        最近更新 更多