- 保存修改后的表格
主要内容 #
完成效果 #
本节课程是简化版Excel的第四节,完成本节课程,能实现将用户修改后的QTableView中的数据保存为新的xlsx文件。
收获 #
学习完本节内容,我们会知道如何修改QTableView的内容,并将新内容保存为新xlsx文件。
1.保存修改后的表格 #
用户可以编辑QTableView中的每一个单元格进行修改,修改完成后,点击保存动作会弹出保存文件对话框,本例中输入Example3_new作为保存文件名,仿照Excel,我们也以xlsx格式保存文件。首先将点击保存动作触发的信号关联到槽函数savefile,通过槽函数来完成保存文件的主要步骤。
在savefile函数中,先通过QTableView的.model()方法获取与QTableView绑定的数据模型,然后逐行读取数据模型中的数据。
最终的结果使用嵌套列表储存,该嵌套列表的每个元素仍然是一个子列表,每个子列表中存的是数据模型一整行的数据,整个嵌套列表就储存了数据模型所有行的数据。最后再次使用pandas库的to_excel函数将结果存为xlsx文件。以下就是本例代码:
from PyQt5.QtWidgets import QMainWindow, QWidget, QAction, QFileDialog, QHeaderView, QApplication, QTableView, \ QMessageBox from PyQt5.QtGui import QStandardItemModel, QStandardItem, QIcon from PyQt5.QtCore import Qt import sys import pandas as pd class Example(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.table = QTableView(self) # 创建一个QTableView表格视图对象 self.setCentralWidget(self.table) # 将该表格试图放在主窗口中间 self.statusBar().showMessage("Ready") # 添加状态栏 openAct = QAction(QIcon("D:\\Python_Tips\\Dashima\\pics\\open.png"), "打开", self) # 添加打开动作,并设置图标 saveAct = QAction(QIcon("D:\\Python_Tips\\Dashima\\pics\\save.png"), "保存", self) # 添加保存动作,并设置图标 openAct.triggered.connect(self.openfile) # 点击打开动作触发triggered信号,连接到槽函数openfile saveAct.triggered.connect(self.savefile) # 点击保存动作触发triggered信号,连接到槽函数savefile menubar = self.menuBar() # 添加菜单栏 fileMenu = menubar.addMenu("文件") # 添加文件菜单 fileMenu.addAction(openAct) # 将打开动作添加到文件菜单 fileMenu.addAction(saveAct) # 将保存动作添加到文件菜单 self.toolbar = self.addToolBar("工具栏") # 添加工具栏 self.toolbar.addAction(openAct) # 将打开动作添加到工具栏 self.toolbar.addAction(saveAct) # 将保存动作添加到工具栏 self.setGeometry(300, 300, 500, 400) self.setWindowTitle("简化版Excel") self.show() def openfile(self): # 槽函数, 用来打开文件 self.statusBar().showMessage("正在打开文件") # 更新状态栏信息 filepath = "D:\\Python_Tips\\Dashima\\pics" # 设置打开文件路径 filename, filetype = QFileDialog.getOpenFileName( self, "打开文件", filepath, "XLSX (*.xlsx *.XLSX)" ) # 弹出打开文件对话框,只选择Excel的xlsx文件 if filename: # 如果文件名不为空,即选择了一个文件 model = self.getModel(filename) # 获取模型 self.table.setModel(model) # 将模型应用到tableview上去 self.table.horizontalHeader().setVisible(False) # 隐藏模型的水平表头 self.table.verticalHeader().setVisible(False) # 隐藏模型的垂直表头 # 让表格的所有列自动拉伸,充满界面 self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.statusBar().showMessage("文件已成功打开") # 更新状态栏信息 def getModel(self, filename): # 用来制作模型 data = pd.read_excel(filename, header=None) # 读取Excel文件,header=None表示不设置表头 datashape = data.shape # 获取二维数据的形状 model = QStandardItemModel(datashape[0], datashape[1]) # 根据数据的形状 创建标准数据模型 for row in range(datashape[0]): # 按行循环 for column in range(datashape[1]): # 按列循环 item = data.iloc[row, column] # 获取row行column列的数据 item = QStandardItem(str(item)) # 转换为QStandardItem对象 item.setTextAlignment(Qt.AlignCenter) # 设置数据居中显示 model.setItem(row, column, item) # 给模型的第row行,第column列添加数据 return model # 返回创建好的模型 def savefile(self): # 用来储存文件 self.statusBar().showMessage("正在保存文件") # 更新状态栏信息 filename2, filetype2 = QFileDialog.getSaveFileName( self, "读取文件", "D:\\Python_Tips\\Dashima\\pics", "XLSX (*.xlsx *.XLSX)" ) # 存为xlsx文件 newModel = self.table.model() # 获取当前的数据视图绑定的数据模型 data = [] # 用来储存模型中的数据 for row in range(newModel.rowCount()): # 按行循环,rowCount()获取行数 rowRes = [] # 储存模型中的每一行数据 for column in range(newModel.columnCount()): # 按列循环,columnCount()获取行数 index = newModel.index(row, column) # 获得第row行 column列数据的索引 item = newModel.data(index) # 获得第row行 column列数据 if item != '': rowRes.append(item) # 如果数据不为空,则添加到行数据列表中 data.append(rowRes) # 将行数据列表添加到data列表中 dataFrame = pd.DataFrame(data) # 转换为pandas的DataFrame对象 dataFrame.to_excel(filename2, header=False, index=False) # 存为excel文件 self.statusBar().showMessage("保存文件成功!") # 更新状态栏信息 app = QApplication(sys.argv) # 创建应用程序 ex = Example() # 创建窗口对象 sys.exit(app.exec_()) # 设置关闭窗口后结束进程
拓展练习:尝试自定义修改QTableView的单元格内容。
小结 #
习题 #
- 习题1:尝试用本程序打开并展示自定义的xlsx文件,自行修改之后再保存为新文件。