Hacker6914
Hacker6914

Reputation: 257

How to get all items shown in the visible region of a QTreeWidget?

I am making a tree-widget, where I want to get all the items present in the visible region only (not all items present in tree-widget) while scrolling - like below image shown:

enter image description here

In the 1st image as you see, I want to get all the items present in the visible region. And in the second image, I changed the scrollbar and items present in the visible region are also changed. So I want to get all items as per visible region while scrolling.

enter image description here

Upvotes: 2

Views: 1118

Answers (1)

ekhumoro
ekhumoro

Reputation: 120598

A reasonably efficient way to do this would be to use indexAt to get the indexes at the top and bottom of the viewport, and then create a range from the row numbers:

def visibleRange(self):
    top = QtCore.QPoint(0, 0)
    bottom = self.tree.viewport().rect().bottomLeft()
    return range(self.tree.indexAt(top).row(),
                 self.tree.indexAt(bottom).row() + 1)

You can then iterate over that to pull out whatever information you need from each row. Here's a complete demo script:

import sys
from PyQt5 import QtCore, QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.button = QtWidgets.QPushButton('Test')
        self.button.clicked.connect(self.handleButton)
        self.tree = QtWidgets.QTreeWidget()
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.tree)
        layout.addWidget(self.button)
        columns = 'ABCDE'
        self.tree.setColumnCount(len(columns))
        for index in range(100):
            QtWidgets.QTreeWidgetItem(
                self.tree, [f'{char}{index:02}' for char in columns])

    def visibleRange(self):
        top = QtCore.QPoint(0, 0)
        bottom = self.tree.viewport().rect().bottomLeft()
        return range(self.tree.indexAt(top).row(),
                     self.tree.indexAt(bottom).row() + 1)

    def handleButton(self):
        for row in self.visibleRange():
            item = self.tree.topLevelItem(row)
            print(item.text(0))

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setWindowTitle('Test')
    window.setGeometry(800, 100, 540, 300)
    window.show()
    sys.exit(app.exec_())

Upvotes: 4

Related Questions