簡體   English   中英

如何再次將TreeView中的文件另存為json文件?

[英]How can I save the file in TreeView as a json file again?

我可以以QTreeWidget形式顯示和編輯json文件。 如何再次在桌面上保存此已編輯的json文件。

我的目標是創建一個可以編輯的json編輯器

import json
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt

class ViewTree(QTreeWidget):
    def __init__(self, value):

        super().__init__()
        def fill_item(item, value):
            def new_item(parent, text, val=None):
                child = QTreeWidgetItem([text])
                child.setFlags(child.flags() | Qt.ItemIsEditable)
                fill_item(child, val)
                parent.addChild(child)
                child.setExpanded(True)
            if value is None: return
            elif isinstance(value, dict):
                for key, val in sorted(value.items()):
                    new_item(item, str(key), val)
            elif isinstance(value, (list, tuple)):
                for val in value:
                    text = (str(val) if not isinstance(val, (dict, list, tuple))
                            else '[%s]' % type(val).__name__)
                    new_item(item, text, val)
            else:
                new_item(item, str(value))

        fill_item(self.invisibleRootItem(), value)



if __name__ == '__main__':

    app = QApplication([])


    fname = QFileDialog.getOpenFileName()
    json_file=open(fname[0],"r")
    file=json.load(json_file)


    window = ViewTree(file)
    window.setGeometry(300, 100, 900, 600)
    window.show()
    app.exec_()

在此處輸入圖片說明

好的,我沒有方便的Json File來進行測試,但是我帶走了您的代碼並對其進行了一些轉換。 現在,當您在TreeWidget中進行任何更改時,您將同時處理JsonTable和TreeWidget,只需使用這些更改更新JsonTable。 這段代碼並不完整,您仍然必須自己呈現一些部分,但是它應該為您提供一個可靠的模板來構建,以及一些您可能沒有意識到的漂亮功能;)

import json
import argparse

from sys import exit as sysExit

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QTreeWidget, QFileDialog, QDockWidget, QAction

class MenuToolBar(QDockWidget):
    def __init__(self, MainWin):
        QDockWidget.__init__(self)
        self.MainWin = MainWin
        self.MainMenu = MainWin.menuBar()

        self.MenuActRef = {'OpnJsonAct':0,
                           'SavJsonAct':0}

        # ******* Create the File Menu *******
        self.FileMenu  = self.MainMenu.addMenu('File')

        # ******* Create File Menu Items *******
#        self.OpnJsonAct = QAction(QIcon('Images/open.ico'), '&Open', self)
        self.OpnJsonAct = QAction('&Open', self)
        self.OpnJsonAct.setShortcut("Ctrl+O")
        self.OpnJsonAct.setStatusTip('Open an Existing Json File')
        self.OpnJsonAct.triggered.connect(self.GetJsonFile)
        self.MenuActRef['OpnJsonAct'] = self.OpnJsonAct

#        self.SavJsonAct = QAction(QIcon('Images/save.ico'), '&Save', self)
        self.SavJsonAct = QAction('&Save', self)
        self.SavJsonAct.setShortcut("Ctrl+S")
        self.SavJsonAct.setStatusTip('Open an Existing Json File')
        self.SavJsonAct.triggered.connect(self.SaveJsonFile)
        self.MenuActRef['SavJsonAct'] = self.SavJsonAct

        # ******* Setup the File Menu *******
        self.FileMenu.addAction(self.OpnJsonAct)
        self.FileMenu.addSeparator()
        self.FileMenu.addAction(self.SavJsonAct)

    def GetJsonFile(self):
        self.MainWin.OpenFile()

    def SaveJsonFile(self):
        self.MainWin.SaveFile()

class ViewTree(QTreeWidget):
    def __init__(self, parent):
        QTreeWidget.__init__(self)

        self.MyParent = parent
        self.TreeRoot = self.invisibleRootItem()

   # Just to show you what a static method looks like
   # one that does not need a reference to self because
   # it does not use self -- non-essential you can 
   # delete this when you are done testing with it
    @staticmethod
    def PrintTree():
        print('Tree View Ready')

    def FillTree(self):
        if self.JSonTable is None:
            pass
        elif isinstance(self.JSonTable, dict):
            for key, val in sorted(self.JSonTable.items()):
                self.new_item(self.TreeRoot, str(key), val)
        elif isinstance(self.JSonTable, (list, tuple)):
            for val in self.JSonTable:
                text = (str(val) if not isinstance(val, (dict, list, tuple))
                        else '[%s]' % type(val).__name__)
                self.new_item(self.TreeRoot, text, val)
        else:
            self.new_item(self.TreeRoot, str(self.JSonTable))

    def new_item(self, text, val=None):
        child = QTreeWidgetItem([text])
        child.setFlags(child.flags() | Qt.ItemIsEditable)

        self.FillTree(child, val)
        self.addChild(child)

        child.setExpanded(True)

   # This is meant to capture the On Change Event for the QTreeWidget
    def OnChange(self):
        print('Handling Changes Here for:',self.MyParent.JSonTable)
      # This routine would update your JsonTable with any changes
      # that take place within your TreeWidget however I do not 
      # think this is the correct function name to capture that
      # event so you might have to research this one a bit to get
      # the appropriate name

class MainWindow(QMainWindow):
    def __init__(self, JsonFilePath):
        super(MainWindow, self).__init__()

        self.setWindowTitle('Json File Editor')
        self.setGeometry(300, 100, 900, 600)

        self.JsonFile = JsonFilePath
        self.JSonTable = None

        self.CenterPane = ViewTree(self)
        self.setCentralWidget(self.CenterPane)

        self.CenterPane.PrintTree()
# Rem'd out because I could not test this for you 
# However it should work or... it might need tweaks
#        if len(self.JsonFile) > 0:
#            self.LoadFile()
        self.MainMenu = MenuToolBar(self)

    def OpenFile():
        self.JsonFile = QFileDialog.getOpenFileName()
      # Do not recall if QFileDialog returns None or not so you need to check that
        if len(self.JsonFile) > 0:
            self.LoadFile()

    def LoadFile():
      # Note one should always validate that they have a valid file prior to opening it
      # isfile() -- and checking the file extension are two methods I use
        JsonData = open(self.JsonFile[0],"r")
        self.JSonTable = json.load(JsonData)

        self.CenterPane.FillTree(self.JSonTable)

    def SaveFile():
      # Either to a new file or overwriting the exiting file
      # but basically you are now just saving your JsonTable
      # to file -- you could just loop through it manually or
      # I think there are wheels already invented to handle
      # Json objects like this and print them out to a file
        print('Saving Jason File')

def CmdLine():
  # create Parser object 
    Parser = argparse.ArgumentParser(description = "Load this Json File - Given the full file path")

  # defining arguments for Parser object 
    Parser.add_argument('-f', '--filepath', type = str, help = "This specifies the full path and filename for the Json File.") 

  # parse the argument if any from standard input
    CmdLineVal = Parser.parse_args().filepath
    RetVal = ''
    if CmdLineVal != None:
        RetVal = CmdLineVal

    return RetVal

if __name__ == '__main__':
    JsonFilePath = CmdLine()

    MainThred = QApplication([])

    MainGUI = MainWindow(JsonFilePath)
    MainGUI.show()

    sysExit(MainThred.exec_())

最后一點,我沒有測試/驗證您的代碼,因為我假設您了解它的功能,並且將了解如果需要調整才能使用此框架,則應如何對其進行調整

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM