在使用QT创建窗体的时候,为了使窗口美化,通常不使用QT自带的边框。会调用下面函数去除窗体边框。

setWindowFlags(Qt::FramelessWindowHint)

但是有个问题,当去除了QT自带边框后,窗体就变得不能移动了,也不能改变窗口大小了。这确实是个问题,该怎么去解决呢?

首先我们来解决窗口移动的问题:解决思路就是在鼠标按下事件中记录按下的位置QPoint pLast, 并标记鼠标状态m_bPressed  = true; 为按下状态。

void MainWindow::mousePressEvent(QMouseEvent *event)
{this->setFocus();if(Qt::LeftButton == event->button() && 0 == (Qt::WindowMaximized & this->windowState())){QPoint temp=event->globalPos();pLast=temp;    //记录鼠标按下的位置event->ignore();}m_bPressed = true; //标记鼠标为按下状态
}

然后在鼠标移动事件中进行窗体移动

void MainWindow::mouseMoveEvent(QMouseEvent * event)
{if(this->isMaximized()) //如果当前是最大化,则不允许移动return; if((event->buttons() & Qt::LeftButton) && m_bPressed)//是否左击{QPoint ptemp=event->globalPos();          //当前鼠标全局位置      ptemp=ptemp-pLast;                        //计算移动变量ptemp=ptemp+pos();                        //窗口原始位置(pos()) + 鼠标移动变量(ptemp) = 最终窗口位置move(ptemp);                              //移动窗口到新的位置}
}

最后需要在鼠标松开事件中进行状态复位

void MainWindow::mouseReleaseEvent(QMouseEvent * event)
{QApplication::restoreOverrideCursor();//恢复鼠标指针性状event->ignore();m_bPressed = false;
}

到这里,就已经全部解决了无边框窗口可以动的问题。但是,但是我们窗口拉伸缩放,进行调节窗口大小的问题还没有解决,这里该怎么解决呢?首先我们将窗口的区域进行划分,如下图

这里我们将一个窗口划分为9个区域,分别为

左上角(1,1)、中上(1,2)、右上角(1,3)

左中  (2,1)、 中间(2,2)、右中  (2,3)

左下角(3,1)、中下(3,2)、 右下角(3,3)

思路应该是这样:

1.当鼠标移动时候,我们首先判断这个光标处于哪个区域

2.当鼠标移动到不同区域,鼠标的形状是不同变化的。

3.根据(2,2)之外的区域,计算初鼠标移动的偏移量,来重新设置窗口的坐标。

比如,鼠标进入区域(2,2)的时候,说明是移动窗口的操作,而不是进行窗口缩放的操作。除了区域(2,2)之外,其他8个区域均是进行窗口缩放的,但是处于不同区域内,鼠标的形状是不一样。

看代码

void MainWindow::mouseMoveEvent(QMouseEvent * event)
{if(this->isMaximized()) //如果最大化,则不允许移动和拉伸return;int poss=countFlag(event->pos(),countRow(event->pos()));//计算出来鼠标在哪个区域if(!event->buttons())setCursorType(poss);//根据不同的区域设置不同的鼠标形状if((event->buttons() & Qt::LeftButton) && m_bPressed)//是否左击{QPoint ptemp=event->globalPos();ptemp=ptemp-pLast;  //鼠标移动的偏移量if(m_curPos==22)    //区域(2,2)表示移动窗口{ptemp=ptemp+pos();move(ptemp);}else{QRect wid=geometry();int minWidth = this->minimumWidth();int minHeight = this->minimumHeight();switch(m_curPos)//改变窗口的大小{case 11:{QPoint pos = wid.topLeft();if(wid.width() > minWidth || ptemp.x() < 0)pos.rx() = pos.rx() + ptemp.x();if(wid.height() > minHeight || ptemp.y() < 0)pos.ry() = pos.ry() + ptemp.y();wid.setTopLeft(pos);break;//左上角}case 13:{QPoint pos = wid.topRight();if(wid.width() > minWidth || ptemp.x() > 0)pos.rx() = pos.rx() + ptemp.x();if(wid.height() > minHeight || ptemp.y() < 0)pos.ry() = pos.ry() + ptemp.y();wid.setTopRight(pos);break;//右上角}case 31:{QPoint pos = wid.bottomLeft();if(wid.width() > minWidth || ptemp.x() < 0)pos.rx() = pos.rx() + ptemp.x();if(wid.height() > minHeight || ptemp.y() > 0)pos.ry() = pos.ry() + ptemp.y();wid.setBottomLeft(pos);break;//左下角}case 33:{QPoint pos = wid.bottomRight();if(wid.width() > minWidth || ptemp.x() > 0)pos.rx() = pos.rx() + ptemp.x();if(wid.height() > minHeight || ptemp.y() > 0)pos.ry() = pos.ry() + ptemp.y();wid.setBottomRight(pos);break;//右下角}case 12:{int topY = wid.top();if(wid.height() > minHeight || ptemp.y() < 0)topY = topY + ptemp.y();wid.setTop(topY);break;//中上角}case 21:{int leftX = wid.left();if(wid.width() > minWidth || ptemp.x() < 0)leftX = leftX + ptemp.x();wid.setLeft(leftX);break;//中左角}case 23:{int rightX = wid.right();if(wid.width() > minWidth || ptemp.x() > 0)rightX = rightX + ptemp.x();wid.setRight(rightX);break;//中右角}case 32:{int botY = wid.bottom();if(wid.height() > minHeight || ptemp.y() > 0)botY = botY + ptemp.y();wid.setBottom(botY);break;//中下角}}setGeometry(wid);   //设置窗口的位置}pLast=event->globalPos();//更新位置}event->ignore();}

计算鼠标在哪个区域

int MainWindow::countFlag(QPoint p,int row)//计算鼠标在哪一列和哪一行
{if(p.y()<MARGIN)return 10+row;else if(p.y()>this->height()-MARGIN)return 30+row;elsereturn 20+row;
}

根据鼠标所在位置改变鼠标形状

void MainWindow::setCursorType(int flag)//根据鼠标所在位置改变鼠标指针形状
{Qt::CursorShape cursor;switch(flag){case 11:case 33:cursor=Qt::SizeFDiagCursor;break;case 13:case 31:cursor=Qt::SizeBDiagCursor;break;case 21:case 23:cursor=Qt::SizeHorCursor;break;case 12:case 32:cursor=Qt::SizeVerCursor;break;case 22:cursor=Qt::ArrowCursor;break;default://  QApplication::restoreOverrideCursor();//恢复鼠标指针性状break;}setCursor(cursor);
}

到这里,就可以正常的进行窗口拉伸进行窗口缩放了。

截止现在,已经完成了一个可拉伸,可移动的无边框窗口。

这里还有个隐患,就是设置了无边框窗口之后,里面的内容就不会及时刷新了

setWindowFlags(Qt::FramelessWindowHint)

我们应该怎么做呢?需要重写显示事件

void MainWindow::showEvent(QShowEvent* event)
{this->setAttribute(Qt::WA_Mapped);//解决不能及时刷新的bugQMainWindow::showEvent(event);
}

这里就完美的解决了所有的问题。

我这里做了一个demo,https://download.csdn.net/download/xiezhongyuan07/10390321

没有积分的小伙伴,评论留下你的邮箱,看到后第一时间发送源码

QT 创建一个 可移动、可拉伸的无边框窗体相关推荐

  1. Qt无边框窗体(Windows)

    Qt无边框窗体Windows篇 去掉标题栏和边框 实现拖拽功能 还原窗体功能 注意点 我们可以做的更好 添加阴影 亚克力面板效果 结语 去掉标题栏和边框 首先第一步我们要通过设置系统绘制的边框消失 s ...

  2. 使用Qt创建一个C语言工程

    使用Qt创建一个C语言工程 第一步:点击new按钮:或者在左边,点击右键选择新建项目:或者点击文件,选择新建项目 方式一 方式二 方式三 第二步:在弹出的对话框中选择Non-Qt Project和Pl ...

  3. MOOS-ivp 使用qt创建一个moosapp

    前言 有一段时间没更新了,这个系列不会涉及到具体项目,只是moos在实际应用的总结. 虽然moos自带编译脚本,但是调试的时候很麻烦,所以直接用qt创建一个moosapp,便于链库和调试. 转载请注明 ...

  4. QT无边框窗体改变大小 很顺畅

    近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...

  5. QT实现可移动和改变尺寸的无边框窗口

    2019独角兽企业重金招聘Python工程师标准>>> 实现QT无边框窗口的拖动,尺寸改变.需要的时候从该类继承,派生类需要定义为QWidget. 头文件: #ifndef SIZE ...

  6. Qt第二十七章:QWidget、QMainWindow无边框自定义标题栏并自由移动、缩放、圆角

    前提:UI必須采用自适应布局.  自定义组件[直接CV]custom_components.py # 自定义组件 """ QCustomTitleBar:自定义标题 QW ...

  7. 使用Qt创建一个时钟

    如何用Qt制作时钟呢?下面一起来看一下吧: 首先来看一下成品图 我在网上找的好看的照片作为背景,用画板画表盘和各个指针,看起来效果挺不错. 主要代码 2.1.设置画家函数 2.2.背景部分 //添加背 ...

  8. outlook自动保存html,当创建一个新的HTML电子邮件时保持默认的Outlook格式

    我想创建一个简单的脚本来创建一个HTML消息,并且我想保留尽可能多的默认值.当创建一个新的HTML电子邮件时保持默认的Outlook格式 在我的情况下,当我使用Home创建一个新邮件->新邮件时 ...

  9. 用Java创建一个学生成绩管理系统登陆界面(初级)

    目录 任务与要求 代码部分 部分代码: 完整代码: 任务与要求 使用eclipse.exe创建一个登录界面,如图1所示,当用户名输入"lili",密码输入"123456& ...

最新文章

  1. Django 视图URLconf3.1
  2. 求真不二,春风细雨:AI界追忆黄煦涛教授的为学、为师、为人
  3. Eclipse插件使用links目录的用法
  4. php按时间分组的sql语句,(SQL语句)按指定时间段分组统计
  5. python调试_Python 调试
  6. Memcached 集群架构方面的问题
  7. 原理图端口符号_电气的原理图和接线图的区别,今天终于弄明白了!
  8. 根据JAVA实体生成SQL建表语句
  9. Iframe的allow属性生效时机
  10. 概率论与数理统计(5):大数定律与中心极限定律
  11. python问题——ValueError: only 2 non-keyword arguments accepted
  12. 劝君莫惜金缕衣 劝君惜取少年时 2015年 ,我22岁。
  13. 比亚迪王传福眼中的绿色工业时代:技术是改变世界的源动力
  14. XXljob 使用教程(springboot)
  15. 揭秘 AGV 物流机器人黑科技
  16. 基于Neo4j的关联数据评估风险投资人业绩
  17. RXTXcomm.jar 读取串口数据时报 Underlying input stream returned zero bytes 异常解决方法
  18. 02.Win10诸多坑之windows search服务启动失败
  19. 【拼车小程序源码推荐】方便省力快速搭建首选人人拼车CMS系统
  20. android获取网址xml,从网址解析的Android ListFragment(sherlock)xml

热门文章

  1. Leetcode 1258:近义词句子(超详细的解法!!!)
  2. IntelliJ IDEA 下载安装教程(详细图文)
  3. 互联网转世,浏览器轮回
  4. 【教程】40G MTP-LC光纤配线架实现4x10G LC布线
  5. Effective C++(编写new和delete时需固守常规)
  6. 会议 | 2017VLDB 参会总结论文鉴赏
  7. 数据库SQL优化:百万级数据优化
  8. Thinkpad T470 拆装字母键帽支架
  9. SNMP4J 处理中文信息时的问题
  10. python中加法表达式_Python自然语言处理练习一