全局修正
This commit is contained in:
@ -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()
|
||||
|
||||
|
||||
@ -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:水质光谱指数计算"""
|
||||
|
||||
Reference in New Issue
Block a user