【PyQt】实战 Super Spider 之窗口移动

:系列文章,前后关联,请结合完整代码参考本系列文章;现已开源在 GitHub PyOc

事件

  • 鼠标按下事件[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)
def mousePressEvent(self, event):
    """重写继承的鼠标按住事件"""

    self._isPressed = True								# 判断是否按下
    self._press_button = event.button()					# 按下的鼠标按键
    self._area = self._compute_area(event.pos())		# 计算鼠标所在区域
    self._move_count = 0								# 鼠标移动计数,用于降低灵敏度
    self._posLast = event.globalPos()					# 当前坐标

    return QMainWindow.mousePressEvent(self, event)     # 交由原事件函数处理
  • 鼠标释放事件[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)
def mouseReleaseEvent(self, event):
    """重写继承的鼠标释放事件"""

        self._isPressed = False                             # 重置按下状态
        self._press_button = None                           # 清空按下的鼠标按键
        self._area = None                                   # 清空鼠标区域
        self._move_count = 0                                # 清空移动计数
        self.setCursor(Qt.ArrowCursor)                      # 还原光标图标

        return QMainWindow.mouseReleaseEvent(self, event)
  • 鼠标移动事件[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)
    def mouseMoveEvent(self, event):
        """重写继承的鼠标移动事件,实现窗口移动及拖动改变窗口大小"""

        area = self._compute_area(event.pos())              # 计算鼠标区域

        # 调整窗口大小及移动
        if self._isPressed and self._press_button == Qt.LeftButton:
            if self._area == 22:
                self._move(event)                           # 调用移动窗口的函数
            elif not self.isMaximized():
                self._resize(event)                         # 调用调整窗口大小的函数

            # 更新鼠标全局坐标
            self._posLast = event.globalPos()
            return None
        if not self._isPressed and not self.isMaximized():
            # 调整鼠标图标,按下鼠标后锁定状态
            self._change_cursor_icon(area)

        return QMainWindow.mouseMoveEvent(self, event)

计算窗口区域

  • 计算鼠标在窗口中的区域
def _compute_area(self, pos):
    """计算鼠标在窗口中的区域

    Args:
        pos: 鼠标相对于窗口的位置
    """
    margin = self.MARGIN						 # 以此值为外边框宽度,划为九宫格区域

    # 定位列坐标
    if pos.x() < margin:
        line = 1
    elif pos.x() > self.width() - margin:
        line = 3
    else:
        line = 2
    # 定位行坐标并结合列坐标
    if pos.y() < margin:
        return 10 + line
    elif pos.y() > self.height() - margin:
        return 30 + line
    else:
        return 20 + line
  • 辅助函数,返回鼠标在窗口中的纵横百分比
def _pos_percent(self, pos):
    """返回鼠标相对窗口的纵横百分比"""

    if pos.x() <= 0:
        x = 0
    else:
        x = round(pos.x() / self.width(), 3)

    if pos.y() <= 0:
        y = 0
    else:
        y = round(pos.y() / self.height(), 3)

    return x, y

移动窗口

  • 移动窗口,最大化时需还原窗口状态

def _move(self, event):
    """实现窗口移动"""

    self._move_count += 1

    # 判断移动次数,减少灵敏度
    if self._move_count < self.MOVE_SENSITIVITY:
        return None

    # 最大化时需恢复普通大小,并按相对坐标移动到鼠标位置
    # 普通状态的宽高在窗口最大化之前获取,需借助标题栏的最大化按钮槽函数
    if self.isMaximized():
        relative = self._pos_percent(event.pos())
        self.titlebar.max_button_click()
        gpos = event.globalPos()
        width = self._last_geometry.width()					# 普通大小的几何属性
        height = self._last_geometry.height()
        x = gpos.x() - round(width * relative[0])
        y = gpos.y() - round(height * relative[1])

        self.setGeometry(x, y, width, height)
    else:
        # 鼠标移动偏移量
        offsetPos = event.globalPos() - self._posLast
        # ~ print(self.pos(), '->', self.pos() + offsetPos)
        self.move(self.pos() + offsetPos)

本文为 one-ccs 原创文章,引用必须注明出处!
https://blog.csdn.net/qq_43155814/article/details/104676865

上一篇:【PyQt】实战 Super Spider 之自定以标题栏

下一篇:【PyQt】实战 Super Spider 之拖动改变窗口大小

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值