- 保存修改后的表格
主要内容 #
完成效果 #
本节课程是简化版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文件,自行修改之后再保存为新文件。