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