Closed milahu closed 2 years ago
Following binding removed in __init__
of class TkScrollableFrame
.
self.unhookMouseWheel(None)
self.TKFrame.bind("<Enter>", self.hookMouseWheel)
self.TKFrame.bind("<Leave>", self.unhookMouseWheel)
and binding with these direcly, the element
is the argument passed to __init__
of class TkScrollableFrame
, then it work.
if element.Scrollable:
self.canvas.bind_all('<4>', self.yscroll, add='+')
self.canvas.bind_all('<5>', self.yscroll, add='+')
self.canvas.bind_all("<MouseWheel>", self.yscroll, add='+')
if not element.VerticalScrollOnly:
self.canvas.bind_all("<Shift-MouseWheel>", self.xscroll, add='+')
self.bind('<Configure>', self.set_scrollregion)
Not sure why mousewheel binding only if mouse enter the Column in PySimpleGUI.py ?
Not sure why mousewheel binding only if mouse enter the Column in PySimpleGUI.py ?
I've not spent any time yet looking at this.
We made changes some time back so that bind of mouse scrollwheel only happens when the mouse enters the element. This was critical for situations when there was embedded elements. If a listbox was inside of a Column, then only the listbox should scroll, not the entire column.
I've not added the new ttk scrollbars to Columns yet as I'm aware of these scroll problems. I want to get through the new ttk stuff first and then I'll come back to these column scoll problems.
Again, I'm not well-versed on the particulars here, but wanted to show this example in case it's at all relevant.
The red text element is not in the Column element and this when scrolled over it will not scroll the column.
When the mouse is over the Listbox, only the listbox is scrolled, etc.
Now that ttk scrollbars are futher along, I'm marking this urgent was I want to make sure it gets addressed in the upcoming release.
Finally got working on this final problem for the 4.60.0 release.
I HOPE I got this right as it impacts SO many programs potentially.
It seems like the big problem was binding to the Frame rather than binding to the Canvas.
The sample program provided by @milahu works now. Thank you for providing something that was elegantly simple to show the problem!
import PySimpleGUI as sg
column_layout = []
for i in range(0, 20):
column_layout.append([sg.Text("test")],)
layout = [
[sg.Column(
column_layout,
scrollable=True,
vertical_scroll_only=True,
expand_x=True,
)],
]
window = sg.Window('test', layout, size=(400, 200))
event, values = window.read()
window.close()
The single column in a layout I'm not concerned about so much.... it's nested scrollable elements that is the bigger issue that makes my stomach ache.
I used this test harness to give things a try. It's not perfect, but it does seem to function correctly most of the time. I welcome additional help on debugging that scrollable column code. It may be a tkinter issue under it all with enter and leave events.
It scares me to make this change, but I'll be brave and give it a go!
import PySimpleGUI as sg
"""
Demonstrates how to use the Window.layout_extend method.
Layouts can be extended at the Window level or within any container element such as a Column.
This demo shows how to extend both.
Note that while you can extend, add to, a layout, you cannot delete items from a layout. Of course you
can make them invisible after adding them.
When using scrollable Columns be sure and call Column.visibility_changed so that the scrollbars will
be correctly reposititioned
Copyright 2020, 2022 PySimpleGUI
"""
col2 = sg.Column([[sg.Multiline('\n'.join([str(x) for x in range(40)]), size=(20,10), no_scrollbar=False), sg.T('Some text')]], scrollable=True, size_subsample_height=2)
layout = [[sg.Text('My Window')],
[sg.Text('Click to add a row inside the Frame'), sg.B('+', key='-ADD FRAME-')],
[sg.Text('Click to add a row inside the Column'), sg.B('+', key='-ADD COL-')],
[sg.Text('Click to add a row inside the Window'), sg.B('+', key='-ADD WIN-')],
[sg.Frame('Frame', [[sg.T('Frame')]], key='-FRAME-')],
[sg.Col([[sg.T('Column')], [col2]], scrollable=True, key='-COL-', s=(400, 400))],
[sg.Input(key='-IN-'), sg.Text(size=(12, 1), key='-OUT-')],
[sg.Button('Button'), sg.Button('Exit')]]
window = sg.Window('Window Title', layout)
i = 0
while True: # Event Loop
event, values = window.read()
print(event, values)
if event in (sg.WIN_CLOSED, 'Exit'):
break
if event == '-ADD FRAME-':
window.extend_layout(window['-FRAME-'], [[sg.T('A New Input Line'), sg.I(key=f'-IN-{i}-')]])
i += 1
elif event == '-ADD COL-':
window.extend_layout(window['-COL-'], [[sg.T('A New Input Line'), sg.I(key=f'-IN-{i}-')]])
window.visibility_changed()
window['-COL-'].contents_changed()
i += 1
elif event == '-ADD WIN-':
window.extend_layout(window, [[sg.T('A New Input Line'), sg.I(key=f'-IN-{i}-')]])
i += 1
window.close()
As you can see, there is a little struggling going on to get the mouse scrollwheel to function correctly in every case.
The above code is 4.59.0.45 that's on GitHub.
I would like to make this the 4.60.0 release if at all possible.
@jason990420 do you have an opinion on this one? Are we in "Good Enough" territory? As I said, it's a fear producing set of changes, but this 4.60.0 ship needs to sail and soon.
I don't have exact conclusion for it, but it looks something strange, not yet do all the tests. Tell the truth, not sure how many items or what items to do the test.
For example:
'Click to add a row inside the Column'
, scroll wheel on Column not scrollable, but inner column scrolled on Column scrollbar.Some text
or number, A New Input Line
no scrollable, need to move mouse leave and enter
of main column, then scrollable.It is meant to be not scrollable at first because the Column isn't "full"... it doesn't have enough things in it to make a scrollable area. Only after the input elements are added that it should scroll.
I do see what you mean by scrollable using the scrollbar even though it doesn't with the wheel.
There are so many weird edge cases... this is why I'm asking for an opinion. It'll drive us CRAZY to try to get all of the edge cases at this point I think. I dunno, maybe I'm wrong about this and being lazy, but I get a sense these have always been there.
This was released in 4.60.0. There may be some edge cases such as those that Jason pointed out, but I think for the most part it should function really well.
continue https://github.com/PySimpleGUI/PySimpleGUI/issues/1779#issuecomment-1093052916
tldr:
Type of Issue (Enhancement, Error, Bug, Question)
Bug
Operating System
linux
PySimpleGUI Port (tkinter, Qt, Wx, Web)
tkinter
Versions
Python version (
sg.sys.version
)3.9
PySimpleGUI Version (
sg.__version__
)32d5481f5097fdbfb151927956023cbde377ffb5
GUI Version (tkinter (
sg.tclversion_detailed
), PySide2, WxPython, Remi)Your Experience In Months or Years (optional)
Years Python programming experience
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
Code To Duplicate
Screenshot, Sketch, or Drawing
Watcha Makin?
If you care to share something about your project, it would be awesome to hear what you're building.
contributing to https://github.com/FHPythonUtils/Cli2Gui
more interesting: ansi terminal emulator widget for PySimpleGUI : ) see https://github.com/FHPythonUtils/Cli2Gui/pull/9