PyQt对话框,控件(实例:绘图——简单画板工具)

PyQt对话框,控件(实例:绘图——简单画板工具)

    • 作业描述
    • 成果展示
    • 全解python代码实现
    • 全解代码截图
    • 全解代码

作业描述

PyQt对话框,控件(实例:绘图——简单画板工具)_第1张图片

成果展示

PyQt对话框,控件(实例:绘图——简单画板工具)_第2张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第3张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第4张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第5张图片

全解python代码实现

全解代码截图

PyQt对话框,控件(实例:绘图——简单画板工具)_第6张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第7张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第8张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第9张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第10张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第11张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第12张图片
PyQt对话框,控件(实例:绘图——简单画板工具)_第13张图片
在这里插入图片描述

全解代码

import os
import sys
import PyQt5.QtCore as qc 
import PyQt5.QtGui as qg
import PyQt5.QtWidgets  as qw



class SetPenColorDlg(qw.QDialog):
    #重载构造函数
    def __init__(self,parent = None):
        #重载父类构造函数
        super().__init__(parent)
        #改变窗口显示的title
        self.setWindowTitle("SetPenWidth")
        
        
        #red设置的Label
        self.RLabel = qw.QLabel("Red :")
        #red的数字框
        self.RSpinBox = qw.QDoubleSpinBox(self)
        #范围
        self.RSpinBox.setRange(0,255)
        #初始值
        self.RSpinBox.setValue(255)

        #green设置的Label 
        self.GLabel = qw.QLabel("Green :")
        #green的数字框
        self.GSpinBox = qw.QDoubleSpinBox(self)
        #范围
        self.GSpinBox.setRange(0,255)
        #初始值
        self.GSpinBox.setValue(255)
        
        #blue设置的Label
        self.BLabel = qw.QLabel("Blue :")
        #blue的数字框
        self.BSpinBox = qw.QDoubleSpinBox(self)
        #范围
        self.BSpinBox.setRange(0,255)
        #初始值
        self.BSpinBox.setValue(255)
        
        #Color Lable
        self.ColorLabel = qw.QLabel("Color :")
        self.resultLabel = qw.QLabel("255,255,255")
        
        #ok/cancel
        self.okButton = qw.QPushButton("&OK")
        self.cancelButton = qw.QPushButton("Cancel")
        
        
        #显示,竖直布局
        self.layout = qw.QGridLayout(self)
        
        self.layout.addWidget(self.RLabel, 0, 0)
        self.layout.addWidget(self.RSpinBox, 0, 1)
        
        self.layout.addWidget(self.GLabel, 1, 0)
        self.layout.addWidget(self.GSpinBox, 1, 1)
        
        self.layout.addWidget(self.BLabel, 2, 0)
        self.layout.addWidget(self.BSpinBox, 2, 1)
        
        
        self.layout.addWidget(self.okButton, 3, 0)
        self.layout.addWidget(self.cancelButton, 3, 1)
        
        self.okButton.clicked.connect(self.accept)
        self.cancelButton.clicked.connect(self.reject)
        
        
class SetPenWidthDlg(qw.QDialog):
    #重载构造函数
    def __init__(self,parent = None):
        #重载父类构造函数
        super().__init__(parent)
        #改变窗口显示的title
        self.setWindowTitle("SetPenWidth")
        
        
        #设置width的Label
        self.widthLabel = qw.QLabel("Width :")
        #width的数字框
        self.widthSpinBox = qw.QDoubleSpinBox(self)
        #范围
        self.widthSpinBox.setRange(1,30)
        #初始值
        self.widthSpinBox.setValue(3)
        
        #ok/cancel
        self.okButton = qw.QPushButton("&OK")
        self.cancelButton = qw.QPushButton("Cancel")
        
        
        #显示,竖直布局
        self.layout = qw.QGridLayout(self)
        
        self.layout.addWidget(self.widthLabel, 0, 0)
        self.layout.addWidget(self.widthSpinBox, 0, 1)
        self.layout.addWidget(self.okButton, 1, 0)
        self.layout.addWidget(self.cancelButton, 1, 1)
        
        self.okButton.clicked.connect(self.accept)
        self.cancelButton.clicked.connect(self.reject)
        
        
#新建一个主窗口程序,继承自QMainWindow
class myMainWindow(qw.QMainWindow):
    #重载构造函数
    def __init__(self,parent = None):
        #重载父类构造函数
        super().__init__(parent)
        #改变窗口显示的title
        self.setWindowTitle("PaintBrush")
        
        
        
        #加载数据
        self.initData()
        
        #加载画板
        self.myLabel = qw.QLabel()
        self.myPixmap = qg.QPixmap(qc.QSize(1000,800))
        self.myPixmap.fill(qc.Qt.white)
        self.myLabel.setPixmap(self.myPixmap)
        self.initView()
        
        
        #动作组
        #徒手画
        self.drawLineAction = qw.QAction(qg.QIcon("draw.png"), "&Draw.", self)
        self.drawLineAction.triggered.connect(self.drawLine)
        self.drawLineAction.setStatusTip("Draw.")
        
        #设置颜色
        self.setColorAction = qw.QAction(qg.QIcon("color.png"), "&set color.", self)
        self.setColorAction.triggered.connect(self.setColor)
        self.setColorAction.setStatusTip("set color.")
        #设置线宽
        self.setWidthAction = qw.QAction(qg.QIcon("width.png"), "&set width.", self)
        self.setWidthAction.triggered.connect(self.setWidth)
        self.setWidthAction.setStatusTip("set width.")
        #打开文件
        self.fileOpenAction = qw.QAction(qg.QIcon("open.png"), "&Open an image.", self)
        self.fileOpenAction.triggered.connect(self.openFile)
        self.fileOpenAction.setShortcut(qg.QKeySequence.Open)
        self.fileOpenAction.setStatusTip("Open an image.")
        #保存文件
        self.fileSaveAction = qw.QAction(qg.QIcon("save.png"), "&Save an image.", self)
        self.fileSaveAction.triggered.connect(self.saveFile)
        self.fileSaveAction.setShortcut(qg.QKeySequence.Save)
        self.fileSaveAction.setStatusTip("Save an image.")

        #清空
        self.ClearAction = qw.QAction(qg.QIcon("clear.png"), "new a paper.", self)
        self.ClearAction.triggered.connect(self.initView)
        self.ClearAction.setStatusTip("new a paper.")

        
        #工具栏
        self.fileToolbar = self.addToolBar("File")
        
        self.fileToolbar.addAction(self.drawLineAction)
        self.fileToolbar.addAction(self.setColorAction)
        self.fileToolbar.addAction(self.setWidthAction)
        self.fileToolbar.addAction(self.fileOpenAction)
        self.fileToolbar.addAction(self.fileSaveAction)
        self.fileToolbar.addAction(self.ClearAction)


        #状态栏
        #定义一个Label用来显示鼠标位置的更新
        self.statusLabel = qw.QLabel("Moun")
        #改变状态栏的Style
        self.statusLabel.setFrameStyle(qw.QFrame.StyledPanel|qw.QFrame.Sunken)
        #定义一个状态栏对象
        self.status = self.statusBar()
        #??
        self.status.setSizeGripEnabled(False)
        #用addPermanentWidget()在状态栏显示Label里的内容
        self.status.addPermanentWidget(self.statusLabel)
        #在状态栏显示信息,后一个参数为显示时间(毫秒)
        self.status.showMessage("Ready", 5000)
        
        
    def initView(self):
        #创建画板
        #设置界面的尺寸为__size
        self.Clear()
        self.myLabel = qw.QLabel()
        self.myPixmap = qg.QPixmap(qc.QSize(1000,800))
        self.myPixmap.fill(qc.Qt.white)
        self.myLabel.setPixmap(self.myPixmap)
        
        #把图显示在中间
        self.setCentralWidget(self.myLabel)
        
    def drawLine(self):
        self.pos_start = qc.QPoint(self.pos_start_X,self.pos_start_Y)
        self.pos_end = qc.QPoint(self.pos_end_X,self.pos_end_Y)
        self.painter = qg.QPainter(self.myPixmap)
        self.painter.setPen(qg.QPen(qg.QColor(self.red,self.green,self.blue),self.pen_width))
        self.painter.drawLine(self.pos_start,self.pos_end)
        self.myLabel.setPixmap(self.myPixmap)
        
    def setColor(self):
        self.dialog_color = SetPenColorDlg(self)
        #初始化上次保存的颜色值
        self.dialog_color.RSpinBox.setValue(self.red)
        self.dialog_color.GSpinBox.setValue(self.green)
        self.dialog_color.BSpinBox.setValue(self.blue)
        if self.dialog_color.exec_():
            #获取RSpinBox中更新的数据
            self.red = (int)(self.dialog_color.RSpinBox.value())
            #获取GSpinBox中更新的数据
            self.green = (int)(self.dialog_color.GSpinBox.value())
            #获取BComboBox中更新的数据
            self.blue = (int)(self.dialog_color.BSpinBox.value())
            #把更新结果显示在resultLabel中
            self.dialog_color.resultLabel.setText("{},{},{}".format(self.red, self.green, self.blue))
        
    def setWidth(self):
        self.dialog_width = SetPenWidthDlg(self)
        #初始化上次保存的颜色值
        self.dialog_width.widthSpinBox.setValue(self.pen_width)
        if self.dialog_width.exec_():
            self.pen_width = self.dialog_width.widthSpinBox.value()
            
    #警告当前图像未保存
    def okToContinue(self): 
        if self.dirty:
            reply = qw.QMessageBox.question(self,
                    "Image Changer - Unsaved Changes",
                    "Save unsaved changes?",
                    qw.QMessageBox.Yes|qw.QMessageBox.No|qw.QMessageBox.Cancel)
            if reply == qw.QMessageBox.Cancel:
                return False
            elif reply == qw.QMessageBox.Yes:
                return self.fileSaveAs()
        return True

    def openFile(self):
        if not self.okToContinue():
            return
        dir = (os.path.dirname(self.filename)
            if self.filename is not None else ".")
        formats = (["*.{}".format(format.data().decode("ascii").lower())
            for format in qg.QImageReader.supportedImageFormats()])
        fname = qw.QFileDialog.getOpenFileName(self,
            "Image Changer - Choose Image", dir,
            "Image files ({})".format(" ".join(formats)))
        if fname:
            print(1)
            self.loadFile(fname[0])
            print(2)
            #self.painter = QPainter(self.pixmap)
            print(3)
            #self.painter.setPen(self.pen)
            #self.updateFileMenu()
            print(self.filename)
            self.updatePainter()
            print(type(self.filename))
        
    def saveFile(self):
        if self.image.isNull():
              return True
        fname = self.filename if self.filename is not None else "."
        formats = (["*.{}".format(format.data().decode("ascii").lower())
              for format in qg.QImageWriter.supportedImageFormats()])
        fname = qw.QFileDialog.getSaveFileName(self,
              "Image Changer - Save Image", fname,
              "Image files ({})".format(" ".join(formats)))
        fname = fname[0]
        if fname:
              print(fname)
              if "." not in fname:
                    fname += ".png"
              self.addRecentFile(fname)
              self.filename = fname
        
              if self.image.save(self.filename, None):
                  self.updateStatus("Saved as {}".format(self.filename))
                  self.dirty = False
                  return True
              else:
                  self.updateStatus("Failed to save {}".format(
                                    self.filename))
                  return False                  
        return False

    def loadFile(self, fname=None):
        if fname is None:
              action = self.sender()
              if isinstance(action, qw.QAction):
                    fname = action.data()
                    if not self.okToContinue():
                        return
              else:
                    return
        if fname:
            self.filename = None
            image = qg.QImage(fname)
            if image.isNull():
                message = "Failed to read {}".format(fname)
            else:
                self.addRecentFile(fname)
                self.image = qg.QImage()
                self.image = image
                self.filename = fname
                self.showImage()
                self.dirty = False
                message = "Loaded {}".format(os.path.basename(fname))
                self.updateStatus(message)

    def addRecentFile(self, fname):
        if fname is None:
            return
        if fname not in self.recentFiles:                 
            if len(self.recentFiles) < 10:
                self.recentFiles = [fname] + self.recentFiles
            else:
                self.recentFiles = [fname] + self.recentFiles[:8]
                print(len(self.recentFiles))
                
    def updateFileMenu(self):
        self.fileMenu.clear()
        self.fileMenu.addAction(self.fileOpenAction)
        self.fileMenu.addAction(self.fileSaveAction)
        current = self.filename
        recentFiles = []
        print(self.recentFiles)
        for fname in self.recentFiles:
            if fname != current and qc.QFile.exists(fname):
                recentFiles.append(fname)
        if recentFiles:
            self.fileMenu.addSeparator()
            for i, fname in enumerate(recentFiles):
                action = qw.QAction(qg.QIcon("images/icon.png"),
                            "&{} {}".format(i + 1, qc.QFileInfo(
                            fname).fileName()), self)
                action.setData(fname)
                action.triggered.connect(lambda: self.loadFile(fname))
                self.fileMenu.addAction(action)
                
    def Clear(self):
        #清空画板
        self.myPixmap.fill(qc.Qt.white)
        self.update()
        self.dirty = False
        
    def initData(self):
        #参数
        self.pos_start_X = 0
        self.pos_start_Y = 0
        self.pos_end_X = 0
        self.pos_end_Y = 0
        self.red = 255
        self.green = 255
        self.blue = 255
        self.pen_width = 3
        self.dirty = False
        self.filename = None
        self.recentFiles = []
        #self.image = QImage()
        
        
        
    def mousePressEvent(self,event):
        print( "startx=",self.pos_start_X , " starty=",self.pos_start_Y)
        self.pos_start = event.pos()
        self.pos_start_X = event.pos().x()
        self.pos_start_Y = event.pos().y()


    def mouseMoveEvent(self,event):
        self.pos_end_X = event.pos().x()
        self.pos_end_Y = event.pos().y()
        self.drawLine()
        self.pos_start_X = event.pos().x()
        self.pos_start_Y = event.pos().y()
    
    def mouseReleaseEvent(self, event):
        print( "endx=",self.pos_end_X , " endy=",self.pos_end_Y)
        self.pos_end_X = event.pos().x()
        self.pos_end_Y = event.pos().y()
        self.drawLine()

    def showImage(self, percent=None):
        if self.image.isNull():
            return
        self.myPixmap = qg.QPixmap.fromImage(self.image)
        self.myLabel.setPixmap(self.myPixmap)
        
        
app = qw.QApplication(sys.argv)
form = myMainWindow()
#设定最小的程序窗口大小
form.setMinimumSize(800,800)
form.show()
app.exec_()

!!!!Interesting!!!!

你可能感兴趣的:(python)