PDA

View Full Version : How can I traverse all of the items in a QStandardItemModel



patrik08
23rd August 2008, 09:28
I need a model tree to save PDF Bookmark like QStandardItemModel
and this model must combine on anchorNames () on a QTextDocument

i need a model to validate anchorNames () at QTextDocument .....

at end i save the tree on this way:



<fo:bookmark-tree>
<fo:bookmark internal-destination="sec0" >
<fo:bookmark-title>Internal dest.0</fo:bookmark-title>
<fo:bookmark internal-destination="sec1" >
<fo:bookmark-title>Internal dest.1</fo:bookmark-title>
</fo:bookmark>
<fo:bookmark internal-destination="sec2" >
<fo:bookmark-title>Internal dest.2</fo:bookmark-title>
</fo:bookmark>
</fo:bookmark>
</fo:bookmark-tree>



I search a way to traverse or iterate all node from model
i find only this here ...

http://troll.no/developer/knowledgebase/faq.2007-10-04.3382815333/?searchterm=qstandarditemmodel

Is here other way?


on read xml-bookmark i make it so...




void BookMarkModelRead::openRootBookmark( const QDomElement e )
{
if (e.tagName() !="fo:bookmark-tree")
{
return;
}
foundTree = true;
model = new QStandardItemModel();
internalLinkFound.clear();
setHeader();
//////////////qDebug() << "### openRootBookmark -> " << e.tagName();
QDomElement child = e.firstChildElement("fo:bookmark");
while (!child.isNull()) {
model->invisibleRootItem()->appendRow(Compose(child,0));
child = child.nextSiblingElement("fo:bookmark");
}
}

QList<QStandardItem *> BookMarkModelRead::Compose( const QDomElement e , const int leveldeep )
{
Q_ASSERT ( e.tagName() == "fo:bookmark" );
treeLoop++;
QList<QStandardItem *> diritto;
QIcon icob = createBookColorIcon( Qt::darkRed );
QString txt = e.firstChildElement("fo:bookmark-title").text();
if (txt.size() < 2) {
txt = tr("No Title found!");
icob = createBookColorIcon( Qt::red );
}
const QString link = e.attribute("internal-destination","null");
internalLinkFound.append(link);
qDebug() << "### read -> " << txt << "-" << treeLoop;

QStandardItem *item0 = new QStandardItem(txt);
item0->setData(leveldeep,Qt::UserRole);
item0->setData(bold_base_font,Qt::FontRole);
item0->setIcon ( icob );
item0->setFlags( flags );

diritto.append(item0);

QStandardItem *item1 = new QStandardItem(link);
item1->setFlags( flags );
item1->setData(leveldeep,Qt::UserRole);

diritto.append(item1);

QStandardItem *item2 = new QStandardItem(QString("%1").arg(leveldeep));
item2->setFlags( Qt::ItemIsEnabled );
item2->setData(leveldeep,Qt::UserRole);

diritto.append(item2);

if (!e.firstChildElement("fo:bookmark").isNull() && leveldeep == 0 ) {
/* one level deep down child */
QDomElement child = e.firstChildElement("fo:bookmark");
while (!child.isNull()) {
if ( child.tagName() == "fo:bookmark") {
const QString nextlink = child.attribute("internal-destination","null");
if (!internalLinkFound.contains(nextlink)) {
diritto.first()->appendRow(Compose(child,leveldeep + 1));
}
}

child = child.nextSiblingElement();
}
} else if (!e.nextSiblingElement("fo:bookmark").isNull() && leveldeep > 0 ) {
/* same level is only next on deep */

}
return diritto;
}



and to read the model it is not possibel?
i can not use QTreeWidget / QTreeWidgetItem why ... i can not set a model at him...
only QTreeView can set a model .... i know only a way to use sqlite3 as model...
Must i use sqlite3 to traverse all tree? QStandardItemModel can not make this job..

the resut... is not possible to read back from QTreeView ...!! onewayQTreeView :-(

http://ppk.ciz.ch/MiniScribus/treebook.png

jacek
24th August 2008, 01:01
Pseudo code:

for i = rowCount() - 1 to 0:
push index( i, 0 )
while stack not empty:
pop idx from stack
process idx
if hasChildren( idx ):
for i = rowCount( idx ) - 1 to 0:
push index( i, 0, idx )

(this code assumes that you keep items as rows and columns just represent their properties)

patrik08
24th August 2008, 14:42
Ok i found a way to build a dom tree .. from a QStandardItemModel

a static function to retry child item



static QList<QStandardItem*> childList( QStandardItem *qi )
{
QStandardItemModel *pm = qi->model();
QList<QStandardItem*> rList;
QModelIndex in = qi->index();
if (!in.isValid()) {
return rList;
}
if (qi->rowCount() == 0) {
return rList;
}
for (int e = 0; e < qi->rowCount(); ++e) {
QModelIndex si = pm->index(e,qi->column(),in);
QStandardItem *iz = pm->itemFromIndex(si);
if (iz) {
rList << iz;
}
}
return rList;
}




and a class to build a xml




void BookTree::subIterate()
{
QStandardItemModel *pm = qobject_cast<QStandardItemModel *>(model());
if (!pm) {
return;
}
QStringList line;
int rw = 0;
int cw = 0;
int ctot = 0;
const int cools = pm->columnCount();
const int rows = pm->rowCount();
qDebug() << "-- iter ---------------------------------------------------------";
for (int i = 0; i < cools; ++i) {
const QString htxt = pm->headerData(i,Qt::Horizontal,Qt::DisplayRole).toStr ing();
const QString htxt1 = pm->headerData(i,Qt::Vertical,Qt::DisplayRole).toStrin g();
line << qMax(htxt,htxt1);
}
QList<QStandardItem*> list;
for (int e = 0; e < rows; ++e) {
QStandardItem *ix_1 = pm->item(e,0);
QStandardItem *ix_2 = pm->item(e,1);
list.clear();
list = childList(ix_1);
ctot = list.size();
int level = 0;
qDebug() << "# lev." << level <<" line " << e << " txt " << ix_1->text() << " child " << ctot;
if (ctot !=0) {

level++;
foreach (QStandardItem *ix,list) {
list.clear();
ctot = 0;
list = childList(ix);
ctot = list.size();
qDebug() << "# lev." << level <<" line " << e << " txt " << ix->text() << " child " << ctot;

}
}
}
qDebug() << "-- iter ---------------------------------------------------------";
}




now i must only transform the tree model -> flat like table to validate link...