近些年,随着智能手机的普及和UI设计的扁平化,桌面客户端程序也流行起了无边框界面的设计,究其原因,一方面是去除掉难看的系统默认标题栏、状态栏和边框,另一方面是可以将菜单以及最小化、关闭等按钮与界面元素统一进行布局设计,让整个界面功能精简、风格统一。
例如下图网易云音乐的客户端标题栏,将搜索、账户以及一些功能按钮整合在一起,这是使用默认的系统标题栏所难以实现的。
因此,今天要介绍的就是在美化PyQt5图形界面时设置无边框的方法。
那么问题来了,把大象放冰箱,不好意思串台了(噗)。
PyQt5实现无边框,总共分几步?
第一步,先把标题栏和边框去掉,状态栏以及菜单栏最好也都去掉,如果需要可以自定义。
第二步,去掉标题栏后,默认的最小化、最大化、关闭按钮也就没了,需要自行创建按钮代替。
第三步,去掉标题栏后,鼠标拖拽移动窗口也就不能实现了,因此要实现鼠标拖拽以及双击最大化、还原等功能。
不过开始第一步之前,先要准备好界面,在设计界面时,我一般使用QtDesigner绘制,然后再将保存的.ui文件转换成.py文件,开发时将UI类进行继承再进行修改。
设置无边框的代码很简单,如下:
self.pushButton.clicked.connect(self.showMinimized)
self.pushButton_2.clicked.connect(self.maxOrNormal)
self.pushButton_3.clicked.connect(self.queryExit)
# 切换最大化与正常大小
def maxOrNormal(self):
if self.isMaximized():
self.showNormal()
else:
self.showMaximized()
# 弹出警告提示窗口确认是否要关闭
def queryExit(self):
res = QtWidgets.QMessageBox.question(self,"Warning","Quit?",QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel)
if res == QtWidgets.QMessageBox.Yes:
QtCore.QCoreApplication.instance().exit()
def mouseMoveEvent(self, a0: QtGui.QMouseEvent):
if self._startPos:
self._endPos = a0.pos() - self._startPos
# 移动窗口
self.move(self.pos() + self._endPos)
# 鼠标按下事件
def mousePressEvent(self, a0: QtGui.QMouseEvent):
# 根据鼠标按下时的位置判断是否在QFrame范围内
if self.childAt(a0.pos().x(),a0.pos().y()).objectName() == "frame":
# 判断鼠标按下的是左键
if a0.button() == QtCore.Qt.LeftButton:
self._isTracking = True
# 记录初始位置
self._startPos = QtCore.QPoint(a0.x(), a0.y())
# 鼠标松开事件
def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):
if a0.button() == QtCore.Qt.LeftButton:
self._isTracking = False
self._startPos = None
self._endPos = None
# 鼠标双击事件
def mouseDoubleClickEvent(self, a0: QtGui.QMouseEvent):
if self.childAt(a0.pos().x(),a0.pos().y()).objectName() == "frame":
if a0.button() == QtCore.Qt.LeftButton:
self.maxOrNormal()
龙哥
那个QFrame部件只是为了生成一个区域,用于判断在点击左键时鼠标的位置是否在区域内,目的是让整个窗口中只有那个区域内可以拖动窗口。
点击没反应是正常的,拖拽如果没反应,那你可以打一下日志看看在哪里出bug了。