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

如何实现Listbox项拖拽至Workspace?PySimpleGUI拖拽故障排查

问题描述

我希望实现将Listbox中的内容以块形式拖拽到Workspace中,类似Scratch的操作逻辑。我给PySimpleGUI的Listbox添加了draggable=True参数,但Listbox内的项仍无法被拖拽。相关代码如下:

import PySimpleGUI as sg
from PIL import ImageGrab

# 创建要显示的代码列表
code_lines = [
    "variable",
    "loops",
    "types of variables"
]

# 创建窗口布局
layout = [  [sg.Column([[sg.Listbox(values=code_lines, size=(20, 10), key='Python Code', draggable = True)]]),
             sg.Column([[sg.Text('Workspace:', size=(20, 1)), sg.Multiline(size=(50, 30), key='workspace', background_color='dark gray')]])],
            [sg.Button('Close')] ]

# 创建窗口
window = sg.Window('PyDrop', layout)

# 事件循环处理事件
while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED or event == 'Close':  # 用户关闭窗口或点击关闭按钮
        break
    elif event == 'Python Code':  # 用户点击Listbox中的项
        # 存储点击项的值
        dragged_item = values['Python Code'][0]
    elif event == sg.DRAG:  # 用户按住按钮移动鼠标
        # 更新目标区域的值
        print('Drag event triggered')
        window['drop_target'].update(dragged_item)

# 关闭窗口
window.close()
解决方案

PySimpleGUI中Listbox的draggable参数作用是让整个Listbox控件可拖拽,而非内部的单个列表项。要实现列表项拖拽到Workspace的效果,需要手动绑定鼠标事件来处理:

  1. 记录鼠标左键按下时选中的列表项
  2. 监听鼠标释放事件,判断释放位置是否处于Workspace区域内
  3. 若位置符合,则将选中项添加到Workspace中

修改后的代码如下:

import PySimpleGUI as sg

code_lines = [
    "variable",
    "loops",
    "types of variables"
]

# 定义窗口布局
layout = [
    [
        sg.Column([[sg.Listbox(values=code_lines, size=(20, 10), key='Python Code', enable_events=True)]]),
        sg.Column([[sg.Text('Workspace:'), sg.Multiline(size=(50, 30), key='workspace', background_color='dark gray')]], key='WorkspaceCol')
    ],
    [sg.Button('Close')]
]

window = sg.Window('PyDrop', layout, finalize=True)

# 获取Workspace列的位置和尺寸,用于判断拖拽释放位置
workspace_col = window['WorkspaceCol']
workspace_rect = workspace_col.get_bbox()
dragged_item = None

while True:
    event, values = window.read(timeout=10)
    if event == sg.WIN_CLOSED or event == 'Close':
        break
    # 鼠标左键按下Listbox项时,记录选中内容
    elif event == 'Python Code' and window.mouse_buttons_pressed == (True, False, False):
        if values['Python Code']:
            dragged_item = values['Python Code'][0]
    # 鼠标释放时,判断是否在Workspace区域内
    elif event == sg.EVENT_MOUSE_UP:
        if dragged_item:
            mouse_x, mouse_y = window.mouse_location()
            # 检查鼠标位置是否处于Workspace列的范围内
            if (workspace_rect[0] <= mouse_x <= workspace_rect[2] and
                workspace_rect[1] <= mouse_y <= workspace_rect[3]):
                # 将拖拽项追加到Workspace中
                current_content = values['workspace']
                window['workspace'].update(current_content + dragged_item + '\n')
            dragged_item = None

window.close()

关键说明

  • 给Listbox添加enable_events=True,确保能触发点击事件
  • 通过window.mouse_buttons_pressed判断鼠标左键按下状态,记录选中的列表项
  • 监听sg.EVENT_MOUSE_UP事件,结合window.mouse_location()和Workspace的位置范围,判断拖拽是否完成
  • 若拖拽到目标区域,将选中项追加到Multiline控件中,模拟Scratch的块添加逻辑

内容的提问来源于stack exchange,提问作者Cole Davidson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:40:26