pythonpyqt5qtreeviewqlayout

Layout in a QStandartItem for QTreeView


I am searching for a way to have a QTreeView that contains hierarchical items which themselfs have a layout that is propperly drawn.

I tried to inherit from both QStandartItem and QWidget (to have a layout) but the second i set the layout on the widget part of this class the programm is shutting down when it tries to render.

class modPackItem(qtg.QStandardItem,qtw.QWidget):
    def __init__(self,txt:str='',image_path:str='./assets/defaultModPack.jpg'):
        super().__init__()
    
        fnt = qtg.QFont('Calibri',12)
        fnt.setBold(True)
    
        self.setEditable(False)
        self.setForeground(qtg.QColor(0,0,0))
        self.setFont(fnt)
        self.setText(txt)
        self.horLayout = qtw.QHBoxLayout()
        self.horLayout.addWidget(qtw.QLabel("test"))
        #self.setLayout(self.horLayout) #this breaks the rendering
            
        modPack_image = qtg.QImage(image_path)        
        self.setData(modPack_image.scaled(64,64,qtc.Qt.AspectRatioMode.KeepAspectRatioByExpanding),qtc.Qt.ItemDataRole.DecorationRole)

Is there a possible way to have all items in the QTreeView contain layouts (For example with multiple texts[description,tag-words,etc]).

Example TreeView containing the desired custom item with layout

Note: I also considered switching to a simple List of widgets which have children containing the hierarchical items. But that would increase complexity of my app-structure a lot and therefore i would like to avoid that.

Edit: To clearify what i want to do: I want to build a mod(pack) manager in the style of the technic-launcher for minecraft mods but instead for any kind of game in any kind of infrastructure(steam, local instal,etc). By clicking different buttons i add new "modpacks" or "mods" (optimally custom QStandartItem with Layout for all the data) in an hierarchical fashion (therefore treeview). Adding the items and the steam-subsrciption or filecopy logic is no problem but i would like to see all infos (Name,descritpion, custom tags) on the overview (like in the example pic). I know i could bind the QStandartItem selection method to a new popup showing all infos but that would be inconvinient.

Edit2: On terms of implementation i just add the QStandartItem-object as an additional row to the root-node before setting the model. I allready tested adding new objects to the rootnode by clicking on a button and that worked fine. Just setting the layout in the object crashes the application at start.

class SteamModManager_Dialog(qtw.QDialog):
window: Ui_SteamModManagerFrame
treeModel: qtg.QStandardItemModel
rootNode: qtg.QStandardItem


def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

    self.window = Ui_SteamModManagerFrame()
    self.window.setupUi(self)

    self.window.label_footer.setText("")
    
    self.treeModel = qtg.QStandardItemModel()
    self.rootNode = self.treeModel.invisibleRootItem()
    
    modPack = modPackItem('Dont Starve Together')
    testMod = modItem("TestMod")
    
    modPack.appendRow(testMod)     
    
    self.rootNode.appendRow(modPack)   
    
    self.window.tView_modPacks.setModel(self.treeModel)
    self.window.tView_modPacks.expandAll()

Solution

  • On the behalf of @musicamente here the solution that worked out for me:

    I created a widget in the designer (as usual, not posting the full ui code here).

    Then i implemented the following code into the Dialog:

    self.treeModel = qtg.QStandardItemModel()
    self.rootNode = self.treeModel.invisibleRootItem()
        
    modPack = modPackItem('Dont Starve Together')
    testMod = modItem("TestMod")
       
    modPack.appendRow(testMod)     
        
    self.rootNode.appendRow(modPack)           
        
    self.window.tView_modPacks.setModel(self.treeModel)
    self.window.tView_modPacks.expandAll()
        
    modPackWidget = qtw.QWidget()
    ui = Ui_modPackWidget()
    ui.setupUi(modPackWidget)
        
    self.window.tView_modPacks.setIndexWidget(self.treeModel.index(0,0),modPackWidget)
    

    This code resulted setting the custom widget to the treeview item. Here the final look: Final Result TreeView Item with corresponding Widget containing a Layout