使用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画左边线时要进行判断,是第一个则显示。如此,就大功造成了。