美文网首页
Python黑科技系列07-小项目-开发一个定制的小画板

Python黑科技系列07-小项目-开发一个定制的小画板

作者: Tony_Pm | 来源:发表于2022-06-24 13:20 被阅读0次

    序言

    有时候想得太多,只会让自己变得心态不好,白白浪费太多的时间,很没有必要。

    因为很多时候,换一个角度,改一下心态,很多想不通的问题,瞬间就想通了。想不通就暂时先不想;不必纠结于一时。人随风过,自在花开花又落。越简单越幸福。

    实战

    素材准备:

    安装第三方模块:pip install PyQt5

    效果先展示一下

    image.png image.png

    本项目共分为3个模块 分别是 窗口组件功能代码、窗口组件代码、程序运行代码。

    第一步:窗口组件功能代码

    from PyQt5.QtWidgets import QWidget
    from PyQt5.Qt import QPixmap, QPainter, QPoint, QPaintEvent, QMouseEvent, QPen, \
        QColor, QSize
    from PyQt5.QtCore import Qt
    
    
    class PaintBoard(QWidget):
    
        def __init__(self, Parent=None):
            '''
            Constructor
            '''
            super().__init__(Parent)
    
            self.__InitData()  # 先初始化数据,再初始化界面
            self.__InitView()
    
        def __InitData(self):
    
            self.__size = QSize(480, 460)
    
            # 新建QPixmap作为画板,尺寸为__size
            self.__board = QPixmap(self.__size)
            self.__board.fill(Qt.white)  # 用白色填充画板
    
            self.__IsEmpty = True  # 默认为空画板
            self.EraserMode = False  # 默认为禁用橡皮擦模式
    
            self.__lastPos = QPoint(0, 0)  # 上一次鼠标位置
            self.__currentPos = QPoint(0, 0)  # 当前的鼠标位置
    
            self.__painter = QPainter()  # 新建绘图工具
    
            self.__thickness = 10  # 默认画笔粗细为10px
            self.__penColor = QColor("black")  # 设置默认画笔颜色为黑色
            self.__colorList = QColor.colorNames()  # 获取颜色列表
    
        def __InitView(self):
            # 设置界面的尺寸为__size
            self.setFixedSize(self.__size)
    
        def Clear(self):
            # 清空画板
            self.__board.fill(Qt.white)
            self.update()
            self.__IsEmpty = True
    
        def ChangePenColor(self, color="black"):
            # 改变画笔颜色
            self.__penColor = QColor(color)
    
        def ChangePenThickness(self, thickness=10):
            # 改变画笔粗细
            self.__thickness = thickness
    
        def IsEmpty(self):
            # 返回画板是否为空
            return self.__IsEmpty
    
        def GetContentAsQImage(self):
            # 获取画板内容(返回QImage)
            image = self.__board.toImage()
            return image
    
        def paintEvent(self, paintEvent):
            # 绘图事件
            self.__painter.begin(self)
            # 0,0为绘图的左上角起点的坐标
            self.__painter.drawPixmap(0, 0, self.__board)
            self.__painter.end()
    
        def mousePressEvent(self, mouseEvent):
            # 鼠标按下时,获取鼠标的当前位置保存为上一次位置
            self.__currentPos = mouseEvent.pos()
            self.__lastPos = self.__currentPos
    
        def mouseMoveEvent(self, mouseEvent):
            # 鼠标移动时,更新当前位置,并在上一个位置和当前位置间画线
            self.__currentPos = mouseEvent.pos()
            self.__painter.begin(self.__board)
    
            if self.EraserMode == False:
                # 非橡皮擦模式
                self.__painter.setPen(QPen(self.__penColor, self.__thickness))  # 设置画笔颜色,粗细
            else:
                # 橡皮擦模式下画笔为纯白色,粗细为10
                self.__painter.setPen(QPen(Qt.white, 10))
    
            # 画线
            self.__painter.drawLine(self.__lastPos, self.__currentPos)
            self.__painter.end()
            self.__lastPos = self.__currentPos
    
            self.update()  # 更新显示
    
        def mouseReleaseEvent(self, mouseEvent):
            self.__IsEmpty = False  # 画板不再为空
    

    第二步:窗口组件代码

    # -*- coding: utf-8 -*-
    # @Author  : Tony
    from PyQt5.Qt import QWidget, QColor, QPixmap, QIcon, QSize, QCheckBox
    from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QPushButton, QSplitter, \
        QComboBox, QLabel, QSpinBox, QFileDialog
    from *.PaintBoard import PaintBoard
    
    
    class MainWidget(QWidget):
    
        def __init__(self, Parent=None):
            '''
            Constructor
            '''
            super().__init__(Parent)
    
            self.__InitData()  # 先初始化数据,再初始化界面
            self.__InitView()
    
        def __InitData(self):
            '''
                      初始化成员变量
            '''
            self.__paintBoard = PaintBoard(self)
            # 获取颜色列表(字符串类型)
            self.__colorList = QColor.colorNames()
    
        def __InitView(self):
            '''
                      初始化界面
            '''
            self.setFixedSize(640, 480)
            self.setWindowTitle("PM_Tony老师定制的小画板·")
    
            # 新建一个水平布局作为本窗体的主布局
            main_layout = QHBoxLayout(self)
            # 设置主布局内边距以及控件间距为10px
            main_layout.setSpacing(10)
    
            # 在主界面左侧放置画板
            main_layout.addWidget(self.__paintBoard)
    
            # 新建垂直子布局用于放置按键
            sub_layout = QVBoxLayout()
    
            # 设置此子布局和内部控件的间距为10px
            sub_layout.setContentsMargins(10, 10, 10, 10)
    
            self.__btn_Clear = QPushButton("清空画板")
            self.__btn_Clear.setParent(self)  # 设置父对象为本界面
    
            # 将按键按下信号与画板清空函数相关联
            self.__btn_Clear.clicked.connect(self.__paintBoard.Clear)
            sub_layout.addWidget(self.__btn_Clear)
    
            self.__btn_Quit = QPushButton("退出")
            self.__btn_Quit.setParent(self)  # 设置父对象为本界面
            self.__btn_Quit.clicked.connect(self.Quit)
            sub_layout.addWidget(self.__btn_Quit)
    
            self.__btn_Save = QPushButton("保存作品")
            self.__btn_Save.setParent(self)
            self.__btn_Save.clicked.connect(self.on_btn_Save_Clicked)
            sub_layout.addWidget(self.__btn_Save)
    
            self.__cbtn_Eraser = QCheckBox("  使用橡皮擦")
            self.__cbtn_Eraser.setParent(self)
            self.__cbtn_Eraser.clicked.connect(self.on_cbtn_Eraser_clicked)
            sub_layout.addWidget(self.__cbtn_Eraser)
    
            splitter = QSplitter(self)  # 占位符
            sub_layout.addWidget(splitter)
    
            self.__label_penThickness = QLabel(self)
            self.__label_penThickness.setText("画笔粗细")
            self.__label_penThickness.setFixedHeight(20)
            sub_layout.addWidget(self.__label_penThickness)
    
            self.__spinBox_penThickness = QSpinBox(self)
            self.__spinBox_penThickness.setMaximum(20)
            self.__spinBox_penThickness.setMinimum(2)
            self.__spinBox_penThickness.setValue(10)  # 默认粗细为10
            self.__spinBox_penThickness.setSingleStep(2)  # 最小变化值为2
            self.__spinBox_penThickness.valueChanged.connect(
                self.on_PenThicknessChange)  # 关联spinBox值变化信号和函数on_PenThicknessChange
            sub_layout.addWidget(self.__spinBox_penThickness)
    
            self.__label_penColor = QLabel(self)
            self.__label_penColor.setText("画笔颜色")
            self.__label_penColor.setFixedHeight(20)
            sub_layout.addWidget(self.__label_penColor)
    
            self.__comboBox_penColor = QComboBox(self)
            self.__fillColorList(self.__comboBox_penColor)  # 用各种颜色填充下拉列表
            self.__comboBox_penColor.currentIndexChanged.connect(self.on_PenColorChange)  # 关联下拉列表的当前索引变更信号与函数on_PenColorChange
            sub_layout.addWidget(self.__comboBox_penColor)
    
            main_layout.addLayout(sub_layout)  # 将子布局加入主布局
    
    
        def __fillColorList(self, comboBox):
            index_black = 0
            index = 0
            for color in self.__colorList:
                if color == "black":
                    index_black = index
                index += 1
                pix = QPixmap(70, 20)
                pix.fill(QColor(color))
                comboBox.addItem(QIcon(pix), None)
                comboBox.setIconSize(QSize(70, 20))
                comboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
    
            comboBox.setCurrentIndex(index_black)
    
    
        def on_PenColorChange(self):
            color_index = self.__comboBox_penColor.currentIndex()
            color_str = self.__colorList[color_index]
            self.__paintBoard.ChangePenColor(color_str)
    
    
        def on_PenThicknessChange(self):
            penThickness = self.__spinBox_penThickness.value()
            self.__paintBoard.ChangePenThickness(penThickness)
    
    
        def on_btn_Save_Clicked(self):
            savePath = QFileDialog.getSaveFileName(self, 'Save Your Paint', '.\\', '*.png')
            print(savePath)
            if savePath[0] == "":
                print("Save cancel")
                return
            image = self.__paintBoard.GetContentAsQImage()
            image.save(savePath[0])
    
    
        def on_cbtn_Eraser_clicked(self):
            if self.__cbtn_Eraser.isChecked():
                self.__paintBoard.EraserMode = True  # 进入橡皮擦模式
            else:
                self.__paintBoard.EraserMode = False  # 退出橡皮擦模式
    
    
        def Quit(self):
            self.close()
    
    

    第三步:程序运行代码

    from *.MainWidget import MainWidget
    from PyQt5.QtWidgets import QApplication
    import sys
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        # 创建窗口
        mainWidget = MainWidget()
        # 显示
        mainWidget.show()
        app.exit(app.exec_())
    

    效果展示

    小画板.gif

    如果本文对你学习有所帮助-可以点赞👍+ 关注!将持续更新更多新的文章。

    相关文章

      网友评论

          本文标题:Python黑科技系列07-小项目-开发一个定制的小画板

          本文链接:https://www.haomeiwen.com/subject/qbfmvrtx.html