java isselected_Java SelectionModel.isSelected方法代码示例

这篇博客深入解析了Google Web Toolkit (GWT) 中CellBrowser组件的renderRowValues方法,该方法用于渲染表格行。内容涉及如何处理选中状态、展开状态以及焦点元素,并展示了如何使用SelectionModel、样式和模板来构建复杂表格布局。同时,文章涵盖了键盘导航、焦点处理以及CSS类的动态应用等细节。

import com.google.gwt.view.client.SelectionModel; //导入方法依赖的package包/类

@Override

protected void renderRowValues(SafeHtmlBuilder sb, List values, int start,

SelectionModel super T> selectionModel) {

Cell cell = getCell();

String keyboardSelectedItem = " " + style.cellBrowserKeyboardSelectedItem();

String selectedItem = " " + style.cellBrowserSelectedItem();

String openItem = " " + style.cellBrowserOpenItem();

String evenItem = style.cellBrowserEvenItem();

String oddItem = style.cellBrowserOddItem();

int keyboardSelectedRow = getKeyboardSelectedRow() + getPageStart();

int length = values.size();

int end = start + length;

for (int i = start; i < end; i++) {

T value = values.get(i - start);

boolean isSelected = selectionModel == null ? false : selectionModel.isSelected(value);

boolean isOpen = isOpen(i);

StringBuilder classesBuilder = new StringBuilder();

classesBuilder.append(i % 2 == 0 ? evenItem : oddItem);

if (isOpen) {

classesBuilder.append(openItem);

}

if (isSelected) {

classesBuilder.append(selectedItem);

}

SafeHtmlBuilder cellBuilder = new SafeHtmlBuilder();

Context context = new Context(i, 0, getValueKey(value));

cell.render(context, value, cellBuilder);

// Figure out which image to use.

SafeHtml image;

if (isOpen) {

image = openImageHtml;

} else if (isLeaf(value)) {

image = LEAF_IMAGE;

} else {

image = closedImageHtml;

}

SafeStyles padding =

SafeStylesUtils.fromTrustedString("padding-right: " + imageWidth + "px;");

if (i == keyboardSelectedRow) {

// This is the focused item.

if (isFocused) {

classesBuilder.append(keyboardSelectedItem);

}

char accessKey = getAccessKey();

if (accessKey != 0) {

sb.append(template.divFocusableWithKey(i, classesBuilder.toString(), padding,

getTabIndex(), getAccessKey(), image, cellBuilder.toSafeHtml()));

} else {

sb.append(template.divFocusable(i, classesBuilder.toString(), padding, getTabIndex(),

image, cellBuilder.toSafeHtml()));

}

} else {

sb.append(template.div(i, classesBuilder.toString(), padding, image, cellBuilder

.toSafeHtml()));

}

}

// Update the child state.

updateChildState(this, true);

}

def edit_CQR_table(self, pos): # 检查 pos 是否有效 if not isinstance(pos, QtCore.QPoint): return menu = QMenu(self) action_add_now_disease_Window = QAction("添加", self) action_delete_now_disease = QAction("删除", self) action_revise_now_disease = QAction("修改", self) menu.addAction(action_add_now_disease_Window) menu.addAction(action_delete_now_disease) menu.addAction(action_revise_now_disease) action_add_now_disease_Window.triggered.connect(self.add_now_disease) action_delete_now_disease.triggered.connect(self.delete_now_disease) action_revise_now_disease.triggered.connect(self.revise_now_diseas) menu.exec_(self.ui.tableWidget__CQR_now_disease.viewport().mapToGlobal(pos)) def add_now_disease(self): self.now_disease_Window = now_disease_Window(mode='add', parent=self) self.now_disease_Window.operation_completed.connect(self.load_data) # 连接操作完成信号 self.now_disease_Window.show() def revise_now_diseas(self): selected_rows = self.ui.tableWidget__CQR_now_disease.selectionModel().selectedRows() if not selected_rows: #selectionModel().selectedRows() 可以更准确、安全地获取用户当前选中的 整行 数据,而不是仅仅依赖于某些单元格的内容。 QMessageBox.warning(self, "警告", "请先选择一行记录") return row_idx = selected_rows[0].row() symptom_name = self.ui.tableWidget__CQR_now_disease.item(row_idx, 0).text() if self.edit_window: self.edit_window.close() self.now_disease_Window = now_disease_Window( mode='edit', symptom_name=symptom_name, parent=self ) self.now_disease_Window.operation_completed.connect(self.CQR_now_disease) # 连接操作完成信号 self.now_disease_Window.show() def delete_now_disease(self): selected_rows = self.ui.tableWidget__CQR_now_disease.selectionModel().selectedRows() if not selected_rows: QMessageBox.warning(self, "警告", "请先选择一行记录") return row_idx = selected_rows[0].row() symptom_name = self.ui.tableWidget__CQR_now_disease.item(row_idx, 0).text() reply = QMessageBox.question( self, '确认删除', f"确定要删除症状 '{symptom_name}' 吗?", QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.Yes: try: with POOL.connection() as conn: with conn.cursor() as cursor: cursor.execute("DELETE FROM `现病史` WHERE 症状 = %s", (symptom_name,)) conn.commit() self.CQR_now_disease() # 刷新表格 QMessageBox.information(self, "成功", "症状已成功删除") except Exception as e: conn.rollback() QMessageBox.critical(self, "数据库错误", f"删除失败: {str(e)}") class now_disease_Window(QMainWindow): operation_completed = pyqtSignal() def __init__(self, mode=None, symptom_name=None, parent=None): super().__init__(parent) self.ui = Ui_now_disease_Window() self.ui.setupUi(self) self.mode = mode # 'add' 或 'edit' self.symptom_name = symptom_name self.show() # if self.mode == 'add': # self.ui.pushButton.setText("添加") # 设置按钮文本为"添加" # self.ui.pushButton.clicked.connect(self.submit_data) if self.mode == 'edit': self.show_disease() # 自动加载现有数据 self.ui.pushButton.clicked.connect(self.update_disease) # 连接更新方法 self.ui.pushButton.setText("更新") # 设置按钮文本为"更新" def submit_data(self): """提交数据到数据库""" disease = self.ui.lineEdit.text() detail = self.ui.textEdit.toPlainText() pinyin_list = lazy_pinyin(disease, style=Style.FIRST_LETTER) pinyin_text = ''.join(pinyin_list) # 设置文本框显示值 self.ui.lineEdit_2.setText(pinyin_text) # 简单的验证 if not disease: QMessageBox.warning(self, "输入错误", "请输入要添加的内容!") return if not detail: QMessageBox.warning(self, "输入错误", "请输入问诊要点!") return try: with POOL.connection() as conn: with conn.cursor() as cursor: # 添加新记录 sql = "INSERT INTO `现病史` (症状,问诊要点,首拼) VALUES (%s, %s, %s)" cursor.execute(sql, (disease,detail, pinyin_text)) conn.commit() if cursor.rowcount > 0: QMessageBox.information(self, "成功", "数据添加成功!") self.operation_completed.emit() else: QMessageBox.warning(self, "失败", "数据添加失败,请重试。") except Exception as e: conn.rollback() QMessageBox.critical(self, "数据库错误", f"操作失败: {str(e)}") def show_disease(self): try: with POOL.connection() as conn: with conn.cursor() as cursor: sql = """SELECT 症状,问诊要点,首拼 FROM `现病史` WHERE `症状` = %s""" cursor.execute(sql, (self.symptom_name,)) symptom_data = cursor.fetchone() # 返回字典 if symptom_data: # 使用字段名访问数据 self.ui.lineEdit.setText(symptom_data['症状']) self.ui.lineEdit_2.setText(symptom_data['首拼']) self.ui.textEdit.setPlainText(symptom_data['问诊要点']) else: QMessageBox.warning(self, "失败", "症状查询失败。") except Exception as e: conn.rollback() QMessageBox.critical(self, "数据库错误", f"操作失败: {str(e)}") def update_disease(self): disease = self.ui.lineEdit.text() detail = self.ui.textEdit.toPlainText() shoupin = self.ui.lineEdit_2.text() try: with POOL.connection() as conn: with conn.cursor() as cursor: sql = """ UPDATE `现病史` SET `症状` = %s, `首拼` = %s, `问诊要点` = %s, WHERE `症状` = %s """ cursor.execute(sql, (disease, shoupin, detail, self.symptom_name)) conn.commit() if cursor.rowcount > 0: QMessageBox.information(self, "成功", "数据更新成功!") self.operation_completed.emit() else: QMessageBox.warning(self, "失败", "数据更新失败,请重试。") except Exception as e: conn.rollback() QMessageBox.critical(self, "数据库错误", f"操作失败: {str(e)}") 为什么点击右键菜单里的按键后立刻卡退,除了删除有用
07-27
设计这样的类型名称为英文,定义名称为中文,标注标号的josn格式存储,文件名为parts_list同时在以下页面中添加"新增配件明细按钮”,打开页面,实现对josn格式的文件增删改查的业务,在以下代码中实现那#配件包配置编辑对话框 class ComponentPackageDialog(QDialog): """配件包配置编辑对话框""" def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("配件包配置") self.setMinimumSize(800, 600) # 关键修复1:在设置背景前应用Fusion样式 self.setStyle(QStyleFactory.create("Fusion")) self.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_new_form_backcolor_style()) # 关键修复3:确保布局有背景设置 self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.Window, QColor(255, 255, 255)) self.setPalette(palette) # 加载配置 self.config_file = "component_packages.json" self.packages = self.load_config() self.init_ui() def init_ui(self): main_layout = QVBoxLayout() # 关键修复4:为布局添加边距避免控件贴边 main_layout.setContentsMargins(15, 15, 15, 15) main_layout.setSpacing(10) # 顶部标题 #title_label = QLabel("配件包配置管理系统") #title_label.setAlignment(Qt.AlignCenter) #title_label.setStyleSheet("font-size: 18px; font-weight: bold; margin: 10px;") #main_layout.addWidget(title_label) # === 新增:查询区域 === search_layout = QHBoxLayout() # 目标类型下拉选择框 search_layout.addWidget(QLabel("目标明细查询:")) self.search_box = QComboBox() self.search_box.setEditable(True) # 允许输入 self.search_box.setMinimumWidth(200) self.search_box.setStyleSheet("background-color: white;") self.populate_search_options() # 填充下拉选项 # 查询按钮 self.search_btn = QPushButton("查询") self.search_btn.clicked.connect(self.search_packages) search_layout.addWidget(self.search_box) search_layout.addWidget(self.search_btn) # 重置按钮 self.reset_btn = QPushButton("显示全部") self.reset_btn.clicked.connect(self.reset_search) search_layout.addWidget(self.reset_btn) search_layout.addStretch(1) # 添加弹性空间使控件靠左 main_layout.addLayout(search_layout) # 按钮区域 btn_layout = QHBoxLayout() self.add_btn = QPushButton("添加配件包") self.add_btn.clicked.connect(self.add_package) btn_layout.addWidget(self.add_btn) self.edit_btn = QPushButton("编辑选中项") self.edit_btn.clicked.connect(self.edit_package) btn_layout.addWidget(self.edit_btn) self.delete_btn = QPushButton("删除选中项") self.delete_btn.clicked.connect(self.delete_package) btn_layout.addWidget(self.delete_btn) # 新增状态切换按钮 self.toggle_status_btn = QPushButton("启用/禁用") self.toggle_status_btn.clicked.connect(self.toggle_package_status) self.toggle_status_btn.setEnabled(True) # 初始禁用 btn_layout.addWidget(self.toggle_status_btn) button_box = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel) button_box.accepted.connect(self.save_config) button_box.rejected.connect(self.reject) btn_layout.addWidget(button_box) # 关键修复6:添加弹性空间使按钮居中 btn_layout.addStretch(1) main_layout.addLayout(btn_layout) # 底部按钮 # button_box = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel) # button_box.accepted.connect(self.save_config) # button_box.rejected.connect(self.reject) # main_layout.addWidget(button_box) # 表格展示区域 self.table = QTableWidget() self.table.setColumnCount(6) # 新增第五列用于明细 self.table.setHorizontalHeaderLabels([ "配件包ID", "名称", "显示名称", "目标种类", "目标明细", "状态" # 新增状态列 ]) self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents) # ID列自适应 self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeToContents) # 名称列拉伸 self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeToContents) # 显示名称列拉伸 self.table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeToContents) # 数量列自适应 self.table.horizontalHeader().setSectionResizeMode(4, QHeaderView.Stretch) # 明细列拉伸 self.table.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeToContents) # 状态列自适应 #self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) # 关键修复5:设置表格透明背景 self.table.setStyleSheet("background-color: rgba(255, 255, 255, 0.7);") self.populate_table() main_layout.addWidget(self.table) self.setLayout(main_layout) # 连接信号:当选择发生变化时更新按钮状态 self.table.selectionModel().selectionChanged.connect(self.update_button_status_based_on_selection) # 关键修复7:确保背景设置生效 self.update() def update_button_status_based_on_selection(self): """根据选中行的状态更新按钮文本""" if self.table.selectionModel().selectedRows(): row = self.table.selectionModel().selectedRows()[0].row() package = self.packages[row] current_status = package.get("enabled", True) # 如果当前状态是启用,则按钮显示"禁用",反之亦然 self.toggle_status_btn.setText("禁用" if current_status else "启用") # 同时更新按钮的颜色提示 if current_status: self.toggle_status_btn.setStyleSheet("background-color: #ffcccc;") # 浅红色表示禁用操作 else: self.toggle_status_btn.setStyleSheet("background-color: #ccffcc;") # 浅绿色表示启用操作 #else: # 没有选中行时禁用按钮 #self.toggle_status_btn.setEnabled(False) #self.toggle_status_btn.setText("启用/禁用") #self.toggle_status_btn.setStyleSheet("") # 清除样式 def populate_search_options(self): """填充目标明细查询下拉框的选项(只保留正文名称)""" self.search_box.clear() self.search_box.addItem("") # 空选项 # 收集所有独特的目标正文名称 unique_names = set() for package in self.packages: for target in package.get("targets", []): # 获取正文名称(优先使用def_name,其次display_name,最后使用type) name = target.get("def_name") or target.get("display_name") or target.get("type", "") if name: # 确保名称有效 unique_names.add(name) # 按字母顺序添加选项 for name in sorted(unique_names): self.search_box.addItem(name) def format_target_description(self, target): """格式化目标类型为查询选项文本""" english_type = target.get("type", "unknown") chinese_name = target.get("def_name") or target.get("display_name") or target.get("type") count = target.get("count", 1) return f"{chinese_name}({english_type}):{count}个" def search_packages(self): """根据输入的目标中文名称查询符合条件的配件包""" search_text = self.search_box.currentText().strip() # 如果没有输入文本,显示全部 if not search_text: self.reset_search() return # 查询符合条件的配件包 matching_packages = [] for package in self.packages: # 检查当前配件包的所有目标 for target in package.get("targets", []): # 检查中文名称(def_name, display_name, type) def_name = target.get("def_name", "").lower() display_name = target.get("display_name", "").lower() type_name = target.get("type", "").lower() # 检查是否匹配 if (search_text.lower() in def_name or search_text.lower() in display_name or search_text.lower() in type_name): matching_packages.append(package) break # 找到一个匹配的目标即可,跳出内层循环 # 更新表格显示查询结果 self.display_packages(matching_packages) # 显示查询结果统计 QMessageBox.information( self, "查询结果", f"找到 {len(matching_packages)} 个包含目标 '{search_text}' 的配件包" ) def display_packages(self, packages): """显示指定的配件包列表""" sorted_packages = sorted( packages, key=lambda p: (not p.get('enabled', False), p.get('display_name', '').lower()), reverse=False ) self.table.setRowCount(len(sorted_packages)) for row, package in enumerate(sorted_packages): # 配件包ID id_item = QTableWidgetItem(str(row + 1)) id_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(row, 0, id_item) # 名称 self.table.setItem(row, 1, QTableWidgetItem(package.get("name", ""))) # 显示名称 self.table.setItem(row, 2, QTableWidgetItem(package.get("display_name", ""))) # 目标类型数量 targets_count = len(package.get("targets", [])) count_item = QTableWidgetItem(str(targets_count)) count_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(row, 3, count_item) # 目标类型明细 - 新增列 details = self.format_target_details(package.get("targets", [])) detail_item = QTableWidgetItem(details) detail_item.setToolTip(details) # 添加悬停提示 self.table.setItem(row, 4, detail_item) status = package.get("enabled", False) # 默认为启用状态 status_item = QTableWidgetItem("启用" if status else "禁用") status_item.setTextAlignment(Qt.AlignCenter) # 根据状态设置文本颜色 if status: status_item.setForeground(QColor(0, 128, 0)) # 启用状态绿色 else: status_item.setForeground(QColor(255, 0, 0)) # 禁用状态红色 self.table.setItem(row, 5, status_item) self.update_button_status_based_on_selection() def reset_search(self): """重置查询,显示所有配件包""" self.search_box.setCurrentIndex(0) # 清空搜索框 self.populate_table() # 显示所有配件包 def populate_table(self): """填充表格数据""" # 按状态排序:先启用(True)后禁用(False) sorted_packages = sorted( self.packages, key=lambda p: (not p.get('enabled', False), p.get('display_name', '').lower()), reverse=False ) self.table.setRowCount(len(sorted_packages)) # 设置最小行高以容纳明细文本 self.table.verticalHeader().setDefaultSectionSize(80) for row, package in enumerate(sorted_packages): # 配件包ID id_item = QTableWidgetItem(str(row + 1)) id_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(row, 0, id_item) # 名称 self.table.setItem(row, 1, QTableWidgetItem(package.get("name", ""))) # 显示名称 self.table.setItem(row, 2, QTableWidgetItem(package.get("display_name", ""))) # 目标类型数量 targets_count = len(package.get("targets", [])) count_item = QTableWidgetItem(str(targets_count)) count_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(row, 3, count_item) # 目标类型明细 - 新增列 details = self.format_target_details(package.get("targets", [])) detail_item = QTableWidgetItem(details) detail_item.setToolTip(details) # 添加悬停提示 self.table.setItem(row, 4, detail_item) status = package.get("enabled", False) # 默认为启用状态 status_item = QTableWidgetItem("启用" if status else "禁用") status_item.setTextAlignment(Qt.AlignCenter) # 根据状态设置文本颜色 if status: status_item.setForeground(QColor(0, 128, 0)) # 启用状态绿色 else: status_item.setForeground(QColor(255, 0, 0)) # 禁用状态红色 self.table.setItem(row, 5, status_item) self.update_button_status_based_on_selection() def format_target_details(self, targets): """格式化目标类型明细为多行文本""" details = [] # for target in targets: # type_name = target.get("type", "未知类型") # count = target.get("count", 1) # details.append(f"{type_name}: {count}个") # 获取英文类型标识符 for target in targets: english_type = target.get("type", "unknown") # 获取中文描述(优先使用def_name,不存在则使用display_name) chinese_name = target.get("def_name") or target.get("display_name") # 组合中英文显示格式 display_type = f"{chinese_name}({english_type})" # 获取数量 count = target.get("count", 1) # 格式化条目 details.append(f"{display_type}: {count}个") return "\n".join(details) if details else "无目标类型" def load_config(self): """加载配置文件""" if os.path.exists(self.config_file): try: with open(self.config_file, 'r', encoding='utf-8') as f: packages = json.load(f) # 为旧数据添加默认状态字段 for package in packages: if "enabled" not in package: package["enabled"] = False return packages except: return [] return [] def save_config(self): """保存配置到文件""" try: with open(self.config_file, 'w', encoding='utf-8') as f: json.dump(self.packages, f, ensure_ascii=False, indent=2) QMessageBox.information(self, "成功", "配置已成功保存!") self.accept() except Exception as e: QMessageBox.critical(self, "错误", f"保存配置失败: {str(e)}") def get_selected_package(self): """获取选中的配件包""" """获取选中的配件包 - 更新按钮状态""" selected_rows = self.table.selectionModel().selectedRows() if not selected_rows: # 没有选中行时禁用操作按钮 self.edit_btn.setEnabled(False) self.delete_btn.setEnabled(False) self.toggle_status_btn.setEnabled(False) return None # 有选中行时启用按钮 self.edit_btn.setEnabled(True) self.delete_btn.setEnabled(True) self.toggle_status_btn.setEnabled(True) # 获取选中行索引 row = selected_rows[0].row() # 更新状态按钮文本 current_status = self.packages[row].get("enabled", True) self.toggle_status_btn.setText("禁用" if current_status else "启用") return row def add_package(self): """添加新配件包""" dialog = PackageEditDialog(self) if dialog.exec_() == QDialog.Accepted: new_package = dialog.get_data() new_package["enabled"] = False # 新增配件包默认禁用 self.packages.append(new_package) self.populate_table() def edit_package(self): """编辑选中的配件包""" """编辑选中的配件包 - 保留状态字段""" # row = self.get_selected_package() # if row is None: # return selected_rows = self.table.selectionModel().selectedRows() # 1. 检查是否有选中行 if not selected_rows: # 提供明确的用户反馈 QMessageBox.warning( self, "未选中配件包", "请先选中一个配件包进行编辑!" ) return # 2. 获取选中行索引 row = selected_rows[0].row() # 3. 验证行索引有效性 if row < 0 or row >= len(self.packages): QMessageBox.critical( self, "无效选择", f"选中的行索引无效: {row} (总配件包数: {len(self.packages)})" ) return # 保留当前状态 current_status = self.packages[row].get("enabled", True) dialog = PackageEditDialog(self, self.packages[row]) if dialog.exec_() == QDialog.Accepted: edited_data = dialog.get_data() edited_data["enabled"] = current_status # 编辑后保持原状态 self.packages[row] = edited_data self.populate_table() def delete_package(self): """删除选中的配件包""" selected_rows = self.table.selectionModel().selectedRows() # 1. 检查是否有选中行 if not selected_rows: # 提供明确的用户反馈 QMessageBox.warning( self, "未选中配件包", "请先选中一个配件包进行删除!" ) return # 2. 获取选中行索引 row = selected_rows[0].row() # 3. 验证行索引有效性 if row < 0 or row >= len(self.packages): QMessageBox.critical( self, "无效选择", f"选中的行索引无效: {row} (总配件包数: {len(self.packages)})" ) return reply = QMessageBox.question( self, "确认删除", f"确定要删除 '{self.packages[row].get('name', '')}' 配件包吗?", QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.Yes: del self.packages[row] self.populate_table() def toggle_package_status(self): """启用/禁用选中的配件包""" row = self.get_selected_package() if row is None: return # 获取当前状态 package = self.packages[row] current_status = self.packages[row].get("enabled", True) # 切换状态 new_status = not current_status package["enabled"] = new_status # 更新表格显示 self.update_package_row(row, package) # 更新按钮文本 self.update_button_status(row) # 显示状态变更通知 package_name = package.get("name", "未知配件包") status_text = "启用" if new_status else "禁用" QMessageBox.information( self, "状态更新", f"配件包 '{package_name}' 已{status_text}" ) self.update_button_status_based_on_selection() def update_package_row(self, row, package): """更新指定行的状态显示""" # 获取状态项 status_item = self.table.item(row, 5) if not status_item: status_item = QTableWidgetItem() status_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(row, 5, status_item) # 更新状态文本和颜色 new_status = package.get("enabled", True) status_item.setText("启用" if new_status else "禁用") if new_status: status_item.setForeground(QColor(0, 128, 0)) # 启用状态绿色 else: status_item.setForeground(QColor(255, 0, 0)) # 禁用状态红色 def update_button_status(self, row): """根据当前状态更新按钮文本""" current_status = self.packages[row].get("enabled", True) self.toggle_status_btn.setText("禁用" if current_status else "启用") #单个配件包编辑对话框 class PackageEditDialog(QDialog): """单个配件包编辑对话框""" def __init__(self, parent=None, data=None): super().__init__(parent) self.setWindowTitle("编辑配件包" if data else "添加配件包") self.setMinimumSize(600, 400) # 关键修复1:在设置背景前应用Fusion样式 self.setStyle(QStyleFactory.create("Fusion")) # 关键修复2:使用样式表设置全局背景 self.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_new_form_backcolor_style()) # 设置白色背景 self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.Window, QColor(255, 255, 255)) # 白色 self.setPalette(palette) # 初始化数据时添加默认的def_name字段 if data: self.data = data # 确保每个target都有def_name字段 for target in self.data.get("targets", []): if "def_name" not in target: target["def_name"] = target.get("type", "") + "_def" else: self.data = { "name": "", "display_name": "", "targets": [] } self.init_ui() def init_ui(self): layout = QVBoxLayout() # 基本信息 form_layout = QVBoxLayout() # 名称 name_layout = QHBoxLayout() name_layout.addWidget(QLabel("名称:")) self.name_edit = QLineEdit(self.data["name"]) self.name_edit.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_label_style()) name_layout.addWidget(self.name_edit) form_layout.addLayout(name_layout) # 显示名称 display_layout = QHBoxLayout() display_layout.addWidget(QLabel("显示名称:")) self.display_edit = QLineEdit(self.data["display_name"]) self.display_edit.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_label_style()) display_layout.addWidget(self.display_edit) form_layout.addLayout(display_layout) layout.addLayout(form_layout) # 目标类型列表 layout.addWidget(QLabel("目标类型配置:")) self.targets_table = QTableWidget() self.targets_table.setColumnCount(3) self.targets_table.setHorizontalHeaderLabels(["类型名称","定义名称", "所需数量"]) self.targets_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 关键修复5:设置表格透明背景 self.targets_table.setStyleSheet("background-color: rgba(255, 255, 255, 0.7);") # 添加数据验证 self.targets_table.itemChanged.connect(self.validate_row) self.populate_targets_table() layout.addWidget(self.targets_table) # 目标操作按钮 target_btn_layout = QHBoxLayout() add_target_btn = QPushButton("添加类型") add_target_btn.clicked.connect(self.add_target) target_btn_layout.addWidget(add_target_btn) remove_target_btn = QPushButton("删除选中") remove_target_btn.clicked.connect(self.remove_target) target_btn_layout.addWidget(remove_target_btn) layout.addLayout(target_btn_layout) # 底部按钮 button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) layout.addWidget(button_box) self.setLayout(layout) def validate_row(self, item): """验证单个行的数据""" row = item.row() type_item = self.targets_table.item(row, 0) def_item = self.targets_table.item(row, 1) count_item = self.targets_table.item(row, 2) # 验证数据类型 if not type_item or not type_item.text().strip(): self.highlight_error(row, "类型名称不能为空") return False # 验证定义名称 if not def_item or not def_item.text().strip(): self.highlight_error(row, "定义名称不能为空") return False # 验证数量 if count_item: try: count = int(count_item.text()) if count <= 0: self.highlight_error(row, "数量必须大于0") return False except ValueError: self.highlight_error(row, "数量必须是整数") return False # 检查类型名称和定义名称是否相同 if type_item.text().strip() == def_item.text().strip(): self.highlight_error(row, "类型名称和定义名称不能相同") return False # 清除错误状态 self.clear_error(row) return True def validate_all_rows(self): """验证所有行的数据""" all_valid = True for row in range(self.targets_table.rowCount()): if not self.validate_row(self.targets_table.item(row, 0)): all_valid = False return all_valid def highlight_error(self, row, message): """高亮显示错误行""" for col in range(3): item = self.targets_table.item(row, col) if item: item.setBackground(QColor(255, 200, 200)) # 浅红色背景 item.setToolTip(message) def clear_error(self, row): """清除错误标记""" for col in range(3): item = self.targets_table.item(row, col) if item: item.setBackground(QColor(255, 255, 255)) # 白色背景 item.setToolTip("") def populate_targets_table(self): """填充目标类型表格(修复定义名称初始化)""" self.targets_table.setRowCount(len(self.data["targets"])) for row, target in enumerate(self.data["targets"]): # 类型名称 self.targets_table.setItem(row, 0, QTableWidgetItem(target.get("type", ""))) # 定义名称 self.targets_table.setItem(row, 1, QTableWidgetItem(target.get("def_name", ""))) # 所需数量 count = target.get("count", 1) count_item = QTableWidgetItem(str(count)) self.targets_table.setItem(row, 2, count_item) def add_target(self): """添加新目标类型""" """添加新目标类型""" row_count = self.targets_table.rowCount() self.targets_table.insertRow(row_count) # 默认设置不同的名称 base_name = f"新类型_{row_count + 1}" self.targets_table.setItem(row_count, 0, QTableWidgetItem(base_name)) self.targets_table.setItem(row_count, 1, QTableWidgetItem(f"{base_name}_def")) # 确保默认名称不同 self.targets_table.setItem(row_count, 2, QTableWidgetItem("1")) # 自动进入编辑模式 self.targets_table.editItem(self.targets_table.item(row_count, 0)) def remove_target(self): """删除选中目标类型""" selected_rows = self.targets_table.selectionModel().selectedRows() if not selected_rows: return for row in sorted(selected_rows, reverse=True): self.targets_table.removeRow(row.row()) def get_data(self): """获取编辑后的数据(确保总是返回有效数据)""" # 基本信息 self.data["name"] = self.name_edit.text().strip() self.data["display_name"] = self.display_edit.text().strip() # 目标类型 self.data["targets"] = [] if not self.targets_table: return self.data for row in range(self.targets_table.rowCount()): type_item = self.targets_table.item(row, 0) def_item = self.targets_table.item(row, 1) count_item = self.targets_table.item(row, 2) # 跳过无效行 if not type_item or not def_item or not count_item: continue target_type = type_item.text().strip() def_name = def_item.text().strip() # 处理数量 try: count = int(count_item.text()) except ValueError: count = 1 if target_type: # 忽略空类型 self.data["targets"].append({ "type": target_type, "def_name": def_name, "count": count }) return self.data
10-23
class PartsListDialog(QDialog): """配件明细管理对话框""" def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("配件明细管理") self.setMinimumSize(600, 400) # 样式设置 self.setStyle(QStyleFactory.create("Fusion")) self.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_new_form_backcolor_style()) self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.Window, QColor(255, 255, 255)) self.setPalette(palette) # 加载配置 self.config_file = "parts_list.json" self.parts = self.load_config() self.init_ui() def init_ui(self): layout = QVBoxLayout() layout.setContentsMargins(15, 15, 15, 15) layout.setSpacing(10) # 按钮区域 btn_layout = QHBoxLayout() self.add_btn = QPushButton("新增配件") self.add_btn.clicked.connect(self.add_part) btn_layout.addWidget(self.add_btn) self.edit_btn = QPushButton("编辑选中") self.edit_btn.clicked.connect(self.edit_part) btn_layout.addWidget(self.edit_btn) self.delete_btn = QPushButton("删除选中") self.delete_btn.clicked.connect(self.delete_part) btn_layout.addWidget(self.delete_btn) btn_layout.addStretch(1) layout.addLayout(btn_layout) # 表格展示区域 self.table = QTableWidget() self.table.setColumnCount(3) self.table.setHorizontalHeaderLabels([ "类型名称(英文)", "定义名称(中文)", "标号" ]) self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table.setStyleSheet("background-color: rgba(255, 255, 255, 0.7);") self.populate_table() layout.addWidget(self.table) # 底部按钮 button_box = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel) button_box.accepted.connect(self.save_config) button_box.rejected.connect(self.reject) layout.addWidget(button_box) self.setLayout(layout) def load_config(self): """加载配件明细配置文件""" if os.path.exists(self.config_file): try: with open(self.config_file, 'r', encoding='utf-8') as f: return json.load(f) except: return [] return [] def save_config(self): """保存配件明细配置""" try: with open(self.config_file, 'w', encoding='utf-8') as f: json.dump(self.parts, f, ensure_ascii=False, indent=2) QMessageBox.information(self, "成功", "配件明细已成功保存!") self.accept() except Exception as e: QMessageBox.critical(self, "错误", f"保存配件明细失败: {str(e)}") def populate_table(self): """填充表格数据""" self.table.setRowCount(len(self.parts)) for row, part in enumerate(self.parts): # 类型名称(英文) self.table.setItem(row, 0, QTableWidgetItem(part.get("type", ""))) # 定义名称(中文) self.table.setItem(row, 1, QTableWidgetItem(part.get("def_name", ""))) # 标号 id_item = QTableWidgetItem(str(part.get("id", ""))) id_item.setTextAlignment(Qt.AlignCenter) self.table.setItem(row, 2, id_item) def get_selected_index(self): """获取选中的配件索引""" selected_rows = self.table.selectionModel().selectedRows() if not selected_rows: QMessageBox.warning(self, "警告", "请先选择一个配件") return -1 return selected_rows[0].row() def add_part(self): """添加新配件""" dialog = PartEditDialog(self) if dialog.exec_() == QDialog.Accepted: new_part = dialog.get_data() self.parts.append(new_part) self.populate_table() def edit_part(self): """编辑选中的配件""" row = self.get_selected_index() if row < 0: return dialog = PartEditDialog(self, self.parts[row]) if dialog.exec_() == QDialog.Accepted: self.parts[row] = dialog.get_data() self.populate_table() def delete_part(self): """删除选中的配件""" row = self.get_selected_index() if row < 0: return reply = QMessageBox.question( self, "确认删除", f"确定要删除 '{self.parts[row].get('def_name', '')}' 配件吗?", QMessageBox.Yes | QDialogButtonBox.No ) if reply == QMessageBox.Yes: del self.parts[row] self.populate_table() # 新添加的配件编辑对话框 class PartEditDialog(QDialog): """单个配件编辑对话框""" def __init__(self, parent=None, data=None): super().__init__(parent) self.setWindowTitle("编辑配件" if data else "添加配件") self.setMinimumSize(400, 250) # 样式设置 self.setStyle(QStyleFactory.create("Fusion")) self.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_new_form_backcolor_style()) self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.Window, QColor(255, 255, 255)) self.setPalette(palette) self.data = data or { "type": "", "def_name": "", "id": "" } self.init_ui() def init_ui(self): layout = QVBoxLayout() layout.setContentsMargins(15, 15, 15, 15) layout.setSpacing(10) # 类型名称(英文) type_layout = QHBoxLayout() type_layout.addWidget(QLabel("类型名称(英文):")) self.type_edit = QLineEdit(self.data["type"]) self.type_edit.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_label_style()) type_layout.addWidget(self.type_edit) layout.addLayout(type_layout) # 定义名称(中文) def_layout = QHBoxLayout() def_layout.addWidget(QLabel("定义名称(中文):")) self.def_edit = QLineEdit(self.data["def_name"]) self.def_edit.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_label_style()) def_layout.addWidget(self.def_edit) layout.addLayout(def_layout) # 标号 id_layout = QHBoxLayout() id_layout.addWidget(QLabel("标号:")) self.id_edit = QLineEdit(str(self.data.get("id", ""))) self.id_edit.setStyleSheet(UiMainTestStyle.UiMainTestStyle.set_label_style()) id_layout.addWidget(self.id_edit) layout.addLayout(id_layout) # 底部按钮 button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.validate_and_accept) button_box.rejected.connect(self.reject) layout.addWidget(button_box) self.setLayout(layout) def validate_and_accept(self): """验证数据并接受""" type_name = self.type_edit.text().strip() def_name = self.def_edit.text().strip() id_text = self.id_edit.text().strip() if not type_name: QMessageBox.warning(self, "错误", "类型名称不能为空") return if not def_name: QMessageBox.warning(self, "错误", "定义名称不能为空") return # 如果提供了ID,确保它是整数 if id_text: try: int(id_text) except ValueError: QMessageBox.warning(self, "错误", "标号必须是整数") return self.accept() def get_data(self): """获取编辑后的数据""" return { "type": self.type_edit.text().strip(), "def_name": self.def_edit.text().strip(), "id": self.id_edit.text().strip() or None } 在配件明细管理中增加图片列,有图片显示图片,单击放大图片,同时在新添加的配件编辑对话框增加绑定图片的按钮
最新发布
10-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值