【问题标题】:Making GUI objects in Red language用 Red 语言制作 GUI 对象
【发布时间】:2017-09-16 04:47:04
【问题描述】:

我有以下简单的小面板代码:

view [
    t: text "label"
    f: field
    button "Click here" [t/text: f/text]    ]

但我必须制作 2 个并将它们放在一个窗口上。我想创建单个对象类并从中制作 2 个对象。我看到可以按如下方式创建对象:

obj: object [
    view [
        t: text "label"
        f: field
        button "Click here" [t/text: f/text] ]  ]

view [
    obj
    obj     ]

但我收到以下错误:

*** Script Error: VID - invalid syntax at: [obj obj]
*** Where: do
*** Stack: view layout cause-error 

如何做到这一点?谢谢你的帮助。

编辑:我尝试使用 do,但只能使用 does 进行管理:

  myview: object [
      show: does [view[
        below
        t: text "1st time"
        f: field "Enter value"
        button "Click here" [f/text "clicked"]
        area] ] ]

  myview/show

  print "READY TO SHOW 2nd OBJECT: "
  myview2: copy myview
  myview2/show

【问题讨论】:

  • 您仍在混合方言,这就是它不起作用的原因。 View 只懂 vid 方言。您可以对do方言中的块进行预处理,并将vid方言的块提供给查看
  • 似乎它们是两种不同的语言,联系非常紧密。
  • 它们是同一种语言的两种不同方言。
  • 我在这个问题和上一个问题中都试过了,但我无法用do 生成一个例子(我可以让collectkeep 工作)。您能否为此使用do 提供答案? (另请参阅上面我的问题中的编辑)。

标签: user-interface object rebol red


【解决方案1】:

我想创建单个对象类并从中制作 2 个对象。

Red 中没有对象class 系统,因此在尝试更复杂的 GUI 构造之前,您应该首先尝试掌握基本的 Red 概念。 Red 是一种非常灵活的面向数据的语言,因此您可以利用它来发挥自己的优势,例如,构建参数化的块模板,并将它们组装成正确的 VID 代码块。这是一个例子:

make-row: func [label [string!] but-label [string!]][
    compose [
        t: text (label)
        f: field
        b: button (but-label) [face/extra/1/text: face/extra/2/text]
        do [b/extra: reduce [t f]]
    ]
]

view compose [
    (make-row "label" "Click") return
    (make-row "label2" "Click2")
]

了解人脸树(类似于 HTML DOM,只是简单得多),是掌握 Red 的 GUI 系统的重要部分。由于目前还没有太多文档(您可以从http://docs.red-lang.org开始),欢迎您在red/helpGitter room 提出实时问题。

【讨论】:

  • `do [b/extra: reduce [t f]]​​` 是做什么的?为什么不是face/pane 而不是face/extra
  • /pane facet 用于构建定义哪个小部件包含其他小部件的面部树。您不希望 button 有子小部件,因此在那里使用 /pane 是没有意义的。 /extra 字段是一个免费的 facet,可用于将任何数据附加到 face 对象。在这种情况下,我们要保存对文本和字段面的引用,以便在单击按钮时可以使用它。请重新阅读documentation
【解决方案2】:

要使用 objects 而不是 VID 方言,请将 view 替换为 layout

lay: layout [
    t: text "label"
    f: field
    button "Click here" [t/text: f/text]
]

view lay

然后您可以像检查任何其他对象一样检查它:?? lay

例如,用pane访问lay的内容:

>> ? lay/pane/1

不过,更有用的函数可能是dump-face

>> dump-face lay
 Type: window Style: none Offset: 833x548 Size: 270x45 Text: "Red: untitled"
     Type: text Style: text Offset: 10x10 Size: 80x24 Text: "label"
     Type: field Style: field Offset: 100x10 Size: 80x24 Text: none
     Type: button Style: button Offset: 190x9 Size: 70x25 Text: "Click here"
== make object! [
    type: 'window
    offset: 833x548
 ...

panels 可用于将对象组合在一起:

>> dump-face blay: layout [p: panel button "hi"]
 Type: window Style: none Offset: none Size: 292x220 Text: none
     Type: panel Style: panel Offset: 10x10 Size: 200x200 Text: none
     Type: button Style: button Offset: 220x9 Size: 62x25 Text: "hi"
== make object! [
    type: 'window
    offset: none
    ...

但首先使用带有composeVID 方言可能更容易构建东​​西。

另见this question

【讨论】:

  • view lay 有效,但我想要另一个对象 lay2 copy lay,它也有效,但我想在一个视图中显示它们,view [lay lay2] 抛出错误:` VID - 无效语法:[laylay2 ]`。如何在一个视图中同时显示lay和lay2?
【解决方案3】:

我猜您正在寻找的是样式而不是对象来创建布局。到目前为止,Red 中还没有官方的风格化功能。但是您可以像这样动态创建布局

view repeat i 2 [
    tname: to-word rejoin ['t i]
    fname: to-word rejoin ['f i]
    append v: [] compose/deep [ 
        (to-set-word tname) text "label"
        (to-set-word fname) field
        button "click here"   [
          (to-set-path  compose [(tname) text])  
          (to-path  compose [(fname) text])
        ] 
    ] 
]

您可以将预定义的单词块多次附加到要查看的块中,您将获得重复的元素。

 txt_btn: [
    t: text "label"
    f: field
    button "Click here" [t/text: f/text] 
 ] 
 view append append [] txt_btn txt_btn

当您在块中引用命名元素时,就会出现问题。但是一个词不能指向重复元素中的多个元素,因此在完整的解决方案中使用 compose 以创建唯一的名称。

也许 Red 有一个错误,因为我认为 compose/deep 也会在里面做括号,不需要更多的 compose –

【讨论】:

  • 是的,它正在工作!一些代码解释也会很有帮助。
  • 如果程序想要分别与这些面板/对象进行交互,我该如何访问它们(它们的名称或符号是什么)?
  • 这可能是构建布局的更好方法。之后您可以通过这种方式修改对象。
  • 但显然不再简单是Red语言的主题。
猜你喜欢
  • 1970-01-01
  • 2013-02-18
  • 2013-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 2016-03-08
相关资源
最近更新 更多