Racket/GUI:如何响应list-box%的双击与悬停事件
刚好我之前在Racket GUI里处理过类似的需求,给你分享下靠谱的解决方案:
一、双击List Box项目的实现(不用手动比较时间戳)
你提到不想通过时间戳判断双击,其实不用这么麻烦——mouse-event%本身就提供了get-click-count方法,能直接获取当前的连续点击次数,完全不需要自己维护时间戳。
直接在list-box%的on-event回调里判断:当触发左键抬起事件(button-up? 'left),且点击次数为2时,就执行打开编辑器的逻辑。代码示例如下:
#lang racket/gui (define main-frame (new frame% [label "List Box Double Click"] [width 350] [height 250])) (define my-list-box (new list-box% [parent main-frame] [label #f] [choices '("Project A" "Project B" "Project C")] [on-event (lambda (lb e) ; 检测左键双击 (when (and (send e button-up? 'left) (= (send e get-click-count) 2)) (let ([selected-index (send lb get-selection)]) (when selected-index (let ([item-text (send lb get-string selected-index)]) ; 这里替换成你打开编辑器的逻辑 (message-box "双击触发" (format "正在打开「~a」的编辑器..." item-text))))))] [style '(single vertical-label)])) (send main-frame show #t)
至于你问的keymap%能不能连接到其他控件——理论上可以通过自定义事件转发实现,但keymap%本质是为文本编辑类控件设计的,用来处理双击反而绕了远路,不如上面的方法直接高效。
二、悬停显示Tooltip的实现
Racket GUI没有原生的Tooltip控件,但我们可以自己用message%(或者label%)模拟一个:当鼠标进入List Box的某个项目时,在鼠标附近显示一个临时消息框;当鼠标离开或移动到其他项目时,隐藏这个消息框。
核心是用list-box%的find-item-at-position方法,根据鼠标坐标找到当前指向的项目,然后动态创建/销毁Tooltip。代码示例:
#lang racket/gui (define main-frame (new frame% [label "List Box Tooltip"] [width 350] [height 250])) (define current-tooltip #f) ; 存储当前显示的Tooltip (define my-list-box (new list-box% [parent main-frame] [label #f] [choices '("用户管理模块" "订单处理系统" "数据统计面板")] [on-event (lambda (lb e) (cond ; 鼠标进入控件或移动时检测 [(or (send e enter?) (send e motion?)) (let* ([mouse-pos (send e get-position)] [item-index (send lb find-item-at-position (car mouse-pos) (cdr mouse-pos))]) ; 先销毁之前的Tooltip (when current-tooltip (send current-tooltip show #f) (set! current-tooltip #f)) ; 如果指向有效项目,创建新Tooltip (when item-index (let ([tooltip-text (case item-index [(0) "管理系统所有用户的账号权限"] [(1) "处理订单的创建、支付与发货流程"] [(2) "生成各类业务数据的统计报表"])]) (set! current-tooltip (new message% [parent main-frame] [label tooltip-text] ; 让Tooltip显示在鼠标右下方 [x (+ (send main-frame get-x) (car mouse-pos) 15)] [y (+ (send main-frame get-y) (cdr mouse-pos) 15)])) (send current-tooltip show #t))))] ; 鼠标离开控件时销毁Tooltip [(send e leave?) (when current-tooltip (send current-tooltip show #f) (set! current-tooltip #f))]))] [style '(single vertical-label)])) (send main-frame show #t)
这个方案的好处是轻量灵活,你可以根据需求自定义Tooltip的样式、位置和内容。
内容的提问来源于stack exchange,提问作者Jochen
相关产品推荐
相关产品推荐

