PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.
https://www.PySimpleGUI.com
Other
13.35k stars 1.84k forks source link

[Enhancement] No enable_events option in sg.OptionMenu #4454

Open jason990420 opened 3 years ago

jason990420 commented 3 years ago

Type of Issue (Enhancement, Error, Bug, Question)

Enhancement


Operating System

WIN10

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

Version information can be obtained by calling sg.main_get_debug_data() Or you can print each version shown in ()

Python version (sg.sys.version)

3.9.5

PySimpleGUI Version (sg.__version__)

4.45.0

GUI Version (tkinter (sg.tclversion_detailed), PySide2, WxPython, Remi)

8.6.9


Your Experience In Months or Years (optional)

2+ Years Python programming experience

10+ Years Programming experience overall

Have used another Python GUI Framework? (tkinter, Qt, etc) (yes/no is fine) yes, tkinter

Anything else you think would be helpful? No


Troubleshooting

These items may solve your problem. Please check those you've done by changing - [ ] to - [X]

Detailed Description

There's no option enable_events for element sg.OptionMenu, so no event generated when content changed. Remove remark at line # 23 to make it work.

Code To Duplicate

import PySimpleGUI as sg

def callback(var, index, mode):
    """
    For OptionMenu
    var - tkinter control variable.
    index - index of var, '' if var is not a list.
    mode - 'w' for 'write' here.
    """
    window.write_event_value("Language", window['Language'].TKStringVar.get())

sg.theme("DarkBlue3")
sg.set_options(font=("Courier New", 16))

data = ["Arabic", "Chinese", "English", "German", "Japanese", "Latin", "Spanish"]

layout = [
    [sg.OptionMenu(data, default_value=data[2], key='Language')],
]

window = sg.Window('Title', layout, finalize=True)
# window['Language'].TKStringVar.trace("w", callback)

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    print(event, values)

window.close()

Screenshot, Sketch, or Drawing

PySimpleGUI commented 3 years ago

Thank you for figuring this one out. I recall there being a tricky problem with generating the callback (finding the right bind) and I see that it's not a bind that's used like in other Widgets.

It's been very very interesting also to see the use of write_event_value recently by code that is not a thread. It had not occurred to me when it was written how useful this function would be for non-threaded problems.

jason990420 commented 3 years ago

Following code for your reference,

import tkinter as tk

def func(select):
    print(f'You select {select.get()}')

root = tk.Tk()
root.wm_title("Message Demo")

items = ('Train', 'Plane', 'Boat')
select = tk.StringVar()
select.set('Selection')
font = ('Courier New', 20, 'bold')

option_menu = tk.OptionMenu(root, select, *items)
option_menu.config(font=font, width=10)
option_menu.pack()

select.trace_add("write", lambda *_, select=select:func(select))

root.mainloop()