小声bb
这只是一个初期的demo,起一个抛砖引玉的作用,所以如果大家有什么好的建议可以留言博主,当然如果有什么问题,请联系博主的QQ:995187021。如果这篇文章对你有一点点帮助,麻烦您点一个赞,让我知道自己不是在做无用功,让卑微的博主找到一丢丢的存在感,谢谢。如果有什么好的萝卜坑推荐的话,也是感谢至极。
效果
说明
思路,首先是根据flickable的显示属性,可以将要显示的区域局部显示,并且可以设置显示区域的位置和大小 ,那就需要一个Handle来动态的改变这个显示区域的属性,这个handle得具有哪些属性呢?1.大小可拉伸,即四个点加上四个边可以拉升改变这个handle,并且大小必须有限定。2.可拖动,在一个区域内要能够拖动。3.鼠标滚轮能控制放大缩小,但不能超过固定区域。
显示,显示区域的大小与flickable对应的比例,与handle大小和handle的限定区域对应的比例一致,并且坐标也应该对应成比例。
代码
StretchableRec.qml(可拉伸的矩形(handle))
import QtQuick 2.0
Rectangle{
id:root
color: "transparent"
border.color: "#cc661a"
border.width: 1
property int smallBoxHeight : 8 //小方框的高
property int smallBoxWidth: 6 //小方框的宽
property int startY:0 //拉伸时鼠标的起始y坐标
property int startX: 0 //拉伸时鼠标的起始x坐标
property int parentData1: 0 //用来自由存储信息
property int parentData2: 0
property bool isPressed: false //小方框是否被点击
property int maxX:0 //方框x的最大值
property int maxY: 0 //方框y的最大值
property int scrollNum:0 //鼠标滚轮的弧度
Drag.active: dragMouse.drag.active //可以拖动
Rectangle{ //左上小方框
z:2
id:leftTopRec
color: "#303030"
height:smallBoxHeight
width: smallBoxWidth
anchors.left: parent.left
anchors.top: parent.top
MouseArea{ //左上小方框的鼠标区域
id:leftTopMouse
anchors.fill: parent
cursorShape: Qt.SizeFDiagCursor
onPressed: { //点击后记录 鼠标被点击 鼠标起始坐标 根矩形的宽 根矩形的高
isPressed=true
startX=mouse.x
startY=mouse.y
parentData1=root.x+root.width
parentData2=root.y+root.height
}
onPositionChanged: { //鼠标移动
if(isPressed){ //只能是在鼠标按下后拉伸
if(root.y+(mouse.y-startY)>=0&&root.height-(mouse.y-startY)>smallBoxHeight){ //限制拉伸极限
root.y=root.y+(mouse.y-startY)
root.height=root.height-(mouse.y-startY)
}else{
if(root.y+(mouse.y-startY)<0){
root.y=0
root.height=parentData2
}
if(root.height-(mouse.y-startY)
root.y=parentData2-smallBoxHeight
root.height=smallBoxHeight
}
}
if(root.x+(mouse.x-startX)>=0&&root.width-(mouse.x-startX)>smallBoxWidth){
root.x=root.x+(mouse.x-startX)
root.width=root.width-(mouse.x-startX)
}else{
if(root.x+(mouse.x-startX)<0){
root.x=0
root.width=parentData1
}
if(root.width-(mouse.x-startX)
root.x=parentData1-smallBoxWidth
root.width=smallBoxWidth
}
}
}
}
onReleased: { //鼠标放下后将按下置为false
isPressed=false
}
}
}
Rectangle{ //右上小矩形
z:2
id:rightTopRec
color: "#303030"
height: smallBoxHeight
width: smallBoxWidth
anchors.right: parent.right
anchors.top: parent.top
MouseArea{ //右上矩形鼠标
id:rightTopMouse
anchors.fill: parent
cursorShape: Qt.SizeBDiagCursor
onPressed: {
isPressed=true
startX=mouse.x
startY=mouse.y
// parentData1=root.x+root.width
parentData2=root.y+root.height
}
onPositionChanged: {
if(isPressed){
if(root.y+(mouse.y-startY)>=0&&root.height-(mouse.y-startY)>smallBoxHeight){
root.y=root.y+(mouse.y-startY)
root.height=root.height-(mouse.y-startY)
}else{
if(root.y+(mouse.y-startY)<0){
root.y=0
root.height=parentData2
}
if(root.height-(mouse.y-startY)
root.y=parentData2-smallBoxHeight
root.height=smallBoxHeight
}
}
if(root.width+root.x+mouse.x-startX
root.width=root.width+mouse.x-startX
}else{
if(root.width+root.x+mouse.x-startX>maxX)
{
root.width=maxX-root.x
}
if(root.width+mouse.x-startX
root.width=smallBoxWidth
}
}
}
}
onReleased: {
isPressed=false
}
}
}
Rectangle{ //左下矩形
z:2
id:leftBottomRec
color: "#303030"
height: smallBoxHeight
width: smallBoxWidth
anchors.left: parent.left
anchors.bottom: parent.bottom
MouseArea{ //左下矩形的鼠标区域
id:leftBottomMouse
anchors.fill: parent
cursorShape: Qt.SizeBDiagCursor
onPressed: {
isPressed=true
startX=mouse.x
startY=mouse.y
parentData1=root.x+root.width
//parentData2=root.y+root.height
}
onPositionChanged: {
if(isPressed){
if(root.x+(mouse.x-startX)>=0&&root.width-(mouse.x-startX)>smallBoxWidth){
root.x=root.x+(mouse.x-startX)
root.width=root.width-(mouse.x-startX)
}else{
if(root.x+(mouse.x-startX)<0){
root.x=0
root.width=parentData1
}
if(root.width-(mouse.x-startX)
root.x=parentData1-smallBoxWidth
root.width=smallBoxWidth
}
}
if(root.height+root.y+mouse.y-startY
root.height=root.height+mouse.y-startY
}else{
if(root.height+root.y+mouse.y-startY>maxY)
{
root.height=maxY-root.y
}
if(root.height+mouse.y-startY
root.height=smallBoxHeight
}
}
}
}
onReleased: {
isPressed=false
}
}
}
Rectangle{
z:2
id:rightBottomRec
color: "#303030"
height:smallBoxHeight
width:smallBoxWidth
anchors.right: parent.right
anchors.bottom: parent.bottom
MouseArea{
id:rightBottomMouse
anchors.fill: parent
cursorShape: Qt.SizeFDiagCursor
onPressed: {
isPressed=true
startX=mouse.x
startY=mouse.y
//parentData1=root.x+root.width
//parentData2=root.y+root.height
}
onPositionChanged: {
if(isPressed){
if(root.width+root.x+mouse.x-startX
root.width=root.width+mouse.x-startX
}else{
if(root.width+root.x+mouse.x-startX>maxX)
{
root.width=maxX-root.x
}
if(root.width+mouse.x-startX
root.width=smallBoxWidth
}
}
if(root.height+root.y+mouse.y-startY
root.height=root.height+mouse.y-startY
}else{
if(root.height+root.y+mouse.y-startY>maxY)
{
root.height=maxY-root.y
}
if(root.height+mouse.y-startY
root.height=smallBoxHeight
}
}
}
}
onReleased: {
isPressed=false
}
}
}
Rectangle{
z:2
id:topRec
color: "#303030"
height:smallBoxHeight
width:smallBoxWidth
x:(parent.width-topRec.width)/2
MouseArea{
id:topMouse
anchors.fill: parent
hoverEnabled: true
cursorShape:Qt.SizeVerCursor
onPressed: {
isPressed=true
//startPoint.x=mouse.x
startY=mouse.y
parentData1=root.y+root.height
}
onPositionChanged: {
if(isPressed){
if(root.y+(mouse.y-startY)>=0&&root.height-(mouse.y-startY)>smallBoxHeight){
root.y=root.y+(mouse.y-startY)
root.height=root.height-(mouse.y-startY)
}else{
if(root.y+(mouse.y-startY)<0){
root.y=0
root.height=parentData1
}
if(root.height-(mouse.y-startY)
root.y=parentData1-smallBoxHeight
root.height=smallBoxHeight
}
}
}
}
onReleased: {
isPressed=false
}
}
}
Rectangle{
z:2
id:rightRec
color: "#303030"
height:smallBoxHeight
width:smallBoxWidth
y:(parent.height-topRec.height)/2
anchors.right: parent.right
MouseArea{
id:rightMouse
anchors.fill: parent
hoverEnabled: true
cursorShape:Qt.SizeHorCursor
onPressed: {
isPressed=true
startX=mouse.x
// parentData1=root.y+root.height
}
onPositionChanged: {
if(isPressed){
if(root.width+root.x+mouse.x-startX
root.width=root.width+mouse.x-startX
}else{
if(root.width+root.x+mouse.x-startX>maxX)
{
root.width=maxX-root.x
}
if(root.width+mouse.x-startX
root.width=smallBoxWidth
}
}
}
}
onReleased: {
isPressed=false
}
}
}
Rectangle{
z:2
id:bottomRec
color: "#303030"
height:smallBoxHeight
width:smallBoxWidth
x:(parent.width-topRec.width)/2
anchors.bottom: parent.bottom
MouseArea{
id:bottomMouse
anchors.fill: parent
hoverEnabled: true
cursorShape:Qt.SizeVerCursor
onPressed: {
isPressed=true
startY=mouse.y
// parentData1=root.y+root.height
}
onPositionChanged: {
if(isPressed){
if(root.height+root.y+mouse.y-startY
root.height=root.height+mouse.y-startY
}else{
if(root.height+root.y+mouse.y-startY>maxY)
{
root.height=maxY-root.y
}
if(root.height+mouse.y-startY
root.height=smallBoxHeight
}
}
}
}
onReleased: {
isPressed=false
}
}
}
Rectangle{
z:2
id:leftRec
color: "#303030"
height:smallBoxHeight
width:smallBoxWidth
y:(parent.height-topRec.height)/2
anchors.left: parent.left
MouseArea{
id:leftMouse
anchors.fill: parent
hoverEnabled: true
cursorShape:Qt.SizeHorCursor
onPressed: {
isPressed=true
startX=mouse.x
parentData1=root.x+root.width
}
onPositionChanged: {
if(isPressed){
if(root.x+(mouse.x-startX)>=0&&root.width-(mouse.x-startX)>smallBoxWidth){
root.x=root.x+(mouse.x-startX)
root.width=root.width-(mouse.x-startX)
}else{
if(root.x+(mouse.x-startX)<0){
root.x=0
root.width=parentData1
}
if(root.width-(mouse.x-startX)
root.x=parentData1-smallBoxWidth
root.width=smallBoxWidth
}
}
}
}
onReleased: {
isPressed=false
}
}
}
Rectangle{ //拖动事件,鼠标触发区域
id:dragArea
anchors.fill: parent
color: "#cc661a"
opacity: 0.2 //透明度0.2
MouseArea{ //鼠标区域
id:dragMouse
anchors.fill: parent
cursorShape:Qt.SizeAllCursor //鼠标样式
drag.target: root
drag.minimumX: 0 //拖动区域限制
drag.minimumY: 0
drag.maximumX:maxX-root.width
drag.maximumY: maxY-root.height
onWheel: { //接收到滚轮事件
scrollNum=wheel.angleDelta.y / 120 //接收滚轮滚动的大小
if(scrollNum>0){ //判断滚动的方向
if(root.x>=5)
{
root.x-=wheel.angleDelta.y /120*5
}else if(0
}
if(root.y>=5)
{
root.y-=wheel.angleDelta.y /120*5
}else if(0
}
if(root.width<=maxX-root.x-10)
{
root.width+=wheel.angleDelta.y /120*5*2
}else if(maxX-root.x-10
root.width=maxX-root.x
}
if(root.height<=maxY-root.y-10)
{
root.height+=wheel.angleDelta.y /120*5*2
}else if(maxY-root.y-10<=root.height
root.height=maxY-root.y
}
}else
{
if(root.width>smallBoxWidth*3){ //限制最小的宽度不小于三个小矩形的宽
root.width+=wheel.angleDelta.y /120 *5*2
root.x-=wheel.angleDelta.y /120 *5
}
if(root.height>smallBoxHeight*3){ //限制最小的高度不小于三个小矩形的高
root.height+= wheel.angleDelta.y /120*5*2
root.y-=wheel.angleDelta.y /120 *5
}
}
}
}
}
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 680
height: 600
title: qsTr("闻天语")
Rectangle{
id:container
height: 200
width: 200
border.color:"#008792"
border.width:1
x:420
y:400
StretchableRec{ //自定义的可拉伸的矩形
id:testRec1
height: 50
width: 50
x:20
y:20
maxY: parent.height
maxX: parent.width
}
}
Flickable {
id:flick
width: 400; height: 400
clip: true
interactive:false //flickable不可拂动(如果不加这句,点击flickable任意位置content会回到(0,0)坐标)
Rectangle{ //需要显示的内容
id:myContent
height:(200/testRec1.height)*flick.height
width: (200/testRec1.width)*flick.width
Image { //这里我们显示一张图片
id: img
source: "qrc:/pic/pic.jpg"
anchors.fill:parent
}
}
contentX: (myContent.width/200)*testRec1.x //使显示区域的坐标与拖动handle在对应框中的坐标相对应
contentY:(myContent.height/200)*testRec1.y
}
}
CSDN下载:https://download.csdn.net/download/weixin_40912639/10828745
---------------------
作者:闻天语~
来源:CSDN
原文:https://blog.csdn.net/weixin_40912639/article/details/84801458
版权声明:本文为博主原创文章,转载请附上博文链接!