无边框窗口可以脱离系统外观的束缚,从而实现无限可能。但同时也意味着要重写一套交互逻辑。
实现无边框
self.setWindowFlags(Qt.FramelessWindowHint)
鼠标拖动窗口
首先定义一个 self.ismoving = False
用来记录当前的移动状态。然后重载三个鼠标事件。
🍡 1. 当鼠标左键被按下时,将 self.ismoving
设为真,然后记录当前鼠标位置 self.start_point
和窗口位置 self.window_point
。
def mousePressEvent(self, e):
if e.button() == Qt.LeftButton:
self.ismoving = True
self.start_point = e.globalPos()
self.window_point = self.frameGeometry().topLeft()
🍭 2. 当鼠标移动时,如果 ismoving
为真,那就获取鼠标的位移,并将其加到窗口位置上。
def mouseMoveEvent(self, e):
if self.ismoving:
relpos = e.globalPos() - self.start_point # QPoint 类型可以直接相减
self.move(self.window_point + relpos) # 所以说 Qt 真是赞!
🍤 3. 当鼠标释放后,把状态改回来。
def mouseReleaseEvent(self, e):
self.ismoving = False
加点难度
如果鼠标点击窗口可以将其关闭,同时又能响应鼠标拖动呢?
def mousePressEvent(self, e):
self.start_point = e.globalPos()
self.window_point = self.frameGeometry().topLeft()
def mouseMoveEvent(self, e):
self.ismoving = True
relpos = e.globalPos() - self.start_point
self.move(self.window_point + relpos)
def mouseReleaseEvent(self, e):
if not self.ismoving:
self.close()
self.ismoving = False