#!/usr/bin/env python3
"""
Example Qt application to reproduce issues whereby Python objects wrapping non-owning Qt objects can
become invalid after a call to `QWidget.parent()` (or to `QWidget.parentWidget()`), if the widget is
inserted as a tab in a `QTabWidget`.
"""
import sys

from PySide6.QtCore import QLibraryInfo, qVersion, Qt, QObject
from PySide6.QtWidgets import QApplication, QWidget, QMenuBar, QPushButton, QVBoxLayout, QTabWidget

from shiboken6 import Shiboken


class Widget(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent=parent)

        menu_bar = QMenuBar()
        menu = menu_bar.addMenu('Menu')
        menu.setObjectName('menu')

        button = QPushButton('Press Me')
        button.clicked.connect(self._on_button_clicked)

        layout = QVBoxLayout(self)
        layout.addWidget(menu_bar)
        layout.addWidget(button)
        layout.addStretch()

    def _on_button_clicked(self):
        menu = self.findChild(QObject, 'menu')
        print(menu)

        pointer = Shiboken.getCppPointer(menu)[0]
        valid = Shiboken.isValid(menu)
        message = 'Menu object is good! ✅' if valid else 'Menu object has gone bad! ⚠️'
        print(f'Underlying C++ object: 0x{pointer:08x}    {message}')

        self.parentWidget()  # Wrongly invalidates `menu`

        pointer = Shiboken.getCppPointer(menu)[0]
        valid = Shiboken.isValid(menu)
        message = 'Menu object is good! ✅' if valid else 'Menu object has gone bad! ⚠️'
        print(f'Underlying C++ object: 0x{pointer:08x}    {message}')


if __name__ == '__main__':
    print('Python {}.{}.{}'.format(sys.version_info[0], sys.version_info[1],
                                   sys.version_info[2]))
    print(QLibraryInfo.build())
    app = QApplication(sys.argv)

    w = QTabWidget()  # Widget needs a parent
    w.setWindowTitle(qVersion())

    w.addTab(Widget(), 'Tab')
    w.show()

    app.exec()
