I am wondering, is it possible to make the right click menu work on the selected box in the list box?
Example of a right click menu
I have succeeded in making a right click menu for the entire list box by doing
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))]
]
but its not quite what I am looking for. I want: if I right click on a box in the list box, said box will be selected and the actions of that menu will affect only that box. Lets say I right click on the middle box and press delete, the middle box will be deleted. I know how to work with the event of clicking the menu, but as of right now I have no way of actually telling which message was clicked.
It's possible, but need tkinter code and hack PySimleGUI code. Here new callback for Button 3, but selection for nearest one, not exact the one. Maybe sg.Table
or sg.Tree
can achieve better selection.
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()
[Edit]
IMO, follow the way provided by library should be preferred.
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()
Add option enable_events=True
to sg.Listbox
if you need event generated when mouse button 1 clicked. When any event generated, you can get the list of items currently selected in this listbox by values['chat']
or window['chat'].get()
, now there's only one item selected, so message is values['chat'][0]
.
If you need index, you have to call window['chat'].get_indexes()
, it returns the items currently selected as a list of indexes. So, the same, get index of selected item by window['chat'].get_indexes()[0]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.