Qt界面

Qt鼠标绘制功能

鼠标事件

  1. 鼠标按下

    def mouseReleaseEvent(self, event):
        QWidget.mouseReleaseEvent(self, event)
    

  2. 鼠标抬起

    def mousePressEvent(self, event):
        QWidget.mousePressEvent(self, event)
    

  3. 鼠标移动
    def mouseMoveEvent(self, event):
        QWidget.mouseMoveEvent(self, event)
    

窗体绘制

  1. 绘制事件

    def paintEvent(self, event):
            QWidget.paintEvent(self, event)
    

  2. 画笔功能

    pen = QPen()
    pen.setColor(QColor(255, 0, 0))
    painter = QPainter()
    painter.begin(self)
    painter.setPen(pen)
    
    painter.drawLine(pre_x, pre_y, end_x, end_y)
    
    painter.end()
    

  3. 触发更新

    self.update()
    

数据定义

绘制过程中, 需要记录鼠标的点位以及当前的操作方式。按照以下格式定义:

class WriteData:
    MOVE = 1  # 移动到某个点
    PENUP = 2  # 抬起笔
    PENDOWN = 3  # 放下笔

    def __init__(self):
        self.type = []
        self.data = []

Info

写一个字,会产生很多点位以及对应的操作方式。

type:所有点位对应的操作方式的集合,是由顺序的。每个item表示为操作方式,在MOVE,PENUP,PENDOWN中作选择。

data: 对应所有点位的集合。由于要表示一个点,需要两个值(x,y),我们将data[i]和data[i+1]定义为一个点。一个type对应两个data的值。

完整代码

# coding: utf-8

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from write_msgs.msg import WriteData
import rospy


class PaintWindow(QWidget):
    def __init__(self):
        super(PaintWindow, self).__init__()
        self.data = WriteData()

    def mouseMoveEvent(self, event):
        QWidget.mouseMoveEvent(self, event)

        if not isinstance(event, QMouseEvent):
            return

        self.data.type.append(WriteData.MOVE)
        self.data.data.append(-event.pos().x())
        self.data.data.append(event.pos().y())

        self.update()


    def mousePressEvent(self, event):
        QWidget.mousePressEvent(self, event)

        if not isinstance(event, QMouseEvent):
            return

        self.data.type.append(WriteData.PENDOWN)
        self.data.data.append(-event.pos().x())
        self.data.data.append(event.pos().y())

        self.update()

    def mouseReleaseEvent(self, event):
        QWidget.mouseReleaseEvent(self, event)

        if not isinstance(event, QMouseEvent):
            return

        self.data.type.append(WriteData.PENUP)
        self.data.data.append(-event.pos().x())
        self.data.data.append(event.pos().y())

        self.update()

    def paintEvent(self, event):
        QWidget.paintEvent(self, event)

        pen = QPen()
        pen.setColor(QColor(255, 0, 0))
        painter = QPainter()
        painter.begin(self)
        painter.setPen(pen)

        if len(self.data.type) > 1:
            pre_x = - self.data.data[0]
            pre_y = self.data.data[1]

            for i in range(len(self.data.type)):
                end_x = - self.data.data[2 * i]
                end_y = self.data.data[2 * i + 1]

                if self.data.type[i] == WriteData.MOVE:
                    painter.drawLine(pre_x, pre_y, end_x, end_y)
                pre_x = end_x
                pre_y = end_y

        painter.end()

    def getData(self):
        return self.data

    def clearData(self):
        self.data = WriteData()
        self.update()


class MainWindow(QWidget):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle("写字面板")

        layout = QVBoxLayout(self)
        self.setLayout(layout)

        topLayout = QHBoxLayout(self)
        layout.addLayout(topLayout)

        self.btnClear = QPushButton("清理")
        topLayout.addWidget(self.btnClear)

        self.btnDraw = QPushButton("绘制")
        topLayout.addWidget(self.btnDraw)

        self.paintWindow = PaintWindow()
        self.paintWindow.setFixedSize(640, 480)
        layout.addWidget(self.paintWindow)

        self.btnClear.clicked.connect(self.clickClear)
        self.btnDraw.clicked.connect(self.clickDraw)


    def clickClear(self):
        self.paintWindow.clearData()

    def clickDraw(self):
        data = self.paintWindow.getData()