Pyqt5设置刻度尺

时间: 2023-10-04 admin IT培训

Pyqt5设置刻度尺

Pyqt5设置刻度尺

前言:

我发现百度上都搜不到有关PyQt有用的东西,全是C语言的Qt,对于我这种不懂C语言的萌新实在是不友好,官方文档也看不懂,实在是难堪。好像PyQt都没人用一样,哎。

我在学习Pyqt5过程中,看到ps的刻度尺然后突发奇想的想要去用pyqt5写一个刻度尺,然而只找到一个相关的代码。

链接:pyqt5 刻度条 尺子 刻度尺叫啥都行_不知道怎么写代码的麻瓜的博客-CSDN博客

 想要的成果如下:

  1、首先创建一个pyqt5的窗口

import sysfrom PyQt5.QtWidgets import QWidget, QApplication# 刻度尺
class GraduatedRuler(QWidget):def __init__(self):super(GraduatedRuler, self).__init__()self.gr_width = 800self.gr_height = 500self.setFixedSize(self.gr_width, self.gr_height)if __name__ == '__main__':app = QApplication(sys.argv)gr = GraduatedRuler()gr.show()sys.exit(app.exec_())

2、第一步:绘画出刻度尺

from PyQt5 import QtGui
from PyQt5.QtCore import QRect, QPoint, Qt
from PyQt5.QtGui import QPainter, QBrush, QPen    # 绘图事件def paintEvent(self, a0: QtGui.QPaintEvent):super().paintEvent(a0)painter = QPainter(self)        # 画图painter.setPen(QPen(QBrush(Qt.black), 1))  # 设置画笔width = int(self.gr_width)height = int(self.gr_height)painter.drawLine(20, 0, 20, height)     # 画一条左侧刻度尺线painter.drawLine(0, 20, width, 20)      # 画一条上边刻度尺线self.width_rect = QRect(0, 40, 20, height)      # 保存左侧刻度尺的范围self.height_rect = QRect(40, 0, width, 20)      # 保存上边刻度尺的范围# 左侧刻度,每10像素为一个小刻度,每40像素为一个大刻度for i in range(40, height, 10):if i % 40 == 0:painter.drawText(QPoint(2, i - 22), str(i))painter.drawLine(0, i, 20, i)else:painter.drawLine(20, i, 15, i)# 上边刻度,每10像素为一个小刻度,每40像素为一个大刻度for i in range(40, width, 10):if i % 40 == 0:painter.drawText(QPoint(i + 5, 10), str(i))painter.drawLine(i, 0, i, 20)else:painter.drawLine(i, 20, i, 15)

3、第二步:点击刻度尺,向右或向下拉动出现刻度线

    def __init__(self):super(GraduatedRuler, self).__init__()self.gr_width = 800self.gr_height = 500self.width_rect = None      # 左侧刻度尺的范围,是一个矩形,QRect类型self.height_rect = None     # 上边刻度尺的范围,是一个矩形,QRect类型self.width_moveLine = False     # 判断是否为左侧刻度尺被拉动self.height_moveLine = False    # 判断是否为上边刻度尺被拉动self.right_click = False  # 右键点击self.drawing_line = []      # 移动画线保存self.drew_line = []         # 保存所有画线self.setFixedSize(self.gr_width, self.gr_height)# 绘图事件def paintEvent(self, a0: QtGui.QPaintEvent):......# 更换画笔样式painter.setPen(QPen(QColor(74, 255, 255), 1, Qt.SolidLine))# 绘制已保存的画线if self.drew_line:for line_norms in self.drew_line:line = line_norms['line']painter.drawLine(line[0], line[1], line[2], line[3])# 绘制“移动画线”,实时显示if self.drawing_line:for line in self.drawing_line:painter.drawLine(line[0], line[1], line[2], line[3])

>> 鼠标操作事件 

    # 鼠标按压事件def mousePressEvent(self, a0: QtGui.QMouseEvent):super().mousePressEvent(a0)self.mStartPoint = a0.pos()# 如果不是右键点击if a0.buttons() != Qt.RightButton:# 如果鼠标点击位置是否在左侧刻度尺范围if self.width_rect.contains(self.mStartPoint):self.width_moveLine = Trueelse:self.width_moveLine = False# 如果鼠标点击位置是否在上边刻度尺范围if self.height_rect.contains(self.mStartPoint):self.height_moveLine = Trueelse:self.height_moveLine = Falseelse:self.right_click = True# 鼠标移动事件def mouseMoveEvent(self, a0: QtGui.QMouseEvent):super().mouseMoveEvent(a0)self.mMovePoint = a0.pos()# 如果不是右键点击if self.right_click is False:if self.mStartPoint is not None:# 如果是点击左侧刻度尺,把竖线保存在“移动画线”列表中,同一时间“移动画线”仅有一个if self.width_moveLine is True:self.drawing_line.clear()self.drawing_line.append([self.mMovePoint.x(), 0, self.mMovePoint.x(), self.height()])self.repaint()# 如果是点击上边刻度尺,也把横线保存在“移动画线”列表中,同一时间“移动画线”仅有一个if self.height_moveLine is True:self.drawing_line.clear()self.drawing_line.append([0, self.mMovePoint.y(), self.width(), self.mMovePoint.y()])self.repaint()# 鼠标施放事件def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):super().mouseReleaseEvent(a0)self.mReleasePoint = a0.pos()# 如果不是右键点击if self.right_click is False:# 如果是点击左侧刻度尺,鼠标释放后就保存竖线if self.width_moveLine is True:for line in self.drawing_line:self.drew_line.append({"norms": "width", "line": line})self.repaint()# 如果是点击上边刻度尺,鼠标释放后就保存横线if self.height_moveLine is True:for line in self.drawing_line:self.drew_line.append({"norms": "height", "line": line})self.repaint()# 鼠标释放后,初始化动态状态self.drawing_line.clear()self.width_moveLine = Falseself.height_moveLine = Falseself.right_click = False

 >> 效果展示:

 4、第三步:点击刻度线,可以任意拖动

    # 鼠标按压事件def mousePressEvent(self, a0: QtGui.QMouseEvent):super().mousePressEvent(a0)self.mStartPoint = a0.pos()# 如果不是右键点击if a0.buttons() != Qt.RightButton:# 如果鼠标点击位置是否在左侧刻度尺范围if self.width_rect.contains(self.mStartPoint):self.width_moveLine = Trueelse:self.width_moveLine = False# 如果鼠标点击位置是否在上边刻度尺范围if self.height_rect.contains(self.mStartPoint):self.height_moveLine = Trueelse:self.height_moveLine = False# 将刻度线变成可移动状态index = 0for drew_line in self.drew_line:norms = drew_line['norms']line = drew_line['line']# 将线变成矩形,利用contains函数判断点击位置是或否在刻度线范围if norms == "width":tmp_rect = QRect(line[0], line[1], 3, line[3])else:tmp_rect = QRect(line[0], line[1], line[2], 3)if tmp_rect.contains(self.mStartPoint):self.drawing_line.clear()self.drawing_line.append(line)if norms == "width":self.width_moveLine = Trueelse:self.height_moveLine = Truebreakindex += 1# 可移动的原理是,将已保存的画线取出放到“移动画线”中,删除已保存画线,“移动画线”释放后会再次保存在保存列表中if index != len(self.drew_line):del self.drew_line[index]else:self.right_click = True

5、删除刻度线,用右键策略

    # 鼠标按压事件def mousePressEvent(self, a0: QtGui.QMouseEvent):super().mousePressEvent(a0)self.mStartPoint = a0.pos()# 如果不是右键点击if a0.buttons() != Qt.RightButton:......else:self.right_click = True# 判断是否选中刻度线,未选中:-1self.selected_line_numble = self.select_line(self.mStartPoint)# 判断是否选中刻度线def select_line(self, mStartPoint):for index, drew_line in enumerate(self.drew_line):norms = drew_line['norms']line = drew_line['line']if norms == "width":tmp_rect = QRect(line[0], line[1], 3, line[3])else:tmp_rect = QRect(line[0], line[1], line[2], 3)if tmp_rect.contains(mStartPoint):return indexreturn -1# 鼠标施放事件def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):super().mouseReleaseEvent(a0)self.mReleasePoint = a0.pos()# 如果不是右键点击if self.right_click is False:......else:# 若选中刻度线,鼠标右键展开策略if self.selected_line_numble != -1:self.right_click_strategy()     # 右键策略......# 右键策略def right_click_strategy(self):popMenu = QMenu(self)   # 动态菜单# 添加删除功能delete_item = popMenu.addAction(u"删除")atum = popMenu.exec_(QtGui.QCursor.pos())# 如果鼠标点击的item相等于删除item,执行删除if atum == delete_item:del self.drew_line[self.selected_line_numble]self.repaint()

>>效果展示:

 6、完整代码

import sys
from PyQt5 import QtGui
from PyQt5.QtCore import QRect, QPoint, Qt
from PyQt5.QtGui import QPainter, QBrush, QPen, QColor
from PyQt5.QtWidgets import QWidget, QApplication, QMenuclass GraduatedRuler(QWidget):def __init__(self):super(GraduatedRuler, self).__init__()self.gr_width = 800self.gr_height = 500self.width_rect = None      # 左侧刻度尺的范围,是一个矩形,QRect类型self.height_rect = None     # 上边刻度尺的范围,是一个矩形,QRect类型self.width_moveLine = False     # 判断是否为左侧刻度尺被拉动self.height_moveLine = False    # 判断是否为上边刻度尺被拉动self.right_click = False  # 右键点击self.selected_line_numble = -1self.drawing_line = []      # 移动画线保存self.drew_line = []         # 保存所有画线self.setFixedSize(self.gr_width, self.gr_height)# 绘图事件def paintEvent(self, a0: QtGui.QPaintEvent):super().paintEvent(a0)painter = QPainter(self)        # 画图painter.setPen(QPen(QBrush(Qt.black), 1))  # 设置画笔width = int(self.gr_width)height = int(self.gr_height)painter.drawLine(20, 0, 20, height)     # 画一条左侧刻度尺线painter.drawLine(0, 20, width, 20)      # 画一条上边刻度尺线self.width_rect = QRect(0, 40, 20, height)      # 保存左侧刻度尺的范围self.height_rect = QRect(40, 0, width, 20)      # 保存上边刻度尺的范围# 左侧刻度,每10像素为一个小刻度,每40像素为一个大刻度for i in range(40, height, 10):if i % 40 == 0:painter.drawText(QPoint(2, i - 22), str(i))painter.drawLine(0, i, 20, i)else:painter.drawLine(20, i, 15, i)# 上边刻度,每10像素为一个小刻度,每40像素为一个大刻度for i in range(40, width, 10):if i % 40 == 0:painter.drawText(QPoint(i + 5, 10), str(i))painter.drawLine(i, 0, i, 20)else:painter.drawLine(i, 20, i, 15)# 更换画笔样式painter.setPen(QPen(QColor(74, 255, 255), 1, Qt.SolidLine))# 绘制已保存的画线if self.drew_line:for line_norms in self.drew_line:line = line_norms['line']painter.drawLine(line[0], line[1], line[2], line[3])# 绘制“移动画线”,实时显示if self.drawing_line:for line in self.drawing_line:painter.drawLine(line[0], line[1], line[2], line[3])# 鼠标按压事件def mousePressEvent(self, a0: QtGui.QMouseEvent):super().mousePressEvent(a0)self.mStartPoint = a0.pos()# 如果不是右键点击if a0.buttons() != Qt.RightButton:# 如果鼠标点击位置是否在左侧刻度尺范围if self.width_rect.contains(self.mStartPoint):self.width_moveLine = Trueelse:self.width_moveLine = False# 如果鼠标点击位置是否在上边刻度尺范围if self.height_rect.contains(self.mStartPoint):self.height_moveLine = Trueelse:self.height_moveLine = False# 将刻度线变成可移动状态index = 0for drew_line in self.drew_line:norms = drew_line['norms']line = drew_line['line']# 将线变成矩形,利用contains函数判断点击位置是或否在刻度线范围if norms == "width":tmp_rect = QRect(line[0], line[1], 3, line[3])else:tmp_rect = QRect(line[0], line[1], line[2], 3)if tmp_rect.contains(self.mStartPoint):self.drawing_line.clear()self.drawing_line.append(line)if norms == "width":self.width_moveLine = Trueelse:self.height_moveLine = Truebreakindex += 1# 可移动的原理是,将已保存的画线取出放到“移动画线”中,删除已保存画线,“移动画线”释放后会再次保存在保存列表中if index != len(self.drew_line):del self.drew_line[index]else:self.right_click = Trueself.selected_line_numble = self.select_line(self.mStartPoint)  # 判断是否选中刻度线,未选中:-1# 判断是否选中刻度线def select_line(self, mStartPoint):for index, drew_line in enumerate(self.drew_line):norms = drew_line['norms']line = drew_line['line']if norms == "width":tmp_rect = QRect(line[0], line[1], 3, line[3])else:tmp_rect = QRect(line[0], line[1], line[2], 3)if tmp_rect.contains(mStartPoint):return indexreturn -1# 鼠标移动事件def mouseMoveEvent(self, a0: QtGui.QMouseEvent):super().mouseMoveEvent(a0)self.mMovePoint = a0.pos()# 如果不是右键点击if self.right_click is False:if self.mStartPoint is not None:# 如果是点击左侧刻度尺,把竖线保存在“移动画线”列表中,同一时间“移动画线”仅有一个if self.width_moveLine is True:self.drawing_line.clear()self.drawing_line.append([self.mMovePoint.x(), 0, self.mMovePoint.x(), self.height()])self.repaint()# 如果是点击上边刻度尺,也把横线保存在“移动画线”列表中,同一时间“移动画线”仅有一个if self.height_moveLine is True:self.drawing_line.clear()self.drawing_line.append([0, self.mMovePoint.y(), self.width(), self.mMovePoint.y()])self.repaint()# 鼠标施放事件def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):super().mouseReleaseEvent(a0)self.mReleasePoint = a0.pos()# 如果不是右键点击if self.right_click is False:# 如果是点击左侧刻度尺,鼠标释放后就保存竖线if self.width_moveLine is True:for line in self.drawing_line:self.drew_line.append({"norms": "width", "line": line})self.repaint()# 如果是点击上边刻度尺,鼠标释放后就保存横线if self.height_moveLine is True:for line in self.drawing_line:self.drew_line.append({"norms": "height", "line": line})self.repaint()else:# 若选中刻度线,鼠标右键展开策略if self.selected_line_numble != -1:self.right_click_strategy()     # 右键策略# 鼠标释放后,初始化动态状态self.drawing_line.clear()self.width_moveLine = Falseself.height_moveLine = Falseself.right_click = False# 右键策略def right_click_strategy(self):popMenu = QMenu(self)   # 动态菜单# 添加删除功能delete_item = popMenu.addAction(u"删除")atum = popMenu.exec_(QtGui.QCursor.pos())# 如果鼠标点击的item相等于删除item,执行删除if atum == delete_item:del self.drew_line[self.selected_line_numble]self.repaint()if __name__ == '__main__':app = QApplication(sys.argv)gr = GraduatedRuler()gr.show()sys.exit(app.exec_())