fix: 修复GUI界面图表显示和事件处理问题
This commit is contained in:
28
gui.py
28
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')
|
||||
|
||||
Reference in New Issue
Block a user