diff --git a/gui.py b/gui.py index 535cc4a..2994bb1 100644 --- a/gui.py +++ b/gui.py @@ -113,15 +113,23 @@ def index(): if refs['plot_container']: refs['plot_container'].clear() with refs['plot_container']: + # 使用 ui.pyplot 上下文自动管理 figure 生命周期 with ui.pyplot(figsize=(10, 8)) as plot: title = f"{result['name']}\nCost: ¥{result['cost']/10000:.2f}万 | Loss: {result['loss']:.2f} kW" - # 获取当前 ui.pyplot 创建的 axes + # 显式获取当前 ui.pyplot 创建的 axes,并传递给绘图函数 + # 确保绘图发生在正确的 figure 上 ax = plt.gca() visualize_design(result['turbines'], state['substation'], result['eval']['details'], title, ax=ax) def handle_row_click(e): - if not e.args or 'data' not in e.args: return - row_name = e.args['data']['name'] + # ui.table row-click args: [evt, row, index] + row = None + if e.args and isinstance(e.args, list) and len(e.args) > 1: + row = e.args[1] + + if not row or 'name' not in row: return + + row_name = row['name'] selected_res = next((r for r in state['results'] if r['name'] == row_name), None) if selected_res: update_plot(selected_res) @@ -161,18 +169,24 @@ def index(): # 2. 定义在线程中运行的任务 def task(): # 捕获 stdout 到我们的 QueueLogger + # 禁止 main.py 中的后台绘图,避免线程安全问题 with contextlib.redirect_stdout(QueueLogger()): return compare_design_methods( excel_path=state['excel_path'], n_clusters_override=n_clusters, interactive=False, - plot_results=False # 禁止后台绘图,避免线程安全问题 + plot_results=False ) + + # 在后台线程运行计算任务 results = await run.io_bound(task) + state['results'] = results if not state['excel_path'] and results: if state['substation'] is None: _, state['substation'] = generate_wind_farm_data(n_turbines=30, layout='grid', spacing=800) + + # 更新结果表格 if refs['results_table']: table_data = [] for res in results: @@ -180,7 +194,7 @@ def index(): refs['results_table'].rows = table_data refs['results_table'].update() - # 计算完成后,自动寻找并显示最佳方案的拓扑图 (不再显示4合1大图) + # 计算完成后,自动寻找并显示最佳方案的拓扑图 if results: best_res = min(results, key=lambda x: x['cost']) update_plot(best_res) @@ -190,6 +204,8 @@ def index(): if refs['status_label']: refs['status_label'].text = "计算完成!" except Exception as ex: ui.notify(f'运行出错: {ex}', type='negative') + import traceback + traceback.print_exc() finally: log_timer.cancel() process_log_queue() @@ -227,7 +243,7 @@ def index(): ] # 移除 selection='single',改为纯行点击交互 refs['results_table'] = ui.table(columns=columns, rows=[]).classes('w-full') - refs['results_table'].on('rowClick', handle_row_click) + refs['results_table'].on('row-click', handle_row_click) with ui.card().classes('w-full p-4 shadow-md'): ui.label('拓扑可视化').classes('text-xl font-semibold mb-2') refs['plot_container'] = ui.column().classes('w-full items-center') @@ -235,4 +251,4 @@ def index(): ui.label('导出与下载').classes('text-xl font-semibold mb-2') refs['export_row'] = ui.row().classes('gap-4') -ui.run(title='海上风电场集电线路优化', port=8080) +ui.run(title='海上风电场集电线路优化', port=8080) \ No newline at end of file