setWindowFlags(Qt::FramelessWindowHint);//無邊框
setAttribute(Qt::WA_TranslucentBackground);//背景透明
無邊框窗口沒有了標題欄,無法通過鼠標來移動窗口。可行的方法是重寫窗口的鼠標按下,移動和釋放等事件。
為了模擬類似拖動標題欄來移動窗口,可以規定當鼠標單擊在某個特定的區域(例如頂部高度為100的矩形區域)才能移動窗口。
下面是一個無邊框背景透明的窗體類的代碼:
//頭文件:BaseWidget.h #ifndef BASEWIDGET_H #define BASEWIDGET_H #include <QWidget> #include <QMouseEvent> //繼承自QWidget的自定義窗口,單擊(左右鍵皆可)窗口並移動鼠標可拖動窗口 class BaseWidget : public QWidget { Q_OBJECT public: explicit BaseWidget(QWidget *parent = 0); //設置鼠標按下可移動窗口的區域,在子窗口中必須設置該區域 void setAreaMovable(const QRect rt); protected: void mousePressEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); private: QRect m_areaMovable;//可移動窗口的區域,鼠標只有在該區域按下才能移動窗口 bool m_bPressed;//鼠標按下標志(不分左右鍵) QPoint m_ptPress;//鼠標按下的初始位置 }; #endif // BASEWIDGET_H
源文件:BaseWidget.cpp #include "basewidget.h" #include <QDebug> BaseWidget::BaseWidget(QWidget *parent) : QWidget(parent) { //設置無邊框透明 setWindowFlags(Qt::FramelessWindowHint);//無邊框 setAttribute(Qt::WA_TranslucentBackground);//背景透明 m_areaMovable = geometry(); m_bPressed = false; } void BaseWidget::mousePressEvent(QMouseEvent *e) { //鼠標左鍵 if(e->button() == Qt::LeftButton) { m_ptPress = e->pos(); qDebug() << pos() << e->pos() << m_ptPress; m_bPressed = m_areaMovable.contains(m_ptPress); } } void BaseWidget::mouseMoveEvent(QMouseEvent *e) { if(m_bPressed) { qDebug() << pos() << e->pos() << m_ptPress; move(pos() + e->pos() - m_ptPress); } } void BaseWidget::mouseReleaseEvent(QMouseEvent *) { m_bPressed = false; } //設置鼠標按下的區域 void BaseWidget::setAreaMovable(const QRect rt) { if(m_areaMovable != rt) { m_areaMovable = rt; } }
最簡單的方式是采用布局,在窗口頂部左側一次放“最大化”“最小化”“關閉” 3個按鈕,實現對應的功能即可,此處就不一一列出。
如果想快速實現無邊框的窗體,只需繼承BaseWidget 類即可。