PyQt5 画图工具:绘制矩形、五边形和圆形
import math
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QColorDialog
from PyQt5.QtGui import QPainter, QColor, QPen, QBrush, QPolygonF, QPainterPath, QIcon
from PyQt5.QtCore import Qt, QPoint, QRect, QPointF
class DrawingWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.shape = None
        self.shapes = []
        self.current_color = Qt.white
        self.drawing = False
        self.dragging = False
        self.selected_shape = None
        self.mouse_pos = QPoint()
        self.dragging_shape = None
        self.start_pos = QPoint()  # 保存拖拽操作开始时的图形位置
        self.disable_dragging = False  # 是否禁止拖拽操作
        self.scaling_shape = []
    def paintEvent(self, event):
        qp = QPainter(self)
        qp.setRenderHint(QPainter.Antialiasing)
        qp.fillRect(event.rect(), QColor(0, 0, 0))
        if self.drawing:
            pen = QPen(self.current_color, 2)
            pen.setStyle(Qt.DashLine)
            qp.setPen(pen)
            qp.setBrush(QBrush(Qt.transparent))
            if self.shape == 'rectangle':
                qp.drawRect(self.start_point.x(), self.start_point.y(), self.mouse_pos.x() - self.start_point.x(),
                            self.mouse_pos.y() - self.start_point.y())
            elif self.shape == 'polygon':
                polygon = QPolygonF()
                polygon.append(self.start_point)
                width = abs(self.start_point.x() - self.mouse_pos.x())
                height = abs(self.start_point.y() - self.mouse_pos.y())
                radius = min(width, height) // 2
                center_x = self.start_point.x() + (self.mouse_pos.x() - self.start_point.x()) / 2
                center_y = self.start_point.y() + (self.mouse_pos.y() - self.start_point.y()) / 2
                for i in range(5):
                    x = center_x + radius * math.cos(math.radians(i * 72))
                    y = center_y + radius * math.sin(math.radians(i * 72))
                    polygon.append(QPointF(x, y))
                qp.drawPolygon(polygon)
            elif self.shape == 'circle':
                radius = abs(self.start_point.x() - self.mouse_pos.x())
                qp.drawEllipse(self.start_point, radius, radius)
        for shape in self.shapes:
            if shape.get('selected'):
                pen = QPen(shape['color'], 0)
                qp.setPen(pen)
                qp.setBrush(QBrush(Qt.white))
            if shape.get('show_points'):
                self.draw_shape_points(qp, shape)  # 绘制角点
        for shape in self.shapes:
            pen = QPen(shape['color'], 1)
            if shape.get('selected'):
                pen.setWidth(1)
            qp.setPen(pen)
            qp.setBrush(QBrush(Qt.transparent))
            if shape['type'] == 'rectangle':
                qp.drawRect(shape['rect'])
            elif shape['type'] == 'polygon':
                polygon = shape['polygon']
                qp.drawPolygon(polygon)
            elif shape['type'] == 'circle':
                radius = min(shape['rect'].width(), shape['rect'].height()) // 2
                center_x = shape['rect'].center().x()
                center_y = shape['rect'].center().y()
                qp.drawEllipse(QPoint(center_x, center_y), radius, radius)
    def draw_shape_points(self, qp, shape):
        pen = QPen(shape['color'], 0)
        qp.setPen(pen)
        qp.setBrush(QBrush(Qt.white))
        if shape['type'] == 'rectangle':
            rect = shape['rect']
            for point in [rect.topLeft(), rect.topRight(), rect.bottomRight(), rect.bottomLeft()]:
                qp.drawEllipse(point, 4, 4)
        elif shape['type'] == 'polygon':
            polygon = shape['polygon']
            for point in polygon:
                qp.drawEllipse(point, 4, 4)
        elif shape['type'] == 'circle':
            rect = shape['rect']
            center = rect.center()
            for point in [center + QPoint(rect.width() // 2, 0), center + QPoint(-rect.width() // 2, 0),
                          center + QPoint(0, rect.height() // 2), center + QPoint(0, -rect.height() // 2)]:
                qp.drawEllipse(point, 4, 4)
    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            for shape in self.shapes:
                shape['show_points'] = False
            self.update()
            self.disable_dragging = True  # 禁止拖拽操作
        elif event.button() == Qt.LeftButton:
            if self.shape:
                # 绘制图形
                self.start_point = event.pos()
                self.drawing = True
                self.update()
            else:
                # 选择图形
                for shape in self.shapes:
                    if shape['rect'].contains(event.pos()):
                        shape['selected'] = not shape['selected']
                        self.update()
                        break
    def mouseMoveEvent(self, event):
        self.mouse_pos = event.pos()
        if self.drawing:
            self.update()
        elif self.dragging_shape:
            if not self.disable_dragging:  # 判断是否禁止拖拽操作
                print(self.disable_dragging)
                dx = event.pos().x() - self.start_pos.x() - self.dragging_shape['rect'].x()
                dy = event.pos().y() - self.start_pos.y() - self.dragging_shape['rect'].y()
                if self.dragging_shape['type'] == 'rectangle':
                    self.dragging_shape['rect'].translate(dx, dy)
                elif self.dragging_shape['type'] == 'polygon':
                    polygon = self.dragging_shape['polygon']
                    polygon.translate(dx, dy)
                    self.dragging_shape['rect'] = polygon.boundingRect()
                elif self.dragging_shape['type'] == 'circle':
                    self.dragging_shape['rect'].translate(dx, dy)
                self.update()
        else:
            if event.buttons() & Qt.LeftButton:
                for shape in self.shapes:
                    if shape['rect'].contains(event.pos()):
                        self.dragging_shape = shape
                        self.start_pos = event.pos() - shape['rect'].topLeft()
                        break
    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            if self.drawing:
                self.drawing = False
                shape = {
                    'type': self.shape,
                    'color': self.current_color,
                    'rect': self.get_current_rect(),
                    'polygon': self.get_current_polygon(),
                    'selected': False
                }
                self.shapes.append(shape)
                self.shape = None
                self.update()
                self.show_shape_points(shape)  # 显示角点
            else:
                self.dragging_shape = None
    def show_shape_points(self, shape):
        shape['show_points'] = True
        self.update()
    def get_current_rect(self):
        x1 = min(self.start_point.x(), self.mouse_pos.x())
        y1 = min(self.start_point.y(), self.mouse_pos.y())
        x2 = max(self.start_point.x(), self.mouse_pos.x())
        y2 = max(self.start_point.y(), self.mouse_pos.y())
        return QRect(x1, y1, x2 - x1, y2 - y1)
    def get_current_polygon(self):
        polygon = QPolygonF()
        if self.shape == 'polygon':
            points = []
            for i in range(5):
                angle_deg = 72 * i
                angle_rad = math.radians(angle_deg)
                x = self.start_point.x() + math.cos(angle_rad) * (self.mouse_pos.x() - self.start_point.x())
                y = self.start_point.y() + math.sin(angle_rad) * (self.mouse_pos.y() - self.start_point.y())
                points.append(QPointF(x, y))
            polygon = QPolygonF(points)
        return polygon
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('画图')
        self.drawing_widget = DrawingWidget()
        self.drawing_widget.setMinimumSize(500, 500)
        self.setCentralWidget(self.drawing_widget)
        self.create_toolbar()
        self.current_color = Qt.black
    def create_toolbar(self):
        toolbar = self.addToolBar('工具栏')
        rectangle_btn = QPushButton('矩形')
        rectangle_iocn = QIcon('./rectangle.png')
        rectangle_btn.setIcon(rectangle_iocn)
        rectangle_btn.clicked.connect(lambda: self.set_shape('rectangle'))
        toolbar.addWidget(rectangle_btn)
        polygon_btn = QPushButton('五边形')
        polygon_iocn = QIcon('./mul.png')
        rectangle_btn.setIcon(polygon_iocn)
        polygon_btn.clicked.connect(lambda: self.set_shape('polygon'))
        toolbar.addWidget(polygon_btn)
        circle_btn = QPushButton('圆形')
        circle_iocn = QIcon('./circle.png')
        circle_btn.setIcon(circle_iocn)
        circle_btn.clicked.connect(lambda: self.set_shape('circle'))
        toolbar.addWidget(circle_btn)
        clear_btn = QPushButton('清屏')
        clear_btn.clicked.connect(self.clear_shapes)
        toolbar.addWidget(clear_btn)
        color_btn = QPushButton('颜色')
        color_iocn = QIcon('/noun_color.png')
        color_btn.setIcon(color_iocn)
        color_btn.clicked.connect(self.set_color)
        toolbar.addWidget(color_btn)
    def set_color(self):
        color = QColorDialog.getColor(self.current_color, self, '选择颜色')
        if color.isValid():
            self.current_color = color
        self.drawing_widget.current_color = self.current_color
    def set_shape(self, shape):
        self.drawing_widget.shape = shape
    def clear_shapes(self):
        self.drawing_widget.shapes = []
        self.drawing_widget.update()
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
这段代码是一个简单的画图应用程序,使用 PyQt5 库进行界面的构建。主要功能包括绘制矩形、五边形和圆形图形,选择图形颜色,清空画布等。
代码中的 DrawingWidget 类是继承自 QWidget 的自定义控件,用于绘制图形和处理鼠标事件。MainWindow 类是继承自 QMainWindow 的主窗口类,用于创建界面和处理按钮点击事件。
在 DrawingWidget 类中,paintEvent 方法用于绘制图形,mousePressEvent、mouseMoveEvent 和 mouseReleaseEvent 方法用于处理鼠标事件。
在 MainWindow 类中,create_toolbar 方法用于创建工具栏,并添加各种按钮。set_color 方法用于设置当前图形的颜色,set_shape 方法用于设置当前绘制的图形形状,clear_shapes 方法用于清空画布。
整个应用程序的界面和功能都是使用 PyQt5 库完成的。如果对 PyQt5 不熟悉,可能需要先学习一些 PyQt5 的基础知识。
原文地址: https://www.cveoy.top/t/topic/pa3i 著作权归作者所有。请勿转载和采集!