永远的GitHub地址: https://github.com/JianBiHua/go_360_safe

如图效果(显示跟隐藏,都是慢慢显示的带尖角的窗体):

这里有几个小问题我还没有解决

  1. 动画时长设置太短(比如0.3秒),左右会多出一部分,
  2. 显示时,会闪现显示一个子控件,然后才正常动画
  3. ticker有时会崩溃.

显示: 当鼠标滑动到"简笔画/登陆/360图标"这块时
隐藏: 当鼠标厉害显示区域以及登陆框区域时。

# 实现原理说明

1. 如上节的波浪球绘制一样,得画一个带尖角的矩形。

2. 使用QT库自带的Mask功能(SetMask2)

核心代码如下:
A. 绘制代码:

  1. 我只画了尖角为上的情况,当然,也可以尖角为左为右。
  2. 为绘制了阴影
  3. 绘制的尖角矩形位置是动态的,效果才好看些
  4. 代码注释还算详细,自己理解吧。
// 画图
// 绘制较简单,就不将painter作为全局变量了
func (p *PopupWidget) onPaint (event *gui.QPaintEvent)  { 创建画笔var device = p.BackingStore().PaintDevice() //window.Painters[0]var painter = gui.NewQPainter2(device)// 反走样painter.SetRenderHint(gui.QPainter__Antialiasing, true)var shadowPath = gui.NewQPainterPath()var path = gui.NewQPainterPath()// 我这里只画一个向上的,其它基本一样,就是坐标不一样罢了// 我最讨厌go里面的不同类型的运算,转来转去,麻烦....switch p.arrowDirection {case ArrowDirectionUp:// 办法1:这个是通过遮罩实现的,但是看不到左右的边,如果有阴影,效果就不是很好了。 这些代码是显示一个完整的带尖角的代码。//path.MoveTo2(0, ArrowWidth)//path.LineTo2(p.luDis-ArrowWidth/2.0, ArrowWidth) 下面两句是画箭头的//path.LineTo2(p.luDis, 0)//path.LineTo2(p.luDis+ArrowWidth/2.0, ArrowWidth)//path.LineTo2(float64(p.Width()), ArrowWidth)//path.LineTo2(float64(p.Width()), float64(p.Height()))//path.LineTo2(0, float64(p.Height()))//path.LineTo2(0, ArrowWidth)// 添加一个遮罩层,我们的遮罩应该以箭头为中心 这样就能算出实际应该遮罩的位置,改变currentProgress, 就出现了从箭头位置向两边延伸的效果//path2.AddRect2(p.luDis*(1-p.currentProgress), 0, p.currentProgress*float64(p.Width()), float64(p.Height()))//painter.DrawPath(path2)// 办法2,直接根据currentProgress,动态画这个带尖角的图形,可以稍微往里留一两个像素,那么就能看到阴影了.// 注意,这个图形最小宽度应为 ArrowWidth+(ShadowWidth*2), 左右留出ShadowWidth大小的像素画阴影。// 这里要考虑两种情况,// 第一: currentProgress*p.width() < ArrowWidth+(ShadowWidth*2) 时// 第二: currentProgress*p.width() >= ArrowWidth+(ShadowWidth*2) 时// 设置颜色。//=======================================================================// 阴影的原理,就是将图形, 向左或者向右,向上或者向下移动一定像素,图形透明度降低// 画阴影painter.SetPen3(core.Qt__NoPen)painter.SetBrush(gui.NewQBrush10(p.getShadowColor()))var rw = p.currentProgress*float64(p.Width()-ShadowWidth*2)var rx = 0.0if rw < ArrowWidth+ShadowWidth*2 {rx = p.luDis-ArrowWidth/2+2} else {rx = p.luDis*(1-p.currentProgress)+2}// 这样就画出了不同的图形,最小宽度ArrowWidth+(ShadowWidth*2)shadowPath.MoveTo2(rx+p.pX, ArrowWidth+2+p.pY)shadowPath.LineTo2(p.luDis-ArrowWidth/2+p.pX, ArrowWidth+2+p.pY)// 画角shadowPath.LineTo2(p.luDis+p.pX, 0+2+p.pY)shadowPath.LineTo2(p.luDis+ArrowWidth/2+p.pX, ArrowWidth+2+p.pY)shadowPath.LineTo2(rx+rw+p.pX, ArrowWidth+2+p.pY)// 留出底部的阴影区域shadowPath.LineTo2(rx+rw+p.pX, float64(p.Height())-ShadowWidth+2+p.pY)shadowPath.LineTo2(rx+p.pX, float64(p.Height())-ShadowWidth+2+p.pY)shadowPath.LineTo2(rx+p.pX, ArrowWidth+2+p.pY)// 显示图形。painter.DrawPath(shadowPath)//=======================================================================// 画正常的图形// 设置颜色。painter.SetPen2(gui.NewQColor3(0x7F, 0x7F, 0x7F, 0x7F))painter.SetBrush(gui.NewQBrush3(gui.NewQColor3(0xF5, 0xF5, 0xF5, 0xFF),1))rw = p.currentProgress*float64(p.Width()-ShadowWidth*2)rx = 0.0if rw < ArrowWidth+ShadowWidth*2 {rx = p.luDis-ArrowWidth/2} else {rx = p.luDis*(1-p.currentProgress)}// 这样就画出了不同的图形,最小宽度ArrowWidth+(ShadowWidth*2)path.MoveTo2(rx+p.pX, ArrowWidth+p.pY)path.LineTo2(p.luDis-ArrowWidth/2+p.pX, ArrowWidth+p.pY)// 画角path.LineTo2(p.luDis+p.pX, 0+p.pY)path.LineTo2(p.luDis+ArrowWidth/2+p.pX, ArrowWidth+p.pY)path.LineTo2(rx+rw+p.pX, ArrowWidth+p.pY)// 留出底部的阴影区域path.LineTo2(rx+rw+p.pX, float64(p.Height())-ShadowWidth+p.pY)path.LineTo2(rx+p.pX, float64(p.Height())-ShadowWidth+p.pY)path.LineTo2(rx+p.pX, ArrowWidth+p.pY)// 显示图形。painter.DrawPath(path)case ArrowDirectionDown:}// 结束绘制painter.End()painter.DestroyQPainter()
}

B. 动画效果.

  1. 实际上就是动态修改currentProgress, 以及动态设置SetMask2
// 显示
// interval:显示的持续时间, 1000 = 1s
// f: 动画结束时相应,可能某些人喜欢在动画结束后执行一些操作,就可以这么写
func (p *PopupWidget) Show2 (interval int, f func(widget *PopupWidget))  {if !p.isShow {// 只有隐藏状态才显示p.ticker = time.NewTicker(20 * time.Millisecond)// 默认遮罩,什么也不显示p.SetMask2(gui.NewQRegion2(int(p.luDis),0,0,p.Height(),gui.QRegion__Rectangle))p.loginWidget.ShowDefault()go func() {defer p.ticker.Stop()var ticker = 0for {select {case <-p.ticker.C:// 1.0 / (interval/20)p.currentProgress += 20.0 / float64(interval)if p.currentProgress > 1 {p.currentProgress = 1// 都跑到了,就直接让它结束吧,ticker = interval}// 修改遮罩位置// 添加一个遮罩层,我们的遮罩应该以箭头为中心// 这样就能算出实际应该遮罩的位置,改变currentProgress, 就出现了从箭头位置向两边延伸的效果p.SetMask2(gui.NewQRegion2(int(p.luDis*(1-p.currentProgress)),0,int(p.currentProgress*float64(p.Width())),p.Height(),gui.QRegion__Rectangle))// 计数ticker += 20if ticker >= interval {//p.isShow = true// 告诉上层,动画完成了.if f != nil {f (p)}return}// 刷新p.Update()}}} ()}
}

C. 控件显示代码

  1. 这里捕获window的事件消息,我们只关心鼠标滑动的消息。
  2. 根据鼠标滑动的坐标,来判断应该是显示,还是隐藏loginPopupWidget
  3. 注意这个SetGeometry3,是自定义的,不是QT系统库函数,我想重载SetGeometry2的,不过失败了
  4. 代码注释也比较详细,自己理解哈。
 mw.window.ConnectEvent(func(event *core.QEvent) bool {if event.Type() == core.QEvent__HoverMove {// 获取当前鼠标在屏幕上的绝对坐标var pos = core.NewQPoint2(gui.QCursor_Pos().X(), gui.QCursor_Pos().Y())// 将全局左边转换成window上的坐标var pos2 = mw.window.MapFromGlobal(pos)var x = pos2.X()var y = pos2.Y()// 如果是鼠标滑动// 处理鼠标的滑动// 实现的逻辑是,// 当鼠标移动到loginPopupWidget上或者移动到登陆区域,才显示登陆框,否则,如果显示了则隐藏。if mw.loginPopupWidget == nil {// 如果loginPopupWidget不存在,移动到登陆区域,才显示登陆框if mw.loginWidget.Widget().Geometry().Contains3(x, y) {mw.loginPopupWidget = NewPopupWidget (mw.window, ArrowDirectionUp, 90, 700, 90)mw.loginPopupWidget.SetGeometry3(700, 90, 180, 100)mw.loginPopupWidget.Show(1*1000)mw.loginPopupWidget.SetWindowFlags(core.Qt__WindowStaysOnTopHint);mw.loginPopupWidget.ShowNormal()}} else {// 如果显示了。鼠标移动到除登录区以及loginPopupWidget区域外时,隐藏loginPopupWidgetif !mw.loginWidget.Widget().Geometry().Contains3(x, y) &&!mw.loginPopupWidget.Geometry().Contains3(x, y) {mw.loginPopupWidget.Hide2(1*1000, func(widget *PopupWidget) {if mw.loginPopupWidget != nil {mw.loginPopupWidget.HideDefault()//当隐藏后销毁mw.loginPopupWidget.DestroyQWidget()mw.loginPopupWidget = nil}})}}}// 如果没有这句,你会发现波浪不动了, 因为你把所有的事件都处理了,下面收不到消息了return mw.window.EventDefault(event)})

[go] 360安全卫士七 --带动画效果的登陆框相关推荐

  1. css3+jQuery制作导航菜单(带动画效果)

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>css ...

  2. (带动画效果)卷积神经网络的讲解.pptx

    这学期我上的另一门课是本科生的<深度学习>,主要用的是吴恩达老师的<深度学习>视频课的内容. 使用教材:吴恩达<深度学习>课程笔记 课外参考书:<深度学习&g ...

  3. 我的Android进阶之旅------Android利用温度传感器实现带动画效果的电子温度计

    要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...

  4. vue伸缩效果_Vue2(三)实现子菜单展开收缩,带动画效果实现方法

    以前做这种操作就是简单的display:block,但现在用户的要求也越来越高,需要美观和动画感. 现在介绍用一种简单的方式来实现子菜单从上向下展开子菜单. 看下效果图: 点开效果: 其实原理比较简单 ...

  5. Android利用温度传感器实现带动画效果的电子温度计

    概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 一.准备工作 需要准备一部带有温度传感器的安卓手机,或者使用有温度传感器的模拟器. 二.程序实现 1.需要截图程序结构 2.实现思 ...

  6. GDI+入门(5、在GDI+中绘制带动画效果的图片)

    五.在GDI+中绘制带动画效果的图片 private void Form2_Load(object sender, EventArgs e) { SetStyle(ControlStyles.Doub ...

  7. Android高效率实现弹出带动画效果的对话框,仿照微信对话框效果

    转载请注明出处: http://blog.csdn.net/jakeyangchina/article/details/53423453 看到很多app页面里都有弹出对话框效果,今天使用PopupWi ...

  8. html5制作天气动画背景,CSS icon图标之纯CSS实现带动画效果的天气图标

    CSS3动画属性并不是很多,但重点其实是你怎样去运用它,从简单的hover状态或复杂的小动画,都可以巧妙的用CSS3动画属性来实现. 今天主要是和大家分享一个比较有创意.实用的CSS天气图标动画,静态 ...

  9. SVG实现带动画效果的购物图标

    下载地址 制作网站CSS动画时,不要为了弦的效果而制作,它更虽然有意义.今天将向大家介绍一套使用CSS实现带动画的商城购物类的图标,图标设计漂亮可爱,加上友好的动画效果,这能给用户增加一点有趣的购物体 ...

最新文章

  1. R构建多项式回归模型(Polynomial Regression)
  2. linux7 开ftp,linux centos 7 开启 ftp
  3. “纯金”卫星,撞向我们的“蛋壳时代”
  4. android componentname activity,ComponentName的使用
  5. 【竞赛相关】Kaggle活跃竞赛(12月汇总)
  6. 【H2 Database】导出CSV
  7. C#可空类型(Nullable Types)
  8. 曹大:我的快速阅读法
  9. uiuc计算机课程,UIUC计算机科学专业解读
  10. C++ 与Qt开发人机象棋(第一部分)
  11. mysql 查看所有表的引擎_MySQL查看数据库、表的占用空间大小以及某个库中所有表的引擎类型...
  12. 人类遗传变异神库 | ClinVar数据库详解
  13. vm15不支持linux,每个处理程序的多个VMExtensions不支持操作系统类型'Linux
  14. SELinux系列(十三)—默认安全上下文的查询和修改(semanage命令)
  15. js date 加一天_需要知道的JS的日期的知识,都在这了
  16. 中国数据中心改造市场趋势报告、技术动态创新及市场预测
  17. 思科下一代模拟器EVE-NG镜像导入
  18. 谷歌拼音输入法PinyinIME源码修改----随着Setting中中英文的切换对应改变软键盘中英文输入且字符变换
  19. 大型Excel插件SqlCel全新上市
  20. JedisConnectionException: java.net.SocketException: Broken pipe (Write failed)

热门文章

  1. 车险理赔9个环节,视频理赔查勘一套搞定!
  2. 双十一最受欢迎真无线蓝牙耳机推荐,2020五款高性价比真无线蓝牙耳机分享
  3. 得物java怎么样_[上海] 得物(毒 app) 国际技术 招聘 高级 Java 开发工程师
  4. 用html制作旋转风车,HTML5 Canvas 旋转风车绘制
  5. pyqt5安装及基础
  6. 二叉树的深度优先搜索
  7. Android——超简单 MVC、MVP、MVVM入门系列
  8. php访问网页post获取源码,post提交获得html页面源码的实现代码
  9. Spring Boot学习笔记总结(一)
  10. NLP——常用工具汇总