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)

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值