diff --git a/images/关闭图标.png b/images/关闭图标.png new file mode 100644 index 0000000..9b090d6 Binary files /dev/null and b/images/关闭图标.png differ diff --git a/images/管片任务信息栏.png b/images/管片任务信息栏.png new file mode 100644 index 0000000..290f6ab Binary files /dev/null and b/images/管片任务信息栏.png differ diff --git a/images/详情弹出背景.png b/images/详情弹出背景.png new file mode 100644 index 0000000..7c003c2 Binary files /dev/null and b/images/详情弹出背景.png differ diff --git a/images/详情标题.png b/images/详情标题.png new file mode 100644 index 0000000..edf08db Binary files /dev/null and b/images/详情标题.png differ diff --git a/utils/image_paths.py b/utils/image_paths.py index ffdda75..a62027b 100644 --- a/utils/image_paths.py +++ b/utils/image_paths.py @@ -101,4 +101,10 @@ class ImagePaths: SYSTEM_DIAGNOSTICS_STATUS_YELLOW = "images/系统诊断状态黄.png" SYSTEM_DIAGNOSTICS_STATUS_RED = "images/系统诊断状态红.png" SYSTEM_DIAGNOSTICS_MS_BG = "images/系统诊断毫秒背景.png" - SYSTEM_DIAGNOSTICS_DROPDOWN_ARROW = "images/系统诊断下拉箭头.png" \ No newline at end of file + SYSTEM_DIAGNOSTICS_DROPDOWN_ARROW = "images/系统诊断下拉箭头.png" + + # 功能:管片任务详情按钮弹窗 + SEGMENT_DETAILS_POPUP_BG = "images/详情弹出背景.png" + SEGMENT_DETAILS_TITLE_BG = "images/详情标题.png" + SEGMENT_DETAILS_INFO_BAR = "images/管片任务信息栏.png" + SEGMENT_DETAILS_CLOSE_ICON = "images/关闭图标.png" \ No newline at end of file diff --git a/view/main_window.py b/view/main_window.py index cb91984..e2a500a 100644 --- a/view/main_window.py +++ b/view/main_window.py @@ -21,6 +21,8 @@ from .widgets.bottom_control_widget import BottomControlWidget import resources.resources_rc from utils.image_paths import ImagePaths +from .widgets.segment_details_dialog import SegmentDetailsDialog + class MainWindow(QWidget): def __init__(self): @@ -34,21 +36,27 @@ class MainWindow(QWidget): # 安装事件过滤器,处理计划方量的 QLineEdit的失去焦点事件 self.installEventFilter(self) + # 连接槽函数 def connectSignalToSlot(self): # 可添加信号槽连接 # self.system_button_widget.buttons["系统启动"].clicked.connect(self.handleSystemStart) # self.system_button_widget.buttons["系统停止"].clicked.connect(self.handleSystemStop) - pass - self.conveyor_system_widget.left_btn.clicked.connect(self.handleHopperMoveLeft) - self.conveyor_system_widget.right_btn.clicked.connect(self.handleHopperMoveRight) + + # 传送带部分的按钮 + self.conveyor_system_widget.left_btn.clicked.connect(self.handleHopperMoveLeft) # 传送带下的左移按钮 + self.conveyor_system_widget.right_btn.clicked.connect(self.handleHopperMoveRight) # 传送带下的右移按钮 + + # 管片任务详情 + self.segment_task_widget.task_details_signal.connect(self.handleSegmentTaskDetails) # 管片任务详情按钮 + def handleSystemStart(self): - # 测试 + # 测试系统开启,进度条动画 self.production_progress.testProgress(60) self.arc_progress.testProgress(60) def handleSystemStop(self): - # 测试 + # 测试系统停止,进度条动画 self.production_progress.animation.stop() self.arc_progress.animation.stop() @@ -101,6 +109,7 @@ class MainWindow(QWidget): self.dispatch_task_widget.set_task_id("task2", "PD0002") self.dispatch_task_widget.set_task_id("task3", "PD0003") + # 读取数据库,初始化 管片任务的数据 from busisness.blls import ArtifactBll, PDRecordBll artifact_dal = ArtifactBll() artifacts = artifact_dal.get_artifact_task() @@ -221,6 +230,17 @@ class MainWindow(QWidget): # 料斗右移完成,恢复料斗左移按钮 QTimer.singleShot(2100, lambda: self.conveyor_system_widget.left_btn.setEnabled(True)) + def handleSegmentTaskDetails(self, segment_task_name:str): + # 管片任务名 task1、task2、task3 (分别对应第一条管片任务、 第二条管片任务...) + print("main_window: handleSegmentTaskDetails", segment_task_name) + + # 显示管片任务详情对话框 + segment_details_dialog = SegmentDetailsDialog(self) + # 这里可以设置对话框显示的内容 如 set_segment_id + # segment_details_dialog.set_segment_id("9999999999") + segment_details_dialog.show() + + # 更新 派单任务widget的坐标 def update_dispatch_task_position(self): # 方法1:获取模具车控件左上角坐标(相对于父控件) diff --git a/view/widgets/segment_details_dialog.py b/view/widgets/segment_details_dialog.py new file mode 100644 index 0000000..1a31784 --- /dev/null +++ b/view/widgets/segment_details_dialog.py @@ -0,0 +1,315 @@ +from PySide6.QtWidgets import ( + QApplication, + QDialog, + QVBoxLayout, + QHBoxLayout, + QGridLayout, + QLabel, + QWidget, + QPushButton +) +from PySide6.QtGui import QPixmap, QFont, QPainter, QIcon +from PySide6.QtCore import Qt +import sys + +from utils.image_paths import ImagePaths + +""" + 管片任务详情的弹出窗口: 点击管片任务的详情按钮之后弹出 +""" + +class SegmentDetailsDialog(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.setAttribute(Qt.WA_TranslucentBackground) + + # 初始化存储需要修改的控件 + self.id_value_label = None # 管片ID值标签 + self.left_cells = [] # 左列单元格列表(每个元素是包含label和value的widget) + self.right_cells = [] # 右列单元格列表 + + self._init_ui() + + def _init_ui(self): + # 基础设置:无边框+窗口尺寸由背景图决定 + self.setWindowFlags(Qt.FramelessWindowHint) + self._load_background() + + # 主布局: + main_layout = QVBoxLayout(self) + main_layout.setContentsMargins(32, 20, 32, 50) + main_layout.setSpacing(0) + + # 1. 顶部区域(标题 + 关闭按钮) + self._add_top_area(main_layout) + + # 2. 管片ID区域(保存ID值标签引用) + self._add_segment_id_area(main_layout) + + # 3. 网格信息区域(保存左右列单元格引用) + self._add_grid_info_area(main_layout) + + def _load_background(self): + self.bg_pixmap = QPixmap(ImagePaths.SEGMENT_DETAILS_POPUP_BG) + if self.bg_pixmap.isNull(): + print("错误:详情弹出背景.png 加载失败,请检查路径!") + self.setFixedSize(800, 600) + else: + self.setFixedSize(self.bg_pixmap.size()) + + def _add_top_area(self, parent_layout): + """创建包含标题和关闭按钮的顶部水平布局""" + top_layout = QHBoxLayout() + top_layout.setContentsMargins(0, 0, 0, 36) # 保持原标题下方36px间距 + top_layout.setSpacing(0) + + # 左侧弹簧(让标题居中) + top_layout.addStretch() + + # 标题标签(复用原标题逻辑) + title_label = QLabel("管片任务") + font = QFont() + font.setPixelSize(24) + font.setLetterSpacing(QFont.AbsoluteSpacing, 2) + font.setBold(True) + title_label.setFont(font) + title_label.setStyleSheet("color: #13fffc; font-weight: Bold;") + title_label.setAlignment(Qt.AlignCenter) + top_layout.addWidget(title_label) + + # 右侧:关闭按钮 + self._create_close_button(top_layout) + + parent_layout.addLayout(top_layout) + + # 新增:创建关闭按钮 + def _create_close_button(self, parent_layout): + """创建36x36关闭按钮""" + self.close_btn = QPushButton() + self.close_btn.setFixedSize(36, 36) # 固定尺寸18x18 + + # 加载关闭图标 + close_icon = QPixmap(ImagePaths.SEGMENT_DETAILS_CLOSE_ICON) + if not close_icon.isNull(): + # 设置图标并自适应按钮大小 + self.close_btn.setIcon(QIcon(close_icon)) + + # 样式设置:默认透明背景,悬停红色背景 + self.close_btn.setStyleSheet(""" + QPushButton { + background-color: transparent; + border: none; + padding: 0px; + } + QPushButton:hover { + background-color: red; + border-radius: 2px; + } + """) + + # 点击事件:关闭窗口 + self.close_btn.clicked.connect(self.close) + + # 添加到布局(与标题保持间距) + parent_layout.addStretch() # 右侧弹簧,确保按钮靠右 + parent_layout.addWidget(self.close_btn) + + + def _add_segment_id_area(self, parent_layout): + id_layout = QHBoxLayout() + + # 左侧:管片ID标签 + id_label = QLabel("管片ID") + id_label.setFixedSize(318, 32) + id_font = QFont() + id_font.setPixelSize(18) + id_font.setLetterSpacing(QFont.AbsoluteSpacing, 2) + id_font.setBold(True) + id_label.setFont(id_font) + id_label.setStyleSheet(f""" + background-image: url({ImagePaths.SEGMENT_DETAILS_TITLE_BG}); + background-repeat: no-repeat; + background-position: center; + color: #13ffff; + """) + id_label.setContentsMargins(16, 0, 0, 0) + id_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) + + # 右侧:管片ID值(保存引用到实例变量) + self.id_value_label = QLabel("346482967298119") + value_font = QFont() + value_font.setPixelSize(18) + value_font.setBold(True) + value_font.setLetterSpacing(QFont.AbsoluteSpacing, 2) + self.id_value_label.setFont(value_font) + self.id_value_label.setStyleSheet("color: #13ffff;") + self.id_value_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) + + id_layout.addWidget(id_label) + id_layout.addStretch() + id_layout.addWidget(self.id_value_label) + id_layout.setContentsMargins(0, 0, 0, 16) + parent_layout.addLayout(id_layout) + + def _add_grid_info_area(self, parent_layout): + grid_layout = QGridLayout() + grid_layout.setSpacing(12) + + # 初始化显示的数据 + # 左侧信息条目 + left_info_items = [ + ("管片编号", "QR1B32000153AD"), + ("管片副标识", "QR1B32000153AD"), + ("生产环号", "QR1B32000153AD"), + ("模具编号", "QR1B32000153AD"), + ("骨架编号", "QR1B32000153AD"), + ("环类型编号", "QR1B32000153AD"), + ("尺寸规格", "QR1B32000153AD"), + ] + + # 右侧信息条目 + right_info_items = [ + ("分块号", "QR3143243423543254"), + ("出洞环标记", "QR3143243423543254"), + ("注浆管标记", "QR3143243423543254"), + ("聚丙烯纤维标记", "QR3143243423543254"), + ("浇筑方量", "QR3143243423543254"), + ("任务单号", "QR3143243423543254"), + ("埋深", "QR3143243423543254"), + ] + + # 填充左列并保存单元格引用 + self.left_cells.clear() # 清空列表 + for row, (label_text, value_text) in enumerate(left_info_items): + cell_widget = self._create_info_cell(label_text, value_text) + self.left_cells.append(cell_widget) # 保存到列表 + grid_layout.addWidget(cell_widget, row, 0) + + # 填充右列并保存单元格引用 + self.right_cells.clear() # 清空列表 + for row, (label_text, value_text) in enumerate(right_info_items): + cell_widget = self._create_info_cell(label_text, value_text) + self.right_cells.append(cell_widget) # 保存到列表 + grid_layout.addWidget(cell_widget, row, 1) + + parent_layout.addLayout(grid_layout) + + def _create_info_cell(self, label_text, value_text): + cell_widget = QWidget() + cell_bg = QPixmap(ImagePaths.SEGMENT_DETAILS_INFO_BAR) + if not cell_bg.isNull(): + cell_widget.setFixedSize(cell_bg.size()) + cell_widget.setStyleSheet(f""" + background-image: url({ImagePaths.SEGMENT_DETAILS_INFO_BAR}); + background-repeat: no-repeat; + background-position: Center; + """) + else: + print("警告:管片任务信息栏.png 加载失败,使用默认背景!") + cell_widget.setStyleSheet("background-color: #0a2463;") + + cell_layout = QHBoxLayout(cell_widget) + cell_layout.setContentsMargins(2, 0, 0, 0) + + # 左侧标签(保存到cell_widget的属性中) + label = QLabel(label_text) + label.setFixedSize(136, 60) + label_font = QFont() + label_font.setPixelSize(16) + label_font.setLetterSpacing(QFont.AbsoluteSpacing, 2) + label.setFont(label_font) + label.setStyleSheet("background: none; background-color: #1369b4; color: #fffffd; font-weight:Bold;") + label.setAlignment(Qt.AlignCenter) + cell_widget.label = label + + # 右侧值(保存到cell_widget的属性中) + value = QLabel(value_text) + value_font = QFont() + value_font.setPixelSize(18) + value.setFont(value_font) + value.setStyleSheet("background: none; color: #9fbfd4;") + value.setAlignment(Qt.AlignVCenter | Qt.AlignLeft) + cell_widget.value = value + + cell_layout.addWidget(label) + cell_layout.addSpacing(60) + cell_layout.addWidget(value) + + return cell_widget + + def paintEvent(self, event): + if not self.bg_pixmap.isNull(): + painter = QPainter(self) + painter.drawPixmap(self.rect(), self.bg_pixmap) + super().paintEvent(event) + + # ------------------- 对外修改接口 ------------------- + # --------------修改管片任务详情中显示的值 ------------ + def set_segment_id(self, new_id): + """修改管片ID的值""" + if self.id_value_label: + self.id_value_label.setText(str(new_id)) + + def set_left_label(self, row, new_label_text:str): + """ + 修改左列网格的标签文本 ("生产环号") + Args: + row: 左列网格行号(0-6,共7行) + new_label_text: 新的标签文字(如“管片编号”) + """ + if 0 <= row < len(self.left_cells): + cell = self.left_cells[row] + cell.label.setText(new_label_text) + + def set_left_value(self, row, new_value_text:str): + """ + 修改左列网格的值 + Args: + row: 左列网格行号(0-6,共7行) + new_value_text: 新的值(如“FB789”) + """ + if 0 <= row < len(self.left_cells): + cell = self.left_cells[row] + cell.value.setText(new_value_text) + + def set_right_label(self, row, new_label_text:str): + """ + 修改右列网格的标签文本 ("任务单号") + Args: + row: 右列网格行号(0-6,共7行) + new_label_text: 新的标签文字(如“分块号”) + """ + if 0 <= row < len(self.right_cells): + cell = self.right_cells[row] + cell.label.setText(new_label_text) + + def set_right_value(self, row, new_value_text:str): + """ + 修改右列网格的值 + Args: + row: 右列网格行号(0-6,共7行) + new_value_text: 新的值(如“FB789”) + """ + if 0 <= row < len(self.left_cells): + cell = self.right_cells[row] + cell.value.setText(new_value_text) + + +# 测试代码 +if __name__ == "__main__": + app = QApplication(sys.argv) + dialog = SegmentDetailsDialog() + dialog.show() + + # 测试修改接口 + dialog.set_segment_id("999999999999999") # 修改管片ID值 + + # 左列修改 + dialog.set_left_label(0, "新管片编号") # 修改左列第0行的标签文本 + dialog.set_left_value(0, "QR6666666666666") # 修改左列第0行的值 + + # 右列修改 + dialog.set_right_label(0, "新分块号") # 修改右列第0行的标签文本 + dialog.set_right_value(0, "QR99999999999999999") # 修改右列第0行的值 + + sys.exit(app.exec()) \ No newline at end of file diff --git a/view/widgets/system_diagnostics_dialog.py b/view/widgets/system_diagnostics_dialog.py index 8c89c48..7295384 100644 --- a/view/widgets/system_diagnostics_dialog.py +++ b/view/widgets/system_diagnostics_dialog.py @@ -27,6 +27,10 @@ import sys from utils.image_paths import ImagePaths +""" + 系统诊断按钮的弹窗: 可以显示设备的状态 +""" + class CustomDropdown(QWidget): """自定义下拉框组件""" @@ -107,11 +111,7 @@ class CustomDropdown(QWidget): if self.is_expanded: self.list_widget.hide() # 箭头恢复向下 - self.arrow_label.setPixmap( - self.arrow_pixmap.scaled( - 12, 9, Qt.KeepAspectRatio, Qt.SmoothTransformation - ) - ) + self.arrow_label.setPixmap(self.arrow_pixmap) else: # 计算下拉框位置(在标签下方对齐) label_pos = self.result_label.mapToGlobal( diff --git a/view/widgets/task_widget.py b/view/widgets/task_widget.py index f3ca49e..e9f7556 100644 --- a/view/widgets/task_widget.py +++ b/view/widgets/task_widget.py @@ -1,14 +1,19 @@ from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QMessageBox, QApplication) -from PySide6.QtCore import Qt +from PySide6.QtCore import Qt, Signal from PySide6.QtGui import QPainter, QPixmap, QFont import sys import resources.resources_rc from utils.image_paths import ImagePaths -# 任务控件,如:管片任务、派单任务 +""" + 任务控件,如:管片任务、派单任务 +""" class TaskWidget(QWidget): + # 任务详情信号: task1表示第一条任务 + task_details_signal = Signal(str) + def __init__(self, taskTitle:str, parent=None): super().__init__(parent) # 设置Widget大小与背景图一致 @@ -153,8 +158,12 @@ class TaskWidget(QWidget): def _show_detail_dialog(self, task_name): """显示任务详情弹窗""" - QMessageBox.information(self, "任务详情", f"任务 {task_name} 的详细信息...") - + # QMessageBox.information(self, "任务详情", f"任务 {task_name} 的详细信息...") + """ + task1 表示第一条任务, 依次类推 + """ + # 发送任务详情信号 + self.task_details_signal.emit(task_name) # -------------------------- # 对外接口:修改任务属性