add(派单任务和管片任务的刷新)

This commit is contained in:
yaj
2026-03-06 18:33:58 +08:00
parent 37d60ba63e
commit a3b6287808
9 changed files with 393 additions and 42 deletions

View File

@ -10,9 +10,9 @@ interval_days = 10
# 方量调节控件最小值 # 方量调节控件最小值
min = 0.0 min = 0.0
# 方量调节控件最大值 # 方量调节控件最大值
max = 99.0 max = 2.4
# 方量调节控件初始值 # 方量调节控件初始值
initial = 2.5 initial = 1.9

View File

@ -14,9 +14,15 @@ sub_interval = 500
[OPC_NODE_LIST] [OPC_NODE_LIST]
upper_weight = 2:upper,2:upper_weight upper_weight = 2:upper,2:upper_weight
lower_weight = 2:lower,2:lower_weight lower_weight = 2:lower,2:lower_weight
upper_hopper_position = 2:upper,2:upper_hopper_position ; ; upper_hopper_position = 2:upper,2:upper_hopper_position
upper_clamp_status = 2:upper,2:upper_clamp_status ; upper_clamp_status = 2:upper,2:upper_clamp_status
vibration_frequency=2:vibration_frequency ; production_progress=2:production_progress
production_progress=2:production_progress ; segment_tasks=2:segment_tasks
segment_tasks=2:segment_tasks ; dispatch_tasks=2:dispatch_tasks
dispatch_tasks=2:dispatch_tasks segment_tasks=2:sys,2:segment_refresh
dispatch_tasks=2:sys,2:pd_refresh
mould_vibrate_status=2:mould,2:mould_vibrate_status
vibration_frequency=2:mould,2:mould_frequency
mould_finish_weight=2:mould,2:mould_finish_weight
pd_mode=2:pd,2:set_mode
pd_plan_volume=2:pd,2:set_volume

View File

@ -4,7 +4,7 @@ from view.widgets.system_center_dialog import SystemCenterDialog
from view.widgets.bottom_control_widget import BottomControlWidget from view.widgets.bottom_control_widget import BottomControlWidget
from view.widgets.system_diagnostics_dialog import SystemDiagnosticsDialog from view.widgets.system_diagnostics_dialog import SystemDiagnosticsDialog
from view.widgets.message_popup_widget import MessagePopupWidget from view.widgets.message_popup_widget import MessagePopupWidget
from view.main_window import MainWindow
from service.msg_recorder import MessageRecorder from service.msg_recorder import MessageRecorder
from service.msg_query_thread import MsgQueryThread from service.msg_query_thread import MsgQueryThread
@ -16,7 +16,7 @@ from service.monitor_thread import MonitorThread
""" """
class BottomControlController: class BottomControlController:
def __init__(self, bottom_control_widget:BottomControlWidget, main_window): def __init__(self, bottom_control_widget:BottomControlWidget, main_window:MainWindow):
self.bottom_control_widget = bottom_control_widget self.bottom_control_widget = bottom_control_widget
self.main_window = main_window self.main_window = main_window
@ -25,7 +25,7 @@ class BottomControlController:
self.diagnostics_device_row = 0 # 系统诊断弹窗的设备检测行号从0开始 self.diagnostics_device_row = 0 # 系统诊断弹窗的设备检测行号从0开始
self.diagnostics_device_col = 0 # 系统诊断弹窗的设备检测列号从0开始 self.diagnostics_device_col = 0 # 系统诊断弹窗的设备检测列号从0开始
self.diagnostics_service_row = 0 # 系统诊断弹窗的服务检测行号从0开始 self.diagnostics_service_row = 0 # 系统诊断弹窗的服务检测行号从0开始
self.diagnostics_service_col = 2 # 系统诊断弹窗的服务检测从2开始 self.diagnostics_service_col = 2 # 系统诊断弹窗的服务检测从2开始
# 系统中心弹窗 # 系统中心弹窗
self.system_center_dialog = SystemCenterDialog(self.main_window) self.system_center_dialog = SystemCenterDialog(self.main_window)
@ -211,8 +211,17 @@ class BottomControlController:
self.system_diagnostics_dialog.set_ms_value(row, col, delay) self.system_diagnostics_dialog.set_ms_value(row, col, delay)
if delay <= self.device_monitor.warning_delay: if delay <= self.device_monitor.warning_delay:
self.system_diagnostics_dialog.set_circle_status(row, col, "normal") self.system_diagnostics_dialog.set_circle_status(row, col, "normal")
# 设置上料斗或者下料斗的设备状态(主界面的上料斗、下料斗控件中)
if device_name == "上料斗":
self.main_window.hopper_widget.setUpperHopperStatus(0)
elif device_name == "下料斗":
self.main_window.hopper_widget.setLowerHopperStatus(0)
else: else:
self.system_diagnostics_dialog.set_circle_status(row, col, "warning") self.system_diagnostics_dialog.set_circle_status(row, col, "warning")
if device_name == "上料斗":
self.main_window.hopper_widget.setUpperHopperStatus(1)
elif device_name == "下料斗":
self.main_window.hopper_widget.setLowerHopperStatus(1)
# 显示检测组件 # 显示检测组件
self.system_diagnostics_dialog.set_selected_show(row, col) self.system_diagnostics_dialog.set_selected_show(row, col)
@ -225,6 +234,11 @@ class BottomControlController:
self.system_diagnostics_dialog.set_circle_status(row, col, "error") self.system_diagnostics_dialog.set_circle_status(row, col, "error")
# 显示检测组件 # 显示检测组件
self.system_diagnostics_dialog.set_selected_show(row, col) self.system_diagnostics_dialog.set_selected_show(row, col)
# 设置上料斗或者下料斗的设备状态(主界面的上料斗、下料斗控件中)
if device_name == "上料斗":
self.main_window.hopper_widget.setUpperHopperStatus(2)
elif device_name == "下料斗":
self.main_window.hopper_widget.setLowerHopperStatus(2)
def _get_diagnostics_service_row_col(self): def _get_diagnostics_service_row_col(self):
"""获取系统诊断弹窗中 服务检测的 行号 和 列号""" """获取系统诊断弹窗中 服务检测的 行号 和 列号"""

View File

@ -80,6 +80,11 @@ class MainController:
self.opc_client.opc_signal.opc_log.connect(self.msg_recorder.normal_record, Qt.QueuedConnection) # opcua客户端日志 self.opc_client.opc_signal.opc_log.connect(self.msg_recorder.normal_record, Qt.QueuedConnection) # opcua客户端日志
# 主界面的计划表单自动派单控制
self.main_window.plan_table_widget.auto_dispatch_signal.connect(self.handlePlanTableAutoDispatch) # 计划表单的自动派单切换
# 主界面的计划表单中的计划方量修改控制
self.main_window.plan_volume_modified_signal.connect(self.handleVolumeModified) # 计划方量修改
def handleMainWindowClose(self): def handleMainWindowClose(self):
"""主界面关闭""" """主界面关闭"""
@ -92,6 +97,19 @@ class MainController:
if hasattr(self, 'opc_client'): if hasattr(self, 'opc_client'):
self.opc_client.stop_run() self.opc_client.stop_run()
def handlePlanTableAutoDispatch(self, auto_status:bool):
"""处理计划表单的 自动派单和手动派单的切换
pd_mode: 1,自动派单 2,手动派单
"""
if auto_status: # 自动派单
self.opc_client.write_value_by_name("pd_mode", 1)
else: # 手动派单
self.opc_client.write_value_by_name("pd_mode", 2)
def handleVolumeModified(self, volume_json_str:str):
"""处理 修改方量 (计划表单中 和 派单详情中)"""
self.opc_client.write_value_by_name("pd_plan_volume", volume_json_str)
def start_msg_database_clean_task(self): def start_msg_database_clean_task(self):
"""启动清理消息数据库(messages.db)中过期消息的定时任务""" """启动清理消息数据库(messages.db)中过期消息的定时任务"""
from PySide6.QtCore import QTimer, QDateTime, QDate, QTime from PySide6.QtCore import QTimer, QDateTime, QDate, QTime
@ -239,4 +257,35 @@ class MainController:
def _update_vibration_frequency(self, val): def _update_vibration_frequency(self, val):
# 更新振捣频率 # 更新振捣频率
self.main_window.frequency_button_group.set_selected_frequency(val) self.main_window.frequency_button_group.set_selected_frequency(val) # 频率选择按钮上显示的选中的频率
self.main_window.arc_progress.setFrequency(val) # 模具车上显示的振捣频率
def _update_mould_vibrate_status(self, vibrate_status:bool):
# 更新模具车上显示的振捣状态
# vibrate_status: False:未振捣、True:振捣中
if vibrate_status:
self.main_window.arc_progress.setState("振捣中")
else:
self.main_window.arc_progress.setState("未振捣")
self.opc_client.write_value_by_name("vibration_frequency", 0) # 将振捣频率设置为0
def _update_mould_finish_weight(self, finish_weight:int):
# 更新模具车中的下料重量
# finish_weight已下料重量
self.main_window.arc_progress.setWeight(finish_weight)
def _update_pd_mode(self, mode:int):
# 更新计划表单中的 派单模式(主界面下发状态的下面的切换开关),自动派单/手动派单
mode_mapping = {
1: "自动派单",
2: "手动派单",
0: None # 未知
}
mode_text = mode_mapping.get(mode)
if mode_text == "自动派单":
# 设置主界面下发状态的下面的切换开关
self.main_window.plan_table_widget.set_auto_dispatch(True) # 开启,自动派单
# 修改系统配置文件中的 派单状态为自动派单...
else:
self.main_window.plan_table_widget.set_auto_dispatch(False) # 关闭,手动派单
# 修改系统配置文件中的 派单状态为手动派单...

View File

@ -27,12 +27,16 @@ from .widgets.dispatch_details_dialog import DispatchDetailsDialog
from busisness.models import ArtifactInfoModel from busisness.models import ArtifactInfoModel
from busisness.models import PDRecordModel from busisness.models import PDRecordModel
import json
class MainWindow(QWidget): class MainWindow(QWidget):
# 定义“即将关闭”的信号 # 定义“即将关闭”的信号
about_to_close = Signal() about_to_close = Signal()
# 计划方量修改信号
plan_volume_modified_signal = Signal(str)
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.initWindow() self.initWindow()
@ -45,6 +49,9 @@ class MainWindow(QWidget):
# 安装事件过滤器,处理计划方量的 QLineEdit的失去焦点事件 # 安装事件过滤器,处理计划方量的 QLineEdit的失去焦点事件
self.installEventFilter(self) self.installEventFilter(self)
# 初始化派单任务控件
self.dispatch_task_widget.set_task_select_btn_selected("task2") # 派单任务控件,初始化选中第二条派单任务
# 连接槽函数 # 连接槽函数
def connectSignalToSlot(self): def connectSignalToSlot(self):
# 可添加信号槽连接 # 可添加信号槽连接
@ -61,6 +68,11 @@ class MainWindow(QWidget):
# 派单任务详情 # 派单任务详情
self.dispatch_task_widget.task_details_signal.connect(self.handleDispatchTaskDetails) # 派单任务详情按钮 self.dispatch_task_widget.task_details_signal.connect(self.handleDispatchTaskDetails) # 派单任务详情按钮
# 派单任务选择 (用于更新计划表单)
self.dispatch_task_widget.task_selected_signal.connect(self.handleDispatchTaskSelected) # 派单任务选择按钮
# 计划表单方量修改
self.plan_table_widget.final_modify_volume_signal.connect(self.handleDispatchTaskVolumeModified) # 计划方量修改
def handleSystemStart(self): def handleSystemStart(self):
# 测试系统开启,进度条动画 # 测试系统开启,进度条动画
@ -109,6 +121,8 @@ class MainWindow(QWidget):
self.dispatch_dict = {} self.dispatch_dict = {}
# 当前点击/选中的 派单任务详情对应的任务名(task1\task2\task3) (用于刷新选中的派单任务详情) # 当前点击/选中的 派单任务详情对应的任务名(task1\task2\task3) (用于刷新选中的派单任务详情)
self.current_selected_dispatch_detail_name = None self.current_selected_dispatch_detail_name = None
# 当前点击/选中的 派单任务选择按钮对应的任务名 (用于刷新 计划表单)
self.current_dispatch_task_select_btn_name = None
def createSubWidgets(self): def createSubWidgets(self):
"""创建所有子部件实例""" """创建所有子部件实例"""
@ -177,7 +191,21 @@ class MainWindow(QWidget):
def update_segment_tasks(self, artifact_list:List[ArtifactInfoModel]): def update_segment_tasks(self, artifact_list:List[ArtifactInfoModel]):
# 更新管片任务相关的信息 # 更新管片任务相关的信息
# 遍历数据并更新UI (包括左侧的管片任务 以及 管片任务详情) # 遍历数据并更新UI (包括左侧的管片任务 以及 管片任务详情)
for index, artifact in enumerate(artifact_list, 1): SEGMENT_STATUS_MAP = {
1: "待生产",
2: "正生产",
3: "已生产" # 完成生产
}
SEGMENT_STATUS_IMAGE = {
1: ImagePaths.TASK_RECT5,
2: ImagePaths.TASK_RECT4,
3: ImagePaths.TASK_RECT3
}
for index, artifact in enumerate(reversed(artifact_list), 1):
# 提取管片生产状态
segment_status_text = SEGMENT_STATUS_MAP.get(artifact.Status, "未知") # 管片状态文本
segment_status_icon = SEGMENT_STATUS_IMAGE.get(artifact.Status, ImagePaths.TASK_RECT1) # 管片状态图标
if artifact.MouldCode: # 更新模具号 if artifact.MouldCode: # 更新模具号
self.segment_task_widget.set_task_id(f"task{index}", artifact.MouldCode) self.segment_task_widget.set_task_id(f"task{index}", artifact.MouldCode)
if artifact.BetonVolume: # 更新浇筑方量 if artifact.BetonVolume: # 更新浇筑方量
@ -185,6 +213,14 @@ class MainWindow(QWidget):
if artifact.BeginTime: # 更新时间 (管片任务的开始时间) if artifact.BeginTime: # 更新时间 (管片任务的开始时间)
# print("artifact.BeginTime: ", artifact.BeginTime) # print("artifact.BeginTime: ", artifact.BeginTime)
self.segment_task_widget.set_task_time(f"task{index}", self.convert_to_ampm(artifact.BeginTime)) self.segment_task_widget.set_task_time(f"task{index}", self.convert_to_ampm(artifact.BeginTime))
if segment_status_text: # 更新管片状态
self.segment_task_widget.set_task_status(f"task{index}", segment_status_text, segment_status_icon)
# 更新模具车上的管片信息
if segment_status_text == "正生产": # 模具车上只显示 正生产的管片信息
self.arc_progress.setRingNumber(artifact.ProduceRingNumber) # 设置模具车上的环号
self.arc_progress.setSegmentModel(artifact.BuriedDepth+": "+artifact.RingTypeCode) # 管片类型(如:中埋: R12
self.arc_progress.setSegmentSize(artifact.SizeSpecification) # 管片规格(尺寸)
self.arc_progress.setSegmentNumber(artifact.MouldCode) # 管片号SHRB1-3[模具编号]
self.SetSegmentTaskDetails(f"task{index}", artifact) # 设置管片任务详情信息 self.SetSegmentTaskDetails(f"task{index}", artifact) # 设置管片任务详情信息
def _init_dispatch_tasks(self): def _init_dispatch_tasks(self):
@ -202,14 +238,60 @@ class MainWindow(QWidget):
def update_dispatch_tasks(self, pdrecord_list:List[PDRecordModel]): def update_dispatch_tasks(self, pdrecord_list:List[PDRecordModel]):
# 更新派单任务相关的信息 # 更新派单任务相关的信息
# 遍历数据并更新UI # 遍历数据并更新UI
for index, record in enumerate(pdrecord_list, 1): # 倒着查,过滤掉 搅拌生产状态不是 未知的,
if record.MouldCode: # 更新模具号 # 1、查到的第一个 派单状态为 已下发或者已超时 作为task1
self.dispatch_task_widget.set_task_id(f"task{index}", record.MouldCode) # 2、查到的第一个 派单状态为 计划中的作为 task2第二个派单状态为 计划中作为 task3
if record.BetonVolume: # 更新方量(派单方量[最终计算出来的派单方量]) # 初始化标记控制只取第一条Status=2/3、前两条Status=1的记录
self.dispatch_task_widget.set_task_volume(f"task{index}", record.FBetonVolume) # 派单状态映射1计划中 2已下发 0未知 3已超时
if record.CreateTime: # 更新时间 (派单任务的创建时间) DISPATCH_STATUS_MAP = {
self.dispatch_task_widget.set_task_time(f"task{index}", self.convert_to_ampm(record.CreateTime)) 0: "未知",
self.SetPDRecordTaskDetails(f"task{index}", record) 1: "计划中",
2: "派单中", # 已下发
3: "已超时",
4: "未扫码"
}
# 派单状态图标映射
DISPATCH_STATUS_IMAGE = {
0: ImagePaths.TASK_RECT1,
1: ImagePaths.TASK_RECT2,
2: ImagePaths.TASK_RECT3,
3: ImagePaths.TASK_RECT4,
4: ImagePaths.TASK_RECT5,
}
# 搅拌生产状态映射
PRODUCE_STATUS_MAP = {
0: "未知",
1: "已取消",
2: "已完成",
3: "异常"
}
task_count = 0 # 有效的派单任务数量(需要显示的, task1,task2,task3
# 倒序遍历pdrecord_list
for record in reversed(pdrecord_list):
# 提取状态文字
dispatch_status_text = DISPATCH_STATUS_MAP.get(record.Status, "未知") # 派单状态
dispatch_status_icon = DISPATCH_STATUS_IMAGE.get(record.Status, ImagePaths.TASK_RECT1) # 派单状态图标
produce_status_text = PRODUCE_STATUS_MAP.get(record.GStatus, "未知") # 搅拌生产状态
# 过滤掉GStatus不为0的记录搅拌生产状态为未知0才需要显示
if produce_status_text != "未知":
continue
task_count += 1 # 有效任务数量加一
self._set_dispatch_tasks_info(f"task{task_count}", record, dispatch_status_text, dispatch_status_icon)
def _set_dispatch_tasks_info(self, task_name, record:PDRecordModel, status_text:str, status_icon:str):
# 设置派单任务的tasks信息
if record.MouldCode:
self.dispatch_task_widget.set_task_id(task_name, record.MouldCode)
if record.FBetonVolume:
self.dispatch_task_widget.set_task_volume(task_name, record.FBetonVolume)
if record.CreateTime:
self.dispatch_task_widget.set_task_time(task_name, self.convert_to_ampm(record.CreateTime))
if status_text:
self.dispatch_task_widget.set_task_status(task_name, status_text, status_icon)
self.SetPDRecordTask(task_name, record)
def setupLayout(self): def setupLayout(self):
"""设置垂直布局,从上到下排列部件""" """设置垂直布局,从上到下排列部件"""
@ -344,6 +426,7 @@ class MainWindow(QWidget):
# 显示派单任务详情对话框 # 显示派单任务详情对话框
if not hasattr(self, "dispatch_details_dialog"): if not hasattr(self, "dispatch_details_dialog"):
self.dispatch_details_dialog = DispatchDetailsDialog(dispatch_task_name, self) self.dispatch_details_dialog = DispatchDetailsDialog(dispatch_task_name, self)
self.dispatch_details_dialog.confirm_modify_volume.connect(self.handleModifyDispatchTaskVolume)
pd_record:PDRecordModel = self.dispatch_dict.get(dispatch_task_name) pd_record:PDRecordModel = self.dispatch_dict.get(dispatch_task_name)
# 这里可以设置对话框显示的内容 如 set_segment_id # 这里可以设置对话框显示的内容 如 set_segment_id
@ -351,25 +434,28 @@ class MainWindow(QWidget):
# 设置派单任务详情中的方量的值 # 设置派单任务详情中的方量的值
# current_volume = self.dispatch_task_widget.get_task_volume(dispatch_task_name) # current_volume = self.dispatch_task_widget.get_task_volume(dispatch_task_name)
# self.dispatch_details_dialog.set_row_value(4, str(current_volume)) # 派单方量的值的行号为4第五行 # self.dispatch_details_dialog.set_row_value(4, str(current_volume)) # 派单方量的值的行号为4第五行
# 更新选中的派单任务详情对应的任务名
self.current_selected_dispatch_detail_name = dispatch_task_name
# 更新派单任务详情按钮弹窗的显示 # 更新派单任务详情按钮弹窗的显示
self.updateDispatchTaskDetailsDialog(pd_record) self.updateDispatchTaskDetailsDialog(pd_record)
# 派单任务详情页面中确定修改了派单任务的方量 # 派单任务详情页面中确定修改了派单任务的方量
# 备注:褚工说管片任务和派单任务中的方量都只有一位小数,料斗上的方量显示两位 2025/11/8 # 备注:褚工说管片任务和派单任务中的方量都只有一位小数,料斗上的方量显示两位 2025/11/8
self.dispatch_details_dialog.confirm_modify_volume.connect(self.handleModifyDispatchTaskVolume) self.dispatch_details_dialog.set_dispatch_task_name(dispatch_task_name) # 更新派单任务名
self.dispatch_details_dialog.show() self.dispatch_details_dialog.show()
# 更新选中的派单任务详情对应的任务名
self.current_selected_dispatch_detail_name = dispatch_task_name
def handleModifyDispatchTaskVolume(self, dispatch_task_name:str, modifyed_volume:float): def handleModifyDispatchTaskVolume(self, dispatch_task_name:str, modifyed_volume:float):
"""派单任务详情页面中, 修改派单任务的方量""" """派单任务详情页面中, 修改派单任务的方量"""
# 修改相应的派单任务条目显示的 派单任务方量 # 修改相应的派单任务条目显示的 派单任务方量
self.dispatch_task_widget.set_task_volume(dispatch_task_name, modifyed_volume) self.dispatch_task_widget.set_task_volume(dispatch_task_name, modifyed_volume)
# 其他操作,可能需要修改数据库的派单任务方量 # 其他操作,可能需要修改数据库的派单任务方量
self.handleDispatchTaskVolumeModified(dispatch_task_name, modifyed_volume)
def updateDispatchTaskDetailsDialog(self, pd_record:PDRecordModel): def updateDispatchTaskDetailsDialog(self, pd_record:PDRecordModel):
"""更新派单详情对话框"""
if pd_record and hasattr(self, "dispatch_details_dialog"): if pd_record and hasattr(self, "dispatch_details_dialog"):
self.dispatch_details_dialog.set_segment_id(pd_record.ArtifactActionID) # 管片ID self.dispatch_details_dialog.set_segment_id(pd_record.ArtifactActionID) # 管片ID
self.dispatch_details_dialog.set_row_value(0, pd_record.CreateTime.split('.')[0] if pd_record.CreateTime else None) # 创建时间 (去掉毫秒) self.dispatch_details_dialog.set_row_value(0, pd_record.CreateTime.split('.')[0] if pd_record.CreateTime else None) # 创建时间 (去掉毫秒)
@ -380,13 +466,20 @@ class MainWindow(QWidget):
# 派单状态 1计划中2已下发0未知)默认1 # 派单状态 1计划中2已下发0未知)默认1
status_mapping = { status_mapping = {
0: None, # 未知
1: "计划中", 1: "计划中",
2: "已下发", 2: "派单中", # 已下发 # 付工说改为派单中更好
0: None # 未知 3: "已超时",
4: "未扫码"
} }
status_text = status_mapping.get(pd_record.Status) status_text = status_mapping.get(pd_record.Status)
self.dispatch_details_dialog.set_row_value(5, status_text) self.dispatch_details_dialog.set_row_value(5, status_text)
if status_text == "计划中": # 只有派单状态为计划中,详情界面才能够修改方量
self.dispatch_details_dialog.set_modify_volume_status(True)
else:
self.dispatch_details_dialog.set_modify_volume_status(False)
# 派单模式(1自动派单 2手动派单 0未知 Mode: int = 0 # 派单模式(1自动派单 2手动派单 0未知 Mode: int = 0
mode_mapping = { mode_mapping = {
1: "自动派单", 1: "自动派单",
@ -395,7 +488,57 @@ class MainWindow(QWidget):
} }
mode_text = mode_mapping.get(pd_record.Mode) mode_text = mode_mapping.get(pd_record.Mode)
self.dispatch_details_dialog.set_row_value(6, mode_text) self.dispatch_details_dialog.set_row_value(6, mode_text)
def handleDispatchTaskSelected(self, dispatch_task_name:str):
"""处理派单任务按钮选中, 更新计划表单相关的(计划单号、计划方量等)"""
pd_record:PDRecordModel = self.dispatch_dict.get(dispatch_task_name) # 根据派单任务名获取派单记录
self.current_dispatch_task_select_btn_name = dispatch_task_name # 更新派单任务选择按钮对应的任务名
self.updatePlanTableWidget(pd_record) # 更新计划表单
def handleDispatchTaskVolumeModified(self, dispatch_task_name:str, final_volume:float):
"""处理派单任务方量修改"""
pd_record:PDRecordModel = self.dispatch_dict.get(dispatch_task_name)
if pd_record:
volume_dict = {
"ID": pd_record.ID,
"ArtifactActionID": pd_record.ArtifactActionID,
"Volume": final_volume
}
volume_json_str = json.dumps(volume_dict, ensure_ascii=False)
# print("volume_json_str: ", volume_json_str)
self.plan_volume_modified_signal.emit(volume_json_str)
def updatePlanTableWidget(self, pd_record:PDRecordModel):
"""更新计划表单"""
def format_plan_number(num):
# 格式化计划单号
# 保留最后5位再补零
remainder = num % 100000
return f"{remainder:05d}"
if pd_record and hasattr(self, "plan_table_widget"):
plan_number = format_plan_number(pd_record.ID) # 计划单号
self.plan_table_widget.set_plan_no(f"PD{plan_number}") # 更新计划表单的计划单号 (PD+表单ID)
self.plan_table_widget.set_plan_volume(pd_record.FBetonVolume) # 更新计划表单的计划方量
self.plan_table_widget.set_plan_ratio(pd_record.ProduceMixID) # 更新计划表单的计划配比
# 派单模式(1自动派单 2手动派单 0未知 Mode: int = 0
status_mapping = {
0: "", # 未知
1: "计划中",
2: "派单中", # 已下发 # 付工说改为派单中更好
3: "已超时",
4: "未扫码"
}
status_text = status_mapping.get(pd_record.Status)
self.plan_table_widget.set_status(status_text)
if status_text == "计划中": # 计划表单只有派单状态为计划中,才能够修改方量
self.plan_table_widget.set_modify_volume_status(True)
else:
self.plan_table_widget.set_modify_volume_status(False)
# 更新计划表单对应的任务名
self.plan_table_widget.set_plan_table_task_name(self.current_dispatch_task_select_btn_name)
# 更新 派单任务widget的坐标 # 更新 派单任务widget的坐标
def update_dispatch_task_position(self): def update_dispatch_task_position(self):
@ -480,13 +623,15 @@ class MainWindow(QWidget):
if task_name == self.current_selected_segment_detail_name: if task_name == self.current_selected_segment_detail_name:
self.updateSegmentTaskDetailsDialog(artifact_info) # 刷新管片任务详情按钮弹窗 self.updateSegmentTaskDetailsDialog(artifact_info) # 刷新管片任务详情按钮弹窗
# ======= 设置派单任务详情接口 ========== # ======= 设置派单任务接口 ==========
# self.dispatch_dict 派单信息的字典 # self.dispatch_dict 派单信息的字典
def SetPDRecordTaskDetails(self, task_name:str, pd_record:PDRecordModel): def SetPDRecordTask(self, task_name:str, pd_record:PDRecordModel):
self.dispatch_dict[task_name] = pd_record self.dispatch_dict[task_name] = pd_record
if hasattr(self, "dispatch_details_dialog") and self.dispatch_details_dialog and self.dispatch_details_dialog.isVisible(): if hasattr(self, "dispatch_details_dialog") and self.dispatch_details_dialog and self.dispatch_details_dialog.isVisible():
if task_name == self.current_selected_dispatch_detail_name: if task_name == self.current_selected_dispatch_detail_name:
self.updateDispatchTaskDetailsDialog(pd_record) # 刷新派单任务详情按钮弹窗 self.updateDispatchTaskDetailsDialog(pd_record) # 刷新派单任务详情按钮弹窗
if hasattr(self, "plan_table_widget") and task_name == self.current_dispatch_task_select_btn_name:
self.updatePlanTableWidget(pd_record) # 刷新计划表单
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys

View File

@ -278,6 +278,14 @@ class ArcProgressWidget(QWidget):
# 管片编号设置 # 管片编号设置
def setSegmentNumber(self, segmentNumberStr:str): def setSegmentNumber(self, segmentNumberStr:str):
self.segment_number_label.setText(segmentNumberStr) self.segment_number_label.setText(segmentNumberStr)
# 环号设置
def setRingNumber(self, ringNumber:int):
self.ring_number_label.setText(f"环号: {ringNumber}")
# 管片尺寸(规格)设置 比如6900*1500
def setSegmentSize(self, SizeSpecification:str):
self.segment_size_label.setText(SizeSpecification)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -337,10 +337,10 @@ class DispatchDetailsDialog(QDialog):
self.modify_btn.show() self.modify_btn.show()
# 2、修改 派单方量标签的值 # 2、修改 派单方量标签的值
volume_label = self.rows[4].value # volume_label = self.rows[4].value
# modifyed_value 为float类型, 一位小数 # modifyed_value 为float类型, 一位小数
modifyed_value = self.volume_value_adjuster.get_value() modifyed_value = self.volume_value_adjuster.get_value()
volume_label.setText(str(modifyed_value)) # volume_label.setText(str(modifyed_value))
# 3、发送派单方量确定修改的信号 (发送派单任务名 + 确认修改之后的派单方量) # 3、发送派单方量确定修改的信号 (发送派单任务名 + 确认修改之后的派单方量)
self.confirm_modify_volume.emit(self.dispatch_task_name, modifyed_value) self.confirm_modify_volume.emit(self.dispatch_task_name, modifyed_value)
@ -383,6 +383,16 @@ class DispatchDetailsDialog(QDialog):
if 0 <= row < len(self.rows): if 0 <= row < len(self.rows):
self.rows[row].value.setText(str(new_value_text) if new_value_text is not None else "") self.rows[row].value.setText(str(new_value_text) if new_value_text is not None else "")
def set_dispatch_task_name(self, task_name:str):
"""设置/刷新 派单任务名"""
self.dispatch_task_name = task_name
def set_modify_volume_status(self, status:bool):
"""设置是否能够在派单详情界面修改方量,
status为False即不能修改方量, 为True表示能够修改方量
"""
self.modify_btn.setVisible(status)
# 测试代码 # 测试代码
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1,6 +1,6 @@
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QApplication) QApplication)
from PySide6.QtCore import Qt from PySide6.QtCore import Qt, Signal, QTimer
from PySide6.QtGui import QPainter, QPixmap from PySide6.QtGui import QPainter, QPixmap
from .value_adjuster import ValueAdjuster from .value_adjuster import ValueAdjuster
from .switch_button import SwitchButton from .switch_button import SwitchButton
@ -10,6 +10,14 @@ import resources.resources_rc
from utils.image_paths import ImagePaths from utils.image_paths import ImagePaths
class PlanWidget(QWidget): class PlanWidget(QWidget):
# 自动派单切换信号
# True: 自动派单 False: 手动派单
auto_dispatch_signal = Signal(bool)
# 计划表单最终的确认的修改的方量
# 对应的任务名, 最终的方量
final_modify_volume_signal = Signal(str, float)
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
# 加载背景图 # 加载背景图
@ -25,6 +33,16 @@ class PlanWidget(QWidget):
"auto_dispatch": None # 自动派单SwitchButton "auto_dispatch": None # 自动派单SwitchButton
} }
# ==================================================
# 用于计划表单的修改方量的最终确认
# 1、确认最终修改的方量的计时器超时代表着确认了最终的方量
self.volume_timer = QTimer(self)
self.volume_timer.setInterval(2500) # 2.5秒延迟(根据需求调整)
self.volume_timer.setSingleShot(True) # 单次触发:避免重复执行
self.volume_timer.timeout.connect(self._sync_final_volume)
# 2、该计划表单对应的任务名
self.plan_table_task_name = None
# 主垂直布局 # 主垂直布局
main_layout = QVBoxLayout(self) main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(13, 5, 6, 15) main_layout.setContentsMargins(13, 5, 6, 15)
@ -63,6 +81,8 @@ class PlanWidget(QWidget):
row2_layout.addWidget(label2) row2_layout.addWidget(label2)
self.fangliang_adjuster = ValueAdjuster() # 导入的方量调整控件 self.fangliang_adjuster = ValueAdjuster() # 导入的方量调整控件
self.fangliang_adjuster.minus_btn.clicked.connect(self._reset_volume_timer)
self.fangliang_adjuster.plus_btn.clicked.connect(self._reset_volume_timer)
row2_layout.addWidget(self.fangliang_adjuster) row2_layout.addWidget(self.fangliang_adjuster)
main_layout.addLayout(row2_layout) main_layout.addLayout(row2_layout)
self.controls["volume"] = self.fangliang_adjuster self.controls["volume"] = self.fangliang_adjuster
@ -75,7 +95,7 @@ class PlanWidget(QWidget):
row3_layout.addWidget(status_icon3) row3_layout.addWidget(status_icon3)
row3_layout.addSpacing(4) row3_layout.addSpacing(4)
label3 = QLabel("计划配比") label3 = QLabel("")
label3.setStyleSheet("font-size: 18px; color: #03f5ff;") label3.setStyleSheet("font-size: 18px; color: #03f5ff;")
row3_layout.addWidget(label3) row3_layout.addWidget(label3)
@ -117,11 +137,24 @@ class PlanWidget(QWidget):
row5_layout.addWidget(label5) row5_layout.addWidget(label5)
self.switch = SwitchButton() self.switch = SwitchButton()
self.switch.switched.connect(self.auto_dispatch_signal)
self.switch.setChecked(True) self.switch.setChecked(True)
row5_layout.addWidget(self.switch, alignment=Qt.AlignLeft) row5_layout.addWidget(self.switch, alignment=Qt.AlignLeft)
main_layout.addLayout(row5_layout) main_layout.addLayout(row5_layout)
self.controls["auto_dispatch"] = self.switch self.controls["auto_dispatch"] = self.switch
def _reset_volume_timer(self):
"""每次调整方量时,重置定时器(倒计时重新开始)"""
if self.volume_timer.isActive(): # 如果定时器正在运行,先停止
self.volume_timer.stop()
self.volume_timer.start() # 重启定时器
def _sync_final_volume(self):
"""同步 确认的最终的修改方量"""
final_volume = self.fangliang_adjuster.get_value()
# print("最终确认的方量为:", final_volume)
self.final_modify_volume_signal.emit(self.plan_table_task_name, final_volume)
def paintEvent(self, event): def paintEvent(self, event):
"""绘制背景图片""" """绘制背景图片"""
painter = QPainter(self) painter = QPainter(self)
@ -150,10 +183,21 @@ class PlanWidget(QWidget):
self.controls["status"].setText(new_status) self.controls["status"].setText(new_status)
def set_auto_dispatch(self, is_checked:bool): def set_auto_dispatch(self, is_checked:bool):
"""修改自动派单开关状态, true: 开启自动派单, False: 关闭自动派单""" """修改自动派单开关状态, true: 自动派单, False: 动派单"""
if self.controls["auto_dispatch"]: if self.controls["auto_dispatch"]:
self.controls["auto_dispatch"].setChecked(is_checked) self.controls["auto_dispatch"].setChecked(is_checked)
def set_modify_volume_status(self, status:bool):
"""设置 计划表单中修改方量控件的状态, 是否能够修改方量
status: True, 能够修改方量
False, 不能修改方量
"""
self.fangliang_adjuster.setEnabled(status)
def set_plan_table_task_name(self, task_name:str):
"""设置 计划表单对应的选中任务名"""
self.plan_table_task_name = task_name
if __name__ == "__main__": if __name__ == "__main__":
app = QApplication(sys.argv) app = QApplication(sys.argv)
widget = PlanWidget() widget = PlanWidget()

View File

@ -11,8 +11,10 @@ from utils.image_paths import ImagePaths
任务控件,如:管片任务、派单任务 任务控件,如:管片任务、派单任务
""" """
class TaskWidget(QWidget): class TaskWidget(QWidget):
# 任务详情信号: task1表示第一条任务 # 任务详情信号: task1表示第一条任务 (用于详情对话框)
task_details_signal = Signal(str) task_details_signal = Signal(str)
# 任务选择按钮选中的信号 (用于上方的计划表单)
task_selected_signal = Signal(str)
def __init__(self, taskTitle:str, parent=None): def __init__(self, taskTitle:str, parent=None):
super().__init__(parent) super().__init__(parent)
@ -40,6 +42,7 @@ class TaskWidget(QWidget):
# 用字典存储每个任务的可修改控件(键:任务名,值:控件字典) # 用字典存储每个任务的可修改控件(键:任务名,值:控件字典)
self.task_controls = {} # 结构:{"task1": {"volume_label": xxx, "time_label": xxx, ...}, ...} self.task_controls = {} # 结构:{"task1": {"volume_label": xxx, "time_label": xxx, ...}, ...}
self.current_selected_task = None # 选择按钮,当前选中的任务的任务名
# 三条任务条目 # 三条任务条目
self._add_task("task1", "SHRB1-3", ImagePaths.TASK_RECT1) self._add_task("task1", "SHRB1-3", ImagePaths.TASK_RECT1)
@ -87,12 +90,17 @@ class TaskWidget(QWidget):
}} }}
""") """)
select_btn.setCheckable(True) select_btn.setCheckable(True)
select_btn.clicked.connect(lambda checked, tn=task_name: self._on_select_btn_clicked(tn, checked))
controls["select_btn"] = select_btn controls["select_btn"] = select_btn
row1_layout.addWidget(select_btn) row1_layout.addWidget(select_btn)
# 任务编号 # 任务编号
task_id_label = QLabel(task_id) task_id_label = QLabel(task_id)
task_id_label.setStyleSheet("font-size: 18px; color: #16ffff;padding-left: 6px;") task_id_label.setStyleSheet("font-size: 18px; color: #16ffff;padding-left: 6px;")
# 1. 设置鼠标样式为手型,提示可点击
task_id_label.setCursor(Qt.PointingHandCursor)
# 2. 绑定点击事件点击标签时选中对应的select_btn
task_id_label.mousePressEvent = lambda event, tn=task_name: self._on_task_id_clicked(tn)
controls["task_id_label"] = task_id_label controls["task_id_label"] = task_id_label
row1_layout.addWidget(task_id_label) row1_layout.addWidget(task_id_label)
@ -124,7 +132,7 @@ class TaskWidget(QWidget):
row2_layout = QHBoxLayout() row2_layout = QHBoxLayout()
# 方量标签 # 方量标签
volume_label = QLabel("方量 200") volume_label = QLabel("方量 200")
volume_label.setStyleSheet("color: #a1c1d7; font-size: 14px;padding-left: 19px;") volume_label.setStyleSheet("color: #a1c1d7; font-size: 14px;padding-left: 6px;")
controls["volume_label"] = volume_label controls["volume_label"] = volume_label
row2_layout.addWidget(volume_label) row2_layout.addWidget(volume_label)
@ -138,13 +146,19 @@ class TaskWidget(QWidget):
time_label.setStyleSheet("color: #a1c1d7; font-size: 14px;") time_label.setStyleSheet("color: #a1c1d7; font-size: 14px;")
controls["time_label"] = time_label controls["time_label"] = time_label
row2_layout.addWidget(time_label) row2_layout.addWidget(time_label)
# 状态文本标签
status_text_label = QLabel()
status_text_label.setStyleSheet("color: #16ffff; font-size: 14px;")
controls["status_text_label"] = status_text_label
row2_layout.addWidget(status_text_label)
# 状态标签 # 状态图标标签
status_icon_label = QLabel() status_icon_label = QLabel()
status_icon_label.setPixmap(QPixmap(status_icon)) status_icon_label.setPixmap(QPixmap(status_icon))
controls["status_icon_label"] = status_icon_label controls["status_icon_label"] = status_icon_label
row2_layout.addWidget(status_icon_label, alignment=Qt.AlignRight) row2_layout.addWidget(status_icon_label, alignment=Qt.AlignRight)
# 添加水平布局2到item_layout
item_layout.addLayout(row2_layout) item_layout.addLayout(row2_layout)
# 分隔线 # 分隔线
@ -165,6 +179,42 @@ class TaskWidget(QWidget):
# 发送任务详情信号 # 发送任务详情信号
self.task_details_signal.emit(task_name) self.task_details_signal.emit(task_name)
def _on_select_btn_clicked(self, task_name: str, checked: bool):
"""
处理选择按钮点击事件,实现互斥选中
:param task_name: 点击的任务名task1/task2/task3
:param checked: 按钮是否被选中True/False
"""
# 1. 如果是选中操作checked=True
if checked:
# 取消之前选中的任务按钮
if self.current_selected_task and self.current_selected_task != task_name:
prev_select_btn = self.task_controls[self.current_selected_task]["select_btn"]
prev_select_btn.setChecked(False) # 取消选中
# 更新当前选中的任务
self.current_selected_task = task_name
# 通知任务选中按钮更新了选中
self.task_selected_signal.emit(task_name)
else:
# 2. 如果是取消选中操作checked=False
# 重新设为选中状态,阻止取消 (确保该按钮继续为选中状态,保证至少有一个按钮被选中)
current_select_btn = self.task_controls[task_name]["select_btn"]
current_select_btn.setChecked(True)
# 确保选中标记不丢失
self.current_selected_task = task_name
def _on_task_id_clicked(self, task_name: str):
"""
点击任务编号标签时,选中对应的选择按钮(复用互斥逻辑)
:param task_name: 点击的任务名task1/task2/task3
"""
if task_name in self.task_controls:
# 1. 获取对应select_btn
select_btn = self.task_controls[task_name]["select_btn"]
# 2. 模拟点击相应的选择按钮
if not select_btn.isChecked():
select_btn.click()
# -------------------------- # --------------------------
# 对外接口:修改任务属性 # 对外接口:修改任务属性
# 三个任务条目对应的任务名task_name分别为 task1、task2、task3 # 三个任务条目对应的任务名task_name分别为 task1、task2、task3
@ -185,11 +235,36 @@ class TaskWidget(QWidget):
time_label = self.task_controls[task_name]["time_label"] time_label = self.task_controls[task_name]["time_label"]
time_label.setText(time_str) time_label.setText(time_str)
def set_task_status(self, task_name:str, status_str: str, icon_path:str):
"""修改指定任务的状态, 比如: 已下发、计划中等"""
ICON_COLOR_MAP = {
ImagePaths.TASK_RECT1: "#16ffff",
ImagePaths.TASK_RECT2: "#ffab11",
ImagePaths.TASK_RECT3: "#54f529",
ImagePaths.TASK_RECT4: "#ff6a5c",
ImagePaths.TASK_RECT5: "#f6f44b"
}
DEFAULT_COLOR = "#000000"
if task_name in self.task_controls:
status_label = self.task_controls[task_name]["status_text_label"] # 状态文本
status_label.setText(status_str)
icon_label = self.task_controls[task_name]["status_icon_label"] # 状态图标
icon_label.setPixmap(QPixmap(icon_path))
# 修改状态文本的颜色
status_text_color = ICON_COLOR_MAP.get(icon_path, DEFAULT_COLOR)
status_label.setStyleSheet(f"QLabel {{ color: {status_text_color}; font-size: 14px;}}")
def set_task_id(self, task_name:str, new_id: str): def set_task_id(self, task_name:str, new_id: str):
"""修改指定任务的编号, 如: SHRB2-3""" """修改指定任务的编号, 如: SHRB2-3"""
if task_name in self.task_controls: if task_name in self.task_controls:
task_id_label = self.task_controls[task_name]["task_id_label"] task_id_label = self.task_controls[task_name]["task_id_label"]
task_id_label.setText(new_id) task_id_label.setText(new_id)
def set_task_select_btn_selected(self, task_name:str):
"""设置 任务选择按钮选中 (主要用于刷新计划表单)"""
if task_name in self.task_controls:
task_select_btn = self.task_controls[task_name]["select_btn"]
task_select_btn.click()
def get_task_volume(self, task_name:str): def get_task_volume(self, task_name:str):
""" """