为什么我的沙盒 Racket GUI 应用程序没有响应事件?
Why is my sandboxed Racket GUI app not responding to events?
我有一个非常简单的 Racket GUI:
(define frame (new frame% [label "Goodbye, World!"]))
(define msg (new message% [parent frame]
[label "No events so far..."]))
(new button% [parent frame]
[label "Click Me"]
(callback (lambda (button event)
(send msg set-label "Button click"))))
(send frame show #t)
这按预期工作 - 生成一个响应事件的按钮 - 如果我直接 运行 它。但是,如果我 运行 它作为另一个 Racket GUI 应用程序的一部分在沙箱中:
(define/public (set-content content)
(parameterize ([sandbox-gui-available #t])
(let ((evaluator (make-evaluator 'racket/gui)))
(evaluator content))))
... 其中content
是上面的Racket源,那么在调用set-content
时显示的框架:
...但不响应点击等事件。
我怀疑我在这里遗漏了一些明显的东西,但文档建议新的 GUI 应该有自己的事件空间,所以感觉 应该 工作。
我认为这是沙盒的 GUI 支持中的错误。启用 GUI 模式后,它会创建一个事件空间,并 运行 在该事件空间的处理程序线程中执行评估循环。但是评估循环阻塞在通道上等待评估,因此它阻止事件空间处理实际的 GUI 事件。
解决方法是在执行任何涉及当前事件空间的其他操作(例如创建框架)之前,先在求值器中 运行 (current-eventspace (make-eventspace))
。
我有一个非常简单的 Racket GUI:
(define frame (new frame% [label "Goodbye, World!"]))
(define msg (new message% [parent frame]
[label "No events so far..."]))
(new button% [parent frame]
[label "Click Me"]
(callback (lambda (button event)
(send msg set-label "Button click"))))
(send frame show #t)
这按预期工作 - 生成一个响应事件的按钮 - 如果我直接 运行 它。但是,如果我 运行 它作为另一个 Racket GUI 应用程序的一部分在沙箱中:
(define/public (set-content content)
(parameterize ([sandbox-gui-available #t])
(let ((evaluator (make-evaluator 'racket/gui)))
(evaluator content))))
... 其中content
是上面的Racket源,那么在调用set-content
时显示的框架:
...但不响应点击等事件。
我怀疑我在这里遗漏了一些明显的东西,但文档建议新的 GUI 应该有自己的事件空间,所以感觉 应该 工作。
我认为这是沙盒的 GUI 支持中的错误。启用 GUI 模式后,它会创建一个事件空间,并 运行 在该事件空间的处理程序线程中执行评估循环。但是评估循环阻塞在通道上等待评估,因此它阻止事件空间处理实际的 GUI 事件。
解决方法是在执行任何涉及当前事件空间的其他操作(例如创建框架)之前,先在求值器中 运行 (current-eventspace (make-eventspace))
。