You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ScalaFX应用中如何在Python脚本运行时显示加载窗口?

问题根源分析

  1. 第一次尝试的问题:roomFindCommand.!会阻塞ScalaFX依赖的JavaFX GUI主线程,导致loadingWindow.show()的界面渲染任务被积压,直到脚本执行完毕才会被处理;之后立刻执行close(),窗口根本来不及完成渲染就被关闭,表现为程序冻结后窗口闪现即消失。
  2. 第二次尝试的问题:你启动后台线程后立即通过Platform.runLater调用close(),此时脚本还在运行,且该逻辑没有等待脚本执行完成;同时直接在后台线程外触发关闭,不符合“脚本运行时显示窗口、运行完关闭”的需求逻辑。

正确实现方案

核心原则:后台线程执行Python脚本,脚本执行完成后回到GUI线程关闭加载窗口,所有UI操作必须在GUI线程(JavaFX Application Thread)中执行。

修改后的点击事件处理代码:

onMouseClicked = event => {
  val x = event.getX()
  val y = event.getY()
  val roomFindCommand = Seq("python3", scriptLocation, fileName, x.toString(), y.toString())

  // 先在GUI线程显示加载窗口
  loadingWindow.show()
  // 可选:设置窗口为模态,阻止用户操作主界面
  loadingWindow.initModality(Modality.APPLICATION_MODAL)

  // 启动后台线程执行脚本
  val modelThread = new Thread(() => {
    try {
      // 在后台线程执行Python脚本,阻塞当前线程直到脚本完成
      roomFindCommand.!
      // 可选:读取脚本生成的文本文件,这里的IO操作放在后台线程
      // val result = Files.readString(Paths.get("output.txt"))
    } finally {
      // 脚本执行完成(成功/失败都执行),回到GUI线程关闭窗口
      Platform.runLater(() => {
        loadingWindow.close()
        // 可选:如果需要更新主界面展示结果,也在这里执行
        // controller.updateResult(result)
      })
    }
  })
  modelThread.start()
}

额外注意事项

  • loadingWindow的创建、初始化必须在GUI线程完成,禁止在后台线程操作任何UI组件。
  • 如果需要处理脚本执行结果(如读取生成的文本文件),IO操作放在后台线程,结果的UI更新逻辑必须包裹在Platform.runLater中。
  • 若脚本执行可能抛出异常,建议在try块中添加异常捕获,在finally中仍保证窗口关闭,避免加载窗口一直停留。

内容的提问来源于stack exchange,提问作者SendHelpPlease

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:30:32