注: 該博文為原創博文,轉載請注明,摘用請隨意;
qml自帶的滾動條不太好用;
首先,利用canvas繪制滾動條兩端的箭頭:
import QtQuick 2.0 Canvas { width: 20; height: 20; property real dir: 0; //0: up; 1: right; 2: down; 3: left; onPaint: { var ctx = getContext("2d") ctx.fillStyle = Qt.rgba(0.1,0.1,0.1,0.7); ctx.clearRect(0,0,width,height) ctx.fillRect(0,0,width,height) ctx.beginPath(); switch(dir) { case 0: //up; ctx.moveTo(width/2,1/4 * height); ctx.lineTo(width/4,3/4 * height); ctx.lineTo(width * 3/4, 3/4 * height); ctx.lineTo(width/2,1/4 *height); break; case 1: //right; ctx.moveTo(width * 3/4,1/2 * height); ctx.lineTo(width/4,1/4 * height); ctx.lineTo(width/4, 3/4 * height); ctx.lineTo(width * 3/4,1/2 *height); break; case 2: //down; ctx.moveTo(width/2,3/4 * height); ctx.lineTo(width * 3/4,1/4 * height); ctx.lineTo(width * 1/4, 1/4 * height); ctx.lineTo(width/2,3/4 *height); break; case 3: //left; ctx.moveTo(width/4,1/2 * height); ctx.lineTo(width *3/4,3/4 * height); ctx.lineTo(width * 3/4, 1/4 * height); ctx.lineTo(width/4,1/2 *height); break; } ctx.closePath(); ctx.fillStyle = Qt.rgba(1,1,1,0.7); ctx.fill(); } }
然后,自定義整個滾動條:
import QtQuick 2.0 Rectangle { property Item attachItem; property bool bHScroll: false; property real barSize : 20; property bool bSpace: false; //是否留空; property real size: 1; color:Qt.rgba(0.1,0.1,0.1,0.1); border.color:Qt.rgba(0.8,0.8,0.8,0.8); border.width: 1; width: bHScroll ? attachItem.width : barSize; height: bHScroll ? barSize : attachItem.height; anchors{ left: bHScroll ? attachItem.left : undefined; right: attachItem.right; top: bHScroll? undefined : attachItem.top; bottom: attachItem.bottom; rightMargin: bHScroll? (bSpace? barSize: 0): undefined; bottomMargin: bHScroll? undefined: (bSpace? barSize: 0) } function scroll(dir) { var step; if( bHScroll) { step= (scrollBtnArea.width - btnRect.width)/10; if( dir < 0 ) //left scroll; btnRect.x= btnRect.x - step > 0? btnRect.x - step : 0; else btnRect.x = btnRect.x + step < scrollBtnArea.width - btnRect.width? btnRect.x + step : scrollBtnArea.width - btnRect.width ; }else{ step = (scrollBtnArea.height - btnRect.height)/10; if( dir < 0 ) btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ; else btnRect.y = btnRect.y + step < scrollBtnArea.height - btnRect.height? btnRect.y + step : scrollBtnArea.height - btnRect.height; } } Arrow{ id: arrow1; anchors{ left: parent.left; top: parent.top; bottom: bHScroll ? parent.bottom : undefined; right: bHScroll ? undefined:parent.right; } width: barSize; height: barSize; dir: bHScroll? 3: 0; MouseArea{ anchors.fill: parent; onClicked:{ var step =2; if(bHScroll) { btnRect.x = btnRect.x - step > 0? btnRect.x - step : 0; }else{ btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ; } } } } Rectangle{ id: scrollBtnArea; color:Qt.rgba(0.1,0.1,0.1,0.7); anchors{ left: bHScroll? arrow1.right : parent.left; right: bHScroll? arrow2.left : parent.right; top: bHScroll? parent.top: arrow1.bottom; bottom: bHScroll? parent.bottom : arrow2.top; } Rectangle{ id: btnRect; x: bHScroll? 0 : 2; y: bHScroll? 2: 0; width: bHScroll? parent.width/size : barSize -4; height: bHScroll? barSize -4 : parent.height/size; color:Qt.rgba(0.1,0.1,0.1,0.7); border.color: Qt.rgba(1,1,1,0.2); border.width: 1; onXChanged:{ if(bHScroll) { var children = attachItem.children; for( var child in children) { var ratio =btnRect.x/(arrow2.x - btnRect.width) children[child].x= - ratio * ( size - 1) * attachItem.width ; console.log("x changed:"+ btnRect.x +";"+arrow1.x+";"+arrow1.width+";"+arrow2.x +";" + btnRect.width+";"+ratio + ";"+ children[child].x +";" + size + ";" + attachItem.width); } } } onYChanged:{ console.log("y changed"); if( !bHScroll) { var children = attachItem.children; for( var child in children) { children[child].y = -btnRect.y/(arrow2.y - btnRect.height) * ( size- 1) * attachItem.height; } } } } MouseArea{ id:mouseFunc; hoverEnabled: true; anchors.fill: parent; acceptedButtons: Qt.AllButtons drag.target: btnRect; drag.axis: bHScroll? Drag.XAxis : Drag.YAxis; drag.minimumX: 0 drag.maximumX: bHScroll? arrow2.x - btnRect.width: 0; drag.minimumY: 0 drag.maximumY: bHScroll? 0: arrow2.y - btnRect.height ; onWheel:{ console.log(" mouse wheel event") var step; if( bHScroll ) { step= (parent.width - btnRect.width)/10; if( wheel.angleDelta.y > 0 ) btnRect.x= btnRect.x - step > 0? btnRect.x - step : 0; else btnRect.x = btnRect.x + step < parent.width - btnRect.width? btnRect.x + step : parent.width - btnRect.width ; }else { step = (parent.height - btnRect.height)/10; if(wheel.angleDelta.y >0 ) btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ; else btnRect.y = btnRect.y + step < parent.height - btnRect.height? btnRect.y + step : parent.height - btnRect.height; } } onClicked:{ var step if(bHScroll) { step= (parent.width - btnRect.width)/10; if( mouseX < btnRect.x) { btnRect.x = btnRect.x - step > 0? btnRect.x - step : 0; }else if( mouseX > btnRect.x ) { btnRect.x = btnRect.x + step < parent.width - btnRect.width? btnRect.x + step : parent.width - btnRect.width ; } }else{ step = (parent.height - btnRect.height)/10; if( mouseY < btnRect.y ) { btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ; }else if(mouseY > btnRect.y){ btnRect.y = btnRect.y + step < parent.height - btnRect.height? btnRect.y + step : parent.height - btnRect.height; } } } } } Arrow{ id: arrow2; anchors{ left: bHScroll?undefined: parent.left; top: bHScroll? parent.top: undefined; bottom: parent.bottom; right: parent.right; } width: barSize; height: barSize; dir: bHScroll?1:2; MouseArea{ anchors.fill: parent; onClicked:{ var step = 2; if(bHScroll) { btnRect.x = btnRect.x + step < scrollBtnArea.width - btnRect.width? btnRect.x + step : scrollBtnArea.width -btnRect.width; }else{ btnRect.y = btnRect.y + step < scrollBtnArea.height - btnRect.height? btnRect.y + step : scrollBtnArea.height - btnRect.height; } } } } }
使用實例:
import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Controls 2.2 Window { visible: true width: 640 height: 700 title: qsTr("Hello World") Rectangle { id: frame clip: true width: 200 height: 200 border.color: "black" anchors.centerIn: parent Image { id: content; source: "tvline.jpg" width: 500; height: 500; } MouseArea{ anchors.fill: parent; onWheel:{ if(wheel.modifiers & Qt.ControlModifier) { if( wheel.angleDelta.y > 0) hscroll.scroll(-1); else hscroll.scroll(1); return; } //單純的滾動; if( wheel.angleDelta.y > 0) vscroll.scroll(-1) else vscroll.scroll(1) } } } UI_ScrollBar{ id: vscroll; visible: content.height > frame.height; attachItem: frame; bHScroll: false; bSpace: hscroll.visible; size: content.height/frame.height; } UI_ScrollBar{ id:hscroll; visible:content.width > frame.width; attachItem: frame; bHScroll: true; bSpace: vscroll.visible; size: content.width/frame.width; } }