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中的部件类型设计.自定义的前台背景与后台背景的颜色: 如果需要一个文本编辑 ...
随机推荐
- VM下安装Windows 2008 R2服务器操作系统
打开虚拟机,双击双击新的虚拟机. 2 硬件兼容性选择workstation10.点击下一步. 3 选择我以后安装操作系统.点击继续 4 选择Microsoft windows,版本为windows s ...
- docx httpheader头设置
设置contentType内容类型如下: Extension MIME Type .doc application/msword .dot application/msword .docx appli ...
- PHP+Ajax实现文件上传功能
前端显示界面: 1 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- 秋日上新!H5活动之家营销平台升级大盘点!
H5活动之家活动营销平台,免费定制使用抽奖.投票.砍价.红包.互动.游戏等不同类型的微信营销活动. 近期多个活动进行了升级改造,更有集福卡持续热度,微助力火热上线等亮点:同时平台也进行了提高访问速度. ...
- Java静态方法为什么不能访问非静态方法
转载自:https://www.2cto.com/kf/201502/375549.html 非静态方法(不带static)可以访问静态方法(带static),但是反过来就不行,为什么呢? publi ...
- document.compatMode 浏览器渲染模式判定利器
在加了DOCTYPE的页面document.compatMode输出CSS1Compat,不管加的是XHTML的还是HTML5的DOCTYPE.没有加的输出BackCompat. BackCompat ...
- 爬虫之scrapy扩展
针对pipelines的扩展 from scrapy.exceptions import DropItem class CustomPipeline(object): def __init__(sel ...
- Arthas进阶学习(常用命令)
Step1 下载demo-arthas-spring-boot.jar,再用java -jar命令启动: wget https://github.com/hengyunabc/katacoda-sce ...
- P61 实践作业
网络攻防实验环境搭建 根据链接下载的实验工具包,将其解压 打开VM虚拟机,点击图中红色框,扫描虚拟机 选择文件所在位置 点击下一步,完成.即可 在VM虚拟机设置中把网络适配器修改为桥接模式.如下图 在 ...
- 项目管理利器maven学习笔记(一):maven介绍及环境搭建
maven介绍 maven下载与环境搭建 http://maven.apache.org/download.cgi# 解压到指定位置,比如我解压到D盘 设置maven环境变量 添加一个变量名,变量值为 ...