Qt自定义滚动条(不使用样式表)
前面使用Qt 样式表实现滚动条,在实际工作中,发现存在一些瑕疵,例如如果在主窗口中绘制背景,则有可能给滚动条染色,还有如果想实现特殊的效果,则必须使用自定义风格,即从QStyle的子类派生出新的类型。以下从QProxyStyl派生出新的风格来实现自定义滚动(Qt4、Qt5均存在QCommonStyle、QProxyStyle,其余的风格在Qt5中已经不存在,不过原理一致)。
首先QScrollbar重绘时直接调用
drawComplexControl( ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget ) const
由此开始我们的自定绘制滚动条:
void MyStyle::drawComplexControl( ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget ) const
{
switch (control)
{
case CC_ScrollBar:
drawScrollbar(control, option, painter, widget);
return;
default:
break;
}
__super::drawComplexControl(control, option, painter, widget);
}
绘制代码的实现(模拟QQ)
void MyStyle::drawScrollbar( ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget ) const
{
//QQ中滚动条的效果是:如果不在滚动条上,默认上下箭头不显示,AddPage, SubPage也不显示。
//如果在滚动条上,如果不在箭头所在的区域,则显示normal,否则显示hot,按下显示down。
//这里按这个标准实现。
const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option);
if(!scrollbar) return;
bool maxedOut = (scrollbar->maximum == scrollbar->minimum);
if(maxedOut) return; painter->save();
painter->setRenderHint(QPainter::Antialiasing);
QRect r = option->rect; const State state = option->state;
const SubControls sub = option->subControls; State flags = option->state;
if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow())
flags |= State_MouseOver; QRect drawRect; if (maxedOut)
flags &= ~State_Enabled; const bool pressed = flags & State_Sunken;
const bool mouseOver = flags & State_MouseOver;
const bool isHorz = flags & State_Horizontal;
const bool isRTL = option->direction == Qt::RightToLeft; QColor bkFillColor = Qt::white;
QColor bkSliderNormal = Qt::lightGray;
QColor bkSliderHover = Qt::gray;
QColor bkSliderPress = Qt::darkGray; //清除所有子控件背景
//上下(左右)箭头可能和沟槽的背景不一样
drawRect= subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
painter->fillRect(drawRect, bkFillColor); drawRect= subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
painter->fillRect(drawRect, bkFillColor); //沟槽的颜色
drawRect = subControlRect(CC_ScrollBar, option, SC_ScrollBarGroove, widget);
painter->fillRect(drawRect, Qt::green);
//在mouse over状态下,才绘制上下左右箭头。
//scrollbar->activeSubControls用于指定当前鼠标所在的子控件
const QStyle::SubControls sc = scrollbar->activeSubControls;
if(!mouseOver)
{
//只绘制Slider,其余清除
drawRect = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); QPainterPath painterPath;
painterPath.addRoundedRect(drawRect.left(), drawRect.top(), drawRect.width(), drawRect.height(), , );
painter->fillPath(painterPath, bkSliderNormal);
}
else
{
//合并绘制AddPage SubPage
drawRect = subControlRect(CC_ScrollBar, option, SC_ScrollBarGroove, widget);
painter->fillRect(drawRect, QColor(, , , )); if (sub & SC_ScrollBarAddLine) //画加号,应该区分水平和垂直
{
drawRect= subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget);
QPixmap pixmap;
if(isHorz)
{
if(pressed) pixmap.load(":/ScrollBar/scrollbar_arrowright_down.png");
else if(sc & SC_ScrollBarAddLine) pixmap.load(":/ScrollBar/scrollbar_arrowright_highlight.png");
else pixmap.load(":/ScrollBar/scrollbar_arrowright_normal.png");
}
else
{
if(pressed) pixmap.load(":/ScrollBar/scrollbar_arrowdown_down.png");
else if(sc & SC_ScrollBarAddLine) pixmap.load(":/ScrollBar/scrollbar_arrowdown_highlight.png");
else pixmap.load(":/ScrollBar/scrollbar_arrowdown_normal.png");
} painter->drawPixmap(drawRect, pixmap);
}
if (sub & SC_ScrollBarSubLine)
{
drawRect= subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget);
QPixmap pixmap; if(isHorz)
{
if(pressed) pixmap.load(":/ScrollBar/scrollbar_arrowleft_down.png");
else if(sc & SC_ScrollBarSubLine) pixmap.load(":/ScrollBar/scrollbar_arrowleft_highlight.png");
else pixmap.load(":/ScrollBar/scrollbar_arrowleft_normal.png");
}
else
{
if(pressed) pixmap.load(":/ScrollBar/scrollbar_arrowup_down.png");
else if(sc & SC_ScrollBarSubLine) pixmap.load(":/ScrollBar/scrollbar_arrowup_highlight.png");
else pixmap.load(":/ScrollBar/scrollbar_arrowup_normal.png");
} painter->drawPixmap(drawRect, pixmap);
}
if (sub & SC_ScrollBarSlider)
{
drawRect = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); QPainterPath painterPath;
painterPath.addRoundedRect(drawRect.left(), drawRect.top(), drawRect.width(), drawRect.height(), , );
if(sc & SC_ScrollBarSlider)
{
painter->fillPath(painterPath, bkSliderPress);
}
else
{
painter->fillPath(painterPath, bkSliderHover);
}
} }
painter->restore();
}
效果如下:

左为鼠标不在滚动条区域,右边为鼠标在滚动条区域
这里使用绿色做沟槽的背景,方便调试。
Qt自定义滚动条(不使用样式表)的更多相关文章
- PyQt(Python+Qt)学习随笔:Qt Designer中部件的样式表styleSheet属性
styleSheet属性是定义部件外观的属性样式表,在Qt中styleSheet样式表是类似于html的css样式一样的方法,只是时专门为Qt中的部件开发的.styleSheet的定义语法也是类似CS ...
- Qt 自定义 滚动条 样式
今天是时候把软件中的进度条给美化美化了,最初的想法就是仿照QQ. 先前的进度条是这样,默认的总是很难受欢迎的:美化之后的是这样,怎么样?稍微好看一点点了吧,最后告诉你实现这个简单的效果在Qt只需要加几 ...
- Qt 自定义 滚动条 样式(模仿QQ)
今天是时候把软件中的进度条给美化美化了,最初的想法就是仿照QQ. 先前的进度条是这样,默认的总是很难受欢迎的:美化之后的是这样,怎么样?稍微好看一点点了吧,最后告诉你实现这个简单的效果在Qt只需要加几 ...
- QT样式表
QT样式表 一.QT样式表简介 1.QT样式表简介 QSS的主要功能是使界面的表现与界面的元素分离,使得设计皮肤与界面控件分离的软件成为可能. QT样式表是允许用户定制widgets组件外观的强大机制 ...
- Qt样式表的使用
Qt中可以灵活的使用层叠样式表(CSS),其语法和CSS很相似.因为HTML CSS的灵活性,所以可以很方便的为QT界面设计自己需要的外观.除了子类化Style类,使用QT样式表(QStyleShee ...
- WPF ScrollViewer(滚动条) 自定义样式表制作 再发一套样式 细节优化
艾尼路 出的效果图 本人嵌套 WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂 WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化) 源代码
- WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂
原文:WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂 先上效果图 正常样式 拖动时样式 好下面 开始吧 ==================================== ...
- WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化)
原文:WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化) 注释直接写在代码里了 不太理解意思的 可以先去看看我上一篇 WPF ScrollViewer(滚动条) 自定 ...
- Qt StyleSheet样式表实例(转)
QT论坛看到的,收藏一下! 在涉及到Qt 美工的时候首先需要掌握CSS 级联样式表. 下面将通过几个例子来介绍一下怎样使用Qt中的部件类型设计.自定义的前台背景与后台背景的颜色: 如果需要一个文本编辑 ...
随机推荐
- H5使用codovar插件实现支付宝支付(支付宝APP支付模式,前端)
H5打包的app实现支付及支付宝支付,本章主要详解支付宝支付,微信支付请查看另一篇“H5使用codovar插件实现微信支付(微信APP支付模式,前端)” ps:本文只试用H5开发的,支付宝 APP支付 ...
- mybatis学习 -每天一记(驼峰命名匹配)
在mybatis 中,数据库表有一个与之对应的实体类.类属性的命名是驼峰命名的,所以在mybatis中要开启驼峰匹配, 在spring boot 的项目中,至需要在yml文件中配置 即可. 当然也有其 ...
- Mac 系统下创建可双击执行文件,cd到执行文件当前目录
在mac下之前我一直用.sh文件,但是要去终端里才能执行,后来得知可以写.command文件,双击及可执行,很方便,特此记录 #!/bin/bash basepath=$(cd `dirname $0 ...
- java中PriorityBlockingQueue 和DelayedWorkQueue 区别
java中PriorityBlockingQueue 和DelayedWorkQueue 区别
- thinkphp5.1的公共函数库 common.php
首先引入Db类 或者是模型 use think\Db; 然后写公共函数 function getUserName($id){ return Db::table('zh_user')->where ...
- 3.搭建Samba服务器
1.在CentOS7上yum安装samba服务: yum -y install samba 2.目前我是直接共享已经存在的目录,如果您需要共享一个未曾创建的目录,需要您新创建一个目录: vim /et ...
- time_wait的快速回收和重用
TCP四次挥手: Time_wait产生原因及作用: 1. time_wait状态如何产生? 由上面的变迁图,首先调用close()发起主动关闭的一方,在发送最后一个ACK之后会进入time_wait ...
- 结对项目-WordCount
结对作业: 成员:201631062115(me),201631062613(partner) 代码地址:https://gitee.com/ackary/WordCount 作业的链接地址:http ...
- Jquery实现点击表格行变色!
时隔一年左右,学习了新的知识,从尝试Linux部署项目,网络安全,至后端开发,然后用起了Jquery, 而且是必须要做.也让自己见识可能会更广泛一些.对于一个刚毕业的大学生而言.方正我是没有用过jqu ...
- Adobe CC 下载地址
Adobe CC 2015下载地址 Photoshop http://trials3.adobe.com/AdobeProducts/PHSP/16/win32/Photoshop_16_LS20_w ...