Don Smythe
Don Smythe

Reputation: 9804

PyQt QScrollArea within QScrollArea

I am trying to use multiple horizontal sub QScrollAreas with text and one vertical container QScrollArea. The idea being that the text area in the horizontal sub QScrollAreas will always have equivalent vertical heights and I would like to have one vertical QScrollArea to control the data within them.

The code below shows that the horizontal sub QScrollAreas work, but the vertical QScrollArea doesn't detect that the line edits within the widget inside it don't fit vertically. If I change

scroll.setWidgetResizable(True) 

for the vertical QScrollArea to False, the vertical QScrollArea detects the widget inside doesn't fit but I want to be able to scroll all the lineEdits up and down not the parent widget. Also I would like all scrollbars to be always visible. Is this possible?

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Widget(QWidget):
    def __init__(self, parent= None):
        super(Widget, self).__init__()
        self.setGeometry(100, 100, 400, 400)
        baseWidget = QWidget()
        hBox = QHBoxLayout()
        hBox.addWidget(self.getWidget())
        hBox.addWidget(self.getWidget())
        baseWidget.setLayout(hBox)
        scroll = QScrollArea()
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        #when set to False all scrolls are not visible and can only scroll parent widget not the data areas
        scroll.setWidgetResizable(True)
        scroll.setWidget(baseWidget)
        vBox = QHBoxLayout()
        vBox.addWidget(scroll)
        self.setLayout(vBox)

    def getWidget(self):      
        widget = QWidget()
        layout = QVBoxLayout()
        for i in range(20):
            lineEdit = QLineEdit("row: "+str(i)+" data: "+str(list(range(10))))
            lineEdit.setMinimumWidth(250)
            layout.addWidget(lineEdit)
        widget.setLayout(layout)
        scroll = QScrollArea()
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(False)
        scroll.setWidget(widget)
        return scroll

if __name__ == '__main__':
    app = QApplication(sys.argv)
    dialog = Widget()
    dialog.show()

Upvotes: 1

Views: 2269

Answers (1)

Don Smythe
Don Smythe

Reputation: 9804

The answer could be found here:

PyQt4 : is there any signal related to scrollbar?

Just needed to sync vertical scrollbars and hide all but one:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Widget(QWidget):

    def __init__(self, parent= None):
        super(Widget, self).__init__()
        self.setGeometry(100, 100, 200, 200)
        baseWidget = QWidget()
        hBox = QHBoxLayout()
        lscrollArea = self.getWidget(False)
        rScrollArea = self.getWidget(True)
        rScrollArea.verticalScrollBar().valueChanged.connect(
        lscrollArea.verticalScrollBar().setValue)
        hBox.addWidget(lscrollArea)
        hBox.addWidget(rScrollArea)
        baseWidget.setLayout(hBox)
        vBox = QHBoxLayout()
        vBox.addWidget(baseWidget)
        self.setLayout(vBox)

    def getWidget(self, vScrollOn):      
        widget = QWidget()
        layout = QVBoxLayout()
        for i in range(20):
            lineEdit = QLineEdit("row: "+str(i)+" data: "+str(list(range(10))))
            lineEdit.setMinimumWidth(250)
            layout.addWidget(lineEdit)
        widget.setLayout(layout)
        scroll = QScrollArea()
        if vScrollOn:
            scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        else:
            scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(False)
        scroll.setWidget(widget)
        return scroll

if __name__ == '__main__':
    app = QApplication(sys.argv)
    dialog = Widget()
    dialog.show()
    app.exec_()

Upvotes: 1

Related Questions