# coding: gb2312 from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt from PyQt5.QtCore import QTimer from LSZXPagesManagerLibrary.consensus import * from LSZXPagesManagerLibrary.person_page_layout_define import PersonPageLayoutDefine from LSZXPagesManagerLibrary.pop_add_person_dialog import PopAddPersonDialog from LSZXPagesManagerLibrary.pop_synchronization_dialog import PopDialogSynchronization from PureBackend.global_execrise_backend import GEB class PersonPage(PersonPageLayoutDefine): def __init__(self): super(PersonPage, self).__init__() # 预加载geb模块 self.eb = GEB().get_geb() self.column_names = ['', '姓名', '编号', '手环编号', '班级', '年龄', '性别', '身高(cm)', '体重(kg)', 'BMI', 'PBF', '操作'] self.header_type_table = HEADER_TYPE_TABLE self.genders = ["男", "女"] # 用于下拉框的选项 self.class_data = None self.name = None # 班级列表 self.class_list = ['所有'] # 人员信息同步按钮事件 self.person_synchronization_button.clicked.connect(self.person_synchronization_button_action) # Excel导入人员信息按钮事件 self.excel_import_button.clicked.connect(self.excel_import_button_action) # Excel导出人员信息按钮事件 self.excel_export_button.clicked.connect(self.excel_export_button_action) self.add_person_button.clicked.connect(self.add_person_button_action) # 人员信息同步加载进度条弹窗 self.pop_dialog_synchronization = PopDialogSynchronization(self) self.pop_dialog_synchronization.connect(self.synchronization_button_action) # 全选/取消全选按钮事件 self.select_all_button.clicked.connect(self.select_all_action) self.delete_persons_button.clicked.connect(self.delete_persons_action) # 人员信息同步加载进度条弹窗 self.pop_add_person_dialog = PopAddPersonDialog(self) self.pop_add_person_dialog.connect(self.pop_commit_add_person) # 表格渲染方法 data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data) # 获取班级列表 self.get_class_list() # 获取并设置进度定时器 self.status_num = 0 self.timer_get_processing = QTimer() self.timer_get_processing.timeout.connect(self.get_synchronization_processing) # self.timer_get_processing.start(1000) # 获取姓名输入框内容事件 self.name_editbox.textChanged.connect(self.get_name_value) # 班级下拉框事件 self.class_combobox.currentIndexChanged.connect(self.class_combobox_changed) # 获取班级列表 def get_class_list(self): self.class_list = ['所有'] response_data = self.eb.get_all_class() self.class_list += response_data for item in self.class_list: self.class_combobox.addItem(item) def table_function(self, data): # self.column_names = ['', '姓名', '编号', '手环编号', '班级', '年龄', '性别', '身高(cm)', '体重(kg)', 'BMI', 'PBF', '操作'] self.table_widget.setColumnCount(len(self.column_names)) self.table_widget.setHorizontalHeaderLabels(self.column_names) # 设置表头样式 header = self.table_widget.horizontalHeader() header.setStyleSheet(""" QHeaderView::section { background-color: #f5f7fa; border-top: none; border-left: none; border-right: 1px solid #d8d8d8; border-bottom: 1px solid #d8d8d8; font: 600 20px 'Microsoft YaHei UI'; } """) # 设置行数并填充数据 self.table_widget.setRowCount(len(data)) self.check_box_list = [] # 用于存储所有的 QCheckBox 对象 for row_index, row_data in enumerate(data): # 添加复选框 check_box = QCheckBox() # 创建一个新的 QWidget 来容纳复选框并使其居中 check_box_widget = QWidget() check_box_layout = QHBoxLayout(check_box_widget) check_box_layout.addWidget(check_box, alignment=Qt.AlignCenter) self.table_widget.setCellWidget(row_index, 0, check_box_widget) check_box.stateChanged.connect(lambda state, row=row_index: self.print_row_info(state, row)) self.check_box_list.append(check_box) # 将复选框添加到列表中 for col_index, col_name in enumerate(self.column_names[1:]): if col_name == self.header_type_table[NAME]: value = row_data['name'] elif col_name == self.header_type_table[ID]: value = str(row_data['id']) elif col_name == self.header_type_table[CLASS]: value = row_data['class'] elif col_name == self.header_type_table[GENDER]: value = row_data['gender'] elif col_name == self.header_type_table[BAND_ID]: value = row_data['band_id'] elif col_name == self.header_type_table[AGE]: value = str(row_data['age']) elif col_name == self.header_type_table[HEIGHT]: value = str(row_data['height']) elif col_name == self.header_type_table[WEIGHT]: value = str(row_data['weight']) elif col_name == self.header_type_table[BMI]: value = str(row_data['bmi']) elif col_name == self.header_type_table[PBF]: value = str(row_data['pbf']) else: value = "" item = QTableWidgetItem(value) item.setTextAlignment(Qt.AlignCenter) # 设置文字居中 self.table_widget.setItem(row_index, col_index + 1, item) # 分配手环按钮 distribute_band_button = QPushButton("分配手环") distribute_band_button.setStyleSheet('color: #409eff') # 更新编辑按钮 h_layout = QHBoxLayout() stacked_widget = QStackedWidget() edit_button = QPushButton("更新") edit_button.setStyleSheet('color: #409eff') update_button = QPushButton("保存") update_button.setStyleSheet('color: #f56c6c') stacked_widget.addWidget(edit_button) stacked_widget.addWidget(update_button) h_layout.addWidget(stacked_widget) edit_button.clicked.connect(lambda _, row=row_index: self.edit_row(row)) update_button.clicked.connect(lambda _, row=row_index: self.update_row(row)) # 删除按钮 delete_button = QPushButton("删除") delete_button.setStyleSheet('color: #409eff') delete_button.clicked.connect(lambda _, row=row_index: self.delete_row(row)) # 创建操作列的布局 operation_layout = QHBoxLayout() operation_layout.setContentsMargins(30, 0, 30, 0) operation_layout.addWidget(distribute_band_button) operation_layout.addLayout(h_layout) operation_layout.addWidget(delete_button) # 将操作布局设置为操作列的单元格 operation_widget = QWidget() operation_widget.setLayout(operation_layout) self.table_widget.setCellWidget(row_index, len(self.column_names) - 1, operation_widget) # 使表格宽度撑满屏幕 # self.table_widget.horizontalHeader().setStretchLastSection(True) self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 设置第一列(复选框列)宽度为 50px self.table_widget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed) self.table_widget.setColumnWidth(0, 50) # 设置第三列(手环编号列)宽度为 200px self.table_widget.horizontalHeader().setSectionResizeMode(3, QHeaderView.Fixed) self.table_widget.setColumnWidth(3, 200) # 设置最后一列(操作列)宽度为 300px self.table_widget.horizontalHeader().setSectionResizeMode(len(self.column_names) - 1, QHeaderView.Fixed) self.table_widget.setColumnWidth(len(self.column_names) - 1, 300) # 使表格行高和列宽自适应 self.table_widget.verticalHeader().setDefaultSectionSize(50) # 双击时不能对表格内容进行修改 self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) def print_row_info(self, state, row): if state == Qt.Checked: row_data = {} for col_index in range(self.table_widget.columnCount()): item = self.table_widget.item(row, col_index) if item: row_data[self.table_widget.horizontalHeaderItem(col_index).text()] = item.text() def select_all_action(self): if self.select_all_button.text() == "全选": for check_box in self.check_box_list: check_box.setChecked(True) self.select_all_button.setText("取消全选") else: for check_box in self.check_box_list: check_box.setChecked(False) self.select_all_button.setText("全选") def delete_persons_action(self): selected_person_ids = [] for check_box in self.check_box_list: row = self.table_widget.indexOf(check_box) if check_box.isChecked(): # 检查此复选框是否被选中 id_item = self.table_widget.item(row, 2) if id_item: person_id = id_item.text() selected_person_ids.append(person_id) def edit_row(self, row): # print(f"编辑行 {row}: 姓名 - {self.table_widget.item(row, 1).text()}, ID - {self.table_widget.item(row, 2).text()}") self.table_widget.item(row, 1).setFlags(Qt.ItemIsEnabled) # 姓名 self.table_widget.item(row, 2).setFlags(Qt.ItemIsEnabled) # 编号 self.table_widget.item(row, 4).setFlags(Qt.ItemIsEnabled) # 班级 self.table_widget.item(row, 5).setFlags(Qt.ItemIsEnabled) # 年龄 self.table_widget.item(row, 6).setFlags(Qt.ItemIsEnabled) # 性别 self.table_widget.item(row, 7).setFlags(Qt.ItemIsEnabled) # 身高 self.table_widget.item(row, 8).setFlags(Qt.ItemIsEnabled) # 体重 self.table_widget.item(row, 9).setFlags(Qt.ItemIsEnabled) # BMI self.table_widget.item(row, 10).setFlags(Qt.ItemIsEnabled) # PBF name_edit = QLineEdit(self.table_widget.item(row, 1).text()) id_edit = QLineEdit(self.table_widget.item(row, 2).text()) class_edit = QLineEdit(self.table_widget.item(row, 4).text()) age_edit = QLineEdit(self.table_widget.item(row, 5).text()) gender_combo = QComboBox() gender_combo.addItems(self.genders) gender_combo.setCurrentText(self.table_widget.item(row, 6).text()) height_edit = QLineEdit(self.table_widget.item(row, 7).text()) weight_edit = QLineEdit(self.table_widget.item(row, 8).text()) bmi_edit = QLineEdit(self.table_widget.item(row, 9).text()) pbf_edit = QLineEdit(self.table_widget.item(row, 10).text()) self.line_edit_style(name_edit) self.line_edit_style(id_edit) self.line_edit_style(class_edit) self.line_edit_style(gender_combo) self.line_edit_style(age_edit) self.line_edit_style(height_edit) self.line_edit_style(weight_edit) self.line_edit_style(bmi_edit) self.line_edit_style(pbf_edit) self.table_widget.setCellWidget(row, 1, name_edit) self.table_widget.setCellWidget(row, 2, id_edit) self.table_widget.setCellWidget(row, 4, class_edit) self.table_widget.setCellWidget(row, 5, age_edit) self.table_widget.setCellWidget(row, 6, gender_combo) self.table_widget.setCellWidget(row, 7, height_edit) self.table_widget.setCellWidget(row, 8, weight_edit) self.table_widget.setCellWidget(row, 9, bmi_edit) self.table_widget.setCellWidget(row, 10, pbf_edit) # 切换到更新按钮 stacked_widget = self.table_widget.cellWidget(row, len(self.column_names) - 1).findChild(QStackedWidget) stacked_widget.setCurrentIndex(1) def update_row(self, row): person_data = { 'name': self.table_widget.cellWidget(row, 1).text(), 'id': self.table_widget.cellWidget(row, 2).text(), 'class': self.table_widget.cellWidget(row, 4).text(), 'age': self.table_widget.cellWidget(row, 5).text(), 'gender': self.table_widget.cellWidget(row, 6).currentText(), 'height': self.table_widget.cellWidget(row, 7).text(), 'weight': self.table_widget.cellWidget(row, 8).text(), 'bmi': self.table_widget.cellWidget(row, 9).text(), 'pbf': self.table_widget.cellWidget(row, 10).text(), 'person_type': None } response_code = self.eb.update_person(person_data) if response_code == 1: data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data) self.table_widget.setCellWidget(row, 1, None) self.table_widget.setCellWidget(row, 2, None) self.table_widget.setCellWidget(row, 4, None) self.table_widget.setCellWidget(row, 5, None) self.table_widget.setCellWidget(row, 6, None) self.table_widget.setCellWidget(row, 7, None) self.table_widget.setCellWidget(row, 8, None) self.table_widget.setCellWidget(row, 9, None) self.table_widget.setCellWidget(row, 10, None) # 切换回编辑按钮 stacked_widget = self.table_widget.cellWidget(row, len(self.column_names) - 1).findChild(QStackedWidget) stacked_widget.setCurrentIndex(0) def delete_row(self, row): person_to_be_del = self.table_widget.item(row, 2).text() _id_list = [person_to_be_del] self.eb.delete_person(_id_list) data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data) def person_synchronization_button_action(self): # 启动定时器 self.start_get_processing() self.pop_dialog_synchronization.show() # 开启数据同步 self.eb.send_data_synchronization() # 重新加载 data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data) self.get_class_list() def synchronization_button_action(self): self.eb.stop_data_synchronization() # print('点击取消同步按钮') # 导入人员excel def excel_import_button_action(self): options = QFileDialog.Options() file_name, _ = QFileDialog.getOpenFileName(self, "选择 Excel 文件", "", "Excel 文件 (*.xls *.xlsx)", options=options) if file_name: self.eb.load_xlsx(file_name) self.get_class_list() data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data) # 导出人员excel def excel_export_button_action(self): folder = QFileDialog.getExistingDirectory(self, "选择文件夹") if folder: self.eb.get_person_xlsx(folder) # print(f"选择的文件夹路径: {folder}") def add_person_button_action(self): self.pop_add_person_dialog.show() def pop_commit_add_person(self): data = self.pop_add_person_dialog.get_data_value() response_code = self.eb.add_person(data) if response_code == 1: self.pop_add_person_dialog.clear_fields() data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data) def line_edit_style(self, line_edit): line_edit.setStyleSheet( "border: 1px solid #222222;" "border-radius: 4px;" "margin: 4px;" "padding-left: 6px;" ) def start_get_processing(self): self.timer_get_processing.start(50) def stop_get_processing(self): self.timer_get_processing.stop() # 获取同步进度进度 def get_synchronization_processing(self): processing_data = self.eb.get_synchronization_processing() task_had_done = processing_data['task_had_done'] task_num = processing_data['task_number'] status = processing_data['status'] if task_num > 0: processing = int((task_had_done / task_num) * 100) else: processing = 0 self.pop_dialog_synchronization.circle_percentage.set_data(processing) if status == 2 or status == 0: self.status_num += 1 if self.status_num >= 3: self.stop_get_processing() self.pop_dialog_synchronization.close() self.status_num = 0 # 搜索班级 def class_combobox_changed(self): self.class_data = self.class_combobox.currentText() if self.class_data == "所有": self.class_data = None data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data) # 搜索姓名 def get_name_value(self): self.name = self.name_editbox.text() data = self.eb.get_person(_class=self.class_data, name=self.name) self.table_function(data)