Графические интерфейсы Python:... Заметка
Planet Python на русском

Графические интерфейсы Python: почему виджеты появляются как отдельные окна — понимание родительских элементов виджетов в Qt и как исправить виджеты, которые выплывают за пределы главного окна

В PyQt6 динамически добавляемые виджеты иногда всплывают как отдельные окна из-за проблем с родительскими виджетами. Каждый виджет в Qt может иметь необязательный родительский виджет, который определяет его визуальное размещение. Без родителя или при потере родителя виджет становится окном верхнего уровня. Это часто происходит, когда виджеты создаются без указания родителя при инициализации. Например, tabs = QTabWidget() создает виджет без родителя, что приводит к его самостоятельному плаванию. Использование tabs = QTabWidget(parent_widget) явно назначает родителя, удерживая его в пределах предполагаемого контейнера. Переназначение атрибута виджета, такого как self.w = QTabWidget(), может непреднамеренно заменить существующий виджет, заставляя его дочерние элементы потерять родителя и стать плавающими окнами. Явное присвоение родителя виджета значению None также делает его автономным окном. Даже косвенные действия, такие как удаление виджета из компоновки определенными способами, могут очистить ссылку на его родителя. Решение заключается в том, чтобы каждый виджет имел родителя, либо передавая его при создании, либо оперативно добавляя в компоновку. Предоставленный пример демонстрирует динамическое создание вкладок, последовательно устанавливая явных родителей для всех виджетов. Это включает создание новых вкладок перед обозначенной вкладкой "+" и использование blockSignals для предотвращения рекурсивного срабатывания сигналов. Понимание и правильное управление родительскими виджетами имеет решающее значение для предотвращения такого неожиданного поведения плавающих окон.