0


【QT】QML—— ListView添加固定表头的方法

在qt中构建界面时经常会对多个数据进行排列显示,可以使用qml提供的ListView组件来快速的构建一个列表模型来进行列表内容的分组显示;
通常的步骤是定义一个简单的ListView列表。创建一个Model并填入数据到其中;

Rectangle {id:rootRect;width:600;height:200;color:"grey";

    ListView {id:listView;width:parent.width;height:parent.height;clip:true;//对超出划定边界的数据进行裁剪
        delegate:modelItem;//自定义列表内容的组件,属性是Component//构建一个Model,也可以直接引入c++中的创建的model 运行程序可已看到生成了一个包含name,age,Heigth的列表model:ListModel {id: listModel;
         ListElement {name:"jack";age:"22";Height:"188cm"}
         ListElement {name:"mark";age:"19";Height:"178cm";}
         ListElement {name:"zhangsan";age:"17";Height:"177cm";}
         ListElement {name:"lisi";age:"27";Height:"167cm";}
         ListElement {name:"xiaoxiao";age:"25";Height:"18";}}}

   Component {id:modelItem;
       Rectangle {width:parent.width;height:40;color:"grey"
           Row {width:0.9*parent.width;
               anchors.left: parent.left;
               anchors.leftMargin:0.1*parent.width;height:parent.height;
               Label {text: name;
                   font.pixelSize:20;width:0.3*parent.width;
                   anchors.verticalCenter: parent.verticalCenter;verticalAlignment: Text.AlignHCenter;}
               Label {text: age;
                   font.pixelSize:20;width:0.3*parent.width
                   anchors.verticalCenter: parent.verticalCenter;verticalAlignment: Text.AlignHCenter;}
               Label {text: Height;
                   font.pixelSize:20;width:0.3*parent.width
                   anchors.verticalCenter: parent.verticalCenter;verticalAlignment: Text.AlignHCenter;}}}}}

以上的内容在qt运行显示的是一个基础的列表,但是一眼望去并不明确每一项的具体含义, 这样在一些使用过程中很不方便:具体的显示效果如下:
在这里插入图片描述
可以通过鼠标移动或者滚轮滑动查看列表的显示,但是对每一项的含义不是那么的直观,也有一种方法就是直接在model也就是列表的index为1的时候添加每一列的名称进去,显示的时候可以看到每一列的名称,具体代码如下,只需在model的第一列添加如下代码到最前面:(修改后的model如下)

model:ListModel {
    id: listModel;
    ListElement {
        name:"name";
        age:"age";
        Height:"height";}

    ListElement {
        name:"jack";
        age:"22";
        Height:"188cm"}
    ListElement {
        name:"mark";
        age:"19";
        Height:"178cm";}
    ListElement {
        name:"zhangsan";
        age:"17";
        Height:"177cm";}
    ListElement {
        name:"lisi";
        age:"27";
        Height:"167cm";}
    ListElement {
        name:"xiaoxiao";
        age:"25";
        Height:"181cm";}
    ListElement {
        name:"huahua";
        age:"38";
        Height:"188cm"}}

效果展示:
在这里插入图片描述
可以看到第一行有显示每一列数据的名字了,但是因为设置的字体显示与后面一致(可以单独对某一个index的item设置不同的参数来突出显示,这里不做过多说明),而且会随着滑动,而且数据多了会滑动消失,所以不推荐使用;
在qml中,可以ListView的特性创建一个列表头,显示每一项的具体含义;表头header的属性和delegate一样也是Component;通过自定义表头的组件显示到列表最上面;

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.4

Window {
    id: window
    width:640
    height:200
    visible: true
    title:qsTr("Hello World")//qml ListView组件/*
      定义一个简单的ListView列表,并创建一个Model填入数据,运行程序可已看到生成了一个包含name,age,Heigth但是一眼望去并不明确每一项的具体含义;
      利用ListView的特性创建一个列表头,显示每一项的具体含义;表头header的属性和delegate一样也是Component;
     */

    Rectangle {
        id:rootRect
        width:parent.width;
        height:parent.height;
        color:"darkgrey";

        ListView {
            id:listView;
            width:parent.width;
            height:parent.height;
            clip: true;//超出边界的数据进行裁剪
            delegate:modelItem;
            header:headerView;//只构建表头上滑动时表头也会跟随上滑动消失
            headerPositioning: ListView.OverlayHeader;//枚举类型/*
                ListView.OverlayHeader: 向上滑动直接覆盖表头
                ListView.InlineHeader:表头和内容是放置在一起的,移动也是一起移动,默认设置此属性;
                ListView.PullBackHeader:表头和内容是可以分开,向上滑动会顶上去看不见
            *///构建一个Model
            model:ListModel {
                id: listModel;
                ListElement {
                    name:"jack";
                    age:"22";
                    Height:"188cm"}
                ListElement {
                    name:"mark";
                    age:"19";
                    Height:"178cm";}
                ListElement {
                    name:"zhangsan";
                    age:"17";
                    Height:"177cm";}
                ListElement {
                    name:"lisi";
                    age:"27";
                    Height:"167cm";}
                ListElement {
                    name:"xiaoxiao";
                    age:"25";
                    Height:"18";}}}

        Component {
            id:headerView;
            Rectangle {
                width:parent.width;
                height:40;
                color:"lightgrey";
                z:2;//将表头的z坐标设置在上层,表头在设置属性为overlayHeader时就不会随滑动而消失,始终显示在最上面

                Row {
                    width:0.9*parent.width;
                    height: parent.height;
                    anchors.left: parent.left;
                    anchors.leftMargin:0.1*parent.width;

                    Label {
                        text:"name";
                        font.pixelSize:20;
                        width:0.3*parent.width;
                        anchors.verticalCenter: parent.verticalCenter;
                        verticalAlignment: Text.AlignHCenter;}
                    Label {
                        text:"age";
                        font.pixelSize:20;
                        width:0.3*parent.width
                        anchors.verticalCenter: parent.verticalCenter;
                        verticalAlignment: Text.AlignHCenter;}
                    Label {
                        text:"Height";
                        font.pixelSize:20;
                        width:0.3*parent.width
                        anchors.verticalCenter: parent.verticalCenter;
                        verticalAlignment: Text.AlignHCenter;}}}}

        Component {
            id:modelItem;
            Rectangle {
                width:parent.width;
                height:40;
                color:"grey"
                Row {
                    width:0.9*parent.width;
                    anchors.left: parent.left;
                    anchors.leftMargin:0.1*parent.width;
                    height:parent.height;
                    Label {
                        text: name;
                        font.pixelSize:20;
                        width:0.3*parent.width;
                        anchors.verticalCenter: parent.verticalCenter;
                        verticalAlignment: Text.AlignHCenter;}
                    Label {
                        text: age;
                        font.pixelSize:20;
                        width:0.3*parent.width
                        anchors.verticalCenter: parent.verticalCenter;
                        verticalAlignment: Text.AlignHCenter;}
                    Label {
                        text: Height;
                        font.pixelSize:20;
                        width:0.3*parent.width
                        anchors.verticalCenter: parent.verticalCenter;
                        verticalAlignment: Text.AlignHCenter;}}}}}}

如果表头还是会随着滑动消失,可以设置组件的z轴,让该组件显示在最上层,达到表头一直显示的效果;特别要注意的是需要设置ListView的headerPositioning的属性为ListView.OverlayHeader这个类型(三个类型的描述在代码里有注释),这个是向上滑动覆盖表头,但是因为表头的z轴设置的是最上层,所以并不会被覆盖,以此达到表头显示的效果。
以上的header添加后就可以在显示一个带表头的列表,并且列表滑动表头不会随着列表滑动,始终显示在最上方。实现效果显示如下:
在这里插入图片描述

可以看到表头一直显示到最上方,且不会随滑动消失。
还有一个问题就是一个点击穿透的问题,上滑后点击表头会触发列表内容的点击,如果有监控对列表的点击操作时点击表头就会造成误操作,这里就需要做一个放穿透效果,即在表头的组件中加上以下代码:

MouseArea {
    anchors.fill: parent;
    onPressed:{
        mouse.accepted = true;}}

如上所述。

标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/weixin_45054387/article/details/128525361
版权归原作者 南方有大雪 所有, 如有侵权,请联系我们删除。

“【QT】QML—— ListView添加固定表头的方法”的评论:

还没有评论