蓝色星晨|C/C++编程笔记:无边框窗口橡皮筋拉伸效果
序有时候UI设计的风格 , 并不需要系统默认的标题栏;如QQ、微信电脑版等等 。
这时候就需要我们实现对窗口的拖动和拉伸进行实现 。
由于拖动比较简单 , 就此略过 。
本文将以Qt做示例介绍我实现的拉伸功能 , 并封装成类 。
当然思路是相同的 , 其他UI也可按此方法实现 。
使用方法秉持实用至上主义 , 集成使用尽可能的方便 , 具体操作如下:只需要在无边框的窗体添加 CFrameForm 对象 , 将它叠放在窗体上就行 。 例如:
#ifndef FORM_H#define FORM_H#include
类实现如下:
#include "form.h"#include "ui_form.h"Form::Form(QWidget *parent) :QWidget(parent),ui(new Ui::Form){ui->setupUi(this);setWindowFlags(windowFlags() | Qt::FramelessWindowHint);m_frame = new CFrameForm(this);// 创建对象}Form::~Form(){delete ui;}
设计思路
- 如图所示 , 一般鼠标移动到窗口的四个角落(黑色区域)和四个边缘(红色区域)的时候 , 就可以进行拖拽了;我们只要对这个几个区域进行监听处理 , 在不同位置时 , 鼠标移动到上面就处于不同的状态 , 这样可以给用户更好的体验 。
- 当点击鼠标左键后开始 , 监听鼠标移动消息;
- 然后只要根据窗口和鼠标的位置 , 进行动态计算 , 确定窗口不动的角、边与拉动的角、边 , 便可以计算出拉伸的区域大小 。
- 再然后对区域大小进行边框标记 , 就可以看到大小;在来回拉动的过程中实时刷新下 , 即可看到橡皮筋的效果了 。
- 等到鼠标是否 , 移到了其他区域如白色区域或者窗口以外的地方 , 鼠标恢复箭头状态 。
拖拽区域为每个区域创建一个窗口 , 实现对响应鼠标的点击和释放 , 以及类型的管理 , 知道每个窗口显示什么样的光标 , 以及区域位置;我们创建一个简单的区域操作类:
class CHandel : public QWidget{Q_OBJECTpublic:CHandel(int type, CFrameForm*frm):QWidget(frm), m_type(type), m_frm(frm){}int type() {return m_type;}private:void mousePressEvent(QMouseEvent *e){m_frm->setType(m_type);QWidget::mousePressEvent(e);}void mouseReleaseEvent(QMouseEvent *e){m_frm->setType(9);QWidget::mouseReleaseEvent(e);}private:int m_type;CFrameForm*m_frm;};
橡皮筋为每个边框设计一个窗口 , 实现4条线组成的方框 , 实现橡皮筋的显示效果 。 (问:为啥不是用一个窗口 , 然后绘制四边?)为了对4条线的管理 , 我们创建一个简单的区域类:class CRubberBand{public:explicit CRubberBand();void setRect(const QRectQRect rect();bool isVisible();void show();void hide();void clear();private:QRect m_rect;QListm_lines;};
类的实现部分:/// class CRubberBandCRubberBand::CRubberBand()// 构造4条线的属性和颜色{for (int i = 0; i < 4; i++) {QWidget *l = new QWidget;l->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);l->setStyleSheet("background:rgb(133,132,131)");l->raise();m_lines.append(l);}}void CRubberBand::setRect(const QRectm_lines[0]->setGeometry(QRect(r.topLeft(), r.topRight()+QPoint(0,2)));m_lines[1]->setGeometry(QRect(r.bottomLeft(), r.bottomRight()+QPoint(0,2)));m_lines[2]->setGeometry(QRect(r.topLeft(), r.bottomLeft()+QPoint(2,0)));m_lines[3]->setGeometry(QRect(r.topRight(), r.bottomRight()+QPoint(2,0)));foreach (auto l, m_lines)l->raise();}QRect CRubberBand::rect(){return m_rect;}bool CRubberBand::isVisible() // 判断是否可见{return m_lines[0]->isVisible();}void CRubberBand::show()// 显示4条线{foreach (auto l, m_lines)l->show();}void CRubberBand::hide() // 隐藏4条线{foreach (auto l, m_lines)l->hide();}void CRubberBand::clear() // 删除四条线{foreach (auto l, m_lines)l->deleteLater();m_lines.clear();}
- 蓝色海洋|这座无人小岛遍布三千多万件“致命物品”,我们正在亲手毁掉蓝色海洋……
- 淡蓝色的记忆|央视晒九部新片海报,杨幂童瑶入镜,46岁的人气男星只有背影
- 中国天气网|台风蓝色预警!“海神”将于明日凌晨进入吉林省境内
- 过膝靴@美女街拍:蓝色牛仔裤搭配过膝靴,满满的冷艳气场啊
- 蓝色星晨|继续打磨14nm!英特尔下一代桌面处理器明年Q1发布
- #黄圣依#黄圣依晒和姐姐们合影,杨澜穿蓝色礼服美颜下很大气,吴昕又美了
- 守不住的空城|蓝色的无袖连衣裙,气质的v领看上去精致又迷人
- 钱江晚报·小时新闻|蓝色保时捷在高速被拦!宁波小伙苦苦哀求,一查背后……
- 淡蓝色的记忆|《元气满满的哥哥》:王耀庆超短裤爆笑~胡军:掀开被子就来了吧
- 淡蓝色的记忆|《在劫难逃》孙晓萌才是系列杀人案的幕后主使赵彬彬是执行者?