qt设置widget边框(Qt–无边框窗口完美(FrameLess)实现,包含缩放和移动功能重写。)
前言
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
星期五女孩
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!