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.42k stars 1.83k forks source link

[Question] If I update the color of a button that is the color picker, I get error. #4728

Closed LtqxWYEG closed 3 years ago

LtqxWYEG commented 3 years ago

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

Question, maybe Bug


Operating System

Windows 10 21H2

PySimpleGUI Port (tkinter, Qt, Wx, Web)

idk


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)

PyCharm says 3.10, but I can only find 3.9.something if I execute something and it tells me the version

PySimpleGUI Version (sg.__version__)

idk how to call the debug data. It's pretty new, just a week since I pip-installed it

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

pfff idk, tkinter, I guess?


Your Experience In Months or Years (optional)

.3 Years Python programming experience

~1 Years Programming experience overall

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

Anything else you think would be helpful?


Troubleshooting

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

Detailed Description

I'm always getting this error because the color variable inside the window definition isn't updated, I guess This happens after two changes to the color:

============ Event =  -------Updating color picker button test---------  ==============
#ff0001
============ Event =  particleColor  ==============
#d5eb56
============ Event =  particleColor  ==============
#54edaf
** Error looking up your element using the key:  Particle color picker: #d5eb56 The closest matching key:  Particle color picker: #ff0001
Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\PySimpleGUI\PySimpleGUI.py", line 9091, in find_element
    element = self.AllKeysDict[key]
KeyError: 'Particle color picker: #d5eb56'
.....

I might just be dumb, but pls help :)

Code To Duplicate


import PySimpleGUI as sg

particleColor = "#ff0001"

def make_window(theme):
    global particleColor
    sg.theme(theme)

    layout = [[sg.T('-------Updating color picker button test---------', size = (38, 1), justification = 'center', font = ("Segoe UI", 16), relief = sg.RELIEF_RIDGE, enable_events = True)]]
    layout += [[sg.Input(visible = False, enable_events = True, k = 'particleColor'),

                sg.ColorChooserButton('Particle color picker: %s' % particleColor, button_color = ("#010101", particleColor), size = (25, 2))],

               [sg.T('_______________________________________________________________________________________________________')],
               [sg.Button('Exit', enable_events = True)]]

    return sg.Window('ShitStuckToYourMouse', layout)

def main():
    global particleColor
    oldColor = particleColor
    window = make_window(sg.theme('Dark'))
    sg.set_options(font = "Segoe UI")
    while True:
        event, values = window.read(timeout = 250)
        window['particleColor'].update(particleColor)
        if event not in (sg.TIMEOUT_EVENT, sg.WIN_CLOSED):
            print('============ Event = ', event, ' ==============')
            print(values['particleColor'])
        if event in (None, 'particleColor'):  # Update color and text of the color-picker button
            particleColor = values['particleColor']
            window['Particle color picker: %s' % oldColor].update(('Particle color picker: %s' % particleColor), button_color = ("#010101", particleColor))
            oldColor = values['particleColor']
        if event in (None, 'Exit'):
            break
    window.close()
    exit(0)

if __name__ == '__main__':
    main()

Screenshot, Sketch, or Drawing


Watcha Makin?

I'm currently making a configurations GUI for my stupid ShitStuckToYourMouse program.

jason990420 commented 3 years ago

It looks like there are lot of problems in your code.

Update code as following,

import PySimpleGUI as sg

def make_window(theme, particleColor):

    layout = [
        [sg.T('-------Updating color picker button test---------', size = (38, 1),
            justification = 'center', font = ("Segoe UI", 16),
            relief = sg.RELIEF_RIDGE, enable_events = True)],
        [sg.Input(visible = False, enable_events = True, k = 'particleColor'),
         sg.ColorChooserButton('Particle color picker: %s' % particleColor,
            button_color = ("#010101", particleColor), size = (25, 2),
            key='Particlw color picker')],
        [sg.HorizontalSeparator()],
        [sg.Button('Exit')],
    ]

    return sg.Window('ShitStuckToYourMouse', layout, finalize=True)

def main():

    sg.theme('Dark')
    sg.set_options(font=("Segoe UI", 11))
    particleColor = "#ff0001"

    window = make_window('Dark', particleColor)
    button = window['Particlw color picker']

    while True:

        event, values = window.read()
        if event in (sg.WINDOW_CLOSED, 'Exit'):
            break
        if event != sg.TIMEOUT_EVENT:
            print('============ Event = ', event, ' ==============')
            print(values['particleColor'])
        if event == 'particleColor':
            particleColor = values['particleColor']
            button.update(('Particle color picker: %s' % particleColor), button_color = ("#010101", particleColor))

    window.close()

if __name__ == '__main__':
    main()
LtqxWYEG commented 3 years ago

It looks like there are lot of problems in your code.

* Key of a button defined as the text on button when initialize if  option `key` or `k` not specified. The key of button won't change when text on button changed.

Oooh... The example I found via google didn't have the second key definition. Didn't know that works 🤦‍♂️

* Call `sg.theme` with theme which is string argument, but you passed it by `window = make_window(sg.theme('Dark'))`, should be `window = make_window('Dark')`

Hm. Ok, but it worked. xD

* Option `font` should be `("Segoe UI", 11)`, not `"Segoe UI"`.

Aaah, many issues with that. It should also be set after make_window. I see. Weirdly enough, I thought the font DID change. It looked like the right one. And since the size never did anything, I just left it out. xD This should throw an error, imo.

* Call `sg.theme` and `sg.set_options` before your layout or window finalized.

idk what finalizing does. As you see I never used it. Afaik both were called before ever reaching sg.Window anyway If that's important then it should also throw an error.

* 'Close' button of window will destroy window, so should check if window to close or closed before you print values of window or update element of window.

Oh, ok. Makes sense, but not really an issue, if I understand correctly :)

* maybe something else.

I'm certain ^^


So the actual issue was that the color-picker button needed a static key. Makes sense 🤦‍♂️xD Can you make it throw an exception if variables are ever used to construct a key? Are there legitimate reasons to use a variable? Or maybe an error if key = text and text has changed. Anyway, that was very confusing

button = window['Particle color picker'] (-and so forth) is optional, right?

Thank you very much. Now it works fine!

jason990420 commented 3 years ago

Keys Keys are a super important concept to understand in PySimpleGUI.

If you are going to do anything beyond the basic stuff with your GUI, then you need to understand keys.

You can think of a "key" as a "name" for an element. Or an "identifier". It's a way for you to identify and talk about an element with the PySimpleGUI library. It's the exact same kind of key as a dictionary key. They must be unique to a window.

Key is defined by scalar or variable for one element, bascially, it cannot be changed after that.

button = window['Particle color picker']         # or you can use window['Particle color picker']  next time

It is used to make window['Particle color picker'] statement clear, short like as button, or quicker if you use it again and again.

LtqxWYEG commented 3 years ago

Key is defined by scalar or variable for one element, bascially, it cannot be changed after that.

Then constructing it from a variable should not be allowed and cause an exception/error

This should throw an error, imo.

Can we please make this into an enhancement issue?

jason990420 commented 3 years ago

Then constructing it from a variable should not be allowed and cause an exception/error

It's not true, construct it from a variable is allowed because it just get the value from variable, and no error here. If nothing wrong, key must be of a type that is immutable, so you can use an integer, float, string, Boolean, tuple or object as a key.

For example

keys = {'button':'Button', 'text':'Label'}

layout = [
    [sg.Text("Hello World", key=keys['text'])],
    [sg.Button("Exit", key=keys['button'])],
]

or

layout = [[sg.Text(f'Text {i}', key=i)] for i in range(5)]
LtqxWYEG commented 3 years ago

Hm... so there is no way to tell the user (me) that he's an idiot?

jason990420 commented 3 years ago

IMO, it is not impossible, but unnecessary.

PySimpleGUI commented 3 years ago

Wow.... What a beautiful thing to see

image

I have so enjoyed the PySimpleGUI users and how you guys treat Jason so well. And of course I'm constantly blown away by how good Jason is in so many dimensions.

PySimpleGUI commented 3 years ago

https://github.com/LtqxWYEG/ShitStuckToYourMouse

image

We've got a winner here of the best named PySimpleGUI-related repo of the month!

LtqxWYEG commented 3 years ago

ShitStuckToYourMouse We've got a winner here of the best named PySimpleGUI-related repo of the month!

hahaha xD

Edit: It's now PoopStuckToYourMouse (Less vulgar) Do I still win? 🙈