feat(ai-outfit): apply approved relayout to the panel (§19.3)
- 数据源/输出 become inline label+path+browse rows (_inline_path_row); removed the left group boxes to free vertical space. - 通用话术 + 最终提示词预览 enlarged and stretch with window height. - 生成设置 grid -> 3 columns (2 rows); AI 模型 dropdown moved under it in the right column. Splitter sizes left360/center/right400; right minWidth 360. - Verified offscreen against the mockup (real Qt grab); full suite (12) green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -162,7 +162,7 @@ class AiOutfitPanel(QWidget):
|
|||||||
splitter.setStretchFactor(0, 0)
|
splitter.setStretchFactor(0, 0)
|
||||||
splitter.setStretchFactor(1, 1)
|
splitter.setStretchFactor(1, 1)
|
||||||
splitter.setStretchFactor(2, 0)
|
splitter.setStretchFactor(2, 0)
|
||||||
splitter.setSizes([400, 600, 300])
|
splitter.setSizes([360, 540, 400])
|
||||||
outer.addWidget(splitter)
|
outer.addWidget(splitter)
|
||||||
|
|
||||||
def _build_left(self):
|
def _build_left(self):
|
||||||
@@ -171,37 +171,25 @@ class AiOutfitPanel(QWidget):
|
|||||||
# AsNeeded (not AlwaysOff): if a child ever exceeds the column it scrolls
|
# AsNeeded (not AlwaysOff): if a child ever exceeds the column it scrolls
|
||||||
# instead of being clipped under the center panel (docs/11 §10.1).
|
# instead of being clipped under the center panel (docs/11 §10.1).
|
||||||
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||||
scroll.setMinimumWidth(360)
|
scroll.setMinimumWidth(320)
|
||||||
inner = QWidget()
|
inner = QWidget()
|
||||||
col = QVBoxLayout(inner)
|
col = QVBoxLayout(inner)
|
||||||
col.setContentsMargins(12, 12, 12, 12)
|
col.setContentsMargins(12, 12, 12, 12)
|
||||||
col.setSpacing(12)
|
col.setSpacing(10)
|
||||||
|
|
||||||
# 数据源
|
# 数据源 / 输出:行内一行(标签 + 路径 + 浏览),省纵向空间给话术/预览
|
||||||
src = QGroupBox("数据源(Excel)")
|
|
||||||
sv = QVBoxLayout(src)
|
|
||||||
self._excel_edit = QLineEdit()
|
self._excel_edit = QLineEdit()
|
||||||
self._excel_edit.setPlaceholderText("选择商品表 .xlsx")
|
self._excel_edit.setPlaceholderText("选择商品表 .xlsx")
|
||||||
sv.addLayout(self._path_row(self._excel_edit, self._browse_excel))
|
col.addLayout(self._inline_path_row("Excel", self._excel_edit, self._browse_excel))
|
||||||
col.addWidget(src)
|
|
||||||
|
|
||||||
# 输出 + 模型
|
|
||||||
out = QGroupBox("输出")
|
|
||||||
ov = QVBoxLayout(out)
|
|
||||||
self._output_edit = QLineEdit()
|
self._output_edit = QLineEdit()
|
||||||
self._output_edit.setPlaceholderText("默认:程序旁的「合并后的图片」")
|
self._output_edit.setPlaceholderText("默认:程序旁的「合并后的图片」")
|
||||||
ov.addLayout(self._path_row(self._output_edit, self._browse_output))
|
col.addLayout(self._inline_path_row("输出", self._output_edit, self._browse_output))
|
||||||
ov.addWidget(QLabel("AI 模型"))
|
|
||||||
self._model_combo = QComboBox()
|
|
||||||
self._compact_combo(self._model_combo)
|
|
||||||
ov.addWidget(self._model_combo)
|
|
||||||
col.addWidget(out)
|
|
||||||
|
|
||||||
# 通用话术
|
# 通用话术(加大,随窗口高度拉伸)
|
||||||
prm = QGroupBox("通用话术")
|
prm = QGroupBox("通用话术")
|
||||||
pv = QVBoxLayout(prm)
|
pv = QVBoxLayout(prm)
|
||||||
self._prompt_edit = QPlainTextEdit()
|
self._prompt_edit = QPlainTextEdit()
|
||||||
self._prompt_edit.setFixedHeight(120)
|
self._prompt_edit.setMinimumHeight(150)
|
||||||
self._prompt_edit.textChanged.connect(self._refresh_preview)
|
self._prompt_edit.textChanged.connect(self._refresh_preview)
|
||||||
pv.addWidget(self._prompt_edit)
|
pv.addWidget(self._prompt_edit)
|
||||||
prow = QHBoxLayout()
|
prow = QHBoxLayout()
|
||||||
@@ -213,9 +201,9 @@ class AiOutfitPanel(QWidget):
|
|||||||
save_btn.clicked.connect(self._save_prompt)
|
save_btn.clicked.connect(self._save_prompt)
|
||||||
prow.addWidget(save_btn)
|
prow.addWidget(save_btn)
|
||||||
pv.addLayout(prow)
|
pv.addLayout(prow)
|
||||||
col.addWidget(prm)
|
col.addWidget(prm, stretch=2)
|
||||||
|
|
||||||
# 最终提示词预览(内嵌、实时;替换样本行的占位符)
|
# 最终提示词预览(加大;内嵌、实时;替换样本行占位符 + 附加输出要求)
|
||||||
prev = QGroupBox("最终提示词预览")
|
prev = QGroupBox("最终提示词预览")
|
||||||
pvw = QVBoxLayout(prev)
|
pvw = QVBoxLayout(prev)
|
||||||
srow = QHBoxLayout()
|
srow = QHBoxLayout()
|
||||||
@@ -231,11 +219,10 @@ class AiOutfitPanel(QWidget):
|
|||||||
pvw.addWidget(self._preview_warn)
|
pvw.addWidget(self._preview_warn)
|
||||||
self._preview_view = QPlainTextEdit()
|
self._preview_view = QPlainTextEdit()
|
||||||
self._preview_view.setReadOnly(True)
|
self._preview_view.setReadOnly(True)
|
||||||
self._preview_view.setMinimumHeight(140)
|
self._preview_view.setMinimumHeight(200)
|
||||||
pvw.addWidget(self._preview_view)
|
pvw.addWidget(self._preview_view)
|
||||||
col.addWidget(prev)
|
col.addWidget(prev, stretch=3)
|
||||||
|
|
||||||
col.addStretch()
|
|
||||||
scroll.setWidget(inner)
|
scroll.setWidget(inner)
|
||||||
return scroll
|
return scroll
|
||||||
|
|
||||||
@@ -270,15 +257,20 @@ class AiOutfitPanel(QWidget):
|
|||||||
grid = QGridLayout()
|
grid = QGridLayout()
|
||||||
grid.setHorizontalSpacing(10)
|
grid.setHorizontalSpacing(10)
|
||||||
grid.setVerticalSpacing(8)
|
grid.setVerticalSpacing(8)
|
||||||
grid.setColumnStretch(0, 1)
|
for c in range(3):
|
||||||
grid.setColumnStretch(1, 1)
|
grid.setColumnStretch(c, 1)
|
||||||
for i, (label, widget) in enumerate(pairs):
|
for i, (label, widget) in enumerate(pairs):
|
||||||
grid.addWidget(self._field(label, widget), i // 2, i % 2)
|
grid.addWidget(self._field(label, widget), i // 3, i % 3)
|
||||||
gv.addLayout(grid)
|
gv.addLayout(grid)
|
||||||
|
|
||||||
|
# AI 模型 下拉(移到生成设置下方)
|
||||||
|
self._model_combo = QComboBox()
|
||||||
|
self._compact_combo(self._model_combo)
|
||||||
|
gv.addWidget(self._field("AI 模型", self._model_combo))
|
||||||
return gen
|
return gen
|
||||||
|
|
||||||
def _field(self, label_text, widget):
|
def _field(self, label_text, widget):
|
||||||
"""A compact label-above-control cell for the 2-column settings grid."""
|
"""A compact label-above-control cell for the settings grid."""
|
||||||
cell = QWidget()
|
cell = QWidget()
|
||||||
v = QVBoxLayout(cell)
|
v = QVBoxLayout(cell)
|
||||||
v.setContentsMargins(0, 0, 0, 0)
|
v.setContentsMargins(0, 0, 0, 0)
|
||||||
@@ -294,8 +286,12 @@ class AiOutfitPanel(QWidget):
|
|||||||
combo.setMinimumContentsLength(6)
|
combo.setMinimumContentsLength(6)
|
||||||
combo.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
|
combo.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)
|
||||||
|
|
||||||
def _path_row(self, line_edit, on_browse):
|
def _inline_path_row(self, label_text, line_edit, on_browse):
|
||||||
|
"""Label + path field + 浏览 button on one row."""
|
||||||
row = QHBoxLayout()
|
row = QHBoxLayout()
|
||||||
|
lbl = QLabel(label_text)
|
||||||
|
lbl.setFixedWidth(40)
|
||||||
|
row.addWidget(lbl)
|
||||||
row.addWidget(line_edit, stretch=1)
|
row.addWidget(line_edit, stretch=1)
|
||||||
btn = QPushButton("浏览…")
|
btn = QPushButton("浏览…")
|
||||||
btn.clicked.connect(on_browse)
|
btn.clicked.connect(on_browse)
|
||||||
@@ -333,7 +329,7 @@ class AiOutfitPanel(QWidget):
|
|||||||
|
|
||||||
def _build_right(self):
|
def _build_right(self):
|
||||||
wrap = QWidget()
|
wrap = QWidget()
|
||||||
wrap.setMinimumWidth(300)
|
wrap.setMinimumWidth(360)
|
||||||
col = QVBoxLayout(wrap)
|
col = QVBoxLayout(wrap)
|
||||||
col.setContentsMargins(12, 12, 12, 12)
|
col.setContentsMargins(12, 12, 12, 12)
|
||||||
col.setSpacing(10)
|
col.setSpacing(10)
|
||||||
|
|||||||
Reference in New Issue
Block a user