Ejemplo n.º 1
0
    def __init__(self, title: str, data: Dict[str, str]):

        super().__init__()

        # ─────────────────── Add content ────────────────── #

        self.setColumnCount(2)
        parent_item = QTreeWidgetItem(self, [f'{title} : '])
        parent_item.set_selectable(False)
        self.addTopLevelItem(parent_item)

        for key, val in data.items():
            item = QTreeWidgetItem(parent_item, [f'{key} : ', val])
            parent_item.addChild(item)

            # Cosmetics
            item.set_selectable(False)
            item.setTextAlignment(0, Qt.AlignRight)

        # ──────────────────── Cosmetics ─────────────────── #

        # Hide header
        self.header().hide()

        # No background
        self.setStyleSheet('background-color: transparent;')

        # Dynamically change height when widget is collapsed or expanded
        # You have to update the maximum height of the widget, based on
        # its contents. For each top item you need to get the height for
        # that row using rowHeight() and do the same recursively for
        # child items whenever the item is expanded. Also, you need to
        # overwrite the sizeHint and minimumSizeHint.
        self.expanded.connect(self.update_height)
        self.collapsed.connect(self.update_height)
Ejemplo n.º 2
0
    def __init__(self, title: str, data: Dict[str, str]):
        """
        Init self with a title and a dictionnary of keys and values (see
        self docstring).

        :param title: The title of the disclosure tree (e.g. 'Details'
            in dEAduction's course and exercise choosers.
        :param data: The data to be displayed in the disclosure
            triangle.
        """

        super().__init__()

        # ─────────────────── Add content ────────────────── #

        self.setColumnCount(2)
        self.__parent_item = QTreeWidgetItem(self, [f'{title} : '])
        self.__parent_item.set_selectable(False)
        self.addTopLevelItem(self.__parent_item)

        for key, val in data.items():
            item = QTreeWidgetItem(self.__parent_item, [f'{key} : ', val])
            self.__parent_item.addChild(item)

            # Cosmetics
            item.set_selectable(False)
            item.setTextAlignment(0, Qt.AlignRight)

        # ──────────────────── Cosmetics ─────────────────── #

        # Hide header
        self.header().hide()

        # No background
        self.setStyleSheet('background-color: transparent;')

        # Dynamically change height when widget is collapsed or expanded
        # You have to update the maximum height of the widget, based on
        # its contents. For each top item you need to get the height for
        # that row using rowHeight() and do the same recursively for
        # child items whenever the item is expanded. Also, you need to
        # overwrite the sizeHint and minimumSizeHint.
        self.expanded.connect(self.update_height)
        self.collapsed.connect(self.update_height)
Ejemplo n.º 3
0
class DisclosureTriangle(QTreeWidget):
    """
    An (very basic) implementation of a DisclosureTriangle, i.e. a
    widget that looks like this:

    ____________________
    |                  |
    |  |> Title:       |
    |      key1: val1  |
    |      key2: val2  |
    |      …           |
    --------------------

    This triangle can be expanded or collapsed and is instanciated with
    a title and a dictionnary of keys and values. Made with the help of
    musicamente on Stackoverflow:  https://stackoverflow.com/questions/
    63862724/
    qtreeview-dynamic-height-according-to-content-disclosure-triangle.
    """
    def __init__(self, title: str, data: Dict[str, str]):
        """
        Init self with a title and a dictionnary of keys and values (see
        self docstring).

        :param title: The title of the disclosure tree (e.g. 'Details'
            in dEAduction's course and exercise choosers.
        :param data: The data to be displayed in the disclosure
            triangle.
        """

        super().__init__()

        # ─────────────────── Add content ────────────────── #

        self.setColumnCount(2)
        self.__parent_item = QTreeWidgetItem(self, [f'{title} : '])
        self.__parent_item.set_selectable(False)
        self.addTopLevelItem(self.__parent_item)

        for key, val in data.items():
            item = QTreeWidgetItem(self.__parent_item, [f'{key} : ', val])
            self.__parent_item.addChild(item)

            # Cosmetics
            item.set_selectable(False)
            item.setTextAlignment(0, Qt.AlignRight)

        # ──────────────────── Cosmetics ─────────────────── #

        # Hide header
        self.header().hide()

        # No background
        self.setStyleSheet('background-color: transparent;')

        # Dynamically change height when widget is collapsed or expanded
        # You have to update the maximum height of the widget, based on
        # its contents. For each top item you need to get the height for
        # that row using rowHeight() and do the same recursively for
        # child items whenever the item is expanded. Also, you need to
        # overwrite the sizeHint and minimumSizeHint.
        self.expanded.connect(self.update_height)
        self.collapsed.connect(self.update_height)

    def expand(self, yes: bool = True):
        """
        Expand the tree is yes is True, collapse it otherwise.

        :param yes: See above.
        """

        if yes:
            self.expandItem(self.__parent_item)
        else:
            self.collapseItem(self.__parent_item)

    #####################
    # Redifined methods #
    #####################

    # See
    # https://stackoverflow.com/questions/63862724/
    # qtreeview-dynamic-height-according-to-content-disclosure-triangle

    def update_height(self):
        self.setMaximumHeight(self.sizeHint().height())

    def get_height(self, parent=None):
        height = 0
        if not parent:
            parent = self.rootIndex()
        for row in range(self.model().rowCount(parent)):
            child = self.model().index(row, 0, parent)
            height += self.rowHeight(child)
            if self.isExpanded(child) and self.model().hasChildren(child):
                height += self.get_height(child)
        return height

    def sizeHint(self):
        hint = super().sizeHint()
        # The + 10 avoids an ugly scroll bar
        hint.setHeight(self.get_height() + 10 + self.frameWidth() * 2)
        return hint

    def minimumSizeHint(self):
        return self.sizeHint()