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();
}
}
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;
}
//需要包含標頭檔案
/*
#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