jarvisteach / appJar

Simple Tkinter GUIs in Python
http://appJar.info
Other
615 stars 68 forks source link

Can't configure scrollPane to stretch widgets across width #586

Open Crivella opened 5 years ago

Crivella commented 5 years ago

I'm trying to put "toggleFrame"s inside of a "scrollPane", but this seems to force then in a stretch='none' state even if the horizontal scrolling is disabled.

I want to set stretch='column' so that the "toggleFrame" will take the entire row, up to the window/frame border.

Here is a snippet of the code to reproduce the problem

from appJar import gui as GUI 

with GUI('','640x480') as gui:
    gui.addLabel('test', 'test', 0,0)

    with gui.toggleFrame(f'a', colspan=3, bg='green', stretch='column'):
        gui.addLabel('a', 'a')
    with gui.scrollPane('Test', colspan=3, bg='red',
        disabled='horizontal'
        ):
        # with gui.frame('123', bg='yellow', colspan=3):
        for i in range(20):
                with gui.toggleFrame(f'{i}', colspan=5):
                    gui.addLabel(str(i), str(i))

    gui.setSticky('ws')
    gui.setStretch('none')
    row = gui.getRow()
    gui.addButton('b111', None, row,0)
    gui.addButton('b222', None, row,1)
    gui.setStretch('column')
    gui.addEmptyLabel('', row,2)
    gui.setLabelBg('', 'green')

I'm running on windows7 appJar 0.94.0 python 3.7.2

tgolsson commented 4 years ago

Hello @Crivella!

I just found the same issue, and fixed it to my liking. First of all, you need to pass in the stick and stretch parameters to the app.scrollPane. My call looks like this:

    ...
    with app.scrollPane("main", disabled='horizontal', sticky='nsew', stretch='both'):
        ...

However, this won't fix the issue completely, due to a bug in appJar. They'll probably look more even but still not fill the width. The issue is that the ScrollPane constructor takes a resize parameter that we can't access from the app. If we could change this, it does fix the width of the scrollable area - but it breaks scrolling. As a simple workaround, this patch enables horizontal resizing/stretching with a vertical scrollbar and resize=False. It might not work in all other situations.

diff --git a/appJar/appjar.py b/appJar/appjar.py
index 572a937..1531897 100644
--- a/appJar/appjar.py
+++ b/appJar/appjar.py
@@ -13696,8 +13696,12 @@ class ScrollPane(frameBase, object):
         if self.resize:
             self.canvas.bind('<Configure>', self._updateWidth)
         else:
+            self.canvas.bind('<Configure>', self._updateFrameWidth)
             self.interior.bind('<Configure>', self._updateWidth)

+    def _updateFrameWidth(self, event):
+        self.canvas.itemconfig(self.interior_id, width=event.width)
+
     def _updateWidth(self, event):
         if self.resize:
             canvas_width = event.width
Crivella commented 4 years ago

Thanks @tgolsson!

This works for my usecase perfectly

jarvisteach commented 4 years ago

The behaviour you're describing is by design; widgets should only take up the space they require. If they need more space than is available, the scrolling area expands, while the pane stays the same size.

However, I can definitely see the use case here - wanting to have widgets fill the available space, then take advantage of scrolling if they get bigger....

jarvisteach commented 4 years ago

I expect the changes mentioned above will break the scrollPane in other scenarios, and will need a bit more investigation