【问题标题】:GUI elements from a function not being displayed in Red language功能中的 GUI 元素未以红色语言显示
【发布时间】:2017-09-17 08:03:26
【问题描述】:

我正在使用以下代码尝试从函数中获取 GUI 元素:

  mypanelfn: func[] [
    collect[
      repeat i 10 [ 
        print append copy "i in loop: " i
        keep [t: text]  keep append copy "message: " i
        keep [field "entry"    
              button "Click" [t/text: "clicked"] return]]]]

  view [ 
    do [mypanelfn]]

没有错误信息,循环继续,还显示一个窗口。但这只是一个没有任何文本、字段或按钮的小空窗口。

这段代码有什么问题?

编辑:将probe 放在collect 显示之前(为了清楚起见,我添加了换行符):

[t: text "message: 1" field "entry" button "Click" [t/text: "clicked"] return 
t: text "message: 2" field "entry" button "Click" [t/text: "clicked"] return 
t: text "message: 3" field "entry" button "Click" [t/text: "clicked"] return 
t: text "message: 4" field "entry" button "Click" [t/text: "clicked"] return 
t: text "message: 5" field "entry" button "Click" [t/text: "clicked"] return

【问题讨论】:

  • 实际上,view mypanelfn 完美运行。正在显示所有 GUI 元素。但是单击任何按钮只会更改最后一个文本标签,而不是相应的文本标签。如何纠正?
  • 使用self/text
  • 哪个text 条目?我无法在任何地方成功添加self
  • 顺便说一句,stackoverflow.com/a/46253902/5798459 解决了这个问题
  • github.com/red/red/blob/master/tests/view-test.red 有更好的动态构造视图对象的例子

标签: function user-interface rebol red


【解决方案1】:

此方法不需要设置任何变量——它通过在一个共同的父对象中包含每个迭代的面来工作 (panel):

view collect [
    keep [below space 0x0]
    repeat i 10 [
        keep compose/deep [
            panel [
                origin 0x0
                text (rejoin ["Message Number: " i])
                field "entry"
                button "Click" [face/parent/pane/1/text: "clicked"]
            ]
        ]
    ]
]

face/parentpanel 面,其第一个孩子 (pane/1) 是文本框(origin 不会创建面)。

【讨论】:

  • @rnso 我的代码段遵循 Rebol/Red 编码风格指南——修改前请参考。
【解决方案2】:

但是,您不一定需要那里的功能:

view mypanelfn

工作。

注意:Rebol 中的等效代码需要layoutview layout mypanelfn

发生这种情况的原因是view 处理blocks![] 中的任何内容)。所以你不必do它。

一般来说,最好将 Red 视为一种函数式的消息传递语言。与具有过程和语句的命令式语言相比,一切都是表达式。

【讨论】:

    【解决方案3】:

    再一次;您需要为要处理的元素提供唯一名称。这里使用reduce而不是compose的解决方案

    mypanelfn: func[] [
      collect[
        repeat i 10 [ 
          tname: to-word rejoin ['t i]
          print append copy "i in loop: " i
          keep  reduce [to-set-word tname 'text]  keep append copy "message: " i
          keep reduce [
           'field "entry" 'button "Click"  reduce  [ 
              to-set-path  reduce [
                 tname 'text ]
                "clicked" ]
          'return ] ] ] ] 
    

    我建议您使用控制台中的命令来查看它们的作用。例如。

    rejoin ['t i] 创建一个字符串"t1",其中包含 t 和 i 的 (reduced/get-) 值。

    to-word 将其更改为红色(bol)字 t1

    to-setword tname 创建一个集合词t1:

    to-set-path reduce [tname 'text ]创建一个设置路径t1/text:

    【讨论】:

    • 是的,效果很好。文本元素被标记为t1, t2 等,单击按钮仅影响相应的文本元素。如果你能解释这个标签是如何工作的,例如to-word, rejoin, to-set-word, to-set-path 等的使用,将会很有用。
    • to-set-path 是干什么用的?
    【解决方案4】:

    这在 rebol/view 中对我有用:

    lay: mypanelfn
    insert head lay 'across
    view layout lay
    

    我认为,在您学习这些内容时,您需要先查看生成的 VID 代码以检查是否没有问题,然后再尝试查看。

    【讨论】:

    • 从函数返回的输出似乎没问题(请参阅上面我的问题中的编辑)。那为什么我的代码在 Red 中不起作用?
    • 您的代码在 Red 中不适合我。错误是:*** Script Error: lay has no value; *** Where: head; *** Stack: mypanelfn (我添加了分号而不是换行符)。
    猜你喜欢
    • 1970-01-01
    • 2018-12-03
    • 2019-10-03
    • 2011-11-30
    • 2018-04-15
    • 2011-09-01
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多