I'm implementing a python application using PyQt5 and I encountered some problems when making use of a QScrollArea. This is the layout of my application:
It's composed of 2 QScrollArea
(left and right pane) and a QMdiArea
(center widget) arranged into a QHBoxLayout
. When I expand the widgets on the left pane by clicking on the controls, and the height of the QWidget
of the QScrollArea
is bigger than then height of the QScrollArea
itself, the scrollbar appears (as expected), but it's overlapping the content of the QScrollArea
. To fix this problem I reimplemented the resizeEvent
adding the necessary space for the scrollbar (till this point everything works.
Now, when I manually resize the Main Window, the left Pane gets more space and the scrollbar should disappear (but it doesn't) and it overlaps the widgets of the pane:
I also tried to manually toggle the visibility of the scrollbar (when the resizeEvent is received): when I do this, I can successfully hide the scrollbar but then I can't show it again (not matter if I call setVisible(True)
on the scrollbar). This results in the space for the scrollbar being added, but the scrollbar is missing and the content of the pane is not scrollable:
Here is the implementation of the pane widget:
class Pane(QScrollArea):
MinWidth = 186
def __init__(self, alignment=0, parent=None):
super().__init__(parent)
self.mainWidget = QWidget(self)
self.mainLayout = QVBoxLayout(self.mainWidget)
self.mainLayout.setAlignment(alignment)
self.mainLayout.setContentsMargins(0, 0, 0, 0)
self.mainLayout.setSpacing(0)
self.setContentsMargins(0, 0, 0, 0)
self.setFrameStyle(QFrame.NoFrame)
self.setFixedWidth(Pane.MinWidth)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored)
self.setWidgetResizable(True)
self.setWidget(self.mainWidget)
def resizeEvent(self, resizeEvent):
if self.viewport().height() < self.widget().height():
self.setFixedWidth(Pane.MinWidth + 18)
# THIS DOESN'T WORK
#self.verticalScrollBar().show()
else:
self.setFixedWidth(Pane.MinWidth)
#self.verticalScrollBar().hide()
def addWidget(self, widget):
self.mainLayout.addWidget(widget)
def removeWidget(self, widget):
self.mainLayout.removeWidget(widget)
def update(self, *__args):
for item in itemsInLayout(self.mainLayout):
item.widget().update()
super().update(*__args)
What I want to achieve is pretty simple (but practically it seems not as simple): I would like to dynamically show the vertical scrollbar on my left/right pane widgets only when it's needed, and add the necessary space for the scrollbar so it doesn't overlap the widgets in the QScrollArea
.
Before someone asks, I already tried to do something like this:
def resizeEvent(self, resizeEvent):
if self.viewport().height() < self.widget().height():
self.setFixedWidth(Pane.MinWidth + 18)
scrollbar = self.verticalScrollbar()
scrollbar.setVisible(True)
self.setVerticalScrollBar(scrollbar) ## APP CRASH
else:
self.setFixedWidth(Pane.MinWidth)
#self.verticalScrollBar().hide()
which results in my application to crash. I hope that someone already faced this issue and is able to help me.
EDIT: I'm using PyQt5.5 compiled against Qt5.5 under OSX Yosemite 10.10.4 using clang.
setWidgetResizable
to true for your scrollArea – Corded