(终)基于 PySide6 的自定义边框窗口类(添加标题右键菜单,双击窗口图标关闭事件)

12 篇文章 1 订阅
12 篇文章 1 订阅

 往期文章链接:

3.(续)基于 PySide6 的自定义边框窗口类(在可移动和调整大小的基础上自定义标题栏,标题,窗口颜色)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2402_84665876/article/details/141106193?spm=1001.2014.3001.5501

2. 

(续)基于 PySide6 的自定义边框窗口类(增加最大化,最小化,关闭按钮)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2402_84665876/article/details/141103045?spm=1001.2014.3001.55011.

基于 PySide6 的 FramelessWindow 类-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/2402_84665876/article/details/141093760?spm=1001.2014.3001.5501

准备工作:

在使用此代码前,请在同目录下放几张图片

close.png(关闭按钮图片)

max.png(最大化按钮图片)

min.png(最小化按钮图片)

normal.png(向下还原按钮图片)

icon.png(窗口图标)

closeborder.png(带透明边框的关闭按钮图片)

maxborder.png(带透明边框的最大化按钮图片)

minborder.png(带透明边框的最小化按钮图片)

normalborder.png(带透明边框的向下还原按钮图片)

后四张图片用来设置标题栏右键菜单的选项图标,如果你不想添加图标,可只准备前五张图片。如果你没有找到合适的图片文件,可访问我的 GitHub 仓库:zyx220623/WindowButtonImage (github.com)icon-default.png?t=N7T8https://github.com/zyx220623/WindowButtonImage/tree/main

完整代码:

import sys
from PySide6.QtCore import (Qt,
                            QRect,
                            QSize,
                            QPoint)
from PySide6.QtGui import (QPixmap,
                           QMouseEvent,
                           QCursor,
                           QGuiApplication,
                           QIcon,
                           QFont, QAction)
from PySide6.QtWidgets import (QPushButton,
                               QWidget,
                               QApplication,
                               QMainWindow, QMenu)


class FrameLessWindow(QMainWindow):
    edge: int

    def __NoneEvent(self, event: QMouseEvent | None = None):
        pass

    def __attributeInit(self):
        self.movemode = 0
        self.is_mouse_pressed = False
        self.up_resized = False
        self.toDownPress = False
        self.left_resized = False
        self.toRightPress = False
        self.upleft_resized = False
        self.upright_resized = False
        self.downright_resized = False
        self.downleft_resized = False
        self.edge = 5
        self.beginning_pos_right = QCursor().pos()
        self.beginning_pos_up = QCursor().pos()
        self.beginning_pos_down = QCursor().pos()
        self.setMouseTracking(True)
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.__setWindowStatusMenu()
        self.__screen__ = QGuiApplication.primaryScreen().size()

    def __init__(self, parent: QWidget | None = None,
                 taskbar_height: int = 44,
                 MinimumSize: QSize = QSize(400, 225),
                 ReSize: QSize = QSize(400, 225),
                 Position: QPoint | None = None,
                 title_height: int = 35,
                 title_font_size: int = 15,
                 background_color_rgba: tuple[int, int, int, int] | list[int] | set[int] = (255, 255, 255, 1),
                 title_background_color_rgba: tuple[int, int, int, int] | list[int] | set[int] = (0, 0, 0, 1),
                 title_text_color_rgba: tuple[int, int, int, int] | list[int] | set[int] = (255, 255, 255, 1),
                 button_hoverColor: tuple[int, int, int, int] | list[int] | set[int] = (100, 100, 100, 1),
                 closeButton_hoverColor: tuple[int, int, int, int] | list[int] | set[int] = (255, 0, 0, 1)):
        super(FrameLessWindow, self).__init__(parent)
        self.__attributeInit()
        self.setMinimumSize(MinimumSize)
        self.resize(ReSize)
        self.taskbar_height = taskbar_height
        self.button_hoverColor = button_hoverColor
        self.closeButton_hoverColor = closeButton_hoverColor
        self.title_font_size = title_font_size
        self.parent_name = parent
        self.background_color_rgba = background_color_rgba
        self.title_background_color_rgba = title_background_color_rgba
        self.title_height = title_height
        self.title_text_color_rgba = title_text_color_rgba
        self.setStyleSheet("QMainWindow {"
                           f"background-color: rgba({background_color_rgba[0]},{background_color_rgba[1]},{background_color_rgba[2]},{background_color_rgba[3]});"
                           "border: none;"
                           "}")
        self.title = ""
        self.__setWindowTitleBar(background_color_rgba=self.title_background_color_rgba,
                                 color_rgba=self.title_text_color_rgba)
        self.__setMainWidget()
        self.__setThreeButton()
        if Position is not None:
            self.move(Position)
        else:
            self.move((self.__screen__.width() - self.size().width()) // 2,
                      (self.__screen__.height() - self.size().height() - self.taskbar_height) // 2)
        self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())

    def setWindowTitle(self, arg__1):
        super().setWindowTitle(arg__1)
        self.title = arg__1
        self.__setWindowTitleBar(background_color_rgba=self.title_background_color_rgba,
                                 color_rgba=self.title_text_color_rgba)

    def setWindowIcon(self, icon: QIcon | QPixmap):
        def windowIconDoubleClickedEvent(event: QMouseEvent):
            self.close()

        super().setWindowIcon(icon)
        self.__icon__ = icon
        self.icon_image = QPushButton(self)
        self.icon_image.setIcon(icon)
        self.icon_image.setIconSize(QSize(self.title_height - 10, self.title_height - 10))
        self.icon_image.setFixedSize(self.title_height - 10, self.title_height - 10)
        self.icon_image.move(5, 5)
        self.icon_image.setStyleSheet("QPushButton {"
                                      "background-color: rgba(0,0,0,0);"
                                      "border: none;"
                                      "}")
        self.icon_image.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.icon_image.customContextMenuRequested.connect(self.__showWindowStatusMenuFromIcon)
        self.icon_image.mouseDoubleClickEvent = windowIconDoubleClickedEvent

    def resizeEvent(self, event):
        self.WindowTitleBar.setGeometry(self.title_height + 5, 0, self.size().width(), self.title_height)
        self.MoveableArea.setGeometry(0, 0, self.size().width(), self.title_height)
        self.ToUpArea.setGeometry(0, 0, self.size().width(), self.edge)
        self.ToDownArea.setGeometry(0, self.size().height() - self.edge, self.size().width(), self.edge)
        self.ToLeftArea.setGeometry(0, 0, self.edge, self.size().height())
        self.ToRightArea.setGeometry(self.size().width() - self.edge, 0, self.edge, self.size().height())
        self.main_widget.setGeometry(0,
                                     self.title_height,
                                     self.size().width(),
                                     self.size().height())
        self.UpRightArea.setGeometry(self.size().width() - self.edge, 0, self.edge, self.edge)
        self.DownRightArea.setGeometry(self.size().width() - self.edge, self.size().height() - self.edge, self.edge,
                                       self.edge)
        self.DownLeftArea.setGeometry(0, self.size().height() - self.edge, self.edge,
                                      self.edge)
        self.CloseButton.move(self.size().width() - self.CloseButton.size().width(), 0)
        self.MaximumButton.move(self.CloseButton.pos().x() - self.MaximumButton.size().width(), 0)
        self.MinimumButton.move(self.MaximumButton.pos().x() - self.MinimumButton.size().width(), 0)
        self.CloseButton.raise_()
        self.MaximumButton.raise_()
        self.MinimumButton.raise_()
        self.ToUpArea.raise_()
        self.ToRightArea.raise_()
        self.ToDownArea.raise_()
        self.ToLeftArea.raise_()
        self.UpRightArea.raise_()
        self.DownRightArea.raise_()
        self.UpLeftArea.raise_()
        self.DownLeftArea.raise_()

    def close(self):
        super().close()

    def __setMainWidget(self):
        self.main_widget = QPushButton(self)
        self.main_widget.setStyleSheet("QPushButton {"
                                       "border: none;"
                                       f"background-color: rgba({self.background_color_rgba[0]}, {self.background_color_rgba[1]}, {self.background_color_rgba[2]}, 0);"
                                       "}")

    def __setNoneEvent(self):
        self.ToUpArea.mouseMoveEvent = self.__NoneEvent
        self.ToUpArea.mousePressEvent = self.__NoneEvent
        self.ToUpArea.mouseReleaseEvent = self.__NoneEvent
        self.ToDownArea.mouseMoveEvent = self.__NoneEvent
        self.ToDownArea.mousePressEvent = self.__NoneEvent
        self.ToDownArea.mouseReleaseEvent = self.__NoneEvent
        self.ToLeftArea.mouseMoveEvent = self.__NoneEvent
        self.ToLeftArea.mousePressEvent = self.__NoneEvent
        self.ToLeftArea.mouseReleaseEvent = self.__NoneEvent
        self.ToRightArea.mouseMoveEvent = self.__NoneEvent
        self.ToRightArea.mousePressEvent = self.__NoneEvent
        self.ToRightArea.mouseReleaseEvent = self.__NoneEvent
        self.UpLeftArea.mouseMoveEvent = self.__NoneEvent
        self.UpLeftArea.mousePressEvent = self.__NoneEvent
        self.UpLeftArea.mouseReleaseEvent = self.__NoneEvent
        self.UpRightArea.mouseMoveEvent = self.__NoneEvent
        self.UpRightArea.mousePressEvent = self.__NoneEvent
        self.UpRightArea.mouseReleaseEvent = self.__NoneEvent
        self.DownRightArea.mouseMoveEvent = self.__NoneEvent
        self.DownRightArea.mousePressEvent = self.__NoneEvent
        self.DownRightArea.mouseReleaseEvent = self.__NoneEvent
        self.DownLeftArea.mouseMoveEvent = self.__NoneEvent
        self.DownLeftArea.mousePressEvent = self.__NoneEvent
        self.DownLeftArea.mouseReleaseEvent = self.__NoneEvent
        self.__setWindowStatusMenuOnEdge()

    def __setNormalEvent(self):
        self.ToUpArea.mouseMoveEvent = self.__toUpMoveEvent
        self.ToUpArea.mousePressEvent = self.__toUpPressEvent
        self.ToUpArea.mouseReleaseEvent = self.__toUpReleaseEvent
        self.ToDownArea.mouseMoveEvent = self.__toDownMoveEvent
        self.ToDownArea.mousePressEvent = self.__toDownPressEvent
        self.ToDownArea.mouseReleaseEvent = self.__toDownReleaseEvent
        self.ToLeftArea.mouseMoveEvent = self.__toLeftMoveEvent
        self.ToLeftArea.mousePressEvent = self.__toLeftPressEvent
        self.ToLeftArea.mouseReleaseEvent = self.__toLeftReleaseEvent
        self.ToRightArea.mouseMoveEvent = self.__toRightMoveEvent
        self.ToRightArea.mousePressEvent = self.__toRightPressEvent
        self.ToRightArea.mouseReleaseEvent = self.__toRightReleaseEvent
        self.MoveableArea.mousePressEvent = self.__movePressEvent
        self.MoveableArea.mouseMoveEvent = self.__moveMoveEvent
        self.MoveableArea.mouseReleaseEvent = self.__moveReleaseEvent
        self.MoveableArea.mouseDoubleClickEvent = self.__titleDoubleClickedEvent
        self.UpLeftArea.mouseMoveEvent = self.__UpLeftMoveEvent
        self.UpLeftArea.mousePressEvent = self.__UpLeftPressEvent
        self.UpLeftArea.mouseReleaseEvent = self.__UpLeftReleaseEvent
        self.UpRightArea.mouseMoveEvent = self.__UpRightMoveEvent
        self.UpRightArea.mousePressEvent = self.__UpRightPressEvent
        self.UpRightArea.mouseReleaseEvent = self.__UpRightReleaseEvent
        self.DownRightArea.mouseMoveEvent = self.__DownRightMoveEvent
        self.DownRightArea.mousePressEvent = self.__DownRightPressEvent
        self.DownRightArea.mouseReleaseEvent = self.__DownRightReleaseEvent
        self.DownLeftArea.mouseMoveEvent = self.__DownLeftMoveEvent
        self.DownLeftArea.mousePressEvent = self.__DownLeftPressEvent
        self.DownLeftArea.mouseReleaseEvent = self.__DownLeftReleaseEvent
        self.__setWindowStatusMenu()

    def showMaximized(self):
        """自定义最大化方法"""
        super().showMaximized()
        self.MaximumButton.setIcon(QIcon("normal.png"))
        self.__setNoneEvent()
        self.__setWindowStatusMenuOnMax()

    def showLined(self):
        self.setGeometry(self.pos().x(), 0, self.size().width(), self.__screen__.height() - self.taskbar_height)
        self.__setNoneEvent()

    def showNormal(self):
        self.setGeometry(self.normal_geometry.x(), self.normal_geometry.y(), self.normal_geometry.width(),
                         self.normal_geometry.height())
        self.MaximumButton.setIcon(QIcon("max.png"))
        self.__setNormalEvent()
        if self.pos().y() <= 5 and self.__isLined() is not True:
            self.move(self.normal_geometry.x(), 5)

    def showSizeNormal(self):
        self.resize(self.normal_geometry.width(), self.normal_geometry.height())
        self.MaximumButton.setIcon(QIcon("max.png"))
        self.__setNormalEvent()

    def showUpLeft(self):
        self.setGeometry(0, 0, self.__screen__.width() // 2,
                         (self.__screen__.height() - self.taskbar_height) // 2)
        self.__setNoneEvent()

    def showFullLeft(self):
        self.setGeometry(0, 0, self.__screen__.width() // 2,
                         self.__screen__.height() - self.taskbar_height)
        self.__setNoneEvent()

    def showDownLeft(self):
        self.setGeometry(0, (self.__screen__.height() - self.taskbar_height) // 2,
                         self.__screen__.width() // 2,
                         (self.__screen__.height() - self.taskbar_height) // 2)
        self.__setNoneEvent()

    def showUpRight(self):
        self.setGeometry(self.__screen__.width() // 2, 0,
                         self.__screen__.width() // 2,
                         (self.__screen__.height() - self.taskbar_height) // 2)
        self.__setNoneEvent()

    def showDownRight(self):
        self.setGeometry(self.__screen__.width() // 2,
                         (self.__screen__.height() - self.taskbar_height) // 2,
                         self.__screen__.width() // 2,
                         (self.__screen__.height() - self.taskbar_height) // 2)
        self.__setNoneEvent()

    def showFullRight(self):
        self.setGeometry(self.__screen__.width() // 2, 0,
                         self.__screen__.width() // 2,
                         self.__screen__.height() - self.taskbar_height)
        self.__setNoneEvent()

    def isMaximized(self) -> bool:
        """自定义最大化规则"""
        return super().isMaximized()

    def __isLined(self) -> bool:
        if self.size().height() == self.__screen__.height() - self.taskbar_height and self.pos().y() == 0:
            return True
        else:
            return False

    def __isFullSide(self) -> bool:
        if self.size().width() == self.__screen__.width() // 2 and \
                self.size().height() == self.__screen__.height() - self.taskbar_height and \
                self.pos().y() == 0:
            if self.pos().x() == self.__screen__.width() // 2 or \
                    self.pos().x() == 0:
                return True
            else:
                return False
        else:
            return False

    def __isFullCorner(self) -> bool:
        result = True
        if (self.size().width() != self.__screen__.width() // 2 or self.size().height() != (
                self.__screen__.height() - self.taskbar_height) // 2) and \
                (self.pos().x() <= 5 or self.pos().x() != self.__screen__.width() // 2) and \
                (self.pos().y() <= 5 or self.pos().y() != (self.__screen__.height() - self.taskbar_height) // 2):
            result = False
        return result

    def __titleDoubleClickedEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            if self.isMaximized() or self.__isLined() or self.__isFullCorner() or self.__isFullSide():
                self.showNormal()
            else:
                self.showMaximized()

    def __setWindowTitleBar(self,
                            background_color_rgba: tuple[int, int, int, int] | list[int] | set[int],
                            color_rgba: tuple[int, int, int, int] | list[int] | set[int]):
        try:
            self.title
        except:
            self.title = ""
        self.WindowTitleBackground = QPushButton(self)
        self.WindowTitleBackground.setStyleSheet("QPushButton {"
                                                 f"background-color: rgba({background_color_rgba[0]}, {background_color_rgba[1]}, {background_color_rgba[2]}, {background_color_rgba[3]});"
                                                 "border: none;"
                                                 "}")
        self.WindowTitleBackground.setGeometry(0, 0, self.__screen__.width(), self.title_height)
        self.WindowTitleBar = QPushButton(self.title, self)
        self.WindowTitleBar.setGeometry(self.title_height + 5, 0, self.size().width(), self.title_height)
        self.WindowTitleBar.setStyleSheet("QPushButton {"
                                          "text-align: left;"
                                          f'font: normal normal {self.title_font_size}px "微软雅黑";'
                                          f"background-color: rgba(0,0,0,0);"
                                          f"color: rgba({color_rgba[0]}, {color_rgba[1]}, {color_rgba[2]}, {color_rgba[3]});"
                                          "border: none;"
                                          "}")
        self.__setMoveableArea()

    def __setWindowStatusMenu(self):
        self.WindowStatusMenu = QMenu(self)
        self.WindowStatusMenu_qss = ("QMenu {"
                                     "background-color:rgb(40, 40, 40);"
                                     "color:rgb(255, 255, 255);"
                                     "}"
                                     "QMenu:item:selected {"
                                     "background-color:rgb(80, 80, 80);"
                                     "}"
                                     "QMenu:separator{"
                                     "height:1px;"
                                     "background-color:rgba(123,123,123,1);"
                                     "margin-left:22px;"
                                     "margin-right:1px;"
                                     "}"
                                     "QMenu:item:disabled {"
                                     "color:rgb(100,100,100);"
                                     "background-color:rgb(40, 40, 40);"
                                     "}")
        self.WindowStatusMenu.setStyleSheet(self.WindowStatusMenu_qss)
        self.NormalAction = QAction("还原(&R)", self)
        self.NormalAction.setEnabled(False)
        self.NormalAction.triggered.connect(self.showNormal)
        self.NormalAction.setIcon(QIcon("normalborder.png"))
        self.WindowStatusMenu.addAction(self.NormalAction)
        self.MoveAction = QAction("移动(&M)", self)
        self.WindowStatusMenu.addAction(self.MoveAction)
        self.SizeAction = QAction("大小(&S)", self)
        self.WindowStatusMenu.addAction(self.SizeAction)
        self.MinAction = QAction("最小化(&N)", self)
        self.MinAction.setIcon(QIcon("minborder.png"))
        self.MinAction.triggered.connect(self.showMinimized)
        self.WindowStatusMenu.addAction(self.MinAction)
        self.MaxAction = QAction("最大化(&X)", self)
        self.MaxAction.triggered.connect(self.showMaximized)
        self.MaxAction.setIcon(QIcon("maxborder.png"))
        self.WindowStatusMenu.addAction(self.MaxAction)
        self.WindowStatusMenu.addSeparator()
        self.CloseAction = QAction("关闭(&C)", self)
        self.CloseAction.setShortcut("Alt+F4")
        self.CloseAction.setIcon(QIcon("closeborder.png"))
        self.CloseAction.triggered.connect(self.close)
        self.WindowStatusMenu.addAction(self.CloseAction)

    def __setWindowStatusMenuOnEdge(self):
        self.WindowStatusMenu = QMenu(self)
        self.WindowStatusMenu.setStyleSheet(self.WindowStatusMenu_qss)
        self.NormalAction = QAction("还原(&R)", self)
        self.NormalAction.triggered.connect(self.showNormal)
        self.NormalAction.setIcon(QIcon("normalborder.png"))
        self.WindowStatusMenu.addAction(self.NormalAction)
        self.MoveAction = QAction("移动(&M)", self)
        self.WindowStatusMenu.addAction(self.MoveAction)
        self.SizeAction = QAction("大小(&S)", self)
        self.SizeAction.setEnabled(False)
        self.WindowStatusMenu.addAction(self.SizeAction)
        self.MinAction = QAction("最小化(&N)", self)
        self.MinAction.setIcon(QIcon("minborder.png"))
        self.MinAction.triggered.connect(self.showMinimized)
        self.WindowStatusMenu.addAction(self.MinAction)
        self.MaxAction = QAction("最大化(&X)", self)
        self.MaxAction.triggered.connect(self.showMaximized)
        self.MaxAction.setIcon(QIcon("maxborder.png"))
        self.WindowStatusMenu.addAction(self.MaxAction)
        self.WindowStatusMenu.addSeparator()
        self.CloseAction = QAction("关闭(&C)", self)
        self.CloseAction.setShortcut("Alt+F4")
        self.CloseAction.setIcon(QIcon("closeborder.png"))
        self.CloseAction.triggered.connect(self.close)
        self.WindowStatusMenu.addAction(self.CloseAction)

    def __setWindowStatusMenuOnMax(self):
        self.WindowStatusMenu = QMenu(self)
        self.WindowStatusMenu.setStyleSheet(self.WindowStatusMenu_qss)
        self.NormalAction = QAction("还原(&R)", self)
        self.NormalAction.triggered.connect(self.showNormal)
        self.NormalAction.setIcon(QIcon("normalborder.png"))
        self.WindowStatusMenu.addAction(self.NormalAction)
        self.MoveAction = QAction("移动(&M)", self)
        self.WindowStatusMenu.addAction(self.MoveAction)
        self.SizeAction = QAction("大小(&S)", self)
        self.SizeAction.setEnabled(False)
        self.WindowStatusMenu.addAction(self.SizeAction)
        self.MinAction = QAction("最小化(&N)", self)
        self.MinAction.setIcon(QIcon("minborder.png"))
        self.MinAction.triggered.connect(self.showMinimized)
        self.WindowStatusMenu.addAction(self.MinAction)
        self.MaxAction = QAction("最大化(&X)", self)
        self.MaxAction.setEnabled(False)
        self.MaxAction.triggered.connect(self.showMaximized)
        self.MaxAction.setIcon(QIcon("maxborder.png"))
        self.WindowStatusMenu.addAction(self.MaxAction)
        self.WindowStatusMenu.addSeparator()
        self.CloseAction = QAction("关闭(&C)", self)
        self.CloseAction.setShortcut("Alt+F4")
        self.CloseAction.setIcon(QIcon("closeborder.png"))
        self.CloseAction.triggered.connect(self.close)
        self.WindowStatusMenu.addAction(self.CloseAction)

    def __showWindowStatusMenuFromTitle(self, pos: QPoint):
        self.WindowStatusMenu.exec(self.MoveableArea.mapToGlobal(pos))

    def __showWindowStatusMenuFromIcon(self, pos: QPoint):
        self.WindowStatusMenu.exec(self.icon_image.mapToGlobal(pos))

    def __setMinimumButton(self):
        self.MinimumButton = QPushButton(self)
        self.MinimumButton.setIcon(QIcon("min.png"))
        self.MinimumButton.setIconSize(QSize(self.title_height - 20, self.title_height - 20))
        self.MinimumButton.setStyleSheet("QPushButton {"
                                         "background-color: rgba(25, 25, 25, 0);"
                                         "border: none;"
                                         "}"
                                         "QPushButton:hover {"
                                         f"background-color: rgba({self.button_hoverColor[0]},{self.button_hoverColor[1]},{self.button_hoverColor[2]}, {self.button_hoverColor[3]});"
                                         "}")
        self.MinimumButton.resize(self.title_height, self.title_height)
        self.MinimumButton.move(self.MaximumButton.pos().x() - self.MinimumButton.size().width(), 0)
        self.MinimumButton.clicked.connect(self.showMinimized)

    def __setMaximumButton(self):
        self.MaximumButton = QPushButton(self)
        self.MaximumButton.setIcon(QIcon("max.png"))
        self.MaximumButton.setIconSize(QSize(self.title_height - 20, self.title_height - 20))
        self.MaximumButton.resize(self.title_height, self.title_height)
        self.MaximumButton.setStyleSheet("QPushButton {"
                                         "background-color: rgba(25, 25, 25, 0);"
                                         "color: rgba(255,255,255,1);"
                                         "border: none;"
                                         "}"
                                         "QPushButton:hover {"
                                         f"background-color: rgba({self.button_hoverColor[0]},{self.button_hoverColor[1]},{self.button_hoverColor[2]}, {self.button_hoverColor[3]});"
                                         "color: rgba(255,255,255,1);"
                                         "}")
        self.MaximumButton.move(self.CloseButton.pos().x() - self.MaximumButton.size().width(), 0)
        self.MaximumButton.clicked.connect(self.MaximumButtonClickedEvent)

    def __setCloseButton(self):
        self.CloseButton = QPushButton(self)
        self.CloseButton.resize(self.title_height, self.title_height)
        self.CloseButton.setIcon(QIcon("close.png"))
        self.CloseButton.setIconSize(QSize(self.title_height - 20, self.title_height - 20))
        self.CloseButton.setStyleSheet("QPushButton {"
                                       "background-color: rgba(25, 25, 25, 0);"
                                       "color: rgba(255,255,255,1);"
                                       "border: none;"
                                       "}"
                                       "QPushButton:hover {"
                                       f"background-color: rgba({self.closeButton_hoverColor[0]},{self.closeButton_hoverColor[1]},{self.closeButton_hoverColor[2]}, {self.closeButton_hoverColor[3]});"
                                       "color: rgba(255,255,255,1);"
                                       "}")
        self.CloseButton.move(self.size().width() - self.CloseButton.size().width(), 0)
        self.CloseButton.raise_()
        self.CloseButton.clicked.connect(self.close)

    def __setThreeButton(self):
        self.__setCloseButton()
        self.__setMaximumButton()
        self.__setMinimumButton()

    def MaximumButtonClickedEvent(self):
        if self.isMaximized():
            self.showNormal()
        else:
            self.showMaximized()

    def __setMoveableArea(self):
        self.MoveableArea = QPushButton(self)
        self.MoveableArea.setStyleSheet("QPushButton {"
                                        "background-color: rgba(255,255,255,0);"
                                        "border: none;"
                                        "}")
        self.MoveableArea.setGeometry(0, 0, self.size().width(), self.title_height)
        self.MoveableArea.mousePressEvent = self.__movePressEvent
        self.MoveableArea.mouseMoveEvent = self.__moveMoveEvent
        self.MoveableArea.mouseReleaseEvent = self.__moveReleaseEvent
        self.MoveableArea.mouseDoubleClickEvent = self.__titleDoubleClickedEvent
        self.MoveableArea.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.MoveableArea.customContextMenuRequested.connect(self.__showWindowStatusMenuFromTitle)
        self.__setToUpArea()

    def __setToUpArea(self):
        self.ToUpArea = QPushButton(self.MoveableArea)
        self.ToUpArea.setStyleSheet("QPushButton {"
                                    "background-color: rgba(255,255,255,0);"
                                    "border: none;"
                                    "}")
        self.ToUpArea.setGeometry(0, 0, self.size().width(), self.edge)
        self.ToUpArea.setCursor(Qt.CursorShape.SizeVerCursor)
        self.ToUpArea.mouseMoveEvent = self.__toUpMoveEvent
        self.ToUpArea.mousePressEvent = self.__toUpPressEvent
        self.ToUpArea.mouseReleaseEvent = self.__toUpReleaseEvent
        self.__setToDownArea()

    def __setToDownArea(self):
        self.ToDownArea = QPushButton(self)
        self.ToDownArea.setStyleSheet("QPushButton {"
                                      "background-color: rgba(255,255,255,0);"
                                      "border: none;"
                                      "}")
        self.ToDownArea.setGeometry(0, self.size().height() - self.edge, self.size().width(), self.edge)
        self.ToDownArea.setCursor(Qt.CursorShape.SizeVerCursor)
        self.ToDownArea.mouseMoveEvent = self.__toDownMoveEvent
        self.ToDownArea.mousePressEvent = self.__toDownPressEvent
        self.ToDownArea.mouseReleaseEvent = self.__toDownReleaseEvent
        self.__setToLeftArea()

    def __setToLeftArea(self):
        self.ToLeftArea = QPushButton(self)
        self.ToLeftArea.setStyleSheet("QPushButton {"
                                      "background-color: rgba(255,255,255,0);"
                                      "border: none;"
                                      "}")
        self.ToLeftArea.setGeometry(0, 0, self.edge, self.size().height())
        self.ToLeftArea.setCursor(Qt.CursorShape.SizeHorCursor)
        self.ToLeftArea.mouseMoveEvent = self.__toLeftMoveEvent
        self.ToLeftArea.mousePressEvent = self.__toLeftPressEvent
        self.ToLeftArea.mouseReleaseEvent = self.__toLeftReleaseEvent
        self.__setToRightArea()

    def __setToRightArea(self):
        self.ToRightArea = QPushButton(self)
        self.ToRightArea.setStyleSheet("QPushButton {"
                                       "background-color: rgba(255,255,255,0);"
                                       "border: none;"
                                       "}")
        self.ToRightArea.setGeometry(self.size().width() - self.edge, 0, self.edge, self.size().height())
        self.ToRightArea.setCursor(Qt.CursorShape.SizeHorCursor)
        self.ToRightArea.mouseMoveEvent = self.__toRightMoveEvent
        self.ToRightArea.mousePressEvent = self.__toRightPressEvent
        self.ToRightArea.mouseReleaseEvent = self.__toRightReleaseEvent
        self.__setUpLeftArea()

    def __toRightPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.right_click_position = event.globalPosition().toPoint() - self.pos()
            self.beginning_pos_x = QCursor.pos().x()
            self.toRightPress = True
            self._width_ = self.size().width()

    def __toRightMoveEvent(self, event: QMouseEvent):
        if self.toRightPress and QCursor.pos().x() >= self.pos().x() + self.minimumWidth() - self.edge:
            self.resize(self._width_ + (QCursor.pos().x() - self.beginning_pos_x), self.size().height())
        event.accept()

    def __toRightReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.toRightPress = False
            self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __movePressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton and \
                event.position().y() <= self.title_height:
            self.is_mouse_pressed = True
            self.mouse_click_position = event.globalPosition().toPoint() - self.pos()
            if self.isMaximized():
                self.movemode = 1
            elif self.__isFullSide():
                self.movemode = 3
            elif self.__isFullCorner():
                self.movemode = 4
            elif self.__isLined():
                self.movemode = 2
            else:
                self.movemode = 0
        event.accept()

    def __moveMoveEvent(self, event: QMouseEvent):
        if self.is_mouse_pressed:
            if self.movemode == 0:
                self.move(event.globalPosition().toPoint() - self.mouse_click_position)
            elif self.movemode == 3:
                self.showSizeNormal()
                self.move(
                    event.globalPosition().toPoint().x() - self.mouse_click_position.x() * self.normal_geometry.width() // (
                            self.__screen__.width() // 2),
                    (event.globalPosition().toPoint() - self.mouse_click_position).y())
            elif self.movemode == 1:
                self.showSizeNormal()
                self.move(
                    event.globalPosition().toPoint().x() - self.mouse_click_position.x() * self.normal_geometry.width() // QGuiApplication.primaryScreen().geometry().width(),
                    (event.globalPosition().toPoint() - self.mouse_click_position).y())
            elif self.movemode == 4:
                self.showSizeNormal()
                self.move(
                    event.globalPosition().toPoint().x() - self.mouse_click_position.x() * self.normal_geometry.width() // (
                            self.__screen__.width() // 2),
                    (event.globalPosition().toPoint() - self.mouse_click_position).y())
            elif self.movemode == 2:
                self.showSizeNormal()
                self.move(event.globalPosition().toPoint() - self.mouse_click_position)

        event.accept()

    def __moveReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.is_mouse_pressed = False
            if QCursor.pos().y() <= 0 and self.__screen__.width() - 5 > QCursor.pos().x() > 5:
                self.showMaximized()
            elif QCursor.pos().x() <= 5 and QCursor.pos().y() <= 5:
                self.showUpLeft()
            elif QCursor.pos().x() >= self.__screen__.width() - 5 and QCursor.pos().y() <= 5:
                self.showUpRight()
            elif QCursor.pos().x() <= 5 and QCursor.pos().y() >= self.__screen__.height() - self.taskbar_height:
                self.showDownLeft()
            elif QCursor.pos().y() >= self.__screen__.height() - self.taskbar_height and \
                    QCursor.pos().x() >= self.__screen__.width() - 5:
                self.showDownRight()
            elif QCursor.pos().x() <= 5 <= QCursor.pos().y() <= self.__screen__.height() - 5:
                self.showFullLeft()
            elif QCursor.pos().x() >= self.__screen__.width() - 5 and \
                    self.__screen__.height() - 5 >= QCursor.pos().y() >= 5:
                self.showFullRight()
            elif QCursor.pos().y() >= self.__screen__.height() - self.taskbar_height and 5 <= QCursor.pos().x() <= self.__screen__.width() - 5:
                self.setGeometry(self.normal_geometry.x(), self.normal_geometry.y(), self.normal_geometry.width(),
                                 self.normal_geometry.height())
            elif not (self.isMaximized() or self.__isLined() or self.__isFullSide() or self.__isFullCorner()):
                self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __toUpPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton and \
                event.position().y() <= self.edge:
            self.up_resized = True
            self.up_click_position = event.globalPosition().toPoint() - self.pos()
            self._x_ = self.pos().x()
            self._y_ = self.pos().y()
            self._width_ = self.size().width()
            self._height_ = self.size().height()
            self.beginning_pos_y = QCursor().pos().y()
            self.justnow_size_list = []
        event.accept()

    def __toUpMoveEvent(self, event: QMouseEvent):
        if self.up_resized and self.size().height() + self.pos().y() - QCursor.pos().y() >= self.minimumHeight():
            self.resize(self._width_, self._height_ - QCursor.pos().y() + self.beginning_pos_y)
            self.move(self._x_, (event.globalPosition().toPoint() - self.up_click_position).y())
        event.accept()

    def __toUpReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.up_resized = False
            if QCursor.pos().y() <= 0 and QGuiApplication.primaryScreen().geometry().width() - 5 > QCursor.pos().x() > 5:
                self.showLined()
            else:
                self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __toDownPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.down_click_position = event.globalPosition().toPoint() - self.pos()
            self.beginning_pos_y = QCursor.pos().y()
            self._height_ = self.size().height()
            self.toDownPress = True

    def __toDownMoveEvent(self, event: QMouseEvent):
        if self.toDownPress and QCursor.pos().y() >= self.minimumHeight() + self.pos().y():
            self.resize(self.size().width(), self._height_ + (QCursor.pos().y() - self.beginning_pos_y))
        event.accept()

    def __toDownReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.toDownPress = False
            if QCursor.pos().y() >= self.__screen__.height() - self.taskbar_height and \
                    5 <= QCursor.pos().x() <= self.__screen__.width() - self.edge:
                self.showLined()
            else:
                self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __toLeftPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton and \
                event.position().x() <= self.edge:
            self.left_resized = True
            self.left_click_position = event.globalPosition().toPoint() - self.pos()
            self._x_ = self.pos().x()
            self._y_ = self.pos().y()
            self._width_ = self.size().width()
            self._height_ = self.size().height()
            self.beginning_pos_x = QCursor().pos().x()
        event.accept()

    def __toLeftMoveEvent(self, event: QMouseEvent):
        if self.left_resized and self.pos().x() + self.size().width() - QCursor.pos().x() >= self.minimumWidth():
            self.resize(self._width_ - QCursor.pos().x() + self.beginning_pos_x, self.height())
            self.move((event.globalPosition().toPoint() - self.left_click_position).x(), self._y_)
        event.accept()

    def __toLeftReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.left_resized = False
            self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __setUpLeftArea(self):
        self.UpLeftArea = QPushButton(self)
        self.UpLeftArea.setStyleSheet("QPushButton {"
                                      "background-color: rgba(255,255,255,0);"
                                      "border: none;"
                                      "}")
        self.UpLeftArea.setGeometry(0, 0, self.edge, self.edge)
        self.UpLeftArea.setCursor(Qt.CursorShape.SizeFDiagCursor)
        self.UpLeftArea.mouseMoveEvent = self.__UpLeftMoveEvent
        self.UpLeftArea.mousePressEvent = self.__UpLeftPressEvent
        self.UpLeftArea.mouseReleaseEvent = self.__UpLeftReleaseEvent
        self.__setUpRightArea()

    def __UpLeftPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.upleft_resized = True
            self.upleft_click_position = event.globalPosition().toPoint() - self.pos()
            self._x_ = self.pos().x()
            self._y_ = self.pos().y()
            self._width_ = self.size().width()
            self._height_ = self.size().height()
            self.beginning_pos = QCursor().pos()
        event.accept()

    def __UpLeftMoveEvent(self, event: QMouseEvent):
        if self.upleft_resized and \
                self.pos().x() + self.size().width() - QCursor.pos().x() >= self.minimumWidth():
            self.resize(self._width_ - QCursor.pos().x() + self.beginning_pos.x(),
                        self.size().height())
            self.move((event.globalPosition().toPoint() - self.upleft_click_position).x(), self.pos().y())
        if self.upleft_resized and \
                self.pos().y() + self.size().height() - QCursor.pos().y() >= self.minimumHeight():
            self.resize(self.size().width(),
                        self._height_ - QCursor.pos().y() + self.beginning_pos.y())
            self.move(self.pos().x(), (event.globalPosition().toPoint() - self.upleft_click_position).y())
        event.accept()

    def __UpLeftReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.upleft_resized = False
            self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __setUpRightArea(self):
        self.UpRightArea = QPushButton(self)
        self.UpRightArea.setStyleSheet("QPushButton {"
                                       "background-color: rgba(255,255,255,0);"
                                       "border: none;"
                                       "}")
        self.UpRightArea.setGeometry(self.size().width() - self.edge, 0, self.edge, self.edge)
        self.UpRightArea.setCursor(Qt.CursorShape.SizeBDiagCursor)
        self.UpRightArea.mouseMoveEvent = self.__UpRightMoveEvent
        self.UpRightArea.mousePressEvent = self.__UpRightPressEvent
        self.UpRightArea.mouseReleaseEvent = self.__UpRightReleaseEvent
        self.__setDownRightArea()

    def __UpRightPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.upright_resized = True
            self.upleft_click_position = event.globalPosition().toPoint() - self.pos()
            self._x_ = self.pos().x()
            self._y_ = self.pos().y()
            self._width_ = self.size().width()
            self._height_ = self.size().height()
            self.beginning_pos_right = QCursor().pos()
            self.beginning_pos_up = QCursor().pos()
        event.accept()

    def __UpRightMoveEvent(self, event: QMouseEvent):
        if self.upright_resized and QCursor.pos().x() >= self.pos().x() + self.minimumWidth() - self.edge:
            self.resize(self._width_ + (QCursor.pos().x() - self.beginning_pos_right.x()), self.size().height())
        if self.upright_resized and self.pos().y() + self.size().height() - QCursor.pos().y() >= self.minimumHeight():
            self.resize(self.width(), self._height_ - QCursor.pos().y() + self.beginning_pos_up.y())
            self.move(self._x_, (event.globalPosition().toPoint() - self.upleft_click_position).y())
        event.accept()

    def __UpRightReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.upright_resized = False
            self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __setDownRightArea(self):
        self.DownRightArea = QPushButton(self)
        self.DownRightArea.setStyleSheet("QPushButton {"
                                         "background-color: rgba(255,255,255,0);"
                                         "border: none;"
                                         "}")
        self.DownRightArea.setGeometry(self.size().width() - self.edge, self.size().height() - self.edge, self.edge,
                                       self.edge)
        self.DownRightArea.setCursor(Qt.CursorShape.SizeFDiagCursor)
        self.DownRightArea.mouseMoveEvent = self.__DownRightMoveEvent
        self.DownRightArea.mousePressEvent = self.__DownRightPressEvent
        self.DownRightArea.mouseReleaseEvent = self.__DownRightReleaseEvent
        self.__setDownLeftArea()

    def __DownRightPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.downright_resized = True
            self.upleft_click_position = event.globalPosition().toPoint() - self.pos()
            self._x_ = self.pos().x()
            self._y_ = self.pos().y()
            self._width_ = self.size().width()
            self._height_ = self.size().height()
            self.beginning_pos_right = QCursor().pos()
            self.beginning_pos_down = QCursor().pos()
        event.accept()

    def __DownRightMoveEvent(self, event: QMouseEvent):
        if self.downright_resized and (
                event.globalPosition().toPoint() - self.pos()).y() >= self.minimumHeight() - self.edge:
            self.resize(self.size().width(), self._height_ + (QCursor.pos().y() - self.beginning_pos_down.y()))
        if self.downright_resized and QCursor.pos().x() >= self.pos().x() + self.minimumWidth() - self.edge:
            self.resize(self._width_ + (QCursor.pos().x() - self.beginning_pos_right.x()), self.size().height())
        event.accept()

    def __DownRightReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.downright_resized = False
            self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()

    def __setDownLeftArea(self):
        self.DownLeftArea = QPushButton(self)
        self.DownLeftArea.setStyleSheet("QPushButton {"
                                        "background-color: rgba(255,255,255,0);"
                                        "border: none;"
                                        "}")
        self.DownLeftArea.setGeometry(0, self.size().height() - self.edge, self.edge,
                                      self.edge)
        self.DownLeftArea.setCursor(Qt.CursorShape.SizeBDiagCursor)
        self.DownLeftArea.mouseMoveEvent = self.__DownLeftMoveEvent
        self.DownLeftArea.mousePressEvent = self.__DownLeftPressEvent
        self.DownLeftArea.mouseReleaseEvent = self.__DownLeftReleaseEvent

    def __DownLeftPressEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.downleft_resized = True
            self.upleft_click_position = event.globalPosition().toPoint() - self.pos()
            self._x_ = self.pos().x()
            self._y_ = self.pos().y()
            self._width_ = self.size().width()
            self._height_ = self.size().height()
            self.beginning_pos_left = QCursor().pos()
            self.beginning_pos_down = QCursor().pos()
        event.accept()

    def __DownLeftMoveEvent(self, event: QMouseEvent):
        if self.downleft_resized and (
                event.globalPosition().toPoint() - self.pos()).y() >= self.minimumHeight() - self.edge:
            self.resize(self.size().width(), self._height_ + (QCursor.pos().y() - self.beginning_pos_down.y()))
        if self.downleft_resized and self.pos().x() + self.size().width() - QCursor.pos().x() >= self.minimumWidth():
            self.resize(self._width_ - QCursor.pos().x() + self.beginning_pos_left.x(), self.size().height())
            self.move((event.globalPosition().toPoint() - self.upleft_click_position).x(), self._y_)
        event.accept()

    def __DownLeftReleaseEvent(self, event: QMouseEvent):
        if event.button() == Qt.MouseButton.LeftButton:
            self.downleft_resized = False
            self.normal_geometry = QRect(self.pos().x(), self.pos().y(), self.size().width(), self.size().height())
        event.accept()


app = QApplication(sys.argv)
window = FrameLessWindow(taskbar_height=40,
                         title_height=35,
                         title_font_size=15)
window.setWindowTitle("FramelessWindow 示例")
window.setWindowIcon(QIcon("icon.png"))  # 替换成你的图标路径
window.show()
app.exec()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值