Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将CSV文件加载到QTreeView中?_Python_Dataframe_Csv_Pyqt5_Qtreeview - Fatal编程技术网

Python 如何将CSV文件加载到QTreeView中?

Python 如何将CSV文件加载到QTreeView中?,python,dataframe,csv,pyqt5,qtreeview,Python,Dataframe,Csv,Pyqt5,Qtreeview,注:我是一个完全的初学者 我正在使用pandas数据框导入从下表转换的csv文件。我需要将csv文件加载到QTreeView中,但无法执行此操作 输出格式应为: 我将不得不在某个时候检索“Scale Type”,因此我想以某种方式将其标记到该项,但我不确定这是否可行。我已经尝试将我的数据转换成熊猫数据帧并加载;使用csv直接加载数据;并把它转换成一本字典,而不是运气 我可以硬编码的数据,但我更喜欢使用csv,因为我可以很容易地改变它以后 目前正在使用: model.setHe

注:我是一个完全的初学者

我正在使用pandas数据框导入从下表转换的csv文件。我需要将csv文件加载到QTreeView中,但无法执行此操作

输出格式应为:

我将不得不在某个时候检索“Scale Type”,因此我想以某种方式将其标记到该项,但我不确定这是否可行。我已经尝试将我的数据转换成熊猫数据帧并加载;使用csv直接加载数据;并把它转换成一本字典,而不是运气

我可以硬编码的数据,但我更喜欢使用csv,因为我可以很容易地改变它以后

目前正在使用:

        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
这仅适用于硬键控值的情况,如:

features={('POLYGON','SLPR'):[('ONE WAY',['NO','YES','maybe','List',3),('CLASS',['INTERSTATE','PRIMARY','RESIDENTIAL','SECONDARY','SERVICE','STATE HWY','treative','TRACK','US HWY','List',11)]

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

我还发现了这段代码,这将是非常棒的。但它只给了我副本和父母

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


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

"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、数据框或字典中转换这些内容?如果可以将类别和子类别嵌套在第一列中,我将在明天某个时候提供完整的答案。