PyQt5-无边框窗体的移动实现
正常情况创建一个窗体,窗口移动、阴影、最大化最小化关闭按钮等PyQt5都处理好了,但是如果隐藏了边框,则需要自己实现上述的功能,最大化最小化直接使用Qt Designer进行信号事件绑定即可。
对于标题栏拖拽窗口跟随移动,则需要重写鼠标事件。
具体步骤如下
1、找一个具有鼠标按下mousePressEvent、鼠标移动mouseMoveEvent和鼠标松开mouseReleaseEvent事件的控件作为标题栏,比如QLabel 2、重写鼠标按下方法mousePressEvent,按下时获取鼠标相对窗口的位置 3、重写鼠标移动方法mouseMoveEvent,如果是鼠标按下了,那么鼠标移动时,修改鼠标指针为手型、改变窗口位置 4、重写鼠标松开方法mouseReleaseEvent,如果是鼠标松开了,则恢复鼠标指针为箭头
UI代码示例,绘制一个带标题栏的窗口
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'frame_move.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Frame(object):
def setupUi(self, Frame):
Frame.setObjectName("Frame")
Frame.resize(673, 490)
self.frame = QtWidgets.QFrame(Frame)
self.frame.setGeometry(QtCore.QRect(0, 0, 671, 481))
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.title_pr = QtWidgets.QLabel(self.frame)
self.title_pr.setGeometry(QtCore.QRect(0, 0, 611, 31))
font = QtGui.QFont()
font.setPointSize(14)
font.setBold(True)
font.setItalic(False)
font.setWeight(75)
self.title_pr.setFont(font)
self.title_pr.setLayoutDirection(QtCore.Qt.LeftToRight)
self.title_pr.setStyleSheet("background-color:#3375D6;\n"
"color:#FFF;")
self.title_pr.setScaledContents(False)
self.title_pr.setObjectName("title_pr")
self.minimized_btn_2 = QtWidgets.QPushButton(self.frame)
self.minimized_btn_2.setGeometry(QtCore.QRect(610, 0, 31, 31))
self.minimized_btn_2.setStyleSheet("#minimized_btn_2{\n"
"border:none;\n"
"background-color:#FFF;\n"
"}\n"
"#minimized_btn_2::hover{\n"
"background-color:#F9F9F9;\n"
"}")
self.minimized_btn_2.setObjectName("minimized_btn_2")
self.closed_btn_2 = QtWidgets.QPushButton(self.frame)
self.closed_btn_2.setGeometry(QtCore.QRect(640, 0, 31, 31))
self.closed_btn_2.setStyleSheet("#closed_btn_2{\n"
"border:none;\n"
"background-color:#FFF;\n"
"}\n"
"#closed_btn_2::hover{\n"
"background-color:#C42B1C;\n"
"}")
self.closed_btn_2.setObjectName("closed_btn_2")
self.retranslateUi(Frame)
QtCore.QMetaObject.connectSlotsByName(Frame)
def retranslateUi(self, Frame):
_translate = QtCore.QCoreApplication.translate
Frame.setWindowTitle(_translate("Frame", "Frame"))
self.title_pr.setText(_translate("Frame", " 我是标题栏"))
self.minimized_btn_2.setText(_translate("Frame", "-"))
self.closed_btn_2.setText(_translate("Frame", "X"))
在调用类中重写鼠标事件,仅监听标题栏
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QApplication, QFrame
# 导入UI
from frame_move import Ui_Frame
class frame_move_test(QFrame, Ui_Frame):
def __init__(self):
super().__init__()
self.setupUi(self)
# 设置窗口=无边框
self.setWindowFlags(Qt.FramelessWindowHint)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
# 标记是否按下
self.m_flag = True
# 获取鼠标相对窗口的位置
self.m_Position = event.globalPos() - self.pos()
event.accept()
def mouseMoveEvent(self, QMouseEvent):
try:
# 仅监听标题栏
if Qt.LeftButton and self.m_flag and self.title_pr.underMouse():
# 更改鼠标图标
self.setCursor(QCursor(Qt.OpenHandCursor))
# 更改窗口位置
self.move(QMouseEvent.globalPos() - self.m_Position)
QMouseEvent.accept()
except Exception as e:
print("报错信息=", e)
def mouseReleaseEvent(self, QMouseEvent):
self.m_flag = False
# 恢复鼠标形状
self.setCursor(QCursor(Qt.ArrowCursor))
if __name__ == '__main__':
app = QApplication(sys.argv)
frame_move_test = frame_move_test()
frame_move_test.show()
sys.exit(app.exec_())
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭