当前位置: 首页 > news >正文

网站执行速度惠州行业网站设计方案

网站执行速度,惠州行业网站设计方案,淘宝网站建设违规吗,十大传媒公司一、 编辑器功能明确 允许用户加载图片、选择切割模式、对切割后的图片片段进行操作#xff08;如移动、复制、粘贴、删除等#xff09;#xff0c;并支持撤销和重做操作。 环境#xff1a;Py2.7 PyQt 4.11 二、导入模块介绍 sys: 用于访问与 Python 解释器强相关的变…一、 编辑器功能明确 允许用户加载图片、选择切割模式、对切割后的图片片段进行操作如移动、复制、粘贴、删除等并支持撤销和重做操作。 环境Py2.7  PyQt 4.11 二、导入模块介绍 sys: 用于访问与 Python 解释器强相关的变量和函数。 os: 提供操作系统相关功能如文件路径操作。 random: 用于生成随机数主要用于自动保存文件名。 json: 用于数据序列化和反序列化方便保存和加载编辑状态。 glob: 用于文件路径匹配例如检查自动保存文件是否存在。 PyQt4: 用于创建图形用户界面GUI。 三、构造函数分析 def __init__(self):super(MainWindow, self).__init__() # 调用父类的构造函数self.setWindowTitle(Picture Cutting Editor) # 设置窗口标题self.undoStack QtGui.QUndoStack(self) # 创建一个QUndoStack对象用于撤销和重做self.initUI() # 初始化界面self.initSignal() # 初始化信号连接self.image QtGui.QPixmap() # 初始化图片对象self.center() # 居中显示窗口self.xx 5self.yy 5self._m_cut_type_str # 初始化切割模式字符串self.curFile # 当前文件路径self.locationList [] # 存储图片位置的列表self.cuttingWidgetList [] # 存储切割小部件的列表self.posList [] # 存储位置信息的列表self.location_pixmap_dict {} # 存储位置和图片的字典self.data [...] # 存储数据的列表self.auto_save_data [...] # 自动保存数据self.savepath_autopath_dict {} # 保存路径和自动保存路径的连接字典self.autoName # 自动保存文件名self.undoStack: 用于支持撤销和重做操作。 self.image: 存储当前加载的图片。 self.data: 存储编辑状态的数据方便保存和加载。 self.auto_save_data: 存储自动保存的数据防止数据丢失。 四、扩展的类 QtGui.QUndoStack(self) # 创建一个QUndoStack对象用于撤销和重做QtGui.QPixmap() # 存储当前加载的图片QtGui.QPixmap()可以从文件、资源或内存中加载图像并可以用于显示图像QtGui.QFileDialog.getOpenFileName: 打开文件选择对话框让用户选择图片文件。 五、小技巧 1. 符号 fileMenu menubar.addMenu(u文件(F)) # 添加“文件”菜单 # 在 PyQt 中菜单项或按钮的文本中添加 符号是一种特殊的语法用于定义快捷键Accelerator。 符号后面的字母会变成该菜单项或按钮的快捷键 2. undoStack undoStack的宏操作(相当于数据库中的事务将多个操作绑定在一起一并撤销 有了undoStack来实现指令的撤销和恢复真的太容易了。 undoStack.beginMacro(bind1)开始一个宏操作允许将多个命令组合在一起。 undoStack.push(self.cmd1)将命令推入撤销栈可以推多个命令进入栈中。 undoStack.endMacro()结束宏操作将所有推入的命令组合为一个。3. 创建一个新的编辑窗口MainWindow 的实例并将其显示在屏幕上QT多窗口模板: def newImageFile(self):newWindow MainWindow() # 创建一个新的 MainWindow 实例# 将新窗口实例添加到 windowList 中以便程序可以统一管理所有打开的窗口。(这是在做商城大作业时的收获无论是红点对象还是复用滚动框中的滚动对象都建议使用一个列表保存起来。1. 避免重复创建减少性能消耗 2.统一管理MainWindow.windowList.append(newWindow) # 将新窗口添加到窗口列表中newWindow.move(self.x() 50, self.y() 50) # 设置新窗口的位置newWindow.show() # 显示新窗口4. Py2获取当前年月日时分秒并生成一个年-月-日-时-分-秒的字符串 # 案例根据当前时间生成新的自动保存文件名from datetime import datetime# 获取当前时间now datetime.now()# 格式化为 年-月-日-时-分-秒 的字符串formatted_time now.strftime(%Y-%m-%d-%H-%M-%S)autoName auto_save/ formatted_time .json5. Py2 解析Json文件 with open(fileName) as fp:load_data json.load(fp) # 使用 json.load 从文件中加载 JSON 数据并将其存储到 self.data 中。 六、图片切割编辑器案例  # -*- coding: utf-8 -*- import sys import os import random import json import glob from PyQt4 import QtGui from PyQt4 import QtCore#定义主窗口类 class MainWindow(QtGui.QMainWindow):windowList []#用于存储所有打开的窗口def __init__(self):super(MainWindow, self).__init__() #调用父类的构造函数self.setWindowTitle(Picture Cutting Editor) # 设置窗口标题self.undoStack QtGui.QUndoStack(self) # 创建一个QUndoStack对象用于撤销和重做self.initUI() # 初始化界面设置菜单、工具栏等。self.initSignal() # 初始化信号连接绑定事件处理函数。self.image QtGui.QPixmap() # 存储当前加载的图片QtGui.QPixmap()可以从文件、资源或内存中加载图像并可以用于显示图像self.center() # 居中显示窗口self.xx 5self.yy 5 # 初始化切割网格的行列数默认为5x5。self._m_cut_type_str # 初始化切割模式字符串用于描述当前的切割方式。self.curFile # 当前编辑的文件路径。self.locationList [] # 存储图片片段的位置信息。self.cuttingWidgetList [] # 存储切割后的小部件如图片片段。self.posList [] # 存储图片片段的位置信息。self.location_pixmap_dict {} # 存储位置与图片片段的映射关系。self.data [ # 存储编辑状态的数据方便保存和加载。{path: [], # 存储文件路径type: [], # 存储切割类型location_list : [], # 存储位置列表square_list : [], # 存储切割小部件列表pos_list:[], # 存储位置信息列表}]self.auto_save_data [ # 存储自动保存的数据防止数据丢失。{autoSavePath:[], # 自动保存路径列表connectDict:{}, # 自动保存路径和文件路径的连接字典}]self.savepath_autopath_dict {} # 保存路径和自动保存路径的连接字典self.autoName # 自动保存文件名def init(self):# 初始化、清空数据结构重置状态self.locationList [] # 清空图片位置信息列表self.cuttingWidgetList [] # 清空切割小部件列表self.posList [] # 清空位置信息列表self.location_pixmap_dict {} # 清空位置与图片片段的映射字典self.data [ # 重置存储编辑状态的数据结构{path:[], # 清空文件路径列表type:[], # 清空切割类型列表location_list:[], # 清空位置列表square_list:[], # 清空切割小部件列表pos_list:[], # 清空位置信息列表}]self.auto_save_data [ # 重置自动保存数据结构{autoSavePath:[], # 清空自动保存路径列表connectDict:{} # 清空自动保存路径与文件路径的映射字典}]self.savepath_autopath_dict {} # 清空保存路径与自动保存路径的映射字典self.piecesList.clear() # 清空图片片段列表组件self.piecesList.locationList [] # 清空图片片段位置列表self.picWidget.cuttingWidgetList [] # 清空图片编辑区域的切割小部件列表self.picWidget.pixmapList [] # 清空图片编辑区域的图片片段列表self.picWidget.posList [] # 清空图片编辑区域的位置信息列表self.picWidget.update() # 更新图片编辑区域的显示# 初始化用户界面UIdef initUI(self):self.statusBar() # 创建状态栏用于显示状态信息self.setFocus() # 设置窗口获取焦点, 确保窗口获取焦点。self.setWidgets() # 调用setWidgets方法设置主窗口的中心部件# 创建菜单栏和导航栏的选项openFile QtGui.QAction(QtGui.QIcon(resources/openFile.png), Open, self)openFile.setShortcut(CtrlO) # 设置快捷键openFile.setStatusTip(Open new file) # 设置状态栏提示self.connect(openFile, QtCore.SIGNAL(triggered()), self.openFile) # 将动作与槽函数连接newFile QtGui.QAction(QtGui.QIcon(resources/new.png), New, self)newFile.setShortcut(CtrlN)newFile.setStatusTip(New file)self.connect(newFile, QtCore.SIGNAL(triggered()), self.newImageFile)# 导入图片选择网格大小importImage QtGui.QAction(Import Image, self)importImage.setStatusTip(Import image)self.connect(importImage, QtCore.SIGNAL(triggered()), self.showDialog)saveFile QtGui.QAction(QtGui.QIcon(resources/save.png), Save, self)saveFile.setShortcut(CtrlS)saveFile.setStatusTip(Save file)self.connect(saveFile, QtCore.SIGNAL(triggered()), self.saveImageFile)save_as QtGui.QAction(QtGui.QIcon(resources/save_as.png), Save As, self)save_as.setShortcut(CtrlShiftS)save_as.setStatusTip(Save file as)self.connect(save_as, QtCore.SIGNAL(triggered()), self.saveImageAs)undo QtGui.QAction(QtGui.QIcon(resources/Undo.png), Undo, self)undo.setShortcut(CtrlZ)undo.setStatusTip(Undo)self.connect(undo, QtCore.SIGNAL(triggered()), self.undoImage)redo QtGui.QAction(QtGui.QIcon(resources/Redo.png), Redo, self)redo.setShortcut(CtrlY)redo.setStatusTip(Redo)self.connect(redo, QtCore.SIGNAL(triggered()), self.redoImage)cut QtGui.QAction(QtGui.QIcon(resources/cut.png), Cut, self)cut.setShortcut(CtrlX)cut.setStatusTip(Cut)self.connect(cut, QtCore.SIGNAL(triggered()), self.cutImage)copyImage QtGui.QAction(QtGui.QIcon(resources/copy.png),Copy,self)copyImage.setShortcut(CtrlC)copyImage.setStatusTip(Copy)self.connect(copyImage, QtCore.SIGNAL(triggered()),self.copyImage)pasteImage QtGui.QAction(QtGui.QIcon(resources/paste.png), Paste, self)pasteImage.setShortcut(CtrlV)pasteImage.setStatusTip(Paste)self.connect(pasteImage,QtCore.SIGNAL(triggered()),self.pasteImage)deleteImage QtGui.QAction(QtGui.QIcon(resources/delete.png), Delete, self)deleteImage.setShortcut(Delete)deleteImage.setStatusTip(delete)self.connect(deleteImage,QtCore.SIGNAL(triggered()), self.deleteImage)# 创建菜单栏menubar self.menuBar() # 获取窗口的菜单栏# 文件fileMenu menubar.addMenu(u文件(F)) # 添加“文件”菜单# 在 PyQt 中菜单项或按钮的文本中添加 符号是一种特殊的语法用于定义快捷键Accelerator。 符号后面的字母会变成该菜单项或按钮的快捷键fileMenu.addAction(openFile) # 添加“打开”选项fileMenu.addAction(newFile)fileMenu.addAction(importImage)fileMenu.addAction(saveFile)fileMenu.addAction(save_as)# 编辑editMenu menubar.addMenu(u编辑(E)) # 添加“编辑”菜单editMenu.addAction(undo) # 添加“撤销”选项editMenu.addAction(redo)editMenu.addAction(cut)editMenu.addAction(copyImage)editMenu.addAction(pasteImage)# 网格设置网格大小 和 长宽# 创建工具栏self.Toolbar self.addToolBar(u工具栏(T)) # 添加工具栏self.Toolbar.addAction(undo)self.Toolbar.addAction(redo)self.Toolbar.addAction(openFile) # 添加“打开”按钮self.Toolbar.addAction(newFile)self.Toolbar.addAction(saveFile)self.Toolbar.addAction(save_as)self.Toolbar.addAction(cut)self.Toolbar.addAction(copyImage)self.Toolbar.addAction(pasteImage)self.Toolbar.addAction(deleteImage)# 使用 self.setGeometry() 设置窗口的初始位置和大小确保窗口在屏幕上合适的位置显示。self.setGeometry(300, 300, 1024, 768) # 设置窗口的位置和大小# 参数解释窗口左上角的X坐标、Y坐标窗口宽度、窗口高度# 初始化信号连接 将自定义信号连接到对应的槽函数处理拖拽、保存等操作。# 信号与槽是 PyQt 中实现组件间通信的核心机制通过这种方式可以将组件的事件如按钮点击、信号发射与相应的处理函数槽函数绑定起来从而实现交互逻辑。def initSignal(self):# piecesList: 自定义组件用于显示图片片段的列表。self.piecesList.upSignal.connect(self.upListWidget) # 自定义信号。self.piecesList.downSignal.connect(self.downListWidget) # 自定义信号。self.piecesList.saveSignal.connect(self.curSave) # 自定义信号。# picWidget: 自定义组件用于显示和编辑图片的区域。self.picWidget.upSignal.connect(self.upWidget) # 自定义信号。self.picWidget.downSignal.connect(self.downWidget)self.picWidget.saveSignal.connect(self.curSave)# 处理用户从列表中拖拽出图片片段的操作。# 使用 QUndoStack 的宏功能将“移除”和“插入”两个操作组合在一起以便用户可以通过一次撤销操作撤销整个拖拽过程。def upListWidget(self):item self.piecesList.currentItem() # 获取当前选中的图片片段row self.piecesList.row(item) # 获取该项在列表中的行号commandCommandDragFromListWidget(self.piecesList,item,row) # 自定义的撤销命令类用于处理从列表中拖拽图片片段的操作。self.cmd command # 将命令对象存储在类变量中供后续使用# 处理用户将图片片段拖拽回列表的操作。def downListWidget(self):command CommandDragToListWidget(self.piecesList) # 一个自定义的撤销命令类用于处理将图片片段拖拽到列表中的操作。它包含将图片片段插入到新位置的逻辑。self.undoStack.beginMacro(bind2) # 开始一个宏操作允许将多个命令组合在一起。这样用户可以通过一次撤销操作撤销整个宏操作而不是逐个撤销每个命令。self.undoStack.push(self.cmd) # 将之前在 upListWidget 中创建的命令推入撤销栈。这个命令表示从列表中移除图片片段的操作。self.undoStack.push(command) # 将当前命令表示将图片片段插入到列表的操作推入撤销栈。self.undoStack.endMacro( ) # 结束宏操作将所有推入的命令组合为一个完整的操作。# 处理用户从图片编辑区域中拖拽出图片片段的操作。def upWidget(self):command CommandDragFromWidget(self.picWidget) # 一个自定义的撤销命令类用于处理从图片编辑区域picWidget中拖拽出图片片段的操作。self.cmd command # 将创建的命令对象存储在类变量 self.cmd 中以便后续的 downWidget 方法可以使用它。# 处理用户将图片片段拖拽回图片编辑区域的操作。def downWidget(self):command CommandDragToWidget(self.picWidget) # 自定义的撤销命令类用于处理将图片片段拖拽到图片编辑区域picWidget中的操作。self.undoStack.beginMacro(bind1) # 开始一个宏操作允许将多个命令组合在一起。self.undoStack.push(self.cmd) # 将之前在 upWidget 中创建的命令推入撤销栈。self.undoStack.push(command) # 将当前命令表示将图片片段插入到图片编辑区域的操作推入撤销栈。self.undoStack.endMacro() # 结束宏操作将所有推入的命令组合为一个完整的操作。# 实现了一个对话框用于让用户选择图片的切割模式def showDialog(self): self.dialog QtGui.QDialog() # 创建一个对话框窗口label QtGui.QLabel(u请选择切割模式, self.dialog) # 创建一个标签提示用户选择切割模式combo QtGui.QComboBox(self.dialog) # 创建一个下拉组合框用于选择切割模式combo.addItem(8 * 8) # 向组合框中添加“8 * 8”选项combo.addItem(8 * 4)label.move(50, 30) # 设置标签的位置combo.move(50, 50) # 设置组合框的位置self.dialog.setVisible(True) # 显示对话框# 将下拉框的选项连接到信号与槽self.connect(combo, QtCore.SIGNAL(activated(QString)), self.onActivated) # 根据选择设置切割方式self.connect(combo, QtCore.SIGNAL(activated(QString)), self.openImage) # 加载切割后的图片def onActivated(self, text):if text 8 * 8: # 如果用户选择了“8 * 8”则设置 self.xx 和 self.yy 为 8表示切割图片为 8x8 张。self.xx 8self.yy 8self._m_cut_type_str 8 * 8 # 选择的模式存储在 self._m_cut_type_str 中用于后续的逻辑处理。elif text 8 * 4:self.xx 8self.yy 4self._m_cut_type_str 8 * 4self.dialog.setVisible(False) # 关闭对话框。def openImage(self): # 如果用户选择了文件autoName auto_save/ str(random.randint(1, 1000)).json # 生成随机的自动保存文件名self.autoName autoName # 将自动生成的文件名存储在类变量中# QtGui.QFileDialog.getOpenFileName: 打开文件选择对话框让用户选择图片文件。filename QtGui.QFileDialog.getOpenFileName(self, Open Image, resources, Image Files (*.png *.jpg *.bmp))if filename : # 调用loadImage方法加载图片并初始化编辑状态self.loadImage(filename) # self.loadImage: 加载图片并初始化编辑状态。def loadImage(self, filename):self.init() # 初始化或重置程序状态清空之前的编辑数据self.undoStack.clear() # 清空撤销栈移除之前的撤销和重做记录image QtGui.QPixmap(filename) # 加载图像文件 QPixmap 是一个轻量级的图像处理类主要用于在屏幕上显示图像。self.image image # 将加载的图像存储到类变量中self.setupPic(self.xx, self.yy) # self.setupPic: 根据切割模式如 8x8 或 8x4对图片进行切割并初始化显示。self.data[0][path].append(str(filename)) # 将图片路径保存起来# 创建一个新的图片编辑窗口MainWindow 的实例并将其显示在屏幕上。def newImageFile(self):newWindow MainWindow() # 创建一个新的 MainWindow 实例# 将新窗口实例添加到 windowList 中以便程序可以统一管理所有打开的窗口。MainWindow.windowList.append(newWindow) # 将新窗口添加到窗口列表中newWindow.move(self.x() 50, self.y() 50) # 设置新窗口的位置newWindow.show() # 显示新窗口def openFile(self):# 检查自动保存文件if glob.glob(auto_save/autosave.json)! []: # 使用 glob.glob 检查是否存在自动保存文件autosave.jsonwith open(auto_save/autosave.json) as fp:load_data json.load(fp)self.auto_save_data load_data # 如果存在加载该文件并将其内容存储到 self.auto_save_data 中。# 根据当前时间生成新的自动保存文件名from datetime import datetime# 获取当前时间now datetime.now()# 格式化为 年-月-日-时-分-秒 的字符串formatted_time now.strftime(%Y-%m-%d-%H-%M-%S)autoName auto_save/ formatted_time .jsonself.autoName autoName# 打开文件选择对话框fileName QtGui.QFileDialog.getOpenFileName(self, directorysave) # 使用 QtGui.QFileDialog.getOpenFileName 打开文件选择对话框让用户选择一个保存的编辑状态文件。if fileName:# 如果选择的文件在自动保存数据中存在对应的自动保存路径弹出一个消息框询问用户是否加载自动保存的数据。# 如果用户选择“是”则加载自动保存的数据并覆盖原文件。if self.auto_save_data[0][connectDict].has_key(str(fileName)):rep QtGui.QMessageBox.question(self, u存在上一局游戏, u该图片被打开过是否加载上一局游戏?, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)if rep QtGui.QMessageBox.Yes:with open(self.auto_save_data[0][connectDict][str(fileName)]) as fpp:data json.load(fpp)with open(fileName,w)as fp:json.dump(data,fp,indent2)self.loadFile(fileName) # 加载文件def loadFile(self,fileName):# 初始化状态, 清空当前的编辑状态和撤销栈。self.init()self.undoStack.clear()# 加载用户选择的文件内容并将其存储到 self.data 中。with open(fileName) as fp:load_data json.load(fp) # 使用 json.load 从文件中加载 JSON 数据并将其存储到 self.data 中。self.data load_dataself.image QtGui.QPixmap(QtCore.QString(self.data[0][path][0])) # 使用 QtGui.QPixmap 加载图片文件路径从 self.data 中获取。QtCore.QString 是 PyQt4 中用于处理字符串的类# 根据保存的切割模式设置 self.xx 和 self.yy。if self.data[0][type][0] 8 * 8:self.xx8self.yy8if self.data[0][type][0]8 * 4:self.xx 8self.yy 4# 切图: 先将图片并缩放到固定大小400x400 再切割图片# 使用 scaled 方法将图片缩放到固定大小400x400忽略纵横比并使用平滑变换以获得更好的视觉效果。size min(self.image.width(), self.image.height())self.image self.image.copy((self.image.width()-size)/2, (self.image.height() - size)/2, size, size).scaled(400, 400, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)self.piecesList.clear() # 清空图片片段列表移除所有之前的图片片段。# 根据切割模式self.xx 和 self.yy将图片分割成多个片段。每个片段的大小为 400 / self.xx 和 400 / self.yy。将每个片段存储到 self.location_pixmap_dict 中键为片段的位置如 (1, 1) 表示左上角的片段。for y in range(self.xx):for x in range(self.yy):pieceImage self.image.copy(x*400/self.yy, y*400/self.xx, 400/self.xx, 400/self.yy)self.location_pixmap_dict[(x1, y1)] pieceImage# 加载数据: 从 self.data 中恢复位置列表、切割小部件列表和位置信息列表。locationList self.data[0][location_list]print len(self.data[0][location_list])cuttingWidgetList self.data[0][square_list]posList self.data[0][pos_list]# 遍历位置列表将每个位置恢复为 QtCore.QPoint 对象并存储到 self.locationList 中。# QtCore.QPoint 是 PyQt4 中的一个类用于表示二维空间中的一个点。它由两个主要属性组成x 和 y分别表示点的横坐标和纵坐标。for i in range(len(locationList)):x locationList[i][0]y locationList[i][1]self.locationList.append(QtCore.QPoint(x, y))# 遍历切割小部件列表将每个小部件恢复为 QtCore.QRect 对象并存储到 self.cuttingWidgetList 中。# QtCore.QRect 是 PyQt4 中的一个类用于表示一个矩形区域。它通常用于定义控件的位置和大小或者在绘图和布局管理中指定一个矩形范围。for j in range(len(cuttingWidgetList)):x cuttingWidgetList[j][0]y cuttingWidgetList[j][1]width cuttingWidgetList[j][2]height cuttingWidgetList[j][3]self.cuttingWidgetList.append(QtCore.QRect(x, y, width, height))# 遍历位置信息列表将每个位置恢复为 QtCore.QPoint 对象并存储到 self.posList 中。for k in range(len(posList)):x posList[k][0]y posList[k][1]self.posList.append(QtCore.QPoint(x, y))# 清空图片片段列表并根据恢复的数据重新添加图片片段。# 遍历位置列表根据每个位置从 self.location_pixmap_dict 中获取对应的图片片段并将其添加到图片片段列表中。cnt 0for location in self.locationList:pixmap self.location_pixmap_dict[(location.x(), location.y())]self.piecesList.addPiece(pixmap, location)# 根据位置信息列表生成图片片段列表。pixmapList []for pos in self.posList:pixmap_r self.location_pixmap_dict[(pos.x(), pos.y())]pixmapList.append(pixmap_r)# 设置图片编辑区域# 将恢复的切割小部件列表、位置信息列表和图片片段列表设置到图片编辑区域。self.picWidget.cuttingWidgetList self.cuttingWidgetListself.picWidget.posList self.posListself.picWidget.pixmapList pixmapListself.picWidget.update() # 调用 update() 方法重新绘制图片编辑区域。# 调用 setCurrentFile 方法设置当前文件路径并更新窗口标题。self.setCurrentFile(fileName)def saveImageFile(self):# 如果 self.curFile当前文件路径不为空调用 self.saveFile(self.curFile) 方法将当前编辑状态保存到已有的文件中。if self.curFile:return self.saveFile(self.curFile)return self.saveImageAs()def saveImageAs(self):# 使用 QtGui.QFileDialog.getSaveFileName 打开文件保存对话框提示用户选择保存路径。fileName QtGui.QFileDialog.getSaveFileName(self, directorysave)# 如果用户选择了文件路径fileName 不为空调用 self.saveFile(fileName) 方法保存文件。if fileName:return self.saveFile(fileName)return Falsedef saveFile(self,fileName):# 清空保存的数据结构准备重新填充当前编辑状态。self.data[0][location_list] []self.data[0][square_list] []self.data[0][pos_list] []# 遍历 self.locationList将每个位置QPoint的坐标保存到 self.data[0][location_list] 中。for i in range(len(self.locationList)):self.data[0][location_list].append([self.locationList[i].x(), self.locationList[i].y()])# 遍历 self.cuttingWidgetList将每个小部件QRect的坐标和尺寸保存到 self.data[0][square_list] 中。for j in range(len(self.cuttingWidgetList)):self.data[0][square_list].append([self.cuttingWidgetList[j].x(), self.cuttingWidgetList[j].y(), self.cuttingWidgetList[j].width(), self.cuttingWidgetList[j].height()])# 遍历 self.posList将每个位置的坐标保存到 self.data[0][pos_list] 中。for k in range(len(self.posList)):self.data[0][ pos_list].append([self.posList[k].x(), self.posList[k].y()])# 如果 self.data[0][type] 为空添加当前切割模式self._m_cut_type_str。if self.data[0][type] []:self.data[0][type].append(self._m_cut_type_str)else :self.data[0][type][0] self._m_cut_type_str # 如果不为空更新当前切割模式。# 使用 json.dump 将当前编辑状态self.data序列化为 JSON 格式并保存到指定文件中。with open(fileName,w) as fp:json.dump(self.data, fp, indent2)# 调用 setCurrentFile 方法更新当前文件路径并刷新窗口标题。self.setCurrentFile(fileName)# 返回 True表示保存操作成功。return Truedef setCurrentFile(self,fileName):self.curFile fileNameif self.curFile:shownName self.strippedName(self.curFile) # 如果 self.curFile 不为空调用 self.strippedName 方法获取文件名不包含路径。else:shownName untitled.json # 如果为空设置默认文件名为 untitled.json。# 更新窗口标题显示当前文件名和应用程序名称。self.setWindowTitle(%s[*] - Application % shownName)def strippedName(self, fullFileName):return QtCore.QFileInfo(fullFileName).fileName() # 使用 QtCore.QFileInfo 获取文件名不包含路径。fullFileName 是完整的文件路径fileName() 方法返回文件名部分。# 实现自动保存功能# 用于触发当前编辑状态的自动保存def curSave(self):# 从 piecesList 和 picWidget 中获取当前的编辑状态位置列表、切割小部件列表、位置信息列表并更新到主窗口类的属性中。self.locationList self.piecesList.locationListself.cuttingWidgetList self.picWidget.cuttingWidgetListself.posList self.picWidget.posList# 如果当前文件路径self.curFile存在调用 autoSave 方法将当前编辑状态保存到自动保存文件中文件名由 self.autoName 指定。if self.curFile:self.autoSave(self.autoName)# 具体执行保存操作包括管理自动保存文件的路径列表、保存当前编辑状态到文件中以及更新自动保存的元数据。def autoSave(self, autoName):# 如果自动保存路径列表超过 5 个文件删除最早的自动保存文件列表的第一个元素并从列表中移除该路径。if len(self.auto_save_data[0][autoSavePath]) 5:os.remove(self.auto_save_data[0][autoSavePath][0])del self.auto_save_data[0][autoSavePath][0]# 如果新的自动保存文件名autoName不在路径列表中且列表长度小于等于 5直接将新路径添加到列表中。# 如果列表长度超过 5删除最早的路径并添加新路径。if autoName not in self.auto_save_data[0][autoSavePath]:if len(self.auto_save_data[0][autoSavePath]) 5:self.auto_save_data[0][autoSavePath].append(autoName)elif len(self.auto_save_data[0][autoSavePath]) 5:os.remove(self.auto_save_data[0][autoSavePath][0])del self.auto_save_data[0][autoSavePath][0]self.auto_save_data[0][autoSavePath].append(autoName)# 将当前的编辑状态位置列表、切割小部件列表、位置信息列表转换为简单的列表格式便于序列化。location []square []pos []for i in range(len(self.locationList)):location.append([self.locationList[i].x(), self.locationList[i].y()])for j in range(len(self.cuttingWidgetList)):square.append([self.cuttingWidgetList[j].x(), self.cuttingWidgetList[j].y(), self.cuttingWidgetList[j].width(), self.cuttingWidgetList[j].height()])for k in range(len(self.posList)):pos.append([self.posList[k].x(), self.posList[k].y()])# 更新 self.data 中的编辑状态数据包括位置列表、切割小部件列表、位置信息列表和切割模式。 self.data[0][location_list] locationself.data[0][square_list] squareself.data[0][pos_list] posif self.data[0][type] []:self.data[0][type].append(self._m_cut_type_str)else:self.data[0][type][0] self._m_cut_type_str# 如果当前文件路径存在将自动保存路径与当前文件路径关联起来便于后续恢复。if self.curFile:self.savepath_autopath_dict[str(self.curFile)] autoNameself.auto_save_data[0][connectDict] self.savepath_autopath_dict# 将当前编辑状态self.data序列化为 JSON 格式并保存到指定的自动保存文件中。with open(autoName,w) as fp:json.dump(self.data, fp, indent2)# 将自动保存路径列表和其他元数据self.auto_save_data保存到 autosave.json 文件中。with open(auto_save/autosave.json,w) as fpp:json.dump(self.auto_save_data, fpp, indent2)# 调用 QUndoStack 的 undo() 方法执行最近一次的撤销操作。def undoImage(self):self.undoStack.undo()# 调用 QUndoStack 的 redo() 方法执行最近一次的重做操作。def redoImage(self):self.undoStack.redo()def cutImage(self):item self.piecesList.currentItem() # 从 piecesList图片片段列表中获取当前选中的项。self.copyImage() # 调用 copyImage 方法将当前选中的图片片段复制到剪贴板。command CommandCut(self.piecesList, item) # 创建一个 CommandCut 对象这是一个自定义的命令类用于实现剪切操作的逻辑。self.undoStack.push(command) # 将剪切命令推入 QUndoStack以便支持撤销操作。def copyImage(self):item self.piecesList.currentItem() # 获取当前选中的图片片段项itemData QtCore.QByteArray() # 创建一个 QDataStream 对象用于序列化数据dataStream QtCore.QDataStream(itemData, QtCore.QIODevice.WriteOnly) # 创建一个 QDataStream 对象用于序列化数据pixmap QtGui.QPixmap(item.data(QtCore.Qt.UserRole)) # 从选中的项中获取 QPixmap 对象location item.data(QtCore.Qt.UserRole 1).toPoint() # 从选中的项中获取位置信息QPointprint -----copy-----print locationdataStream pixmap location # 将 QPixmap 和位置信息序列化到 QByteArray 中mimeData QtCore.QMimeData() # 创建一个 QMimeData 对象用于存储剪贴板数据mimeData.setData(image/pic, itemData) # 将 QByteArray 数据存储到 QMimeData 中指定 MIME 类型为 image/picself.clipBoard QtGui.QApplication.clipboard() # 获取系统剪贴板self.clipBoard.setMimeData(mimeData) # 将 QMimeData 设置到剪贴板def pasteImage(self):picDataself.clipBoard.mimeData().data(image/pic) # 从剪贴板获取 MIME 类型为 image/pic 的数据dataStream QtCore.QDataStream(picData, QtCore.QIODevice.ReadOnly) # 创建一个 QDataStream 对象用于反序列化数据pixmap QtGui.QPixmap() # 创建一个 QPixmap 对象用于存储图片location QtCore.QPoint() # 创建一个 QPoint 对象用于存储位置信息dataStream pixmap location # 从数据流中反序列化 QPixmap 和 QPointcommand CommandPaste(self.piecesList, pixmap, location) # 创建一个粘贴命令对象self.undoStack.push(command) # 将粘贴命令推入撤销栈def deleteImage(self):item self.piecesList.currentItem() # 获取当前选中的图片片段项command CommandDelete(self.piecesList, item) # 创建一个删除命令对象self.undoStack.push(command) # 将删除命令推入撤销栈# 将图片缩放到固定大小400*400px, 然后进行切割再保存到图片片段列表中去def setupPic(self, xx, yy):# 将图片缩放到固定大小400*400pxsize min(self.image.width(), self.image.height())self.image self.image.copy((self.image.width() - size)/2, (self.image.height() - size)/2, size, size).scaled(400, 400, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)# 清空 piecesList移除所有之前的图片片段。self.piecesList.clear()# 然后进行切割再保存到图片片段列表中去for x in range(xx):for y in range(yy):pieceImage self.image.copy(x*400/self.xx, y*400/self.yy, 400/self.xx, 400/self.yy)self.location_pixmap_dict[(x 1, y 1)] pieceImageself.piecesList.addPiece(pieceImage, QtCore.QPoint(x 1, y 1))# 初始化主窗口的布局和组件def setWidgets(self):frame QtGui.QFrame() # 创建一个框架组件frameLayout QtGui.QHBoxLayout(frame) # 创建一个水平布局管理器self.piecesList PicturesList() # 创建一个图片片段列表组件self.picWidgetPictureWidget() # 创建一个图片编辑区域组件frameLayout.addWidget(self.piecesList) # 将图片片段列表组件添加到布局中frameLayout.addWidget(self.picWidget) # 将图片编辑区域组件添加到布局中self.setCentralWidget(frame) # 将框架组件设置为主窗口的中心部件# 处理窗口关闭事件退出游戏def closeEvent(self, event):reply QtGui.QMessageBox.question(self, u退出游戏, u是否退出游戏?, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) # 使用 QtGui.QMessageBox.question 弹出一个消息框提示用户是否确定退出。reply 变量存储用户的选择结果。if reply QtGui.QMessageBox.Yes:event.accept()else:event.ignore()# 窗口居中显示def center(self):screen QtGui.QDesktopWidget().screenGeometry() # 获取屏幕的几何信息size self.geometry() # 获取窗口的几何信息self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) # 将窗口移动到屏幕中央# PicturesList 类继承自 QtGui.QListWidget。它用于显示和管理图片片段的列表并支持拖拽操作。 class PicturesList(QtGui.QListWidget):upSignal QtCore.pyqtSignal() # 自定义信号downSignal QtCore.pyqtSignal()saveSignal QtCore.pyqtSignal()def __init__(self, parentNone):super(PicturesList,self).__init__(parent) # 调用父类的构造函数self.setDragEnabled(True) # 启用拖拽功能self.setViewMode(QtGui.QListView.IconMode) # 设置视图模式为图标模式self.setIconSize(QtCore.QSize(60, 60)) # 设置图标大小为60x60 像素self.setSpacing(10) # 设置图标之间的间距为 10 像素self.setAcceptDrops(True) # 启用接受拖拽操作self.setDropIndicatorShown(True) # 显示拖拽指示器self.pixmapList [] # 存储图片片段存储切图self.locationList[] # 存储位置信息# 添加图片到左侧的资源列表中def addPiece(self,pixmap, location):self.pixmapList.append(pixmap) # 将图片片段添加到 pixmapList 中self.locationList.append(location) # 将位置信息添加到 locationList 中pieceItem QtGui.QListWidgetItem(self) # 创建一个 QListWidgetItem 对象pieceItem.setIcon(QtGui.QIcon(pixmap)) # 使用 QIcon 将传入的 pixmap 设置为列表项的图标。pieceItem.setData(QtCore.Qt.UserRole, pixmap) # 将 QPixmap 对象存储为用户数据pieceItem.setData(QtCore.Qt.UserRole 1, location) # 将位置信息存储为用户数据pieceItem.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled) # 设置列表项的标志使其可启用、可选择、可拖拽# 可启用ItemIsEnabled用户可以与之交互。# 可选择ItemIsSelectable用户可以选中该条目。# 可拖拽ItemIsDragEnabled用户可以拖拽该条目。def delete_piece(self, item):self.takeItem(self.row(item)) # 从 PicturesList 中移除指定的图片片段。def startDrag(self, supportedActions):item self.currentItem() # 获取QListWidget当前选中的 QListWidgetItem 对象。itemData QtCore.QByteArray() # 创建一个 QByteArray 对象用于存储序列化后的数据。dataStream QtCore.QDataStream(itemData, QtCore.QIODevice.WriteOnly) # 创建一个 QDataStream 对象用于将数据写入 QByteArray。# 从列表项中获取存储的 QPixmap 对象和位置信息QPoint。self.pixmap QtGui.QPixmap(item.data(QtCore.Qt.UserRole))self.location item.data(QtCore.Qt.UserRole 1).toPoint()# 使用 QDataStream 将 QPixmap 和 QPoint 序列化到 QByteArray 中。dataStream self.pixmap self.location# 创建一个 QMimeData 对象用于存储拖拽数据。mimeData QtCore.QMimeData()mimeData.setData(image/pic, itemData) # 将序列化后的数据存储到 QMimeData 中指定 MIME 类型为 image/pic。# 创建一个 QDrag 对象用于处理拖拽操作。# 并设置拖拽对象的 MIME 数据、热点位置拖拽的起始点和拖拽时显示的图标。drag QtGui.QDrag(self)drag.setMimeData(mimeData)drag.setHotSpot(QtCore.QPoint(self.pixmap.width()/2, self.pixmap.height()/2))drag.setPixmap(self.pixmap)# 发射 upSignal 信号通知其他组件拖拽操作开始。self.upSignal.emit()# 调用 drag.exec_() 方法执行拖拽操作支持移动操作Qt.MoveAction。如果拖拽操作成功完成从列表中移除当前选中的项。if drag.exec_(QtCore.Qt.MoveAction) QtCore.Qt.MoveAction:self.takeItem(self.row(item))def dragEnterEvent(self,event):# 如果拖拽数据包含 image/pic 格式调用 event.accept()表示接受拖拽操作。否则调用 event.ignore()忽略拖拽操作。if event.mimeData().hasFormat(image/pic): # 检查拖拽事件的 MIME 数据是否包含 image/pic 格式。event.accept()else: event.ignore()def dragMoveEvent(self, event):# 检查拖拽事件的 MIME 数据是否包含 image/pic 格式。如果数据格式匹配设置拖拽操作类型为 MoveAction表示允许移动操作。调用 event.accept()表示接受拖拽操作。if event.mimeData().hasFormat(image/pic):event.setDropAction(QtCore.Qt.MoveAction)event.accept()else:event.ignore() # 忽略不支持的拖拽事件# 用于响应拖拽释放事件。通过这个方法PicturesList 组件可以处理拖拽释放时的数据接收并通知其他组件拖拽操作完成。def dropEvent(self,event):if event.mimeData().hasFormat(image/pic):picData event.mimeData().data(image/pic) # 获取 MIME 数据中的图片数据dataStream QtCore.QDataStream(picData,QtCore.QIODevice.ReadOnly) # 创建一个 QDataStream 对象用于反序列化数据self.pixmap QtGui.QPixmap() # 创建一个 QPixmap 对象用于存储图片self.location QtCore.QPoint() # 创建一个 QPoint 对象用于存储位置信息dataStream self.pixmap self.location # 从数据流中反序列化 QPixmap 和 QPointself.downSignal.emit() # 发射 downSignal 信号通知其他组件拖拽操作完成event.setDropAction(QtCore.Qt.MoveAction) # 设置拖拽操作类型为 MoveActionevent.accept() # 接受拖拽操作else :event.ignore() # 忽略不支持的拖拽事件# PictureWidget 类继承自 QtGui.QWidget。它用于显示和管理图片编辑区域并支持拖拽操作。 class PictureWidget(QtGui.QWidget):upSignal QtCore.pyqtSignal() # 自定义信号downSignal QtCore.pyqtSignal()saveSignal QtCore.pyqtSignal()def __init__(self,parentNone):super(PictureWidget, self).__init__(parent)self.setMinimumSize(640, 670) # 设置最小尺寸self.setMaximumSize(640, 670) # 设置最大尺寸self.highlightedRect QtCore.QRect() # 创建一个 QRect 对象用于表示高亮显示的矩形区域。初始值为空矩形。self.setAcceptDrops(True) # 启用组件接受拖拽操作允许用户将图片片段拖拽到该区域。self.cuttingWidgetList [] # 初始化切割小部件列表self.pixmapList [] # 初始化图片片段列表self.posList [] # 初始化位置信息列表self.drop_success_flag True # 初始化一个布尔标志用于指示拖拽操作是否成功完成。# 处理拖拽进入事件和拖拽离开事件def dragEnterEvent(self, event):if event.mimeData().hasFormat(image/pic):event.accept()else:event.ignore()def dragLeaveEvent(self, event):updateRect self.highlightedRect # 获取当前高亮显示的矩形区域self.highlightedRect QtCore.QRect() # 清空高亮显示的矩形区域self.update(updateRect) # 更新组件重新绘制高亮区域event.accept() # 接受拖拽离开事件# 处理拖拽移动事件和拖拽释放事件def dragMoveEvent(self, event):updateRect self.highlightedRect.unite(self.targetSquare(event.pos())) # 使用 unite 方法计算当前高亮矩形区域和目标矩形区域的联合区域确保更新整个相关区域。if event.mimeData().hasFormat(image/pic): # 检查拖拽事件的 MIME 数据是否包含 image/pic 格式。self.highlightedRect self.targetSquare(event.pos()) # 如果数据格式匹配调用 self.targetSquare(event.pos()) 获取目标矩形区域并将其设置为高亮显示区域。event.setDropAction(QtCore.Qt.MoveAction) # 设置拖拽操作类型为 MoveAction表示允许移动操作。event.accept() # 调用 event.accept()表示接受拖拽操作。else:self.highlightedRect QtCore.QRect() # 如果数据格式不匹配清空高亮显示的矩形区域并调用 event.ignore()忽略拖拽操作。event.ignore()self.update(updateRect) # 调用 self.update(updateRect)重新绘制需要更新的矩形区域。def dropEvent(self,event):if event.mimeData().hasFormat(image/pic): # 检查拖拽事件的 MIME 数据是否包含 image/pic 格式。picData event.mimeData().data(image/pic) # 从 MIME 数据中获取 image/pic 格式的数据。dataStream QtCore.QDataStream(picData, QtCore.QIODevice.ReadOnly) # 创建一个 QDataStream 对象用于从数据中反序列化 QPixmap 和 QPoint。self.square self.targetSquare(event.pos()) # 调用 self.targetSquare(event.pos()) 获取目标矩形区域。self.pixmap QtGui.QPixmap()self.location QtCore.QPoint()dataStream self.pixmap self.locationself.hightlightedRect QtCore.QRect() # 清空高亮显示的矩形区域。self.downSignal.emit() # 发射 downSignal 信号通知其他组件拖拽操作完成。event.setDropAction(QtCore.Qt.MoveAction) # 设置拖拽操作类型为 MoveAction。 event.accept() # 调用 event.accept()表示接受拖拽操作。else:self.hightlightedRect QtCore.QRect() # 如果数据格式不匹配清空高亮显示的矩形区域event.ignore()# 查找特定的切割小部件矩形区域 使用 index 方法在 cuttingWidgetList 中查找 pieceRect 的索引。如果找到返回其索引值。def findPiece(self, pieceRect):try:return self.cuttingWidgetList.index(pieceRect)except ValueError:return -1 # 如果 pieceRect 未在 cuttingWidgetList 中找到捕获 ValueError 异常并返回 -1。# 处理鼠标按下事件从而实现拖拽操作的开始。def mousePressEvent(self, event):self.square self.targetSquare(event.pos()) # 获取鼠标点击位置对应的目标矩形区域found self.findPiece(self.square) # 查找该矩形区域在 cuttingWidgetList 中的索引if found -1:return # 如果未找到直接返回self.location self.posList[found] # 获取该矩形区域的位置信息self.pixmap self.pixmapList[found] # 获取该矩形区域的图片片段# del self.posList[found]# del self.pixmapList[found]# del self.cuttingWidgetList[found]self.upSignal.emit() # 发射 upSignal 信号通知其他组件拖拽操作开始itemData QtCore.QByteArray() # 创建一个 QByteArray 对象用于存储数据dataStream QtCore.QDataStream(itemData, QtCore.QIODevice.WriteOnly) # 创建一个 QDataStream 对象用于序列化数据dataStream self.pixmap self.location # 将 QPixmap 和 QPoint 序列化到 QByteArray 中mimeData QtCore.QMimeData() # 创建一个 QMimeData 对象用于存储 MIME 类型的数据mimeData.setData(image/pic, itemData) # 将 QByteArray 数据存储到 QMimeData 中指定 MIME 类型为 image/picdrag QtGui.QDrag(self) # 创建一个 QDrag 对象用于处理拖拽操作drag.setMimeData(mimeData) # 将 QMimeData 设置到拖拽对象中drag.setHotSpot(event.pos() - self.square.topLeft()) # 设置拖拽的热点位置drag.setPixmap(self .pixmap) # 设置拖拽时显示的图标if drag.exec_(QtCore.Qt.MoveAction) ! QtCore.Qt.MoveAction:self.posList.insert(found, self.location)self.pixmapList.insert(found, self.pixmap)self.cuttingWidgetList.insert(found, self.square)self.update(self.square)def paintEvent(self, event):painter QtGui.QPainter() # 创建一个 QPainter 对象用于绘制图形。painter.begin(self) # 调用 begin(self) 方法指定绘制目标为当前组件。painter.fillRect(event.rect(), QtCore.Qt.white) # 使用 fillRect 方法将整个组件区域填充为白色。if self.highlightedRect.isValid(): # 检查 highlightedRect 是否有效。painter.setBrush(QtGui.QColor(#ffcccc)) # 如果有效设置画刷颜色为浅红色#ffcccc画笔为无边框。painter.setPen(QtCore.Qt.NoPen)painter.drawRect(self.highlightedRect.adjusted(0, 0, -1, -1)) # 使用 drawRect 方法绘制高亮矩形区域adjusted(0, 0, -1, -1) 用于调整矩形的大小使其不包含边界。# 使用 zip 函数同时遍历 cuttingWidgetList 和 pixmapList。在每个矩形区域内绘制对应的图片片段。for rect, pixmap in zip(self.cuttingWidgetList, self.pixmapList):painter.drawPixmap(rect, pixmap)painter.end() # 调用 end() 方法结束绘制。# targetSquare 方法用于计算鼠标位置对应的目标矩形区域 该方法将鼠标位置对齐到 80x80 的网格上确保拖拽操作的目标区域是固定的网格单元。def targetSquare(self, position):# 创建一个 QRect 对象表示目标矩形区域。矩形的左上角坐标为对齐后的坐标宽度和高度均为 80 像素。return QtCore.QRect(position.x() // 80 * 80, position.y() // 80 * 80, 80, 80)# 自定义不同情况的撤销命令类支持撤销和重做操作。 # 自定义的撤销命令类 CommandCut继承自 QtGui.QUndoCommand class CommandCut(QtGui.QUndoCommand):def __init__(self, piecesList, item):super(CommandCut, self).__init__() # 调用父类的构造函数self.piecesList piecesList # 存储图片片段列表组件self.item item # 存储当前操作的图片片段项self.row self.piecesList.row(self.item) # 获取该项在列表中的行号def redo(self):self.piecesList.takeItem(self.row) # 从列表中移除该项self.piecesList.saveSignal.emit() # 发射 saveSignal 信号通知其他组件保存状态def undo(self):self.piecesList.insertItem(self.row, self.item) # 将该项重新插入到列表中self.piecesList.saveSignal.emit() # 发射 saveSignal 信号通知其他组件保存状态class CommandPaste(QtGui.QUndoCommand):def __init__(self,piecesList, pixmap, location):super(CommandPaste,self).__init__()self.piecesList piecesListself.pixmap pixmapself.location locationdef redo(self):self.piecesList.addPiece(self.pixmap, self.location)self.piecesList.saveSignal.emit()def undo(self):count self.piecesList.count()self.piecesList.takeItem(self.piecesList.row(self.piecesList.item(count - 1)))self.piecesList.saveSignal.emit()class CommandDragToWidget(QtGui.QUndoCommand):def __init__(self, widget):super(CommandDragToWidget, self).__init__()self.widget widgetself.square self.widget.squareself.pixmap self.widget.pixmapself.location self.widget.locationdef redo(self):self.widget.cuttingWidgetList.append(self.square)self.widget.pixmapList.append(self.pixmap)self.widget.posList.append(self.location)self.widget.update(self.square)self.widget.saveSignal.emit()def undo(self):found self.widget.findPiece(self.square)if found -1:returndel self.widget.posList[found]del self.widget.pixmapList[found]del self.widget.cuttingWidgetList[found]self.widget.highlightedRect QtCore.QRect()self.widget.update(self.square)self.widget.saveSignal.emit()class CommandDragToListWidget(QtGui.QUndoCommand):def __init__(self, lstWidget):super(CommandDragToListWidget, self).__init__()self.lstWidget lstWidgetself.pixmap self.lstWidget.pixmapself.location self.lstWidget.locationdef redo(self):self.lstWidget.addPiece(self.pixmap, self.location)self.lstWidget.saveSignal.emit()def undo(self):count self.lstWidget.count()self.lstWidget.takeItem(self.lstWidget.row(self.lstWidget.item(count - 1)))self.lstWidget.saveSignal.emit()class CommandDragFromWidget(QtGui.QUndoCommand):def __init__(self,widget):super(CommandDragFromWidget, self).__init__()self.widget widgetself.square self.widget.squareself.pixmap self.widget.pixmapself.location self.widget.locationself.found self.widget.findPiece(self.square)def redo(self):if self.found -1:returndel self.widget.posList[self.found]del self.widget.pixmapList[self.found]del self.widget.cuttingWidgetList[self.found]self.widget.highlightedRect QtCore.QRect()self.widget.update(self.square)self.widget.saveSignal.emit()def undo(self):self.widget.posList.insert(self.found, self.location)self .widget.pixmapList.insert(self.found, self.pixmap)self.widget.cuttingWidgetList.insert(self.found, self.square)self.widget.update(self.square)self.widget.saveSignal.emit()class CommandDragFromListWidget(QtGui.QUndoCommand):def __init__(self, lstWidget, item, row):super(CommandDragFromListWidget, self).__init__()self.row rowself.lstWidget lstWidgetself.item itemdef redo(self):tmp self.lstWidget.item(self.row)tmp_location Nonetmp_index Nonefor i in self.lstWidget.locationList:if i.x() tmp.data(QtCore.Qt.UserRole 1).toPoint().x() and i.y() tmp.data(QtCore.Qt.UserRole 1).toPoint().y():tmp_index self.lstWidget.locationList.index(i)tmp_location ibreakif tmp_index ! None and tmp_location ! None:self.lstWidget.pixmapList.pop(tmp_index)self.lstWidget.locationList.remove(tmp_location)self.lstWidget.takeItem(self.row)self.lstWidget.saveSignal.emit()def undo(self):self.lstWidget.insertItem(self.row, self.item)self.lstWidget.saveSignal.emit()# 自定义的撤销命令类 CommandDelete继承自 QtGui.QUndoCommand。这个类用于实现“删除”操作的撤销和重做功能。 class CommandDelete(QtGui.QUndoCommand):def __init__(self, lstWidget, item):super(CommandDelete, self).__init__() # 调用父类的构造函数self.lstWidget lstWidget # 存储图片片段列表组件self.item item # 存储当前操作的图片片段项self.row self.lstWidget.row(self.item) # 获取该项在列表中的行号def redo(self):self.lstWidget.delete_piece(self.item) # 从列表中删除该项self.lstWidget.saveSignal.emit() # 发射 saveSignal 信号通知其他组件保存状态def undo(self):self.lstWidget.insertItem(self.row, self.item) # 将该项重新插入到列表中self.lstWidget.saveSignal.emit() # 发射 saveSignal 信号通知其他组件保存状态if __name__ __main__: # 如果是主程序运行执行以下代码如果是被导入为模块则跳过以下代码。app QtGui.QApplication(sys.argv) # QtGui.QApplication: PyQt 的应用程序类负责管理应用程序的资源如窗口、图标、菜单等。ex MainWindow() # 创建一个 MainWindow 类的实例MainWindow 是自定义的主窗口类继承自 QtGui.QMainWindow。ex.show() # 调用 show() 方法将主窗口显示在屏幕上。app.exec_() # 调用 exec_() 方法启动应用程序的事件循环。------------------------END------------------------- 才疏学浅谬误难免欢迎各位批评指正。
http://www.hkea.cn/news/14500734/

相关文章:

  • 做网站的像素是多少钱vs简易新闻建设网站
  • 做流媒体视频播放网站求助logo设计免费网址
  • ps网站logo制作教程长沙棋牌软件制作开发
  • 2018什么做网站国美电器如何进行网站的建设与维护
  • 义乌做公司网站东莞外贸建站及推广
  • 江苏省建设局网站首页来个网站吧好人一生平安
  • 东莞家具网站建设wordpress相册点击弹出
  • 网站建设费 科目化州网站开发公司
  • 如何做网站购物车海南住建部建设网站的网站
  • 旅游网站建设和实现巧克力网站模板
  • 无锡网站建设哪家做的比较好佛山网站营销
  • 张家界网站定制福建企业seo推广
  • 个人网站做多久有效果最大的购物平台
  • 专业做网站哪家便宜潍坊网站制作保定公司
  • 专业手机网站建设公司如何建设移动端网站
  • 在深圳做网站时代设计网 新网站
  • 余姚专业做网站公司网站外链建设记住5种外链方式不可用
  • 芜湖新芜湖网站建设手机wordpress加载图片慢
  • WordPress站点地址填错北京的互联网企业
  • 做哪一类网站能赚钱免费平面设计软件有哪些
  • 佛山外贸网站设计公司wordpress下载网站
  • 昆山建设工程安监站网站百度智能小程序是什么
  • 六安市城乡和建设局官方网站wordpress服务器如何使用
  • 学校网站建设实施方案国际设计公司logo
  • 企业进行网站建设的方式深圳网络推广代运营
  • 简单的个人网站制作流程网站制作ppt模板
  • 做网站第三方登录怎么弄营销型网站模板免费下载
  • 包头 网站建设win2008r2做网站服务器
  • 餐饮设计网站建设百度工具
  • 杭州网站建设市场网站要能被搜到需要做推广嘛