Qt--无边框窗口完美(FrameLess)实现,包含缩放和移动功能重写。
2024-09-06 11:44:37
前言
- Qt原本的窗口虽然可以通过QSS样式进行美化,但是只是对客户区有用,对于客户区是无效的。所以想做出一个比较好看的程序,还得自己重写实现无边框窗口。
- Qt实现无边框其实一句代码就可以,但是窗口自带的缩放,移动功和关闭功能都会没有,需要自己重写。
setWindowFlags(Qt::FramelessWindowHint);
重写无边框窗口
1.效果如下
2.由于无边框窗口没有了标题栏和最小化,最大化,关闭的按钮,所以需要自己布局相对应的控件,并重写事件。我的布局如下
3.事件对应代码
展开
//窗口关闭事件
void MainWindow::windowClose()
{
qApp->exit();
}
//窗口最小化
void MainWindow::windowMin()
{
this->showMinimized();
}
//窗口最大化
void MainWindow::windowMax()
{
isMaxWin=!isMaxWin;
if(isMaxWin) //根据是否最大化窗口,改变对应的图标
{
ui->btnMax->setIcon(QIcon(":/icons/normal.png"));
this->showMaximized();
}
else
{
ui->btnMax->setIcon(QIcon(":/icons/maxsize.png"));
this->showNormal();
}
}
4.窗口移动事件,需要重写鼠标的点击事件和移动事件
展开
void MainWindow::mousePressEvent(QMouseEvent*event)
{
if(event->button()==Qt::LeftButton) //如果鼠标左键按下
{
isPressed=true;
curPos=event->pos(); //记录当前的点击坐标
}
}
void MainWindow::mouseMoveEvent(QMouseEvent*event)
{
if(isPressed) //如果鼠标左键按下
{
this->move(event->pos()-curPos+this->pos()); //窗口移动
}
}
//鼠标释放
void MainWindow::mouseReleaseEvent(QMouseEvent*event)
{
isPressed=false;
}
3.窗口的缩放功能比较麻烦,需要用到windows的消息机制.代码如下
展开
//需要包含头文件
/*
#include <qt_windows.h>
#include <Windowsx.h>
*/
//消息处理
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
int m_nBorder = 5; //边界宽度
Q_UNUSED(eventType)
MSG *param = static_cast<MSG *>(message);
switch (param->message)
{
case WM_NCHITTEST:
{
int nX = GET_X_LPARAM(param->lParam) - this->geometry().x();
int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y();
*result = HTCAPTION;
//判断鼠标位置是否位于窗口边界
if ((nX > 0) && (nX < m_nBorder))
*result = HTLEFT;
if ((nX > this->width() - m_nBorder) && (nX < this->width()))
*result = HTRIGHT;
if ((nY > 0) && (nY < m_nBorder))
*result = HTTOP;
if ((nY > this->height() - m_nBorder) && (nY < this->height()))
*result = HTBOTTOM;
if ((nX > 0) && (nX < m_nBorder) && (nY > 0)
&& (nY < m_nBorder))
*result = HTTOPLEFT;
if ((nX > this->width() - m_nBorder) && (nX < this->width())
&& (nY > 0) && (nY < m_nBorder))
*result = HTTOPRIGHT;
if ((nX > 0) && (nX < m_nBorder)
&& (nY > this->height() - m_nBorder) && (nY < this->height()))
*result = HTBOTTOMLEFT;
if ((nX > this->width() - m_nBorder) && (nX < this->width())
&& (nY > this->height() - m_nBorder) && (nY < this->height()))
*result = HTBOTTOMRIGHT;
if (*result == HTCAPTION)
{
return false;
}
return true;
}
}
return QMainWindow::nativeEvent(eventType, message, result);
}
4.要实现窗口的正常功能,还需要对窗口的Flags进行一些设置,同时也要给父类设置,要不然会有问题的.
其中 Qt::FramelessWindowHint设置窗口为无边框,Qt::Window表示widegt为窗口,Qt::WindowMinimizeButtonHint 程序在任务栏被点击时能够显示/隐藏.
一些问题
1.把以上那些功能实现了,无边框窗口基本可以用了,至于如何用Qss美化,界面如何布局,那就看每个人了,反正可以自己进行定制
2.由于用到了windows下的消息机制,所以该实现只适用于Windows系统.虽然我在GitHub上找到不少可以跨平台的无边框窗口实现,但是都不是很完美,有兴趣的自己可以去GitHub上去看看.
3.目前的实现方法都会有一些问题,没有原本的好,但基本不影响使用,如果有需要自己也可以进行优化,所以问题不大.
完整项目代码
github: QtFrameLess
星期五女孩
最新文章
- 轻量级前端MVVM框架avalon源码分析-总结
- Android使用TextureView播放视频
- nginx搭建高性能流媒体技术
- Screen 对象
- LR常用函数整理
- Get open Popups
- 作业七:团队项目——Alpha版本冲刺阶段
- iOS 复选框做法
- HDU 1002 A + B Problem II(AC代码)
- Python之添加新元素
- POJ 3280 Cheapest Palindrome(水题)
- SuperSocket入门(二)- 探索AppServer、AppSession,Conmmand和App.config
- AutoLayout的几种方法
- 原生JS实现下拉刷新
- 模块(modue)和包(package)的概念-import导入模块
- 前端三大框架Angular &; React &; Vue
- Equivalent Sets HDU - 3836 2011多校I tarjan强连通分量
- layer(jQuery弹出层插件)
- 新建asp.net core项目
- 【托业】【新托业TOEIC新题型真题】学习笔记2-题库一-->;P5-6
热门文章
- 用Socket套接字发送和接收文件(中间用数组存取)
- Python小游戏——外星人入侵(保姆级教程)第一章 07调整飞船速度 08限制飞船活动范围
- Spring 10: AspectJ框架 + @Before前置通知
- java方法---可变参数
- 钓鱼利用-CVE-2018-20250
- 域名+端口号 访问minio服务问题
- CSS基础第一篇:图片插入<;img>;,文本空格
- 校园网跨网段共享文件Samba+SSH
- SpringMVC 06: 日期类型的变量的注入和显示
- gin如何多次shoubind一个请求参数