FrameLess Qt--無邊框窗口完美實現,包含縮放和移動功能重寫。

前言

  1. Qt原本的窗口雖然可以通過QSS樣式進行美化,但是只是對客戶區有用,對于客戶區是無效的 。所以想做出一個比較好看的程序,還得自己重寫實現無邊框窗口 。
  2. Qt實現無邊框其實一句代碼就可以,但是窗口自帶的縮放,移動功和關閉功能都會沒有,需要自己重寫 。setWindowFlags(Qt::FramelessWindowHint);
    FrameLess Qt--無邊框窗口完美實現,包含縮放和移動功能重寫。

    文章插圖
重寫無邊框窗口1.效果如下
FrameLess Qt--無邊框窗口完美實現,包含縮放和移動功能重寫。

文章插圖
2.由于無邊框窗口沒有了標題欄和最小化 , 最大化,關閉的按鈕 , 所以需要自己布局相對應的控件,并重寫事件 。我的布局如下
FrameLess Qt--無邊框窗口完美實現,包含縮放和移動功能重寫。

文章插圖
3.事件對應代碼
展開【FrameLess Qt--無邊框窗口完美實現,包含縮放和移動功能重寫?!?/strong>//窗口關閉事件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進行一些設置,同時也要給父類設置,要不然會有問題的.
FrameLess Qt--無邊框窗口完美實現,包含縮放和移動功能重寫。

文章插圖
其中 Qt::FramelessWindowHint設置窗口為無邊框,Qt::Window表示widegt為窗口,Qt::WindowMinimizeButtonHint 程序在任務欄被點擊時能夠顯示/隱藏.
一些問題1.把以上那些功能實現了,無邊框窗口基本可以用了,至于如何用Qss美化,界面如何布局,那就看每個人了,反正可以自己進行定制2.由于用到了windows下的消息機制,所以該實現只適用于Windows系統.雖然我在GitHub上找到不少可以跨平臺的無邊框窗口實現,但是都不是很完美,有興趣的自己可以去GitHub上去看看.3.目前的實現方法都會有一些問題,沒有原本的好,但基本不影響使用,如果有需要自己也可以進行優化,所以問題不大.
完整項目代碼github: QtFrameLess
星期五女孩
FrameLess Qt--無邊框窗口完美實現,包含縮放和移動功能重寫。

文章插圖

    推薦閱讀