近些年,随着智能手机的普及和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了。