1

I am working in Maya with pyside2 (basically the same as PyQt5).

I have a gui with a scroll area in it... The scroll area has rows of some buttons and stuff that I want to expand horizontally if the user drags the window and expands it larger. Extra rows of these items can be added to it which makes the vertical scroll bar appear (obviously).

I'm trying to determine a way to prevent the slight resize of my rows of items when the scroll bar appears/disappears. Visually, I want the width of the items in each row to say the same if new rows get added and the scroll bar appears, or if the user expands the window some and the scroll bar disappears...

Is there a signal or something that gets sent if the scroll bar's visibility changes so I can adjust the margins of the layout for the items in the scroll area?

I know I can set the scroll bar to be visible or not, but I can't find anything that I can hook into for when this inherently changes as the size of the gui or contents in the scroll area is modified... If there's not already a signal, how could I go about creating one?

silent_sight
  • 492
  • 1
  • 8
  • 16
  • have you tried overriding the hide event handler in a custom qscrollbar class? https://doc.qt.io/qt-5/qscrollbar.html#hideEvent – Aaron May 15 '20 at 17:02
  • @Aaron I have not... How do you actually do that (and make sure that the QScrollArea uses your overridden QScrollBar class)? – silent_sight May 15 '20 at 17:23

1 Answers1

1

Ok, after searching around about the hideEvent like Aaron commented about, I've found something that seems to work...

I created an event filter for the vertical scroll bar in my scroll area... So, in the part of my code where the scroll area is defined, I have something like this:

scroll_area_widget = QtWidgets.QWidget()
self.scroll_area_layout = QtWidgets.QVBoxLayout()
scroll_area_widget.setLayout(self.scroll_area_layout)

scroll_area = QtWidgets.QScrollArea()
scroll_area.setWidget(scroll_area_widget)

self.scrollbar = scroll_area.verticalScrollBar()
self.scrollbar.installEventFilter(self)

Then, I define an 'eventFilter' method like this:

def eventFilter(self, o, e):
    if o is self.scrollbar:
        if e.type() == QtCore.QEvent.Show:
            self.scroll_area_layout.setContentsMargins(5, 0, 3, 0)
        elif e.type() == QtCore.QEvent.Hide:
            self.scroll_area_layout.setContentsMargins(5, 0, 15, 0)
            QtWidgets.QApplication.processEvents()
    return False

I put the 'processEvents' in there because I'm getting a flickering when the scrollbar disappears where I think the widgets in the layout stretch out to fill the space before the contents margins gets updated... It doesn't help prevent the flickering every time, but it seems to be less than if I don't have it...

The question now is how do I avoid the flicker? Of course, another question is whether or not this is even a good way to solve this particular issue since I don't know enough about event filters... Is this something that will get triggered only when the scroll bar is shown/hidden, or does it apply to anything in the gui that gets shown/hidden? I ask that since the 'eventFilter' method doesn't seem specific to the scroll bar, and placing the if statement checking if it's the scrollbar seems like it might be a bit of overhead if every event in the whole gui is passing through....

silent_sight
  • 492
  • 1
  • 8
  • 16
  • The flickering happens due to the updating of the layout indeed. Another possibility might be to set a fixed width for the widget whenever the scroll area is resized, but a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) in your original question might help. – musicamante May 15 '20 at 22:18
  • @musicamante - yeah, I had a feeling that's what it was... unfortunately, I do need the widgets inside the scroll area to expand out when the user makes the window wider, so setting a fixed width would prevent that... – silent_sight May 18 '20 at 18:18
  • Which is exactly what I said: a fixed width *whenever* the scroll area is resized. Again, provide an MRE, it'll make everything simpler. – musicamante May 19 '20 at 14:39