@@ -163,8 +163,99 @@ def _on_setting_changed(self, value, full_key, display_map=None):
163163 reverse_map = {v : k for k , v in display_map .items ()}
164164 final_value = reverse_map .get (value , value ) # Fallback to value itself if not in map
165165
166+ # 特殊处理:当 upscaler 变化时,更新 upscale_ratio 动态下拉框
167+ if full_key == "upscale.upscaler" :
168+ self ._update_upscale_ratio_options (value )
169+
166170 self .setting_changed .emit (full_key , final_value )
167171
172+ def _on_upscale_ratio_changed (self , text , full_key ):
173+ """处理 upscale_ratio 动态下拉框的变化"""
174+ config = self .config_service .get_config ()
175+
176+ if config .upscale .upscaler == "realcugan" :
177+ # 当前是 realcugan
178+ if text == "不使用" :
179+ # 禁用超分
180+ self .setting_changed .emit ("upscale.upscale_ratio" , None )
181+ self .setting_changed .emit ("upscale.realcugan_model" , None )
182+ else :
183+ # text 是模型名称,从中提取倍率
184+ scale_str = text .split ('x' )[0 ] if 'x' in text else None
185+ if scale_str and scale_str .isdigit ():
186+ scale = int (scale_str )
187+ # 同时更新 realcugan_model 和 upscale_ratio
188+ self .setting_changed .emit ("upscale.realcugan_model" , text )
189+ self .setting_changed .emit ("upscale.upscale_ratio" , scale )
190+ else :
191+ # 无法解析倍率,只更新模型
192+ self .setting_changed .emit ("upscale.realcugan_model" , text )
193+ else :
194+ # 当前是其他超分模型,text 是倍率
195+ if text == "不使用" :
196+ self .setting_changed .emit (full_key , None )
197+ else :
198+ try :
199+ ratio = int (text )
200+ self .setting_changed .emit (full_key , ratio )
201+ except ValueError :
202+ self .setting_changed .emit (full_key , None )
203+
204+ def _on_tile_size_input_changed (self , text , full_key ):
205+ """处理 tile_size 输入框的变化"""
206+ if not text or not text .strip ():
207+ # 空值 = 使用默认值 (None)
208+ self .setting_changed .emit (full_key , None )
209+ else :
210+ try :
211+ tile_size = int (text )
212+ self .setting_changed .emit (full_key , tile_size )
213+ except ValueError :
214+ # 无效输入 = 使用默认值
215+ self .setting_changed .emit (full_key , None )
216+
217+ def _update_upscale_ratio_options (self , upscaler ):
218+ """当 upscaler 变化时,更新 upscale_ratio 下拉框的选项"""
219+ # 查找 upscale_ratio_dynamic widget
220+ upscale_ratio_widget = self .findChild (QComboBox , "upscale_ratio_dynamic" )
221+ if not upscale_ratio_widget :
222+ return
223+
224+ # 阻止信号触发
225+ upscale_ratio_widget .blockSignals (True )
226+
227+ # 清空并重新填充
228+ upscale_ratio_widget .clear ()
229+
230+ if upscaler == "realcugan" :
231+ # 显示 Real-CUGAN 模型列表
232+ realcugan_models = self .controller .get_options_for_key ("realcugan_model" )
233+ if realcugan_models :
234+ # 添加"不使用"选项
235+ all_options = ["不使用" ] + realcugan_models
236+ upscale_ratio_widget .addItems (all_options )
237+ # 设置默认值
238+ config = self .config_service .get_config ()
239+ if config .upscale .realcugan_model :
240+ upscale_ratio_widget .setCurrentText (config .upscale .realcugan_model )
241+ elif config .upscale .upscale_ratio is None :
242+ upscale_ratio_widget .setCurrentText ("不使用" )
243+ elif realcugan_models :
244+ upscale_ratio_widget .setCurrentText (realcugan_models [0 ])
245+ else :
246+ # 显示普通倍率选项
247+ ratio_options = ["不使用" , "2" , "3" , "4" ]
248+ upscale_ratio_widget .addItems (ratio_options )
249+ # 设置默认值
250+ config = self .config_service .get_config ()
251+ if config .upscale .upscale_ratio is None :
252+ upscale_ratio_widget .setCurrentText ("不使用" )
253+ else :
254+ upscale_ratio_widget .setCurrentText (str (config .upscale .upscale_ratio ))
255+
256+ # 恢复信号
257+ upscale_ratio_widget .blockSignals (False )
258+
168259 def _create_param_widgets (self , data , parent_layout , prefix = "" ):
169260 if not isinstance (data , dict ):
170261 return
@@ -173,7 +264,8 @@ def _create_param_widgets(self, data, parent_layout, prefix=""):
173264 full_key = f"{ prefix } .{ key } " if prefix else key
174265
175266 # 跳过这些选项,因为已经用下拉框替代或不需要在UI中显示
176- if full_key in ["cli.load_text" , "cli.template" , "cli.generate_and_export" , "cli.colorize_only" ]:
267+ # realcugan_model 将通过 upscale_ratio 动态下拉框处理
268+ if full_key in ["cli.load_text" , "cli.template" , "cli.generate_and_export" , "cli.colorize_only" , "cli.upscale_only" , "upscale.realcugan_model" ]:
177269 continue
178270
179271 label_text = key
@@ -249,24 +341,71 @@ def showPopup(self):
249341 widget .setChecked (value )
250342 widget .stateChanged .connect (lambda state , k = full_key : self ._on_setting_changed (bool (state ), k , None ))
251343
344+ # 特殊处理:upscale_ratio 动态下拉框(必须在 int/float 判断之前)
345+ elif full_key == "upscale.upscale_ratio" :
346+ widget = QComboBox ()
347+ widget .setObjectName ("upscale_ratio_dynamic" )
348+
349+ # 获取当前的 upscaler 值来决定显示什么选项
350+ config = self .config_service .get_config ()
351+ current_upscaler = config .upscale .upscaler
352+
353+ if current_upscaler == "realcugan" :
354+ # 显示 Real-CUGAN 模型列表
355+ realcugan_models = self .controller .get_options_for_key ("realcugan_model" )
356+ if realcugan_models :
357+ # 添加"不使用"选项
358+ all_options = ["不使用" ] + realcugan_models
359+ widget .addItems (all_options )
360+ # 设置当前值(从 realcugan_model 获取)
361+ current_model = config .upscale .realcugan_model
362+ if current_model :
363+ widget .setCurrentText (current_model )
364+ elif value is None :
365+ widget .setCurrentText ("不使用" )
366+ elif realcugan_models :
367+ widget .setCurrentText (realcugan_models [0 ])
368+ else :
369+ # 显示普通倍率选项
370+ ratio_options = ["不使用" , "2" , "3" , "4" ]
371+ widget .addItems (ratio_options )
372+ # 设置当前值
373+ if value is None :
374+ widget .setCurrentText ("不使用" )
375+ else :
376+ widget .setCurrentText (str (value ))
377+
378+ widget .currentTextChanged .connect (lambda text , k = full_key : self ._on_upscale_ratio_changed (text , k ))
379+
380+ # 特殊处理:tile_size 输入框(即使值为 None 也显示)
381+ elif full_key == "upscale.tile_size" :
382+ widget = QLineEdit (str (value ) if value is not None else "" )
383+ widget .setPlaceholderText ("默认: 400" )
384+ widget .editingFinished .connect (lambda k = full_key , w = widget : self ._on_tile_size_input_changed (w .text (), k ))
385+
252386 elif isinstance (value , (int , float )):
253387 widget = QLineEdit (str (value ))
254388 widget .editingFinished .connect (lambda k = full_key , w = widget : self ._on_setting_changed (w .text (), k , None ))
255389
256- elif isinstance (value , str ) and (options or display_map ):
390+ elif ( isinstance (value , str ) or value is None ) and (options or display_map ):
257391 widget = QComboBox ()
258392 if key == "translator" :
259393 widget .setObjectName ("translator.translator" )
260394
261395 if display_map :
262396 widget .addItems (list (display_map .values ()))
263- current_display_name = display_map .get (value )
397+ current_display_name = display_map .get (value ) if value is not None else None
264398 if current_display_name :
265399 widget .setCurrentText (current_display_name )
266400 widget .currentTextChanged .connect (lambda text , k = full_key , dm = display_map : self ._on_setting_changed (text , k , dm ))
267401 else :
268402 widget .addItems (options )
269- widget .setCurrentText (value )
403+ if value is not None :
404+ widget .setCurrentText (value )
405+ else :
406+ # 对于 None 值,设置第一个选项为默认值(通常是 "不使用")
407+ if options :
408+ widget .setCurrentText (options [0 ])
270409 widget .currentTextChanged .connect (lambda text , k = full_key : self ._on_setting_changed (text , k , None ))
271410
272411 elif isinstance (value , str ):
@@ -324,7 +463,8 @@ def _create_left_panel(self) -> QWidget:
324463 "导出翻译" ,
325464 "导出原文" ,
326465 "导入翻译并渲染" ,
327- "仅上色"
466+ "仅上色" ,
467+ "仅超分"
328468 ])
329469 self .workflow_mode_combo .currentIndexChanged .connect (self ._on_workflow_mode_changed )
330470 left_layout .addWidget (self .workflow_mode_combo )
@@ -506,7 +646,9 @@ def _sync_workflow_mode_from_config(self):
506646 # 阻止信号触发,避免循环
507647 self .workflow_mode_combo .blockSignals (True )
508648
509- if config .cli .colorize_only :
649+ if config .cli .upscale_only :
650+ self .workflow_mode_combo .setCurrentIndex (5 ) # 仅超分
651+ elif config .cli .colorize_only :
510652 self .workflow_mode_combo .setCurrentIndex (4 ) # 仅上色
511653 elif config .cli .load_text :
512654 self .workflow_mode_combo .setCurrentIndex (3 ) # 导入翻译并渲染
@@ -529,6 +671,7 @@ def _on_workflow_mode_changed(self, index: int):
529671 # 2: 导出原文
530672 # 3: 导入翻译并渲染
531673 # 4: 仅上色
674+ # 5: 仅超分
532675
533676 config = self .config_service .get_config ()
534677
@@ -537,6 +680,7 @@ def _on_workflow_mode_changed(self, index: int):
537680 config .cli .template = False
538681 config .cli .generate_and_export = False
539682 config .cli .colorize_only = False
683+ config .cli .upscale_only = False
540684
541685 if index == 1 : # 导出翻译
542686 config .cli .generate_and_export = True
@@ -546,6 +690,8 @@ def _on_workflow_mode_changed(self, index: int):
546690 config .cli .load_text = True
547691 elif index == 4 : # 仅上色
548692 config .cli .colorize_only = True
693+ elif index == 5 : # 仅超分
694+ config .cli .upscale_only = True
549695
550696 # ✅ 保存配置到内存和文件
551697 self .config_service .set_config (config )
@@ -561,7 +707,9 @@ def update_start_button_text(self):
561707
562708 try :
563709 config = self .config_service .get_config ()
564- if config .cli .colorize_only :
710+ if config .cli .upscale_only :
711+ self .start_button .setText ("开始超分" )
712+ elif config .cli .colorize_only :
565713 self .start_button .setText ("开始上色" )
566714 elif config .cli .load_text :
567715 self .start_button .setText ("导入翻译并渲染" )
0 commit comments