Skip to content

PyQt5 隱藏了窗口標題後使用滑鼠拖曳界面

在使用 PyQt5 設計圖形化界面的時候,我們時常會為了美觀,而將圖形化界面的原生窗口隱藏,大概就是像以下:

這是我目前正在開發的倒數計時器。

去掉窗口之後:

當然,目前還沒有開發完成,這個界面離美觀還遠得很。不過,請原諒我拿這個界面來進行 Demo。

今天我在去掉圖形化界面的窗口之後,突然想到:欸,該怎麼拖曳?本來使用滑鼠的拖曳都是靠按住窗口來進行移動。現在沒有了窗口,如果我想要移動這個小工具該怎麼辦?

於是研究了一會兒,終於找到了不錯的方法 —— 重寫當前窗口的 mousePressEvent()、mouseMoveEvent()、mouseReleaseEvent() 這三個 methods 即可。

如果對 PyQt5 有興趣,可以參閱我之前所寫過的 PyQt5 基本教學

如果想要看官方的指南,可以參考這裡: https://www.riverbankcomputing.com/static/Docs/PyQt5/index.html?highlight=qicon


mousePressEvent()

def mousePressEvent(self, event):
    if event.button() == Qt.LeftButton:
        self.moveFlag = True
        self.movePosition = event.globalPos() - self.pos()
        self.setCursor(QCursor(Qt.OpenHandCursor))
        event.accept()



這個函式本來是我們繼承的界面的 method,現在我們重寫這個 method。
我們在判斷滑鼠按下左鍵的時候, moveFlag 為 True,並且讓系統自動計算『滑鼠座標位置』跟『界面座標位置』的差距,也就是滑鼠座標到界面座標的偏移量。

順帶一提,setCursor() 只是更換滑鼠圖示而已。


mouseMoveEvent()

剛剛看過了計算『滑鼠左鍵點下去的當下』的事件了(也就是計算偏移量)。那麼我們來看怎麼移動界面。

def mouseMoveEvent(self, event):
    if Qt.LeftButton and self.moveFlag:
        self.move(event.globalPos() - self.movePosition)
        event.accept()



剛剛我們將 moveFlag 設為 True 了,所以在滿足『滑鼠左鍵點擊』時,我們可以移動我們的界面。

使用 move() 就可以將『滑鼠座標位置』減去『偏移量』來移動我們的界面。

這兩個 method 大致上就是在做上圖的事情:

  • movePressEvent() 紀錄滑鼠點擊的位置到界面原點的『偏移量』
  • mouseMoveEvent() 計算出滑鼠移動的向量,給予界面一樣的『移動向量』。

完成這兩步驟,基本上就可以使用滑鼠拖曳視窗了。不過目前的話,即使放開滑鼠,視窗還是會被持續拖曳;所以我們需要第三個 method。


mouseReleaseEvent()

def mouseReleaseEvent(self, event):
    self.moveFlag = False
    self.setCursor(Qt.CrossCursor)



這裡要作的事情其實相當單純:還記得剛才我們將 moveFlag 設為 True 才允許界面移動嗎?現在我們在滑鼠放開的時候將 moveFlag 設為 Flase,界面就不能再移動了。

另外,再次使用 setCursor() 將滑鼠圖示換回來。

這樣就完成了基本的拖曳了。


後記

這裡是我紀錄這個心得筆記時的煩惱,已與本文無關,大家可以直接 End 沒關係。

我其實頗後悔憑著當初熱情一口氣將 PyQt5 直接作為一個系列開始寫,因為隨著我開發的需求,我發現了越來越多我『漏掉的東西』。然後,就如同此刻一般,不將這篇文列在『PyQt5 基本教學』這個系列中,而是自己獨立出來一篇,當作補述一樣,僅僅將分類列為『PyQt5』。

我最早開始寫這個 Blog,最大的目的就是讓自己能夠查詢自己學習過的東西——但最近查詢自己所寫的 PyQt5 系列時,感覺太多需要的東西分散在各章節中,沒有好好地統整起來,這都是我當初隨意開始紀錄心得筆記的錯哈哈哈哈。

之後,我想比較好的方式是:如果我學習了一項可能會用到的東西,便將其紀錄成單獨的心得筆記,若學習地更深入了,感覺自己需要完整地紀錄一遍了,再以『系列』的方式紀錄起來。

希望能分享給大家各式各樣的東西、也希望我將來查詢自己寫的 Blog 文章能更方便。

Leave a Reply