У меня есть этот код, который работает до сих пор, чтобы иметь прямое древовидное представление файла xml:
from PyQt5.QtCore import QAbstractItemModel, QFile, QIODevice, QModelIndex, Qt
from PyQt5.QtWidgets import QApplication, QFileDialog, QMainWindow, QTreeView
from PyQt5.QtXml import QDomDocument, QDomElement
class DomItem(object):
def __init__(self, node, row, parent=None):
self.domNode = node
# Record the item's location within its parent.
self.rowNumber = row
self.parentItem = parent
self.childItems = {}
def node(self):
return self.domNode
def parent(self):
return self.parentItem
def child(self, i):
if i in self.childItems:
return self.childItems[i]
if 0 <= i < self.domNode.childNodes().count():
childNode = self.domNode.childNodes().item(i)
childItem = DomItem(childNode, i, self)
self.childItems[i] = childItem
return childItem
return None
def row(self):
return self.rowNumber
class DomModel(QAbstractItemModel):
def __init__(self, document, parent=None):
super(DomModel, self).__init__(parent)
self.domDocument = document
self.rootItem = DomItem(self.domDocument, 0)
def columnCount(self, parent):
# return 3
return 2
def data(self, index, role):
if not index.isValid():
return None
if role != Qt.DisplayRole:
return None
item = index.internalPointer()
node = item.node()
if index.column() == 0:
# print(node.nodeName())
if node.nodeName() != '#text':
return node.nodeName()
else:
return None
if index.column() == 1:
value = node.nodeValue()
if value is None:
return ''
else:
return ' '.join(node.nodeValue().split('\n'))
return None
def flags(self, index):
if not index.isValid():
return Qt.NoItemFlags
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def headerData(self, section, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
if section == 0:
return "Category"
if section == 1:
return "Name"
return None
def index(self, row, column, parent):
if not self.hasIndex(row, column, parent):
return QModelIndex()
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QModelIndex()
def parent(self, child):
if not child.isValid():
return QModelIndex()
childItem = child.internalPointer()
parentItem = childItem.parent()
if not parentItem or parentItem == self.rootItem:
return QModelIndex()
return self.createIndex(parentItem.row(), 0, parentItem)
def rowCount(self, parent):
if parent.column() > 0:
return 0
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
return parentItem.node().childNodes().count()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.fileMenu = self.menuBar().addMenu("&File")
self.fileMenu.addAction("&Open...", self.openFile, "Ctrl+O")
self.fileMenu.addAction("E&xit", self.close, "Ctrl+Q")
self.xmlPath = ""
self.model = DomModel(QDomDocument(), self)
self.view = QTreeView(self)
self.view.setModel(self.model)
self.setCentralWidget(self.view)
self.setWindowTitle("Simple DOM Model")
def openFile(self, filePath):
if filePath:
f = QFile(filePath)
if f.open(QIODevice.ReadOnly):
document = QDomDocument()
if document.setContent(f):
newModel = DomModel(document, self)
self.view.setModel(newModel)
self.view.expandAll()
self.model = newModel
self.xmlPath = filePath
f.close()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.resize(640, 480)
window.show()
window.openFile('your file full path')
sys.exit(app.exec_())
Файл xml:
<repoCoordinates>
<name>repostructuretrials</name>
<branches>master</branches>
<submodules>
<submodule_0>
<name>gameengine</name>
<branches>*master,remotes/origin/develop,remotes/origin/feature/NormalMappingAndTextureCombination,remotes/origin/feature/light,remotes/origin/feature/particleEmitter,remotes/origin/master</branches>
</submodule_0>
<submodule_1>
<name>GraphicEngineOpenGLBasics</name>
<branches>feature/shadows,*master,remotes/origin/develop,remotes/origin/feature/billboards,remotes/origin/feature/shadows,remotes/origin/master</branches>
</submodule_1>
</submodules>
</repoCoordinates>
И я получаю это:
Код большой, но не очень сложный. Моя проблема в том, что я хочу, чтобы каждое имя ветви было отдельным элементом в древовидной модели, и все значения, разделенные запятыми, являются единственным уникальным элементом для модели. Я попытался проанализировать xml и поиграть с классом QDomElement()
, пытаясь добавить дочерние элементы к моим узлам, чтобы иметь возможность выбирать каждую из ветвей отдельно.
Я хотел бы разделить все имена ветвей на "," и добавить эти узлы в мой DOM.
Любая помощь по этому вопросу будет мне очень признательна, а также любые советы по справиться с этим, если класс QDomDocument
не лучший способ.
Большое спасибо