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

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

作业描述

在这里插入图片描述

成果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全解python代码实现

全解代码截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全解代码

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!!!!

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值