PySimpleGUI icon indicating copy to clipboard operation
PySimpleGUI copied to clipboard

[Bug] Table colored rows flashes when updating in 5.0, while they didn't in 4.x

Open tepiloxtl opened this issue 1 year ago • 10 comments

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

Bug


Environment

Operating System

Windows version ('10', '10.0.22631', 'SP0', 'Multiprocessor Free')

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

Python version (sg.sys.version)

3.11.8 (tags/v3.11.8:db85d51, Feb 6 2024, 21:52:07) [MSC v.1937 32 bit (Intel)]

PySimpleGUI Version (sg.__version__)

5.0.4

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

8.6.12

Support Code

Priority Support Code 26cbf4019119


Your Experience In Months or Years (optional)

3 Years Python programming experience 6 Years Programming experience overall Yes (tkinter, briefly) 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
  • [ ] 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)
  • [X] Run your program outside of your debugger (from a command line)
  • [X] Searched through Issues (open and closed) to see if already reported Issues.PySimpleGUI.org
  • [X] 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

Have been using this code that was part of Demo_Table_Checkmark.py for a few years since 4.x, after upgrading to 5.0, any clicks in the table causes all already select rows to flash (colors stays off as long as I keep the mouse button down)

Code To Duplicate

# Code taken from my code, modified from Demo_Table_Checkmark.py

import PySimpleGUI as sg

table = [["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"]]


BLANK_BOX = '☐'
CHECKED_BOX = '☑'

table_headings = ["☐", "a", "a"]
selected = {i for i, row in enumerate(table) if row[0] == CHECKED_BOX}

layout = [  [sg.Table(values=table, headings=table_headings,
                    max_col_width=25,
                    auto_size_columns=False,
                    col_widths=[1, 5, 20],
                    display_row_numbers=False,
                    justification='center',
                    num_rows=20,
                    key='-TABLE-',
                    selected_row_colors='red on yellow',
                    expand_x=True,
                    expand_y=True,
                    vertical_scroll_only=True,
                    enable_click_events=True)]
        ]

window = sg.Window('test gui', layout, resizable=True, finalize=True)
window['-TABLE-'].update(values=table, select_rows=list(selected))


while True:
    event, values = window.read()
    if event[0] == '-TABLE-' and event[2][0] not in (None, -1):   # if clicked a data row rather than header or outside table
        row = event[2][0]
        if table[row][0] == CHECKED_BOX:     # Going from Checked to Unchecked
            selected.remove(row)
            table[row][0] = BLANK_BOX
        else:                               # Going from Unchecked to Checked
            selected.add(row)
            table[row ][0] = CHECKED_BOX
        window['-TABLE-'].update(values=table, select_rows=list(selected))    # Update the table and the selected rows


Screenshot, Sketch, or Drawing

explorer_R1pcR70y2l


        ## Watcha Makin?
        It's a work project, expanding functionality of Enterprise Resource Planning suite of applications

tepiloxtl avatar May 13 '24 06:05 tepiloxtl

For 4.55.1.19

                if element.enable_click_events is True:
                    treeview.bind('<Button-1>', element._table_clicked)

For 5.0.4.13

                if element.enable_click_events is True:
                    treeview.bind('<ButtonRelease-1>', element._table_clicked)

So it will select last clicked row, then selected all previous clicked rows for 5.0.4.13

Not sure why it changed ?

jason990420 avatar May 13 '24 09:05 jason990420

Not sure why it changed ?

Thank you for identifying what changed!

Here is what I wrote in the release notes about this change:

Changed Table click events to be generated on Button Release instead of Button (down). Was not getting the correct selected rows in the values dictionary when the click event was generated using down. Now the selected rows is correct

PySimpleGUI avatar May 13 '24 11:05 PySimpleGUI

If you click a row and hold the click down, then you'll see that tkinter removes all of the selected row highlights. When you release the button, then the rows are highlighted again. I believe it's this tkinter behavior that is causing the "flash".

PySimpleGUI avatar May 13 '24 15:05 PySimpleGUI

The selection for one row is done defaultly by clicking the mouse, and all old selection removed before it. Now the option enable_click_events=True generate an event to add one new row to existing selection, and update the total selection to the Table elemenet by method update in the event loop by user code.

What I can do is to recover it to old one, like

window = sg.Window('test gui', layout, resizable=True, finalize=True)
window['-TABLE-'].update(values=table, select_rows=list(selected))

tbl = window['-TABLE-']
tbl.widget.unbind('<ButtonRelease-1>')
tbl.widget.bind('<Button-1>', tbl._table_clicked)

jason990420 avatar May 13 '24 15:05 jason990420

This will fix it.... add the select_mode parameter to your Table element.

                      select_mode=sg.TABLE_SELECT_MODE_NONE,

Because you are doing your own highlighting, using a mode of 'none' will keep tkinter from removing the previous selection. It will be smooth again.

# Code taken from my code, modified from Demo_Table_Checkmark.py

import PySimpleGUI as sg

table = [["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"], ["☐", "a", "a"]]


BLANK_BOX = '☐'
CHECKED_BOX = '☑'

table_headings = ["☐", "a", "a"]
selected = {i for i, row in enumerate(table) if row[0] == CHECKED_BOX}

layout = [  [sg.Table(values=table, headings=table_headings,
                    max_col_width=25,
                    auto_size_columns=False,
                    col_widths=[3, 5, 20],
                    display_row_numbers=False,
                    justification='center',
                    num_rows=20,
                    key='-TABLE-',
                    selected_row_colors='red on yellow',
                    expand_x=True,
                    expand_y=True,
                    vertical_scroll_only=True,
                    select_mode=sg.TABLE_SELECT_MODE_NONE,
                    enable_click_events=True)]
        ]

window = sg.Window('test gui', layout, resizable=True, finalize=True)
window['-TABLE-'].update(values=table, select_rows=list(selected))


while True:
    event, values = window.read()
    if event[0] == '-TABLE-' and event[2][0] not in (None, -1):   # if clicked a data row rather than header or outside table
        row = event[2][0]
        if table[row][0] == CHECKED_BOX:     # Going from Checked to Unchecked
            selected.remove(row)
            table[row][0] = BLANK_BOX
        else:                               # Going from Unchecked to Checked
            selected.add(row)
            table[row ][0] = CHECKED_BOX
        window['-TABLE-'].update(values=table, select_rows=list(selected))    # Update the table and the selected rows

python_Ge9JQj9r53

PySimpleGUI avatar May 13 '24 16:05 PySimpleGUI

In 5.0.4.14 I changed the docstring for the Table element. It is not required in order for the code that added:

select_mode=sg.TABLE_SELECT_MODE_NONE,

In PyCharm I was seeing a warning because the parameter was defined as an enum instead of a string.

PySimpleGUI avatar May 13 '24 18:05 PySimpleGUI

Huh. For a single moment when making this bug report yesterday I haven't noticed this is select_rows and not row_colors which I have been dealing with a lot lately, that could have helped figuring out the issue :)

Adding select_mode=sg.TABLE_SELECT_MODE_NONE, fixes the issue, thanks!

tepiloxtl avatar May 14 '24 05:05 tepiloxtl

I haven't noticed this is select_rows and not row_colors

That's an interesting observation that I missed..... row colors could have been used perhaps instead of selected rows. Maybe?

I've updated the Table Checkmark Demo Program with this change too. Thank you for indicating you picked up code from the Demo so that it's fixed and the next person won't have this problem.

And, thank you for the "thanks!" image It's always nice to see that Jason and I are doing a good job of helping PySimpleGUI users be successful.

PySimpleGUI avatar May 14 '24 06:05 PySimpleGUI

I'm very grateful for the immense work you do in supporting users both here and on Stack Overflow, I definitely picked a lot of tips over the years from yours and Jasons responses :)

tepiloxtl avatar May 14 '24 10:05 tepiloxtl

I'm very grateful

I can't express how much it means to see these words. Thank you so very much. I'm extremely grateful to have grateful users. Maybe it's not unusual or rare, but it sure feels that way. Jason provides the best support I've ever seen, is quicker and more thorough than I am. We're very fortunate.

PySimpleGUI avatar May 14 '24 15:05 PySimpleGUI