为什么我的沙盒球拍GUI应用不响应事件?
我有一个非常简单的球拍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)
这是按预期工作的 - 如果我直接运行,则产生一个对事件做出响应的按钮。但是,如果我在沙箱中运行它作为另一个球拍GUI应用程序的一部分:
(define/public (set-content content)
(parameterize ([sandbox-gui-available #t])
(let ((evaluator (make-evaluator 'racket/gui)))
(evaluator content))))
...其中content
是上面的球拍源,则在set-content
时显示帧。称为:
...但没有响应诸如点击之类的事件。
我怀疑我在这里缺少一些明显的东西,但文档建议新的GUI应该获得自己的活动空间,所以这感觉就像是应该工作。
I have a very simple 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)
This works as expected - producing a button which responds to events - if I run it directly. However, if I run it in a sandbox as part of another Racket GUI application:
(define/public (set-content content)
(parameterize ([sandbox-gui-available #t])
(let ((evaluator (make-evaluator 'racket/gui)))
(evaluator content))))
... where content
is the Racket source above, then the frame displays when set-content
is called:
... but doesn't respond to events like clicks.
I suspect I'm missing something obvious here but the docs suggest the new GUI should get its own eventspace, so this feels like it should work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这是沙盒GUI支持中的错误。启用GUI模式后,它会创建事件空间并在该事件空间的处理程序线程中运行评估循环。但是,评估循环块在频道上等待进行评估,因此它阻止了事件空间处理实际的GUI事件。
解决方法是在做在做任何涉及当前事件空间的其他操作之前,例如创建帧。
I think this is a bug in the sandbox's GUI support. When GUI mode is enabled, it creates an eventspace and runs the evaluation loop in that eventspace's handler thread. But the evaluation loop blocks on a channel waiting for things to evaluate, so it blocks the eventspace from handling actual GUI events.
A workaround is to run
(current-eventspace (make-eventspace))
in the evaluator before doing anything else that involves the current eventspace, like creating a frame.