無邊框窗口
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 類即可。