Tree
Lingfa Yang
QTreeWidgetItem:
Query:
Number of children?
| first/last/ index of child?
| parent?
| previousSibling
| nextSibling
Collect:
| name or text?
| All siblings?
| All sibling's names?
| All sibling names except me?
Build:
| Build a path up to the root?
| a path to its ancestor?
Find:
| Find the first direct child by name.
| A child of the given path?
| Find the first occurrence of the given child name, recursively
| treeWidget
QTreeWidget:
findItems
| invisibleRootItem
| createTreeWidgetItem recursively?
Tree Model/View/Edit:
Models
| Views
| Simple Delegates
| Structural Dialog Delegating
| Attributes Dialog Delegating
QTreeWidgetItem:
Number of children?
int count = parent->childCount();
|
first/last/ index of child?
QTreeWidgetItem *child = parent->child(index);
|
parent?
QTreeWidgetItem *parent = child->parent();
|
previousSibling?
QTreeWidgetItem *TreeWidget::previousSibling(QTreeWidgetItem *ref)
{
QTreeWidgetItem *parent = ref->parent();
if(! parent)
{
int index = this->indexOfTopLevelItem(ref);
// this is NOT decleared as a const. ?!
return topLevelItem(index-1);
}
int index = parent->indexOfChild(ref);
if(index == 0) // ref is the first child;
return parent; // 1st child's previousSibling be its parent
return parent->child(index-1);
}
|
nextSibling?
QTreeWidgetItem *TreeWidget::nextSibling(QTreeWidgetItem *ref)
{
QTreeWidgetItem *parent = ref->parent();
if(! parent)
{
int index = this->indexOfTopLevelItem(ref);
return topLevelItem(index+1);
}
int index = parent->indexOfChild(ref);
return parent->child(index+1);
}
|
name or text?
QString name = item->text(0); // first column
|
All siblings?
QList<QTreeWidgetItem *> TreeWidget::siblings(QTreeWidgetItem *item)
{
if(!item) return QList<QTreeWidgetItem *>(); // wrong argument
QList<QTreeWidgetItem *> list;
QTreeWidgetItem *parent = item->parent();
if(parent)
{
for(int i=0; i<parent->childCount(); ++i)
list << parent->child(i);
return list;
}
// otherwise, it is a top level item.
for(int i=0; i<topLevelItemCount(); ++i)
list << topLevelItem(i);
return list;
}
|
// New version:
QList<QTreeWidgetItem *> TreeWidget::siblings(QTreeWidgetItem *item)const
{
QList<QTreeWidgetItem *> list;
if(!item) return list; // wrong argument
QTreeWidgetItem *parent = item->parent();
if(!parent) // it is a top level item.
parent = invisibleRootItem(); // introduced in Qt 4.2.
for(int i=0; i<parent->childCount(); ++i)
list << parent->child(i);
return list;
}
|
All sibling's names?
QStringList TreeWidget::siblingNames(QTreeWidgetItem *item)const
{
QList<QTreeWidgetItem *> items = siblings(item);
QStringList names;
foreach(QTreeWidgetItem *item, items)
names << item->text(0);
return names;
}
|
All sibling names except me?
QStringList TreeWidget::siblingNamesNotMe(QTreeWidgetItem *item)const
{
if(!item) return QStringList (); // wrong argument
QStringList list;
QTreeWidgetItem *parent = item->parent();
if(parent)
{
for(int i=0; i<parent->childCount(); ++i)
{
if(parent->child(i) == item) continue;
list << parent->child(i)->text(0);
}
return list;
}
// otherwise, it is a top level item.
for(int i=0; i<topLevelItemCount(); ++i)
{
if(topLevelItem(i) == item) continue;
list << topLevelItem(i)->text(0);
}return list;
}
|
Build a path up to the root?
QString sfm::rootPath(QTreeWidgetItem *item)
{
QTreeWidgetItem *p = item;
QString path;
while(p)
{
path = path.prepend(p->text(0) + "/");
p = p->parent();
}
return path;
}
|
a path to its ancestor?
QString sfm::pathTo(QTreeWidgetItem *item, QTreeWidgetItem *parent)
{
QTreeWidgetItem *p = item;
QString path;
while(p)
{
path = path.prepend(p->text(0) + "/");
if(p == parent) break;
p = p->parent();
}
return path;
}
|
Find the first direct child by name.
QTreeWidgetItem *sfm::firstDirectChild(
const QTreeWidgetItem *parent, const QString &name)
{
if(!parent)return NULL; // invalid input
int count = parent->childCount();
for(int i=0; i<count; ++i)
{
if(parent->child(i)->text(0) == name) // found
return parent->child(i);
}
return NULL; // not found
}
|
A child of the given path?
QTreeWidgetItem *sfm::findChild(
QTreeWidgetItem *parent, const QString &path)
{
if(path.isEmpty()) return NULL; // input problem
QStringList list(path.split("/",QString::SkipEmptyParts));
QString text = list.at(0);
QTreeWidgetItem *item = parent;
if(item->text(0) != text)
return NULL;
for(int i=1; i<list.size(); ++i)
{
item = firstDirectChild(item, list.at(i));
if(!item) return NULL; // Fail to match
}
return item;
}
|
Find the first occurrence of the given child name, recursively
QTreeWidgetItem *sfm::firstChild(
QTreeWidgetItem *parent, const QString &name)
{
if(!parent)return NULL; // invalid input
int count = parent->childCount();
QTreeWidgetItem *p = parent;
for(int i=0; i<count; ++i)
{
QTreeWidgetItem *child = firstChild(p, name); // recursion
if(child) // found
return child;
child = p->child(i);
if(child->text(0) == name) // found
return child;
}
return NULL; // not found after recursion
}
|
treeWidget?
QTreeWidget * treeWidget = item->treeWidget(); // contains
|
QTreeWidget
-
findItems?
QList<QTreeWidgetItem *> items = this->findItems ("png",
Qt::MatchRecursive | Qt::MatchEndsWith, 0);
foreach(QTreeWidgetItem *itm, items)
sfm::showString(itm->text(0));
|
-
invisibleRootItem?
It is useful for recursive functions, where can treat top-level items and their children in a uniform way;
QTreeWidgetItem *parent = item->parent();
if(!parent) // it is a top level item.
parent = invisibleRootItem(); // introduced in Qt 4.2.
|
-
createTreeWidgetItem recursively?
QTreeWidgetItem *PackageViewer::createTreeWidgetItem(
QTreeWidgetItem *parent, const QStringList &path)
{
if(path.isEmpty()) return NULL;
if(!parent) return NULL;
// topLevelItems have invisibleRootItem introduced in Qt 4.2
QTreeWidgetItem *child, *p = parent;
QStringList li = path;
for(int i=0; i<parent->childCount(); ++i)
{
child = parent->child(i);
if(child->text(0) != li[0]) continue;
// found
li.removeFirst();
if(li.isEmpty())
return child;
return createTreeWidgetItem(child, li);
}
// not exist
child = new QTreeWidgetItem(parent, QStringList() << li[0]);
li.removeFirst();
if(li.isEmpty())
return child;
return createTreeWidgetItem(child, li); // resursion
}
|
This method is quite useful when we build
list-and-tree views.
Tree Model/View/Edit
-
Tree Models
(underconstruction)
-
Tree Views
(underconstruction)
-
Simple Delegates
(underconstruction)
-
Structural Dialog Delegating
We know QSize has height pair of integers;
QBrush has a brush style and a color;
QPen has a pen styles and a brush.
So if a tree is displaying these known objects,
the editing method can be a dialog or a tab-dialog,
which takes it dependents (children or grandchildren)
for initial conditions, and talk to users to get new inputs.
This is what I call "Structural Dialog Delegating".
Another good example is Open Office XML 2007,
where tags and attributes are more or less standardized after
Microsoft submits documents to ISO. spPr (Shape Properties in 5.6.2.29 on page 3975):
This element specifies the visual shape properties that can be applied to a special shape
such as a connector shape or picture.
These are the same properties that are allowed to describe the visual properties
of a shape but are used here to describe additional object-specific properties within a document.
This allows for these shapes to have both the properties of a shape as well as specific properties
that are unique to only them.
which gives a Meta Frame style of a Picture Format
Picture Format | Style = Meta Frame
-
Attributes Dialog Delegating
For example, a:bevelT (Top Bevel, on page 3559 in 5.1.7.4)
This element holds the properties associated with defining a bevel on the top or front face of a shape.
On double click (means "edit") on attributes,
you will see an attribute-dialog,
where title shows the tagName, labels show attribute-names,
and lineEdits are listed ready for editing attribute-values.
Get it?! You are allowed to change attribute-values,
but not allowed any changes on the tagName and the attribute-names
which Microsoft specified.
This is the code behind the scene.
QDomNamedNodeMap attributeMap = node.attributes();
if(attributeMap.isEmpty()) return;
int n = attributeMap.count();
QString *attributeValue = new QString [n];
MyDialog dlg(node.toElement().tagName());
for (int i = 0; i<n; ++i)
{
QDomNode attribute = attributeMap.item(i);
attributeValue[i] = attribute.nodeValue();
dlg.add(attribute.nodeName(), &attributeValue[i]);
}
if(dlg.exec() == 0) return; // Cancelled
for (int i = 0; i<n; ++i)
{
QDomNode attribute = attributeMap.item(i);
if(attribute.nodeValue() == attributeValue[i])
continue; // no change
node.toElement().setAttribute( // update
attribute.nodeName(), attributeValue[i]);
}
delete []attributeValue;
|
Here is a table regarding the prst,
a preset for a type of bevel which can be applied to a shape in 3D.
(Duplicated from 5.1.12.9 ST_BevelPresetType (Bevel Presets) on page 3684)
Dialogs
| Model/View(
List/Tree,
Table, Network)
| XML/
Office 2007 XML
| COM/ActiveX
| Network TCP/IP
| OpenGL
| Online Help ...
|| MyQt
| Qt C++
| C/C++
| eBooks
|