参考资料https://www.zhihu.com/column/pyqt5
最终效果软件
导入安装包
pip install PyQt5 -i https://pypi.douban.com/simple
pip install PyQt5-tools -i https://pypi.douban.com/simple
要使用PyQt5编写一个文本处理程序,你可以按照以下步骤进行:
安装PyQt5:如果你还没有安装PyQt5,请使用pip安装它。打开命令提示符或终端窗口,然后运行以下命令:
shell
pip install PyQt5 -i https://pypi.douban.com/simple
pip uninstall PyQt5
# 不要安装下面的
pip install PyQt5-tools -i https://pypi.douban.com/simple
pip uninstall PyQt5-tools
pip install --upgrade sip -i https://pypi.douban.com/simplepip install PyQt5 --use-feature=2020-resolver -i https://pypi.douban.com/simple
pip install --upgrade pyqt5-plugins -i https://pypi.douban.com/simple
pip install --upgrade sip -i https://pypi.douban.com/simple
pip install --upgrade pyqt5 -i https://pypi.douban.com/simple
创建主窗口:使用PyQt5创建一个主窗口,这将作为应用程序的入口点。你可以使用Qt Designer设计主窗口的界面,或者手动编写代码来创建窗口。
添加文本处理功能:根据你的需求,在主窗口中添加文本处理功能。这可能包括打开和保存文本文件、编辑文本、查找和替换文本、格式化文本等。你可以使用QTextEdit、QPlainTextEdit等控件来显示和编辑文本。
编写处理函数:为文本处理功能编写函数,以便在需要时执行。例如,你可以编写一个函数来查找文本中的特定字符串,并高亮显示它们。
连接信号和槽:在PyQt5中,信号和槽机制用于处理事件和消息。你可以将按钮的点击事件与相应的槽函数连接起来,以便在用户单击按钮时执行特定的操作。
运行应用程序:最后,运行应用程序并测试它是否按预期工作。你可以使用QApplication对象来运行应用程序,并使用主窗口对象显示它。
下面是一个简单的示例代码,演示如何使用PyQt5创建一个基本的文本处理程序:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QTextEdit, QVBoxLayout, QWidgetclass TextProcessor(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowTitle('Text Processor')self.setGeometry(300, 300, 300, 200)# 创建文本编辑器和按钮self.text_edit = QTextEdit(self)self.button = QPushButton('Process', self)self.button.clicked.connect(self.processText)# 创建垂直布局并将控件添加到布局中layout = QVBoxLayout()layout.addWidget(self.text_edit)layout.addWidget(self.button)# 创建容器并将布局添加到容器中container = QWidget()container.setLayout(layout)self.setCentralWidget(container)def processText(self):# 处理文本的代码将放在这里passif __name__ == '__main__':app = QApplication(sys.argv)processor = TextProcessor()processor.show()sys.exit(app.exec_())
在这个示例中,我们创建了一个名为TextProcessor的类,它继承自QMainWindow。我们创建了一个QTextEdit控件和一个QPushButton控件,并将它们添加到一个垂直布局中。我们还连接了按钮的点击事件与processText方法。processText方法将在用户单击按钮时被调用,你可以在这里编写处理文本的代码。最后,我们创建了一个QApplication对象并显示主窗口。
最终完整代码
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QFileDialog, QLabel, QLineEdit
from PyQt5.QtGui import QIcon
from openpyxl import load_workbook
from openpyxl.styles import *
import pandas as pd
import string
import os
from openpyxl import Workbookclass FileProcessor(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowTitle('冬装奖励处理')self.setWindowIcon(QIcon('icon.png')) # 设置窗口图标,需要一个PNG格式的图标文件self.setGeometry(300, 300, 500, 200) # 设置窗口位置和大小layout = QVBoxLayout() # 创建垂直布局# 创建文件选择按钮和标签self.input_btn = QPushButton('选择文件')self.input_btn.clicked.connect(self.select_file)layout.addWidget(self.input_btn)self.input_label = QLabel('请选择文件')layout.addWidget(self.input_label)# 创建处理按钮和处理标签self.process_btn = QPushButton('处理文件')self.process_btn.clicked.connect(self.process_file)layout.addWidget(self.process_btn)self.process_label = QLabel('处理中...')layout.addWidget(self.process_label)# 创建输出标签和文件路径输入框self.output_label = QLabel('输出文件路径:')layout.addWidget(self.output_label)self.output_line = QLineEdit()layout.addWidget(self.output_line)# 将布局设置到窗口上self.setLayout(layout)self.show()def select_file(self):# 打开文件选择对话框,并获取选中的文件路径fname = QFileDialog.getOpenFileName(self, '打开文件', os.getcwd())[0]if fname: # 如果用户选择了文件self.input_label.setText('已选择文件:' + fname) # 更新标签显示选中的文件路径self.output_line.setText(fname) # 将输出路径设置为选中的文件路径,这里仅作示例,实际上你可能需要生成一个新的文件名或目录结构def process_file(self):# 这里是处理文件的逻辑,例如读取选中的文件内容并保存到新的文件中。这里只是一个示例。selected_file = self.input_label.text().split(':')[1] # 获取选中的文件路径(去掉“已选择文件:”文字)print(selected_file)parent_path = os.path.dirname(selected_file)file_path2 = parent_path + '/冬季奖励数据处理结果.xlsx'self.data_deal(selected_file)print(file_path2+'数据处理')self.style_deal(file_path2)print(file_path2 + '格式处理')self.process_label.setText('文件已处理!') # 更新标签显示处理完成的信息(这里只是一个示例)self.output_line.setText(file_path2) # 更新输出路径的显示(这里只是一个示例)@staticmethoddef create_excel(self, file_path):# 没有就创建if os.path.exists(file_path):print("文件已存在")print(file_path)else:# 创建一个新的 Excel 文件wb = Workbook()wb.save(file_path)@staticmethoddef set_cell_style(self, ws):# 边框border = Border(left=Side(border_style='thin', color='000000'),right=Side(border_style='thin', color='000000'),top=Side(border_style='thin', color='000000'),bottom=Side(border_style='thin', color='000000'),)# 对齐alignment = Alignment(horizontal='center',vertical='center',text_rotation=0,indent=0)# 字体font = Font(name='微软雅黑',size=11,bold=False,italic=False,strike=False,color='000000')rows = ws.max_row # 获取最大行columns = ws.max_column # 获取最大列# 遍历表格内容,注意:openpyxl下标是从1开始for i in range(1, rows + 1):for j in range(1, columns + 1):# 设置边框ws.cell(i, j).border = border# 设置居中对齐ws.cell(i, j).alignment = alignment# 设置字体ws.cell(i, j).font = fontreturn ws@staticmethoddef number_to_column(self, n):"""Convert a number to the corresponding column letter in Excel"""column = ""while n > 0:n -= 1column = string.ascii_uppercase[n % 26] + columnn //= 26return column@staticmethoddef auto_col_width(self, ws):lks = [] # 英文变量太费劲,用汉语首字拼音代替for i in range(1, ws.max_column + 1): # 每列循环lk = 1 # 定义初始列宽,并在每个行循环完成后重置for j in range(1, ws.max_row + 1): # 每行循环sz = ws.cell(row=j, column=i).value # 每个单元格内容if isinstance(sz, str): # 中文占用多个字节,需要分开处理lk1 = len(sz.encode('gbk')) # gbk解码一个中文两字节,utf-8一个中文三字节,gbk合适else:lk1 = len(str(sz))if lk < lk1:lk = lk1 # 借助每行循环将最大值存入lk中# print(lk)lks.append(lk) # 将每列最大宽度加入列表。(犯了一个错,用lks = lks.append(lk)报错,append会修改列表变量,返回值none,而none不能继续用append方法)# 第二步:设置列宽for i in range(1, ws.max_column + 1):k = self.number_to_column(i) # 将数字转化为列名,26个字母以内也可以用[chr(i).upper() for i in range(97, 123)],不用导入模块ws.column_dimensions[k].width = lks[i - 1] + 2 # 设置列宽,一般加两个字节宽度,可以根据实际情况灵活调整return ws@staticmethoddef sheet_name_deal(self, file_path):wb = load_workbook(file_path)# 获取sheet页,修改第一个sheet页面名为销售明细name1 = wb.sheetnames[0]ws1 = wb[name1]ws1.title = "销售明细"wb.save(file_path)# 首行@staticmethoddef style_deal(self, file_path1):wb = load_workbook(file_path1)name_list = wb.sheetnamesfor name in name_list:ws = wb[name]self.set_cell_style(ws)# 自适应列宽self.auto_col_width(ws)wb.save(file_path1)@staticmethoddef data_deal(self, file_path1):# 使用os.path.dirname()获取父路径parent_path = os.path.dirname(file_path1)file_path2 = parent_path+'/冬季奖励数据处理结果.xlsx'self.sheet_name_deal(file_path1)self.create_excel(file_path2)# 读入数据df1 = pd.read_excel(file_path1, sheet_name='销售明细')df2 = df1[df1['季节名称'] == '冬'].copy()# 筛选品类category_list = ['大衣', '派克服', '皮毛一体', '皮羽绒', '羽绒服', '麂皮绒', '坎毛', '水貂派克服', '雪兰貂']# 字典category_dict = dict(zip(category_list, [True] * len(category_list)))df2 = df2.loc[df2['品类名称'].isin(category_list), :]# 修改直销价为浮点类型df2['直销价'] = df2['直销价'].astype('float')# 单价在500元以上 1000元以下的衣服df3 = df2[(df2['直销价'] >= 500) & (df2['直销价'] < 1000)].copy()# 单价在1000元以上的衣服df4 = df2[df2['直销价'] >= 1000].copy()# 500-1000部门商店品类销售数量index_list = ['日期', '部门名称', '商店名称', '品类名称']value_list = ['销售数量']df31 = df3.pivot_table(index=index_list, values=value_list, aggfunc='sum')df31['提成金额'] = df31['销售数量'] * 50df31 = df31.reset_index()# 部门客户销售数量index_list = ['日期', '部门名称', '商店名称']value_list = ['销售数量']df32 = df3.pivot_table(index=index_list, values=value_list, aggfunc='sum')df32['提成金额'] = df32['销售数量'] * 50df32 = df32.reset_index()# 1000元以上部门商店品类销售数量index_list = ['日期', '部门名称', '商店名称', '品类名称']value_list = ['销售数量']df41 = df4.pivot_table(index=index_list, values=value_list, aggfunc='sum')df41['提成金额'] = df41['销售数量'] * 100df41 = df41.reset_index()# 部门客户销售数量index_list = ['日期', '部门名称', '商店名称']value_list = ['销售数量']df42 = df4.pivot_table(index=index_list, values=value_list, aggfunc='sum')df42['提成金额'] = df42['销售数量'] * 100df42 = df42.reset_index()# 部门品类销售数量df51 = df31.copy()df52 = df41.copy()df51['500元档位数量'] = df51.pop('销售数量')df52['1000元档位数量'] = df52.pop('销售数量')index_list = ['部门名称', '品类名称']value_list = ['500元档位数量']df511 = df51.pivot_table(index=index_list, values=value_list, aggfunc='sum')value_list = ['1000元档位数量']df521 = df52.pivot_table(index=index_list, values=value_list, aggfunc='sum')df53 = pd.merge(df511, df521, how='outer', left_index=True, right_index=True)df54 = df53.reset_index()df54 = df54.fillna(0)# 日期部门客户大类备注df60 = df2.copy()df61 = df60[df60['直销价'] >= 500]index_list = ['日期', '部门名称', '商店名称']column_list = ['品类名称']# value_list = ['销售数量']df666 = df61.pivot_table(index=index_list, columns=column_list, values='销售数量', aggfunc='sum')df666 = df666.reset_index()# 生成备注列notes_list = []# 获取列名start_len = len(index_list)column_list = df666.columns.tolist()df666 = df666.fillna(0)for row in df666.itertuples():strings = ''for pos in range(start_len, len(column_list)):col_name = column_list[pos]num = getattr(row, col_name)num = int(num)if num != 0:strings = strings + str(num) + '件' + col_name + ','# 切片操作strings = strings[:-1] + "" # 将最后一个字符替换为空notes_list.append(strings)# 删除品类列sum_len = len(column_list)df667 = df666.copy()for pos in range(start_len, sum_len):col_name = column_list[pos]df667.pop(col_name)df667['备注'] = pd.Series(notes_list)# 获取部门客户品类df71 = df31.copy()df72 = df41.copy()df71['500元档位数量'] = df71.pop('销售数量')df72['1000元档位数量'] = df72.pop('销售数量')index_list = ['日期', '部门名称', '商店名称']value_list = ['500元档位数量']df711 = df71.pivot_table(index=index_list, values=value_list, aggfunc='sum')value_list = ['1000元档位数量']df721 = df72.pivot_table(index=index_list, values=value_list, aggfunc='sum')df73 = pd.merge(df711, df721, how='outer', left_index=True, right_index=True)df74 = df73.reset_index()df74 = df74.fillna(0)df74['总奖励金额'] = df74['500元档位数量'] * 50 + df74['1000元档位数量'] * 100df75 = pd.merge(df74, df667, how='left')wb = load_workbook(file_path2)# 获取sheet页,修改第一个sheet页面为name1 = wb.sheetnames[0]ws1 = wb[name1]ws1.title = "500-1000冬装销售明细"# 创建工作表wb.create_sheet("500-1000客户品类销售")wb.create_sheet("500-1000客户销售")wb.create_sheet("1000以上冬装销售明细")wb.create_sheet("1000以上客户品类销售")wb.create_sheet("1000以上客户销售")wb.create_sheet("部门品类销售")wb.create_sheet("部门客户品类销售")wb.create_sheet("部门客户销售备注")wb.create_sheet("部门客户档位销售")wb.save(file_path2)# 将生成的工作表导入到程序中result_sheet = pd.ExcelWriter(file_path2, engine='openpyxl') # 先定义要存入的文件名xxx,然后分别存入xxx下不同的sheet# df1将0转变为空df3.to_excel(result_sheet, "500-1000冬装销售明细", index=False, na_rep=0, inf_rep=0)df31.to_excel(result_sheet, "500-1000客户品类销售", index=False, na_rep=0, inf_rep=0)df32.to_excel(result_sheet, "500-1000客户销售", index=False, na_rep=0, inf_rep=0)df4.to_excel(result_sheet, "1000以上冬装销售明细", index=False, na_rep=0, inf_rep=0)df41.to_excel(result_sheet, "1000以上客户品类销售", index=False, na_rep=0, inf_rep=0)df42.to_excel(result_sheet, "1000以上客户销售", index=False, na_rep=0, inf_rep=0)df54.to_excel(result_sheet, "部门品类销售", index=False, na_rep=0, inf_rep=0)df666.to_excel(result_sheet, "部门客户品类销售", index=False, na_rep=0, inf_rep=0)df667.to_excel(result_sheet, "部门客户销售备注", index=False, na_rep=0, inf_rep=0)df75.to_excel(result_sheet, "客户档位销售", index=False, na_rep=0, inf_rep=0)# 这步不能省,否则不生成文件result_sheet._save()if __name__ == '__main__':app = QApplication(sys.argv)processor = FileProcessor()processor.show()sys.exit(app.exec_())
打包成exe软件
安装依赖
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple
使用pyinstaller将py文件打包为exe
1.打开对应py文件,在Terminal终端,输入:pyinstaller -F -w ’文件名‘.py
pyinstaller -F -w 文件处理.py
生成的exe文件位置在哪里?
打包后的exe文件在项目的dist目录下:
最终效果