全局修正

This commit is contained in:
DXC
2026-06-29 16:16:55 +08:00
parent 2788fb3fe1
commit e337f01312
7 changed files with 437 additions and 104 deletions

View File

@ -236,6 +236,16 @@ class AISettingsDialog(QDialog):
layout = QVBoxLayout(self)
layout.setSpacing(12)
s = QSettings(AI_SETTINGS_ORG, AI_SETTINGS_APP)
# ★ 通用工具:把历史记录列表绑定到 QComboBox去重追加
def _fill_combo_history(combo: QComboBox, history: list, preset: list):
if not history:
return
for item in history:
if item and item not in preset and combo.findText(item) == -1:
combo.addItem(item)
# ── Provider ──────────────────────────────────────────────────────────
provider_row = QHBoxLayout()
provider_row.addWidget(QLabel("AI 引擎提供商:"))
@ -243,7 +253,10 @@ class AISettingsDialog(QDialog):
# ★ 核心改动:开启可编辑模式,允许用户随意输入第三方代理商名字
self._provider_combo.setEditable(True)
self._provider_combo.addItems(["Aliyun", "Zhipu", "DeepSeek", "OpenAI", "Minimax", "Ollama"])
provider_preset = ["Aliyun", "Zhipu", "DeepSeek", "OpenAI", "Minimax", "Ollama"]
self._provider_combo.addItems(provider_preset)
# 【历史倒灌】去重追加最近用过的 provider
_fill_combo_history(self._provider_combo, s.value("ai_provider_history", [], type=list), provider_preset)
self._provider_combo.setCurrentText(self._provider)
# 当文本改变时自动带出推荐配置
@ -256,8 +269,12 @@ class AISettingsDialog(QDialog):
# ── API Base URL ───────────────────────────────────────────────────────
url_row = QHBoxLayout()
url_row.addWidget(QLabel("API Base URL:"))
self._url_edit = QLineEdit(self._api_base_url)
self._url_edit.setPlaceholderText("填入兼容 OpenAI 规范的完整 URL")
# 升级为可编辑下拉框:保留历史下拉 + 允许自由输入 111/localhost 等自定义值
self._url_edit = QComboBox()
self._url_edit.setEditable(True)
self._url_edit.addItems(s.value("api_url_history", [], type=list))
self._url_edit.setCurrentText(self._api_base_url)
self._url_edit.setPlaceholderText("可输入 111/localhost 等自定义值并自动记忆")
url_row.addWidget(self._url_edit, 1)
layout.addLayout(url_row)
@ -273,11 +290,18 @@ class AISettingsDialog(QDialog):
# ── 模型名称 ───────────────────────────────────────────────────────────
model_row = QHBoxLayout()
model_row.addWidget(QLabel("视觉模型:"))
self._vision_edit = QLineEdit(self._vision_model)
# 升级为可编辑下拉框:保留历史下拉 + 允许自由输入
self._vision_edit = QComboBox()
self._vision_edit.setEditable(True)
self._vision_edit.addItems(s.value("vision_model_history", [], type=list))
self._vision_edit.setCurrentText(self._vision_model)
model_row.addWidget(self._vision_edit, 1)
model_row.addSpacing(12)
model_row.addWidget(QLabel("文本模型:"))
self._text_edit = QLineEdit(self._text_model)
self._text_edit = QComboBox()
self._text_edit.setEditable(True)
self._text_edit.addItems(s.value("text_model_history", [], type=list))
self._text_edit.setCurrentText(self._text_model)
model_row.addWidget(self._text_edit, 1)
layout.addLayout(model_row)
@ -317,21 +341,41 @@ class AISettingsDialog(QDialog):
provider_key = text.lower()
if provider_key in AI_DEFAULTS:
defaults = AI_DEFAULTS[provider_key]
self._url_edit.setText(defaults["api_base_url"])
self._vision_edit.setText(defaults["vision_model"])
self._text_edit.setText(defaults["text_model"])
self._url_edit.setCurrentText(defaults["api_base_url"])
self._vision_edit.setCurrentText(defaults["vision_model"])
self._text_edit.setCurrentText(defaults["text_model"])
def _save_and_close(self):
"""持久化到 QSettings 并关闭。"""
s = QSettings(AI_SETTINGS_ORG, AI_SETTINGS_APP)
# 获取用户输入的文本(无论是选的还是自己打字的)
provider = self._provider_combo.currentText().strip()
url = self._url_edit.currentText().strip()
vision = self._vision_edit.currentText().strip()
text = self._text_edit.currentText().strip()
s.setValue("ai_provider", provider)
s.setValue("api_base_url", self._url_edit.text().strip())
s.setValue("api_base_url", url)
s.setValue("api_key", self._key_edit.text().strip())
s.setValue("vision_model", self._vision_edit.text().strip())
s.setValue("text_model", self._text_edit.text().strip())
s.setValue("vision_model", vision)
s.setValue("text_model", text)
s.setValue("timeout_s", self._timeout_spin.value())
# 【历史记录记忆拦截器】去重 + 最新在前 + 最多 10 条
def _push_history(key: str, value: str):
if not value:
return
hist = s.value(key, [], type=list) or []
if value in hist:
hist.remove(value)
hist.insert(0, value)
s.setValue(key, hist[:10])
_push_history("ai_provider_history", provider)
_push_history("api_url_history", url)
_push_history("vision_model_history", vision)
_push_history("text_model_history", text)
s.sync()
self.accept()

View File

@ -6,21 +6,46 @@ Step7 视图 - 水质光谱指数计算 (完美对齐卡片化重构版)
import os
import sys
import pandas as pd
import csv
from pathlib import Path
from PyQt5.QtWidgets import (
QVBoxLayout, QHBoxLayout, QGroupBox, QFormLayout,
QLabel, QPushButton, QMessageBox, QListWidget,
QListWidgetItem, QSizePolicy, QWidget
QListWidgetItem, QSizePolicy, QWidget, QComboBox,
)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
from src.gui.core.event_bus import global_event_bus
from src.gui.components.custom_widgets import FileSelectWidget
from src.gui.styles import ModernStylesheet
# ==========================================
# 模块级字典 + 防穿透 ListWidget与 Step10 对齐)
# ==========================================
CATEGORY_CHINESE_MAP = {
'Total_Suspended_Matter': '总悬浮物 (TSM)',
'Phycocyanin (BGA_PC)': '藻蓝蛋白 (PC)',
'Turbidity': '浊度 (Turbidity)',
'chlorophyll_a': '叶绿素a (Chl-a)',
'Colored_Dissolved_Organic_Matter': '有色可溶性有机物 (CDOM)',
'Secchi_Disk_Depth': '透明度 (SDD)',
'Total_Nitrogen': '总氮 (TN)',
'Total_Phosphorus': '总磷 (TP)',
'Chemical_Oxygen_Demand': '化学需氧量 (COD)',
'Ammonia_Nitrogen': '氨氮 (NH3-N)',
'Dissolved_Oxygen': '溶解氧 (DO)'
}
class NoScrollPassListWidget(QListWidget):
"""一个绝对不会把滚轮事件传给外层父组件的列表控件(与 Step10 同源)。"""
def wheelEvent(self, event):
super().wheelEvent(event)
event.accept()
class Step7InversionPanel(QWidget):
"""步骤7水质光谱指数计算"""