You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用QTreeView/QTreeWidget实现Rest API文件夹树GUI及数据模型构建

Solution for Building Folder Tree from REST API with QTreeWidget/QTreeView

Hey there! Let's solve this problem where you need to convert a flat list of file paths (from your REST API) into a hierarchical folder tree for both QTreeWidget and QTreeView. I'll walk you through implementations for both widgets, including how to parse the API response and build the tree structure.

First: Parse the API Response

First, let's handle the JSON data from your API. The response is a flat array of objects with name (full path) and size. We'll need to split each path into segments (e.g., /folder1/sub/file3.txt becomes ["folder1", "sub", "file3.txt"]) to build the hierarchy.

Here's how you might fetch and parse the data (using Python's requests for API calls):

import requests
import json

def fetch_folder_data():
    api_url = "YOUR_REST_API_ENDPOINT"
    response = requests.get(api_url)
    # Fix the sample JSON (note: your original sample uses semicolons instead of commas—make sure to correct that in actual API response!)
    data = json.loads(response.text.replace(";", ","))
    return data

Option 1: Build Tree with QTreeWidget

You mentioned you already have static data in QTreeWidget, so let's expand that to work with the API data. The key is a helper function that finds or creates parent nodes for each path segment.

Full Implementation Code

from PyQt5.QtWidgets import (QApplication, QMainWindow, QTreeWidget, 
                             QTreeWidgetItem, QVBoxLayout, QWidget, QPushButton)
import sys

class TreeWidgetWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTreeWidget Folder Tree")
        self.resize(400, 500)
        
        # Create UI
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        
        self.tree_widget = QTreeWidget()
        self.tree_widget.setColumnCount(2)
        self.tree_widget.setHeaderLabels(["Name", "Size"])
        layout.addWidget(self.tree_widget)
        
        load_btn = QPushButton("Load from API")
        load_btn.clicked.connect(self.load_tree_from_api)
        layout.addWidget(load_btn)
    
    def get_or_create_parent(self, parent_item, segment):
        """Helper to find existing parent item or create a new one"""
        for i in range(parent_item.childCount()):
            child = parent_item.child(i)
            if child.text(0) == segment:
                return child
        # Create new item if not found
        new_item = QTreeWidgetItem([segment])
        parent_item.addChild(new_item)
        return new_item
    
    def load_tree_from_api(self):
        # Clear existing tree
        self.tree_widget.clear()
        
        # Fetch data
        data = fetch_folder_data()
        root_item = self.tree_widget.invisibleRootItem()
        
        for item in data:
            full_path = item["name"]
            size = item["size"]
            # Split path into segments, ignore empty strings from leading /
            segments = [s for s in full_path.split("/") if s]
            
            current_parent = root_item
            # Create folders recursively
            for seg in segments[:-1]:
                current_parent = self.get_or_create_parent(current_parent, seg)
            # Add file item
            file_item = QTreeWidgetItem([segments[-1], size])
            current_parent.addChild(file_item)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = TreeWidgetWindow()
    window.show()
    sys.exit(app.exec_())

Option 2: Build Tree with QTreeView (using QStandardItemModel)

For QTreeView, we'll use QStandardItemModel to manage the data, which is more flexible for larger datasets or if you need to modify the data later. The logic is similar to QTreeWidget, but we work with model items instead of widget items.

Full Implementation Code

from PyQt5.QtWidgets import (QApplication, QMainWindow, QTreeView, 
                             QVBoxLayout, QWidget, QPushButton)
from PyQt5.QtGui import QStandardItemModel, QStandardItem
import sys

class TreeViewWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTreeView Folder Tree")
        self.resize(400, 500)
        
        # Create UI
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        
        self.model = QStandardItemModel()
        self.model.setHorizontalHeaderLabels(["Name", "Size"])
        self.tree_view = QTreeView()
        self.tree_view.setModel(self.model)
        layout.addWidget(self.tree_view)
        
        load_btn = QPushButton("Load from API")
        load_btn.clicked.connect(self.load_tree_from_api)
        layout.addWidget(load_btn)
    
    def get_or_create_parent(self, parent_item, segment):
        """Helper to find existing parent item or create a new one"""
        for row in range(parent_item.rowCount()):
            child_item = parent_item.child(row, 0)
            if child_item.text() == segment:
                return parent_item.child(row)
        # Create new folder item (only first column has name, second is empty)
        folder_name_item = QStandardItem(segment)
        folder_size_item = QStandardItem("")
        parent_item.appendRow([folder_name_item, folder_size_item])
        return parent_item.child(parent_item.rowCount() - 1)
    
    def load_tree_from_api(self):
        # Clear existing model
        self.model.clear()
        self.model.setHorizontalHeaderLabels(["Name", "Size"])
        
        # Fetch data
        data = fetch_folder_data()
        root_item = self.model.invisibleRootItem()
        
        for item in data:
            full_path = item["name"]
            size = item["size"]
            segments = [s for s in full_path.split("/") if s]
            
            current_parent = root_item
            # Create folders recursively
            for seg in segments[:-1]:
                current_parent = self.get_or_create_parent(current_parent, seg)
            # Add file item (both columns filled)
            file_name_item = QStandardItem(segments[-1])
            file_size_item = QStandardItem(size)
            current_parent.appendRow([file_name_item, file_size_item])

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = TreeViewWindow()
    window.show()
    sys.exit(app.exec_())

Key Notes

  • Path Handling: The split("/") gives us segments, but we filter out empty strings to avoid creating unnecessary root-level empty items (from the leading / in paths).
  • Helper Function: The get_or_create_parent function is the core—it ensures we don't duplicate folder nodes for the same path segment.
  • API Data Fix: Your sample JSON uses semicolons instead of commas—make sure your actual API returns valid JSON with commas!

内容的提问来源于stack exchange,提问作者kien bui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:25:37