feat: 添加运行模式选择功能,更新配置加载逻辑以支持单机模式和接口模式

This commit is contained in:
zhu-mengmeng 2025-06-17 10:57:49 +08:00
parent 1a5fa1a95b
commit 507a345d43
6 changed files with 220 additions and 45 deletions

Binary file not shown.

View File

@ -109,6 +109,29 @@ class MainWindowUI(QMainWindow):
self.task_label.setStyleSheet("font-weight: bold; color: #333333;")
self.task_layout.addWidget(self.task_label)
# 订单行
self.order_layout = QHBoxLayout()
self.order_layout.setAlignment(Qt.AlignLeft) # 设置整个布局左对齐
self.order_label = QLabel("工程号")
self.order_label.setFont(QFont("微软雅黑", 12, QFont.Bold))
self.order_label.setFixedHeight(30)
self.order_label.setStyleSheet("padding: 0 5px; color: #333333;")
self.order_edit = QLineEdit()
self.order_edit.setFixedHeight(30)
self.order_edit.setFixedWidth(150)
self.order_edit.setReadOnly(False)
self.order_edit.setFont(QFont("微软雅黑", 12))
self.order_edit.setText("") # 设置默认订单号
self.order_edit.setStyleSheet("background-color: #f9f9f9; border: 1px solid #cccccc; border-radius: 3px; padding: 2px 5px;")
self.order_layout.addWidget(self.order_label)
self.order_layout.addWidget(self.order_edit)
self.order_layout.addStretch() # 添加弹性空间,将组件推到左侧
self.task_layout.addLayout(self.order_layout)
# 任务表格 - 使用合并单元格实现一级二级标题
self.task_table = QTableWidget(3, 4) # 3行4列一级标题行、二级标题行、数据行
self.task_table.setEditTriggers(QTableWidget.NoEditTriggers) # 设置为不可编辑
@ -148,24 +171,6 @@ class MainWindowUI(QMainWindow):
self.task_table.setRowHeight(2, 30) # 数据行高
self.task_layout.addWidget(self.task_table)
# 订单行
self.order_layout = QHBoxLayout()
self.order_label = QLabel("工程号")
self.order_label.setFont(QFont("微软雅黑", 12, QFont.Bold))
self.order_label.setFixedHeight(35)
self.order_label.setStyleSheet("padding: 0 5px; color: #333333;")
self.order_edit = QLineEdit()
self.order_edit.setFixedHeight(35)
self.order_edit.setReadOnly(False)
self.order_edit.setFont(QFont("微软雅黑", 12))
self.order_edit.setText("ORD-2025-001") # 设置默认订单号
self.order_edit.setStyleSheet("background-color: #f9f9f9; border: 1px solid #cccccc; border-radius: 3px; padding: 2px 5px;")
self.order_layout.addWidget(self.order_label)
self.order_layout.addWidget(self.order_edit)
self.task_layout.addLayout(self.order_layout)
self.left_layout.addWidget(self.task_frame)
# 上料区 - 使用QFrame包裹添加边框

View File

@ -1,7 +1,7 @@
from PySide6.QtWidgets import (
QWidget, QLabel, QLineEdit, QPushButton, QComboBox, QGridLayout, QHBoxLayout, QVBoxLayout,
QTabWidget, QFrame, QFormLayout, QGroupBox, QRadioButton, QSpacerItem, QSizePolicy,
QTableWidget, QTableWidgetItem, QHeaderView, QSlider, QCheckBox
QTableWidget, QTableWidgetItem, QHeaderView, QSlider, QCheckBox, QButtonGroup
)
from PySide6.QtGui import QFont, QBrush, QColor
from PySide6.QtCore import Qt, Signal, QSize
@ -233,6 +233,34 @@ class SettingsUI(QWidget):
self.db_type_group.setLayout(self.db_type_layout)
self.database_layout.addWidget(self.db_type_group)
# 添加运行模式选择组
self.mode_group = QGroupBox("运行模式")
self.mode_group.setFont(self.normal_font)
self.mode_layout = QHBoxLayout()
# 创建单选按钮组
self.mode_button_group = QButtonGroup(self)
# 创建单机模式单选按钮
self.standalone_mode_radio = QRadioButton("单机模式")
self.standalone_mode_radio.setFont(self.normal_font)
self.standalone_mode_radio.setChecked(True) # 默认选中单机模式
self.mode_button_group.addButton(self.standalone_mode_radio, 1)
# 创建接口模式单选按钮
self.api_mode_radio = QRadioButton("接口模式")
self.api_mode_radio.setFont(self.normal_font)
self.mode_button_group.addButton(self.api_mode_radio, 2)
# 添加单选按钮到布局
self.mode_layout.addWidget(QLabel("选择运行模式:"))
self.mode_layout.addWidget(self.standalone_mode_radio)
self.mode_layout.addWidget(self.api_mode_radio)
self.mode_layout.addStretch(1)
self.mode_group.setLayout(self.mode_layout)
self.database_layout.addWidget(self.mode_group)
# 数据库连接设置
self.db_conn_group = QGroupBox("连接设置")
self.db_conn_group.setFont(self.normal_font)

56
utils/app_mode.py Normal file
View File

@ -0,0 +1,56 @@
import logging
from utils.config_loader import ConfigLoader
class AppMode:
"""
应用运行模式工具类用于判断当前系统是单机模式还是接口模式
"""
@staticmethod
def get_mode():
"""
获取当前应用运行模式
Returns:
str: 'standalone'(单机模式) 'api'(接口模式)
"""
config_loader = ConfigLoader.get_instance()
return config_loader.get_app_mode()
@staticmethod
def set_mode(mode):
"""
设置应用运行模式
Args:
mode: 'standalone'(单机模式) 'api'(接口模式)
Returns:
bool: 是否设置成功
"""
config_loader = ConfigLoader.get_instance()
result = config_loader.set_app_mode(mode)
logging.info(f"应用运行模式已设置为: {mode}")
return result
@staticmethod
def is_standalone():
"""
检查是否为单机模式
Returns:
bool: True表示单机模式False表示接口模式
"""
config_loader = ConfigLoader.get_instance()
return config_loader.is_standalone_mode()
@staticmethod
def is_api():
"""
检查是否为接口模式
Returns:
bool: True表示接口模式False表示单机模式
"""
config_loader = ConfigLoader.get_instance()
return config_loader.is_api_mode()

View File

@ -45,7 +45,8 @@ class ConfigLoader:
"enable_serial_ports": False,
"enable_keyboard_listener": False,
"enable_camera": False
}
},
"mode": "standalone" # 默认为单机模式
},
"database": {
"current": "sqlite",
@ -104,7 +105,8 @@ class ConfigLoader:
"enable_serial_ports": False,
"enable_keyboard_listener": False,
"enable_camera": False
}
},
"mode": "standalone" # 默认为单机模式
},
"database": {
"current": "sqlite",
@ -180,6 +182,12 @@ class ConfigLoader:
db_config['default'] = 'postgresql'
self.save_config()
# 检查并添加运行模式配置
if 'app' in self.config and 'mode' not in self.config['app']:
logging.info("添加运行模式配置...")
self.config['app']['mode'] = 'standalone'
self.save_config()
except Exception as e:
logging.error(f"升级配置文件结构失败: {e}")
@ -241,6 +249,49 @@ class ConfigLoader:
# 保存配置
return self.save_config()
def get_app_mode(self):
"""
获取应用运行模式
Returns:
str: 'standalone'(单机模式) 'api'(接口模式)
"""
return self.get_value('app.mode', 'standalone')
def set_app_mode(self, mode):
"""
设置应用运行模式
Args:
mode: 'standalone'(单机模式) 'api'(接口模式)
Returns:
bool: 是否设置成功
"""
if mode not in ['standalone', 'api']:
logging.error(f"无效的运行模式: {mode},必须是 'standalone''api'")
return False
return self.set_value('app.mode', mode)
def is_standalone_mode(self):
"""
检查是否为单机模式
Returns:
bool: True表示单机模式False表示接口模式
"""
return self.get_app_mode() == 'standalone'
def is_api_mode(self):
"""
检查是否为接口模式
Returns:
bool: True表示接口模式False表示单机模式
"""
return self.get_app_mode() == 'api'
def get_config(self, key):
"""
获取serial配置下的指定配置
@ -249,15 +300,10 @@ class ConfigLoader:
key: 配置键例如'mdz', 'cz'
Returns:
dict: 配置未找到则返回None
dict: 配置数据
"""
if 'serial' not in self.config:
self.config['serial'] = {}
if key not in self.config['serial']:
return None
return self.config['serial'][key]
serial_config = self.config.get('serial', {})
return serial_config.get(key, {})
def set_config(self, key, config_data):
"""
@ -265,7 +311,7 @@ class ConfigLoader:
Args:
key: 配置键例如'mdz', 'cz'
config_data: 要设置的配置数据
config_data: 配置数据
Returns:
bool: 是否设置成功
@ -274,26 +320,24 @@ class ConfigLoader:
self.config['serial'] = {}
self.config['serial'][key] = config_data
# 这里不保存配置等待调用save_config方法时一并保存
return True
return self.save_config()
def get_database_config(self, db_type=None):
"""
获取指定类型的数据库配置
获取数据库配置
Args:
db_type: 数据库类型'sqlite', 'postgresql', 'mysql'不指定则使用默认配置
db_type: 数据库类型果为None则返回当前使用的数据库配置
Returns:
dict: 数据库配置
"""
# 如果未指定数据库类型,使用当前设置的类型
db_config = self.config.get('database', {})
db_sources = db_config.get('sources', {})
# 如果未指定数据库类型,则使用当前配置的数据库类型
if db_type is None:
db_type = self.get_value('database.default', 'sqlite')
db_type = db_config.get('current', 'sqlite')
# 处理pgsql和postgresql兼容
if db_type == 'pgsql':
db_type = 'postgresql'
# 获取数据库配置
return self.get_value(f'database.sources.{db_type}', {})
# 返回指定类型的数据库配置
return db_sources.get(db_type, {})

View File

@ -1,4 +1,5 @@
from PySide6.QtWidgets import QMessageBox, QVBoxLayout
from PySide6.QtCore import Qt
import logging
import json
import os
@ -7,6 +8,7 @@ from utils.sql_utils import SQLUtils
from widgets.inspection_settings_widget import InspectionSettingsWidget
from widgets.pallet_type_settings_widget import PalletTypeSettingsWidget
from utils.config_loader import ConfigLoader
from utils.app_mode import AppMode
class SettingsWidget(SettingsUI):
def __init__(self, parent=None):
@ -64,6 +66,9 @@ class SettingsWidget(SettingsUI):
# 初始化数据库类型UI状态
self.load_db_config()
# 初始化运行模式状态
self.load_app_mode()
logging.info("SettingsWidget初始化完成")
def connect_signals(self):
@ -87,6 +92,43 @@ class SettingsWidget(SettingsUI):
if hasattr(self, 'back_button'):
self.back_button.clicked.connect(self.back_to_main)
# 运行模式单选按钮
self.standalone_mode_radio.toggled.connect(self.on_app_mode_changed)
self.api_mode_radio.toggled.connect(self.on_app_mode_changed)
def load_app_mode(self):
"""加载应用运行模式设置"""
try:
# 获取当前运行模式
current_mode = AppMode.get_mode()
# 设置对应的单选按钮
if current_mode == 'api':
self.api_mode_radio.setChecked(True)
else: # 默认为standalone
self.standalone_mode_radio.setChecked(True)
logging.info(f"已加载应用运行模式: {current_mode}")
except Exception as e:
logging.error(f"加载应用运行模式失败: {e}")
# 默认选择单机模式
self.standalone_mode_radio.setChecked(True)
def on_app_mode_changed(self, checked):
"""处理运行模式变更"""
if not checked: # 忽略未选中状态的信号
return
try:
if self.standalone_mode_radio.isChecked():
AppMode.set_mode('standalone')
logging.info("已将应用运行模式设置为: 单机模式")
elif self.api_mode_radio.isChecked():
AppMode.set_mode('api')
logging.info("已将应用运行模式设置为: 接口模式")
except Exception as e:
logging.error(f"设置应用运行模式失败: {e}")
def load_db_config(self):
"""加载数据库配置"""
try: