Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Changing Font and background color of individual item in editable Treeview
Forum Updated to NodeBB v4.3 + New Features

Changing Font and background color of individual item in editable Treeview

Scheduled Pinned Locked Moved Solved Qt for Python
21 Posts 4 Posters 5.0k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Stan Pamela

    @SGaist yes, it's

    def data(self, index: QModelIndex, role: int = None):
        if not index.isValid():
            return None
    
        #if role == Qt.FontRole: # sorry please ignore! that was confusing...
        #   return item.data(index.column())
    
        if role != Qt.DisplayRole and role != Qt.EditRole:
            return None
    
        item: TreeItem = self.get_item(index)
    
        return item.data(index.column())
    

    which then goes to treeitem.py -> data

    def data(self, column: int):
        if column < 0 or column >= len(self.item_data):
            return None
        return self.item_data[column]
    

    in other words, it's wrapping a TreeItem to get item_data[column]. What would I need to target to return the font? or the style or background?

    SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #11

    @Stan-Pamela you are not passing the role down to your item data call.

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    S 1 Reply Last reply
    0
    • SGaistS SGaist

      @Stan-Pamela you are not passing the role down to your item data call.

      S Offline
      S Offline
      Stan Pamela
      wrote on last edited by
      #12

      @SGaist
      :)
      I can only reply every 600sec apparently because I'm a new user. I think you need to give me a "reputation" to be able to interact faster? :)

      Anyway, really sorry about last post, that was confusing, I was trying to edit the data function and copy pasted something that wasn't working...

      Still, these are the two functions that wrap around item_data

      def setData(self, index: QModelIndex, value, role: int) -> bool:
          if (role != Qt.EditRole) and (role != Qt.FontRole):
              return False
      
          item: TreeItem = self.get_item(index)
          result: bool = item.set_data(index.column(), value)
      
          if result:
              self.dataChanged.emit(index, index, [Qt.DisplayRole, Qt.EditRole, Qt.FontRole])
      
          return result
      

      and

      def set_data(self, column: int, value):
          if column < 0 or column >= len(self.item_data):
              return False
      
          self.item_data[column] = value
          return True
      
      SGaistS 1 Reply Last reply
      0
      • S Stan Pamela

        @SGaist
        :)
        I can only reply every 600sec apparently because I'm a new user. I think you need to give me a "reputation" to be able to interact faster? :)

        Anyway, really sorry about last post, that was confusing, I was trying to edit the data function and copy pasted something that wasn't working...

        Still, these are the two functions that wrap around item_data

        def setData(self, index: QModelIndex, value, role: int) -> bool:
            if (role != Qt.EditRole) and (role != Qt.FontRole):
                return False
        
            item: TreeItem = self.get_item(index)
            result: bool = item.set_data(index.column(), value)
        
            if result:
                self.dataChanged.emit(index, index, [Qt.DisplayRole, Qt.EditRole, Qt.FontRole])
        
            return result
        

        and

        def set_data(self, column: int, value):
            if column < 0 or column >= len(self.item_data):
                return False
        
            self.item_data[column] = value
            return True
        
        SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #13

        @Stan-Pamela that's another issue: you don't handle the role in your wrapper just the value.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        S 1 Reply Last reply
        1
        • SGaistS SGaist

          @Stan-Pamela that's another issue: you don't handle the role in your wrapper just the value.

          S Offline
          S Offline
          Stan Pamela
          wrote on last edited by
          #14

          @SGaist OK, how do I handle the role?
          Really sorry, I know this is probably so obvious to you all, but I just can't figure it out. It seems this treeview example is a corner case with all the wrappers, isn't it? Or it's just me?

          Still can't write more than every 600sec :( maybe just as well, ahah!

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #15

            Ok, I see the issue. The example works well for just handling "data".

            You need to modify your custom TreeItem to handle the role in addition to the value. As a basic version, you can use a dictionary where the key is the role and the item the value. Add a role parameter to the set_data and data methods so that you can properly set and retrieve these values.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            S 1 Reply Last reply
            0
            • SGaistS SGaist

              Ok, I see the issue. The example works well for just handling "data".

              You need to modify your custom TreeItem to handle the role in addition to the value. As a basic version, you can use a dictionary where the key is the role and the item the value. Add a role parameter to the set_data and data methods so that you can properly set and retrieve these values.

              S Offline
              S Offline
              Stan Pamela
              wrote on last edited by
              #16

              @SGaist

              Thanks again. I'm still not sure how to do that...
              Even for the "value" itself, could you explain how/where the final target TreeItem->item_data is set? This doesn't seem to be a standard Qt class/variable... I'm confused...

              At the very end of treeitem.py, in this editable tree example, there is this recursive function:

              def set_data(self, column: int, value):
                  if column < 0 or column >= len(self.item_data):
                      return False
              
                  self.item_data[column] = value
                  return True
              
              def __repr__(self) -> str:
                  result = f"<treeitem.TreeItem at 0x{id(self):x}"
                  for d in self.item_data:
                      result += f' "{d}"' if d else " <None>"
                  result += f", {len(self.child_items)} children>"
                  return result
              

              Is it this repr function that's used internally, in the backend of the Qt library, to display the text manually? Do I need to use a similar backend function for the role?

              SGaistS 1 Reply Last reply
              0
              • S Stan Pamela

                @SGaist

                Thanks again. I'm still not sure how to do that...
                Even for the "value" itself, could you explain how/where the final target TreeItem->item_data is set? This doesn't seem to be a standard Qt class/variable... I'm confused...

                At the very end of treeitem.py, in this editable tree example, there is this recursive function:

                def set_data(self, column: int, value):
                    if column < 0 or column >= len(self.item_data):
                        return False
                
                    self.item_data[column] = value
                    return True
                
                def __repr__(self) -> str:
                    result = f"<treeitem.TreeItem at 0x{id(self):x}"
                    for d in self.item_data:
                        result += f' "{d}"' if d else " <None>"
                    result += f", {len(self.child_items)} children>"
                    return result
                

                Is it this repr function that's used internally, in the backend of the Qt library, to display the text manually? Do I need to use a similar backend function for the role?

                SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #17

                Basically:

                     def set_data(self, column: int, value, role):
                         if column < 0 or column >= len(self.item_data):
                             return False
                 
                         if column not in self.item_data.keys():
                             self.item_data[column] = {}
                         self.item_data[column][role] = value
                         return True
                

                Don't forget to handle the EditRole and Display role properly.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                S 1 Reply Last reply
                0
                • SGaistS SGaist

                  Basically:

                       def set_data(self, column: int, value, role):
                           if column < 0 or column >= len(self.item_data):
                               return False
                   
                           if column not in self.item_data.keys():
                               self.item_data[column] = {}
                           self.item_data[column][role] = value
                           return True
                  

                  Don't forget to handle the EditRole and Display role properly.

                  S Offline
                  S Offline
                  Stan Pamela
                  wrote on last edited by
                  #18

                  That doesn't work either. Or I'm not doing it properly(?)
                  Even ignoring the font role, and just trying to do the simplest thing possible: to use a dict like this for the text edit alone, and replace the original functionality, it doesn't work:

                  def set_data(self, column: int, value):
                      if column < 0 or column >= len(self.item_data):
                          return False
                  
                      #self.item_data[column] = value
                      self.item_data[column] = {Qt.EditRole: value}
                  
                  SGaistS 1 Reply Last reply
                  0
                  • S Stan Pamela

                    That doesn't work either. Or I'm not doing it properly(?)
                    Even ignoring the font role, and just trying to do the simplest thing possible: to use a dict like this for the text edit alone, and replace the original functionality, it doesn't work:

                    def set_data(self, column: int, value):
                        if column < 0 or column >= len(self.item_data):
                            return False
                    
                        #self.item_data[column] = value
                        self.item_data[column] = {Qt.EditRole: value}
                    
                    SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #19

                    @Stan-Pamela did you adapt the data function in a similar fashion ?

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    S 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      @Stan-Pamela did you adapt the data function in a similar fashion ?

                      S Offline
                      S Offline
                      Stan Pamela
                      wrote on last edited by
                      #20

                      @SGaist, got it!
                      Thanks so much and sorry it took me so long to understand the trail of wrappers and how that feeds back into the main model. Awesome. I did it in a dirty way for now, but shall I clean up and post a zip of the code for consistency and closure of this forum thread?

                      Screenshot 2024-01-24 at 22.19.29.png

                      S 1 Reply Last reply
                      0
                      • S Stan Pamela

                        @SGaist, got it!
                        Thanks so much and sorry it took me so long to understand the trail of wrappers and how that feeds back into the main model. Awesome. I did it in a dirty way for now, but shall I clean up and post a zip of the code for consistency and closure of this forum thread?

                        Screenshot 2024-01-24 at 22.19.29.png

                        S Offline
                        S Offline
                        Stan Pamela
                        wrote on last edited by
                        #21

                        Thanks again so much @SGaist , @friedemannkleint and @mpergand for the help and patience. Just for the record, here are the details for a working example, based on the original https://doc.qt.io/qtforpython-6/examples/example_widgets_itemviews_editabletreemodel.html

                        ======================
                        mainwindow.py:

                        # Copyright (C) 2022 The Qt Company Ltd.
                        # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
                        
                        import sys
                        from pathlib import Path
                        
                        from PySide6.QtCore import (QAbstractItemModel, QItemSelectionModel,
                                                    QModelIndex, Qt, Slot)
                        from PySide6.QtWidgets import (QAbstractItemView, QMainWindow, QTreeView,
                                                       QWidget)
                        from PySide6.QtGui import QFont
                        from PySide6.QtTest import QAbstractItemModelTester
                        
                        from treemodel import TreeModel
                        
                        
                        class MainWindow(QMainWindow):
                            def __init__(self, parent: QWidget = None):
                                super().__init__(parent)
                                self.resize(573, 468)
                        
                                self.view = QTreeView()
                                self.view.setAlternatingRowColors(True)
                                self.view.setSelectionBehavior(QAbstractItemView.SelectItems)
                                self.view.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
                                self.view.setAnimated(False)
                                self.view.setAllColumnsShowFocus(True)
                                self.setCentralWidget(self.view)
                        
                                menubar = self.menuBar()
                                file_menu = menubar.addMenu("&File")
                                self.exit_action = file_menu.addAction("E&xit")
                                self.exit_action.setShortcut("Ctrl+Q")
                                self.exit_action.triggered.connect(self.close)
                        
                                actions_menu = menubar.addMenu("&Actions")
                                actions_menu.triggered.connect(self.update_actions)
                                self.insert_row_action = actions_menu.addAction("Insert Row")
                                self.insert_row_action.setShortcut("Ctrl+I, R")
                                self.insert_row_action.triggered.connect(self.insert_row)
                                self.insert_column_action = actions_menu.addAction("Insert Column")
                                self.insert_column_action.setShortcut("Ctrl+I, C")
                                self.insert_column_action.triggered.connect(self.insert_column)
                                actions_menu.addSeparator()
                                self.remove_row_action = actions_menu.addAction("Remove Row")
                                self.remove_row_action.setShortcut("Ctrl+R, R")
                                self.remove_row_action.triggered.connect(self.remove_row)
                                self.remove_column_action = actions_menu.addAction("Remove Column")
                                self.remove_column_action.setShortcut("Ctrl+R, C")
                                self.remove_column_action.triggered.connect(self.remove_column)
                                actions_menu.addSeparator()
                                self.insert_child_action = actions_menu.addAction("Insert Child")
                                self.insert_child_action.setShortcut("Ctrl+N")
                                self.insert_child_action.triggered.connect(self.insert_child)
                                help_menu = menubar.addMenu("&Help")
                                about_qt_action = help_menu.addAction("About Qt", qApp.aboutQt)
                                about_qt_action.setShortcut("F1")
                        
                                self.setWindowTitle("Editable Tree Model")
                        
                                headers = ["Title", "Description"]
                        
                                file = Path(__file__).parent / "default.txt"
                                self.model = TreeModel(headers, file.read_text(), self)
                        
                                if "-t" in sys.argv:
                                    QAbstractItemModelTester(self.model, self)
                                self.view.setModel(self.model)
                                self.view.expandAll()
                        
                                for column in range(self.model.columnCount()):
                                    self.view.resizeColumnToContents(column)
                        
                                selection_model = self.view.selectionModel()
                                selection_model.selectionChanged.connect(self.update_actions)
                        
                                self.update_actions()
                        
                            @Slot()
                            def insert_child(self) -> None:
                                selection_model = self.view.selectionModel()
                                index: QModelIndex = selection_model.currentIndex()
                                model: QAbstractItemModel = self.view.model()
                        
                                if model.columnCount(index) == 0:
                                    if not model.insertColumn(0, index):
                                        return
                        
                                if not model.insertRow(0, index):
                                    return
                        
                                for column in range(model.columnCount(index)):
                                    child: QModelIndex = model.index(0, column, index)
                                    model.setData(child, "[No data]", Qt.EditRole)
                                    if not model.headerData(column, Qt.Horizontal):
                                        model.setHeaderData(column, Qt.Horizontal, "[No header]",
                                                            Qt.EditRole)
                        
                                selection_model.setCurrentIndex(
                                    model.index(0, 0, index), QItemSelectionModel.ClearAndSelect
                                )
                                self.update_actions()
                        
                            @Slot()
                            def insert_column(self) -> None:
                                model: QAbstractItemModel = self.view.model()
                                column: int = self.view.selectionModel().currentIndex().column()
                        
                                changed: bool = model.insertColumn(column + 1)
                                if changed:
                                    model.setHeaderData(column + 1, Qt.Horizontal, "[No header]",
                                                        Qt.EditRole)
                        
                                self.update_actions()
                        
                            @Slot()
                            def insert_row(self) -> None:
                                index: QModelIndex = self.view.selectionModel().currentIndex()
                                model: QAbstractItemModel = self.view.model()
                                parent: QModelIndex = index.parent()
                        
                                if not model.insertRow(index.row() + 1, parent):
                                    return
                        
                                self.update_actions()
                        
                                for column in range(model.columnCount(parent)):
                                    child: QModelIndex = model.index(index.row() + 1, column, parent)
                                    model.setData(child, "[No data]", Qt.EditRole)
                        
                            @Slot()
                            def remove_column(self) -> None:
                                model: QAbstractItemModel = self.view.model()
                                column: int = self.view.selectionModel().currentIndex().column()
                        
                                if model.removeColumn(column):
                                    self.update_actions()
                        
                            @Slot()
                            def remove_row(self) -> None:
                                index: QModelIndex = self.view.selectionModel().currentIndex()
                                model: QAbstractItemModel = self.view.model()
                        
                                if model.removeRow(index.row(), index.parent()):
                                    self.update_actions()
                        
                            @Slot()
                            def update_actions(self) -> None:
                                selection_model = self.view.selectionModel()
                                has_selection: bool = not selection_model.selection().isEmpty()
                                self.remove_row_action.setEnabled(has_selection)
                                self.remove_column_action.setEnabled(has_selection)
                        
                                current_index = selection_model.currentIndex()
                                has_current: bool = current_index.isValid()
                                self.insert_row_action.setEnabled(has_current)
                                self.insert_column_action.setEnabled(has_current)
                        
                                model: QAbstractItemModel = self.view.model()
                                newFont = QFont("Times New Roman", 20, QFont.Bold)
                                newFont.setItalic(True)
                                model.setData(current_index, newFont, role=Qt.FontRole)
                        
                                if has_current:
                                    self.view.closePersistentEditor(current_index)
                                    msg = f"Position: ({current_index.row()},{current_index.column()})"
                                    if not current_index.parent().isValid():
                                        msg += " in top level"
                                    self.statusBar().showMessage(msg)
                        

                        ======================
                        treeitem.py:

                        # Copyright (C) 2022 The Qt Company Ltd.
                        # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
                        
                        
                        class TreeItem:
                            def __init__(self, data: list, parent: 'TreeItem' = None):
                                self.item_data = data
                                self.item_font = [None] * len(data)
                                self.parent_item = parent
                                self.child_items = []
                        
                            def child(self, number: int) -> 'TreeItem':
                                if number < 0 or number >= len(self.child_items):
                                    return None
                                return self.child_items[number]
                        
                            def last_child(self):
                                return self.child_items[-1] if self.child_items else None
                        
                            def child_count(self) -> int:
                                return len(self.child_items)
                        
                            def child_number(self) -> int:
                                if self.parent_item:
                                    return self.parent_item.child_items.index(self)
                                return 0
                        
                            def column_count(self) -> int:
                                return len(self.item_data)
                        
                            def font(self, column: int):
                                if column < 0 or column >= len(self.item_data):
                                    return None
                                return self.item_font[column]
                        
                            def data(self, column: int):
                                if column < 0 or column >= len(self.item_data):
                                    return None
                                return self.item_data[column]
                        
                            def insert_children(self, position: int, count: int, columns: int) -> bool:
                                if position < 0 or position > len(self.child_items):
                                    return False
                        
                                for row in range(count):
                                    data = [None] * columns
                                    item = TreeItem(data.copy(), self)
                                    self.child_items.insert(position, item)
                        
                                return True
                        
                            def insert_columns(self, position: int, columns: int) -> bool:
                                if position < 0 or position > len(self.item_data):
                                    return False
                        
                                for column in range(columns):
                                    self.item_data.insert(position, None)
                        
                                for child in self.child_items:
                                    child.insert_columns(position, columns)
                        
                                return True
                        
                            def parent(self):
                                return self.parent_item
                        
                            def remove_children(self, position: int, count: int) -> bool:
                                if position < 0 or position + count > len(self.child_items):
                                    return False
                        
                                for row in range(count):
                                    self.child_items.pop(position)
                        
                                return True
                        
                            def remove_columns(self, position: int, columns: int) -> bool:
                                if position < 0 or position + columns > len(self.item_data):
                                    return False
                        
                                for column in range(columns):
                                    self.item_data.pop(position)
                        
                                for child in self.child_items:
                                    child.remove_columns(position, columns)
                        
                                return True
                        
                            def set_font(self, column: int, value):
                                if column < 0 or column >= len(self.item_data):
                                    return False
                        
                                self.item_font[column] = value
                                return True
                        
                            def set_data(self, column: int, value):
                                if column < 0 or column >= len(self.item_data):
                                    return False
                        
                                self.item_data[column] = value
                                return True
                        
                            def __repr__(self) -> str:
                                result = f"<treeitem.TreeItem at 0x{id(self):x}"
                                for d in self.item_data:
                                    result += f' "{d}"' if d else " <None>"
                                result += f", {len(self.child_items)} children>"
                                return result
                        

                        ======================
                        treemodel.py:

                        # Copyright (C) 2022 The Qt Company Ltd.
                        # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
                        
                        
                        from PySide6.QtCore import QModelIndex, Qt, QAbstractItemModel
                        from treeitem import TreeItem
                        
                        
                        class TreeModel(QAbstractItemModel):
                        
                            def __init__(self, headers: list, data: str, parent=None):
                                super().__init__(parent)
                        
                                self.root_data = headers
                                self.root_item = TreeItem(self.root_data.copy())
                                self.setup_model_data(data.split("\n"), self.root_item)
                        
                            def columnCount(self, parent: QModelIndex = None) -> int:
                                return self.root_item.column_count()
                        
                            def data(self, index: QModelIndex, role: int = None):
                                if not index.isValid():
                                    return None
                        
                                if role != Qt.DisplayRole and role != Qt.EditRole and role != Qt.FontRole:
                                    return None
                        
                                item: TreeItem = self.get_item(index)
                        
                                if role == Qt.FontRole:
                                    return item.font(index.column())
                        
                                return item.data(index.column())
                        
                            def flags(self, index: QModelIndex) -> Qt.ItemFlags:
                                if not index.isValid():
                                    return Qt.NoItemFlags
                        
                                return Qt.ItemIsEditable | QAbstractItemModel.flags(self, index)
                        
                            def get_item(self, index: QModelIndex = QModelIndex()) -> TreeItem:
                                if index.isValid():
                                    item: TreeItem = index.internalPointer()
                                    if item:
                                        return item
                        
                                return self.root_item
                        
                            def headerData(self, section: int, orientation: Qt.Orientation,
                                           role: int = Qt.DisplayRole):
                                if orientation == Qt.Horizontal and role == Qt.DisplayRole:
                                    return self.root_item.data(section)
                        
                                return None
                        
                            def index(self, row: int, column: int, parent: QModelIndex = QModelIndex()) -> QModelIndex:
                                if parent.isValid() and parent.column() != 0:
                                    return QModelIndex()
                        
                                parent_item: TreeItem = self.get_item(parent)
                                if not parent_item:
                                    return QModelIndex()
                        
                                child_item: TreeItem = parent_item.child(row)
                                if child_item:
                                    return self.createIndex(row, column, child_item)
                                return QModelIndex()
                        
                            def insertColumns(self, position: int, columns: int,
                                              parent: QModelIndex = QModelIndex()) -> bool:
                                self.beginInsertColumns(parent, position, position + columns - 1)
                                success: bool = self.root_item.insert_columns(position, columns)
                                self.endInsertColumns()
                        
                                return success
                        
                            def insertRows(self, position: int, rows: int,
                                           parent: QModelIndex = QModelIndex()) -> bool:
                                parent_item: TreeItem = self.get_item(parent)
                                if not parent_item:
                                    return False
                        
                                self.beginInsertRows(parent, position, position + rows - 1)
                                column_count = self.root_item.column_count()
                                success: bool = parent_item.insert_children(position, rows, column_count)
                                self.endInsertRows()
                        
                                return success
                        
                            def parent(self, index: QModelIndex = QModelIndex()) -> QModelIndex:
                                if not index.isValid():
                                    return QModelIndex()
                        
                                child_item: TreeItem = self.get_item(index)
                                if child_item:
                                    parent_item: TreeItem = child_item.parent()
                                else:
                                    parent_item = None
                        
                                if parent_item == self.root_item or not parent_item:
                                    return QModelIndex()
                        
                                return self.createIndex(parent_item.child_number(), 0, parent_item)
                        
                            def removeColumns(self, position: int, columns: int,
                                              parent: QModelIndex = QModelIndex()) -> bool:
                                self.beginRemoveColumns(parent, position, position + columns - 1)
                                success: bool = self.root_item.remove_columns(position, columns)
                                self.endRemoveColumns()
                        
                                if self.root_item.column_count() == 0:
                                    self.removeRows(0, self.rowCount())
                        
                                return success
                        
                            def removeRows(self, position: int, rows: int,
                                           parent: QModelIndex = QModelIndex()) -> bool:
                                parent_item: TreeItem = self.get_item(parent)
                                if not parent_item:
                                    return False
                        
                                self.beginRemoveRows(parent, position, position + rows - 1)
                                success: bool = parent_item.remove_children(position, rows)
                                self.endRemoveRows()
                        
                                return success
                        
                            def rowCount(self, parent: QModelIndex = QModelIndex()) -> int:
                                if parent.isValid() and parent.column() > 0:
                                    return 0
                        
                                parent_item: TreeItem = self.get_item(parent)
                                if not parent_item:
                                    return 0
                                return parent_item.child_count()
                        
                            def setData(self, index: QModelIndex, value, role: int) -> bool:
                                if (role != Qt.EditRole) and (role != Qt.FontRole):
                                    return False
                        
                                item: TreeItem = self.get_item(index)
                                if role == Qt.FontRole:
                                    result: bool = item.set_font(index.column(), value)
                                else:
                                    result: bool = item.set_data(index.column(), value)
                        
                                if result:
                                    self.dataChanged.emit(index, index, [Qt.DisplayRole, Qt.EditRole, Qt.FontRole])
                        
                                return result
                        
                            def setHeaderData(self, section: int, orientation: Qt.Orientation, value,
                                              role: int = None) -> bool:
                                if role != Qt.EditRole or orientation != Qt.Horizontal:
                                    return False
                        
                                result: bool = self.root_item.set_data(section, value)
                        
                                if result:
                                    self.headerDataChanged.emit(orientation, section, section)
                        
                                return result
                        
                            def setup_model_data(self, lines: list, parent: TreeItem):
                                parents = [parent]
                                indentations = [0]
                        
                                for line in lines:
                                    line = line.rstrip()
                                    if line and "\t" in line:
                        
                                        position = 0
                                        while position < len(line):
                                            if line[position] != " ":
                                                break
                                            position += 1
                        
                                        column_data = line[position:].split("\t")
                                        column_data = [string for string in column_data if string]
                        
                                        if position > indentations[-1]:
                                            if parents[-1].child_count() > 0:
                                                parents.append(parents[-1].last_child())
                                                indentations.append(position)
                                        else:
                                            while position < indentations[-1] and parents:
                                                parents.pop()
                                                indentations.pop()
                        
                                        parent: TreeItem = parents[-1]
                                        col_count = self.root_item.column_count()
                                        parent.insert_children(parent.child_count(), 1, col_count)
                        
                                        for column in range(len(column_data)):
                                            child = parent.last_child()
                                            child.set_data(column, column_data[column])
                        
                            def _repr_recursion(self, item: TreeItem, indent: int = 0) -> str:
                                result = " " * indent + repr(item) + "\n"
                                for child in item.child_items:
                                    result += self._repr_recursion(child, indent + 2)
                                return result
                        
                            def __repr__(self) -> str:
                                return self._repr_recursion(self.root_item)
                        
                        1 Reply Last reply
                        0
                        • S Stan Pamela has marked this topic as solved on

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved