注:  该博文为原创博文,转载请注明,摘用请随意;

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;
} }

  

qml: 自定义滚动条;的更多相关文章

  1. CSS3自定义滚动条样式 -webkit-scrollbar(转)

    有没有觉得浏览器自带的原始滚动条很不美观,同时也有看到很多网站的自定义滚动条显得高端,就连chrome32.0开发板都抛弃了原始的滚动条,美观多了.那webkit浏览器是如何自定义滚动条的呢? 前言 ...

  2. jquery自定义滚动条 鼠标移入或滚轮时显示 鼠标离开或悬停超时时隐藏

    一.需求: 我需要做一个多媒体播放页面,左侧为播放列表,右侧为播放器.为了避免系统滚动条把列表和播放器隔断开,左侧列表的滚动条需要自定义,并且滚动停止和鼠标离开时要隐藏掉. 二.他山之石: 案例来自h ...

  3. 利用JS实现自定义滚动条

    一般默认的滚动条会比较丑,我们可以用简单的js实现自定义滚动条的功能: 代码如下: <!doctype html> <html> <head> <meta c ...

  4. javascript 学习之自定义滚动条加滚轮事件

    要自己写一个自定义滚动条加上滚轮事件,之前的没有滚轮事件不完整,今天整理了一个. 1.滚轮事件是不兼容的,firefox中是必需要用事件绑定的添加,用的DOMMouseScroll,当滚动鼠标的时候, ...

  5. 自定义滚动条 - mCustomScrollbar

    项目中需要使用自定义滚动条,但是试用了很多都功能不够全,今天发现一个比较全而且用法很简单的 -- mCustomScrollbar http://manos.malihu.gr/jquery-cust ...

  6. Flex:自定义滚动条样式/隐藏上下箭头

    Flex组件自定义滚动条的实现 .scrollBar{ downArrowUpSkin:Embed(source="img/mainLeftScrollBar/bar_bottom.png& ...

  7. javascript自定义滚动条插件,几行代码的事儿

    在实际项目中,经常由于浏览器自带的滚动条样式太戳,而且在各个浏览器中显示不一样,所以我们不得不去实现自定义的滚动条,今天我就用最少的代码实现了一个自定义滚动条,代码量区区只有几十行,使用起来也非常方便 ...

  8. jQuery自定义滚动条样式插件mCustomScrollbar

    如果你构建一个很有特色和创意的网页,那么肯定希望定义网页中的滚动条样式,这方面的 jQuery 插件比较不错的,有两个:jScrollPane 和 mCustomScrollbar. 关于 jScro ...

  9. WPF 自定义滚动条样式

    先看一下效果: 先分析一下滚动条有哪儿几部分组成: 滚动条总共有五部分组成: 两端的箭头按钮,实际类型为RepeatButton Thumb 两端的空白,实际也是RepeatButton 最后就是Th ...

随机推荐

  1. git reset 版本回退的三种用法总结

    git reset (–mixed) HEAD~1 回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也不受影响) git reset –soft ...

  2. 共轭函数Fenchel不等式

    f(x)不一定是凸函数,但他的共轭函数一定是凸函数.是仿射函数的逐点上确界. Fenchel不等式 f(x)+f*(x)>=xTy 如

  3. How to write to an event log by using Visual C#

    using System; using System.Diagnostics; namespace WriteToAnEventLog_csharp { /// Summary description ...

  4. 微信小程序 canvas 字体自动换行(支持换行符)

    微信小程序 canvas 自动适配 自动换行,保存图片分享到朋友圈  https://github.com/richard1015/News 微信IDE演示代码https://developers.w ...

  5. HTTP 错误 500.21 - Internal Server Error 处理程序“BlockViewHandler”在其模块列表中有一个错误模块“ManagedPipelineHandler

    HTTP 错误 500.21 - Internal Server Error  处理程序“BlockViewHandler”在其模块列表中有一个错误模块“ManagedPipelineHandler ...

  6. Python Argparse模块

    argparse模块 在Python中,argparse模块是标准库中用来解析命令行参数的模块,用来替代已经过时的optparse模块.argparse模块能够根据程序中的定义从sys.argv中解析 ...

  7. BZOJ4519[Cqoi2016]不同的最小割——最小割树+map

    题目描述 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成 两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割.对于带权图来说,将 所有顶点处在 ...

  8. Destroying the bus stations HDU - 2485(最小割点)

    题意: 就是求最小割点 解析: 正向一遍spfa 反向一遍spfa  然后遍历每一条边,对于当前边 如果dis1[u] + dis2[v] + 1 <= k 那么就把这条边加入到网络流图中, 每 ...

  9. day27

    27.01 反射(类的加载概述和加载时机) 1.类的加载 当程序要使用某个类时,如果该类还未加载到内存中,系统会通知加载,连接,初始化三步来实现对这个类初始化 a.加载 是指将.class文件读入内存 ...

  10. Markdown基础(内含:锚点使用,使用HTML,新页面跳转,目录生成)

    Github样式显示参考:点我 之前说过用word写文章,这次说说Markdown写文章(推荐) 逆天推荐使用VSCode编写 装这个插件写作更方便: 内含:锚点使用,使用HTML,新页面跳转,目录生 ...