PySimpleGUI 列表框右键菜单

Posted

技术标签:

【中文标题】PySimpleGUI 列表框右键菜单【英文标题】:PySimpleGUI Listbox right click menu 【发布时间】:2021-05-31 09:31:46 【问题描述】:

我想知道,是否可以让右键菜单在列表框中的选中框上起作用?

右键菜单示例

我已经成功为整个列表框制作了右键菜单

layout = [
        [gui.Listbox(size=(35, 22), key='chat', values=messages,
                     right_click_menu=['&Right', ['Delete', 'Favourite', 'Reply', 'Copy', 'Edit']])],
        [gui.InputText(key='input', size=(25, 10)), gui.Button('Send', bind_return_key=True, size=(9, 1))]
    ]

但这并不是我想要的。我想要:如果我右键单击列表框中的一个框,该框将被选中,并且该菜单的操作将仅影响该框。假设我右键单击中间框并按删除,中间框将被删除。我知道如何处理单击菜单的事件,但到目前为止,我无法确定单击了哪条消息。

【问题讨论】:

更好地创建最小的工作代码,我们可以简单地复制并用于测试解决方案。 【参考方案1】:

这是可能的,但需要 tkinter 代码和破解 PySimleGUI 代码。 这里是按钮 3 的新回调,但选择最近的一个,而不是精确的那个。或许sg.Tablesg.Tree可以实现更好的选择。

import PySimpleGUI as sg

def RightClickMenuCallback(event, element):
    widget = element.Widget
    current = widget.curselection()
    if current:
        widget.selection_clear(current[0])
    index = widget.nearest(event.y)
    widget.selection_set(index)
    element.TKRightClickMenu.tk_popup(event.x_root, event.y_root, 0)
    element.TKRightClickMenu.grab_release()

messages = [
    'This is the start of your chat!',
    'demo messages',
    'dont know what to right',
]

command = ['Delete', 'Favourite', 'Reply', 'Copy', 'Edit']
layout = [
    [sg.Listbox(size=(35, 22), key='chat', values=messages,
        right_click_menu=['&Right', command])],
    [sg.InputText(key='input', size=(25, 10)),
     sg.Button('Send', bind_return_key=True, size=(9, 1))],
]
window = sg.Window("Test", layout, finalize=True)
chat = window['chat']
chat.Widget.bind('<Button-3>', lambda event,
    element=chat: RightClickMenuCallback(event, element))

while True:

    event, values = window.read()
    if event == sg.WIN_CLOSED:
        break
    print(event, values)

window.close()

[编辑]

IMO,最好按照图书馆提供的方式。

import PySimpleGUI as sg

messages = [
    'This is the start of your chat!',
    'demo messages',
    'dont know what to right',
]

command = ['Delete', 'Favourite', 'Reply', 'Copy', 'Edit']
cmd_layout = [[sg.Button(cmd, size=(10, 1))] for cmd in command]
layout = [
    [sg.Listbox(values=messages, size=(35, 22), key='chat'),
     sg.Column(cmd_layout)],
    [sg.InputText(key='input', size=(25, 10)),
     sg.Button('Send', bind_return_key=True, size=(9, 1))],
]
window = sg.Window("Test", layout, finalize=True)
window['input'].expand(expand_x=True)

while True:

    event, values = window.read()
    if event == sg.WIN_CLOSED:
        break
    print(event, values)

window.close()

如果您需要在单击鼠标按钮 1 时生成事件,请将选项 enable_events=True 添加到 sg.Listbox。当任何事件产生时,您可以通过values['chat']window['chat'].get()获取此列表框中当前选择的项目列表,现在只有一个项目被选择,所以消息是values['chat'][0]

如果你需要索引,你必须调用window['chat'].get_indexes(),它返回当前选择的项目作为索引列表。所以,同样的,通过window['chat'].get_indexes()[0]获取所选项目的索引

【讨论】:

您好,谢谢您的帮助。有没有办法同时获取消息本身及其索引?我不太明白函数里面的代码...... 我不明白这会给我用户右键单击的框的索引.... event.y 给出事件、右键单击、生成时鼠标的位置。方法nearest(y) 返回相对于列表框小部件最接近y 坐标y 的可见线的索引。 嘿,再次打扰,很抱歉打扰你,但我仍然无法解决这个问题,因为我对 pysimplegui 很陌生。我想以任何可能的方式获取值,'chat': message and index,但我无法弄清楚函数的调用是如何工作的,所以我不知道该怎么做...... 谢谢@JasonYang!我有一个图像查看器,里面有十几个PySimpleGUI.Image 对象-每个图像都定义了right_click_menu,因此可以使用matplotlib 打开它,我找不到获取生成上下文菜单的图像键的方法。您的示例代码很有帮助。!

以上是关于PySimpleGUI 列表框右键菜单的主要内容,如果未能解决你的问题,请参考以下文章

VBA - 右键单击​​列表框时创建菜单列表

VBA - 右键单击 列表框时创建菜单列表

右键单击列表视图以显示 contextmenustrip,但弹出菜单出现在屏幕的不相关点

为啥我电脑在桌面点击鼠标右键不出菜单

MFC列表右键弹出菜单

怎么管理右键新建菜单