前言
老姐要求做个记录销售汽车配件得的excel,我觉得太麻烦了,身为程序员的我 必须安排一个方便快捷的系统,安排上!!!
环境要求:python3,pyqt5,pandas
1、实现效果
初始界面
添加界面
2、代码实现
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import pandas as pd
import sys
import datetime
import os
from shutil import copyfile
class DataManage(QWidget):
def __init__(self):
super(DataManage, self).__init__()
self.data_list = []
self.base_path = r'C:\CarData'
self.money_sum_text = '总金额:¥ 0.0'
if not os.path.exists(self.base_path):
os.mkdir(self.base_path)
if not os.path.exists(self.base_path + '\data.xlsx'):
file = open(self.base_path + '\data.xlsx', 'w')
file.close()
if os.path.exists(self.base_path + '\data.xlsx'):
data = pd.read_excel(self.base_path + '\data.xlsx', dtype=str)
self.money_sum_text = '总金额:¥{}'.format(str(data['销售金额'][:-1].astype(dtype='float').sum()))
self.data_list = data.iloc[0:-1,:].values.tolist()
self.init_ui()
def init_ui(self):
'''全局设置'''
self.setWindowIcon(QIcon('i.ico'))
self.setWindowTitle('汽车配件记录系统')
self.resize(726, 440)
grid = QGridLayout()
'''菜单设置'''
self.add_btn = QPushButton()
self.add_btn.setText('添加数据')
self.add_btn.setStyleSheet("background-color:#1890ff;color:white;border:none;font: 15px \"微软雅黑\";")
self.add_btn.setFixedSize(100,30)
self.add_btn.clicked.connect(self.add_btn_click)
self.del_btn = QPushButton()
self.del_btn.setText('删除数据')
self.del_btn.setStyleSheet("background-color:#ff4949;color:white;border:none;font: 15px \"微软雅黑\";")
self.del_btn.setFixedSize(100,30)
self.del_btn.clicked.connect(self.del_data_row)
self.query_btn = QPushButton()
self.query_btn.setText('查询')
self.query_btn.setStyleSheet("background-color:#1890ff;color:white;border:none;font: 15px \"微软雅黑\";")
self.query_btn.setFixedSize(100,30)
self.query_btn.clicked.connect(self.query_data_list)
self.saveData_btn = QPushButton()
self.saveData_btn.setText('打开文件')
self.saveData_btn.setStyleSheet("background-color:#13ce66;color:white;border:none;font: 15px \"微软雅黑\";")
self.saveData_btn.setFixedSize(100,30)
self.saveData_btn.clicked.connect(self.saveData_data_click)
self.money_sum = QLabel()
self.money_sum.setText(self.money_sum_text)
'''数据列表设置'''
self.data_table = QTableWidget()
self.data_table.setStyleSheet("QHeaderView::section{background-color:#DCDCDC;border:1px solid #D3D3D3;font: 15px \"微软雅黑\";}")
COLUMN = 7
ROW = 0
self.data_table.setColumnCount(COLUMN)
self.data_table.setRowCount(ROW)
h_table_header = ['序号', '车型', '配件名称', '规格', '单价', '数量','销售金额']
self.data_table.setHorizontalHeaderLabels(h_table_header)
self.data_table.horizontalHeader().setDefaultAlignment(Qt.AlignVCenter)
self.data_table.verticalHeader().setVisible(False)
self.data_table.setShowGrid(True)
self.data_table.setEditTriggers(QTableWidget.NoEditTriggers)
self.data_table.setSelectionBehavior(QTableWidget.SelectRows)
self.data_table.setSelectionMode(QTableWidget.SingleSelection)
for index in range(self.data_table.columnCount()):
headItem = self.data_table.horizontalHeaderItem(index)
headItem.setTextAlignment(Qt.AlignVCenter)
'''加入布局'''
grid.addWidget(self.add_btn, 0, 0, 1, 1)
grid.addWidget(self.del_btn, 0, 1, 1, 1)
#grid.addWidget(self.query_btn, 0, 2, 1, 1)
grid.addWidget(self.saveData_btn, 0, 2, 1, 1)
grid.addWidget(self.money_sum, 0, 3, 1, 1)
grid.addWidget(self.data_table, 1, 0, 1, 4)
grid.setSpacing(12)
self.setLayout(grid)
# 初始化数据
self.query_data_list()
# 将新增数据的按钮绑定到该槽函数
def add_btn_click(self):
'''
打开新增数据的弹框模块
:return:
'''
try:
AddDialog.get_add_dialog(self)
self.refsh_data()
except PermissionError:
#reply = QMessageBox.critical(self, '标题', '严重错误对话框消息正文', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
QMessageBox.critical(self, "错误", "Excel文件正在打开,请关闭文件后操作!")
except:
QMessageBox.critical(self, "错误", "操作异常!")
# 将查询数据的按钮绑定到该槽函数
def query_data_list(self):
'''
查询数据、并将数据展示到主窗口的数据列表中
:return:
'''
data = self.data_list
if len(data) != 0 and len(data[0]) != 0:
self.data_table.setRowCount(len(data))
self.data_table.setColumnCount(len(data[0]))
for i in range(len(data)):
for j in range(len(data[0])):
self.data_table.setItem(i, j, QTableWidgetItem(str(data[i][j])))
# 将删除数据按钮绑定到该槽函数
def del_data_row(self):
'''
删除某一行的数据信息
:return:
'''
try:
row_select = self.data_table.selectedItems()
if len(row_select) != 0:
row = row_select[0].row()
self.data_table.removeRow(row)
del self.data_list[row]
self.refsh_data()
except PermissionError:
#reply = QMessageBox.critical(self, '标题', '严重错误对话框消息正文', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
QMessageBox.critical(self, "错误", "Excel文件正在打开,请关闭文件后操作!")
except:
QMessageBox.critical(self, "错误", "操作异常!")
# 刷新数据到文件
def refsh_data(self):
'''
将数据更新到文件
:return:
'''
df = pd.DataFrame(self.data_list, columns=['序号', '车型', '配件名称', '规格', '单价', '数量','销售金额'])
df['单价'].astype('float')
df['数量'].astype('int')
df['销售金额'].astype('float')
# 保存到本地excel
path = r'C:\CarData'
if not os.path.exists(path):
os.mkdir(r'C:\CarData')
file_name = "C:\CarData\data.xlsx"
if len(self.data_list) > 0:
writer = pd.ExcelWriter(file_name, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1', index=False)
workbook = writer.book
worksheet = writer.sheets['Sheet1']
header_format = workbook.add_format({
'bold': True, # 字体加粗
'text_wrap': True, # 是否自动换行
'valign': 'bottom', # 垂直对齐方式
'align': 'center', # 水平对齐方式
'border': 1, # 边框
'top':1, # 上边框
'left':1, # 左边框
'right':1, # 右边框
'bottom':1, # 底边框
})
sumMoney = 0.0
for i in df['销售金额']:
sumMoney += float(i)
worksheet.write_string(len(self.data_list) + 1, 6, u'总金额:{}'.format(sumMoney))
writer.save()
writer.close()
self.money_sum.setText('总金额:¥{}'.format(sumMoney))
else:
os.remove(file_name)
self.money_sum.setText('总金额:¥0.0')
# 打开文件
def saveData_data_click(self):
'''
打开文件
:return:
'''
if len(self.data_list) > 0:
df = pd.DataFrame(self.data_list, columns=['序号', '车型', '配件名称', '规格', '单价', '数量','销售金额'])
df['单价'].astype('float')
df['数量'].astype('int')
df['销售金额'].astype('float')
try:
# 保存到文件中
file_name = "C:\CarData\data.xlsx"
if not os.path.exists(r'C:\CarData\copy'):
os.mkdir(r'C:\CarData\copy')
copyfile(file_name, "C:\CarData\copy\data_copy.xlsx")
if not os.path.exists(file_name):
QMessageBox.critical(self, "错误", "数据存储路径不存在,请重启系统!")
os.startfile("C:\CarData\copy\data_copy.xlsx")
except PermissionError:
#reply = QMessageBox.critical(self, '标题', '严重错误对话框消息正文', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
QMessageBox.critical(self, "错误", "Excel文件正在打开,请关闭文件后操作!")
except:
QMessageBox.critical(self, "错误", "操作异常!")
else:
QMessageBox.critical(self, "错误", "数据为空!")
class AddDialog(QDialog):
def __init__(self, parent=None):
super(AddDialog, self).__init__(parent)
self.init_ui(parent)
def init_ui(self,parent):
self.setWindowTitle('添加界面')
self.resize(400, 200)
'''水平布局'''
hbox = QHBoxLayout()
self.save_btn = QPushButton()
self.save_btn.setText('保存')
self.save_btn.setStyleSheet("background-color:#1890ff;color:white;border:none;")
self.save_btn.setFixedSize(200,30)
self.save_btn.clicked.connect(lambda :self.save_btn_click(parent))
self.cancel_btn = QPushButton()
self.cancel_btn.setText('取消')
self.cancel_btn.setFixedSize(200,30)
self.cancel_btn.clicked.connect(self.cancel_btn_click)
hbox.addWidget(self.save_btn)
hbox.addWidget(self.cancel_btn)
hbox.setSpacing(12)
'''校验器'''
self.intvalidator = QIntValidator()
self.doublevalidator = QDoubleValidator()
self.doublevalidator.setDecimals(2)
'''表单布局'''
fbox = QFormLayout()
self.seq_lab = QLabel()
self.seq_lab.setText('序号:')
self.seq_lab.setStyleSheet("font: 15px \"微软雅黑\";")
self.seq_text = QLineEdit()
self.seq_text.setFixedHeight(30)
self.seq_text.setValidator(self.intvalidator)
self.seq_text.setPlaceholderText('请输入序号')
self.name_lab = QLabel()
self.name_lab.setText('车型:')
self.name_lab.setStyleSheet("font: 15px \"微软雅黑\";")
self.name_text = QLineEdit()
self.name_text.setFixedHeight(30)
self.name_text.setPlaceholderText('请输入车型')
self.age_lab = QLabel()
self.age_lab.setText('配件名称:')
self.age_lab.setStyleSheet("font: 15px \"微软雅黑\";")
self.age_text = QLineEdit()
self.age_text.setFixedHeight(30)
self.age_text.setPlaceholderText('请输入配件名称')
self.class_lab = QLabel()
self.class_lab.setText('规格:')
self.class_lab.setStyleSheet("font: 15px \"微软雅黑\";")
self.class_text = QLineEdit()
self.class_text.setFixedHeight(30)
self.class_text.setPlaceholderText('请输入规格')
self.socre_lab = QLabel()
self.socre_lab.setText('单价:')
self.socre_lab.setStyleSheet("font: 15px \"微软雅黑\";")
self.socre_text = QLineEdit()
self.socre_text.setFixedHeight(30)
self.socre_text.setValidator(self.doublevalidator)
self.socre_text.setPlaceholderText('请输入单价')
self.num_lab = QLabel()
self.num_lab.setText('数量:')
self.num_lab.setStyleSheet("font: 15px \"微软雅黑\";")
self.num_text = QLineEdit()
self.num_text.setFixedHeight(30)
self.num_text.setValidator(self.intvalidator)
self.num_text.setPlaceholderText('请输入数量')
self.money_lab = QLabel()
self.money_lab.setText('销售金额:')
self.money_lab.setStyleSheet("font: 15px \"微软雅黑\";")
self.money_text = QLineEdit()
self.money_text.setFixedHeight(30)
self.money_text.setValidator(self.doublevalidator)
self.money_text.setPlaceholderText('请输入销售金额')
fbox.addRow(self.seq_lab,self.seq_text)
fbox.addRow(self.name_lab, self.name_text)
fbox.addRow(self.age_lab, self.age_text)
fbox.addRow(self.class_lab, self.class_text)
fbox.addRow(self.socre_lab, self.socre_text)
fbox.addRow(self.num_lab, self.num_text)
fbox.addRow(self.money_lab, self.money_text)
fbox.setSpacing(12)
vbox = QVBoxLayout()
vbox.addLayout(fbox)
vbox.addLayout(hbox)
self.setLayout(vbox)
def save_btn_click(self,parent):
if self.seq_text.text().strip() != '' and self.name_text.text().strip() != '' \
and self.age_text.text().strip() != ''and self.class_text.text().strip() != '' \
and self.socre_text.text().strip() != '' and self.num_text.text().strip() != '' \
and self.money_text.text().strip() != '':
data = [self.seq_text.text(),
self.name_text.text(),
self.age_text.text(),
self.class_text.text(),
self.socre_text.text(),
self.num_text.text(),
self.money_text.text()]
parent.data_list.append(data)
parent.query_data_list()
self.close()
def cancel_btn_click(self):
self.close()
@staticmethod
def get_add_dialog(parent=None):
dialog = AddDialog(parent)
return dialog.exec()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = DataManage()
main.show()
sys.exit(app.exec_())
3、pyinstaller打包成exe
pyinstaller -F -w main.py --icon=i.ico
扫描二维码关注公众号,回复: 17194683 查看本文章