1. 程式人生 > >Qt學習筆記:無邊框窗體的移動

Qt學習筆記:無邊框窗體的移動

類似360安全衛士介面,
這裡寫圖片描述
滑鼠只能夠在綠色的位置進行點選和移動,這就是採用Qt實現的無邊框窗體的移動。
其實實現無邊框窗體的移動主要是靠以下三個函式:

    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

首先 在mainwindows.cpp中,新增

  setWindowFlags(Qt::FramelessWindowHint);//隱藏標題欄
  m_MousePressed =
false;
//滑鼠按下事件,確定相對位置
void csxfwidget::mousePressEvent(QMouseEvent *event)
{
    QRect *rc = new QRect(5,5,900,150);//建立一個矩形區域

    if(rc->contains(this>mapFromGlobal(QCursor::pos()))==true)//確定是這個矩形區域按下
    {
        if(event->button()==Qt::LeftButton)
        {
            m_WindowPos = this->
pos(); m_MousePos = event->globalPos(); this->m_MousePressed = true; } } }
//滑鼠移動事件
void csxfwidget::mouseMoveEvent(QMouseEvent *event)
{
    if(m_MousePressed)
    {
        this->move(m_WindowPos+(event->globalPos()-m_MousePos));
    }
}
//滑鼠釋放按鈕事件
void
csxfwidget::mouseReleaseEvent(QMouseEvent *event) { if(event->button()==Qt::LeftButton) { this->m_MousePressed = false; } }

mainwindows.h檔案中,新增以下程式碼:

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

    bool m_MousePressed;
    QPoint m_MousePos;
    QPoint m_WindowPos;

真正移動窗體的函式是move()函式。其他的只是為了獲取相對的位置,
因此需要理解以下幾個概念:
QMouseEvent中儲存了兩個座標,一個是全域性座標,當然另外一個是區域性座標。
全域性座標(globalPos())即是相對於螢幕的座標。
區域性座標(pos()),即是相對當前active widget的座標,左上角座標為(0, 0)。
其中:
this->mapFromGlobal(this->cursor().pos()) = event.pos()

event.pos()返回的是區域性座標,該值等於 mapFromGlobal( event.globalPos() );
因此:
if(rc->contains(this>mapFromGlobal(QCursor::pos()))==true)
可以理解為當前座標是不是包含在所確定的Rect(矩形)中。

接下來需要理解幾個點的座標:
this->pos();
介面左上角的座標,介面窗體固定了,其值也就固定了,和滑鼠點選那個點無關。
event->pos();
滑鼠事件中,相對於介面窗體左上角(0,0)的座標。
event->globalPos();
滑鼠事件中,相對於螢幕左上角(0,0)的座標
m_WindowPos+(event->globalPos()-m_MousePos)
表示,介面上一次固定的座標+(當前滑鼠移動到最終點的相對螢幕的座標-上次儲存的相對螢幕的座標)
即 上次固定的座標+移動的相對座標。
this->move(m_WindowPos+(event->globalPos()-m_MousePos));