Skip to content

TableToListProxyModel

Qt Base Class: QIdentityProxyModel

Signature: QIdentityProxyModel(self, parent: Optional[PySide6.QtCore.QObject] = None) -> None

Base classes

Name Children Inherits
IdentityProxyModel
prettyqt.core.identityproxymodel

⋔ Inheritance diagram

graph TD
  1473290729632["itemmodels.TableToListProxyModel"]
  1473299892128["core.IdentityProxyModel"]
  1473299903840["core.AbstractProxyModelMixin"]
  1473299890176["core.AbstractItemModelMixin"]
  1473299815024["core.ObjectMixin"]
  140713234304496["builtins.object"]
  1473289064768["QtCore.QIdentityProxyModel"]
  1473289061840["QtCore.QAbstractProxyModel"]
  1473289050128["QtCore.QAbstractItemModel"]
  1473288842240["QtCore.QObject"]
  1473291690208["Shiboken.Object"]
  1473299892128 --> 1473290729632
  1473299903840 --> 1473299892128
  1473299890176 --> 1473299903840
  1473299815024 --> 1473299890176
  140713234304496 --> 1473299815024
  1473289064768 --> 1473299892128
  1473289061840 --> 1473289064768
  1473289050128 --> 1473289061840
  1473288842240 --> 1473289050128
  1473291690208 --> 1473288842240
  140713234304496 --> 1473291690208

🛈 DocStrings

Bases: IdentityProxyModel

Proxy model to flatten a table to a list.

Reshapes a table by concatenating all columns into one large column, so that the new rowCount equals to sourceModel rowCount * sourceModel columnCount. If a verticalHeader is available, it will show the original position of the cell.

data = dict(
    first=["John", "Mary"],
    last=["Doe", "Bo"],
    height=[5.5, 6.0],
    weight=[130, 150],
)
model = gui.StandardItemModel.from_dict(data)
table = widgets.TableView()
table.set_model(model)
# table.proxifier.to_list()
table.show()
Image title

data = dict(
    first=["John", "Mary"],
    last=["Doe", "Bo"],
    height=[5.5, 6.0],
    weight=[130, 150],
)
model = gui.StandardItemModel.from_dict(data)
table = widgets.TableView()
table.set_model(model)
table.proxifier.to_list()
table.show()
Image title

Source code in prettyqt\itemmodels\proxies\tabletolistproxymodel.py
class TableToListProxyModel(core.IdentityProxyModel):
    """Proxy model to flatten a table to a list.

    Reshapes a table by concatenating all columns into one large column,
    so that the new rowCount equals to sourceModel rowCount * sourceModel columnCount.
    If a verticalHeader is available, it will show the original position of the cell.

    === "Without proxy"

        ```py
        data = dict(
            first=["John", "Mary"],
            last=["Doe", "Bo"],
            height=[5.5, 6.0],
            weight=[130, 150],
        )
        model = gui.StandardItemModel.from_dict(data)
        table = widgets.TableView()
        table.set_model(model)
        # table.proxifier.to_list()
        table.show()

        ```
        <figure markdown>
          ![Image title](../../images/tabletolistproxymodel_before.png)
        </figure>

    === "With proxy"

        ```py
        data = dict(
            first=["John", "Mary"],
            last=["Doe", "Bo"],
            height=[5.5, 6.0],
            weight=[130, 150],
        )
        model = gui.StandardItemModel.from_dict(data)
        table = widgets.TableView()
        table.set_model(model)
        table.proxifier.to_list()
        table.show()
        ```
        <figure markdown>
          ![Image title](../../images/tabletolistproxymodel_after.png)
        </figure>

    """

    ID = "table_to_list"
    ICON = "mdi6.table-pivot"

    def __init__(self, *args, header_title: str = "", **kwargs):
        super().__init__(*args, **kwargs)
        self._header_title = header_title

    def columnCount(self, parent: core.ModelIndex | None = None) -> int:
        parent = parent or core.ModelIndex()
        return 0 if self.sourceModel() is None else 1

    def headerData(
        self,
        section: int,
        orientation: constants.Orientation,
        role: constants.ItemDataRole = constants.DISPLAY_ROLE,
    ) -> str | None:
        match orientation, role:
            case constants.HORIZONTAL, constants.DISPLAY_ROLE:
                return self._header_title or None
            case constants.VERTICAL, constants.DISPLAY_ROLE:
                col_section = section % super().columnCount()
                row_section = section // super().columnCount()
                pre = super().headerData(col_section, constants.HORIZONTAL, role)
                post = super().headerData(row_section, constants.VERTICAL, role)
                pre_str = col_section if pre is None else pre
                post_str = row_section if post is None else post
                return f"{pre_str} | {post_str}"
        return None

    def rowCount(self, parent: core.ModelIndex | None = None) -> int:
        parent = parent or core.ModelIndex()
        source = self.sourceModel()
        return 0 if source is None else source.rowCount() * source.columnCount()

    def index(
        self, row: int, column: int, parent: core.ModelIndex | None = None
    ) -> core.ModelIndex:
        parent = parent or core.ModelIndex()
        source = self.sourceModel()
        if row < 0 or column < 0 or source is None:
            return core.ModelIndex()
        source_parent = self.mapToSource(parent)
        colcount = source.columnCount()
        source_index = source.index(row // colcount, row % colcount, source_parent)
        return self.mapFromSource(source_index)

    def mapToSource(self, proxy_idx: core.ModelIndex) -> core.ModelIndex:
        source = self.sourceModel()
        if source is None or not proxy_idx.isValid():
            return core.ModelIndex()
        row = proxy_idx.row()
        colcount = source.columnCount()
        return source.index(row // colcount, row % colcount)

    def mapFromSource(self, source_index: core.ModelIndex) -> core.ModelIndex:
        source = self.sourceModel()
        if source is None or not source_index.isValid():
            return core.ModelIndex()
        r = source_index.row() * source.columnCount() + source_index.column()
        return self.createIndex(r, 0, source_index.internalPointer())

    def set_header_title(self, title: str):
        self._header_title = title
        self.headerDataChanged.emit(constants.HORIZONTAL, 0, 0)

    def get_header_title(self) -> str:
        return self._header_title

    header_title = core.Property(
        str,
        get_header_title,
        set_header_title,
        doc="Column header for resulting column",
    )

⌗ Property table

Qt Property Type Doc
objectName QString
sourceModel QAbstractItemModel
header_title QString Column header for resulting column