我正在研究使用Racket进行GUI开发。我想创建一个tab-panel%
,其中包含多个标签。文档说,tab的切换只调用一个过程而不会自动进行内容更改。我认为这是非常聪明的行为,但我在实现一个最初为空的选项卡面板时遇到问题,当我选择其中一个选项卡时,它只获取内容(子项)。
这是我已有的代码:
#lang racket/gui
(require racket/gui/base)
(define nil '())
(define application-frame
(new frame%
[label "Example"]
[width 400]
[height 300]))
(define menu-bar
(new menu-bar%
[parent application-frame]))
(define file-menu
(new menu%
[label "&File"]
[parent menu-bar]))
(new menu%
[label "&Edit"]
[parent menu-bar])
(new menu%
[label "&Help"]
[parent menu-bar])
(new menu-item%
[label "E&xit"]
[parent file-menu]
[callback
(λ (m event)
(exit nil))])
(define tab-panel
(new tab-panel%
[parent application-frame]
[choices '("&Lookup" "&Training")]
[callback
(λ (tp event)
(case (send tp get-item-label (send tp get-selection))
[("&Lookup")
(send tp change-children
(λ (children)
(list lookup-panel)))]
[("&Training")
(send tp change-children
(λ (children)
(list training-panel)))]))]))
(define get-lookup-panel
(lambda (children)
(let
[(lookup-panel (new panel% [parent tab-panel]))]
[(new message%
[parent lookup-panel]
[label "The content of the lookup panel for the lookup tab."])
lookup-panel])))
(define lookup-panel (new panel% [parent tab-panel]))
(define lookup-panel-content
(new message%
[parent lookup-panel]
[label "The content of the lookup panel for the lookup tab."]))
(define training-panel (new panel% [parent tab-panel]))
(define training-panel-content
(new message%
[parent training-panel]
[label "The content of the training panel for the training tab."]))
(define status-message
(new message%
[parent application-frame]
[label "No events so far..."]
[auto-resize #t]))
(send application-frame show #t)
这里的问题是,最初tab-panel
的两个孩子都是可见的,虽然(当然)只选择了一个选项卡。当我更改制表符时,行为会由case
表单中的lambdas更正。
但是,我不能简单地给那些我设置为子{no} panel
的{{1}},因为球拍会告诉我,我需要指定所需的初始参数parent
。这意味着它们最初将添加到parent
。是否有必要创建tab-panel
然后再将其从panel
中删除?那看起来有点脏。我认为可能有更好的方法。
我已经尝试动态创建面板,如tab-panel
过程中所示,但我无法以get-lookup-panel
形式工作。
实施它的正确方法是什么?
我找到了一种定义过程的方法,可以按照我想要的方式使用它:
case
可以使用如下:
(define (get-lookup-panel4 children)
(define lookup-panel (new panel% [parent tab-panel]))
(define lookup-panel-message (new message% [parent lookup-panel] [label "LOOKUP"]))
(list lookup-panel))
但是我不明白这个程序与(define tab-panel
(new tab-panel%
[parent application-frame]
[choices '("&Lookup" "&Training")]
[callback
(λ (tp event)
(case (send tp get-item-label (send tp get-selection))
[("&Lookup")
(send tp change-children get-lookup-panel4)]
[("&Training")
(send tp change-children
(λ (children)
(list training-panel)))]))]))
表达式的另一个程序之间的区别是什么,这个方法的另一个问题是,我之后无法修改创建的let
或{ {1}},因为它们的范围是程序。