使用qml 创建带不重叠线框Table

使用qml可以使用TableView轻松的自定义出个性化的表格,但我发现使用TableView创建表格时,如果将itemDelegate设置为矩形框那么边框会有重叠,导致粗细不一样

于是开始了研究,以下为代码示例创建不重叠线框Table。

Window {  //窗体根对象
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Item{
        anchors.fill: parent
        TableView{
            x:50
            y:50
            width: 500
            height: 350
            backgroundVisible: false //隐藏表格默认背景色(白色)
            frameVisible: false //隐藏表格最外面的矩形框线
            model: ListModel{ //使用ListModel,并加入测试数据
                ListElement{
                    name: "张三"
                    age: 34
                    sex: "男"
                }
                ListElement{
                    name: "张三"
                    age: 34
                    sex: "男"
                }
                ListElement{
                    name: "张三"
                    age: 34
                    sex: "男"
                }
            }
            headerDelegate: headDel  //表格头委托
            rowDelegate: rowDel    //表格行委托
            itemDelegate: Item{  //数据item委托
                Canvas{  //创建一个画布画矩形框的左边垂直线
                    width: 1 //宽度为1
                    height: parent.height    //高度为item的高度
                    anchors.left: parent.left //为item靠左对齐
                    visible: styleData.column == 0 ? true : false  //如果当前列是0列则显示,防止重叠
                    onPaint: {
                        var ctx = getContext("2d"); //获取画笔对象
                        ctx.strokeStyle = "red";  //设置颜色
                        ctx.lineWidth = 1;  //设置宽度,默认为1,可不写

                        ctx.beginPath();  //开始画路径
                        ctx.moveTo(0,0);  //移动到0,0点
                        ctx.lineTo(0,height); //移动到0,height点,此时为左边竖线
                        ctx.stroke();  //画出该图形
                    }
                }

                Canvas{ //画矩形框底线,每个item都要画
                    width: parent.width
                    height: 1
                    anchors.bottom: parent.bottom
                    onPaint: {
                        var ctx = getContext("2d");
                        ctx.beginPath();
                        ctx.moveTo(0,0);
                        ctx.lineTo(width,0);
                        ctx.stroke();
                    }
                }

                Canvas{//画矩形框右边竖线,每个item都要画
                    width: 1
                    height: parent.height
                    anchors.right: parent.right
                    onPaint: {
                        var ctx = getContext("2d");
                        ctx.beginPath();
                        ctx.moveTo(0,0);
                        ctx.lineTo(0,height);
                        ctx.stroke();
                    }
                }

                Text{ //数据显示
                    color: "black"
                    anchors.centerIn: parent
                    text: styleData.value
                }
            }

            Component{ //表头委托,用于设置表头行高,内容显示,色彩等
                id: headDel
                Rectangle{
                    color: "transparent"
                    border.width: 1
                    radius: 3
                    height: 23
                    Text{
                        anchors.centerIn: parent
                        text: styleData.value
                        color: "black"
                    }
                }
            }

            Component{ //行委托,用于设置行高和每行背景色等,此处为透明
                id: rowDel
                Item{
                    height: 20
                }
            }

            TableViewColumn{ //加入姓名列
                title: "姓名"
                role: "name"
                width: 60
            }

            TableViewColumn{ //加入年龄列
                title: "年龄"
                role: "age"
                width: 60
            }

            TableViewColumn{ //加入性别列
                title: "性别"
                role: "sex"
                width: 50
            }
        }
    }
}

完以上代码便可以看到一个带虚线框的table了,而且所有item显示的线都是单线,没有重叠。这里利用了表头矩形框的底线,以此为起点,那么第一行的每个item就不用画上边线;而由于每个item都会画下边线,所以第二列也就不用画上边线,以此内推后面都不用画上边线了;而左右是一样的,只需要画一边就可以了,由于第一列的左边需要一根线,所以每个item画左边线时要进行判断,是第一个则显示。如此,就大功造成了。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值