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:
  1. Number of children?

    	int count = parent->childCount();
    
  2. first/last/ index of child?

    	QTreeWidgetItem *child = parent->child(index); 
    
  3. parent?

    	QTreeWidgetItem *parent = child->parent(); 
    
  4. 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);
    }
    
  5. 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);
    }
    
  6. name or text?

    	QString name = item->text(0); // first column
    
  7. 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;
    }
    
  8. 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;
    }
    
  9. 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;
    }
    
  10. 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;
    }
    
  11. 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;
    }
    
  12. 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
    }
    
  13. 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; 
    }
    
  14. 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
    }
    
  15. treeWidget?

    QTreeWidget * treeWidget = item->treeWidget(); // contains 
    

QTreeWidget

  1. findItems?

    	QList<QTreeWidgetItem *> items = this->findItems ("png", 
    		Qt::MatchRecursive | Qt::MatchEndsWith, 0); 
    	foreach(QTreeWidgetItem *itm, items)
    		sfm::showString(itm->text(0));
    
  2. 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. 
    
  3. 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

  1. Tree Models

    (underconstruction)
  2. Tree Views

    (underconstruction)
  3. Simple Delegates

    (underconstruction)
  4. 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

  5. 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