PySimpleGUI icon indicating copy to clipboard operation
PySimpleGUI copied to clipboard

[Question] How to update class parameter within inherited class

Open Whitelegs opened this issue 1 year ago • 4 comments

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

Question


Environment

Operating System

Linux version ('glibc', '2.35')

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

Python version (sg.sys.version)

3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]

PySimpleGUI Version (sg.__version__)

5.0.3

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

8.6.12


Your Experience In Months or Years (optional)

0 Years Python programming experience 30 Years Programming experience overall Yes Have used another Python GUI Framework? (tkinter, Qt, etc) (yes/no is fine)


Troubleshooting

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

  • [X] Searched main docs for your problem www.PySimpleGUI.org
  • [X] Looked for Demo Programs that are similar to your goal. It is recommend you use the Demo Browser! Demos.PySimpleGUI.org
  • [X] If not tkinter - looked for Demo Programs for specific port
  • [ ] For non tkinter - Looked at readme for your specific port if not PySimpleGUI (Qt, WX, Remi)
  • [ ] Run your program outside of your debugger (from a command line)
  • [ ] Searched through Issues (open and closed) to see if already reported Issues.PySimpleGUI.org
  • [ ] Upgraded to the latest official release of PySimpleGUI on PyPI
  • [ ] Tried using the PySimpleGUI.py file on GitHub. Your problem may have already been fixed but not released

Detailed Description

This may be more a Python thing I'm missing but I have created a class, inherited from sg.Button. I set various parameters within the class (image_data, text etc.) & then want to update the image from within a method. My program code calls the method correctly
window['Cancel'].hover() and if I use window['Cancel'].update(image_data=red_hovered) from within the program it works correctly, however I cannot get the method to compile when I try it within the class. I have tried self.update(image_data=...), super().update(...) and various similar options but I get a syntax error every time (expression cannot contain assignment). What am I missing? Thanks

Code To Duplicate

class CancelButton(sg.Button):
    def __init__(self, *args, **kwargs):
        kwargs['button_text'] = 'Cancel'
        kwargs["button_color"] = ('white', sg.theme_background_color())
        kwargs['image_data'] = red_80x32
        kwargs['mouseover_colors'] = sg.theme_background_color()
        super().__init__(*args, **kwargs)

    def hover(self):
        print('hover')
        # self.update('image_data'=red_hovered)


Screenshot, Sketch, or Drawing

Whitelegs avatar Apr 10 '24 02:04 Whitelegs

OK, I've sort of solved it. My hover method works if I include all parameters in order up to image source without using keywords eg. self.update('Cancel', ('white',sg.theme_background_color()), False, red_hovered) however fails otherwise. I'd be interested to know why & if there's a better way to do something like this.

Whitelegs avatar Apr 10 '24 04:04 Whitelegs

Firstly, I found that you use a string equal to a value in the method of update, it's wrong syntax.

self.update('image_data'=red_hovered)
>>> class Test():
...     def update(self, image_data=None):
...         print(image_data)
...
>>> test = Test()
>>> test.update("image_data"=1)
  File "<stdin>", line 1
    test.update("image_data"=1)
                ^
SyntaxError: expression cannot contain assignment, perhaps you meant "=="?

It should be

self.update(image_data=red_hovered)
>>> test.update(image_data=1)
1

jason990420 avatar Apr 10 '24 05:04 jason990420

Thanks, I thought I'd tried that but obviously not! That works to the extent that I don't get an error & the correct graphic is displayed but I get the graphic button within a white box (per button_color parameter), which I'm trying to avoid. I tried updating that using the same syntax but it still left it within the white box, whereas if I don't name any parameters & just supply values up to the image source the white box is not displayed. I can live with that as a 'work around' but I am curious why it doesn't work as I would expect

Interestingly, I create the button with button_ color = ('white', background). If I reverse them within the 'hover' method & then reverse them again, back to the original in my 'unhover' method it all displays correctly with no white box!

Whitelegs avatar Apr 10 '24 06:04 Whitelegs

Not sure what you mean, better with code and pictures to show what your expectation.

Example code

import PySimpleGUI as sg

bg = sg.theme_background_color()
data  = [sg.EMOJI_BASE64_HAPPY_LAUGH, sg.EMOJI_BASE64_CRY]
color = [('white', bg), (bg, 'white')]

layout = [
    [sg.Button("", image_data=data[0], key="1st", metadata=0, border_width=0, button_color=color[0]),
     sg.Checkbox("Change Background", key="Bg")],
]
window = sg.Window("Title", layout)

while True:

    event, values = window.read()

    if event == sg.WIN_CLOSED:
        break
    elif event == "1st":
        element = window[event]
        element.metadata = 1 - element.metadata
        element.update(image_data=data[element.metadata], button_color=color[element.metadata] if values["Bg"] else None)

window.close()

jason990420 avatar Apr 10 '24 08:04 jason990420