背景:
博主在某个项目中,需要模拟每秒钟生成一行数据,所以有了该博客的想法,其中有线程的内容,为了防止主界面卡住
效果:
代码:
import sys
import threading
import timeimport openpyxl
import pandas as pd
from PySide2.QtWidgets import QApplication, QWidget, QFileDialog
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile, QIODevicesourceFilePath = "" # 源文件路径
targetFilePath = "" # 目标文件路径
source_data = None # 源文件数据class MyWindow:def __init__(self):# 从文件中加载UI定义self.load_ui()# 绑定事件# 给 选择源文件 按钮 绑定事件self.ui.btn_selectSourceFile.clicked.connect(self.click_selectSourceFile)# 给 选择目标文件 按钮 绑定事件self.ui.btn_selectTargetFile.clicked.connect(self.click_selectTargetFile)# 给 开始复制 按钮 绑定事件self.ui.btn_runCopy.clicked.connect(self.click_runCopy)# 连接文本编辑器的文本变化信号到滚动到底部的槽self.ui.textEdit_log.textChanged.connect(self.scroll_to_bottom)def load_ui(self):# 从文件中加载UI定义ui_file_name = 'UI/WriteMain.ui'ui_file = QFile(ui_file_name)if not ui_file.open(QIODevice.ReadOnly):print(f"Cannot open {ui_file_name}: {ui_file.errorString()}")sys.exit(-1)# 从 UI 定义中动态 创建一个相应的窗口对象# 注意:里面的控件对象也成为窗口对象的属性了# 比如 self.ui.button , self.ui.textEditloader = QUiLoader()self.ui = loader.load(ui_file)ui_file.close()if not self.ui:print(loader.errorString())sys.exit(-1)# 选择源文件 按钮 单击事件def click_selectSourceFile(self):global sourceFilePath, source_datafile_name = QFileDialog.getOpenFileName(self.ui, "选择源文件", "../Data",'Excel files (*.xls *.xlsx);; All files (*)') # 选择文件,返回选中的文件路径print(file_name)if file_name:file_name = file_name[0]self.file_name = file_name# 根据文件类型读取数据if file_name.endswith('.xls') or file_name.endswith('.xlsx'):sourceFilePath = file_name# 读取Excel文件# source_data = pd.read_excel(file_name)# print(source_data)self.ui.lineEdit_sourcePath.setText(file_name)else:# 无法识别的文件类型print('无法识别的文件类型')return# 选择目标 按钮 单击事件def click_selectTargetFile(self):global targetFilePathfile_name = QFileDialog.getOpenFileName(self.ui, "选择目标文件", "../Data",'Excel files (*.xls *.xlsx);; All files (*)') # 选择文件,返回选中的文件路径print(file_name)if file_name:file_name = file_name[0]self.file_name = file_name# 根据文件类型读取数据if file_name.endswith('.xls') or file_name.endswith('.xlsx'):targetFilePath = file_name# 显示文件名称self.ui.lineEdit_targetPath.setText(file_name)else:# 无法识别的文件类型print('无法识别的文件类型')return# 运行 按钮 单击事件def click_runCopy(self):t_write = threading.Thread(target=write_row_by_second, )t_write.setDaemon(True)t_write.start()# 更新日志def update_log(self, msg):self.ui.textEdit_log.append(msg)def scroll_to_bottom(self):# 获取垂直滚动条scrollbar = self.ui.textEdit_log.verticalScrollBar()# 设置滚动条到最下面scrollbar.setValue(scrollbar.maximum())def write_row_by_second():global sourceFilePath, targetFilePath# 获取源文件的总行数source_workbook = openpyxl.load_workbook(sourceFilePath)source_sheet = source_workbook.active # 假设源文件只有一个工作表total_rows = source_sheet.max_row# 初始化计数器row_to_copy = 1print(f"total_rows={total_rows}")while row_to_copy <= total_rows:# 打开目标文件target_workbook = openpyxl.load_workbook(targetFilePath)target_sheet = target_workbook.active # 假设目标文件只有一个工作表# 复制数据,每次复制一行,,所有列for col in range(1, source_sheet.max_column + 1):cell_value = source_sheet.cell(row=row_to_copy, column=col).valuetarget_sheet.cell(row=row_to_copy, column=col, value=cell_value)# 保存目标文件target_workbook.save(targetFilePath)target_workbook.close()# 打印信息print(f"Copied data from row {row_to_copy}: {source_sheet[row_to_copy]}")msg = f"Copied data from row {row_to_copy}\n"window.update_log(msg=msg)# 增加行计数row_to_copy += 1if row_to_copy <= total_rows:# 1秒复制一行time.sleep(1)# 关闭源文件的工作簿source_workbook.close()if __name__ == "__main__":app = QApplication(sys.argv)window = MyWindow()window.ui.show()sys.exit(app.exec_())