首页
学习
活动
专区
圈层
工具
发布

实验室耗材管理平台

实验室耗材管理平台

一、输入员工基本信息。

二、预览、提交申请,自动生成申请记录。

三、在records文件中累计申请记录,便于统计耗材消耗情况,安排预算。

实验室耗材申请单

软件关键代码:

  def setup_application_tab(self):

      layout = QVBoxLayout()

      # 标题

      title_label = QLabel("实验室耗材管理平台")

      title_label.setFont(QFont("Arial", 16, QFont.Bold))

      title_label.setAlignment(Qt.AlignCenter)

      layout.addWidget(title_label)

      # 申请人信息

      info_layout = QVBoxLayout()

      # 姓名

      name_layout = QHBoxLayout()

      name_label = QLabel("姓  名:")

      name_label.setFixedWidth(80)

      self.name_input = QLineEdit()

      self.name_input.setPlaceholderText("请输入申请人姓名")

      name_layout.addWidget(name_label)

      name_layout.addWidget(self.name_input)

      info_layout.addLayout(name_layout)

      # 部门

      dept_layout = QHBoxLayout()

      dept_label = QLabel("部  门:")

      dept_label.setFixedWidth(80)

      self.dept_input = QLineEdit()

      self.dept_input.setPlaceholderText("请输入所在部门")

      dept_layout.addWidget(dept_label)

      dept_layout.addWidget(self.dept_input)

      info_layout.addLayout(dept_layout)

      layout.addLayout(info_layout)

      # 耗材选择

      material_layout = QVBoxLayout()

      material_title = QLabel("耗材选择:")

      material_title.setFont(QFont("Arial", 12, QFont.Bold))

      material_layout.addWidget(material_title)

      # 耗材类型

      type_layout = QHBoxLayout()

      type_label = QLabel("耗材类型:")

      type_label.setFixedWidth(80)

      self.material_combo = QComboBox()

      self.materials = ["实验服", "**", "**", "**", "**", "**", "**"]

      self.material_combo.addItems(self.materials)

      type_layout.addWidget(type_label)

      type_layout.addWidget(self.material_combo)

      material_layout.addLayout(type_layout)

      # 数量

      quantity_layout = QHBoxLayout()

      quantity_label = QLabel("数  量:")

      quantity_label.setFixedWidth(80)

      self.quantity_spin = QSpinBox()

      self.quantity_spin.setRange(1, 100)

      self.quantity_spin.setValue(1)

      quantity_layout.addWidget(quantity_label)

      quantity_layout.addWidget(self.quantity_spin)

      material_layout.addLayout(quantity_layout)

      layout.addLayout(material_layout)

      # 按钮

      button_layout = QHBoxLayout()

      self.preview_btn = QPushButton("预览申请")

      self.preview_btn.clicked.connect(self.preview_application)

      self.submit_btn = QPushButton("提交申请")

      self.submit_btn.clicked.connect(self.submit_application)

      self.clear_btn = QPushButton("清空表单")

      self.clear_btn.clicked.connect(self.clear_form)

      button_layout.addWidget(self.preview_btn)

      button_layout.addWidget(self.submit_btn)

      button_layout.addWidget(self.clear_btn)

      layout.addLayout(button_layout)

      # 预览区域

      preview_label = QLabel("申请预览:")

      preview_label.setFont(QFont("Arial", 12, QFont.Bold))

      layout.addWidget(preview_label)

      self.preview_text = QTextEdit()

      self.preview_text.setReadOnly(True)

      layout.addWidget(self.preview_text)

      self.application_tab.setLayout(layout)

  def setup_records_tab(self):

      layout = QVBoxLayout()

      # 标题

      title_label = QLabel("申请记录")

      title_label.setFont(QFont("Arial", 16, QFont.Bold))

      title_label.setAlignment(Qt.AlignCenter)

      layout.addWidget(title_label)

      # 记录表格

      self.records_table = QTableWidget()

      self.records_table.setColumnCount(5)

      self.records_table.setHorizontalHeaderLabels(["申请时间", "姓名", "部门", "耗材类型", "数量"])

      self.records_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

      layout.addWidget(self.records_table)

      # 按钮布局

      button_layout = QHBoxLayout()

      refresh_btn = QPushButton("刷新记录")

      refresh_btn.clicked.connect(self.refresh_records)

      export_btn = QPushButton("导出为Excel")

      export_btn.clicked.connect(self.export_to_excel)

      button_layout.addWidget(refresh_btn)

      button_layout.addWidget(export_btn)

      layout.addLayout(button_layout)

      self.records_tab.setLayout(layout)

  def setup_statistics_tab(self):

      layout = QVBoxLayout()

      # 标题

      title_label = QLabel("统计信息")

      title_label.setFont(QFont("Arial", 16, QFont.Bold))

      title_label.setAlignment(Qt.AlignCenter)

      layout.addWidget(title_label)

      # 统计显示

      self.stats_text = QTextEdit()

      self.stats_text.setReadOnly(True)

      layout.addWidget(self.stats_text)

      # 刷新按钮

      refresh_btn = QPushButton("刷新统计")

      refresh_btn.clicked.connect(self.refresh_statistics)

      layout.addWidget(refresh_btn)

      self.statistics_tab.setLayout(layout)

  def preview_application(self):

      """预览申请内容"""

      name = self.name_input.text().strip()

      dept = self.dept_input.text().strip()

      material = self.material_combo.currentText()

      quantity = self.quantity_spin.value()

      if not name or not dept:

          QMessageBox.warning(self, "输入错误", "请填写姓名和部门信息!")

          return

      preview_content = f"""

      ===== 实验室耗材申请单 =====

      申请人信息:

      姓  名:{name}

      部  门:{dept}

      申请耗材:

      耗材类型:{material}

      数  量:{quantity}

      申请时间:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}

      ============================

      """

      self.preview_text.setText(preview_content)

  def submit_application(self):

      """提交申请"""

      name = self.name_input.text().strip()

      dept = self.dept_input.text().strip()

      material = self.material_combo.currentText()

      quantity = self.quantity_spin.value()

      if not name or not dept:

          QMessageBox.warning(self, "输入错误", "请填写姓名和部门信息!")

          return

      # 创建记录

      record = {

          'timestamp': datetime.now(),

          'name': name,

          'department': dept,

          'material': material,

          'quantity': quantity

      }

      self.records.append(record)

      # 保存到文件

      self.save_record(record)

      # 显示成功消息

      QMessageBox.information(self, "申请成功", "耗材申请已提交成功!")

      # 清空表单

      self.clear_form()

      # 刷新记录和统计

      self.refresh_records()

      self.refresh_statistics()

  def clear_form(self):

      """清空表单"""

      self.name_input.clear()

      self.dept_input.clear()

      self.material_combo.setCurrentIndex(0)

      self.quantity_spin.setValue(1)

      self.preview_text.clear()

  def refresh_records(self):

      """刷新记录表格"""

      self.records_table.setRowCount(len(self.records))

      for row, record in enumerate(self.records):

          self.records_table.setItem(row, 0, QTableWidgetItem(record['timestamp'].strftime("%Y-%m-%d %H:%M")))

          self.records_table.setItem(row, 1, QTableWidgetItem(record['name']))

          self.records_table.setItem(row, 2, QTableWidgetItem(record['department']))

          self.records_table.setItem(row, 3, QTableWidgetItem(record['material']))

          self.records_table.setItem(row, 4, QTableWidgetItem(str(record['quantity'])))

  def refresh_statistics(self):

      """刷新统计信息"""

      if not self.records:

          self.stats_text.setText("暂无申请记录")

          return

      # 使用pandas进行统计分析

      df = pd.DataFrame(self.records)

      # 按人员统计

      person_stats = df.groupby('name').agg({

          'quantity': 'sum',

          'material': 'count'

      }).rename(columns={'quantity': '总数量', 'material': '申请次数'})

      # 按耗材类型统计

      material_stats = df.groupby('material')['quantity'].sum()

      # 按部门统计

      dept_stats = df.groupby('department')['quantity'].sum()

      stats_text = "===== 统计信息汇总 =====\n\n"

      stats_text += "1. 按人员统计:\n"

      stats_text += person_stats.to_string() + "\n\n"

      stats_text += "2. 按耗材类型统计:\n"

      stats_text += material_stats.to_string() + "\n\n"

      stats_text += "3. 按部门统计:\n"

      stats_text += dept_stats.to_string() + "\n\n"

      stats_text += f"总申请次数:{len(self.records)}\n"

      stats_text += f"总耗材数量:{df['quantity'].sum()}\n"

      self.stats_text.setText(stats_text)

  def save_record(self, record):

      """保存记录到CSV文件(解决中文乱码问题)"""

      filename = "material_records.csv"

      # 如果文件不存在,创建文件并写入UTF-8 BOM表头

      if not os.path.exists(filename):

          with codecs.open(filename, 'w', encoding='utf-8-sig') as f:

              f.write("时间,姓名,部门,耗材类型,数量\n")

      # 追加记录(使用utf-8-sig编码解决Excel中文乱码问题)

      with codecs.open(filename, 'a', encoding='utf-8-sig') as f:

          f.write(f"{record['timestamp'].strftime('%Y-%m-%d %H:%M:%S')},"

                 f"{record['name']},{record['department']},"

                 f"{record['material']},{record['quantity']}\n")

  def load_existing_records(self):

      """加载已有的记录(支持多种编码尝试)"""

      filename = "material_records.csv"

      if os.path.exists(filename):

          try:

              # 尝试多种编码方式读取

              encodings = ['utf-8-sig', 'gbk', 'utf-8', 'latin-1']

              for encoding in encodings:

                  try:

                      with codecs.open(filename, 'r', encoding=encoding) as f:

                          lines = f.readlines()

                      # 跳过表头

                      for line in lines[1:]:

                          parts = line.strip().split(',')

                          if len(parts) == 5:

                              record = {

                                  'timestamp': datetime.strptime(parts[0], '%Y-%m-%d %H:%M:%S'),

                                  'name': parts[1],

                                  'department': parts[2],

                                  'material': parts[3],

                                  'quantity': int(parts[4])

                              }

                              self.records.append(record)

                      print(f"成功使用 {encoding} 编码加载记录")

                      break

                  except UnicodeDecodeError:

                      continue

                  except Exception as e:

                      print(f"使用 {encoding} 编码加载失败: {e}")

                      continue

          except Exception as e:

              print(f"加载记录时出错: {e}")

              QMessageBox.warning(self, "加载错误", f"加载历史记录时出错: {e}")

  def export_to_excel(self):

      """导出为Excel文件(解决中文乱码问题)"""

      if not self.records:

          QMessageBox.information(self, "导出提示", "没有记录可以导出!")

          return

      try:

          # 创建DataFrame

          df = pd.DataFrame(self.records)

          # 重命名列名为中文

          df = df.rename(columns={

              'timestamp': '申请时间',

              'name': '姓名',

              'department': '部门',

              'material': '耗材类型',

              'quantity': '数量'

          })

          # 格式化时间列

          df['申请时间'] = df['申请时间'].apply(lambda x: x.strftime("%Y-%m-%d %H:%M:%S"))

          # 导出为Excel

          excel_filename = f"耗材申请记录_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"

          df.to_excel(excel_filename, index=False, engine='openpyxl')

          QMessageBox.information(self, "导出成功", f"记录已成功导出为: {excel_filename}")

      except Exception as e:

          QMessageBox.critical(self, "导出错误", f"导出Excel文件时出错: {e}")

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OcK3-2dd7t41P03PpZV6itAw0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券