如何将 CSV 文件加载到 QTreeView 中? [英] How can I load a CSV file into a QTreeView?

查看:100
本文介绍了如何将 CSV 文件加载到 QTreeView 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我是一个完整的初学者.

Note: I am a complete beginner.

我正在使用 Pandas 数据框导入我从下表转换的 csv 文件.我需要将 csv 文件加载到 QTreeView 中,但一直无法这样做.

I am using a pandas dataframe to import a csv file that I converted from the following table. I need to load the csv file into a QTreeView and have been unable to do so.

输出格式应该是:

我将不得不检索比例类型";在某些时候,所以我想以某种方式将它标记为该项目,但我不确定这是否可能.我曾尝试将我的数据转换为 Pandas 数据框并加载;直接用csv加载数据;并将其转换为字典,但运气不佳.

I will have to retrieve the "Scale Type" at some point, so I would like to somehow tag it to that item, but I'm not sure if that is possible. I have tried converting my data into a pandas dataframe and loading; loading the data directly with a csv; and converting it into a dictionary with no luck.

我可以对该数据进行硬编码,但我更喜欢使用 csv,因为我以后可以轻松更改它.

I can hard-code that data in, but I would prefer to use a csv as I can easily change it later.

目前使用:

        model.setHeaderData(0,Qt.Horizontal,"Category")
        model.setHeaderData(1,Qt.Horizontal,"Sub Category")
        model.setHeaderData(2,Qt.Horizontal,"Test")
        self.ui.tv.setModel(model)
        self.SetContent(model)

    def SetContent(self, model):
        self.ui.tv.setModel(model)
        i=0

        for k,featuretype in features.items():
            parent1 = QStandardItem('{}'.format(k[1]))
            for item in featuretype:
                child = QStandardItem(item[0])
                if len(item[1])>0:
                    
                    for listitem in item[1]:
                        gchild=QStandardItem(listitem)
                        child.appendRow(gchild)
                parent1.appendRow(child)
            model.setItem(i,0,parent1)
            self.ui.tv.setFirstColumnSpanned(i,self.ui.tv.rootIndex(),True)
            i+=1

这仅在值是硬键时有效,例如:

This only works when values are hard keyed like:

features = {('POLYGON', 'SLPR'): [('ONE WAY', ['NO', 'YES','maybe'], 'List', 3), ('CLASS', ['州际公路', '主要', '住宅', '中学', '服务', '州高速公路', '高等教育', '轨道', '美国高速公路'], '列表', 11)]

但它不适用于我从 csv 或数据帧创建的字典对象,并且出现字符串索引超出范围错误".

But it doesn't work with dictionary objects I create from the csv or dataframe, and I get the "String Index out of Range Error".

我也找到了这段代码,那太好了.但它只给我重复和父母.

I also found this code, which would have been great. But it gives me duplicates and the parents only.

            reader = csv.reader(f)
            for row in reader:
                item = QTreeWidgetItem(self.ui.tv, row)
                print(row)

推荐答案

下面是一个演示脚本,它应该可以完成您所要求的大部分工作.它不能产生与第二个屏幕截图相同的布局,但结构是相同的.csv 文件转换为嵌套的 dicts/lists,可以保存到 json 文件中.也可以直接加载json文件.我假设您的 csv 文件如下所示:

Below is a demo script which should do most of what you asked for. It cannot quite produce the same layout as in your second screenshot, but the structure is the same. The csv file is converted to nested dicts/lists, which can be saved to a json file. It's also possible to load the json file directly. I assumed your csv file looks like this:

"Test Category","Sub Category","Test Type","Scale Type"
"Premorbid Func.","SIMPLE","Actual","Scale"
"Premorbid Func.","SIMPLE","Predicted","Scale"
"Premorbid Func.","COMPL Montanist","TEST","Scale"
"Premorbid Func.","COMPL Montanist","Actual","Scale"
"Premorbid Func.","COMPL Montanist","Predicted","Scale"
"Intellect","WAIS-IV","WAIS-IV","T Score"
"Intellect","WAIS-IV","VCI","T Score"
"Intellect","WAIS-IV","Similarities","T Score"
"Intellect","WAIS-IV","Vocabulary","T Score"
"Attention","TOVA","RT","Scale"
"Attention","TOVA","RTV","Scale"
"Attention","DV","T","T Score"

这里是树视图的样子:

演示脚本:

import sys, os, csv, json
from collections import defaultdict
from PyQt5 import QtCore, QtGui, QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.buttonLoad = QtWidgets.QPushButton('Load Data')
        self.buttonLoad.clicked.connect(self.handleProcessData)
        self.buttonSave = QtWidgets.QPushButton('Save Data')
        self.buttonSave.clicked.connect(self.handleSaveData)
        self.buttonSave.setEnabled(False)
        self.tree = QtWidgets.QTreeView()
        layout = QtWidgets.QGridLayout(self)
        layout.addWidget(self.tree, 0, 0, 1, 2)
        layout.addWidget(self.buttonLoad, 1, 0)
        layout.addWidget(self.buttonSave, 1, 1)
        self.data = None

    def loadData(self):
        path, ok = QtWidgets.QFileDialog.getOpenFileName(
            self, 'Open CSV/JSON', '.', filter='Data Files (*.csv *.json)')
        if ok:
            with open(path) as stream:
                if os.path.splitext(path)[1] == '.json':
                    self.data = json.load(stream)
                else:
                    reader = csv.reader(stream)
                    # ignore the header
                    next(reader)
                    # convert to nested dicts/lists
                    self.data = defaultdict(lambda: defaultdict(list))
                    for record in reader:
                        self.data[record[0]][record[1]].append(record[2:])

    def handleProcessData(self):
        self.loadData()
        if self.data is not None:
            model = QtGui.QStandardItemModel(self.tree)
            model.setHorizontalHeaderLabels(('Category', 'Type', 'Scale'))
            self.tree.setModel(model)
            self.tree.setColumnWidth(0, 200)
            root = self.tree.rootIndex()
            for row, (text, values) in enumerate(self.data.items()):
                category = QtGui.QStandardItem(text)
                model.appendRow(category)
                self.tree.setFirstColumnSpanned(row, root, True)
                for row, (text, values) in enumerate(values.items()):
                    subcategory = QtGui.QStandardItem(text)
                    for value in values:
                        subcategory.appendRow([
                            QtGui.QStandardItem(),
                            QtGui.QStandardItem(value[0]),
                            QtGui.QStandardItem(value[1]),
                            ])
                    category.appendRow(subcategory)
                    self.tree.setFirstColumnSpanned(
                        row, category.index(), True)
            self.tree.expandAll()
            self.buttonSave.setEnabled(True)

    def handleSaveData(self):
        path, ok = QtWidgets.QFileDialog.getSaveFileName(
            self, 'Save JSON', '.', filter='JSON Files (*.json)')
        if ok:
            with open(path, 'w') as stream:
                json.dump(self.data, stream, indent=2)


if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setWindowTitle('Test')
    window.setGeometry(600, 100, 540, 480)
    window.show()
    sys.exit(app.exec_())

这篇关于如何将 CSV 文件加载到 QTreeView 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆