![](/img/trans.png)
[英]Can I use python to open an XML file, format it, then save it again?
[英]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.