QT 创建一个 可移动、可拉伸的无边框窗体
在使用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 创建一个 可移动、可拉伸的无边框窗体相关推荐
- Qt无边框窗体(Windows)
Qt无边框窗体Windows篇 去掉标题栏和边框 实现拖拽功能 还原窗体功能 注意点 我们可以做的更好 添加阴影 亚克力面板效果 结语 去掉标题栏和边框 首先第一步我们要通过设置系统绘制的边框消失 s ...
- 使用Qt创建一个C语言工程
使用Qt创建一个C语言工程 第一步:点击new按钮:或者在左边,点击右键选择新建项目:或者点击文件,选择新建项目 方式一 方式二 方式三 第二步:在弹出的对话框中选择Non-Qt Project和Pl ...
- MOOS-ivp 使用qt创建一个moosapp
前言 有一段时间没更新了,这个系列不会涉及到具体项目,只是moos在实际应用的总结. 虽然moos自带编译脚本,但是调试的时候很麻烦,所以直接用qt创建一个moosapp,便于链库和调试. 转载请注明 ...
- QT无边框窗体改变大小 很顺畅
近期,做项目用到无边框窗体,令人蛋疼的是无边框窗体大小的改变要像右边框那样,上下左右四周,而且要流畅. 网上也找了些代码,发现居然还要连接到windows事件,这显然不合常理,后来自己新建了demo, ...
- QT实现可移动和改变尺寸的无边框窗口
2019独角兽企业重金招聘Python工程师标准>>> 实现QT无边框窗口的拖动,尺寸改变.需要的时候从该类继承,派生类需要定义为QWidget. 头文件: #ifndef SIZE ...
- Qt第二十七章:QWidget、QMainWindow无边框自定义标题栏并自由移动、缩放、圆角
前提:UI必須采用自适应布局. 自定义组件[直接CV]custom_components.py # 自定义组件 """ QCustomTitleBar:自定义标题 QW ...
- 使用Qt创建一个时钟
如何用Qt制作时钟呢?下面一起来看一下吧: 首先来看一下成品图 我在网上找的好看的照片作为背景,用画板画表盘和各个指针,看起来效果挺不错. 主要代码 2.1.设置画家函数 2.2.背景部分 //添加背 ...
- outlook自动保存html,当创建一个新的HTML电子邮件时保持默认的Outlook格式
我想创建一个简单的脚本来创建一个HTML消息,并且我想保留尽可能多的默认值.当创建一个新的HTML电子邮件时保持默认的Outlook格式 在我的情况下,当我使用Home创建一个新邮件->新邮件时 ...
- 用Java创建一个学生成绩管理系统登陆界面(初级)
目录 任务与要求 代码部分 部分代码: 完整代码: 任务与要求 使用eclipse.exe创建一个登录界面,如图1所示,当用户名输入"lili",密码输入"123456& ...
最新文章
- Django 视图URLconf3.1
- 求真不二,春风细雨:AI界追忆黄煦涛教授的为学、为师、为人
- Eclipse插件使用links目录的用法
- php按时间分组的sql语句,(SQL语句)按指定时间段分组统计
- python调试_Python 调试
- Memcached 集群架构方面的问题
- 原理图端口符号_电气的原理图和接线图的区别,今天终于弄明白了!
- 根据JAVA实体生成SQL建表语句
- Iframe的allow属性生效时机
- 概率论与数理统计(5):大数定律与中心极限定律
- python问题——ValueError: only 2 non-keyword arguments accepted
- 劝君莫惜金缕衣 劝君惜取少年时 2015年 ,我22岁。
- 比亚迪王传福眼中的绿色工业时代:技术是改变世界的源动力
- XXljob 使用教程(springboot)
- 揭秘 AGV 物流机器人黑科技
- 基于Neo4j的关联数据评估风险投资人业绩
- RXTXcomm.jar 读取串口数据时报 Underlying input stream returned zero bytes 异常解决方法
- 02.Win10诸多坑之windows search服务启动失败
- 【拼车小程序源码推荐】方便省力快速搭建首选人人拼车CMS系统
- android获取网址xml,从网址解析的Android ListFragment(sherlock)xml