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方法。
- 当我们按下鼠标时,触发mousePress事件,记录此刻光标位置;
- 当光标拖动时触发mouseMove事件,获取当前光标位置,计算与之前位置的x和y的差值,然后加到按钮的相对坐标上,获得按钮需要移动到的位置坐标;
- 调用move方法移动按钮;
- 更新pos1即按钮位置;
- 只要光标移动,就会触发mouseMove事件,就会不断移动按钮与更新按钮位置,在视觉上按钮就是在跟着光标任意拖动。
要实现鼠标释放时对齐到网格,需要重写mouseReleaseEvent方法,用来响应鼠标释放动作。
- 当鼠标释放时,立即读取按钮的当前相对坐标;
- 将按钮的坐标除以100用来获取其在网格上的位置,如果坐标小于0应令其等于0,同时0-99的坐标除以100也等于0,于是只要小于99就等于0;
- 然后调用自定义的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获取异常信息exc_info和print_exc的使用
python通过sys.exc_info获取异常信息,通过traceback.print_exc打印堆栈信息,包括错误类型和错误位置等信息,本文就来介绍一下具体用法,感兴趣的可以了解一下2023-12-12python爬取豆瓣电影排行榜(requests)的示例代码
这篇文章主要介绍了python爬取豆瓣电影排行榜(requests),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-02-02Python使用win32 COM实现Excel的写入与保存功能示例
这篇文章主要介绍了Python使用win32 COM实现Excel的写入与保存功能,结合实例形式分析了Python调用win32 COM组件针对Excel文件的读写与保存相关操作技巧,需要的朋友可以参考下2018-05-05Numpy中转置transpose、T和swapaxes的实例讲解
下面小编就为大家分享一篇Numpy中转置transpose、T和swapaxes的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2018-04-04
最新评论