最近写了一个修改头像功能的UI,布局参考了QQ目前的修改头像界面。如下图

这里主要说明一下两个地方的技术:1.头像图片上层的遮罩层,圆形外部为灰色,内部为全透明;2.上传图片宽高比例可以通过鼠标拖拽移动图片显示并通过滑动条进行图片大小放缩

遮罩层说明

遮罩层的处理主要在于怎么在一个透明灰色窗口上擦除出一个透明的圆形。之前使用了QPainter::CompositionMode里面的QPainter::CompositionMode_Clear擦除模式,但是试验后结果是,对于顶层窗口(没有父窗口)的效果是OK的,但是针对这里以显示图片的滚动区域窗口为父窗口的遮罩层,擦除只会变成完全的黑色。

重新考虑之后想到了ClipPath,剪切的绘图路径,通过在QPainterPath里增加路径获取一个剪切路径,再设置给QPainter,即可达到需要的效果,关键代码如下

m_pDivWidget->resize(ui.scrollArea->size());
QPainterPath path;
path.addRect(m_pDivWidget->geometry());
path.addEllipse(m_pDivWidget->geometry().adjusted(2, 2, -2, -2));
QPainter p(m_pDivWidget);
p.setRenderHint(QPainter::Antialiasing);
p.setBrush(QColor(100, 100, 100, 200));
p.setClipPath(path);
p.drawRect(m_pDivWidget->geometry());

 如果不想子类化QWidget,可以在父窗口里注册过滤事件,捕获遮罩层的绘图事件来重绘遮罩层QEvent::Paint == event->type()。

拖拽滚动窗口

其实简单说就是拖拽来模拟滚动条拖拽的效果,拖拽的距离和滚动区域内展示窗口的大小比例,再结合滚动条的当前值可以算出滚动条应该更新的值。代码如下

DragScrollArea::DragScrollArea(QWidget *parent)
: QScrollArea(parent)
{
//首先,关闭显示所有滚动条
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
} DragScrollArea::~DragScrollArea()
{ } bool DragScrollArea::event(QEvent* event)
{
if (widget()) //没有滚动窗口的时候,不处理
{
static QPoint pos;//记录拖拽位置
if (QEvent::MouseButtonPress == event->type())
{
              //开始拖拽
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
pos = mouseEvent->pos();
}
else if (QEvent::MouseMove == event->type())
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (Qt::LeftButton & mouseEvent->buttons())
{
                  //计算偏移量
pos = mouseEvent->pos() - pos;
                  //根据偏移量算出当前滚动条更新的值
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pos.x()*horizontalScrollBar()->maximum() / widget()->width());
verticalScrollBar()->setValue(verticalScrollBar()->value() - pos.y()*verticalScrollBar()->maximum() / widget()->height());
pos = mouseEvent->pos();
}
}
} return QScrollArea::event(event);
}

最终效果如图

项目代码地址,界面重新做了简单调整

https://github.com/KaiMingPrince/QtProject/tree/master/ChangeHeader

最新文章

  1. 最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)
  2. [20130919]出现有持续性的Lazy Write
  3. 网上找到的一个jquery版网页换肤特效
  4. 转载:使用命令行启动VirtualBox虚拟机
  5. COJ990 WZJ的数据结构(负十)
  6. 关于.Net Remoting 和 Web Servcie的比较
  7. FFT一周目开坑!
  8. JSON介绍与JavaScript解析
  9. hdu 5124
  10. Android: ScrollView监听滑动到顶端和底端
  11. qq音乐的歌词接口中例如&amp;#58,&amp;#46的特殊符号编码使用js进行转义
  12. backdrop-filter 和filter 写出高斯模糊效果 以及两者区别
  13. 在SQLSERVER中创建DBLINK,操作远程服务器数据库
  14. java 实现登录验证码 (kaptcha 验证码组件)
  15. jquery各大学选择插件
  16. canvas svg webgl threejs d3js 的区别
  17. Linux中目录proc/net/dev详解【转】
  18. win PowerCmd命令行工具安装
  19. patch函数的解释2
  20. JAVA通过oshi获取系统和硬件信息

热门文章

  1. Altera特殊管脚的使用(适用全系列Altera FPGA,MSEL区别除外)-来自altera论坛
  2. CentOS7设置开机自启动命令大全
  3. 修改查看MYSQL字符集(charset)
  4. Go 内嵌静态资源
  5. 工具类之数据库工具类:DBUtil(採用反射机制)
  6. Codeforces Round #313 D. Equivalent Strings(DFS)
  7. POJ 1691 Painting a Board(状态压缩DP)
  8. iOS 开发自定义一个提示框
  9. js实现卡号每四位空格分隔
  10. Android DOM解析XML示例程序