pyside6开发篇---隐藏标题栏后,实现关闭、最大(小)化、窗口拖动、窗口拖动调整大小 代码很简单,但是这样就会失去最大化、窗口拖动、窗口调整大小等功能,需要我们手动实现。

1、隐藏标题栏

窗口自带的标题栏和按钮,很难满足美化的需求,所以就需要将其隐藏:

# 隐藏标题栏
self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)

代码很简单,但是这样就会失去最大化、窗口拖动、窗口调整大小等功能,需要我们手动实现。

2、最小化、最大化、关闭

这三个是窗口最基础的功能,直接调用窗口本身自带的函数即可,需要我们使用三个按钮实现:

图标资源可以去阿里巴巴矢量图库下载:iconfont-阿里巴巴矢量图标库

代码实现三个按钮功能:

# 最小化
self.ui.btn_min.clicked.connect(self.showMinimized)
# 关闭
self.ui.btn_close.clicked.connect(self.close)
# 最大化
self.ui.btn_max.clicked.connect(self.showMaximized)

这是QMainWindow自带的三个功能,但是最大化功能需要自己改造一下,不然最大化之后,再次点击无法返回原来大小。

 将最大化按钮绑定为自定义的最大化函数,就可以实现最大化和原始大小之间的切换:

self.ui.btn_max.clicked.connect(self.maximize_restore)
# 全局变量
GLOBAL_STATE = False
def maximize_restore(self):
 global GLOBAL_STATE
 status = GLOBAL_STATE
 if status == False:
 self.showMaximized()
 GLOBAL_STATE = True
 else:
 GLOBAL_STATE = False
 self.showNormal()
 self.resize(self.width() + 1, self.height() + 1)

双击实现最大化:

def double_click_max(event):
 # 双击切换最大化
 if event.type() == QEvent.MouseButtonDblClick:
 QTimer.singleShot(250, lambda: UIFunctions.maximize_restore(self))
self.ui.top_bar.mouseDoubleClickEvent = double_click_max

通过将双击实现最大化的函数绑定到UI界面中的top_bar,top_bar是使用QFrame绘制的一块区域,用来规定双击最大化的区域,也可以使用其他控件。

3、窗口拖动

窗口拖动需要重写QMainWindow的一些函数:

def mousePressEvent(self, event):
 if event.button() == Qt.LeftButton and self.ui.top_bar.geometry().contains(event.position().toPoint()):
 self.old_pos = event.globalPosition().toPoint()
def mouseMoveEvent(self, event):
 if self.old_pos is not None:
 delta = QPoint(event.globalPosition().toPoint() - self.old_pos)
 self.move(self.x() + delta.x(), self.y() + delta.y())
 self.old_pos = event.globalPosition().toPoint()
def mouseReleaseEvent(self, event):
 self.old_pos = None

需要根据自己的UI界面,修改self.ui.top_bar,其作用是规定界面中哪一部分可以被拖动,可以是QFrame或者其他控件。

4、窗口边缘调整窗口大小

实现这个功能还是比较麻烦的,需要自己定义一个组件类CustomGrip:

from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
"""
自定义CustomGrip控件,实现用户通过拖动窗口的边缘来调整窗口的大小
"""
class CustomGrip(QWidget):
 def __init__(self, parent, position, disable_color = False):
 # 设置UI
 QWidget.__init__(self)
 self.parent = parent
 self.setParent(parent)
 self.wi = Widgets()
 if position == Qt.TopEdge:
 self.wi.top(self)
 self.setGeometry(0, 0, self.parent.width(), 10)
 self.setMaximumHeight(10)
 top_left = QSizeGrip(self.wi.top_left)
 top_right = QSizeGrip(self.wi.top_right)
 def resize_top(event):
 delta = event.pos()
 height = max(self.parent.minimumHeight(), self.parent.height() - delta.y())
 geo = self.parent.geometry()
 geo.setTop(geo.bottom() - height)
 self.parent.setGeometry(geo)
 event.accept()
 self.wi.top.mouseMoveEvent = resize_top
 if disable_color:
 self.wi.top_left.setStyleSheet("background: transparent")
 self.wi.top_right.setStyleSheet("background: transparent")
 self.wi.top.setStyleSheet("background: transparent")
 elif position == Qt.BottomEdge:
 self.wi.bottom(self)
 self.setGeometry(0, self.parent.height() - 10, self.parent.width(), 10)
 self.setMaximumHeight(10)
 self.bottom_left = QSizeGrip(self.wi.bottom_left)
 self.bottom_right = QSizeGrip(self.wi.bottom_right)
 def resize_bottom(event):
 delta = event.pos()
 height = max(self.parent.minimumHeight(), self.parent.height() + delta.y())
 self.parent.resize(self.parent.width(), height)
 event.accept()
 self.wi.bottom.mouseMoveEvent = resize_bottom
 if disable_color:
 self.wi.bottom_left.setStyleSheet("background: transparent")
 self.wi.bottom_right.setStyleSheet("background: transparent")
 self.wi.bottom.setStyleSheet("background: transparent")
 elif position == Qt.LeftEdge:
 self.wi.left(self)
 self.setGeometry(0, 10, 10, self.parent.height())
 self.setMaximumWidth(10)
 def resize_left(event):
 delta = event.pos()
 width = max(self.parent.minimumWidth(), self.parent.width() - delta.x())
 geo = self.parent.geometry()
 geo.setLeft(geo.right() - width)
 self.parent.setGeometry(geo)
 event.accept()
 self.wi.leftgrip.mouseMoveEvent = resize_left
 if disable_color:
 self.wi.leftgrip.setStyleSheet("background: transparent")
 elif position == Qt.RightEdge:
 self.wi.right(self)
 self.setGeometry(self.parent.width() - 10, 10, 10, self.parent.height())
 self.setMaximumWidth(10)
 def resize_right(event):
 delta = event.pos()
 width = max(self.parent.minimumWidth(), self.parent.width() + delta.x())
 self.parent.resize(width, self.parent.height())
 event.accept()
 self.wi.rightgrip.mouseMoveEvent = resize_right
 if disable_color:
 self.wi.rightgrip.setStyleSheet("background: transparent")
 def mouseReleaseEvent(self, event):
 self.mousePos = None
 def resizeEvent(self, event):
 if hasattr(self.wi, 'container_top'):
 self.wi.container_top.setGeometry(0, 0, self.width(), 10)
 elif hasattr(self.wi, 'container_bottom'):
 self.wi.container_bottom.setGeometry(0, 0, self.width(), 10)
 elif hasattr(self.wi, 'leftgrip'):
 self.wi.leftgrip.setGeometry(0, 0, 10, self.height() - 20)
 elif hasattr(self.wi, 'rightgrip'):
 self.wi.rightgrip.setGeometry(0, 0, 10, self.height() - 20)
class Widgets(object):
 def top(self, Form):
 if not Form.objectName():
 Form.setObjectName(u"Form")
 self.container_top = QFrame(Form)
 self.container_top.setObjectName(u"container_top")
 self.container_top.setGeometry(QRect(0, 0, 500, 10))
 self.container_top.setMinimumSize(QSize(0, 10))
 self.container_top.setMaximumSize(QSize(16777215, 10))
 self.container_top.setFrameShape(QFrame.NoFrame)
 self.container_top.setFrameShadow(QFrame.Raised)
 self.top_layout = QHBoxLayout(self.container_top)
 self.top_layout.setSpacing(0)
 self.top_layout.setObjectName(u"top_layout")
 self.top_layout.setContentsMargins(0, 0, 0, 0)
 self.top_left = QFrame(self.container_top)
 self.top_left.setObjectName(u"top_left")
 self.top_left.setMinimumSize(QSize(10, 10))
 self.top_left.setMaximumSize(QSize(10, 10))
 self.top_left.setCursor(QCursor(Qt.SizeFDiagCursor))
 self.top_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
 self.top_left.setFrameShape(QFrame.NoFrame)
 self.top_left.setFrameShadow(QFrame.Raised)
 self.top_layout.addWidget(self.top_left)
 self.top = QFrame(self.container_top)
 self.top.setObjectName(u"top")
 self.top.setCursor(QCursor(Qt.SizeVerCursor))
 self.top.setStyleSheet(u"background-color: rgb(85, 255, 255);")
 self.top.setFrameShape(QFrame.NoFrame)
 self.top.setFrameShadow(QFrame.Raised)
 self.top_layout.addWidget(self.top)
 self.top_right = QFrame(self.container_top)
 self.top_right.setObjectName(u"top_right")
 self.top_right.setMinimumSize(QSize(10, 10))
 self.top_right.setMaximumSize(QSize(10, 10))
 self.top_right.setCursor(QCursor(Qt.SizeBDiagCursor))
 self.top_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
 self.top_right.setFrameShape(QFrame.NoFrame)
 self.top_right.setFrameShadow(QFrame.Raised)
 self.top_layout.addWidget(self.top_right)
 def bottom(self, Form):
 if not Form.objectName():
 Form.setObjectName(u"Form")
 self.container_bottom = QFrame(Form)
 self.container_bottom.setObjectName(u"container_bottom")
 self.container_bottom.setGeometry(QRect(0, 0, 500, 10))
 self.container_bottom.setMinimumSize(QSize(0, 10))
 self.container_bottom.setMaximumSize(QSize(16777215, 10))
 self.container_bottom.setFrameShape(QFrame.NoFrame)
 self.container_bottom.setFrameShadow(QFrame.Raised)
 self.bottom_layout = QHBoxLayout(self.container_bottom)
 self.bottom_layout.setSpacing(0)
 self.bottom_layout.setObjectName(u"bottom_layout")
 self.bottom_layout.setContentsMargins(0, 0, 0, 0)
 self.bottom_left = QFrame(self.container_bottom)
 self.bottom_left.setObjectName(u"bottom_left")
 self.bottom_left.setMinimumSize(QSize(10, 10))
 self.bottom_left.setMaximumSize(QSize(10, 10))
 self.bottom_left.setCursor(QCursor(Qt.SizeBDiagCursor))
 self.bottom_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
 self.bottom_left.setFrameShape(QFrame.NoFrame)
 self.bottom_left.setFrameShadow(QFrame.Raised)
 self.bottom_layout.addWidget(self.bottom_left)
 self.bottom = QFrame(self.container_bottom)
 self.bottom.setObjectName(u"bottom")
 self.bottom.setCursor(QCursor(Qt.SizeVerCursor))
 self.bottom.setStyleSheet(u"background-color: rgb(85, 170, 0);")
 self.bottom.setFrameShape(QFrame.NoFrame)
 self.bottom.setFrameShadow(QFrame.Raised)
 self.bottom_layout.addWidget(self.bottom)
 self.bottom_right = QFrame(self.container_bottom)
 self.bottom_right.setObjectName(u"bottom_right")
 self.bottom_right.setMinimumSize(QSize(10, 10))
 self.bottom_right.setMaximumSize(QSize(10, 10))
 self.bottom_right.setCursor(QCursor(Qt.SizeFDiagCursor))
 self.bottom_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
 self.bottom_right.setFrameShape(QFrame.NoFrame)
 self.bottom_right.setFrameShadow(QFrame.Raised)
 self.bottom_layout.addWidget(self.bottom_right)
 def left(self, Form):
 if not Form.objectName():
 Form.setObjectName(u"Form")
 self.leftgrip = QFrame(Form)
 self.leftgrip.setObjectName(u"left")
 self.leftgrip.setGeometry(QRect(0, 10, 10, 480))
 self.leftgrip.setMinimumSize(QSize(10, 0))
 self.leftgrip.setCursor(QCursor(Qt.SizeHorCursor))
 self.leftgrip.setStyleSheet(u"background-color: rgb(255, 121, 198);")
 self.leftgrip.setFrameShape(QFrame.NoFrame)
 self.leftgrip.setFrameShadow(QFrame.Raised)
 def right(self, Form):
 if not Form.objectName():
 Form.setObjectName(u"Form")
 Form.resize(500, 500)
 self.rightgrip = QFrame(Form)
 self.rightgrip.setObjectName(u"right")
 self.rightgrip.setGeometry(QRect(0, 0, 10, 500))
 self.rightgrip.setMinimumSize(QSize(10, 0))
 self.rightgrip.setCursor(QCursor(Qt.SizeHorCursor))
 self.rightgrip.setStyleSheet(u"background-color: rgb(255, 0, 127);")
 self.rightgrip.setFrameShape(QFrame.NoFrame)
 self.rightgrip.setFrameShadow(QFrame.Raised)

并实例化该类为四个边框,作为窗口边缘:

# 实例化四个CustomGrip对象,作为窗口边缘
self.left_grip = CustomGrip(self, Qt.LeftEdge, True)
self.right_grip = CustomGrip(self, Qt.RightEdge, True)
self.top_grip = CustomGrip(self, Qt.TopEdge, True)
self.bottom_grip = CustomGrip(self, Qt.BottomEdge, True)

还需要根据窗口状态更新四个窗口边缘对象的位置和大小,具体使用见完整代码。

5、完整代码

 项目结构:

images:UI界面资源文件

modules:

        app_functions.py:软件功能具体程序

        custon_grips.py:自定义组件类

        resources_rc.py:qrc的py文件

        ui_functions.py:UI功能具体程序

        ui_main.py:ui的py文件

本示例将主窗口的入口程序放到了main.py,将UI界面功能的程序放到了ui_functions.py,通过子类unctions继承父类MyWindow,来实现代码分离:

main.py:

from PySide6.QtCore import Qt, QPoint
from PySide6.QtWidgets import QApplication, QMainWindow, QButtonGroup
from modules import *
class MyWindow(QMainWindow):
 def __init__(self):
 super().__init__()
 self.ui = Ui_MainWindow()
 global widget
 widget = self.ui
 self.ui.setupUi(self)
 # 设置UI功能
 # ===============================================
 UIFunctions.ui_definitions(self)
 def mousePressEvent(self, event):
 if event.button() == Qt.LeftButton and self.ui.top_bar.geometry().contains(event.position().toPoint()):
 self.old_pos = event.globalPosition().toPoint()
 def mouseMoveEvent(self, event):
 if self.old_pos is not None:
 delta = QPoint(event.globalPosition().toPoint() - self.old_pos)
 self.move(self.x() + delta.x(), self.y() + delta.y())
 self.old_pos = event.globalPosition().toPoint()
 def mouseReleaseEvent(self, event):
 self.old_pos = None
 def resizeEvent(self, event):
 UIFunctions.resize_grips(self)
if __name__ == '__main__':
 app = QApplication([])
 window = MyWindow()
 window.show()
 app.exec()

ui_functions.py:

from PySide6.QtCore import Qt, QTimer, QEvent
from .custom_grips import CustomGrip
from main import MyWindow
GLOBAL_STATE = False
GLOBAL_TITLE_BAR = True
class UIFunctions(MyWindow):
 # 最大化/还原
 def maximize_restore(self):
 global GLOBAL_STATE
 status = GLOBAL_STATE
 if status == False:
 self.showMaximized()
 GLOBAL_STATE = True
 self.left_grip.hide()
 self.right_grip.hide()
 self.top_grip.hide()
 self.bottom_grip.hide()
 else:
 GLOBAL_STATE = False
 self.showNormal()
 self.resize(self.width() + 1, self.height() + 1)
 self.left_grip.show()
 self.right_grip.show()
 self.top_grip.show()
 self.bottom_grip.show()
 def resize_grips(self):
 self.left_grip.setGeometry(0, 10, 10, self.height())
 self.right_grip.setGeometry(self.width() - 10, 10, 10, self.height())
 self.top_grip.setGeometry(0, 0, self.width(), 10)
 self.bottom_grip.setGeometry(0, self.height() - 10, self.width(), 10)
 def ui_definitions(self):
 def double_click_max(event):
 # 双击切换最大化
 if event.type() == QEvent.MouseButtonDblClick:
 QTimer.singleShot(250, lambda: UIFunctions.maximize_restore(self))
 self.ui.top_bar.mouseDoubleClickEvent = double_click_max
 # 实例化四个CustomGrip对象,作为窗口边缘
 self.left_grip = CustomGrip(self, Qt.LeftEdge, True)
 self.right_grip = CustomGrip(self, Qt.RightEdge, True)
 self.top_grip = CustomGrip(self, Qt.TopEdge, True)
 self.bottom_grip = CustomGrip(self, Qt.BottomEdge, True)
 # 最大化
 self.ui.btn_max.clicked.connect(lambda: UIFunctions.maximize_restore(self))
 # 隐藏标题栏
 self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
 self.setAttribute(Qt.WA_TranslucentBackground)
 # 最小化
 self.ui.btn_min.clicked.connect(self.showMinimized)
 # 关闭
 self.ui.btn_close.clicked.connect(self.close)

作者:布呐呐na原文地址:https://blog.csdn.net/m0_55575697/article/details/140584936

%s 个评论

要回复文章请先登录注册