You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:10:35