Python PyQt拖动控件对齐到网格的方法步骤

 更新时间:2022年12月30日 11:39:21   作者:@苏丶  
pyqt是一个用于创建GUI应用程序的跨平台工具包,它将python与qt库融为一体,下面这篇文章主要给大家介绍了关于Python PyQt拖动控件对齐到网格的方法步骤,需要的朋友可以参考下

实现如下需求:

在PyQt界面上有一个控件,实现其可任意拖动,且鼠标释放时自动对齐到网格。

1.控件任意拖动并对齐到网格

如下按钮(尺寸100×100),可任意拖动,释放时对齐到网格(网格尺寸100×100)

首先给出代码

from PyQt5.QtWidgets import QPushButton, QMainWindow, QApplication


class Button(QPushButton):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(100, 100)

        self.pos1 = 0  # 用于拖动时的鼠标位置初始值

    def mousePressEvent(self, QMouseEvent):
        self.pos1 = QMouseEvent.screenPos()

    def mouseReleaseEvent(self, QMouseEvent) -> None:
        fx, fy = self.frameGeometry().x(), self.frameGeometry().y()  # 相对父控件坐标
        tx_index, ty_index = fx // 100 if fx > 99 else 0, fy // 100 if fy > 99 else 0
        # 移动到网格上
        self.mymove(tx_index, ty_index)

    def mouseMoveEvent(self, QMouseEvent):
        pos2 = QMouseEvent.screenPos()
        tx = int(self.frameGeometry().x() + pos2.x() - self.pos1.x())
        ty = int(self.frameGeometry().y() + pos2.y() - self.pos1.y())
        self.move(tx, ty)
        self.pos1 = pos2

    def mymove(self, tx_index, ty_index):
        self.move(tx_index * 100, ty_index * 100)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('按钮测试')
        self.resize(500, 500)

        self.btn = Button(self)
        self.btn.setText('ABCD')

if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

这里自定义Button类继承QPushButton类,因为我们需要重写鼠标移动的方法来实现所需功能。

要实现任意拖动,按钮必须跟随鼠标,于是我们重写mousePressEvent方法和mouseMoveEvent方法。

  1. 当我们按下鼠标时,触发mousePress事件,记录此刻光标位置;
  2. 当光标拖动时触发mouseMove事件,获取当前光标位置,计算与之前位置的x和y的差值,然后加到按钮的相对坐标上,获得按钮需要移动到的位置坐标;
  3. 调用move方法移动按钮;
  4. 更新pos1即按钮位置;
  5. 只要光标移动,就会触发mouseMove事件,就会不断移动按钮与更新按钮位置,在视觉上按钮就是在跟着光标任意拖动。

要实现鼠标释放时对齐到网格,需要重写mouseReleaseEvent方法,用来响应鼠标释放动作。

  1. 当鼠标释放时,立即读取按钮的当前相对坐标;
  2. 将按钮的坐标除以100用来获取其在网格上的位置,如果坐标小于0应令其等于0,同时0-99的坐标除以100也等于0,于是只要小于99就等于0;
  3. 然后调用自定义的mymove方法,在这个方法中,将网格位置换算到相对坐标,再调用move方法使其移动到网格。

2.进阶:双击控件使其移动到其他网格

移动并对齐到网格的功能已经在上一部分实现了,这里需要实现鼠标双击动作,首先给出代码

from PyQt5.QtWidgets import QPushButton, QMainWindow, QApplication
from PyQt5.QtCore import Qt


class Button(QPushButton):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(100, 100)

        self.pos1 = 0  # 用于拖动时的鼠标位置初始值
        self.x_index, self.y_index = 0, 0  # 记录按钮在网格上的位置

    def mousePressEvent(self, QMouseEvent):
        if QMouseEvent.buttons() == Qt.LeftButton:
            print('左键按下')
            self.pos1 = QMouseEvent.screenPos()
        elif QMouseEvent.buttons() == Qt.RightButton:
            print('右键按下')
            self.pos1 = QMouseEvent.screenPos()

    def mouseReleaseEvent(self, QMouseEvent) -> None:
        print('鼠标释放')
        fx, fy = self.frameGeometry().x(), self.frameGeometry().y()  # 相对父控件坐标
        tx_index, ty_index = fx // 100 if fx > 99 else 0, fy // 100 if fy > 99 else 0
        # 移动到网格上
        self.x_index, self.y_index = tx_index, ty_index
        self.mymove(tx_index, ty_index)

    def mouseDoubleClickEvent(self, QMouseEvent):
        if QMouseEvent.buttons() == Qt.LeftButton:
            print('左键双击')
            self.x_index += 1
            self.y_index += 1
            self.mymove(self.x_index, self.y_index)
        elif QMouseEvent.buttons() == Qt.RightButton:
            print('右键双击')

    def mouseMoveEvent(self, QMouseEvent):
        if QMouseEvent.buttons() == Qt.LeftButton:
            pos2 = QMouseEvent.screenPos()
            tx = int(self.frameGeometry().x() + pos2.x() - self.pos1.x())
            ty = int(self.frameGeometry().y() + pos2.y() - self.pos1.y())
            self.move(tx, ty)
            self.pos1 = pos2

    def mymove(self, tx_index, ty_index):
        self.move(tx_index * 100, ty_index * 100)
        print(f'按钮移动到({tx_index}, {ty_index})')

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('按钮测试')
        self.resize(500, 500)

        self.btn = Button(self)
        self.btn.setText('ABCD')

if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

在这里多了一些实例属性,如self.x_index, self.y_index用来记录按钮在网格上的位置。

要实现双击动作,必须重写mouseDoubleClickEvent方法,在mouseDoubleClickEvent方法中,我们首先将self.x_index, self.y_index进行修改,以更改按钮要移动到的位置,然后调用mymove方法进行移动。

此外,代码还进行了左键与右键的判断,当左键进行操作时,按钮可以更改位置,右键操作时不可更改。

总结

到此这篇关于Python PyQt拖动控件对齐到网格的文章就介绍到这了,更多相关PyQt拖动控件对齐到网格内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解python的网络编程基础

    详解python的网络编程基础

    这篇文章主要为大家介绍了python网络编程的基础,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • 如何用python爬取微博热搜数据并保存

    如何用python爬取微博热搜数据并保存

    这篇文章主要介绍了如何用python爬取微博热搜数据并保存,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • 关于多元线性回归分析——Python&SPSS

    关于多元线性回归分析——Python&SPSS

    今天小编就为大家分享一篇关于多元线性回归分析——Python&SPSS,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • Python sorted排序方法如何实现

    Python sorted排序方法如何实现

    这篇文章主要介绍了Python sorted排序方法如何实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Python中re.compile函数的使用方法

    Python中re.compile函数的使用方法

    这篇文章主要介绍在python的re模块中怎样应用正则表达式,文中有相关的代码示例,具有一定的参考价值,需要的朋友可以参考下
    2023-06-06
  • Python使用colorlog实现控制台管理日志多种颜色显示

    Python使用colorlog实现控制台管理日志多种颜色显示

    colorlog 是一个 Python 日志库,它可以让你在控制台中以彩色的方式显示日志消息,使得日志更易于阅读和理解,下面就跟随小编一起来看看它的具体应用吧
    2024-03-03
  • 利用python程序生成word和PDF文档的方法

    利用python程序生成word和PDF文档的方法

    这篇文章主要给大家介绍了利用python程序生成word和PDF文档的方法,文中给出了详细的介绍和示例代码,相信对大家具有一定的参考价值,有需要的朋友们下面来一起看看吧。
    2017-02-02
  • Python极简代码实现杨辉三角示例代码

    Python极简代码实现杨辉三角示例代码

    杨辉三角形因为其形式简单,又有一定的使用价值,因此是入门编程题中被用的最多的,也是很好的语言实例标的。这篇文章就给大家介绍了Python极简代码实现杨辉三角的方法,文章给出了详细的示例代码和解释,对大家理解很有帮助,感兴趣的朋友们下面来一起看看吧。
    2016-11-11
  • 解决python selenium3启动不了firefox的问题

    解决python selenium3启动不了firefox的问题

    今天小编就为大家分享一篇解决python selenium3启动不了firefox的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • python中shell执行知识点

    python中shell执行知识点

    在本篇文章里小编给大家分享的是关于python中shell执行知识点内容,需要的朋友们可以学习下。
    2020-05-05

最新评论