Racket GUI:如何引用运行时动态创建的窗口小部件?

罗伯特

这是我第一次使用Racket GUI,必须说我真的很困惑。

我有以下要求:

  1. 一个由几个小部件组成的窗口
  2. 窗口小部件状态必须随用户操作而改变
  3. 可以同时具有这些窗口的多个实例

由于(3),我创建了一个函数create-window该函数使用新的小部件创建一个新窗口。但是正因为如此,我没有全局变量来引用我的小部件。

如何引用运行时动态创建的小部件?

如何以惯用的Racket GUI样式组织GUI代码?

瑞安·库珀珀(Ryan Culpepper)

这取决于引用需要在哪里出现。谁需要与谁交谈?

例如,如果一个窗口小部件在同一框架中具有对另一个窗口小部件的回调,并且如果您要一起创建这两个窗口小部件,则只需命名它们,并使回调闭包引用正确的名称(即变量)即可。这是一个小示例程序:

#lang racket/gui

;; create-hello-window : -> Void
(define (create-hello-window)
  (define f (new frame% (label "Example") (width 600) (height 400)))
  (define t (new text%))
  (define ec (new editor-canvas% (parent f) (editor t)))
  (define b (new button% (parent f) (label "Say hello")
                 (callback (lambda (b ce) (say-hello t)))))
  (send f show #t)
  (void))

;; say-hello : Editor -> Void
(define (say-hello t)
  (send t set-position (send t last-position))
  (send t insert "Hello world!\n"))

;; Create two independent hello windows
(for ([i 2]) (create-hello-window))

请注意,按钮回调引用了局部变量t(编辑器)。

对于更复杂的通信,您需要将引用保存到要引用的对象的某处。这是先前程序的另一个版本,其中将窗口组织成组,每个窗口都有一个按钮,用于向组中的其他窗口写问候语。该组管理窗口及其编辑器的列表。

#lang racket/gui

;; A HelloWin is (hellowin Editor Frame)
(struct hellowin (editor frame))

;; A HelloGroup is (hellogroup String (Listof HelloWin))
(struct hellogroup (name [wins #:mutable]))

;; create-hello-window : HelloGroup -> Void
(define (create-hello-window group)
  (define f
    (new frame% (label (hellogroup-name group)) (width 600) (height 400)))
  (define t (new text%))
  (define ec (new editor-canvas% (parent f) (editor t)))
  (define hi-b
    (new button% (parent f) (label "Say hello")
         (callback (lambda (b ce) (add-to-end t "Hello world!\n")))))
  (define greet-b
    (new button% (parent f) (label "Greet others in group")
         (callback (lambda (b ce) (greet-everyone-else t group)))))
  (send f show #t)
  (set-hellogroup-wins! group (cons (hellowin t f) (hellogroup-wins group))))

;; add-to-end : Editor String -> Void
(define (add-to-end t str)
  (send t set-position (send t last-position))
  (send t insert str))

;; greet-everyone-else : Editor HelloGroup -> Void
(define (greet-everyone-else my-t group)
  (for ([h (in-list (hellogroup-wins group))])
    (define t (hellowin-editor h))
    (unless (equal? t my-t)
      (add-to-end t (format "~a, hello from another window!\n"
                            (hellogroup-name group))))))

;; Create two groups, and create windows for each group.

(define group1 (hellogroup "Group 1" null))
(for ([i 3]) (create-hello-window group1))

(define group2 (hellogroup "Group 2" null))
(for ([i 2]) (create-hello-window group2))

我的代码未使用hellowin-frame,但是您可以使用它编写一个例如关闭一个组中所有窗口的过程。

也许您不希望该组直接访问框架及其小部件。然后,您可以更改协议,以便组包含某种类型的问候语回调,或实现greetable<%>您定义接口的对象(而不是小部件本身),等等。然后,回调(或greetable<%>对象)将具有对小部件的引用(或字段),但不会直接将其公开给组代码。同样,也许组应该是具有注册方法的对象,而不是具有可变字段的结构。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Racket中的运行时模式匹配

来自分类Dev

从 Racket 中的结构创建列表

来自分类Dev

如何使用xrepl启动Racket?

来自分类Dev

如何在Racket中处理GUI退出?

来自分类Dev

如何在Racket的GUI上绘图?

来自分类Dev

GUI:将racket:text%配置为只读

来自分类Dev

在scheme(racket)中创建列表的空列表

来自分类Dev

如何在Racket中将`and`作为函数传递?

来自分类Dev

如何在Racket中使用TCP?

来自分类Dev

如何在Racket中解析JSON?

来自分类Dev

如何在Racket中返回参数值?

来自分类Dev

如何使Typed Racket的类型检查器更快?

来自分类Dev

如何在Racket内编写jQuery代码?

来自分类Dev

如何使Typed Racket的类型检查器更快?

来自分类Dev

如何返回Racket博士列表的顶点?

来自分类Dev

如何不重复 Racket 中的代码

来自分类Dev

是否可以在运行时保存由代码创建的gui /小部件?

来自分类Dev

如何在RACKET中运行否定测试

来自分类Dev

flutter 在运行时创建小部件

来自分类Dev

如何在不引用输出的情况下运行Racket程序?

来自分类Dev

在Racket的GUI库中仅接受数字的文本框

来自分类Dev

Racket终结器在程序退出时运行吗?

来自分类Dev

在 Racket 中创建一个大的随机数

来自分类Dev

如何告诉Racket程序加载可选的配置代码?

来自分类Dev

如何在Racket中获取文件的修改日期?

来自分类Dev

Racket如何定义像Python这样的递归生成器?

来自分类Dev

如何清除Dr. Racket IDE中的解释器屏幕?

来自分类Dev

如何从Racket中的文件中读取一组数据?

来自分类Dev

如何用Racket的“ big-bang”感测多个按键