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

使用cl-gtk4无法热重载:主函数阻塞问题求助

解决方案

核心原因是默认调用(test-app)会启动GTK的主循环并阻塞当前线程(即REPL所在线程),导致后续代码无法被求值。要实现热重载,必须让GTK主循环在后台线程运行,保留REPL的交互能力。

方法一:用线程启动主循环

先加载跨平台线程库bordeaux-threads,再将主函数放到后台线程执行:

(ql:quickload '(:cl-gtk4 :bordeaux-threads))

(gtk4:define-application (:name test-app :id "org.testorg.testapp")
  (gtk4:define-main-window (window (gtk4:make-application-window :application gtk4:*application* ))
    (setf (gtk4:window-title window) "Test App"
          (gtk4:window-default-size window) '(800 600))
    (gtk4:window-present window)))

;; 后台启动GTK主循环,不阻塞REPL
(bordeaux-threads:make-thread #'test-app :name "GTK Main Loop")

方法二:禁用自动主循环,手动后台启动

利用define-application的:run-main-loop参数,避免自动阻塞,再手动将主循环放到后台:

(ql:quickload '(:cl-gtk4 :bordeaux-threads))

(gtk4:define-application (:name test-app :id "org.testorg.testapp" :run-main-loop nil)
  (gtk4:define-main-window (window (gtk4:make-application-window :application gtk4:*application* ))
    (setf (gtk4:window-title window) "Test App"
          (gtk4:window-default-size window) '(800 600))
    (gtk4:window-present window)))

;; 启动应用后,后台运行GTK主循环
(test-app)
(bordeaux-threads:make-thread (lambda () (gtk4:main)) :name "GTK Main Loop")

热重载的正确操作

  1. 用上述任一方式启动应用,确保REPL保持可交互状态
  2. 修改代码后,用Slimv的,d重新定义窗口逻辑
  3. 直接修改已存在的窗口对象属性:
    • 先将窗口变量设为全局可访问,比如在定义中加入(defvar *main-window* nil),并在窗口初始化时赋值(setf *main-window* window)
    • 修改标题时直接在REPL执行:(setf (gtk4:window-title *main-window*) "Updated Title")
    • 如果需要重建窗口,可先销毁旧窗口(gtk4:window-destroy *main-window*),再重新执行窗口定义代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:34:50