Все объекты фреймверка Qt наследуются от базового класса QObject. В этом классе есть свойство, содержащее имя объекта в виде QString. Заполнить это свойство можно через вызов метода setObjectName():
anyObject->setObjectName("anyObject");
В классе QObject есть метод findChild(). Он ищет (по-умолчанию даже рекурсивно) объект определенного типа по имени.
Вот небольшой пример, показывающий как происходит поиск. В примере используется три класса - класс главного окна MainWindow (наследник QMainWindows), класс First (наследник QObject), класс Second (наследник QObject).
В конструкторе главного окна вызывается создание объекта класса First, а следом за ним создается объект класса Second. В классе Second происходит поиск объекта First через метод findChild().
Следует обратить внимание, что внутри объекта Second поиск происходит начиная с объекта parent, а parent является указателем на объект главного окна. И самое главное, что поиск работает даже несмотря на то, что объект главного окна по сути еще не создан, так как до конца не отработал конструктор главного окна (ведь создание объекта Second происходит в конструкторе главного окна).
То есть, механизму поиска объектов findChild() достаточно того, чтобы была цепочка указателей. Другими словами, поиск работает просто по указателям, реализующим взаимосвязь между главным и подчиненным объектом. Эту особенность можно выразить следующим правилом:
Поиск будет работать только в том случае, если в объекте класса, унаследованного от QObject, будет задан parent-объект.
Я специально проверил это правило, создавая объекты First и Second без указания главного объекта класса MainWindow. То есть, вместо
First *first=new First(pMainWindow);
first->setObjectName("first");
Second *second=new Second(pMainWindow);
second->setObjectName("second");
писал
First *first=new First();
first->setObjectName("first");
Second *second=new Second();
second->setObjectName("second");
Как итог, поиск не работает. То есть, в Qt нет никакой магии, отслеживающей моменты и место создания объектов, и выстраивающей дерево взаимосвязей. Если взаимосвязь явно не задана указателем на родительский объект, то создаваемый объект будет "оторван" от объекта, внутри которого он создается, и просто помещен в кучу объектов. Тут нужно разбираться дальше, видимо из этого следует, что при создании внутри главного класса подчиненных объектов через оператор new, в случае уничтожения главного объекта, деструкторы подчиненных объектов автоматически вызваны не будут, если для этих подчиненных объектов не был задан parent-указатель.
Код примера
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Создается главное окно
MainWindow mainWindow;
mainWindow.setWindowTitle("Main window");
mainWindow.show();
return app.exec();
}
----- 8< -----
MainWindow::MainWindow()
{
// Указатель на главное окно прямо внутри конструктора главного окна
QObject *pMainWindow;
pMainWindow=this;
First *first=new First(pMainWindow);
first->setObjectName("first");
Second *second=new Second(pMainWindow);
second->setObjectName("second");
}
----- 8< -----
class First : public QObject
{
public:
First(QObject *parent=0);
};
First::First(QObject *parent) : QObject(parent)
{
}
----- 8< -----
class Second : public QObject
{
public:
Second(QObject *parent=0);
};
Second::Second(QObject *parent) : QObject(parent)
{
First *findObj=parent->findChild<First *>("first"); // Поиск объекта
if(findObj==NULL)
qDebug() << "First not found";
else
qDebug() << "First found";
}