【问题标题】:Returning information from buttons in clojure/seesaw从 clojure/seesaw 中的按钮返回信息
【发布时间】:2016-02-24 21:17:44
【问题描述】:

我还有另一个 clojure 问题。

所以我目前正在开发一个项目并尝试为它编写一个 GUI 组件。我的所有功能部件都在工作,所以现在我只是想让它看起来也不错,并进一步了解跷跷板的工作原理。

基本上,我有一堆输入字段(即文本字段、滑块、组合框),用户可以使用它们来输入某些类型的数据。当用户单击“确认”按钮时,我希望按钮的操作返回上述输入字段的所有值。我对线程没有太多经验,但我知道(显然)可能存在一些并发问题。我怎样才能做到这一点?

作为参考,这是我的代码的一个小示例:

    ;
    ;in restaurant-gui.core
    ;

    (defn window-setup []
      (let [my-font        (font :name "Arial"
                                 :size 22)

           cuisine-label   (label    :text "Cuisine: "
                                     :font my-font
                                     :border [20 10])

           cuisine         (combobox :model["Any cuisine"
                                            "American"
                                            "Barbecue"
                                            "Chinese"
                                            "French"
                                            "Italian"])

           confirm-button  (button   :text "Confirm"
                                     :listen [:action (fn [event] event 
                           (selection cuisine))])

           window-contents (vertical-panel :items [cuisine-label cuisine 
                            confirm-button])]
           window-contents))

    ;     
    ;in restaurant-inference-engine.core
    ;

    (defn -main
      [&args]

      (binding [window-contents (window-setup)]
        (draw-window window-contents)     ;somehow listen here for
                                          ;information from the button
                                          ;and bind it to button-info?...

        (search-for-restaurant button-info)))

另外,如果有人知道任何简单到中间的 clojure 代码,我可以看看,我将不胜感激。我想更多地接触编写良好的 clojure 代码,以提高我对语言的理解。

【问题讨论】:

    标签: multithreading button clojure seesaw


    【解决方案1】:

    在使用像 GUI 这样具有固有状态的东西时,求助于 Clojure 的可变状态功能通常会很有帮助。我见过两种基本方法:

    • 将每个 UI 元素的状态存储在 ref 中,然后将相关的 ref 传递给需要处理 UI 状态的函数。
    • 将 GUI 的状态存储在一个 atom 中,并将该原子传递给使用任何 UI 组件的每个函数,以便它们始终可以随时使用 UI 的当前状态。请注意以一致的方式对其进行更新。
    • 使用 core.async 让 ui 事件向需要它们的组件发送消息。尽管您必须完成设置通道的工作,但在我看来,这允许非常灵敏的 UI 和干净的代码。

    其中任何一个似乎都不太可能适用于所有甚至大多数项目,因此它对您的特定项目的外观有一些影响。如果您坚持使用官方 Clojure 方法来处理不断变化的状态(atoms.vars、refs、agents、chans),您可能不需要担心“并发”问题

    【讨论】:

    • 所以,我的项目设置“restaurant-inference-engine.core”(包含我所有的功能材料)可以访问“restaurant-gui.core”(只有我的 gui组件),但反之则不然。因此,我无法调用“restaurant-inference-engine.core”中的函数,因此无法将相关的引用传递给它们。如何确保我在 -main 中的 search-for-restaurant 调用等到用户按下“确定”按钮后再尝试访问相关数据?
    • 我建议以atom 开头。这是最简单的方法。随着程序变得越来越复杂,ref 和使用事件之间的决定应该变得更加清晰。如果我没记错所有动作事件都在同一个事件中运行,那么即使没有并发引用类型,并发也不应该成为问题。一如既往的出色回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 2014-05-30
    相关资源
    最近更新 更多