Pyqt5设置刻度尺

前言:

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

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

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

 想要的成果如下:

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

import sys

from PyQt5.QtWidgets import QWidget, QApplication

# 刻度尺
class GraduatedRuler(QWidget):

    def __init__(self):
        super(GraduatedRuler, self).__init__()
        self.gr_width = 800
        self.gr_height = 500

        self.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 = 800
        self.gr_height = 500

        self.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 = True
            else:
                self.width_moveLine = False

            # 如果鼠标点击位置是否在上边刻度尺范围
            if self.height_rect.contains(self.mStartPoint):
                self.height_moveLine = True
            else:
                self.height_moveLine = False
        else:
            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 = False
        self.height_moveLine = False
        self.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 = True
            else:
                self.width_moveLine = False

            # 如果鼠标点击位置是否在上边刻度尺范围
            if self.height_rect.contains(self.mStartPoint):
                self.height_moveLine = True
            else:
                self.height_moveLine = False

            # 将刻度线变成可移动状态
            index = 0
            for 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 = True
                    else:
                        self.height_moveLine = True
                    break
                index += 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
            # 判断是否选中刻度线,未选中:-1
            self.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 index
        return -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, QMenu


class GraduatedRuler(QWidget):

    def __init__(self):
        super(GraduatedRuler, self).__init__()
        self.gr_width = 800
        self.gr_height = 500

        self.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 = -1

        self.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 = True
            else:
                self.width_moveLine = False

            # 如果鼠标点击位置是否在上边刻度尺范围
            if self.height_rect.contains(self.mStartPoint):
                self.height_moveLine = True
            else:
                self.height_moveLine = False

            # 将刻度线变成可移动状态
            index = 0
            for 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 = True
                    else:
                        self.height_moveLine = True
                    break
                index += 1

            # 可移动的原理是,将已保存的画线取出放到“移动画线”中,删除已保存画线,“移动画线”释放后会再次保存在保存列表中
            if index != len(self.drew_line):
                del self.drew_line[index]

        else:
            self.right_click = True
            self.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 index
        return -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 = False
        self.height_moveLine = False
        self.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_())

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值