• Qt Quick 常用元素:TabView(选项卡) 与 Slider(滑块)


    一、TabView

    TabView 可以实现类似 Windows 任务管理器的界面,有人叫 TabView 为标签控件,有人又称之为选项卡控件,我们知道它就是这么个东西就行了。现在来介绍 TabView 的属性和方法。

    • count 属性是只读的,返回 TabView 内的标签页的个数。

    • currentlndex 属性代表当前标签页的索引,从 0 开始,可以读取也可以设置它来切换标签。

    • frameVisible 指示标签页对应的内容周围的边框是否可见。tabVisible 设置标签栏是否可见。

    • tabPosition 保存标签栏的位置,默认是 Qt.TopEdge,在界面顶部;置 tabPosition 为 Qt.BottomEdge,标签栏就会跑到界面底部。

    • addTab (title, component) 方法用于增加一个标签,第一个参数是标签的标题,第二个参数是一个组件,代表标签对应的可视控件。insertTab (index, title, component)在指定索引位置插入一个标签。

    • removeTab (index) 删除指定位置的标签。moveTab(from, to) 将一个标签从索引 from 移动到索引。getTab (index) 返回指定位置的标签对象(类型为Tab),Tab 对象只有一个 title 属性,是 Loader 的派生类。


    7.1 标签控件简单示例

    tabview_simple.qml 的内容如下:

    import QtQuick 2.2
    import QtQuick.Controls 1.2
    
    Rectangle {
         360;
        height: 240;
        color: "lightgray";
    
        Component {
            id: tabContent;
            Rectangle {
                implicitWidth: 100;
                implicitHeight: 100;
                anchors.fill: parent;
                color: Qt.rgba(Math.random(), Math.random(), Math.random());
            }
        }
    
        Button {
            id: addTab;
            x: 8;
            y: 8;
             60;
            height: 25;
            text: "AddTab";
            onClicked: {
                tabView.addTab("tab-" + tabView.count, tabContent);
            }
        }
    
        TabView {
            id: tabView;
            anchors.top: addTab.bottom;
            anchors.margins: 8;
            anchors.left: parent.left;
            anchors.right: parent.right;
            anchors.bottom: parent.bottom;
        }
    }
    

    执行后,点击四次 "AddTab" 按钮后,再选择 "tab-1" 后的效果图如下所示。


    太丑了点儿,对吧。没关系,咱们可以用 TabViewStyle 来定制。


    7.2 使用 TabViewStyle

    TabView 有 style 这个属性,可以为其指定一个 TabViewStyle 对象来定制 TabView。tabBar 绘制标签栏的背景。tab 绘制一个个的标签。frame 绘制 TabView 的边框。一般我们设置这三个属性即可打造一个美丽动人的 TabView。

    下面看一个示例:

    import QtQuick 2.2
    import QtQuick.Controls 1.2
    import QtQuick.Controls.Styles 1.2
    import QtQuick.Layouts 1.1
    
    Rectangle {
         360;
        height: 240;
        color: "lightgray";
        id: root;
        property var icons: ["call1.png", "call2.png", "call3.png"];
        Component.onCompleted: {
            tabView.addTab("ABC", tabContent);
            tabView.addTab("ZXY", tabContent);
            tabView.addTab("MQF", tabContent);
            tabView.addTab("WKJ", tabContent);
        }
    
        Component {
            id: tabContent;
            Rectangle {
                implicitWidth: 100;
                implicitHeight: 100;
                anchors.fill: parent;
                color: Qt.rgba(Math.random(), Math.random(), Math.random());
            }
        }
    
        TabView {
            id: tabView;
            anchors.fill: parent;
    
            style: TabViewStyle {
                tab: Item{
                    implicitWidth: Math.max(text.width + 8, 80);
                    implicitHeight: 48;
                    Rectangle {
                         (styleData.index < control.count - 1) ? (parent.width - 2) : parent.width;
                        height: parent.height - 4;
                        anchors.top: parent.top;
                        anchors.left: parent.left;
                        anchors.leftMargin: 1;
                        visible: styleData.selected;
                        gradient: Gradient {
                            GradientStop{position: 0.0; color: "#606060";}
                            GradientStop{position: 0.5; color: "#c0c0c0";}
                            GradientStop{position: 1.0; color: "#a0a0a0";}
                        }
                    }
                    Rectangle {
                         2;
                        height: parent.height - 4;
                        anchors.top: parent.top;
                        anchors.right: parent.right;
                        visible: styleData.index < control.count - 1;
                        gradient: Gradient {
                            GradientStop{position: 0.0; color: "#404040";}
                            GradientStop{position: 0.5; color: "#707070";}
                            GradientStop{position: 1.0; color: "#404040";}
                        }
                    }
                    RowLayout {
                        implicitWidth: Math.max(text.width, 72);
                        height: 48;
                        anchors.centerIn: parent;
                        z: 1;
                        Image{
                             48;
                            height: 48;
                            source: root.icons[styleData.index%3];
                        }
                        Text {
                            id: text;
                            text: styleData.title;
                            color: styleData.selected ? "blue" : (styleData.hovered ? "green" : "white");
                        }
                    }
                }
                tabBar: Rectangle {
                    height: 56;
                    gradient: Gradient {
                        GradientStop{position: 0.0; color: "#484848";}
                        GradientStop{position: 0.3; color: "#787878";}
                        GradientStop{position: 1.0; color: "#a0a0a0";}
                    }
                    Rectangle {
                         parent.width;
                        height: 4;
                        anchors.bottom: parent.bottom;
                        border. 2;
                        border.color: "#c7c7c7";
                    }
                }
            }
        }
    }
    

    执行后的效果图如下所示:


    TabViewStyle 对象的 tab 组件相对复杂一些,我设计为 “图标+文本” 的样式,图标在左, 文本在右。当选中标签时,使用 Rectangle 高亮背景。选中标签(styleData.selected为true)的文本,颜色为蓝色;未选中标签的文本,鼠标悬停(styleData.hovered为true)时为绿色,否则为白色。


    二、Slider

    Slider 类代表一个水平或垂直的滑块控件,通常用于让用户在某个取值范围内选择一个值。先来看一个示意图,见下图。


    滑块组件分为面板(panel)、滑槽(groove)、刻度线(tickmarks)和滑块(handle)四部分。而 Slider 对应的用来定制滑块控件外观的 SliderStyle 类,恰恰就有 groove、handle、 panel、tickmarks 四个组件。也就是说,滑块控件的每个组成部分,都可以定制。不过,我们一般只定制 handle 和 groove,其他两个定制起来稍微麻烦一些。

    • maximumValue 用来设置最大值,默认值为 1.0。minimumValue 用来设置最小值,默认值为0。value 代表滑块控件的当前值,默认值为 0,使用 onValueChanged 信号处理器可以跟踪滑块当前值的变化。

    • stepSize 用来设置滑块变化的步长,当你使用方向键调整滑块时,按一次它就增加或减少 stepSize 设定的值。

    • orientation 属性用来设置控件的方向,可以是水平的(Qt.Horizontal)或垂直的 (Qt. Vertical)。

    • updateValueWhileDragging 属性用来设置拖动滑块时控件的当前值是否变化,默认为 true。

    • tickmarksEnabled 属性指示是否显示刻度线,默认为 false。

    • hovered 属性指示鼠标是否悬停在控件上方,pressed 指示鼠标或手指是否按下。这两个属性都是只读的。

    • activeFocusOnPress 属性指示当用户按下鼠标或手指时,控件是否获得键盘焦点,默认为 false。

    现在隆重地介绍我们的重量级嘉宾:style。使用 style 属性,你就可以随心所欲地妆扮你的滑块控件了。一般,style 属性指向一个 SliderStyle 对象。


    2.1 SliderStyle

    SliderStyle 用来定制一个 Slider 的外观,你可以定制面板、滑槽、滑块、刻度线四部分。

    • control 属性指向应用此风格对象的滑块控件实例。
    • groove 属性指向滑槽组件,handle 指向滑块组件,tickmarks 指向刻度线组件,panel 指向面板组件,它们的类型都是 Component。

    需要说明的是,一般我们只需要定制 groove 和 handle 就能够得到不错的效果。


    2.2 滑块简单示例

    好啦,现在我们提供一个滑块的示例,看看 Slider 的各个属性的用法。slider_demo.qml 代码如下:

    import QtQuick 2.2
    import QtQuick.Controls 1.2
    import QtQuick.Controls.Styles 1.2
    
    Rectangle {
         320;
        height: 240;
        color: "lightgray";
        Row {
            anchors.fill: parent;
            spacing: 20;
            Column{
                 200;
                spacing: 16;
                Text {
                    id: sliderStat;
                    color: "blue";
                    text: "current - 0.1";
                }
                Slider {
                     200;
                    height: 30;
                    stepSize: 0.01;
                    value: 0.1;
                    onValueChanged: {
                        sliderStat.text = "current - " + value;
                    }
                    Component.onCompleted: console.log(activeFocusOnPress);
                }
    
                Slider {
                     200;
                    height: 30;
                    minimumValue: 0;
                    maximumValue: 100;
                    stepSize: 1;
                    value: 50;
                    tickmarksEnabled: true;
                }
                Slider {
                    id: customGrooveAndHandle;
                     200;
                    height: 30;
                    stepSize: 0.1;
                    value: 0;
                    tickmarksEnabled: true;
                    style: SliderStyle {
                        groove: Rectangle {
                            implicitWidth: 200;
                            implicitHeight: 8;
                            color: "gray";
                            radius: 8;
                        }
                        handle: Rectangle {
                            anchors.centerIn: parent;
                            color: control.pressed ? "white" : "lightgray";
                            border.color: "gray";
                            border. 2;
                             34;
                            height: 34;
                            radius: 12;
                        }
                    }
                }
                Slider {
                    id: customPanel;
                     200;
                    height: 36;
                    stepSize: 0.1;
                    value: 0;
                    tickmarksEnabled: true;
                    style: SliderStyle {
                        groove: Rectangle {
                            implicitWidth: 200;
                            implicitHeight: 8;
                            color: "gray";
                            radius: 8;
                        }
                        handle: Rectangle {
                            anchors.centerIn: parent;
                            color: control.pressed ? "white" : "lightgray";
                            border.color: "gray";
                            border. 2;
                             34;
                            height: 34;
                            radius: 12;
                            Text {
                                anchors.centerIn: parent;
                                text: control.value;
                                color: "red";
                            }
                        }
                        panel: Rectangle {
                            anchors.fill: parent;
                            radius: 4;
                            color: "lightsteelblue";
                            Loader {
                                id: grooveLoader;
                                anchors.centerIn: parent;
                                sourceComponent: groove;
                            }
                            Loader {
                                id: handleLoader;
                                anchors.verticalCenter: grooveLoader.verticalCenter;
                                x: Math.min(grooveLoader.x + (control.value * grooveLoader.width) / (control.maximumValue - control.minimumValue), grooveLoader.width - item.width);
                                sourceComponent: handle;
                            }
                        }
                    }
                }
            }
            Slider {
                 30;
                height: 200;
                orientation: Qt.Vertical;
                stepSize: 0.1;
                value: 0.2;
                tickmarksEnabled: true;
            }
        }
    }
    

    使用 qmlscene 加载 slider_demo.qml,效果如下图所示。


    参考:

    《Qt Quick核心编程》第9章


  • 相关阅读:
    浅谈Tarjan算法及思想
    浅谈前向星
    线段树初步
    树状数组的简单运用
    字典树(trie树)的指针简单实现pascal
    排序专辑
    POJ 2155 Matrix (矩形)
    区间动态规划
    hdu-2795 Billboard---线段树
    hdu-1754 I Hate It---线段树模板题
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/11953763.html
Copyright © 2020-2023  润新知