作者:muc4093631 | 来源:互联网 | 2024-12-08 18:09
原来的网址: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事件,就可以达到上述所说的效果:
- void Preview360::paintEvent(QPaintEvent *)
- {
- QBitmap bitmap(this->size());
- QPainter painter(&bitmap);
- painter.fillRect(bitmap.rect(), Qt::white);
- painter.setBrush(QColor(0, 0, 0));
-
- painter.drawRoundedRect(QRect(0, 2, this->width(), this->height()-2), 5, 5);
-
- painter.drawRoundedRect(QRect(20, 0, 120-20, 2), 2, 2);
- setMask(bitmap);
- }
代码很简单,关键在于setMask函数的使用。
若要在一个矩形窗口中央画一个圆,以下步骤:
(1).先画出窗体
(2).在窗体大小的矩形QBitmap中以白色填充整张图
(3).在矩形中央以黑色画一个圆,用黑色填充这个圆
(4).setMask(bitmap)
此时效果就出来了,一个不规则窗体,圆。
这时候再加入图片,最基本的背景图就出来了。
new出2个QLabel标签来存放图片: - m_pLabelBg0 = new QLabel(this);
- m_pLabelBg0->setPixmap(QPixmap(":/images/bg_bottom.png"));
- m_pLabelBg0->setGeometry(QRect(0, 2, this->width(), this->height()-2));
-
- m_pLabelBg1 = new QLabel(this);
- m_pLabelBg1->setPixmap(QPixmap(":/images/bg_top.png"));
- m_pLabelBg1->setGeometry(QRect(0, 0, this->width(), this->height()));
bg_top.png这张图必须置顶,Qt窗体中是基于堆栈窗体的,只需将m_pLabelBg1提升到栈顶即可,Qt提供了一个函数:raise。 当然这里涉及到很多控件的排序(栈排序),所以待所有控件都初始化完成后,再来控制也不迟。
3.画出4个页面
这里使用的方法是将4张图画到一个QLabel中的方法,该方法比较简单。 - QPixmap pixmap(QSize(this->width()*WINDOW_PAGE_COUNT, WINDOW_HEIGHT-2));
- QPainter painter(&pixmap);
- for (int i &#61; 0; i < WINDOW_PAGE_COUNT; i&#43;&#43;)
- {
- painter.drawImage(QRect(WINDOW_WIDTH*i, 0, WINDOW_WIDTH, WINDOW_HEIGHT-2),
- QImage(tr(":/images/desktop_%1.jpg").arg(i)));
- }
- m_pLabelFgTotal &#61; new QLabel(this);
-
- m_pLabelFgTotal->resize(pixmap.size());
- m_pLabelFgTotal->setPixmap(pixmap);
- 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; - void CLabel::paintEvent(QPaintEvent *e)
- {
- QPainter painter(this);
-
- if (getMouseEnterFlag())
- {
- paintWidget(50, &painter);
- }
- else if (getMousePressFlag())
- {
- paintWidget(80, &painter);
- }
-
- QWidget::paintEvent(e);
- }
- void CLabel::paintWidget(int transparency, QPainter *device)
- {
- QPen pen(Qt::NoBrush, 1);
- device->setPen(pen);
-
- QLinearGradient linear(this->rect().topLeft(), this->rect().bottomLeft());
-
-
-
- linear.setColorAt(0, QColor(255, 255, 255, transparency));
-
- QBrush brush(linear);
- device->setBrush(brush);
- device->drawRoundedRect(this->rect(), 2, 2);
- }
鼠标的几个事件&#xff1a; - void CLabel::enterEvent(QEvent *e)
- {
- if (!getMousePressFlag())
- {
- setMouseEnterFlag(true);
- }
- this->setCursor(Qt::PointingHandCursor);
- }
-
- void CLabel::leaveEvent(QEvent *e)
- {
- setMouseEnterFlag(false);
- }
-
- void CLabel::mousePressEvent(QMouseEvent *e)
- {
- if (e->button() &#61;&#61; Qt::LeftButton)
- {
- setMousePressFlag(true);
- emit signalLabelPress(this);
- }
- }
5.设置样式
其实用函数也能设置&#xff0c;但我发现用css语法来编辑样式挺方便的&#xff0c;以后会专门来介绍样式的使用&#xff0c;正因为她的实用。
在CLabel中&#xff0c;用如下样式来设置字体和背景 - this->setStyleSheet("QWidget {background:transparent;border:0px;color:white;font-weight:bold;font-size:16px;}");
6.画出4个按钮
在Preview360类中&#xff0c;创建4个按钮&#xff1a; - QStringList nameList;
-
- nameList << tr("360安全桌面 ")
- << tr("木马防火墙 ")
- << tr("360保镖 ")
- << tr("电脑门诊 ");
- for (int i &#61; 0; i < WINDOW_BUTTON_COUNT; i&#43;&#43;)
- {
- CLabel *label &#61; new CLabel(this);
- label &#61; new CLabel(this);
- label->resize(QSize(155, 45));
- label->setPixmap(QPixmap(tr(":/images/btn_%1.png").arg(i)));
- label->setText(nameList.at(i));
- label->move(8&#43;i*170, 319);
- connect(label, SIGNAL(signalLabelPress(CLabel*)), this, SLOT(slotLabelButtonPress(CLabel*)));;
- connect(label, SIGNAL(signalLabelPress(CLabel*)), this, SLOT(slotChangeCurrentPage(CLabel*)));
- m_pLabelBtnArray[i] &#61; label;
- }
- m_pLabelBtnArray[0]->setMousePressFlag(true);
将4个CLabel按钮提升到栈顶&#xff1a; - for (int i &#61; 0; i < WINDOW_BUTTON_COUNT; i&#43;&#43;)
- {
- m_pLabelBtnArray[i]->raise();
- }
但CLabel被press时&#xff0c;只能一个按钮为被press状态: - void Preview360::slotLabelButtonPress(CLabel *label)
- {
- for (int i &#61; 0; i < WINDOW_BUTTON_COUNT; i&#43;&#43;)
- {
- if (label !&#61; m_pLabelBtnArray[i])
- {
- m_pLabelBtnArray[i]->setMousePressFlag(false);
- }
- }
- }
下载地址&#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