Qt第二十七章:QWidget、QMainWindow自定义标题栏并自由移动缩放

news2024/12/26 12:02:05

前提:UI必須采用自适应布局。 

  1. 自定义组件【直接CV】custom_components.py
    from PySide6 import QtGui, QtWidgets, QtCore
    from PySide6.QtCore import Qt, QSize, QRect
    from PySide6.QtWidgets import QPushButton, QLabel, QWidget
    
    
    class QCustomTitleBar:
        def __init__(self, window: QtWidgets):
            self.window = window
            # 默认标题栏高度 必须设
            self.DEFAULT_TITILE_BAR_HEIGHT = 40
            # 存储父类的双击事件
            self.mouseDoubleClickEvent_parent = self.window.mouseDoubleClickEvent
            # 将本类的双击事件赋值给将父类的双击事件
            self.window.mouseDoubleClickEvent = self.mouseDoubleClickEvent
    
            # 存储父类的窗口大小改变事件
            self.resizeEvent_parent = self.window.resizeEvent
            # 将本类的窗口大小改变事件赋值给将父类的窗口大小改变事件
            self.window.resizeEvent = self.resizeEvent
    
            # 设置ui文件里main_layout上边距,以免遮挡标题栏
            self.window.setContentsMargins(0, self.DEFAULT_TITILE_BAR_HEIGHT, 0, 0)
    
            # 1.设置无边框 和 透明背景 无边框必须设置全,不然会导致点击任务栏不能最小化窗口
            self.window.setWindowFlags(
                Qt.Window
                | Qt.FramelessWindowHint
                | Qt.WindowSystemMenuHint
                | Qt.WindowMinimizeButtonHint
                | Qt.WindowMaximizeButtonHint
            )
            # self.window.setAttribute(Qt.WA_TranslucentBackground)
            # 2.添加自定义的标题栏到最顶部
            self.title = QLabel("标题文字", self.window)
            # 3.设置标题栏样式
            self.setStyle()
            # 4.添加按钮
            # 添加关闭按钮
            self.close_btn = QPushButton("", self.window)
            self.close_btn.setGeometry(self.window.width() - 33, 10, 20, 20)
            # 添加最大化按钮
            self.max_btn = QPushButton("", self.window)
            self.max_btn.setGeometry(self.window.width() - 66, 10, 20, 20)
            # 添加最小化按钮
            self.min_btn = QPushButton("", self.window)
            self.min_btn.setGeometry(self.window.width() - 99, 10, 20, 20)
            # 设置三个按钮的鼠标样式
            self.close_btn.setCursor(Qt.PointingHandCursor)
            self.max_btn.setCursor(Qt.PointingHandCursor)
            self.min_btn.setCursor(Qt.PointingHandCursor)
            # 设置三个按钮的样式
            self.close_btn.setStyleSheet(
                "QPushButton{border-image:url('./images/close.png');background:#ff625f;border-radius:10px;}"
                "QPushButton:hover{background:#eb4845;}"
            )
            self.max_btn.setStyleSheet(
                "QPushButton{border-image:url('./images/max.png');background:#ffbe2f;border-radius:10px;}"
                "QPushButton:hover{background:#ecae27;}"
            )
            self.min_btn.setStyleSheet(
                "QPushButton{border-image:url('./images/min.png');background:#29c941;border-radius:10px;}"
                "QPushButton:hover{background:#1ac033;}"
            )
    
            # 5.添加工具栏按钮事件
            # 关闭按钮点击绑定窗口关闭事件
            self.close_btn.pressed.connect(self.window.close)
            # 最大化按钮绑定窗口最大化事件
            self.max_btn.pressed.connect(self.setMaxEvent)
            # 最小化按钮绑定窗口最小化事件
            self.min_btn.pressed.connect(self.window.showMinimized)
            # 6.记录全屏窗口的大小-ps非常有用
            self.window_max_size = None
            # 7.设置标题栏鼠标跟踪 鼠标移入触发,不设置,移入标题栏不触发
            self.title.setMouseTracking(True)
    
        def setMaxEvent(self, flag=False):
            """
            @description  最大化按钮绑定窗口最大化事件和事件 拿出来是因为拖动标题栏时需要恢复界面大小
            @param flag 是否是拖动标题栏 bool
            @return
            """
            if flag:
                if self.window.isMaximized():
                    self.window.showNormal()
                    self.max_btn.setStyleSheet(
                        "QPushButton{border-image:url('./images/max.png');background:#ffbe2f;border-radius:10px;}"
                        "QPushButton:hover{background:#ecae27;}"
                    )
                    return self.window_max_size
                return None
            else:
                if self.window.isMaximized():
                    self.window.showNormal()
                    self.max_btn.setStyleSheet(
                        "QPushButton{border-image:url('./images/max.png');background:#ffbe2f;border-radius:10px;}"
                        "QPushButton:hover{background:#ecae27;}"
                    )
                else:
                    self.window.showMaximized()
                    self.max_btn.setStyleSheet(
                        "QPushButton{border-image:url('./images/restore.png');background:#ffbe2f;border-radius:10px;}"
                        "QPushButton:hover{background:#ecae27;}"
                    )
                    # 记录最大化窗口的大小  用于返回最大化时拖动窗口恢复前的大小 这个程序循环帧会取不到恢复前的宽度
                    self.window_max_size = QSize(self.window.width(), self.window.height())
    
        def setStyle(self, style: str = ""):
            """
            @description 设置自定义标题栏样式
            @param
            @return
            """
            # 想要边框 加上border:1px solid #cccccc;
            DEFAULT_STYLE = """
                                background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #fafafa,stop:1 #d1d1d1);
                                color:#333333;padding:10px;border:1px solid #c6c6c6;
                                border-top-left-radius:4px;
                                border-top-right-radius:4px;
                            """
            self.title.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
            # 设置样式
            self.title.setStyleSheet(DEFAULT_STYLE if not style else DEFAULT_STYLE + style)
            # 设置大小
            self.title.setGeometry(0, 0, self.window.width(), self.DEFAULT_TITILE_BAR_HEIGHT)
    
        def mouseDoubleClickEvent(self, a0: QtGui.QMouseEvent) -> None:
            """
            @description 鼠标双击事件
            @param
            @return
            """
            # 如果双击的是鼠标左键 且在标题栏范围内 则放大缩小窗口
            if a0.button() == Qt.MouseButton.LeftButton and a0.position().y() < self.title.height():
                self.setMaxEvent()
            return self.mouseDoubleClickEvent_parent(a0)
    
        def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
            """
            @description  窗口缩放事件
            @param
            @return
            """
            # 最大化最小化的时候,需要去改变按钮组位置
            self.close_btn.move(self.window.width() - 33, 10)
            self.max_btn.move(self.window.width() - 66, 10)
            self.min_btn.move(self.window.width() - 99, 10)
            self.title.resize(self.window.width(), self.DEFAULT_TITILE_BAR_HEIGHT)
            return self.resizeEvent_parent(a0)
    
    
    class QWindowMoveResize(QWidget):
    
        def __init__(self, parent=None):
            super(QWindowMoveResize, self).__init__(parent)
            # 1.设置无边框 和 透明背景 无边框必须设置全,不然会导致点击任务栏不能最小化窗口
            self.setWindowFlags(
                Qt.Window
                | Qt.FramelessWindowHint
                | Qt.WindowSystemMenuHint
                | Qt.WindowMinimizeButtonHint
                | Qt.WindowMaximizeButtonHint
            )
            # self.window.setAttribute(Qt.WA_TranslucentBackground)
            # 默认标题栏高度 必须设
            self.DEFAULT_TITILE_BAR_HEIGHT = 40
            # 鼠标缩放窗口最小宽度,必须设
            self.MIN_WINDOW_WIDTH = 10
            self.MIN_WINDOW_HEIGHT = 10
            # 鼠标拖动窗口的标识
            self.m_flag = False
            # 初始化鼠标拖动标题栏标志
            self.drag_flag = False
            # 记录按下时窗口坐标, 这个用于窗口移动
            self.win_x = 0
            self.win_y = 0
            # 记录按下时鼠标坐标,这个用于计算鼠标移动的距离
            self.mouse_x = 0
            self.mouse_y = 0
            # 记录鼠标移入的拖动区域,共8种区域 左上 左 左下 上 下 右上 右 右下
            self.left_up = None
            self.left = None
            self.left_down = None
            self.up = None
            self.down = None
            self.right_up = None
            self.right = None
            self.right_down = None
            # 设置为True则mouseMoveEvent事件不需要按下也能触发,不然要按着鼠标左键或右键才能触发
            self.setMouseTracking(True)
            # 设置子类的mousetrack
            # self.centralwidget.setMouseTracking(True)
            # 记录按下时窗口的大小,用于计算鼠标相对于窗口移动的距离,用于缩放
            self.win_w = 0
            self.win_h = 0
            # 初始化鼠标缩放标志
            self.move_left_up_flag = False
            self.move_left_flag = False
            self.move_left_down_flag = False
            self.move_up_flag = False
            self.move_down_flag = False
            self.move_right_up_flag = False
            self.move_right_flag = False
            self.move_right_down_flag = False
    
        def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
            """
            @description  窗口缩放事件
            @param
            @return
            """
            # 最大化最小化的时候,需要去改变按钮组位置
            # self.titleBar.close_btn.move(self.width() - 33, 10)
            # self.titleBar.max_btn.move(self.width() - 66, 10)
            # self.titleBar.min_btn.move(self.width() - 99, 10)
            # self.titleBar.title.resize(self.width(), DEFAULT_TITILE_BAR_HEIGHT)
    
            # 记录鼠标移入的拖动区域,共8种区域
            self.left_up = QRect(0, 0, 10, 10)
            self.left = QRect(0, 10, 10, self.height() - 20)
            self.left_down = QRect(0, self.height() - 10, 10, 10)
            self.up = QRect(10, 0, self.width() - 20, 10)
            self.down = QRect(10, self.height() - 10, self.width() - 20, 10)
            self.right_up = QRect(self.width() - 10, 0, 10, 10)
            self.right = QRect(self.width() - 10, 10, 10, self.height() - 20)
            self.right_down = QRect(self.width() - 10, self.height() - 10, 10, 10)
    
            return super().resizeEvent(a0)
    
        def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:
            """
            拖动窗口
            """
            if a0.button() == QtCore.Qt.LeftButton and self.isMaximized() == False and self.cursor().shape() == QtGui.QCursor(
                    QtCore.Qt.ArrowCursor).shape():
                self.m_flag = True
                self.m_Position = a0.globalPosition().toPoint() - self.pos()  # 获取鼠标相对窗口的位置
                a0.accept()
                self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))  # 更改鼠标图标
            else:
                """
                @description 鼠标按下事件
                @param
                @return
                """
                # 记录按下时窗口坐标, 这个用于窗口移动
                self.win_x = self.x()
                self.win_y = self.y()
                # 记录按下时鼠标坐标,这个用于计算鼠标移动的距离
                self.mouse_x = a0.globalPosition().x()
                self.mouse_y = a0.globalPosition().y()
                # 记录按下时窗口的大小,用于计算鼠标相对于窗口移动的距离,用于缩放
                self.win_w = self.width()
                self.win_h = self.height()
    
                if not self.isMaximized():
                    # 如果按下的是鼠标左键
                    if a0.button() == Qt.MouseButton.LeftButton and self.left_up.contains(a0.position().x(),
                                                                                          a0.position().y()):
                        self.move_left_up_flag = True
                    if a0.button() == Qt.MouseButton.LeftButton and self.left.contains(a0.position().x(),
                                                                                       a0.position().y()):
                        self.move_left_flag = True
                    if a0.button() == Qt.MouseButton.LeftButton and self.left_down.contains(
                            a0.position().x(), a0.position().y()
                    ):
                        self.move_left_down_flag = True
                    if a0.button() == Qt.MouseButton.LeftButton and self.up.contains(a0.position().x(), a0.position().y()):
                        self.move_up_flag = True
                    if a0.button() == Qt.MouseButton.LeftButton and self.down.contains(a0.position().x(),
                                                                                       a0.position().y()):
                        self.move_down_flag = True
                    if a0.button() == Qt.MouseButton.LeftButton and self.right_up.contains(
                            a0.position().x(), a0.position().y()
                    ):
                        self.move_right_up_flag = True
                    if a0.button() == Qt.MouseButton.LeftButton and self.right.contains(a0.position().x(),
                                                                                        a0.position().y()):
                        self.move_right_flag = True
                    if a0.button() == Qt.MouseButton.LeftButton and self.right_down.contains(
                            a0.position().x(), a0.position().y()
                    ):
                        self.move_right_down_flag = True
                return super().mousePressEvent(a0)
    
        def mouseMoveEvent(self, a0: QtGui.QMouseEvent) -> None:
            """
            拖动窗口
            """
            if QtCore.Qt.LeftButton and self.m_flag and self.cursor().shape() == QtGui.QCursor(
                    QtCore.Qt.OpenHandCursor).shape():
                self.move(a0.globalPosition().toPoint() - self.m_Position)  # 更改窗口位置
                a0.accept()
            else:
                """
                @description 鼠标按下移动事件
                @param
                @return
                """
                # 获取移动后鼠标的位置
                mouse_move_x = a0.globalPosition().x()
                mouse_move_y = a0.globalPosition().y()
                # 计算移动的距离
                offset_x = mouse_move_x - self.mouse_x
                offset_y = mouse_move_y - self.mouse_y
                # 移动鼠标时设置鼠标样式
                if not self.isMaximized():
                    # 不是拖动的时才可能是缩放状态
                    if not self.drag_flag:
                        # 左上
                        if self.left_up.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeFDiagCursor)
                        # 左
                        elif self.left.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeHorCursor)
                        # 左下
                        elif self.left_down.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeBDiagCursor)
                        # 上
                        elif self.up.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeVerCursor)
                        # 下
                        elif self.down.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeVerCursor)
                        # 右上
                        elif self.right_up.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeBDiagCursor)
                        # 右
                        elif self.right.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeHorCursor)
                        # 右下
                        elif self.right_down.contains(a0.position().x(), a0.position().y()):
                            self.setCursor(Qt.SizeFDiagCursor)
                        else:
                            self.setCursor(Qt.ArrowCursor)
                    else:
                        self.setCursor(Qt.ArrowCursor)
                else:
                    self.setCursor(Qt.ArrowCursor)
                # 如果按下且在左上角范围内则缩放(其他代码参考左上)
                if self.move_left_up_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeFDiagCursor)
                    resize_w = self.win_w - offset_x
                    resize_h = self.win_h - offset_y
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_w = self.MIN_WINDOW_WIDTH if resize_w < self.MIN_WINDOW_WIDTH else resize_w
                    resize_h = self.MIN_WINDOW_HEIGHT if resize_h < self.MIN_WINDOW_HEIGHT else resize_h
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                    # 设置窗口移动,需要鼠标跟随
                    # x y 都要鼠标跟随
                    if resize_w != self.MIN_WINDOW_WIDTH and resize_h != self.MIN_WINDOW_HEIGHT:
                        self.move(self.win_x + offset_x, self.win_y + offset_y)
                    # 缩放宽度等于最小宽度,高度鼠标跟随
                    if resize_w == self.MIN_WINDOW_WIDTH and resize_h != self.MIN_WINDOW_HEIGHT:
                        self.move(self.x(), self.win_y + offset_y)
                    # 缩放高度等于最小高度,宽度鼠标跟随
                    if resize_w != self.MIN_WINDOW_WIDTH and resize_h == self.MIN_WINDOW_HEIGHT:
                        self.move(self.win_x + offset_x, self.y())
                # 如果按下且在左边范围内则缩放
                elif self.move_left_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeHorCursor)
                    resize_w = self.win_w - offset_x
                    resize_h = self.win_h
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_w = self.MIN_WINDOW_WIDTH if resize_w < self.MIN_WINDOW_WIDTH else resize_w
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                    # 设置窗口移动,需要鼠标跟随
                    # 只要宽度鼠标跟随
                    if resize_w != self.MIN_WINDOW_WIDTH:
                        self.move(self.win_x + offset_x, self.win_y)
                # 如果按下且在左下角范围内则缩放
                elif self.move_left_down_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeBDiagCursor)
                    resize_w = self.win_w - offset_x
                    resize_h = self.win_h + offset_y
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_w = self.MIN_WINDOW_WIDTH if resize_w < self.MIN_WINDOW_WIDTH else resize_w
                    resize_h = self.MIN_WINDOW_HEIGHT if resize_h < self.MIN_WINDOW_HEIGHT else resize_h
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                    # 设置窗口移动,需要鼠标跟随
                    # x y 都要鼠标跟随
                    if resize_w != self.MIN_WINDOW_WIDTH and resize_h != self.MIN_WINDOW_HEIGHT:
                        self.move(self.win_x + offset_x, self.y())
                    # 缩放高度等于最小高度,宽度鼠标跟随
                    if resize_w != self.MIN_WINDOW_WIDTH and resize_h == self.MIN_WINDOW_HEIGHT:
                        self.move(self.win_x + offset_x, self.y())
                # 如果按下且在上边范围内则缩放
                elif self.move_up_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeVerCursor)
                    resize_w = self.win_w
                    resize_h = self.win_h - offset_y
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_h = self.MIN_WINDOW_HEIGHT if resize_h < self.MIN_WINDOW_HEIGHT else resize_h
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                    # 设置窗口移动,需要鼠标跟随
                    # 只要高度鼠标跟随
                    if resize_h != self.MIN_WINDOW_HEIGHT:
                        self.move(self.win_x, self.win_y + offset_y)
                # 如果按下且在下边范围内则缩放
                elif self.move_down_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeVerCursor)
                    resize_w = self.win_w
                    resize_h = self.win_h + offset_y
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_h = self.MIN_WINDOW_HEIGHT if resize_h < self.MIN_WINDOW_HEIGHT else resize_h
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                # 如果按下且在右上角范围内则缩放
                elif self.move_right_up_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeBDiagCursor)
                    resize_w = self.win_w + offset_x
                    resize_h = self.win_h - offset_y
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_w = self.MIN_WINDOW_WIDTH if resize_w < self.MIN_WINDOW_WIDTH else resize_w
                    resize_h = self.MIN_WINDOW_HEIGHT if resize_h < self.MIN_WINDOW_HEIGHT else resize_h
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                    # 设置窗口移动,需要鼠标跟随
                    # x y 都要鼠标跟随
                    if resize_w != self.MIN_WINDOW_WIDTH and resize_h != self.MIN_WINDOW_HEIGHT:
                        self.move(self.win_x, self.win_y + offset_y)
                    # 缩放宽度等于最小宽度,高度鼠标跟随
                    if resize_w == self.MIN_WINDOW_WIDTH and resize_h != self.MIN_WINDOW_HEIGHT:
                        self.move(self.x(), self.win_y + offset_y)
                # 如果按下且在右边范围内则缩放
                elif self.move_right_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeHorCursor)
                    resize_w = self.win_w + offset_x
                    resize_h = self.win_h
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_w = self.MIN_WINDOW_WIDTH if resize_w < self.MIN_WINDOW_WIDTH else resize_w
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                # 如果按下且在右下角范围内则缩放
                elif self.move_right_down_flag:
                    # 拖动的时候也要设置一下形状
                    self.setCursor(Qt.SizeFDiagCursor)
                    resize_w = self.win_w + offset_x
                    resize_h = self.win_h + offset_y
                    # 如果缩放后的尺寸小于最小尺寸则窗口不能缩放了
                    resize_w = self.MIN_WINDOW_WIDTH if resize_w < self.MIN_WINDOW_WIDTH else resize_w
                    resize_h = self.MIN_WINDOW_HEIGHT if resize_h < self.MIN_WINDOW_HEIGHT else resize_h
                    # 设置窗口缩放尺寸
                    self.resize(resize_w, resize_h)
                # 如果按下才能移动
                elif self.drag_flag:
                    # 设置窗口移动的距离
                    self.move(self.win_x + offset_x, self.win_y + offset_y)
                return super().mouseMoveEvent(a0)
    
        def mouseReleaseEvent(self, a0: QtGui.QMouseEvent) -> None:
            self.m_flag = False
            self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
            """
            @description 鼠标按下松开事件
            @param
            @return
            """
            self.drag_flag = False
            self.move_left_up_flag = False
            self.move_left_flag = False
            self.move_left_down_flag = False
            self.move_up_flag = False
            self.move_down_flag = False
            self.move_right_up_flag = False
            self.move_right_flag = False
            self.move_right_down_flag = False
            return super().mouseReleaseEvent(a0)
    
  2. 使用实例
    ①QWidget使用示例
    UI文件(转成py文件)
    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Form</string>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout_2">
       <item>
        <layout class="QVBoxLayout" name="verticalLayout">
         <item>
          <layout class="QHBoxLayout" name="horizontalLayout">
           <item>
            <widget class="QLineEdit" name="lineEdit"/>
           </item>
           <item>
            <widget class="QPushButton" name="pushButton">
             <property name="text">
              <string>PushButton</string>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item>
          <widget class="QTextEdit" name="textEdit"/>
         </item>
        </layout>
       </item>
      </layout>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    from PySide6.QtWidgets import QApplication, QWidget
    
    from custom_components import QWindowMoveResize, QCustomTitleBar
    from ui_widget_test import Ui_Form
    
    
    class TestWindow(QWindowMoveResize, Ui_Form):
        def __init__(self, parent=None):
            super(TestWindow, self).__init__(parent)
            self.setupUi(self)
            # 自定义标题栏
            QCustomTitleBar(self)
    
    
    if __name__ == "__main__":
        app = QApplication([])
        window = TestWindow()
        window.show()
        app.exec()

     ②QMainWindow使用示例
    UI文件(转成py文件)

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>641</width>
        <height>444</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QHBoxLayout" name="horizontalLayout_2">
        <item>
         <layout class="QVBoxLayout" name="verticalLayout">
          <item>
           <layout class="QHBoxLayout" name="horizontalLayout">
            <item>
             <widget class="QLineEdit" name="lineEdit"/>
            </item>
            <item>
             <widget class="QPushButton" name="pushButton">
              <property name="text">
               <string>PushButton</string>
              </property>
             </widget>
            </item>
           </layout>
          </item>
          <item>
           <widget class="QTextEdit" name="textEdit"/>
          </item>
         </layout>
        </item>
       </layout>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>641</width>
         <height>23</height>
        </rect>
       </property>
       <widget class="QMenu" name="menu">
        <property name="title">
         <string>菜单</string>
        </property>
       </widget>
       <addaction name="menu"/>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    from PySide6 import QtCore, QtGui
    from PySide6.QtWidgets import QApplication, QMainWindow
    
    from custom_components import QCustomTitleBar
    from ui_main_window_test import Ui_MainWindow
    
    
    class TestWindow(QMainWindow, Ui_MainWindow):
        def __init__(self, parent=None):
            super(TestWindow, self).__init__(parent)
            self.setupUi(self)
            # 自定义标题栏
            QCustomTitleBar(self)
    
        def mousePressEvent(self, event):
            if event.button() == QtCore.Qt.LeftButton and self.isMaximized() == False:
                self.m_flag = True
                self.m_Position = event.globalPosition().toPoint() - self.pos()  # 获取鼠标相对窗口的位置
                event.accept()
                self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))  # 更改鼠标图标
    
        def mouseMoveEvent(self, mouse_event):
            if QtCore.Qt.LeftButton and self.m_flag:
                self.move(mouse_event.globalPosition().toPoint() - self.m_Position)  # 更改窗口位置
                mouse_event.accept()
    
        def mouseReleaseEvent(self, mouse_event):
            self.m_flag = False
            self.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
    
    
    if __name__ == "__main__":
        app = QApplication([])
        window = TestWindow()
        window.show()
        app.exec()
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/55817.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SpringBoot vue的茶叶商城平台源码和论文含支付宝沙箱支付

此项目是前后端分离的 后台项目:shop 前端项目:Vue-shop 后端项目启动步骤: 1.先把sql导入数据库 2.把后台项目导入编辑器 3.修改数据库配置 4.启动项目 前端项目启动步骤: 1.打开Vue-shop目录,在这个文件夹里面加入cmd目录窗口 2.运行启动vue项目目录(需先安装nodejs软件)…

四、伊森商城 前端基础-Vue 双向绑定事件处理安装插件 p22

1、双向绑定 双向绑定&#xff1a; 效果&#xff1a;我们修改表单项&#xff0c;num 会发生变化。我们修改 num&#xff0c;表单项也会发生变化。为了实 时观察到这个变化&#xff0c;我们将 num 输出到页面。 我们不需要关注他们为什么会建立起来关联&#xff0c;以及页面如何…

Java面向对象三大特性:继承、封装、多态

java封装、继承、多态笔记 1.包 1.包的命名规则 &#xff08;1&#xff09;只能包含数字、字母、下划线、小圆点. &#xff08;2&#xff09;不能用数字开头&#xff0c; &#xff08;3&#xff09;不能是关键字或保留字 例如&#xff1a; demo.class.exec1 //错误class…

Redis学习笔记(三)

Jedis java语言连接redis工具准备工作 下载地址&#xff1a;https://mvnrepository.com/artifact/redis.clients/jedis基于maven <dependency> <groupId> redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</versi…

【面试题】面试官:你能自己实现一个async await吗?

开启掘金成长之旅&#xff01;这是我参与「掘金日新计划 12 月更文挑战」的第3天(点击查看活动详情) 相信大家对于Promise都不再陌生了&#xff0c;简易版的Promise对象源码我们也手撕过一次了&#xff0c;那接下来我们聊聊Promise的语法糖async-await&#xff0c;那让我们从…

【JavaWeb】第六章 xml

文章目录1、XML简介2、xml语法3、xml解析4、Dom4j类库的使用5、dom4j解析xml1、XML简介 xml是可扩展的标记性语言&#xff0c;xml的主要作用有&#xff1a; 用来保存数据&#xff0c;而且这些数据具有自我描述性 做为项目或者模块的配置文件做为网络传输数据的格式&#xff0…

QML 如何显示文本?Text可以有多少功能?

目录1.如何显示文本&#xff1f;2. Text有哪些主要功能&#xff1f;2.1 基本属性示例2.2 字重属性2.3 字体样式2.4 字体上标下标支持2.5 富文本2.6 文字换行 缩略1.如何显示文本&#xff1f; Text {font.pixelSize: 20; text: "这是20普通文字"} //一行即可以上代码…

12.2排序

目录 0.做题的失误 1.引用传值和传址 1.斐波那契数列 一.快速排序 1.挖坑法 2.优化 2.1 随机取数法 2.2 三数取中法 2.3把基准值相同的值移到基准旁边 2.4引用直接插入排序 3.Hoare 法: 4.非递归法 5.总结 二,归并排序 1.原理 2.代码实现 3.分析 4.非递归 5…

Git(第一篇)——Git的下载与安装(史上最全最详细)

Git&#xff08;第一篇&#xff09;——Git的下载与安装&#xff08;史上最全最详细&#xff09; 目录Git&#xff08;第一篇&#xff09;——Git的下载与安装&#xff08;史上最全最详细&#xff09;git的下载git的安装git的下载 如果你还没有下载Git&#xff0c;可直接到git…

什么是数据管理能力成熟度评估(DCMM)

GB/T 36073-2018 《数据管理能力成熟度评估模型》&#xff08;Data Management Capability Maturity Assessment Model&#xff0c;简称&#xff1a;DCMM&#xff09;是我国数据管理领域首个国家标准。该标准将组织对象的数据管理划分为八大能力域&#xff08;数据战略、数据治…

【Hbase】第一章——从原理剖析

文章目录1. HBase的实现原理1.1 HBase功能组件1.2 表和Region1.3 Region的定位2. HBase运行机制2.1 HBase系统架构2.2 Region服务器工作原理2.3 Store工作原理2.4 HLog工作原理3. HBase应用方案3.1 HBase实际应用中的性能优化方法3.2 HBase性能监视3.3 在HBase之上构建SQL引擎3…

【图像压缩】DCT图像无损压缩【含GUI Matlab源码 726期】

⛄一、DCT图像无损压缩简介 1 图像压缩 图像压缩按照压缩过程中是否有信息的损失以及解压后与原始图像是否有误差可以分为无损压缩和有损压缩两大类。无损压缩是指不损失图像质量的压缩&#xff0c;它是对文件的存储方式进行优化&#xff0c;采用某种算法表示重复的数据信息&a…

关于Jetpack Compose的初步使用、学习和总结

初步使用和学习ComposeJetpack Compose简要介绍创建一个Jetpack Compose项目自定义组合函数MessageCard通过修饰符&#xff0c;进一步改善布局为什么使用ComposeCompose 与 XML总结与期望Jetpack Compose 简要介绍 根据developers上的介绍&#xff0c;Jetpack Compose 是推荐…

【3D目标检测】Rethinking Pseudo-LiDAR Representation

目录概述细节证明基于伪点云的3D目标检测算法效果好的原因并不是伪点云这种数据表示基于深度图的图像表示的算法PatchNet证明基于伪点云的3D目标检测算法效果好的原因是从图像到点云坐标系转换的过程概述 本文是基于图像的3D目标检测算法。 贡献&#xff1a; 作者认为基于伪点…

开放式运动耳机排行榜,排行靠前的五款高性能耳机分享

智能产品的发展迅猛&#xff0c;作为生活必需品的耳机&#xff0c;更是在不断的更新&#xff0c;尤其是对于运动爱好者而言&#xff0c;以往的入耳式蓝牙耳机存在汗渍入耳等问题。而为了有效解决这一些列问题&#xff0c;新型的骨传导耳机随之诞生了&#xff0c;相比入耳式的蓝…

一定要用Photoshop?no!动手用Python做一个颜色提取器! ⛵

&#x1f4a1; 作者&#xff1a;韩信子ShowMeAI &#x1f4d8; Python3◉技能提升系列&#xff1a;https://www.showmeai.tech/tutorials/56 &#x1f4d8; 计算机视觉实战系列&#xff1a;https://www.showmeai.tech/tutorials/46 &#x1f4d8; 本文地址&#xff1a;https://…

直播 | 数据仓库?数据湖?停止纠结,流批融合的极速 Lakehouse来了!

万物皆数据的时代&#xff0c;各行各业对数据分析架构的要求日益拔高&#xff0c;打破传统的数据湖应需而生。企业得以用更低廉的成本、更完善的 ACID 支持、更实时的方式&#xff0c;导入并存储所有结构化、半结构化和非结构化数据。得益于数据湖良好的伸缩性和灵活性&#xf…

jQuery 安装

网页中添加 jQuery 可以通过多种方法在网页中添加 jQuery。 您可以使用以下方法&#xff1a; 从 jquery.com 下载 jQuery 库从 CDN 中载入 jQuery, 如从 Google 中加载 jQuery下载 jQuery 有两个版本的 jQuery 可供下载&#xff1a; Production version - 用于实际的网站中…

渲染时间过长?这些参数设置学起来

渲染时间 为了契合创作者的需求&#xff0c;V-Ray渲染器近年来迭代迅速&#xff0c;新版本的上线&#xff0c;便利了更多用户。但也有小伙伴在使用后反馈&#xff1a; 我的渲染器明明已经升级到最高版本了&#xff0c;为什么渲染时间还这么慢&#xff1f; 实际上&#xff0c;出…

如何通过一个项目征服Java

Java早已经不是高大山的稀世珍品了&#xff0c;程序员也不再是高科技工作者&#xff0c;而被称为码农 &#xff0c;为什么呢&#xff1f;因为Java后台的很多基础技术都已经固定了&#xff0c;也就是说主要你从头到尾学一遍就能会 &#xff0c;淘宝双十一搞不定&#xff0c;但是…