Отношения родитель - ребенок между объектами являются "сердцем" QT. Основным является следующее правило : когда удален "родитель" - его "дети", и дети детей до последнего колена тоже удаляются. Для компонентов часто имеет значение то, что отношения между "родителем" и "ребенком" означает отображение процесса - "ребенка" только внутри зоны "родителя".
Рождение, существование, смерть |
"Родители" обычно задаются в тот момент, когда строятся QObject`ы. Если объект является QWidget, то родительский компонент может быть изменен, при помощи функции QWidget::reparent(); иначе его можно изменить функциями QObject::InsertChild() и removeChild.
В тот момент, когда объект получает нового "ребенка", он также получает ChildInserted событие, соответственно и наоборот, при потере процесса - "ребенка" будет получено событие ChildRemoved. При реимплементации QObject::childEvent(), процесс - "родитель" может предостережен от этих событий. Много из встроеных в QT объектов, таких как QGroupBox, QMainWindow, QSplitter и QWorkspace реимплементируют эту функцию, для того, чтобы перехватить контроль за геометрическими параметрами своих "детей" (позиция и размер).
Находим детей |
Q_CHILD является одним из наименее известных макросов, и своей неизвестностью он обязан классической QT документации. Этот макрос получает имя ребенка, и накладывает его на указатель.
QListBox *list = Q_CHILD( parent, QListBox, "list" );
Функция вернет null указатель, если не будет найден объект - "ребенок" соответствующего типа.
Функция QObject::child() подобна Q_CHILD(), за исключением того, что она поддерживает рекурсивный поиск :
QListBox *clients = (QListBox *)parent->child( "clients", "QListBox", TRUE );
Функция QObject::queryList() гораздо более гибкая. Она возвращает указатель на новораспределенный QObjectList, который содержит указатели на все наследованые объекты, удовлетворяющие определенному критерию. Вот прототип этой функции :
QObjectList *queryList( const char *inheritsClass = 0, const char *objName = 0, bool regexpMatch = TRUE, bool recursiveSearch = TRUE );
QObjectList *list = obj->queryList();
QObjectList *list = obj->queryList( "QListBox" );
QObjectList *list = obj->queryList( 0, "lb.*" );
QObjectList *list = obj->queryList( "QFrame", "frame", FALSE, FALSE );
const QObjectList *list = obj->children(); QObjectListIt it( *list ); while ( it.current() ) { do_something( it.current() ); ++it; }
const QObjectList *list = QObject::objectTrees();
Кто чей? |
Функция QObject::dumpObjectTree() [1] печатает дерево объекта. К примеру для QTabDialog в этом дереве покажутся его наследники.
QTabDialog::dialog <574,451,133,123> QBoxLayout::unnamed QBoxLayout::unnamed QBoxLayout::unnamed QPushButton::ok <45,91,82,26> QTabWidget::tab widget <6,6,119,75> QTabBar::tab control <0,0,48,24> QToolButton::qt_right_btn I QToolButton::qt_left_btn I QAccel::tab accelerators QWidget::tab base I QWidgetStack::tab pages <0,22,119,51> QFrame::first <2,2,115,47> QObject::unnamed QWidgetStackPrivate::Invisible::unnamed <2,2,115,47>
При соединении dumpObjectTree() с objectTrees(), вы можете легко вывести на экран все объекты в памяти, на протяжении выполнения вашей программы.
const QObjectList *list = QObject::objectTrees(); QObjectListIt it( *list ); while ( it.current() ) { it.current()->dumpObjectTree(); ++it; }
void dumpAllObjectTrees() { dumpRecursive( QObject::objectTrees(), 0 ); }
void dumpRecursive( const QObjectList *list, QListViewItem *parent ) { if ( list == 0 ) return; QListView *listView = 0; QListViewItem *child; if ( parent == 0 ) { listView = new QListView( 0 ); listView->setRootIsDecorated( TRUE ); listView->addColumn( "Class" ); listView->addColumn( "Name" ); listView->addColumn( "Geometry" ); listView->setSorting( -1 ); listView->show(); } QObjectListIt it( *list ); QObject *obj; while ( (obj = it.current()) ) { if ( obj == listView ) { ++it; continue; } QString flags; if ( obj->isWidgetType() ) { QWidget *w = (QWidget *) obj; if ( w->isVisible() ) { flags.sprintf( "<%d,%d,%d,%d>", w->x(), w->y(), w->width(), w->height() ); } else { flags = "invisible"; } } child = parent ? new QListViewItem( parent ) : new QListViewItem( listView ); child->setText( 0, obj->className() ); child->setText( 1, obj->name() ); child->setText( 2, flags ); dumpRecursive( it.current()->children(), child ); ++it; } }
[1]
[1] QObject::dumpObjectTree() не делает ничего, если библиотека QT скопмпилирована в release режиме.
Copyright © 2002 Trolltech. | Trademarks |