热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

360新版特性界面实现(2)

原来的网址:http:www.oschina.netquestion234345_550671.UI的结构开始画图形界面,首先确定UI的大小ÿ

原来的网址:http://www.oschina.net/question/234345_55067


1.UI的结构


开始画图形界面,首先确定UI的大小,找到360新版特性界面的皮肤,可以看到:
4个不同的页面的像素为:680 * 370
而最顶层的一层透明页面像素为:680 * 372
如图:
QSize(680, 370):

QSize(680, 372):

现在可以确定下来,UI的大小为(680, 372);但4个页面只在370个像素空间中运动,最上面空余的为透明区域,其中在X轴(20-100)的矩形区域,为玻璃效果的区域,这些均为图片贴出。下面给个示意图:

在图中,2个像素空间中,红色区域使用Qt中的setMask函数来遮掩,绿色矩形区域为要显示的图片部分,此为玻璃效果。
所以剩下的所有控件均活动在矩形:点(0, 2) -> 点(680, 372)空间中。

在这张图中,画出了UI的设计框架,具体还是根据程序进行调整最佳位置。

2.画出最基本的背景图
只需重新实现QWidget的paintEvent事件,就可以达到上述所说的效果:

源码打印?
  1. void Preview360::paintEvent(QPaintEvent *)  
  2. {  
  3.     QBitmap bitmap(this->size());  
  4.     QPainter painter(&bitmap);  
  5.     painter.fillRect(bitmap.rect(), Qt::white);  
  6.     painter.setBrush(QColor(0, 0, 0));  
  7.     //填充一个以圆弧为4个角的矩形,使窗体的四个角变成圆弧  
  8.     painter.drawRoundedRect(QRect(0, 2, this->width(), this->height()-2), 5, 5);  
  9.     //画出(0, 2) -> (2, 100)区域  
  10.     painter.drawRoundedRect(QRect(20, 0, 120-20, 2), 2, 2);  
  11.     setMask(bitmap);  
  12. }  




代码很简单,关键在于setMask函数的使用。
若要在一个矩形窗口中央画一个圆,以下步骤:
(1).先画出窗体
(2).在窗体大小的矩形QBitmap中以白色填充整张图
(3).在矩形中央以黑色画一个圆,用黑色填充这个圆
(4).setMask(bitmap)
此时效果就出来了,一个不规则窗体,圆。

这时候再加入图片,最基本的背景图就出来了。
new出2个QLabel标签来存放图片:



源码打印?
  1. m_pLabelBg0 = new QLabel(this);  
  2. m_pLabelBg0->setPixmap(QPixmap(":/images/bg_bottom.png"));  
  3. m_pLabelBg0->setGeometry(QRect(0, 2, this->width(), this->height()-2));  
  4.   
  5. m_pLabelBg1 = new QLabel(this);  
  6. m_pLabelBg1->setPixmap(QPixmap(":/images/bg_top.png"));  
  7. m_pLabelBg1->setGeometry(QRect(0, 0, this->width(), this->height()));  




bg_top.png这张图必须置顶,Qt窗体中是基于堆栈窗体的,只需将m_pLabelBg1提升到栈顶即可,Qt提供了一个函数:raise。


源码打印?
  1. m_pLabelBg1->raise();  




当然这里涉及到很多控件的排序(栈排序),所以待所有控件都初始化完成后,再来控制也不迟。

3.画出4个页面
这里使用的方法是将4张图画到一个QLabel中的方法,该方法比较简单。



源码打印?
  1. QPixmap pixmap(QSize(this->width()*WINDOW_PAGE_COUNT, WINDOW_HEIGHT-2));  
  2. QPainter painter(&pixmap);  
  3. for (int i &#61; 0; i < WINDOW_PAGE_COUNT; i&#43;&#43;)  
  4. {  
  5.     painter.drawImage(QRect(WINDOW_WIDTH*i, 0, WINDOW_WIDTH, WINDOW_HEIGHT-2),  
  6.                       QImage(tr(":/images/desktop_%1.jpg").arg(i)));  
  7. }  
  8. m_pLabelFgTotal &#61; new QLabel(this);  
  9.   
  10. m_pLabelFgTotal->resize(pixmap.size());  
  11. m_pLabelFgTotal->setPixmap(pixmap);  
  12. m_pLabelFgTotal->move(WINDOW_START_X, WINDOW_START_Y);  




ok&#xff0c;现在样子基本上差不多了。

4.创建自定义山寨按钮
这4个按钮并不是标准的按钮&#xff0c;只需子类化QWidget&#xff0c;在QWidget中添加2个QLabel&#xff0c;一个存放图片&#xff0c;一个存放文本&#xff0c;就能做出这种效果来&#xff0c;来看看效果图&#xff1a;

从图中&#xff0c;可以看出要实现几个功能&#xff1a;
(1).2个QLabel的布局。
(2).实现鼠标3个事件&#xff1a;enterEvent, leaveEvent, mousePressEvent。
(3).重新实现paintEvent事件&#xff0c;绘制不同的效果。
(4).鼠标移动到该区域&#xff0c;改变鼠标指针形状。
至于第(2)点&#xff0c;
enterEvent&#xff1a;鼠标进入该区域&#xff0c;背景变透明模糊
leaveEvent&#xff1a;鼠标离开该区域&#xff0c;背景恢复正常
mousePressEvent&#xff1a;鼠标点击该区域&#xff0c;背景变透明模糊&#xff0c;明显。
绘制背景透明模糊的效果&#xff1a;



源码打印&#xff1f;
  1. void CLabel::paintEvent(QPaintEvent *e)  
  2. {  
  3.     QPainter painter(this);  
  4.   
  5.     if (getMouseEnterFlag())  
  6.     {  
  7.         paintWidget(50, &painter);  
  8.     }  
  9.     else if (getMousePressFlag())  
  10.     {  
  11.         paintWidget(80, &painter);  
  12.     }  
  13.   
  14.     QWidget::paintEvent(e);  
  15. }  
  16. void CLabel::paintWidget(int transparency, QPainter *device)  
  17. {  
  18.     QPen pen(Qt::NoBrush, 1);  
  19.     device->setPen(pen);  
  20.     //渐变线  
  21.     QLinearGradient linear(this->rect().topLeft(), this->rect().bottomLeft());  
  22.     //设置前景色;  
  23.     //0:前景色; 0.5:中间色; 1:背景色;  
  24.     //transparency为透明度  
  25.     linear.setColorAt(0, QColor(255, 255, 255, transparency));  
  26.   
  27.     QBrush brush(linear);  
  28.     device->setBrush(brush);  
  29.     device->drawRoundedRect(this->rect(), 2, 2);  
  30. }  



鼠标的几个事件&#xff1a;



源码打印&#xff1f;
  1. void CLabel::enterEvent(QEvent *e)  
  2. {  
  3.     if (!getMousePressFlag())  
  4.     {  
  5.         setMouseEnterFlag(true);  
  6.     }  
  7.     this->setCursor(Qt::PointingHandCursor);  
  8. }  
  9.   
  10. void CLabel::leaveEvent(QEvent *e)  
  11. {  
  12.     setMouseEnterFlag(false);  
  13. }  
  14.   
  15. void CLabel::mousePressEvent(QMouseEvent *e)  
  16. {  
  17.     if (e->button() &#61;&#61; Qt::LeftButton)  
  18.     {  
  19.         setMousePressFlag(true);  
  20.         emit signalLabelPress(this);  
  21.     }  
  22. }  





5.设置样式
其实用函数也能设置&#xff0c;但我发现用css语法来编辑样式挺方便的&#xff0c;以后会专门来介绍样式的使用&#xff0c;正因为她的实用。
在CLabel中&#xff0c;用如下样式来设置字体和背景



源码打印&#xff1f;
  1. this->setStyleSheet("QWidget {background:transparent;border:0px;color:white;font-weight:bold;font-size:16px;}");  




6.画出4个按钮
在Preview360类中&#xff0c;创建4个按钮&#xff1a;



源码打印&#xff1f;
  1. QStringList nameList;  
  2. //为了对齐&#xff0c;所以在文字后面加了空格  
  3. nameList << tr("360安全桌面 ")  
  4.          << tr("木马防火墙   ")  
  5.          << tr("360保镖     ")  
  6.          << tr("电脑门诊     ");  
  7. for (int i &#61; 0; i < WINDOW_BUTTON_COUNT; i&#43;&#43;)  
  8. {  
  9.     CLabel *label &#61; new CLabel(this);  
  10.     label &#61; new CLabel(this);  
  11.     label->resize(QSize(155, 45));  
  12.     label->setPixmap(QPixmap(tr(":/images/btn_%1.png").arg(i)));  
  13.     label->setText(nameList.at(i));  
  14.     label->move(8&#43;i*170, 319);  
  15.     connect(label, SIGNAL(signalLabelPress(CLabel*)), this, SLOT(slotLabelButtonPress(CLabel*)));;  
  16.     connect(label, SIGNAL(signalLabelPress(CLabel*)), this, SLOT(slotChangeCurrentPage(CLabel*)));  
  17.     m_pLabelBtnArray[i] &#61; label;  
  18. }  
  19. m_pLabelBtnArray[0]->setMousePressFlag(true);  




将4个CLabel按钮提升到栈顶&#xff1a;


源码打印&#xff1f;
  1. for (int i &#61; 0; i < WINDOW_BUTTON_COUNT; i&#43;&#43;)  
  2. {  
  3.     m_pLabelBtnArray[i]->raise();  
  4. }  




但CLabel被press时&#xff0c;只能一个按钮为被press状态:


源码打印&#xff1f;
  1. void Preview360::slotLabelButtonPress(CLabel *label)  
  2. {  
  3.     for (int i &#61; 0; i < WINDOW_BUTTON_COUNT; i&#43;&#43;)  
  4.     {  
  5.         if (label !&#61; m_pLabelBtnArray[i])  
  6.         {  
  7.             m_pLabelBtnArray[i]->setMousePressFlag(false);  
  8.         }  
  9.     }  
  10. }  


下载地址&#xff1a;360新版特性界面


其实这些东西都很简单&#xff0c;没什么好说的。
下一篇文章继续说明4张漂亮图的移动和窗体移动。。。


作者  : gzshun.
E-Mail: gzshuns#163.com (&#64;)
转载请注明出处:http://blog.csdn.net/gzshun/article/details/7596542




原文链接&#xff1a;
http://blog.csdn.net/gzshun/article/details/7596542


推荐阅读
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 本文介绍如何使用布局文件在Android应用中排列多行TextView和Button,使其占据屏幕的特定比例,并提供示例代码以帮助理解和实现。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文探讨了在Java中实现系统托盘最小化的两种方法:使用SWT库和JDK6自带的功能。通过这两种方式,开发者可以创建跨平台的应用程序,使窗口能够最小化到系统托盘,并提供丰富的交互功能。 ... [详细]
  • Qt QTableView 内嵌控件的实现方法
    本文详细介绍了在 Qt QTableView 中嵌入控件的多种方法,包括使用 QItemDelegate、setIndexWidget 和 setIndexWidget 结合布局管理器。每种方法都有其适用场景和优缺点。 ... [详细]
author-avatar
muc4093631
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有