T-5
T-5

Reputation: 23

Adding custom widgets to a QScrollArea in pyqt5 does not make scrollbar appear

The example shown below adds a very simple custom pyqt5 widget to a QScrollArea. When i move the custom widget "off" the area of the scroll area I would expect that scrollbars should appear. Obviously this is not the case.

#!/usr/bin/python3
from PyQt5.QtWidgets import QMainWindow, QWidget, QApplication, QScrollArea
from PyQt5.QtCore import QObject
from PyQt5.QtGui import QPainter, QColor, QPen
import sys

class ExampleWidget(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent=parent)

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        self.drawWidget(qp)
        qp.end()

    def drawWidget(self, qp):
        qp.setPen(QColor(255, 0, 0))
        qp.setBrush(QColor(255, 0, 0))
        qp.drawRect(0, 0, 100, 100)

class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setGeometry(300, 300, 300, 200)
        self.scrollArea = QScrollArea(self)
        self.setCentralWidget(self.scrollArea)
        self.widget = ExampleWidget(self.scrollArea)
        self.widget.setGeometry(250, 150, 100, 100)
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

How can I make the scrollbars appear once a widget is moved so it's not visible completely anymore?

Upvotes: 2

Views: 1264

Answers (1)

eyllanesc
eyllanesc

Reputation: 243955

In the code that samples ExampleWidget is a child of QScrollArea: self.widget = ExampleWidget(self.scrollArea), that does not imply that the widget is handled with the properties of the QScrollArea, the QScrollArea has a viewport() that is the background widget and the QScrollArea only shows a part of it. So if you want a widget to be inside you have to use the setWidget() method. On the other hand that viewport() has the size of the content and how it calculates that size ?, by default it uses the sizeHint() of the widget, and in your case it does not have it so it will not show what you want.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class ExampleWidget(QtWidgets.QWidget):
    def paintEvent(self, e):
        qp = QtGui.QPainter(self)
        self.drawWidget(qp)

    def drawWidget(self, qp):
        qp.setPen(QtGui.QColor(255, 0, 0))
        qp.setBrush(QtGui.QColor(255, 0, 0))
        qp.drawRect(0, 0, 100, 100)

    def sizeHint(self):
        return QtCore.QSize(500, 500)


class Example(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.scrollArea = QtWidgets.QScrollArea()
        self.setCentralWidget(self.scrollArea)
        self.widget = ExampleWidget()
        self.scrollArea.setWidget(self.widget)
        self.show()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

enter image description here

Upvotes: 1

Related Questions