PDA

View Full Version : QTreeView: How to create objects from root items?



ficaras0
23rd June 2015, 20:17
Given a QTreeView that is supplied with a QStandardItemModel is it possible to create an object out of each root item in the model where all parent items linked to each root are contained in the created object? Furthermore, given a QTreeView set up with a model is it possible to save or access all data within the model, i assume yes by iterating somehow but the documentation at this point is just not helping; it leaves a lot unanswered if your a newbie. I've read all the documentation on QAbstractItemModel, QStandardItemModel, QTreeView, QAbstractItemView. I've read about the mimeData, mimeTypes, index, data, parent, rowCount, columnCount, createIndex et cetera methods in detail many times. Below i posted the code i have been using to experiment in hopes of figuring this stuff out. I auto add data when it's initialized to speed up the testing process but you can also add roots but entering text in the root box and pressing enter. To enter a parent enter text in parent box then click the item you would like it added to.

This code is ready to run no outside resources needed besides the obvious, paste into an IDE and run. A pre-built model is loaded.


# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Tree2.ui'
#
# Created: Thu Jun 18 17:54:24 2015
# by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!
import sys
from PyQt4 import QtCore, QtGui

try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s

try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)

data1 = [("Name", [("a",[]), ("b",[]), ("c", [("e",[]), ("f", []) ])])]


class Ui_MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setupUi(self)
self.indyTracker = 1
self. stringBuilder = None
self.boole = False
self.treeBuilder = {}
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(437, 529)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.verticalLayout_2 = QtGui.QVBoxLayout(self.centralwidget)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))


self.treeView = QtGui.QTreeView(self.centralwidget)
self.treeView.setObjectName(_fromUtf8("treeView"))
self.model = QtGui.QStandardItemModel()
self.addItems(self.model, data1)
self.treeView.setModel(self.model)
self.model.setHorizontalHeaderLabels([self.tr("ROOT")])


self.verticalLayout.addWidget(self.treeView)
self.lineEdit_2 = QtGui.QLineEdit(self.centralwidget)
self.lineEdit_2.setObjectName(_fromUtf8("lineEdit_2"))
self.verticalLayout.addWidget(self.lineEdit_2)
self.lineEdit = QtGui.QLineEdit(self.centralwidget)
self.lineEdit.setText(_fromUtf8(""))
self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
self.verticalLayout.addWidget(self.lineEdit)
self.label = QtGui.QLabel(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label.sizePolicy ().hasHeightForWidth())
self.label.setSizePolicy(sizePolicy)
self.label.setAutoFillBackground(True)
self.label.setFrameShape(QtGui.QFrame.Box)
self.label.setFrameShadow(QtGui.QFrame.Raised)
self.label.setLineWidth(3)
self.label.setMidLineWidth(1)
self.label.setText(_fromUtf8(""))
self.label.setWordWrap(True)
self.label.setOpenExternalLinks(True)
self.label.setObjectName(_fromUtf8("label"))
self.verticalLayout.addWidget(self.label)
self.verticalLayout_2.addLayout(self.verticalLayou t)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 437, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)

self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.lineEdit_2.setPlaceholderText(_translate("MainWindow", "Parent/Child - Press return to Add", None))
self.lineEdit.setPlaceholderText(_translate("MainWindow", "Root Index - Press Return to Add", None))

self.lineEdit.returnPressed.connect(self.addAROOT)
self.treeView.clicked.connect(self.addParents)
#self.treeView.clicked.connect(self.modelIndexDefi ner)
self.treeView.clicked.connect(self.createIndex)



def addAROOT(self):
parent = self.lineEdit.text()
self.model.appendRow(QtGui.QStandardItem(parent))

@QtCore.pyqtSlot(QtCore.QAbstractItemModel)
def addParents(self, index):
selectedItem = index.model().itemFromIndex(index)
if self.lineEdit_2.text() == "":
errorHandle()
else:
selectedItem.appendRow(QtGui.QStandardItem(self.li neEdit_2.text()))
self.lineEdit.clear()
self.lineEdit_2.clear()




@QtCore.pyqtSlot(QtCore.QAbstractItemModel)
def modelIndexDefiner(self, index):
childFlag = index.model().hasChildren(index)
currentIndex = index.parent()
currentItem = index.data()
originalItem = currentItem



@QtCore.pyqtSlot(QtCore.QAbstractItemModel)
def createIndex(self, index):
selectedItem1 = index.model().itemFromIndex(index)
selectedItem2 = index.parent()
getRow = selectedItem1.rowCount()
getColumn = selectedItem1.columnCount()
if not selectedItem2.isValid():
self.label.setText(("\t" + selectedItem1.text() + "\t" + str(getRow) + "\t" + str(getColumn))
+ "\n" + "\tROOT")
else:
self.label.setText(("\t" + selectedItem1.text() + "\t" + str(getRow) + "\t" + str(getColumn))
+ "\n\tPARENT")

@QtCore.pyqtSlot(QtCore.QAbstractItemModel)
def createRoot(self, index):
self.selectedItem = index.model().itemFromIndex(index)
self.parentCheck = index.parent()
if not self.parentCheck.isValid():
print("ROOT")



def addItems(self, parent, elements):

for text, children in elements:
item = QtGui.QStandardItem(text)
parent.appendRow(item)
if children:
self.addItems(item, children)
class errorHandle():
def __init__(self):
pass





if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWin = Ui_MainWindow()
mainWin.show()
sys.exit(app.exec())

anda_skoa
23rd June 2015, 21:07
Given a QTreeView that is supplied with a QStandardItemModel is it possible to create an object out of each root item in the model where all parent items linked to each root are contained in the created object?

No idea what you mean.
Maybe provide an example of the tree and the desired result?



Furthermore, given a QTreeView set up with a model is it possible to save or access all data within the model

1) You start with the invalid model index.
2) You ask the model for the row count using that index
3) You iterate over the range from 0 to row count, asking the model for the index with the model index you already have as a parent
4) You recurse with the new index, go to (2)

Cheers,
_

ficaras0
23rd June 2015, 21:31
I will edit with a comparison to make it more clear, also giving your solution a try.

Added after 19 minutes:


asking the model for the index with the model index you already have as a parent

This is the only part i'm not quite understanding, what you say makes sense i just don't understand how to implement it.
Where would i go from here


@QtCore.pyqtSlot(QtCore.QAbstractItemModel)
def createRoot(self, index, parent = QtCore.QModelIndex()):
self.selectedItem = index.model().itemFromIndex(index)
self.parentCheck = index.parent()
self.modelIdx = index.model()
if not self.parentCheck.isValid():
rowCount = self.selectedItem.rowCount()
for child in range(0, rowCount):

anda_skoa
24th June 2015, 09:05
I am not sure what your code snippet is supposed to do, but it is not what I described.

1) create a function that gets a QModelndex as its argument
2) in that function call the model's rowCount() with the given argument
3) loop over the range of rows
4) in the loop get the index for the current row
5) call the function recursively

Cheers,
_