Erik Iverson
Erik Iverson

Reputation: 353

pyqt5 QScrollArea inheritance

I'm having a hard time understanding how to use scroll bars in PyQt5. I have an arbitrary layout to experiment with, which is just some blocks of colors. I'd like to have the layout of colors to have a minimum size, and when the window is smaller than that, the scroll bars appear (or the scroll bars are just present all the time). I found this example:

PyQt: Put scrollbars in this

and changed it to work with PyQt5:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QScrollArea, QVBoxLayout, QWidget
class myDialog(QDialog):
    _buttons = 0

    def __init__(self, parent=None):
        super(myDialog, self).__init__(parent)
        self.pushButton = QPushButton(self)
        self.pushButton.setText("Add Button!")
        self.pushButton.clicked.connect(self.on_pushButton_clicked)
        self.scrollArea = QScrollArea(self)
        self.scrollArea.setWidgetResizable(True)
        self.scrollAreaWidgetContents = QWidget(self.scrollArea)
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 380, 247))
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.addWidget(self.pushButton)
        self.verticalLayout.addWidget(self.scrollArea)
        self.verticalLayoutScroll = QVBoxLayout(self.scrollAreaWidgetContents)
'''
verticalLayoutScroll is a child of scrollAreaWidgetContents
scrollAreaWidgetContents is a child of scrollArea
scrollArea is child of self

verticalLayout is also a child of self has the widgets pushButton and scrollArea
'''
    @QtCore.pyqtSlot()
    def on_pushButton_clicked(self):
        self._buttons  += 1
        pustButtonName = u"Button {0}".format(self._buttons)

        pushButton = QPushButton(self.scrollAreaWidgetContents)
        pushButton.setText(pustButtonName)

        self.verticalLayoutScroll.addWidget(pushButton)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    app.setApplicationName('myDialog')
    main = myDialog()
    main.show()
    sys.exit(app.exec_())

Here is my code:

    # -*- coding: utf-8 -*-
"""
Created on Mon Jan 15 07:37:28 2018

@author: Erik
"""
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QSlider, QPushButton, 
QMainWindow, QAction, qApp,
    QLCDNumber, QGridLayout, QLabel, QLineEdit, QVBoxLayout, QHBoxLayout, 
QSizePolicy, QScrollArea, QLayout)
from PyQt5.QtGui import QIcon, QColor, QPalette
from PyQt5.QtCore import Qt, QSize, QRect

class Color(QWidget):

    def __init__(self, color, *args, **kwargs):
        super(Color, self).__init__(*args, **kwargs)
        self.setAutoFillBackground(True)

        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(color))
        self.setPalette(palette)

class Color2(QWidget):

    def __init__(self, color, *args, **kwargs):
        super(Color2, self).__init__(*args, **kwargs)
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(QPalette.Window, QColor(color))
        self.setPalette(palette)

    def sizeHint(self):
        return QSize(150,150)

class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle("My Awesome App")

        size = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        layout = QVBoxLayout()
        layout2 = QVBoxLayout()
        brw = Color2('brown')
        brw.setSizePolicy(size)
        layout2.addWidget(brw)
        layout2.addWidget(Color('black'))
        layout2.setStretch(1,2)
        layout2.addWidget(Color('cyan'))
        layout2.setStretch(2, 1)

        layout.addWidget(Color('red'))
        layout.addWidget(Color('blue'))
        layout.addWidget(Color('green'))


        self.scrollArea = QScrollArea(self)
        self.scrollArea.setWidgetResizable(True)
        self.scrollAreaWidgetContents = QWidget(self.scrollArea)
        self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 600, 500))   
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.scrollAreaWidgetContents.setMinimumSize(QSize(500, 500))

        self.scrollLayout = QVBoxLayout(self.scrollAreaWidgetContents)
        #self.scrollLayout.setSizeConstraint(QLayout.SetMinimumSize) #2
        self.mainLayout = QHBoxLayout()
        self.mainLayout.addWidget(Color('purple'))
        self.mainLayout.addWidget(Color('yellow'))
        self.mainLayout.addWidget(Color('orange'))
        self.mainLayout.addLayout(layout2)
        self.mainLayout.addLayout(layout)
        self.scrollLayout.addLayout(self.mainLayout)

        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())

I can barely see the colors in the scrollArea. In the first code block above, I don't understand the necessary inheritance structure I described in the comment block. Do I need to extend a layout class to set a minimum size? https://doc.qt.io/qt-5/qlayoutitem.html#minimumSize How is the "Size Hints and Layouts" section of https://doc.qt.io/qt-5/qscrollarea.html#details relevant?
Thanks.

Upvotes: 0

Views: 982

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

The problem is that you have not established the QScrollArea as centralWidget.

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setWindowTitle("My Awesome App")

        size = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        layout = QVBoxLayout()
        layout2 = QVBoxLayout()
        brw = Color2('brown')
        brw.setSizePolicy(size)
        layout2.addWidget(brw)
        layout2.addWidget(Color('black'))
        layout2.setStretch(1,2)
        layout2.addWidget(Color('cyan'))
        layout2.setStretch(2, 1)

        layout.addWidget(Color('red'))
        layout.addWidget(Color('blue'))
        layout.addWidget(Color('green'))

        self.scrollArea = QScrollArea()
        # set CentralWidget
        self.setCentralWidget(self.scrollArea)

        self.scrollArea.setWidgetResizable(True)
        self.scrollAreaWidgetContents = QWidget(self.scrollArea)
        self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 600, 500))   
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.scrollAreaWidgetContents.setMinimumSize(QSize(500, 500))

        self.scrollLayout = QVBoxLayout(self.scrollAreaWidgetContents)
        #self.scrollLayout.setSizeConstraint(QLayout.SetMinimumSize) #2
        self.mainLayout = QHBoxLayout()
        self.mainLayout.addWidget(Color('purple'))
        self.mainLayout.addWidget(Color('yellow'))
        self.mainLayout.addWidget(Color('orange'))
        self.mainLayout.addLayout(layout2)
        self.mainLayout.addLayout(layout)
        self.scrollLayout.addLayout(self.mainLayout)

        self.show()

Upvotes: 1

Related Questions