aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6')
-rw-r--r--sources/pyside6/.cmake.conf5
-rw-r--r--sources/pyside6/.gitattributes2
-rw-r--r--sources/pyside6/.gitignore6
-rw-r--r--sources/pyside6/CMakeLists.txt45
-rw-r--r--sources/pyside6/COPYING501
-rw-r--r--sources/pyside6/PySide6/CMakeLists.txt114
-rw-r--r--sources/pyside6/PySide6/Qt3DAnimation/CMakeLists.txt69
-rw-r--r--sources/pyside6/PySide6/Qt3DAnimation/typesystem_3danimation.xml60
-rw-r--r--sources/pyside6/PySide6/Qt3DCore/CMakeLists.txt62
-rw-r--r--sources/pyside6/PySide6/Qt3DCore/typesystem_3dcore.xml82
-rw-r--r--sources/pyside6/PySide6/Qt3DExtras/CMakeLists.txt85
-rw-r--r--sources/pyside6/PySide6/Qt3DExtras/typesystem_3dextras.xml58
-rw-r--r--sources/pyside6/PySide6/Qt3DInput/CMakeLists.txt54
-rw-r--r--sources/pyside6/PySide6/Qt3DInput/typesystem_3dinput.xml58
-rw-r--r--sources/pyside6/PySide6/Qt3DLogic/CMakeLists.txt35
-rw-r--r--sources/pyside6/PySide6/Qt3DLogic/typesystem_3dlogic.xml14
-rw-r--r--sources/pyside6/PySide6/Qt3DRender/CMakeLists.txt158
-rw-r--r--sources/pyside6/PySide6/Qt3DRender/typesystem_3drender.xml241
-rw-r--r--sources/pyside6/PySide6/QtAsyncio/__init__.py60
-rw-r--r--sources/pyside6/PySide6/QtAsyncio/events.py725
-rw-r--r--sources/pyside6/PySide6/QtAsyncio/futures.py117
-rw-r--r--sources/pyside6/PySide6/QtAsyncio/tasks.py190
-rw-r--r--sources/pyside6/PySide6/QtAxContainer/CMakeLists.txt47
-rw-r--r--sources/pyside6/PySide6/QtAxContainer/QtAxContainer_global.post.h.in1
-rw-r--r--sources/pyside6/PySide6/QtAxContainer/typesystem_axcontainer.xml40
-rw-r--r--sources/pyside6/PySide6/QtBluetooth/CMakeLists.txt56
-rw-r--r--sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml120
-rw-r--r--sources/pyside6/PySide6/QtCharts/CMakeLists.txt85
-rw-r--r--sources/pyside6/PySide6/QtCharts/typesystem_charts.xml256
-rw-r--r--sources/pyside6/PySide6/QtConcurrent/CMakeLists.txt33
-rw-r--r--sources/pyside6/PySide6/QtConcurrent/curr_errors.txt21
-rw-r--r--sources/pyside6/PySide6/QtConcurrent/typesystem_concurrent.xml35
-rw-r--r--sources/pyside6/PySide6/QtCore/CMakeLists.txt291
-rw-r--r--sources/pyside6/PySide6/QtCore/QtCore_global.post.h.in2
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp346
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h105
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.cpp123
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.h30
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/qiopipe.cpp142
-rw-r--r--sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp108
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core.xml12
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core_common.xml3630
-rw-r--r--sources/pyside6/PySide6/QtCore/typesystem_core_win.xml32
-rw-r--r--sources/pyside6/PySide6/QtDBus/CMakeLists.txt54
-rw-r--r--sources/pyside6/PySide6/QtDBus/QtDBus_global.post.h.in1
-rw-r--r--sources/pyside6/PySide6/QtDBus/typesystem_dbus.xml115
-rw-r--r--sources/pyside6/PySide6/QtDataVisualization/CMakeLists.txt71
-rw-r--r--sources/pyside6/PySide6/QtDataVisualization/qtdatavisualization_helper.cpp97
-rw-r--r--sources/pyside6/PySide6/QtDataVisualization/typesystem_datavisualization.xml476
-rw-r--r--sources/pyside6/PySide6/QtDesigner/CMakeLists.txt70
-rw-r--r--sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in1
-rw-r--r--sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in3
-rw-r--r--sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp223
-rw-r--r--sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml103
-rw-r--r--sources/pyside6/PySide6/QtGraphs/CMakeLists.txt100
-rw-r--r--sources/pyside6/PySide6/QtGraphs/qtgraphs_helper.cpp97
-rw-r--r--sources/pyside6/PySide6/QtGraphs/typesystem_graphs.xml303
-rw-r--r--sources/pyside6/PySide6/QtGui/CMakeLists.txt355
-rw-r--r--sources/pyside6/PySide6/QtGui/QtGui_global.post.h.in6
-rw-r--r--sources/pyside6/PySide6/QtGui/typesystem_gui.xml20
-rw-r--r--sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml3182
-rw-r--r--sources/pyside6/PySide6/QtGui/typesystem_gui_mac.xml6
-rw-r--r--sources/pyside6/PySide6/QtGui/typesystem_gui_rhi.xml176
-rw-r--r--sources/pyside6/PySide6/QtGui/typesystem_gui_win.xml43
-rw-r--r--sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml9
-rw-r--r--sources/pyside6/PySide6/QtHelp/CMakeLists.txt53
-rw-r--r--sources/pyside6/PySide6/QtHelp/QtHelp_global.pre.h.in3
-rw-r--r--sources/pyside6/PySide6/QtHelp/typesystem_help.xml37
-rw-r--r--sources/pyside6/PySide6/QtHttpServer/CMakeLists.txt40
-rw-r--r--sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml38
-rw-r--r--sources/pyside6/PySide6/QtLocation/CMakeLists.txt70
-rw-r--r--sources/pyside6/PySide6/QtLocation/typesystem_location.xml82
-rw-r--r--sources/pyside6/PySide6/QtMultimedia/CMakeLists.txt65
-rw-r--r--sources/pyside6/PySide6/QtMultimedia/typesystem_multimedia.xml180
-rw-r--r--sources/pyside6/PySide6/QtMultimediaWidgets/CMakeLists.txt39
-rw-r--r--sources/pyside6/PySide6/QtMultimediaWidgets/typesystem_multimediawidgets.xml15
-rw-r--r--sources/pyside6/PySide6/QtNetwork/CMakeLists.txt121
-rw-r--r--sources/pyside6/PySide6/QtNetwork/typesystem_network.xml475
-rw-r--r--sources/pyside6/PySide6/QtNetworkAuth/CMakeLists.txt38
-rw-r--r--sources/pyside6/PySide6/QtNetworkAuth/typesystem_networkauth.xml110
-rw-r--r--sources/pyside6/PySide6/QtNfc/CMakeLists.txt38
-rw-r--r--sources/pyside6/PySide6/QtNfc/typesystem_nfc.xml35
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/CMakeLists.txt100
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/QtOpenGL_global.post.h.in35
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/glue/utils.cpp40
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_includes.xml1
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_modifications.xml18
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_includes.xml5
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_modifications.xml36
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl.xml723
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0.xml15
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0_compat.xml67
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1.xml8
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1_compat.xml11
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_2_compat.xml10
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_3_compat.xml10
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4.xml11
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4_compat.xml13
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0.xml13
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0_compat.xml1
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_1.xml7
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_0.xml10
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3.xml10
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3a.xml21
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_0.xml10
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_1.xml40
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_3.xml7
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4.xml20
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4_core.xml7
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5.xml21
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5_core.xml5
-rw-r--r--sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications_va.xml7
-rw-r--r--sources/pyside6/PySide6/QtOpenGLWidgets/CMakeLists.txt33
-rw-r--r--sources/pyside6/PySide6/QtOpenGLWidgets/typesystem_openglwidgets.xml16
-rw-r--r--sources/pyside6/PySide6/QtPdf/CMakeLists.txt42
-rw-r--r--sources/pyside6/PySide6/QtPdf/typesystem_pdf.xml35
-rw-r--r--sources/pyside6/PySide6/QtPdfWidgets/CMakeLists.txt39
-rw-r--r--sources/pyside6/PySide6/QtPdfWidgets/typesystem_pdfwidgets.xml17
-rw-r--r--sources/pyside6/PySide6/QtPositioning/CMakeLists.txt60
-rw-r--r--sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml51
-rw-r--r--sources/pyside6/PySide6/QtPrintSupport/CMakeLists.txt40
-rw-r--r--sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport.xml10
-rw-r--r--sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport_common.xml71
-rw-r--r--sources/pyside6/PySide6/QtQml/CMakeLists.txt76
-rw-r--r--sources/pyside6/PySide6/QtQml/QtQml_global.post.h.in2
-rw-r--r--sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp161
-rw-r--r--sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.h15
-rw-r--r--sources/pyside6/PySide6/QtQml/typesystem_qml.xml340
-rw-r--r--sources/pyside6/PySide6/QtQuick/CMakeLists.txt119
-rw-r--r--sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp76
-rw-r--r--sources/pyside6/PySide6/QtQuick/pysidequickregistertype.h14
-rw-r--r--sources/pyside6/PySide6/QtQuick/typesystem_quick.xml251
-rw-r--r--sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt54
-rw-r--r--sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml30
-rw-r--r--sources/pyside6/PySide6/QtQuickControls2/CMakeLists.txt46
-rw-r--r--sources/pyside6/PySide6/QtQuickControls2/typesystem_quickcontrols2.xml13
-rw-r--r--sources/pyside6/PySide6/QtQuickTest/CMakeLists.txt44
-rw-r--r--sources/pyside6/PySide6/QtQuickTest/typesystem_quicktest.xml33
-rw-r--r--sources/pyside6/PySide6/QtQuickWidgets/CMakeLists.txt48
-rw-r--r--sources/pyside6/PySide6/QtQuickWidgets/typesystem_quickwidgets.xml19
-rw-r--r--sources/pyside6/PySide6/QtRemoteObjects/CMakeLists.txt53
-rw-r--r--sources/pyside6/PySide6/QtRemoteObjects/typesystem_remoteobjects.xml56
-rw-r--r--sources/pyside6/PySide6/QtScxml/CMakeLists.txt52
-rw-r--r--sources/pyside6/PySide6/QtScxml/typesystem_scxml.xml52
-rw-r--r--sources/pyside6/PySide6/QtSensors/CMakeLists.txt94
-rw-r--r--sources/pyside6/PySide6/QtSensors/typesystem_sensors.xml87
-rw-r--r--sources/pyside6/PySide6/QtSerialBus/CMakeLists.txt66
-rw-r--r--sources/pyside6/PySide6/QtSerialBus/typesystem_serialbus.xml118
-rw-r--r--sources/pyside6/PySide6/QtSerialPort/CMakeLists.txt34
-rw-r--r--sources/pyside6/PySide6/QtSerialPort/typesystem_serialport.xml20
-rw-r--r--sources/pyside6/PySide6/QtSpatialAudio/CMakeLists.txt40
-rw-r--r--sources/pyside6/PySide6/QtSpatialAudio/typesystem_spatialaudio.xml32
-rw-r--r--sources/pyside6/PySide6/QtSql/CMakeLists.txt52
-rw-r--r--sources/pyside6/PySide6/QtSql/QtSql_global.pre.h.in5
-rw-r--r--sources/pyside6/PySide6/QtSql/typesystem_sql.xml182
-rw-r--r--sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt42
-rw-r--r--sources/pyside6/PySide6/QtStateMachine/typesystem_statemachine.xml195
-rw-r--r--sources/pyside6/PySide6/QtSvg/CMakeLists.txt34
-rw-r--r--sources/pyside6/PySide6/QtSvg/typesystem_svg.xml30
-rw-r--r--sources/pyside6/PySide6/QtSvgWidgets/CMakeLists.txt36
-rw-r--r--sources/pyside6/PySide6/QtSvgWidgets/typesystem_svgwidgets.xml25
-rw-r--r--sources/pyside6/PySide6/QtTest/CMakeLists.txt46
-rw-r--r--sources/pyside6/PySide6/QtTest/QtTest_global.post.h.in1
-rw-r--r--sources/pyside6/PySide6/QtTest/QtTest_global.pre.h.in5
-rw-r--r--sources/pyside6/PySide6/QtTest/typesystem_test.xml130
-rw-r--r--sources/pyside6/PySide6/QtTextToSpeech/CMakeLists.txt31
-rw-r--r--sources/pyside6/PySide6/QtTextToSpeech/typesystem_texttospeech.xml21
-rw-r--r--sources/pyside6/PySide6/QtUiTools/CMakeLists.txt45
-rw-r--r--sources/pyside6/PySide6/QtUiTools/QtUiTools_global.pre.h.in7
-rw-r--r--sources/pyside6/PySide6/QtUiTools/glue/plugins.h31
-rw-r--r--sources/pyside6/PySide6/QtUiTools/typesystem_uitools.xml88
-rw-r--r--sources/pyside6/PySide6/QtWebChannel/CMakeLists.txt30
-rw-r--r--sources/pyside6/PySide6/QtWebChannel/typesystem_webchannel.xml23
-rw-r--r--sources/pyside6/PySide6/QtWebEngineCore/CMakeLists.txt75
-rw-r--r--sources/pyside6/PySide6/QtWebEngineCore/typesystem_webenginecore.xml192
-rw-r--r--sources/pyside6/PySide6/QtWebEngineQuick/CMakeLists.txt43
-rw-r--r--sources/pyside6/PySide6/QtWebEngineQuick/typesystem_webenginequick.xml18
-rw-r--r--sources/pyside6/PySide6/QtWebEngineWidgets/CMakeLists.txt45
-rw-r--r--sources/pyside6/PySide6/QtWebEngineWidgets/typesystem_webenginewidgets.xml21
-rw-r--r--sources/pyside6/PySide6/QtWebSockets/CMakeLists.txt37
-rw-r--r--sources/pyside6/PySide6/QtWebSockets/typesystem_websockets.xml34
-rw-r--r--sources/pyside6/PySide6/QtWidgets/CMakeLists.txt226
-rw-r--r--sources/pyside6/PySide6/QtWidgets/typesystem_widgets.xml10
-rw-r--r--sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml3420
-rw-r--r--sources/pyside6/PySide6/QtXml/CMakeLists.txt45
-rw-r--r--sources/pyside6/PySide6/QtXml/typesystem_xml.xml173
-rw-r--r--sources/pyside6/PySide6/__feature__.pyi.in10
-rw-r--r--sources/pyside6/PySide6/__init__.py.in124
-rw-r--r--sources/pyside6/PySide6/_config.py.in17
-rw-r--r--sources/pyside6/PySide6/doc/qtqml_functions.rst152
-rw-r--r--sources/pyside6/PySide6/doc/qtquicktest.rst62
-rw-r--r--sources/pyside6/PySide6/doc/qtuitools.rst68
-rw-r--r--sources/pyside6/PySide6/global.h.in20
-rw-r--r--sources/pyside6/PySide6/glue/qhttpserver.cpp50
-rw-r--r--sources/pyside6/PySide6/glue/qtcharts.cpp16
-rw-r--r--sources/pyside6/PySide6/glue/qtcore.cpp2150
-rw-r--r--sources/pyside6/PySide6/glue/qtdatavisualization.cpp90
-rw-r--r--sources/pyside6/PySide6/glue/qtdesigner.cpp7
-rw-r--r--sources/pyside6/PySide6/glue/qtgraphs.cpp8
-rw-r--r--sources/pyside6/PySide6/glue/qtgui.cpp947
-rw-r--r--sources/pyside6/PySide6/glue/qtmultimedia.cpp28
-rw-r--r--sources/pyside6/PySide6/glue/qtnetwork.cpp130
-rw-r--r--sources/pyside6/PySide6/glue/qtnetworkauth.cpp44
-rw-r--r--sources/pyside6/PySide6/glue/qtopengl.cpp89
-rw-r--r--sources/pyside6/PySide6/glue/qtpositioning.cpp14
-rw-r--r--sources/pyside6/PySide6/glue/qtprintsupport.cpp20
-rw-r--r--sources/pyside6/PySide6/glue/qtqml.cpp90
-rw-r--r--sources/pyside6/PySide6/glue/qtquick.cpp27
-rw-r--r--sources/pyside6/PySide6/glue/qtquicktest.cpp50
-rw-r--r--sources/pyside6/PySide6/glue/qtserialbus.cpp30
-rw-r--r--sources/pyside6/PySide6/glue/qtsql.cpp60
-rw-r--r--sources/pyside6/PySide6/glue/qtstatemachine.cpp67
-rw-r--r--sources/pyside6/PySide6/glue/qttest.cpp24
-rw-r--r--sources/pyside6/PySide6/glue/qtuitools.cpp212
-rw-r--r--sources/pyside6/PySide6/glue/qtwebenginecore.cpp64
-rw-r--r--sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp121
-rw-r--r--sources/pyside6/PySide6/glue/qtwidgets.cpp818
-rw-r--r--sources/pyside6/PySide6/glue/qtxml.cpp17
-rw-r--r--sources/pyside6/PySide6/licensecomment.txt2
-rw-r--r--sources/pyside6/PySide6/py.typed.in1
-rw-r--r--sources/pyside6/PySide6/pysideqtesttouch.h179
-rw-r--r--sources/pyside6/PySide6/pysidewtypes.h30
-rw-r--r--sources/pyside6/PySide6/qiopipe.h36
-rw-r--r--sources/pyside6/PySide6/qpydesignerextensions.h84
-rw-r--r--sources/pyside6/PySide6/qpyqmlparserstatus.h28
-rw-r--r--sources/pyside6/PySide6/qpyqmlpropertyvaluesource.h27
-rw-r--r--sources/pyside6/PySide6/qpytextobject.cpp14
-rw-r--r--sources/pyside6/PySide6/qpytextobject.h28
-rw-r--r--sources/pyside6/PySide6/qt.conf.in2
-rw-r--r--sources/pyside6/PySide6/qtcorehelper.h122
-rw-r--r--sources/pyside6/PySide6/qtdatavisualization_helper.h19
-rw-r--r--sources/pyside6/PySide6/qtdbushelper.h62
-rw-r--r--sources/pyside6/PySide6/qtgraphs_helper.h19
-rw-r--r--sources/pyside6/PySide6/qtguihelper.h35
-rw-r--r--sources/pyside6/PySide6/support/__init__.py6
-rw-r--r--sources/pyside6/PySide6/support/deprecated.py18
-rw-r--r--sources/pyside6/PySide6/support/generate_pyi.py93
-rw-r--r--sources/pyside6/PySide6/templates/common.xml27
-rw-r--r--sources/pyside6/PySide6/templates/core_common.xml287
-rw-r--r--sources/pyside6/PySide6/templates/datavisualization_common.xml40
-rw-r--r--sources/pyside6/PySide6/templates/gui_common.xml266
-rw-r--r--sources/pyside6/PySide6/templates/opengl_common.xml30
-rw-r--r--sources/pyside6/PySide6/templates/widgets_common.xml55
-rw-r--r--sources/pyside6/cmake/Macros/PySideModules.cmake386
-rw-r--r--sources/pyside6/cmake/Macros/icecc.cmake14
-rw-r--r--sources/pyside6/cmake/PySideHelpers.cmake275
-rw-r--r--sources/pyside6/cmake/PySideSetup.cmake243
-rw-r--r--sources/pyside6/cmake_uninstall.cmake24
-rw-r--r--sources/pyside6/doc/CMakeLists.txt294
-rw-r--r--sources/pyside6/doc/PySide6/QtAsyncio/index.rst150
-rw-r--r--sources/pyside6/doc/_static/css/qt_font.css15
-rw-r--r--sources/pyside6/doc/_static/css/qt_style.css100
-rw-r--r--sources/pyside6/doc/_static/qtforpython.icobin0 -> 766 bytes
-rw-r--r--sources/pyside6/doc/_static/qtforpython.pngbin0 -> 4043 bytes
-rw-r--r--sources/pyside6/doc/_tags/android.rst21
-rw-r--r--sources/pyside6/doc/_tags/tagsindex.rst12
-rw-r--r--sources/pyside6/doc/_templates/layout.html53
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/domainindex.html57
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/fakebar.pngbin0 -> 101 bytes
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_python.jpgbin0 -> 2660 bytes
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_qt.pngbin0 -> 1936 bytes
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/minus.pngbin0 -> 199 bytes
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/plus.pngbin0 -> 199 bytes
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pyside.css1943
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pysidelogo.pngbin0 -> 4936 bytes
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/static/relbar_bg.pngbin0 -> 130 bytes
-rw-r--r--sources/pyside6/doc/_themes/pysidedocs_qthelp/theme.conf7
-rw-r--r--sources/pyside6/doc/additionaldocs.lst624
-rw-r--r--sources/pyside6/doc/api.rst59
-rw-r--r--sources/pyside6/doc/commercial/index.rst250
-rw-r--r--sources/pyside6/doc/commercial/products.pngbin0 -> 23289 bytes
-rw-r--r--sources/pyside6/doc/commercial/qtcreator_python.pngbin0 -> 40845 bytes
-rw-r--r--sources/pyside6/doc/commercial/versions_commercial.pngbin0 -> 34660 bytes
-rw-r--r--sources/pyside6/doc/commercial/versions_lts.pngbin0 -> 34293 bytes
-rw-r--r--sources/pyside6/doc/conf.py.in244
-rw-r--r--sources/pyside6/doc/considerations.rst441
-rw-r--r--sources/pyside6/doc/contents.rst28
-rw-r--r--sources/pyside6/doc/deployment/deployment-briefcase.rst211
-rw-r--r--sources/pyside6/doc/deployment/deployment-cxfreeze.rst131
-rw-r--r--sources/pyside6/doc/deployment/deployment-fbs.rst97
-rw-r--r--sources/pyside6/doc/deployment/deployment-nuitka.rst132
-rw-r--r--sources/pyside6/doc/deployment/deployment-py2exe.rst16
-rw-r--r--sources/pyside6/doc/deployment/deployment-pyinstaller.rst164
-rw-r--r--sources/pyside6/doc/deployment/deployment-pyside6-android-deploy.rst211
-rw-r--r--sources/pyside6/doc/deployment/deployment-pyside6-deploy.rst217
-rw-r--r--sources/pyside6/doc/deployment/index.rst155
-rw-r--r--sources/pyside6/doc/developer/adapt_qt.rst54
-rw-r--r--sources/pyside6/doc/developer/add_module.rst61
-rw-r--r--sources/pyside6/doc/developer/add_port_example.rst67
-rw-r--r--sources/pyside6/doc/developer/add_tool.rst51
-rw-r--r--sources/pyside6/doc/developer/documentation.rst73
-rw-r--r--sources/pyside6/doc/developer/enumfeatures_doc.rst160
-rw-r--r--sources/pyside6/doc/developer/extras.rst55
-rw-r--r--sources/pyside6/doc/developer/feature-motivation.rst303
-rw-r--r--sources/pyside6/doc/developer/index.rst35
-rw-r--r--sources/pyside6/doc/developer/limited_api.rst703
-rw-r--r--sources/pyside6/doc/developer/signature_doc.rst361
-rw-r--r--sources/pyside6/doc/example_no_image.pngbin0 -> 65484 bytes
-rw-r--r--sources/pyside6/doc/extras/QtBluetooth.rst102
-rw-r--r--sources/pyside6/doc/extras/QtCharts.rst21
-rw-r--r--sources/pyside6/doc/extras/QtConcurrent.rst37
-rw-r--r--sources/pyside6/doc/extras/QtCore.ClassInfo.rst34
-rw-r--r--sources/pyside6/doc/extras/QtCore.Property.rst129
-rw-r--r--sources/pyside6/doc/extras/QtCore.QEnum.rst27
-rw-r--r--sources/pyside6/doc/extras/QtCore.QFlag.rst74
-rw-r--r--sources/pyside6/doc/extras/QtCore.Signal.rst58
-rw-r--r--sources/pyside6/doc/extras/QtCore.Slot.rst42
-rw-r--r--sources/pyside6/doc/extras/QtCore.rst61
-rw-r--r--sources/pyside6/doc/extras/QtDBus.rst193
-rw-r--r--sources/pyside6/doc/extras/QtDataVisualization.rst30
-rw-r--r--sources/pyside6/doc/extras/QtDesigner.QPyDesignerContainerExtension.rst9
-rw-r--r--sources/pyside6/doc/extras/QtDesigner.QPyDesignerCustomWidgetCollection.rst52
-rw-r--r--sources/pyside6/doc/extras/QtDesigner.QPyDesignerMemberSheetExtension.rst9
-rw-r--r--sources/pyside6/doc/extras/QtDesigner.QPyDesignerTaskMenuExtension.rst9
-rw-r--r--sources/pyside6/doc/extras/QtDesigner.rst18
-rw-r--r--sources/pyside6/doc/extras/QtGui.rst142
-rw-r--r--sources/pyside6/doc/extras/QtHelp.rst19
-rw-r--r--sources/pyside6/doc/extras/QtMultimedia.rst116
-rw-r--r--sources/pyside6/doc/extras/QtMultimediaWidgets.rst15
-rw-r--r--sources/pyside6/doc/extras/QtNetwork.rst30
-rw-r--r--sources/pyside6/doc/extras/QtNetworkAuth.rst37
-rw-r--r--sources/pyside6/doc/extras/QtNfc.rst31
-rw-r--r--sources/pyside6/doc/extras/QtOpenGL.rst26
-rw-r--r--sources/pyside6/doc/extras/QtOpenGLWidgets.rst8
-rw-r--r--sources/pyside6/doc/extras/QtPositioning.rst40
-rw-r--r--sources/pyside6/doc/extras/QtPrintSupport.rst15
-rw-r--r--sources/pyside6/doc/extras/QtQml.ListProperty.rst24
-rw-r--r--sources/pyside6/doc/extras/QtQml.QPyQmlParserStatus.rst9
-rw-r--r--sources/pyside6/doc/extras/QtQml.QPyQmlPropertyValueSource.rst9
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst17
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlAttached.rst35
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlElement.rst25
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlExtended.rst32
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlForeign.rst28
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlNamedElement.rst26
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlSingleton.rst33
-rw-r--r--sources/pyside6/doc/extras/QtQml.QmlUncreatable.rst26
-rw-r--r--sources/pyside6/doc/extras/QtQml.rst75
-rw-r--r--sources/pyside6/doc/extras/QtQuickControls2.rst45
-rw-r--r--sources/pyside6/doc/extras/QtQuickTest.rst58
-rw-r--r--sources/pyside6/doc/extras/QtRemoteObjects.rst101
-rw-r--r--sources/pyside6/doc/extras/QtScxml.rst25
-rw-r--r--sources/pyside6/doc/extras/QtSensors.rst19
-rw-r--r--sources/pyside6/doc/extras/QtSerialBus.rst46
-rw-r--r--sources/pyside6/doc/extras/QtSerialPort.rst18
-rw-r--r--sources/pyside6/doc/extras/QtSql.rst21
-rw-r--r--sources/pyside6/doc/extras/QtSvg.rst21
-rw-r--r--sources/pyside6/doc/extras/QtTest.rst7
-rw-r--r--sources/pyside6/doc/extras/QtUiTools.rst17
-rw-r--r--sources/pyside6/doc/extras/QtWebChannel.rst30
-rw-r--r--sources/pyside6/doc/extras/QtWebEngineCore.rst19
-rw-r--r--sources/pyside6/doc/extras/QtWebEngineWidgets.rst18
-rw-r--r--sources/pyside6/doc/extras/QtWebSockets.rst29
-rw-r--r--sources/pyside6/doc/extras/QtWidgets.rst86
-rw-r--r--sources/pyside6/doc/extras/QtXml.rst13
-rw-r--r--sources/pyside6/doc/faq.rst38
-rw-r--r--sources/pyside6/doc/faq/distribution.rst69
-rw-r--r--sources/pyside6/doc/faq/hello_linux.pngbin0 -> 5960 bytes
-rw-r--r--sources/pyside6/doc/faq/hello_macOS.pngbin0 -> 38777 bytes
-rw-r--r--sources/pyside6/doc/faq/hello_win10.jpgbin0 -> 5314 bytes
-rw-r--r--sources/pyside6/doc/faq/tiobe.pngbin0 -> 49961 bytes
-rw-r--r--sources/pyside6/doc/faq/typesoffiles.rst152
-rw-r--r--sources/pyside6/doc/faq/whatisqt.rst112
-rw-r--r--sources/pyside6/doc/faq/whatisshiboken.rst40
-rw-r--r--sources/pyside6/doc/faq/whichide.rst56
-rw-r--r--sources/pyside6/doc/faq/whyqtforpython.rst203
-rw-r--r--sources/pyside6/doc/gettingstarted/index.rst572
-rw-r--r--sources/pyside6/doc/gettingstarted/linux.rst119
-rw-r--r--sources/pyside6/doc/gettingstarted/macOS.rst89
-rw-r--r--sources/pyside6/doc/gettingstarted/package_details.rst75
-rw-r--r--sources/pyside6/doc/gettingstarted/packages.pngbin0 -> 12157 bytes
-rw-r--r--sources/pyside6/doc/gettingstarted/porting_from2.rst94
-rw-r--r--sources/pyside6/doc/gettingstarted/windows.rst114
-rw-r--r--sources/pyside6/doc/images/Commercial.svg49
-rw-r--r--sources/pyside6/doc/images/Deployment.svg26
-rw-r--r--sources/pyside6/doc/images/Desktop.svg26
-rw-r--r--sources/pyside6/doc/images/Dev.svg24
-rw-r--r--sources/pyside6/doc/images/Development.svg27
-rw-r--r--sources/pyside6/doc/images/Examples.svg34
-rw-r--r--sources/pyside6/doc/images/Support.svg24
-rw-r--r--sources/pyside6/doc/images/Tooling.svg24
-rw-r--r--sources/pyside6/doc/images/Training.svg24
-rw-r--r--sources/pyside6/doc/images/Tutorials.svg24
-rw-r--r--sources/pyside6/doc/images/cpp_python.svg142
-rw-r--r--sources/pyside6/doc/images/linux.svg37
-rw-r--r--sources/pyside6/doc/images/macos.svg38
-rw-r--r--sources/pyside6/doc/images/screenshot_hello.pngbin0 -> 21193 bytes
-rw-r--r--sources/pyside6/doc/images/stopwatch.svg24
-rw-r--r--sources/pyside6/doc/images/windows.svg38
-rw-r--r--sources/pyside6/doc/import_inheritance.py152
-rw-r--r--sources/pyside6/doc/index.rst222
-rw-r--r--sources/pyside6/doc/inheritance_diagram.py165
-rw-r--r--sources/pyside6/doc/inheritance_diagram.pyproject6
-rw-r--r--sources/pyside6/doc/inheritance_graph.py145
-rw-r--r--sources/pyside6/doc/json_inheritance.py74
-rw-r--r--sources/pyside6/doc/modules.rst234
-rw-r--r--sources/pyside6/doc/pyside-config.qdocconf.in19
-rw-r--r--sources/pyside6/doc/pysideinclude.py148
-rw-r--r--sources/pyside6/doc/qdoc_spawner.py.in105
-rw-r--r--sources/pyside6/doc/qtattributionsscannertorst.py123
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qt3dextras.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtbluetooth.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtcharts.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtconcurrent.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtcore.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtdbus.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtdesigner.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtdoc.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtgui.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qthelp.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtnetwork.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtnetworkauth.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtnfc.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtopengl.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtpdf.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtpositioning.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtprintsupport.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtqml.qdocconf.in5
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtquickcontrols2.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtquicktest.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtremoteobjects.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtscxml.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtsensors.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtserialbus.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtserialport.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtspatialaudio.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtsql.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtsvg.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qttest.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qttexttospeech.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtuitools.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtwebchannel.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in3
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtwebsockets.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtwidgets.qdocconf.in2
-rw-r--r--sources/pyside6/doc/qtmodules/pyside-qtxml.qdocconf.in2
-rw-r--r--sources/pyside6/doc/quickstart.rst287
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_0.cpp.py4
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_1.cpp.py5
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_2.cpp.py5
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_3.cpp.py5
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_4.cpp.py4
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/itemviews/spinboxdelegate/delegate_0.h.py18
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/1_readonly/mymodel_Quoting_ModelView_Tutorial.h.py15
-rw-r--r--sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/5_edit/mymodel_Quoting_ModelView_Tutorial.h.py27
-rw-r--r--sources/pyside6/doc/snippets/qtbase/src/gui/doc/snippets/code/src_gui_painting_qpainter_drawText.cpp.py13
-rw-r--r--sources/pyside6/doc/snippets/qtbase/src/widgets/doc/snippets/stringlistmodel/model_0.h.py24
-rw-r--r--sources/pyside6/doc/src/README.md1
-rw-r--r--sources/pyside6/doc/tools/index.rst211
-rw-r--r--sources/pyside6/doc/tools/pyside-assistant.rst21
-rw-r--r--sources/pyside6/doc/tools/pyside-designer.rst91
-rw-r--r--sources/pyside6/doc/tools/pyside-genpyi.rst52
-rw-r--r--sources/pyside6/doc/tools/pyside-linguist.rst20
-rw-r--r--sources/pyside6/doc/tools/pyside-lrelease.rst25
-rw-r--r--sources/pyside6/doc/tools/pyside-lupdate.rst23
-rw-r--r--sources/pyside6/doc/tools/pyside-metaobjectdump.rst92
-rw-r--r--sources/pyside6/doc/tools/pyside-project.rst64
-rw-r--r--sources/pyside6/doc/tools/pyside-qml.rst84
-rw-r--r--sources/pyside6/doc/tools/pyside-qmlcachegen.rst25
-rw-r--r--sources/pyside6/doc/tools/pyside-qmllint.rst49
-rw-r--r--sources/pyside6/doc/tools/pyside-qmltyperegistrar.rst17
-rw-r--r--sources/pyside6/doc/tools/pyside-rcc.rst55
-rw-r--r--sources/pyside6/doc/tools/pyside-uic.rst59
-rw-r--r--sources/pyside6/doc/tools/pyside6-assistant_screenshot.webpbin0 -> 18474 bytes
-rw-r--r--sources/pyside6/doc/tools/pyside6-balsam.rst59
-rw-r--r--sources/pyside6/doc/tools/pyside6-balsamui.rst22
-rw-r--r--sources/pyside6/doc/tools/pyside6-balsamui_screenshot.webpbin0 -> 10190 bytes
-rw-r--r--sources/pyside6/doc/tools/pyside6-designer_base_screenshot.webpbin0 -> 9446 bytes
-rw-r--r--sources/pyside6/doc/tools/pyside6-designer_customwidgets_screenshot.webpbin0 -> 39422 bytes
-rw-r--r--sources/pyside6/doc/tools/pyside6-designer_screenshot.webpbin0 -> 61182 bytes
-rw-r--r--sources/pyside6/doc/tools/pyside6-designer_sections_screenshot.webpbin0 -> 73738 bytes
-rw-r--r--sources/pyside6/doc/tools/pyside6-linguist_screenshot.webpbin0 -> 90474 bytes
-rw-r--r--sources/pyside6/doc/tools/pyside6-qmlimportscanner.rst53
-rw-r--r--sources/pyside6/doc/tools/pyside6-qsb.rst39
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/clickablebutton.pngbin0 -> 7059 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst95
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/dialog.pngbin0 -> 21263 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/dialog.rst149
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/greenapplication.pngbin0 -> 2089 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons.pngbin0 -> 1599 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons.zipbin0 -> 6156 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons/forward.pngbin0 -> 1113 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons/pause.pngbin0 -> 1001 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons/play.pngbin0 -> 970 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons/previous.pngbin0 -> 1050 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons/stop.pngbin0 -> 1064 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/player-new.pngbin0 -> 3369 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/player.pngbin0 -> 2631 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/qml.rst79
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst173
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst263
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/signals_slots.pngbin0 -> 14787 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/style.qss23
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/tablewidget.pngbin0 -> 14509 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/tablewidget.rst97
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/translations.pngbin0 -> 25318 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/translations.rst232
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/treewidget.pngbin0 -> 3709 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/treewidget.rst79
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/uifiles.pngbin0 -> 86503 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/uifiles.rst304
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgets.pngbin0 -> 23233 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgets.rst52
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgetstyling-no.pngbin0 -> 11004 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-no.pngbin0 -> 1206 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-yes.pngbin0 -> 1596 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgetstyling-yes.pngbin0 -> 24791 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgetstyling.py58
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst171
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/add_chart.rst20
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/add_mainwindow.rst32
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/add_tableview.rst70
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/all_hour.csv8
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize1/main.py18
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize2/main.py41
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main.py51
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main_window.py31
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main.py53
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_widget.py43
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_window.py32
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize4/table_model.py51
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main.py53
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_widget.py54
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_window.py32
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize5/table_model.py51
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main.py55
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_widget.py95
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_window.py32
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/datavisualize6/table_model.py51
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/filter_data.rst29
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/images/QMainWindow-layout.pngbin0 -> 17272 bytes
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/images/datavisualization_app.pngbin0 -> 49419 bytes
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/index.rst31
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/plot_datapoints.rst27
-rw-r--r--sources/pyside6/doc/tutorials/datavisualize/read_data.rst41
-rw-r--r--sources/pyside6/doc/tutorials/debugging/mixed_debugging.rst126
-rw-r--r--sources/pyside6/doc/tutorials/debugging/qml_debugging.rst32
-rw-r--r--sources/pyside6/doc/tutorials/debugging/qtcreator/breakpoint_cpp.pngbin0 -> 42765 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_create.pngbin0 -> 40278 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_run_config.pngbin0 -> 43483 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/qtcreator/qtcreator.rst39
-rw-r--r--sources/pyside6/doc/tutorials/debugging/qtcreator/start_debugging_without_deployment.pngbin0 -> 49267 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/vscode/audioformat_cpp.pngbin0 -> 43650 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/vscode/audioformat_wrapper.pngbin0 -> 40677 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/vscode/breakpoint_gdb.pngbin0 -> 33684 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/vscode/find_process_gdb.pngbin0 -> 42303 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/vscode/python_set_interpreter.pngbin0 -> 4664 bytes
-rw-r--r--sources/pyside6/doc/tutorials/debugging/vscode/vscode.rst192
-rw-r--r--sources/pyside6/doc/tutorials/expenses/expenses.rst285
-rw-r--r--sources/pyside6/doc/tutorials/expenses/expenses_tool.pngbin0 -> 47826 bytes
-rw-r--r--sources/pyside6/doc/tutorials/expenses/main.py153
-rw-r--r--sources/pyside6/doc/tutorials/expenses/main_snake_prop.py177
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/01-expenses.py22
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/02-expenses.py31
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/03-expenses.py31
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/04-expenses.py45
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/05-expenses.py69
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/06-expenses.py89
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/07-expenses.py112
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/08-expenses.py123
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/09-expenses.py131
-rw-r--r--sources/pyside6/doc/tutorials/expenses/steps/10-expenses.py153
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/Main.qml196
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/app.qrc16
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons.qrc15
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/app_icon.svg2
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_closed.svg38
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_open.svg38
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/generic_file.svg38
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/globe.svg38
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/info_sign.svg38
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/leaf.svg7
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/light_bulb.svg43
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/qt_logo.svg26
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/read.svg38
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/resize.svg6
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/About.qml93
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ColorScheme.qml118
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Editor.qml160
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/FileSystemView.qml156
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenu.qml45
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenuBar.qml177
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ResizeButton.qml23
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Sidebar.qml146
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/WindowDragHandler.qml16
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qmldir11
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/editormodels.py116
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md210
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.pyproject31
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/main.py50
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/resources/Colors.qml22
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/resources/colorscheme.pngbin0 -> 27675 bytes
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.gifbin0 -> 2082470 bytes
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.webpbin0 -> 23628 bytes
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/scheme_manager.py97
-rw-r--r--sources/pyside6/doc/tutorials/extendedexplorer/schemes.json82
-rw-r--r--sources/pyside6/doc/tutorials/index.rst206
-rw-r--r--sources/pyside6/doc/tutorials/modelviewprogramming/qlistview-dnd.py137
-rw-r--r--sources/pyside6/doc/tutorials/modelviewprogramming/simplemodel-use.py44
-rw-r--r--sources/pyside6/doc/tutorials/modelviewprogramming/stringlistmodel.py124
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst89
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py94
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.pngbin0 -> 25391 bytes
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h113
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter1/main.py22
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.cpp96
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.h36
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.py101
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/chapter2.rst93
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/createdb.py94
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books.pngbin0 -> 34658 bytes
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.pngbin0 -> 44122 bytes
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/images/star.pngbin0 -> 782 bytes
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter2/main.py26
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate-old.py101
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate.py96
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/books.qrc5
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.cpp124
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.py99
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.ui149
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/chapter3.rst121
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/createdb.py94
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/images/chapter3-books.pngbin0 -> 34624 bytes
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/images/star.pngbin0 -> 782 bytes
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/main-old.py15
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/chapter3/main.py16
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/hello_world_ex.py39
-rw-r--r--sources/pyside6/doc/tutorials/portingguide/index.rst194
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/logo.pngbin0 -> 6208 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/main.py46
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/newpyproject.pngbin0 -> 16091 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/projectsmode.pngbin0 -> 8848 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/pyprojname.pngbin0 -> 8068 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/pyprojxplor.pngbin0 -> 10062 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/qmlapplication.pngbin0 -> 10950 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst132
-rw-r--r--sources/pyside6/doc/tutorials/qmlapp/view.qml56
-rw-r--r--sources/pyside6/doc/tutorials/qmlintegration/main.py77
-rw-r--r--sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst128
-rw-r--r--sources/pyside6/doc/tutorials/qmlintegration/qtquickcontrols2.conf10
-rw-r--r--sources/pyside6/doc/tutorials/qmlintegration/style.qrc5
-rw-r--r--sources/pyside6/doc/tutorials/qmlintegration/textproperties_default.pngbin0 -> 19347 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlintegration/textproperties_material.pngbin0 -> 21170 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlintegration/view.qml160
-rw-r--r--sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml98
-rw-r--r--sources/pyside6/doc/tutorials/qmlsqlintegration/example_list_view.pngbin0 -> 6954 bytes
-rw-r--r--sources/pyside6/doc/tutorials/qmlsqlintegration/main.py52
-rw-r--r--sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst232
-rw-r--r--sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py116
-rw-r--r--sources/pyside6/doc/typesystem_doc.xml.in17
-rw-r--r--sources/pyside6/doc/videos.rst155
-rw-r--r--sources/pyside6/libpyside/CMakeLists.txt194
-rw-r--r--sources/pyside6/libpyside/PySide6Config-spec.cmake.in16
-rw-r--r--sources/pyside6/libpyside/PySide6Config.cmake.in5
-rw-r--r--sources/pyside6/libpyside/PySide6ConfigVersion.cmake.in10
-rw-r--r--sources/pyside6/libpyside/class_property.cpp178
-rw-r--r--sources/pyside6/libpyside/class_property.h43
-rw-r--r--sources/pyside6/libpyside/dynamicqmetaobject.cpp675
-rw-r--r--sources/pyside6/libpyside/dynamicqmetaobject.h54
-rw-r--r--sources/pyside6/libpyside/feature_select.cpp798
-rw-r--r--sources/pyside6/libpyside/feature_select.h19
-rw-r--r--sources/pyside6/libpyside/globalreceiverv2.cpp322
-rw-r--r--sources/pyside6/libpyside/globalreceiverv2.h115
-rw-r--r--sources/pyside6/libpyside/libpyside.qrc5
-rw-r--r--sources/pyside6/libpyside/pyside.cpp1215
-rw-r--r--sources/pyside6/libpyside/pyside.h16
-rw-r--r--sources/pyside6/libpyside/pyside6.pc.in15
-rw-r--r--sources/pyside6/libpyside/pyside_numpy.cpp98
-rw-r--r--sources/pyside6/libpyside/pyside_numpy.h37
-rw-r--r--sources/pyside6/libpyside/pyside_p.h32
-rw-r--r--sources/pyside6/libpyside/pysideclassdecorator.cpp103
-rw-r--r--sources/pyside6/libpyside/pysideclassdecorator_p.h164
-rw-r--r--sources/pyside6/libpyside/pysideclassinfo.cpp158
-rw-r--r--sources/pyside6/libpyside/pysideclassinfo.h33
-rw-r--r--sources/pyside6/libpyside/pysideclassinfo_p.h43
-rw-r--r--sources/pyside6/libpyside/pysidecleanup.h20
-rw-r--r--sources/pyside6/libpyside/pysideinit.h27
-rw-r--r--sources/pyside6/libpyside/pysidelogging_p.h11
-rw-r--r--sources/pyside6/libpyside/pysidemacros.h18
-rw-r--r--sources/pyside6/libpyside/pysidemetafunction.cpp197
-rw-r--r--sources/pyside6/libpyside/pysidemetafunction.h38
-rw-r--r--sources/pyside6/libpyside/pysidemetafunction_p.h25
-rw-r--r--sources/pyside6/libpyside/pysidemetatype.h26
-rw-r--r--sources/pyside6/libpyside/pysideproperty.cpp600
-rw-r--r--sources/pyside6/libpyside/pysideproperty.h73
-rw-r--r--sources/pyside6/libpyside/pysideproperty_p.h169
-rw-r--r--sources/pyside6/libpyside/pysideqapp.h19
-rw-r--r--sources/pyside6/libpyside/pysideqenum.cpp197
-rw-r--r--sources/pyside6/libpyside/pysideqenum.h20
-rw-r--r--sources/pyside6/libpyside/pysideqhash.h24
-rw-r--r--sources/pyside6/libpyside/pysideqmetatype.h35
-rw-r--r--sources/pyside6/libpyside/pysideqobject.h70
-rw-r--r--sources/pyside6/libpyside/pysideqslotobject_p.cpp36
-rw-r--r--sources/pyside6/libpyside/pysideqslotobject_p.h39
-rw-r--r--sources/pyside6/libpyside/pysidesignal.cpp1335
-rw-r--r--sources/pyside6/libpyside/pysidesignal.h152
-rw-r--r--sources/pyside6/libpyside/pysidesignal_p.h60
-rw-r--r--sources/pyside6/libpyside/pysideslot.cpp183
-rw-r--r--sources/pyside6/libpyside/pysideslot_p.h28
-rw-r--r--sources/pyside6/libpyside/pysidestaticstrings.cpp40
-rw-r--r--sources/pyside6/libpyside/pysidestaticstrings.h38
-rw-r--r--sources/pyside6/libpyside/pysideutils.h69
-rw-r--r--sources/pyside6/libpyside/pysideweakref.cpp82
-rw-r--r--sources/pyside6/libpyside/pysideweakref.h18
-rw-r--r--sources/pyside6/libpyside/qobjectconnect.cpp336
-rw-r--r--sources/pyside6/libpyside/qobjectconnect.h47
-rw-r--r--sources/pyside6/libpyside/signalmanager.cpp815
-rw-r--r--sources/pyside6/libpyside/signalmanager.h100
-rw-r--r--sources/pyside6/libpysideqml/CMakeLists.txt115
-rw-r--r--sources/pyside6/libpysideqml/PySide6QmlConfig-spec.cmake.in7
-rw-r--r--sources/pyside6/libpysideqml/PySide6QmlConfig.cmake.in5
-rw-r--r--sources/pyside6/libpysideqml/PySide6QmlConfigVersion.cmake.in10
-rw-r--r--sources/pyside6/libpysideqml/pysideqml.cpp35
-rw-r--r--sources/pyside6/libpysideqml/pysideqml.h18
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlattached.cpp216
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlattached.h28
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlattached_p.h21
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlextended.cpp145
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlextended_p.h21
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlforeign.cpp92
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlforeign_p.h17
-rw-r--r--sources/pyside6/libpysideqml/pysideqmllistproperty.cpp307
-rw-r--r--sources/pyside6/libpysideqml/pysideqmllistproperty_p.h13
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlmacros.h18
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlmetacallerror.cpp67
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlmetacallerror_p.h21
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlnamedelement.cpp74
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlnamedelement_p.h11
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlregistertype.cpp757
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlregistertype.h99
-rw-r--r--sources/pyside6/libpysideqml/pysideqmlregistertype_p.h20
-rw-r--r--sources/pyside6/libpysideqml/pysideqmltypeinfo.cpp70
-rw-r--r--sources/pyside6/libpysideqml/pysideqmltypeinfo_p.h59
-rw-r--r--sources/pyside6/libpysideqml/pysideqmluncreatable.cpp118
-rw-r--r--sources/pyside6/libpysideqml/pysideqmluncreatable.h26
-rw-r--r--sources/pyside6/plugins/designer/CMakeLists.txt59
-rw-r--r--sources/pyside6/plugins/designer/designercustomwidgets.cpp261
-rw-r--r--sources/pyside6/plugins/designer/designercustomwidgets.h28
-rw-r--r--sources/pyside6/plugins/uitools/CMakeLists.txt35
-rw-r--r--sources/pyside6/plugins/uitools/customwidget.cpp104
-rw-r--r--sources/pyside6/plugins/uitools/customwidget.h37
-rw-r--r--sources/pyside6/plugins/uitools/customwidgets.cpp25
-rw-r--r--sources/pyside6/plugins/uitools/customwidgets.h35
-rw-r--r--sources/pyside6/pyside_version.py19
-rw-r--r--sources/pyside6/qtexampleicons/CMakeLists.txt52
-rw-r--r--sources/pyside6/qtexampleicons/module.c41
-rw-r--r--sources/pyside6/tests/CMakeLists.txt73
-rw-r--r--sources/pyside6/tests/Qt3DAnimation/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/Qt3DCore/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/Qt3DExtras/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/Qt3DExtras/Qt3DExtras.pyproject3
-rw-r--r--sources/pyside6/tests/Qt3DExtras/qt3dextras_test.py140
-rw-r--r--sources/pyside6/tests/Qt3DInput/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/Qt3DLogic/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/Qt3DQuick/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/Qt3DRender/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtAsyncio/CMakeLists.txt2
-rw-r--r--sources/pyside6/tests/QtAsyncio/QtAsyncio.pyproject3
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test.py51
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_task.py46
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_taskgroup.py57
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test_chain.py57
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test_executor.py47
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test_queues.py70
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test_threadsafe.py58
-rw-r--r--sources/pyside6/tests/QtAsyncio/qasyncio_test_time.py49
-rw-r--r--sources/pyside6/tests/QtAxContainer/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtBluetooth/CMakeLists.txt2
-rw-r--r--sources/pyside6/tests/QtBluetooth/QtBluetooth.pyproject4
-rw-r--r--sources/pyside6/tests/QtBluetooth/localdevice.py25
-rw-r--r--sources/pyside6/tests/QtBluetooth/lowenergy_characteristics.py51
-rw-r--r--sources/pyside6/tests/QtCharts/CMakeLists.txt2
-rw-r--r--sources/pyside6/tests/QtCharts/QtCharts.pyproject3
-rw-r--r--sources/pyside6/tests/QtCharts/qcharts_numpy_test.py49
-rw-r--r--sources/pyside6/tests/QtCharts/qcharts_test.py46
-rw-r--r--sources/pyside6/tests/QtConcurrent/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtCore/CMakeLists.txt148
-rw-r--r--sources/pyside6/tests/QtCore/QtCore.pyproject148
-rw-r--r--sources/pyside6/tests/QtCore/attr_cache_py3k.py36
-rw-r--r--sources/pyside6/tests/QtCore/blocking_signals_test.py154
-rw-r--r--sources/pyside6/tests/QtCore/bug_1019.py48
-rw-r--r--sources/pyside6/tests/QtCore/bug_1063.py41
-rw-r--r--sources/pyside6/tests/QtCore/bug_1069.py35
-rw-r--r--sources/pyside6/tests/QtCore/bug_1313.py58
-rw-r--r--sources/pyside6/tests/QtCore/bug_278_test.py34
-rw-r--r--sources/pyside6/tests/QtCore/bug_300_test.py29
-rw-r--r--sources/pyside6/tests/QtCore/bug_324.py43
-rw-r--r--sources/pyside6/tests/QtCore/bug_332.py30
-rw-r--r--sources/pyside6/tests/QtCore/bug_408.py41
-rw-r--r--sources/pyside6/tests/QtCore/bug_428.py31
-rw-r--r--sources/pyside6/tests/QtCore/bug_462.py59
-rw-r--r--sources/pyside6/tests/QtCore/bug_505.py38
-rw-r--r--sources/pyside6/tests/QtCore/bug_515.py35
-rw-r--r--sources/pyside6/tests/QtCore/bug_606.py46
-rw-r--r--sources/pyside6/tests/QtCore/bug_656.py23
-rw-r--r--sources/pyside6/tests/QtCore/bug_686.py118
-rw-r--r--sources/pyside6/tests/QtCore/bug_699.py30
-rw-r--r--sources/pyside6/tests/QtCore/bug_706.py40
-rw-r--r--sources/pyside6/tests/QtCore/bug_820.py82
-rw-r--r--sources/pyside6/tests/QtCore/bug_826.py38
-rw-r--r--sources/pyside6/tests/QtCore/bug_829.py54
-rw-r--r--sources/pyside6/tests/QtCore/bug_835.py80
-rw-r--r--sources/pyside6/tests/QtCore/bug_920.py36
-rw-r--r--sources/pyside6/tests/QtCore/bug_927.py50
-rw-r--r--sources/pyside6/tests/QtCore/bug_931.py35
-rw-r--r--sources/pyside6/tests/QtCore/bug_938.py27
-rw-r--r--sources/pyside6/tests/QtCore/bug_953.py35
-rw-r--r--sources/pyside6/tests/QtCore/bug_987.py26
-rw-r--r--sources/pyside6/tests/QtCore/bug_994.py38
-rw-r--r--sources/pyside6/tests/QtCore/bug_PYSIDE-164.py54
-rw-r--r--sources/pyside6/tests/QtCore/bug_PYSIDE-2745.py37
-rw-r--r--sources/pyside6/tests/QtCore/bug_PYSIDE-41.py49
-rw-r--r--sources/pyside6/tests/QtCore/bug_PYSIDE-42.py29
-rw-r--r--sources/pyside6/tests/QtCore/child_event_test.py64
-rw-r--r--sources/pyside6/tests/QtCore/classinfo_test.py114
-rw-r--r--sources/pyside6/tests/QtCore/deepcopy_test.py102
-rw-r--r--sources/pyside6/tests/QtCore/deletelater_test.py36
-rw-r--r--sources/pyside6/tests/QtCore/destroysignal_test.py78
-rw-r--r--sources/pyside6/tests/QtCore/duck_punching_test.py89
-rw-r--r--sources/pyside6/tests/QtCore/emoji_string_test.py51
-rw-r--r--sources/pyside6/tests/QtCore/errormessages_with_features_test.py102
-rw-r--r--sources/pyside6/tests/QtCore/feature_with_uic/window.py52
-rw-r--r--sources/pyside6/tests/QtCore/feature_with_uic/window.ui62
-rw-r--r--sources/pyside6/tests/QtCore/feature_with_uic_test.py59
-rw-r--r--sources/pyside6/tests/QtCore/hash_test.py101
-rw-r--r--sources/pyside6/tests/QtCore/inherits_test.py29
-rw-r--r--sources/pyside6/tests/QtCore/loggingcategorymacros_test.py84
-rw-r--r--sources/pyside6/tests/QtCore/max_signals.py48
-rw-r--r--sources/pyside6/tests/QtCore/missing_symbols_test.py28
-rw-r--r--sources/pyside6/tests/QtCore/mockclass_test.py40
-rw-r--r--sources/pyside6/tests/QtCore/multiple_feature_test.py116
-rw-r--r--sources/pyside6/tests/QtCore/python_conversion.py77
-rw-r--r--sources/pyside6/tests/QtCore/qabs_test.py31
-rw-r--r--sources/pyside6/tests/QtCore/qabstractitemmodel_test.py52
-rw-r--r--sources/pyside6/tests/QtCore/qanimationgroup_test.py37
-rw-r--r--sources/pyside6/tests/QtCore/qbitarray_test.py134
-rw-r--r--sources/pyside6/tests/QtCore/qbytearray_concatenation_operator_test.py40
-rw-r--r--sources/pyside6/tests/QtCore/qbytearray_operator_iadd_test.py70
-rw-r--r--sources/pyside6/tests/QtCore/qbytearray_operator_test.py92
-rw-r--r--sources/pyside6/tests/QtCore/qbytearray_test.py290
-rw-r--r--sources/pyside6/tests/QtCore/qcalendar_test.py29
-rw-r--r--sources/pyside6/tests/QtCore/qcbor_test.py62
-rw-r--r--sources/pyside6/tests/QtCore/qcollator_test.py43
-rw-r--r--sources/pyside6/tests/QtCore/qcommandlineparser_test.py38
-rw-r--r--sources/pyside6/tests/QtCore/qcoreapplication_argv_test.py25
-rw-r--r--sources/pyside6/tests/QtCore/qcoreapplication_instance_test.py31
-rw-r--r--sources/pyside6/tests/QtCore/qcoreapplication_test.py23
-rw-r--r--sources/pyside6/tests/QtCore/qdatastream_test.py326
-rw-r--r--sources/pyside6/tests/QtCore/qdate_test.py45
-rw-r--r--sources/pyside6/tests/QtCore/qdatetime_test.py35
-rw-r--r--sources/pyside6/tests/QtCore/qdir_test.py39
-rw-r--r--sources/pyside6/tests/QtCore/qeasingcurve_test.py42
-rw-r--r--sources/pyside6/tests/QtCore/qenum_test.py202
-rw-r--r--sources/pyside6/tests/QtCore/qevent_test.py36
-rw-r--r--sources/pyside6/tests/QtCore/qfile_test.py85
-rw-r--r--sources/pyside6/tests/QtCore/qfileinfo_test.py33
-rw-r--r--sources/pyside6/tests/QtCore/qfileread_test.py66
-rw-r--r--sources/pyside6/tests/QtCore/qflags_test.py131
-rw-r--r--sources/pyside6/tests/QtCore/qhandle_test.py28
-rw-r--r--sources/pyside6/tests/QtCore/qinstallmsghandler_test.py76
-rw-r--r--sources/pyside6/tests/QtCore/qiodevice_buffered_read_test.py78
-rw-r--r--sources/pyside6/tests/QtCore/qiopipe_test.py36
-rw-r--r--sources/pyside6/tests/QtCore/qjsondocument_test.py32
-rw-r--r--sources/pyside6/tests/QtCore/qlinef_test.py31
-rw-r--r--sources/pyside6/tests/QtCore/qlocale_test.py73
-rw-r--r--sources/pyside6/tests/QtCore/qlockfile_test.py42
-rw-r--r--sources/pyside6/tests/QtCore/qmessageauthenticationcode_test.py28
-rw-r--r--sources/pyside6/tests/QtCore/qmetaobject_test.py213
-rw-r--r--sources/pyside6/tests/QtCore/qmetatype_test.py43
-rw-r--r--sources/pyside6/tests/QtCore/qmimedatabase_test.py59
-rw-r--r--sources/pyside6/tests/QtCore/qmodelindex_internalpointer_test.py63
-rw-r--r--sources/pyside6/tests/QtCore/qobject_children_segfault_test.py42
-rw-r--r--sources/pyside6/tests/QtCore/qobject_connect_notify_test.py99
-rw-r--r--sources/pyside6/tests/QtCore/qobject_destructor.py33
-rw-r--r--sources/pyside6/tests/QtCore/qobject_event_filter_test.py150
-rw-r--r--sources/pyside6/tests/QtCore/qobject_inherits_test.py115
-rw-r--r--sources/pyside6/tests/QtCore/qobject_objectproperty_test.py42
-rw-r--r--sources/pyside6/tests/QtCore/qobject_parent_test.py335
-rw-r--r--sources/pyside6/tests/QtCore/qobject_property_test.py53
-rw-r--r--sources/pyside6/tests/QtCore/qobject_protected_methods_test.py50
-rw-r--r--sources/pyside6/tests/QtCore/qobject_test.py96
-rw-r--r--sources/pyside6/tests/QtCore/qobject_timer_event_test.py57
-rw-r--r--sources/pyside6/tests/QtCore/qobject_tr_as_instance_test.py54
-rw-r--r--sources/pyside6/tests/QtCore/qoperatingsystemversion_test.py24
-rw-r--r--sources/pyside6/tests/QtCore/qpoint_test.py32
-rw-r--r--sources/pyside6/tests/QtCore/qprocess_test.py40
-rw-r--r--sources/pyside6/tests/QtCore/qproperty_decorator.py54
-rw-r--r--sources/pyside6/tests/QtCore/qrandomgenerator_test.py33
-rw-r--r--sources/pyside6/tests/QtCore/qrect_test.py123
-rw-r--r--sources/pyside6/tests/QtCore/qregularexpression_test.py41
-rw-r--r--sources/pyside6/tests/QtCore/qresource_test.py56
-rw-r--r--sources/pyside6/tests/QtCore/qrunnable_test.py45
-rw-r--r--sources/pyside6/tests/QtCore/qsettings_test.ini4
-rw-r--r--sources/pyside6/tests/QtCore/qsettings_test.py130
-rw-r--r--sources/pyside6/tests/QtCore/qsharedmemory_client.py36
-rw-r--r--sources/pyside6/tests/QtCore/qsharedmemory_test.py73
-rw-r--r--sources/pyside6/tests/QtCore/qsize_test.py37
-rw-r--r--sources/pyside6/tests/QtCore/qslot_object_test.py54
-rw-r--r--sources/pyside6/tests/QtCore/qsocketnotifier_test.py38
-rw-r--r--sources/pyside6/tests/QtCore/qsrand_test.py33
-rw-r--r--sources/pyside6/tests/QtCore/qstandardpaths_test.py32
-rw-r--r--sources/pyside6/tests/QtCore/qstorageinfo_test.py26
-rw-r--r--sources/pyside6/tests/QtCore/qstring_test.py37
-rw-r--r--sources/pyside6/tests/QtCore/qsysinfo_test.py28
-rw-r--r--sources/pyside6/tests/QtCore/qtextstream_test.py92
-rw-r--r--sources/pyside6/tests/QtCore/qthread_prod_cons_test.py116
-rw-r--r--sources/pyside6/tests/QtCore/qthread_signal_test.py71
-rw-r--r--sources/pyside6/tests/QtCore/qthread_test.py84
-rw-r--r--sources/pyside6/tests/QtCore/qtimer_singleshot_test.py195
-rw-r--r--sources/pyside6/tests/QtCore/qtimer_timeout_test.py73
-rw-r--r--sources/pyside6/tests/QtCore/qtimezone_test.py27
-rw-r--r--sources/pyside6/tests/QtCore/qtnamespace_test.py30
-rw-r--r--sources/pyside6/tests/QtCore/quoteEnUS.txt1
-rw-r--r--sources/pyside6/tests/QtCore/qurl_test.py149
-rw-r--r--sources/pyside6/tests/QtCore/qurlquery_test.py39
-rw-r--r--sources/pyside6/tests/QtCore/quuid_test.py29
-rw-r--r--sources/pyside6/tests/QtCore/qversionnumber_test.py31
-rw-r--r--sources/pyside6/tests/QtCore/repr_test.py97
-rw-r--r--sources/pyside6/tests/QtCore/resources.qrc7
-rw-r--r--sources/pyside6/tests/QtCore/resources_mc.py3547
-rw-r--r--sources/pyside6/tests/QtCore/sample.pngbin0 -> 55944 bytes
-rw-r--r--sources/pyside6/tests/QtCore/setprop_on_ctor_test.py24
-rw-r--r--sources/pyside6/tests/QtCore/signal_sender.py91
-rw-r--r--sources/pyside6/tests/QtCore/snake_prop_feature_test.py143
-rw-r--r--sources/pyside6/tests/QtCore/staticMetaObject_test.py36
-rw-r--r--sources/pyside6/tests/QtCore/static_method_test.py65
-rw-r--r--sources/pyside6/tests/QtCore/thread_signals_test.py47
-rw-r--r--sources/pyside6/tests/QtCore/tr_noop_test.py66
-rw-r--r--sources/pyside6/tests/QtCore/translation_test.py102
-rw-r--r--sources/pyside6/tests/QtCore/translations/trans_latin.qmbin0 -> 125 bytes
-rw-r--r--sources/pyside6/tests/QtCore/translations/trans_latin.ts11
-rw-r--r--sources/pyside6/tests/QtCore/translations/trans_russian.qmbin0 -> 114 bytes
-rw-r--r--sources/pyside6/tests/QtCore/translations/trans_russian.ts11
-rw-r--r--sources/pyside6/tests/QtCore/unaryoperator_test.py53
-rw-r--r--sources/pyside6/tests/QtCore/unicode_test.py44
-rw-r--r--sources/pyside6/tests/QtCore/versioninfo_test.py32
-rw-r--r--sources/pyside6/tests/QtDBus/CMakeLists.txt6
-rw-r--r--sources/pyside6/tests/QtDBus/QtDBus.pyproject3
-rw-r--r--sources/pyside6/tests/QtDBus/test_dbus.py44
-rw-r--r--sources/pyside6/tests/QtDataVisualization/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtDataVisualization/QtDataVisualization.pyproject3
-rw-r--r--sources/pyside6/tests/QtDataVisualization/datavisualization_test.py104
-rw-r--r--sources/pyside6/tests/QtDesigner/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtGraphs/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtGui/CMakeLists.txt60
-rw-r--r--sources/pyside6/tests/QtGui/QtGui.pyproject56
-rw-r--r--sources/pyside6/tests/QtGui/bug_1091.py25
-rw-r--r--sources/pyside6/tests/QtGui/bug_367.py35
-rw-r--r--sources/pyside6/tests/QtGui/bug_493.py32
-rw-r--r--sources/pyside6/tests/QtGui/bug_606.py45
-rw-r--r--sources/pyside6/tests/QtGui/bug_617.py34
-rw-r--r--sources/pyside6/tests/QtGui/bug_652.py47
-rw-r--r--sources/pyside6/tests/QtGui/bug_660.py40
-rw-r--r--sources/pyside6/tests/QtGui/bug_716.py20
-rw-r--r--sources/pyside6/tests/QtGui/bug_740.py25
-rw-r--r--sources/pyside6/tests/QtGui/bug_743.py27
-rw-r--r--sources/pyside6/tests/QtGui/bug_785.py41
-rw-r--r--sources/pyside6/tests/QtGui/bug_991.py28
-rw-r--r--sources/pyside6/tests/QtGui/bug_PYSIDE-344.py49
-rw-r--r--sources/pyside6/tests/QtGui/deepcopy_test.py140
-rw-r--r--sources/pyside6/tests/QtGui/event_filter_test.py51
-rw-r--r--sources/pyside6/tests/QtGui/float_to_int_implicit_conversion_test.py45
-rw-r--r--sources/pyside6/tests/QtGui/pyside_reload_test.py63
-rw-r--r--sources/pyside6/tests/QtGui/qbrush_test.py43
-rw-r--r--sources/pyside6/tests/QtGui/qcolor_reduce_test.py44
-rw-r--r--sources/pyside6/tests/QtGui/qcolor_test.py111
-rw-r--r--sources/pyside6/tests/QtGui/qcursor_test.py29
-rw-r--r--sources/pyside6/tests/QtGui/qdatastream_gui_operators_test.py45
-rw-r--r--sources/pyside6/tests/QtGui/qdesktopservices_test.py27
-rw-r--r--sources/pyside6/tests/QtGui/qfont_test.py35
-rw-r--r--sources/pyside6/tests/QtGui/qfontmetrics_test.py215
-rw-r--r--sources/pyside6/tests/QtGui/qguiapplication_test.py23
-rw-r--r--sources/pyside6/tests/QtGui/qicon_test.py48
-rw-r--r--sources/pyside6/tests/QtGui/qimage_test.py56
-rw-r--r--sources/pyside6/tests/QtGui/qimage_win_test.py41
-rw-r--r--sources/pyside6/tests/QtGui/qitemselection_test.py31
-rw-r--r--sources/pyside6/tests/QtGui/qkeysequence_test.py36
-rw-r--r--sources/pyside6/tests/QtGui/qpainter_test.py115
-rw-r--r--sources/pyside6/tests/QtGui/qpdfwriter_test.py32
-rw-r--r--sources/pyside6/tests/QtGui/qpen_test.py57
-rw-r--r--sources/pyside6/tests/QtGui/qpixelformat_test.py40
-rw-r--r--sources/pyside6/tests/QtGui/qpixmap_constructor.py260
-rw-r--r--sources/pyside6/tests/QtGui/qpixmap_test.py67
-rw-r--r--sources/pyside6/tests/QtGui/qpixmapcache_test.py56
-rw-r--r--sources/pyside6/tests/QtGui/qpolygonf_test.py42
-rw-r--r--sources/pyside6/tests/QtGui/qradialgradient_test.py41
-rw-r--r--sources/pyside6/tests/QtGui/qrasterwindow_test.py77
-rw-r--r--sources/pyside6/tests/QtGui/qregion_test.py40
-rw-r--r--sources/pyside6/tests/QtGui/qshortcut_test.py60
-rw-r--r--sources/pyside6/tests/QtGui/qstandarditemmodel_test.py85
-rw-r--r--sources/pyside6/tests/QtGui/qstring_qkeysequence_test.py42
-rw-r--r--sources/pyside6/tests/QtGui/qstylehints_test.py26
-rw-r--r--sources/pyside6/tests/QtGui/qtextdocument_functions.py37
-rw-r--r--sources/pyside6/tests/QtGui/qtextdocument_undoredo_test.py42
-rw-r--r--sources/pyside6/tests/QtGui/qtextdocumentwriter_test.py31
-rw-r--r--sources/pyside6/tests/QtGui/qtextline_test.py39
-rw-r--r--sources/pyside6/tests/QtGui/qtransform_test.py90
-rw-r--r--sources/pyside6/tests/QtGui/repr_test.py96
-rw-r--r--sources/pyside6/tests/QtGui/sample.pngbin0 -> 55944 bytes
-rw-r--r--sources/pyside6/tests/QtGui/timed_app_and_patching_test.py27
-rw-r--r--sources/pyside6/tests/QtGui/xpm_data.py237
-rw-r--r--sources/pyside6/tests/QtHelp/CMakeLists.txt2
-rw-r--r--sources/pyside6/tests/QtHelp/QtHelp.pyproject4
-rw-r--r--sources/pyside6/tests/QtHelp/help_test.py25
-rw-r--r--sources/pyside6/tests/QtHelp/helpsearchengine_test.py28
-rw-r--r--sources/pyside6/tests/QtHttpServer/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtLocation/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtLocation/QtLocation.pyproject3
-rw-r--r--sources/pyside6/tests/QtLocation/location.py26
-rw-r--r--sources/pyside6/tests/QtMultimedia/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtMultimedia/QtMultimedia.pyproject3
-rw-r--r--sources/pyside6/tests/QtMultimedia/audio_test.py58
-rw-r--r--sources/pyside6/tests/QtMultimediaWidgets/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtMultimediaWidgets/QtMultimediaWidgets.pyproject3
-rw-r--r--sources/pyside6/tests/QtMultimediaWidgets/qmultimediawidgets.py44
-rw-r--r--sources/pyside6/tests/QtNetwork/CMakeLists.txt13
-rw-r--r--sources/pyside6/tests/QtNetwork/QtNetwork.pyproject11
-rw-r--r--sources/pyside6/tests/QtNetwork/accessManager_test.py55
-rw-r--r--sources/pyside6/tests/QtNetwork/bug_1084.py28
-rw-r--r--sources/pyside6/tests/QtNetwork/bug_446.py58
-rw-r--r--sources/pyside6/tests/QtNetwork/dnslookup_test.py46
-rw-r--r--sources/pyside6/tests/QtNetwork/qhostinfo_test.py76
-rw-r--r--sources/pyside6/tests/QtNetwork/qipv6address_test.py34
-rw-r--r--sources/pyside6/tests/QtNetwork/qpassworddigestor_test.py28
-rw-r--r--sources/pyside6/tests/QtNetwork/tcpserver_test.py39
-rw-r--r--sources/pyside6/tests/QtNetwork/udpsocket_test.py65
-rw-r--r--sources/pyside6/tests/QtNetworkAuth/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtNfc/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtNfc/QtNfc.pyproject3
-rw-r--r--sources/pyside6/tests/QtNfc/test_nfc.py29
-rw-r--r--sources/pyside6/tests/QtOpenGL/CMakeLists.txt2
-rw-r--r--sources/pyside6/tests/QtOpenGL/QtOpenGL.pyproject4
-rw-r--r--sources/pyside6/tests/QtOpenGL/qopenglbuffer_test.py77
-rw-r--r--sources/pyside6/tests/QtOpenGL/qopenglwindow_test.py96
-rw-r--r--sources/pyside6/tests/QtOpenGLWidgets/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtPdf/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtPdfWidgets/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtPositioning/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtPositioning/QtPositioning.pyproject3
-rw-r--r--sources/pyside6/tests/QtPositioning/positioning.py28
-rw-r--r--sources/pyside6/tests/QtPrintSupport/CMakeLists.txt2
-rw-r--r--sources/pyside6/tests/QtPrintSupport/QtPrintSupport.pyproject4
-rw-r--r--sources/pyside6/tests/QtPrintSupport/bug_500.py25
-rw-r--r--sources/pyside6/tests/QtPrintSupport/returnquadruplesofnumbers_test.py65
-rw-r--r--sources/pyside6/tests/QtQml/CMakeLists.txt37
-rw-r--r--sources/pyside6/tests/QtQml/ModuleType.qml8
-rw-r--r--sources/pyside6/tests/QtQml/QtQml.pyproject65
-rw-r--r--sources/pyside6/tests/QtQml/bug_1029.py43
-rw-r--r--sources/pyside6/tests/QtQml/bug_1029.qml18
-rw-r--r--sources/pyside6/tests/QtQml/bug_451.py93
-rw-r--r--sources/pyside6/tests/QtQml/bug_451.qml31
-rw-r--r--sources/pyside6/tests/QtQml/bug_456.py63
-rw-r--r--sources/pyside6/tests/QtQml/bug_456.qml36
-rw-r--r--sources/pyside6/tests/QtQml/bug_557.py28
-rw-r--r--sources/pyside6/tests/QtQml/bug_726.py63
-rw-r--r--sources/pyside6/tests/QtQml/bug_726.qml36
-rw-r--r--sources/pyside6/tests/QtQml/bug_814.py65
-rw-r--r--sources/pyside6/tests/QtQml/bug_814.qml13
-rw-r--r--sources/pyside6/tests/QtQml/bug_825.py80
-rw-r--r--sources/pyside6/tests/QtQml/bug_825.qml13
-rw-r--r--sources/pyside6/tests/QtQml/bug_825_old.py80
-rw-r--r--sources/pyside6/tests/QtQml/bug_847.py70
-rw-r--r--sources/pyside6/tests/QtQml/bug_847.qml37
-rw-r--r--sources/pyside6/tests/QtQml/bug_915.py40
-rw-r--r--sources/pyside6/tests/QtQml/bug_926.py57
-rw-r--r--sources/pyside6/tests/QtQml/bug_926.qml20
-rw-r--r--sources/pyside6/tests/QtQml/bug_951.py51
-rw-r--r--sources/pyside6/tests/QtQml/bug_951.qml10
-rw-r--r--sources/pyside6/tests/QtQml/bug_995.py31
-rw-r--r--sources/pyside6/tests/QtQml/bug_995.qml15
-rw-r--r--sources/pyside6/tests/QtQml/bug_997.py51
-rw-r--r--sources/pyside6/tests/QtQml/bug_997.qml13
-rw-r--r--sources/pyside6/tests/QtQml/connect_python_qml.py55
-rw-r--r--sources/pyside6/tests/QtQml/connect_python_qml.qml23
-rw-r--r--sources/pyside6/tests/QtQml/groupedproperty.py112
-rw-r--r--sources/pyside6/tests/QtQml/groupedproperty.qml9
-rw-r--r--sources/pyside6/tests/QtQml/hw.qml23
-rw-r--r--sources/pyside6/tests/QtQml/javascript_exceptions.py91
-rw-r--r--sources/pyside6/tests/QtQml/javascript_exceptions.qml28
-rw-r--r--sources/pyside6/tests/QtQml/listproperty.py136
-rw-r--r--sources/pyside6/tests/QtQml/listproperty.qml50
-rw-r--r--sources/pyside6/tests/QtQml/qmlregistertype_test.py53
-rw-r--r--sources/pyside6/tests/QtQml/qmlregistertype_test.qml7
-rw-r--r--sources/pyside6/tests/QtQml/qqmlapplicationengine.qml23
-rw-r--r--sources/pyside6/tests/QtQml/qqmlapplicationengine_test.py38
-rw-r--r--sources/pyside6/tests/QtQml/qqmlcomponent_test.py36
-rw-r--r--sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.py84
-rw-r--r--sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.qml42
-rw-r--r--sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile_component.qml10
-rw-r--r--sources/pyside6/tests/QtQml/qqmlnetwork_test.py76
-rw-r--r--sources/pyside6/tests/QtQml/qquickitem_grabToImage.py69
-rw-r--r--sources/pyside6/tests/QtQml/qquickitem_grabToImage.qml44
-rw-r--r--sources/pyside6/tests/QtQml/qquickview_test.py87
-rw-r--r--sources/pyside6/tests/QtQml/registerattached.py101
-rw-r--r--sources/pyside6/tests/QtQml/registerattached.qml20
-rw-r--r--sources/pyside6/tests/QtQml/registerextended.py74
-rw-r--r--sources/pyside6/tests/QtQml/registerextended.qml9
-rw-r--r--sources/pyside6/tests/QtQml/registerforeign.py52
-rw-r--r--sources/pyside6/tests/QtQml/registerforeign.qml8
-rw-r--r--sources/pyside6/tests/QtQml/registerparserstatus.py60
-rw-r--r--sources/pyside6/tests/QtQml/registerparserstatus.qml8
-rw-r--r--sources/pyside6/tests/QtQml/registerqmlfile.py30
-rw-r--r--sources/pyside6/tests/QtQml/registersingletontype.py152
-rw-r--r--sources/pyside6/tests/QtQml/registersingletontype.qml14
-rw-r--r--sources/pyside6/tests/QtQml/registertype.py116
-rw-r--r--sources/pyside6/tests/QtQml/registertype.qml32
-rw-r--r--sources/pyside6/tests/QtQml/registeruncreatable.qml13
-rw-r--r--sources/pyside6/tests/QtQml/registeruncreatabletype.py62
-rw-r--r--sources/pyside6/tests/QtQml/signal_arguments.py61
-rw-r--r--sources/pyside6/tests/QtQml/signal_arguments.qml36
-rw-r--r--sources/pyside6/tests/QtQml/signal_types.py124
-rw-r--r--sources/pyside6/tests/QtQml/signal_types.qml26
-rw-r--r--sources/pyside6/tests/QtQml/view.qml19
-rw-r--r--sources/pyside6/tests/QtQml/viewmodel.qml16
-rw-r--r--sources/pyside6/tests/QtQuick/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtQuick3D/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtQuickControls2/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtQuickTest/CMakeLists.txt3
-rw-r--r--sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/data/tst_setup.qml20
-rw-r--r--sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/ImportPathQmlType.qml3
-rw-r--r--sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/qmldir2
-rw-r--r--sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/quicktestmainwithsetup.pyproject4
-rw-r--r--sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/tst_quicktestmainwithsetup.py46
-rw-r--r--sources/pyside6/tests/QtQuickWidgets/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtRemoteObjects/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtScxml/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtScxml/QtScxml.pyproject3
-rw-r--r--sources/pyside6/tests/QtScxml/test_dynamic.py53
-rw-r--r--sources/pyside6/tests/QtScxml/trafficlight.scxml64
-rw-r--r--sources/pyside6/tests/QtSensors/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtSensors/QtSensors.pyproject3
-rw-r--r--sources/pyside6/tests/QtSensors/sensors.py46
-rw-r--r--sources/pyside6/tests/QtSerialBus/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtSerialPort/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtSerialPort/QtSerialPort.pyproject3
-rw-r--r--sources/pyside6/tests/QtSerialPort/serial.py72
-rw-r--r--sources/pyside6/tests/QtSpatialAudio/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtSql/CMakeLists.txt6
-rw-r--r--sources/pyside6/tests/QtSql/QtSql.pyproject5
-rw-r--r--sources/pyside6/tests/QtSql/bug_1013.py43
-rw-r--r--sources/pyside6/tests/QtSql/qsqldatabaseandqueries_test.py86
-rw-r--r--sources/pyside6/tests/QtSql/qvarianttype_test.py39
-rw-r--r--sources/pyside6/tests/QtStateMachine/CMakeLists.txt8
-rw-r--r--sources/pyside6/tests/QtStateMachine/QtStateMachine.pyproject7
-rw-r--r--sources/pyside6/tests/QtStateMachine/bug_1031.py18
-rw-r--r--sources/pyside6/tests/QtStateMachine/qabstracttransition_test.py175
-rw-r--r--sources/pyside6/tests/QtStateMachine/qstate_test.py49
-rw-r--r--sources/pyside6/tests/QtStateMachine/qstatemachine_test.py68
-rw-r--r--sources/pyside6/tests/QtStateMachine/setprop_on_ctor_test.py24
-rw-r--r--sources/pyside6/tests/QtSvg/CMakeLists.txt2
-rw-r--r--sources/pyside6/tests/QtSvg/QtSvg.pyproject4
-rw-r--r--sources/pyside6/tests/QtSvg/qsvggenerator_test.py47
-rw-r--r--sources/pyside6/tests/QtSvg/qsvgrenderer_test.py37
-rw-r--r--sources/pyside6/tests/QtSvg/tiger.svg730
-rw-r--r--sources/pyside6/tests/QtSvgWidgets/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtSvgWidgets/QtSvgWidgets.pyproject3
-rw-r--r--sources/pyside6/tests/QtSvgWidgets/qsvgwidget_test.py41
-rw-r--r--sources/pyside6/tests/QtTest/CMakeLists.txt9
-rw-r--r--sources/pyside6/tests/QtTest/QtTest.pyproject7
-rw-r--r--sources/pyside6/tests/QtTest/click_test.py38
-rw-r--r--sources/pyside6/tests/QtTest/eventfilter_test.py57
-rw-r--r--sources/pyside6/tests/QtTest/qsignalspy_test.py42
-rw-r--r--sources/pyside6/tests/QtTest/qvalidator_test.py122
-rw-r--r--sources/pyside6/tests/QtTest/touchevent_test.py63
-rw-r--r--sources/pyside6/tests/QtTextToSpeech/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtTextToSpeech/QtTextToSpeech.pyproject3
-rw-r--r--sources/pyside6/tests/QtTextToSpeech/qtexttospeech_test.py49
-rw-r--r--sources/pyside6/tests/QtUiTools/CMakeLists.txt16
-rw-r--r--sources/pyside6/tests/QtUiTools/QtUiTools.pyproject28
-rw-r--r--sources/pyside6/tests/QtUiTools/action.ui16
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_1060.py32
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_1060.ui19
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_360.py48
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_376.py31
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_392.py63
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_426.py32
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_426.ui19
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_552.py37
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_552.ui42
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_797.py25
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_909.py37
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_909.ui31
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_913.py32
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_913.ui57
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_958.py40
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_958.ui48
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_965.py35
-rw-r--r--sources/pyside6/tests/QtUiTools/bug_965.ui27
-rw-r--r--sources/pyside6/tests/QtUiTools/loadUiType_test.py52
-rw-r--r--sources/pyside6/tests/QtUiTools/minimal.ui6
-rw-r--r--sources/pyside6/tests/QtUiTools/pycustomwidget.ui36
-rw-r--r--sources/pyside6/tests/QtUiTools/pycustomwidget2.ui48
-rw-r--r--sources/pyside6/tests/QtUiTools/test.ui48
-rw-r--r--sources/pyside6/tests/QtUiTools/ui_test.py25
-rw-r--r--sources/pyside6/tests/QtUiTools/uiloader_test.py54
-rw-r--r--sources/pyside6/tests/QtWebChannel/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtWebEngineCore/CMakeLists.txt5
-rw-r--r--sources/pyside6/tests/QtWebEngineCore/QtWebEngineCore.pyproject4
-rw-r--r--sources/pyside6/tests/QtWebEngineCore/qwebenginecookiestore_test.py46
-rw-r--r--sources/pyside6/tests/QtWebEngineCore/resources/index.html12
-rw-r--r--sources/pyside6/tests/QtWebEngineCore/web_engine_custom_scheme.py70
-rw-r--r--sources/pyside6/tests/QtWebEngineQuick/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtWebEngineWidgets/CMakeLists.txt4
-rw-r--r--sources/pyside6/tests/QtWebEngineWidgets/QtWebEngineWidgets.pyproject3
-rw-r--r--sources/pyside6/tests/QtWebEngineWidgets/fox.html7
-rw-r--r--sources/pyside6/tests/QtWebEngineWidgets/pyside-474-qtwebengineview.py59
-rw-r--r--sources/pyside6/tests/QtWebSockets/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtWidgets/CMakeLists.txt134
-rw-r--r--sources/pyside6/tests/QtWidgets/QtWidgets.pyproject130
-rw-r--r--sources/pyside6/tests/QtWidgets/action_clear.py68
-rw-r--r--sources/pyside6/tests/QtWidgets/add_action_test.py60
-rw-r--r--sources/pyside6/tests/QtWidgets/api2_test.py73
-rw-r--r--sources/pyside6/tests/QtWidgets/application_test.py42
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_1002.py35
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_1006.py99
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_1048.py21
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_1077.py32
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_172.py26
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_243.py28
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_307.py37
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_338.py38
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_389.py28
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_400.py38
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_429.py22
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_430.py29
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_433.py28
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_467.py32
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_480.py39
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_512.py34
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_525.py35
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_546.py27
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_547.py73
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_549.py28
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_569.py30
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_575.py33
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_576.py49
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_585.py38
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_589.py32
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_635.py41
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_640.py23
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_653.py29
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_662.py42
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_667.py37
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_668.py34
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_674.py35
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_675.py28
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_688.py98
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_693.py42
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_696.py38
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_711.py34
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_722.py36
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_728.py39
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_736.py30
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_750.py38
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_778.py34
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_793.py45
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_811.py46
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_834.py33
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_836.py46
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_844.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_854.py54
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_860.py46
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_862.py78
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_871.py53
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_879.py43
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_919.py51
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_921.py67
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_941.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_964.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_967.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_972.py52
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_979.py21
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_988.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/bug_998.py23
-rw-r--r--sources/pyside6/tests/QtWidgets/customproxywidget_test.py47
-rw-r--r--sources/pyside6/tests/QtWidgets/grandparent_method_test.py35
-rw-r--r--sources/pyside6/tests/QtWidgets/hashabletype_test.py30
-rw-r--r--sources/pyside6/tests/QtWidgets/import_test.py2
-rw-r--r--sources/pyside6/tests/QtWidgets/keep_reference_test.py91
-rw-r--r--sources/pyside6/tests/QtWidgets/missing_symbols_test.py43
-rw-r--r--sources/pyside6/tests/QtWidgets/paint_event_test.py68
-rw-r--r--sources/pyside6/tests/QtWidgets/parent_method_test.py38
-rw-r--r--sources/pyside6/tests/QtWidgets/private_mangle_test.py94
-rw-r--r--sources/pyside6/tests/QtWidgets/python_properties_test.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/qabstracttextdocumentlayout_test.py59
-rw-r--r--sources/pyside6/tests/QtWidgets/qaccessible_test.py138
-rw-r--r--sources/pyside6/tests/QtWidgets/qaction_test.py65
-rw-r--r--sources/pyside6/tests/QtWidgets/qapp_issue_585.py53
-rw-r--r--sources/pyside6/tests/QtWidgets/qapp_test.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/qapplication_exit_segfault_test.py30
-rw-r--r--sources/pyside6/tests/QtWidgets/qapplication_test.py23
-rw-r--r--sources/pyside6/tests/QtWidgets/qcolormap_test.py25
-rw-r--r--sources/pyside6/tests/QtWidgets/qdialog_test.py52
-rw-r--r--sources/pyside6/tests/QtWidgets/qdynamic_signal.py41
-rw-r--r--sources/pyside6/tests/QtWidgets/qfontdialog_test.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/qformlayout_test.py99
-rw-r--r--sources/pyside6/tests/QtWidgets/qgraphicsitem_isblocked_test.py41
-rw-r--r--sources/pyside6/tests/QtWidgets/qgraphicsitem_test.py50
-rw-r--r--sources/pyside6/tests/QtWidgets/qgraphicsobjectreimpl_test.py62
-rw-r--r--sources/pyside6/tests/QtWidgets/qgraphicsproxywidget_test.py42
-rw-r--r--sources/pyside6/tests/QtWidgets/qgraphicsscene_test.py213
-rw-r--r--sources/pyside6/tests/QtWidgets/qinputdialog_get_test.py47
-rw-r--r--sources/pyside6/tests/QtWidgets/qkeysequenceedit_test.py31
-rw-r--r--sources/pyside6/tests/QtWidgets/qlabel_test.py77
-rw-r--r--sources/pyside6/tests/QtWidgets/qlayout_ref_test.py171
-rw-r--r--sources/pyside6/tests/QtWidgets/qlayout_test.py139
-rw-r--r--sources/pyside6/tests/QtWidgets/qlcdnumber_test.py33
-rw-r--r--sources/pyside6/tests/QtWidgets/qlistwidget_test.py77
-rw-r--r--sources/pyside6/tests/QtWidgets/qlistwidgetitem_test.py42
-rw-r--r--sources/pyside6/tests/QtWidgets/qmainwindow_test.py97
-rw-r--r--sources/pyside6/tests/QtWidgets/qmenu_test.py76
-rw-r--r--sources/pyside6/tests/QtWidgets/qmenuadd_test.py33
-rw-r--r--sources/pyside6/tests/QtWidgets/qobject_mi_test.py51
-rw-r--r--sources/pyside6/tests/QtWidgets/qpicture_test.py48
-rw-r--r--sources/pyside6/tests/QtWidgets/qpushbutton_test.py54
-rw-r--r--sources/pyside6/tests/QtWidgets/qsplitter_test.py29
-rw-r--r--sources/pyside6/tests/QtWidgets/qstyle_test.py76
-rw-r--r--sources/pyside6/tests/QtWidgets/qstyleoption_test.py43
-rw-r--r--sources/pyside6/tests/QtWidgets/qtableview_test.py28
-rw-r--r--sources/pyside6/tests/QtWidgets/qtabwidget_test.py43
-rw-r--r--sources/pyside6/tests/QtWidgets/qtabwidgetclear_test.py48
-rw-r--r--sources/pyside6/tests/QtWidgets/qtextedit_signal_test.py50
-rw-r--r--sources/pyside6/tests/QtWidgets/qtextedit_test.py45
-rw-r--r--sources/pyside6/tests/QtWidgets/qtoolbar_test.py50
-rw-r--r--sources/pyside6/tests/QtWidgets/qtoolbox_test.py45
-rw-r--r--sources/pyside6/tests/QtWidgets/qtreeview_test.py84
-rw-r--r--sources/pyside6/tests/QtWidgets/qtreewidget_test.py48
-rw-r--r--sources/pyside6/tests/QtWidgets/qtreewidgetitem_test.py47
-rw-r--r--sources/pyside6/tests/QtWidgets/qvariant_test.py142
-rw-r--r--sources/pyside6/tests/QtWidgets/qwidget_setlayout_test.py44
-rw-r--r--sources/pyside6/tests/QtWidgets/qwidget_test.py61
-rw-r--r--sources/pyside6/tests/QtWidgets/reference_count_test.py84
-rw-r--r--sources/pyside6/tests/QtWidgets/sample.pngbin0 -> 55944 bytes
-rw-r--r--sources/pyside6/tests/QtWidgets/signature_test.py59
-rw-r--r--sources/pyside6/tests/QtWidgets/standardpixmap_test.py27
-rw-r--r--sources/pyside6/tests/QtWidgets/test_module_template.py27
-rw-r--r--sources/pyside6/tests/QtWidgets/virtual_protected_inheritance_test.py84
-rw-r--r--sources/pyside6/tests/QtWidgets/virtual_pure_override_test.py61
-rw-r--r--sources/pyside6/tests/QtWidgets/wrong_return_test.py39
-rw-r--r--sources/pyside6/tests/QtXml/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/QtXml/QtXml.pyproject3
-rw-r--r--sources/pyside6/tests/QtXml/qdomdocument_test.py82
-rw-r--r--sources/pyside6/tests/init_paths.py78
-rw-r--r--sources/pyside6/tests/mac/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/mac/qmacstyle_test.py32
-rw-r--r--sources/pyside6/tests/manually/README.txt5
-rw-r--r--sources/pyside6/tests/manually/bug_841.py57
-rw-r--r--sources/pyside6/tests/manually/lazytiming.py38
-rw-r--r--sources/pyside6/tests/pysidetest/CMakeLists.txt171
-rw-r--r--sources/pyside6/tests/pysidetest/all_modules_load_test.py29
-rw-r--r--sources/pyside6/tests/pysidetest/bug_1016.py26
-rw-r--r--sources/pyside6/tests/pysidetest/constructor_properties_test.py127
-rw-r--r--sources/pyside6/tests/pysidetest/container_test.py63
-rw-r--r--sources/pyside6/tests/pysidetest/containertest.cpp59
-rw-r--r--sources/pyside6/tests/pysidetest/containertest.h34
-rw-r--r--sources/pyside6/tests/pysidetest/curr_errors.txt12
-rw-r--r--sources/pyside6/tests/pysidetest/decoratedslot_test.py50
-rw-r--r--sources/pyside6/tests/pysidetest/delegatecreateseditor_test.py81
-rw-r--r--sources/pyside6/tests/pysidetest/enum_test.py186
-rw-r--r--sources/pyside6/tests/pysidetest/flagstest.cpp11
-rw-r--r--sources/pyside6/tests/pysidetest/flagstest.h32
-rw-r--r--sources/pyside6/tests/pysidetest/hiddenobject.cpp19
-rw-r--r--sources/pyside6/tests/pysidetest/hiddenobject.h27
-rw-r--r--sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py109
-rw-r--r--sources/pyside6/tests/pysidetest/iterable_test.py68
-rw-r--r--sources/pyside6/tests/pysidetest/list_signal_test.py34
-rw-r--r--sources/pyside6/tests/pysidetest/mixin_signal_slots_test.py205
-rw-r--r--sources/pyside6/tests/pysidetest/mock_as_slot_test.py33
-rw-r--r--sources/pyside6/tests/pysidetest/modelview_test.py85
-rw-r--r--sources/pyside6/tests/pysidetest/multiple_inheritance_test.py189
-rw-r--r--sources/pyside6/tests/pysidetest/new_inherited_functions_test.py159
-rw-r--r--sources/pyside6/tests/pysidetest/notify_id.py65
-rw-r--r--sources/pyside6/tests/pysidetest/properties_test.py108
-rw-r--r--sources/pyside6/tests/pysidetest/property_python_test.py222
-rw-r--r--sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py136
-rw-r--r--sources/pyside6/tests/pysidetest/pysidetest.pyproject33
-rw-r--r--sources/pyside6/tests/pysidetest/pysidetest_global.h16
-rw-r--r--sources/pyside6/tests/pysidetest/pysidetest_macros.h18
-rw-r--r--sources/pyside6/tests/pysidetest/qapp_like_a_macro_test.py68
-rw-r--r--sources/pyside6/tests/pysidetest/qvariant_test.py67
-rw-r--r--sources/pyside6/tests/pysidetest/repr_test.py64
-rw-r--r--sources/pyside6/tests/pysidetest/shared_pointer_test.py54
-rw-r--r--sources/pyside6/tests/pysidetest/sharedpointertestbench.cpp46
-rw-r--r--sources/pyside6/tests/pysidetest/sharedpointertestbench.h29
-rw-r--r--sources/pyside6/tests/pysidetest/signal_slot_warning.py50
-rw-r--r--sources/pyside6/tests/pysidetest/signal_tp_descr_get_test.py60
-rw-r--r--sources/pyside6/tests/pysidetest/signalandnamespace_test.py103
-rw-r--r--sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py96
-rw-r--r--sources/pyside6/tests/pysidetest/signalinstance_equality_test.py85
-rw-r--r--sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py96
-rw-r--r--sources/pyside6/tests/pysidetest/snake_case_sub.py23
-rw-r--r--sources/pyside6/tests/pysidetest/snake_case_test.py38
-rw-r--r--sources/pyside6/tests/pysidetest/symbols.filter7
-rw-r--r--sources/pyside6/tests/pysidetest/testobject.cpp73
-rw-r--r--sources/pyside6/tests/pysidetest/testobject.h140
-rw-r--r--sources/pyside6/tests/pysidetest/testqvariantenum.cpp29
-rw-r--r--sources/pyside6/tests/pysidetest/testqvariantenum.h35
-rw-r--r--sources/pyside6/tests/pysidetest/testview.cpp27
-rw-r--r--sources/pyside6/tests/pysidetest/testview.h35
-rw-r--r--sources/pyside6/tests/pysidetest/true_property_test.py58
-rw-r--r--sources/pyside6/tests/pysidetest/typedef_signal_test.py52
-rw-r--r--sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml80
-rw-r--r--sources/pyside6/tests/pysidetest/version_test.py31
-rw-r--r--sources/pyside6/tests/registry/CMakeLists.txt4
-rw-r--r--sources/pyside6/tests/registry/existence_test.py229
-rw-r--r--sources/pyside6/tests/registry/init_platform.py210
-rw-r--r--sources/pyside6/tests/registry/scrape_testresults.py338
-rw-r--r--sources/pyside6/tests/registry/util.py149
-rwxr-xr-xsources/pyside6/tests/run_test.sh15
-rw-r--r--sources/pyside6/tests/signals/CMakeLists.txt47
-rw-r--r--sources/pyside6/tests/signals/anonymous_slot_leak_test.py55
-rw-r--r--sources/pyside6/tests/signals/args_dont_match_test.py36
-rw-r--r--sources/pyside6/tests/signals/bug_189.py38
-rw-r--r--sources/pyside6/tests/signals/bug_311.py54
-rw-r--r--sources/pyside6/tests/signals/bug_312.py45
-rw-r--r--sources/pyside6/tests/signals/bug_319.py47
-rw-r--r--sources/pyside6/tests/signals/bug_79.py59
-rw-r--r--sources/pyside6/tests/signals/decorators_test.py95
-rw-r--r--sources/pyside6/tests/signals/disconnect_test.py70
-rw-r--r--sources/pyside6/tests/signals/invalid_callback_test.py41
-rw-r--r--sources/pyside6/tests/signals/lambda_gui_test.py50
-rw-r--r--sources/pyside6/tests/signals/lambda_test.py123
-rw-r--r--sources/pyside6/tests/signals/leaking_signal_test.py27
-rw-r--r--sources/pyside6/tests/signals/multiple_connections_gui_test.py60
-rw-r--r--sources/pyside6/tests/signals/multiple_connections_test.py90
-rw-r--r--sources/pyside6/tests/signals/pysignal_test.py203
-rw-r--r--sources/pyside6/tests/signals/qobject_callable_connect_test.py45
-rw-r--r--sources/pyside6/tests/signals/qobject_destroyed_test.py39
-rw-r--r--sources/pyside6/tests/signals/qobject_receivers_test.py65
-rw-r--r--sources/pyside6/tests/signals/qobject_sender_test.py117
-rw-r--r--sources/pyside6/tests/signals/ref01_test.py39
-rw-r--r--sources/pyside6/tests/signals/ref02_test.py60
-rw-r--r--sources/pyside6/tests/signals/ref03_test.py42
-rw-r--r--sources/pyside6/tests/signals/ref04_test.py58
-rw-r--r--sources/pyside6/tests/signals/ref05_test.py58
-rw-r--r--sources/pyside6/tests/signals/ref06_test.py61
-rw-r--r--sources/pyside6/tests/signals/segfault_proxyparent_test.py78
-rw-r--r--sources/pyside6/tests/signals/self_connect_test.py64
-rw-r--r--sources/pyside6/tests/signals/short_circuit_test.py85
-rw-r--r--sources/pyside6/tests/signals/signal2signal_connect_test.py121
-rw-r--r--sources/pyside6/tests/signals/signal_across_threads.py82
-rw-r--r--sources/pyside6/tests/signals/signal_autoconnect_test.py41
-rw-r--r--sources/pyside6/tests/signals/signal_connectiontype_support_test.py42
-rw-r--r--sources/pyside6/tests/signals/signal_emission_gui_test.py118
-rw-r--r--sources/pyside6/tests/signals/signal_emission_test.py142
-rw-r--r--sources/pyside6/tests/signals/signal_enum_test.py57
-rw-r--r--sources/pyside6/tests/signals/signal_func_test.py31
-rw-r--r--sources/pyside6/tests/signals/signal_manager_refcount_test.py36
-rw-r--r--sources/pyside6/tests/signals/signal_newenum_test.py50
-rw-r--r--sources/pyside6/tests/signals/signal_number_limit_test.py74
-rw-r--r--sources/pyside6/tests/signals/signal_object_test.py98
-rw-r--r--sources/pyside6/tests/signals/signal_signature_test.py105
-rw-r--r--sources/pyside6/tests/signals/signal_with_primitive_type_test.py38
-rw-r--r--sources/pyside6/tests/signals/signals.pyproject19
-rw-r--r--sources/pyside6/tests/signals/slot_reference_count_test.py70
-rw-r--r--sources/pyside6/tests/signals/static_metaobject_test.py83
-rw-r--r--sources/pyside6/tests/support/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/support/voidptr_test.py49
-rw-r--r--sources/pyside6/tests/tools/__init__.py1
-rw-r--r--sources/pyside6/tests/tools/list-class-hierarchy.py88
-rw-r--r--sources/pyside6/tests/tools/metaobjectdump/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/tools/metaobjectdump/baseline_default_birthdayparty.json1
-rw-r--r--sources/pyside6/tests/tools/metaobjectdump/baseline_default_person.json1
-rw-r--r--sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_birthdayparty.json1
-rw-r--r--sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_person.json1
-rw-r--r--sources/pyside6/tests/tools/metaobjectdump/baseline_property_happybirthdaysong.json1
-rw-r--r--sources/pyside6/tests/tools/metaobjectdump/test_metaobjectdump.py73
-rw-r--r--sources/pyside6/tests/tools/pyside6-android-deploy/CMakeLists.txt3
-rw-r--r--sources/pyside6/tests/tools/pyside6-android-deploy/extensive_android_deploy_test.py88
-rw-r--r--sources/pyside6/tests/tools/pyside6-android-deploy/test_pyside6_android_deploy.py274
-rw-r--r--sources/pyside6/tests/tools/pyside6-deploy/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/tools/pyside6-deploy/extensive_deploy_test.py88
-rw-r--r--sources/pyside6/tests/tools/pyside6-deploy/test_pyside6_deploy.py400
-rw-r--r--sources/pyside6/tests/tools/pyside6-qml/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/tools/pyside6-qml/test_pyside6_qml.py75
-rw-r--r--sources/pyside6/tests/util/color.py14
-rw-r--r--sources/pyside6/tests/util/helper/__init__.py1
-rw-r--r--sources/pyside6/tests/util/helper/basicpyslotcase.py33
-rw-r--r--sources/pyside6/tests/util/helper/docmodifier.py91
-rw-r--r--sources/pyside6/tests/util/helper/helper.py37
-rw-r--r--sources/pyside6/tests/util/helper/helper.pyproject5
-rw-r--r--sources/pyside6/tests/util/helper/timedqapplication.py27
-rw-r--r--sources/pyside6/tests/util/helper/timedqguiapplication.py27
-rw-r--r--sources/pyside6/tests/util/helper/usesqapplication.py43
-rw-r--r--sources/pyside6/tests/util/httpd.py153
-rw-r--r--sources/pyside6/tests/util/processtimer.py54
-rwxr-xr-xsources/pyside6/tests/util/rename_imports.sh16
-rw-r--r--sources/pyside6/tests/util/test_processtimer.py73
-rw-r--r--sources/pyside6/tests/util/valgrind-python.supp349
1492 files changed, 112604 insertions, 0 deletions
diff --git a/sources/pyside6/.cmake.conf b/sources/pyside6/.cmake.conf
new file mode 100644
index 000000000..201688f47
--- /dev/null
+++ b/sources/pyside6/.cmake.conf
@@ -0,0 +1,5 @@
+set(pyside_MAJOR_VERSION "6")
+set(pyside_MINOR_VERSION "7")
+set(pyside_MICRO_VERSION "0")
+set(pyside_PRE_RELEASE_VERSION_TYPE "a")
+set(pyside_PRE_RELEASE_VERSION "1")
diff --git a/sources/pyside6/.gitattributes b/sources/pyside6/.gitattributes
new file mode 100644
index 000000000..adbe833c1
--- /dev/null
+++ b/sources/pyside6/.gitattributes
@@ -0,0 +1,2 @@
+.gitignore export-ignore
+.gitattributes export-ignore
diff --git a/sources/pyside6/.gitignore b/sources/pyside6/.gitignore
new file mode 100644
index 000000000..b2e7c9d7d
--- /dev/null
+++ b/sources/pyside6/.gitignore
@@ -0,0 +1,6 @@
+build
+*.kdev4
+.kdev4
+*~
+*.log
+*.pyc
diff --git a/sources/pyside6/CMakeLists.txt b/sources/pyside6/CMakeLists.txt
new file mode 100644
index 000000000..f45c07114
--- /dev/null
+++ b/sources/pyside6/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(cmake/Macros/icecc.cmake) # this must be the first line!
+
+cmake_minimum_required(VERSION 3.18)
+cmake_policy(VERSION 3.18)
+
+include(".cmake.conf")
+project(pysidebindings)
+
+include(cmake/PySideSetup.cmake)
+
+get_rpath_base_token(base)
+
+if (${STANDALONE})
+ set(CMAKE_INSTALL_RPATH ${base}/ ${base}/Qt/lib ${base}/../shiboken6/)
+else()
+ set(CMAKE_INSTALL_RPATH ${base}/ ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBS} ${base}/../shiboken6/)
+endif()
+
+add_subdirectory(libpyside)
+
+if(Qt${QT_MAJOR_VERSION}Qml_FOUND)
+ add_subdirectory(libpysideqml)
+endif()
+
+if(Qt${QT_MAJOR_VERSION}UiTools_FOUND)
+ add_subdirectory(plugins/uitools)
+ find_package(Qt6 COMPONENTS Designer)
+ # PYSIDE-535: Enable when PyPy supports embedding
+ if (Qt${QT_MAJOR_VERSION}Designer_FOUND AND NOT PYPY_VERSION)
+ add_subdirectory(plugins/designer)
+ endif()
+endif()
+
+add_subdirectory(PySide6)
+if(BUILD_TESTS)
+ enable_testing()
+ add_subdirectory(tests)
+endif()
+
+add_subdirectory(doc)
+
+add_subdirectory(qtexampleicons)
diff --git a/sources/pyside6/COPYING b/sources/pyside6/COPYING
new file mode 100644
index 000000000..9315102f7
--- /dev/null
+++ b/sources/pyside6/COPYING
@@ -0,0 +1,501 @@
+GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
diff --git a/sources/pyside6/PySide6/CMakeLists.txt b/sources/pyside6/PySide6/CMakeLists.txt
new file mode 100644
index 000000000..37b7a6c9c
--- /dev/null
+++ b/sources/pyside6/PySide6/CMakeLists.txt
@@ -0,0 +1,114 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(pyside6)
+
+# Configure include based on platform
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/global.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/pyside6_global.h" @ONLY)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" @ONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/_config.py" @ONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__feature__.pyi.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/__feature__.pyi" @ONLY)
+# typing support for mypy
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/py.typed.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/py.typed" @ONLY)
+
+# Use absolute path instead of relative path, to avoid ninja build errors due to
+# duplicate file dependency inconsistency.
+set(pyside_version_relative_path "${CMAKE_CURRENT_SOURCE_DIR}/../pyside_version.py")
+get_filename_component(pyside_version_path ${pyside_version_relative_path} ABSOLUTE)
+configure_file("${pyside_version_path}"
+ "${CMAKE_CURRENT_BINARY_DIR}/_git_pyside_version.py" @ONLY)
+
+# qt.conf needs to be placed next to QtWebEngineProcess so that the executable uses the correct
+# Prefix location leading to an existing icu data file. It is needed on Windows, Linux, and macOS
+# non-framework build. In framework build, instead of using qt.conf, Bundle querying is used.
+if (WIN32 OR (UNIX AND NOT APPLE) OR (APPLE AND NOT QtCore_is_framework))
+
+ if (WIN32)
+ # On Windows, the QtWebEngineProcess is directly located in the Prefix, due to not using
+ # a "Qt" subfolder like on the other platforms.
+ set(QT_CONF_PREFIX ".")
+ else()
+ # On Linux and non-framework macOS, the QtWebEngineProcess is in ./libexec, so prefix is one
+ # level higher.
+ set(QT_CONF_PREFIX "..")
+ endif()
+
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/qt.conf.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" @ONLY)
+endif()
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/__init__.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/__init__.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/generate_pyi.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/generate_pyi.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/deprecated.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/deprecated.py" COPYONLY)
+
+# now compile all modules.
+file(READ "${CMAKE_CURRENT_BINARY_DIR}/pyside6_global.h" pyside6_global_contents)
+
+foreach(shortname IN LISTS all_module_shortnames)
+ set(name "Qt${QT_MAJOR_VERSION}${shortname}")
+ set(_qt_module_name "${name}")
+ if ("${shortname}" STREQUAL "OpenGLFunctions")
+ set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui")
+ endif()
+ HAS_QT_MODULE(${_qt_module_name}_FOUND Qt${shortname})
+
+ # Create a module header consisting of pyside6_global.h and the module
+ # include. Note: The contents of pyside6_global.h must be copied instead of
+ # just #including it since shiboken will otherwise generate an
+ # #include <pyside6_global.h> for the the type entries originating from it
+ # (cf AbstractMetaBuilderPrivate::setInclude()).
+ set(module_header "${CMAKE_CURRENT_BINARY_DIR}/Qt${shortname}_global.h")
+ set(module_header_content "")
+ set(pre_header "${CMAKE_CURRENT_BINARY_DIR}/Qt${shortname}/Qt${shortname}_global.pre.h")
+ if(EXISTS "${pre_header}")
+ file(READ "${pre_header}" pre_header_content)
+ set(module_header_content "${pre_header_content}")
+ endif()
+ set(module_header_content "${module_header_content}\n${pyside6_global_contents}")
+ # AxContainer/AxServer from Active Qt do not have module headers
+ if(NOT "${shortname}" STREQUAL "AxContainer" AND NOT "${shortname}" STREQUAL "OpenGLFunctions")
+ set(module_header_content "${module_header_content}\n#include <Qt${shortname}/Qt${shortname}>")
+ endif()
+ set(post_header "${CMAKE_CURRENT_BINARY_DIR}/Qt${shortname}/Qt${shortname}_global.post.h")
+ if(EXISTS "${post_header}")
+ file(READ "${post_header}" post_header_content)
+ set(module_header_content "${module_header_content}\n${post_header_content}")
+ endif()
+ file(WRITE ${module_header} "${module_header_content}")
+endforeach()
+
+# install
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/__init__.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside6_SUFFIX}")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside6_SUFFIX}")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_git_pyside_version.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside6_SUFFIX}")
+install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/support"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside6_SUFFIX}")
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/common.xml
+ DESTINATION share/PySide6${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/core_common.xml
+ DESTINATION share/PySide6${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/gui_common.xml
+ DESTINATION share/PySide6${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/widgets_common.xml
+ DESTINATION share/PySide6${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/datavisualization_common.xml
+ DESTINATION share/PySide6${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/opengl_common.xml
+ DESTINATION share/PySide6${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pyside6_global.h
+ DESTINATION include/${BINDING_NAME}${pyside6_SUFFIX})
+
+install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/QtAsyncio"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside6_SUFFIX}")
diff --git a/sources/pyside6/PySide6/Qt3DAnimation/CMakeLists.txt b/sources/pyside6/PySide6/Qt3DAnimation/CMakeLists.txt
new file mode 100644
index 000000000..d9169924e
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DAnimation/CMakeLists.txt
@@ -0,0 +1,69 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(Qt3DAnimation)
+
+set(Qt3DAnimation_SRC
+${Qt3DAnimation_GEN_DIR}/qt3danimation_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractanimation_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractanimationclip_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractchannelmapping_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractclipanimator_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractclipblendnode_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qadditiveclipblend_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationaspect_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationcallback_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationclip_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationclipdata_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationcliploader_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationcontroller_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationgroup_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qblendedclipanimator_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qcallbackmapping_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qchannel_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qchannelcomponent_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qchannelmapper_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qchannelmapping_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qclipanimator_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qclipblendvalue_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qclock_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qkeyframe_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qkeyframeanimation_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qlerpclipblend_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qmorphinganimation_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qmorphtarget_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qskeletonmapping_wrapper.cpp
+${Qt3DAnimation_GEN_DIR}/qt3danimation_qvertexblendanimation_wrapper.cpp
+# module is always needed
+${Qt3DAnimation_GEN_DIR}/qt3danimation_module_wrapper.cpp)
+
+set(Qt3DAnimation_include_dirs
+ ${Qt3DAnimation_SOURCE_DIR}
+ ${Qt3DAnimation_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DRender_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DAnimation_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtOpenGL_GEN_DIR}
+ ${Qt3DCore_GEN_DIR}
+ ${Qt3DRender_GEN_DIR}
+ ${Qt3DAnimation_GEN_DIR})
+
+set(Qt3DAnimation_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}3DAnimation_LIBRARIES})
+
+set(Qt3DAnimation_deps Qt3DRender)
+
+create_pyside_module(NAME Qt3DAnimation
+ INCLUDE_DIRS Qt3DAnimation_include_dirs
+ LIBRARIES Qt3DAnimation_libraries
+ DEPS Qt3DAnimation_deps
+ TYPESYSTEM_PATH Qt3DAnimation_SOURCE_DIR
+ SOURCES Qt3DAnimation_SRC
+ TYPESYSTEM_NAME ${Qt3DAnimation_BINARY_DIR}/typesystem_3danimation.xml)
diff --git a/sources/pyside6/PySide6/Qt3DAnimation/typesystem_3danimation.xml b/sources/pyside6/PySide6/Qt3DAnimation/typesystem_3danimation.xml
new file mode 100644
index 000000000..61af82d6d
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DAnimation/typesystem_3danimation.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.Qt3DAnimation"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="Qt3DRender/typesystem_3drender.xml" generate="no"/>
+ <namespace-type name="Qt3DAnimation">
+ <object-type name="QAbstractAnimation">
+ <enum-type name="AnimationType"/>
+ <!-- Disambiguate from QtCore/qabstractanimation.h -->
+ <include file-name="Qt3DAnimation/qabstractanimation.h" location="global"/>
+ </object-type>
+ <object-type name="QAbstractAnimationClip"/>
+ <value-type name="QAnimationClipData" since="6.1"/>
+ <object-type name="QAbstractChannelMapping"/>
+ <object-type name="QAbstractClipAnimator">
+ <enum-type name="Loops"/>
+ </object-type>
+ <object-type name="QAbstractClipBlendNode"/>
+ <object-type name="QAdditiveClipBlend"/>
+ <object-type name="QAnimationAspect"/>
+ <object-type name="QAnimationCallback">
+ <enum-type name="Flag"/>
+ </object-type>
+ <object-type name="QAnimationClip"/>
+ <object-type name="QAnimationClipLoader">
+ <enum-type name="Status"/>
+ </object-type>
+ <object-type name="QAnimationController"/>
+ <object-type name="QAnimationGroup">
+ <!-- Disambiguate from QtCore/qanimationgroup.h -->
+ <include file-name="Qt3DAnimation/qanimationgroup.h" location="global"/>
+ </object-type>
+ <object-type name="QBlendedClipAnimator"/>
+ <value-type name="QChannel"/>
+ <value-type name="QChannelComponent"/>
+ <object-type name="QCallbackMapping"/>
+ <object-type name="QChannelMapper" since="6.1"/>
+ <object-type name="QChannelMapping"/>
+ <object-type name="QClipAnimator"/>
+ <object-type name="QClipBlendValue"/>
+ <object-type name="QClock"/>
+ <object-type name="QKeyFrame">
+ <enum-type name="InterpolationType"/>
+ </object-type>
+ <object-type name="QKeyframeAnimation">
+ <enum-type name="RepeatMode"/>
+ </object-type>
+ <object-type name="QLerpClipBlend"/>
+ <object-type name="QMorphingAnimation">
+ <enum-type name="Method"/>
+ </object-type>
+ <object-type name="QMorphTarget"/>
+ <object-type name="QSkeletonMapping"/>
+ <object-type name="QVertexBlendAnimation"/>
+ </namespace-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/Qt3DCore/CMakeLists.txt b/sources/pyside6/PySide6/Qt3DCore/CMakeLists.txt
new file mode 100644
index 000000000..cd2699f11
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DCore/CMakeLists.txt
@@ -0,0 +1,62 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(Qt3DCore)
+
+set(Qt3DCore_SRC
+${Qt3DCore_GEN_DIR}/qsharedpointer_qaspectjob_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qsharedpointer_qbackendnodemapper_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qsharedpointer_qentity_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qabstractaspect_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qabstractfunctor_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qabstractskeleton_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qarmature_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qaspectengine_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qaspectjob_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qattribute_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qbackendnode_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qbackendnodemapper_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qboundingvolume_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qbuffer_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qcomponent_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qcoreaspect_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qcoresettings_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qentity_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qgeometry_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qgeometryview_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qjoint_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qnode_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qnodeid_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qnodeidtypepair_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qskeleton_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qskeletonloader_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_qtransform_wrapper.cpp
+${Qt3DCore_GEN_DIR}/qt3dcore_wrapper.cpp
+# module is always needed
+${Qt3DCore_GEN_DIR}/qt3dcore_module_wrapper.cpp)
+
+set(Qt3DCore_include_dirs
+ ${Qt3DCore_SOURCE_DIR}
+ ${Qt3DCore_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtNetwork_GEN_DIR})
+
+set(Qt3DCore_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}3DCore_LIBRARIES})
+
+set(Qt3DCore_deps QtGui QtNetwork)
+
+create_pyside_module(NAME Qt3DCore
+ INCLUDE_DIRS Qt3DCore_include_dirs
+ LIBRARIES Qt3DCore_libraries
+ DEPS Qt3DCore_deps
+ TYPESYSTEM_PATH Qt3DCore_SOURCE_DIR
+ SOURCES Qt3DCore_SRC
+ TYPESYSTEM_NAME ${Qt3DCore_BINARY_DIR}/typesystem_3dcore.xml)
diff --git a/sources/pyside6/PySide6/Qt3DCore/typesystem_3dcore.xml b/sources/pyside6/PySide6/Qt3DCore/typesystem_3dcore.xml
new file mode 100644
index 000000000..985c459b6
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DCore/typesystem_3dcore.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.Qt3DCore"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <smart-pointer-type name="QSharedPointer" type="shared" getter="data"
+ reset-method="reset"
+ instantiations="Qt3DCore::QAspectJob=Qt3DCore::QAspectJobPtr,Qt3DCore::QBackendNodeMapper=Qt3DCore::QBackendNodeMapperPtr,Qt3DCore::QEntity=Qt3DCore::QEntityPtr"/>
+ <namespace-type name="Qt3DCore" generate-using="no">
+ <object-type name="QAbstractAspect"/>
+ <object-type name="QAbstractFunctor"/>
+ <object-type name="QAbstractSkeleton"/>
+ <object-type name="QArmature"/>
+ <object-type name="QAspectEngine">
+ <enum-type name="RunMode"/>
+ <modify-function signature="registerAspect(Qt3DCore::QAbstractAspect*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAspectJob"/>
+ <object-type name="QBackendNode">
+ <enum-type name="Mode"/>
+ </object-type>
+ <object-type name="QBackendNodeMapper"/>
+ <object-type name="QAttribute">
+ <enum-type name="AttributeType"/>
+ <enum-type name="VertexBaseType"/>
+ </object-type>
+ <!-- TODO: Solve issues related to windows and a unresolved
+ external symbol
+ <object-type name="QBackendNodeMapper"/>-->
+ <object-type name="QBoundingVolume"/>
+ <object-type name="QBuffer">
+ <enum-type name="AccessType"/>
+ <enum-type name="UsageType"/>
+ <!-- Disambiguate from QtCore/qbuffer.h -->
+ <include file-name="Qt3DCore/qbuffer.h" location="global"/>
+ </object-type>
+ <object-type name="QComponent"/>
+ <object-type name="QEntity">
+ <modify-function signature="addComponent(Qt3DCore::QComponent*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QCoreAspect"/>
+ <object-type name="QCoreSettings"/>
+ <object-type name="QGeometry"/>
+ <object-type name="QGeometryView">
+ <enum-type name="PrimitiveType"/>
+ </object-type>
+ <object-type name="QJoint">
+ <modify-function signature="addChildJoint(Qt3DCore::QJoint*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QNode"/>
+ <value-type name="QNodeId"/>
+ <value-type name="QNodeIdTypePair"/>
+ <object-type name="QSkeleton"/>
+ <object-type name="QSkeletonLoader">
+ <enum-type name="Status"/>
+ </object-type>
+ <object-type name="QTransform">
+ <!-- Disambiguate from QtGui/qtransform.h -->
+ <include file-name="Qt3DCore/qtransform.h" location="global"/>
+ </object-type>
+ </namespace-type>
+
+ <!-- QtNetwork is pulled in via QtBluetoothDepends. -->
+ <suppress-warning text="^Scoped enum 'Q(Ocsp)|(Dtls).*' does not have a type entry.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/Qt3DExtras/CMakeLists.txt b/sources/pyside6/PySide6/Qt3DExtras/CMakeLists.txt
new file mode 100644
index 000000000..6f6f637fe
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DExtras/CMakeLists.txt
@@ -0,0 +1,85 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(Qt3DExtras)
+
+set(Qt3DExtras_SRC
+${Qt3DExtras_GEN_DIR}/qt3dextras_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractcameracontroller_inputstate_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractcameracontroller_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractspritesheet_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qconegeometry_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qconegeometryview_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qconemesh_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qcuboidgeometry_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qcuboidgeometryview_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qcuboidmesh_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qcylindergeometry_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qcylindergeometryview_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qcylindermesh_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qdiffusemapmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qdiffusespecularmapmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qdiffusespecularmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qextrudedtextgeometry_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qextrudedtextmesh_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qfirstpersoncameracontroller_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qforwardrenderer_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qgoochmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qmetalroughmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qmorphphongmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qnormaldiffusemapmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qnormaldiffusemapalphamaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qnormaldiffusespecularmapmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qorbitcameracontroller_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qpervertexcolormaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qphongmaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qphongalphamaterial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qplanegeometry_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qplanegeometryview_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qplanemesh_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qskyboxentity_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qspheregeometry_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qspheregeometryview_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qspheremesh_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qspritegrid_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qspritesheet_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qspritesheetitem_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qtext2dentity_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qtexturematerial_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qtorusgeometry_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qtorusgeometryview_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qtorusmesh_wrapper.cpp
+${Qt3DExtras_GEN_DIR}/qt3dextras_qt3dwindow_wrapper.cpp
+# module is always needed
+${Qt3DExtras_GEN_DIR}/qt3dextras_module_wrapper.cpp)
+
+
+set(Qt3DExtras_include_dirs
+ ${Qt3DExtras_SOURCE_DIR}
+ ${Qt3DExtras_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DRender_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}3DExtras_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtOpenGL_GEN_DIR}
+ ${Qt3DCore_GEN_DIR}
+ ${Qt3DRender_GEN_DIR})
+
+set(Qt3DExtras_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}3DExtras_LIBRARIES})
+
+set(Qt3DExtras_deps Qt3DRender)
+
+create_pyside_module(NAME Qt3DExtras
+ INCLUDE_DIRS Qt3DExtras_include_dirs
+ LIBRARIES Qt3DExtras_libraries
+ DEPS Qt3DExtras_deps
+ TYPESYSTEM_PATH Qt3DExtras_SOURCE_DIR
+ SOURCES Qt3DExtras_SRC
+ TYPESYSTEM_NAME ${Qt3DExtras_BINARY_DIR}/typesystem_3dextras.xml)
diff --git a/sources/pyside6/PySide6/Qt3DExtras/typesystem_3dextras.xml b/sources/pyside6/PySide6/Qt3DExtras/typesystem_3dextras.xml
new file mode 100644
index 000000000..d281ae15f
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DExtras/typesystem_3dextras.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.Qt3DExtras"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="Qt3DRender/typesystem_3drender.xml" generate="no"/>
+ <namespace-type name="Qt3DExtras">
+ <object-type name="QAbstractCameraController">
+ <value-type name="InputState"/>
+ </object-type>
+ <object-type name="QAbstractSpriteSheet"/>
+ <object-type name="QConeGeometry"/>
+ <object-type name="QConeMesh"/>
+ <object-type name="QConeGeometryView"/>
+ <object-type name="QCuboidGeometry"/>
+ <object-type name="QCuboidGeometryView"/>
+ <object-type name="QCuboidMesh"/>
+ <object-type name="QCylinderGeometry"/>
+ <object-type name="QCylinderGeometryView"/>
+ <object-type name="QCylinderMesh"/>
+ <object-type name="QDiffuseMapMaterial"/>
+ <object-type name="QDiffuseSpecularMaterial"/>
+ <object-type name="QDiffuseSpecularMapMaterial"/>
+ <object-type name="QExtrudedTextGeometry"/>
+ <object-type name="QExtrudedTextMesh"/>
+ <object-type name="QFirstPersonCameraController"/>
+ <object-type name="QForwardRenderer"/>
+ <object-type name="QGoochMaterial"/>
+ <object-type name="QMetalRoughMaterial"/>
+ <object-type name="QMorphPhongMaterial"/>
+ <object-type name="QNormalDiffuseMapAlphaMaterial"/>
+ <object-type name="QNormalDiffuseMapMaterial"/>
+ <object-type name="QNormalDiffuseSpecularMapMaterial"/>
+ <object-type name="QOrbitCameraController"/>
+ <object-type name="QPerVertexColorMaterial"/>
+ <object-type name="QPhongMaterial"/>
+ <object-type name="QPhongAlphaMaterial"/>
+ <object-type name="QPlaneGeometry"/>
+ <object-type name="QPlaneGeometryView"/>
+ <object-type name="QPlaneMesh"/>
+ <object-type name="QSkyboxEntity"/>
+ <object-type name="QSphereGeometry"/>
+ <object-type name="QSphereGeometryView"/>
+ <object-type name="QSphereMesh"/>
+ <object-type name="QSpriteGrid"/>
+ <object-type name="QSpriteSheet"/>
+ <object-type name="QSpriteSheetItem"/>
+ <object-type name="QText2DEntity"/>
+ <object-type name="QTextureMaterial"/>
+ <object-type name="QTorusGeometry"/>
+ <object-type name="QTorusGeometryView"/>
+ <object-type name="QTorusMesh"/>
+ <object-type name="Qt3DWindow"/>
+ </namespace-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/Qt3DInput/CMakeLists.txt b/sources/pyside6/PySide6/Qt3DInput/CMakeLists.txt
new file mode 100644
index 000000000..c27c27718
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DInput/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(Qt3DInput)
+
+set(Qt3DInput_SRC
+${Qt3DInput_GEN_DIR}/qt3dinput_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qabstractactioninput_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qabstractaxisinput_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qabstractphysicaldevice_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qaction_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qactioninput_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qanalogaxisinput_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qaxis_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qaxisaccumulator_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qaxissetting_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qbuttonaxisinput_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qinputaspect_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qinputchord_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qinputsequence_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qinputsettings_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qkeyboardhandler_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qkeyevent_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qlogicaldevice_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qkeyboarddevice_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qmousedevice_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qmouseevent_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qwheelevent_wrapper.cpp
+${Qt3DInput_GEN_DIR}/qt3dinput_qmousehandler_wrapper.cpp
+# module is always needed
+${Qt3DInput_GEN_DIR}/qt3dinput_module_wrapper.cpp)
+
+set(Qt3DInput_include_dirs
+ ${Qt3DInput_SOURCE_DIR}
+ ${Qt3DInput_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${Qt3DCore_GEN_DIR})
+
+set(Qt3DInput_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}3DInput_LIBRARIES})
+
+set(Qt3DInput_deps Qt3DCore)
+
+create_pyside_module(NAME Qt3DInput
+ INCLUDE_DIRS Qt3DInput_include_dirs
+ LIBRARIES Qt3DInput_libraries
+ DEPS Qt3DInput_deps
+ TYPESYSTEM_PATH Qt3DInput_SOURCE_DIR
+ SOURCES Qt3DInput_SRC
+ TYPESYSTEM_NAME ${Qt3DInput_BINARY_DIR}/typesystem_3dinput.xml)
diff --git a/sources/pyside6/PySide6/Qt3DInput/typesystem_3dinput.xml b/sources/pyside6/PySide6/Qt3DInput/typesystem_3dinput.xml
new file mode 100644
index 000000000..fbdfc5961
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DInput/typesystem_3dinput.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.Qt3DInput"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="Qt3DCore/typesystem_3dcore.xml" generate="no"/>
+ <namespace-type name="Qt3DInput">
+ <object-type name="QAbstractActionInput"/>
+ <object-type name="QAbstractAxisInput"/>
+ <object-type name="QAbstractPhysicalDevice"/>
+ <object-type name="QAction">
+ <!-- Disambiguate from QtGui/qaction.h -->
+ <include file-name="Qt3DInput/qaction.h" location="global"/>
+ </object-type>
+ <object-type name="QActionInput"/>
+ <object-type name="QAnalogAxisInput"/>
+ <object-type name="QAxis"/>
+ <object-type name="QAxisAccumulator">
+ <enum-type name="SourceAxisType"/>
+ </object-type>
+ <object-type name="QAxisSetting"/>
+ <object-type name="QButtonAxisInput"/>
+ <object-type name="QInputAspect"/>
+ <object-type name="QInputChord"/>
+ <!-- On windows this raises the following error:
+ type 'Qt3DInput::QInputDeviceIntegration' is specified in typesystem, but not defined.
+ This could potentially lead to compilation errors.
+ <object-type name="QInputDeviceIntegration"/>
+ -->
+ <object-type name="QInputSequence"/>
+ <object-type name="QInputSettings"/>
+ <object-type name="QKeyboardDevice"/>
+ <object-type name="QKeyboardHandler"/>
+ <object-type name="QKeyEvent"/>
+ <object-type name="QLogicalDevice"/>
+ <object-type name="QMouseDevice">
+ <enum-type name="Axis"/>
+ </object-type>
+ <object-type name="QMouseEvent">
+ <enum-type name="Buttons"/>
+ <enum-type name="Modifiers"/>
+ </object-type>
+ <object-type name="QWheelEvent">
+ <enum-type name="Buttons"/>
+ <enum-type name="Modifiers"/>
+ </object-type>
+ <object-type name="QMouseHandler"/>
+ <!-- On windows this raise the following error:
+ qt3dinput_module_wrapper.cpp.obj : error LNK2019:
+ unresolved external symbol "void __cdecl init_Qt3DInput_QPhysicalDeviceCreatedChangeBase(struct _object *)"
+ (?init_Qt3DInput_QPhysicalDeviceCreatedChangeBase@@YAXPAU_object@@@Z) referenced in function _PyInit_Qt3DInput
+ <object-type name="QPhysicalDeviceCreatedChangeBase"/>
+ -->
+ </namespace-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/Qt3DLogic/CMakeLists.txt b/sources/pyside6/PySide6/Qt3DLogic/CMakeLists.txt
new file mode 100644
index 000000000..b9da0cceb
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DLogic/CMakeLists.txt
@@ -0,0 +1,35 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(Qt3DLogic)
+
+set(Qt3DLogic_SRC
+${Qt3DLogic_GEN_DIR}/qt3dlogic_wrapper.cpp
+${Qt3DLogic_GEN_DIR}/qt3dlogic_qframeaction_wrapper.cpp
+${Qt3DLogic_GEN_DIR}/qt3dlogic_qlogicaspect_wrapper.cpp
+# module is always needed
+${Qt3DLogic_GEN_DIR}/qt3dlogic_module_wrapper.cpp)
+
+set(Qt3DLogic_include_dirs
+ ${Qt3DLogic_SOURCE_DIR}
+ ${Qt3DLogic_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${Qt3DCore_GEN_DIR})
+
+set(Qt3DLogic_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}3DLogic_LIBRARIES})
+
+set(Qt3DLogic_deps Qt3DCore)
+
+create_pyside_module(NAME Qt3DLogic
+ INCLUDE_DIRS Qt3DLogic_include_dirs
+ LIBRARIES Qt3DLogic_libraries
+ DEPS Qt3DLogic_deps
+ TYPESYSTEM_PATH Qt3DLogic_SOURCE_DIR
+ SOURCES Qt3DLogic_SRC
+ TYPESYSTEM_NAME ${Qt3DLogic_BINARY_DIR}/typesystem_3dlogic.xml)
diff --git a/sources/pyside6/PySide6/Qt3DLogic/typesystem_3dlogic.xml b/sources/pyside6/PySide6/Qt3DLogic/typesystem_3dlogic.xml
new file mode 100644
index 000000000..60f362534
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DLogic/typesystem_3dlogic.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.Qt3DLogic"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="Qt3DCore/typesystem_3dcore.xml" generate="no"/>
+ <namespace-type name="Qt3DLogic">
+ <object-type name="QFrameAction"/>
+ <object-type name="QLogicAspect"/>
+ </namespace-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/Qt3DRender/CMakeLists.txt b/sources/pyside6/PySide6/Qt3DRender/CMakeLists.txt
new file mode 100644
index 000000000..72f859305
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DRender/CMakeLists.txt
@@ -0,0 +1,158 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(Qt3DRender)
+
+set(Qt3DRender_DROPPED_ENTRIES)
+
+set(Qt3DRender_SRC
+${Qt3DRender_GEN_DIR}/qsharedpointer_propertyreaderinterface_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qsharedpointer_qtextureimagedata_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qsharedpointer_qtextureimagedatagenerator_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_propertyreaderinterface_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qabstractlight_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qabstractraycaster_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qabstracttexture_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qabstracttextureimage_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qalphacoverage_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qalphatest_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qblendequation_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qblendequationarguments_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qblitframebuffer_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qbuffercapture_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qcamera_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qcameralens_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qcameraselector_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qclearbuffers_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qclipplane_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qcolormask_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qcomputecommand_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qcullface_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qdebugoverlay_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qdepthrange_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qdepthtest_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qdirectionallight_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qdispatchcompute_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qdithering_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qeffect_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qenvironmentlight_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qfilterkey_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qframegraphnode_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qfrontface_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qfrustumculling_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qgeometryrenderer_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qgraphicsapifilter_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qlayer_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qlayerfilter_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qlevelofdetail_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qlevelofdetailboundingsphere_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qlevelofdetailswitch_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qlinewidth_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qmaterial_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qmemorybarrier_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qmesh_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qmultisampleantialiasing_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qnodepthmask_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qnodraw_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qnopicking_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qobjectpicker_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpaintedtextureimage_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qparameter_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpickevent_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpickingproxy_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpickingsettings_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpicklineevent_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpickpointevent_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpicktriangleevent_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpointlight_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpointsize_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qpolygonoffset_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qproximityfilter_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrastermode_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qraycaster_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qraycasterhit_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrenderaspect_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendercapabilities_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendercapture_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendercapturereply_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrenderpass_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrenderpassfilter_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendersettings_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrenderstate_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrenderstateset_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendersurfaceselector_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendertarget_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendertargetoutput_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qrendertargetselector_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qsceneloader_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qscissortest_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qscreenraycaster_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qseamlesscubemap_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qsetfence_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qshaderdata_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qshaderimage_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qshaderprogram_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qshaderprogrambuilder_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qsharedgltexture_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qsortpolicy_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qspotlight_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qstencilmask_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qstenciloperation_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qstenciloperationarguments_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qstenciltest_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qstenciltestarguments_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qsubtreeenabler_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtechnique_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtechniquefilter_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexture1d_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexture1darray_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexture2d_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexture2darray_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexture2dmultisample_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexture2dmultisamplearray_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexture3d_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexturebuffer_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexturecubemap_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexturecubemaparray_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexturedata_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexturedataupdate_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtextureimage_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtextureimagedata_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtextureimagedatagenerator_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtextureloader_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexturerectangle_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qtexturewrapmode_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qviewport_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_qwaitfence_wrapper.cpp
+${Qt3DRender_GEN_DIR}/qt3drender_wrapper.cpp
+# module is always needed
+${Qt3DRender_GEN_DIR}/qt3drender_module_wrapper.cpp)
+
+set(Qt3DRender_include_dirs
+ ${Qt3DRender_SOURCE_DIR}
+ ${Qt3DRender_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+
+ ${Qt3DCore_GEN_DIR})
+
+set(Qt3DRender_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}3DRender_LIBRARIES})
+
+set(Qt3DRender_deps Qt3DCore)
+
+check_qt_opengl("3DRender" Qt3DRender_include_dirs Qt3DRender_deps
+ Qt3DRender_DROPPED_ENTRIES)
+
+create_pyside_module(NAME Qt3DRender
+ INCLUDE_DIRS Qt3DRender_include_dirs
+ LIBRARIES Qt3DRender_libraries
+ DEPS Qt3DRender_deps
+ TYPESYSTEM_PATH Qt3DRender_SOURCE_DIR
+ SOURCES Qt3DRender_SRC
+ TYPESYSTEM_NAME ${Qt3DRender_BINARY_DIR}/typesystem_3drender.xml
+ DROPPED_ENTRIES Qt3DRender_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/Qt3DRender/typesystem_3drender.xml b/sources/pyside6/PySide6/Qt3DRender/typesystem_3drender.xml
new file mode 100644
index 000000000..66fd70927
--- /dev/null
+++ b/sources/pyside6/PySide6/Qt3DRender/typesystem_3drender.xml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.Qt3DRender"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="Qt3DCore/typesystem_3dcore.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <!-- PYSIDE-2610: QOpenGLTexture's enums are used -->
+ <?if !no_QtOpenGL?>
+ <load-typesystem name="QtOpenGL/typesystem_opengl.xml" generate="no"/>
+ <?endif?>
+ <smart-pointer-type name="QSharedPointer" type="shared" getter="data"
+ reset-method="reset"
+ instantiations="Qt3DRender::PropertyReaderInterface=Qt3DRender::PropertyReaderInterfacePtr,Qt3DRender::QTextureImageData=Qt3DRender::QTextureImageDataPtr,Qt3DRender::QTextureImageDataGenerator=Qt3DRender::QTextureImageDataGeneratorPtr"/>
+ <namespace-type name="Qt3DRender">
+ <enum-type name="API"/>
+ <object-type name="PropertyReaderInterface"/>
+ <object-type name="QAbstractLight">
+ <enum-type name="Type"/>
+ </object-type>
+ <object-type name="QAbstractRayCaster">
+ <enum-type name="RunMode"/>
+ <enum-type name="FilterMode"/>
+ </object-type>
+ <object-type name="QAbstractTexture">
+ <enum-type name="CubeMapFace"/>
+ <enum-type name="ComparisonFunction"/>
+ <enum-type name="ComparisonMode"/>
+ <enum-type name="HandleType"/>
+ <enum-type name="Filter"/>
+ <enum-type name="Status"/>
+ <enum-type name="Target"/>
+ <enum-type name="TextureFormat"/>
+ </object-type>
+ <object-type name="QAbstractTextureImage"/>
+ <object-type name="QAlphaCoverage"/>
+ <object-type name="QAlphaTest">
+ <enum-type name="AlphaFunction"/>
+ </object-type>
+ <object-type name="QBlendEquation">
+ <enum-type name="BlendFunction"/>
+ </object-type>
+ <object-type name="QBlendEquationArguments">
+ <enum-type name="Blending"/>
+ </object-type>
+ <object-type name="QBlitFramebuffer">
+ <enum-type name="InterpolationMethod"/>
+ </object-type>
+ <object-type name="QBufferCapture"/>
+ <object-type name="QCamera">
+ <enum-type name="CameraTranslationOption"/>
+ </object-type>
+ <object-type name="QCameraLens">
+ <enum-type name="ProjectionType"/>
+ </object-type>
+ <object-type name="QCameraSelector"/>
+ <object-type name="QClearBuffers">
+ <enum-type name="BufferType" flags="BufferTypeFlags"/>
+ </object-type>
+ <object-type name="QClipPlane"/>
+ <object-type name="QColorMask"/>
+ <object-type name="QComputeCommand">
+ <enum-type name="RunType"/>
+ </object-type>
+ <object-type name="QCullFace">
+ <enum-type name="CullingMode"/>
+ </object-type>
+ <object-type name="QDebugOverlay"/>
+ <object-type name="QDepthRange"/>
+ <object-type name="QDepthTest">
+ <enum-type name="DepthFunction"/>
+ </object-type>
+ <object-type name="QDirectionalLight"/>
+ <object-type name="QDispatchCompute"/>
+ <object-type name="QDithering"/>
+ <object-type name="QEffect"/>
+ <object-type name="QEnvironmentLight"/>
+ <object-type name="QFilterKey"/>
+ <object-type name="QFrameGraphNode"/>
+ <object-type name="QFrontFace">
+ <enum-type name="WindingDirection"/>
+ </object-type>
+ <object-type name="QFrustumCulling"/>
+ <object-type name="QGeometryRenderer">
+ <enum-type name="PrimitiveType"/>
+ </object-type>
+ <object-type name="QGraphicsApiFilter">
+ <enum-type name="Api"/>
+ <enum-type name="OpenGLProfile"/>
+ <!-- only Q_AUTOTEST_EXPORT -->
+ <modify-function signature="operator==(Qt3DRender::QGraphicsApiFilter,Qt3DRender::QGraphicsApiFilter)"
+ remove="all"/>
+ <modify-function signature="operator!=(Qt3DRender::QGraphicsApiFilter,Qt3DRender::QGraphicsApiFilter)"
+ remove="all"/>
+ </object-type>
+ <object-type name="QLayer"/>
+ <object-type name="QLayerFilter">
+ <enum-type name="FilterMode"/>
+ </object-type>
+ <object-type name="QLevelOfDetail">
+ <enum-type name="ThresholdType"/>
+ </object-type>
+ <object-type name="QLevelOfDetailBoundingSphere"/>
+ <object-type name="QLevelOfDetailSwitch"/>
+ <object-type name="QLineWidth"/>
+ <object-type name="QMaterial"/>
+ <object-type name="QMemoryBarrier">
+ <enum-type name="Operation" flags="Operations"/>
+ </object-type>
+ <object-type name="QMesh">
+ <enum-type name="Status"/>
+ </object-type>
+ <object-type name="QMultiSampleAntiAliasing"/>
+ <object-type name="QNoDepthMask"/>
+ <object-type name="QNoDraw"/>
+ <object-type name="QNoPicking"/>
+ <object-type name="QObjectPicker"/>
+ <object-type name="QPaintedTextureImage"/>
+ <object-type name="QParameter"/>
+ <object-type name="QPickEvent">
+ <enum-type name="Buttons"/>
+ <enum-type name="Modifiers"/>
+ </object-type>
+ <object-type name="QPickingProxy"/>
+ <object-type name="QPickLineEvent"/>
+ <object-type name="QPickPointEvent"/>
+ <object-type name="QPickTriangleEvent"/>
+ <object-type name="QPickingSettings">
+ <enum-type name="FaceOrientationPickingMode"/>
+ <enum-type name="PickMethod"/>
+ <enum-type name="PickResultMode"/>
+ </object-type>
+ <object-type name="QPointLight"/>
+ <object-type name="QPointSize">
+ <enum-type name="SizeMode"/>
+ </object-type>
+ <object-type name="QPolygonOffset"/>
+ <object-type name="QProximityFilter"/>
+ <object-type name="QRasterMode">
+ <enum-type name="RasterMode"/>
+ <enum-type name="FaceMode"/>
+ </object-type>
+ <object-type name="QRayCaster"/>
+ <value-type name="QRayCasterHit">
+ <enum-type name="HitType"/>
+ </value-type>
+ <object-type name="QRenderAspect">
+ <enum-type name="SubmissionType"/>
+ </object-type>
+ <object-type name="QRenderCapabilities">
+ <enum-type name="API"/>
+ <enum-type name="Profile"/>
+ </object-type>
+ <object-type name="QRenderCapture"/>
+ <object-type name="QRenderCaptureReply"/>
+ <object-type name="QRenderPass"/>
+ <object-type name="QRenderPassFilter"/>
+ <object-type name="QRenderSettings">
+ <enum-type name="RenderPolicy"/>
+ </object-type>
+ <object-type name="QRenderState"/>
+ <object-type name="QRenderStateSet"/>
+ <object-type name="QRenderSurfaceSelector"/>
+ <object-type name="QRenderTarget"/>
+ <object-type name="QRenderTargetOutput">
+ <enum-type name="AttachmentPoint"/>
+ </object-type>
+ <object-type name="QRenderTargetSelector"/>
+ <object-type name="QSceneLoader">
+ <enum-type name="Status"/>
+ <enum-type name="ComponentType"/>
+ </object-type>
+ <object-type name="QScissorTest"/>
+ <object-type name="QScreenRayCaster"/>
+ <object-type name="QSeamlessCubemap"/>
+ <object-type name="QSetFence">
+ <enum-type name="HandleType"/>
+ </object-type>
+ <object-type name="QShaderData"/>
+ <object-type name="QShaderProgram">
+ <enum-type name="Format"/>
+ <enum-type name="ShaderType"/>
+ <enum-type name="Status"/>
+ </object-type>
+ <object-type name="QShaderImage">
+ <enum-type name="Access"/>
+ <enum-type name="ImageFormat"/>
+ </object-type>
+ <object-type name="QShaderProgramBuilder"/>
+ <object-type name="QSharedGLTexture"/>
+ <object-type name="QSortPolicy">
+ <enum-type name="SortType"/>
+ </object-type>
+ <object-type name="QSpotLight"/>
+ <object-type name="QStencilMask"/>
+ <object-type name="QStencilOperation"/>
+ <object-type name="QStencilOperationArguments">
+ <enum-type name="FaceMode"/>
+ <enum-type name="Operation"/>
+ </object-type>
+ <object-type name="QStencilTest"/>
+ <object-type name="QStencilTestArguments">
+ <enum-type name="StencilFaceMode"/>
+ <enum-type name="StencilFunction"/>
+ </object-type>
+ <object-type name="QSubtreeEnabler">
+ <enum-type name="Enablement"/>
+ </object-type>
+ <object-type name="QTechnique"/>
+ <object-type name="QTechniqueFilter"/>
+ <object-type name="QTexture1D"/>
+ <object-type name="QTexture1DArray"/>
+ <object-type name="QTexture2D"/>
+ <object-type name="QTexture2DArray"/>
+ <object-type name="QTexture2DMultisample"/>
+ <object-type name="QTexture2DMultisampleArray"/>
+ <object-type name="QTexture3D"/>
+ <object-type name="QTextureBuffer"/>
+ <object-type name="QTextureCubeMap"/>
+ <object-type name="QTextureCubeMapArray"/>
+ <object-type name="QTextureData"/>
+ <value-type name="QTextureDataUpdate"/>
+ <object-type name="QTextureImage">
+ <enum-type name="Status"/>
+ </object-type>
+ <object-type name="QTextureImageData"/>
+ <object-type name="QTextureImageDataGenerator"/>
+ <object-type name="QTextureLoader"/>
+ <object-type name="QTextureRectangle"/>
+ <object-type name="QTextureWrapMode">
+ <enum-type name="WrapMode"/>
+ </object-type>
+ <object-type name="QViewport"/>
+ <object-type name="QWaitFence">
+ <enum-type name="HandleType"/>
+ </object-type>
+ </namespace-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtAsyncio/__init__.py b/sources/pyside6/PySide6/QtAsyncio/__init__.py
new file mode 100644
index 000000000..60d1846d1
--- /dev/null
+++ b/sources/pyside6/PySide6/QtAsyncio/__init__.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+from .events import (
+ QAsyncioEventLoopPolicy, QAsyncioEventLoop, QAsyncioHandle, QAsyncioTimerHandle
+)
+from .futures import QAsyncioFuture
+from .tasks import QAsyncioTask
+
+import asyncio
+import typing
+
+__all__ = [
+ "QAsyncioEventLoopPolicy", "QAsyncioEventLoop",
+ "QAsyncioHandle", "QAsyncioTimerHandle",
+ "QAsyncioFuture", "QAsyncioTask"
+]
+
+
+def run(coro: typing.Optional[typing.Coroutine] = None,
+ keep_running: bool = True,
+ quit_qapp: bool = True, *,
+ handle_sigint: bool = False,
+ debug: typing.Optional[bool] = None) -> typing.Any:
+ """Run the QtAsyncio event loop."""
+
+ # Event loop policies are expected to be deprecated with Python 3.13, with
+ # subsequent removal in Python 3.15. At that point, part of the current
+ # logic of the QAsyncioEventLoopPolicy constructor will have to be moved
+ # here and/or to a loop factory class (to be provided as an argument to
+ # asyncio.run()). In particular, this concerns the logic of setting up the
+ # QCoreApplication and the SIGINT handler.
+ #
+ # More details:
+ # https://discuss.python.org/t/removing-the-asyncio-policy-system-asyncio-set-event-loop-policy-in-python-3-15/37553 # noqa: E501
+ default_policy = asyncio.get_event_loop_policy()
+ asyncio.set_event_loop_policy(
+ QAsyncioEventLoopPolicy(quit_qapp=quit_qapp, handle_sigint=handle_sigint))
+
+ ret = None
+ exc = None
+
+ if keep_running:
+ if coro:
+ asyncio.ensure_future(coro)
+ asyncio.get_event_loop().run_forever()
+ else:
+ if coro:
+ ret = asyncio.run(coro, debug=debug)
+ else:
+ exc = RuntimeError(
+ "QtAsyncio was set to keep running after the coroutine "
+ "finished, but no coroutine was provided.")
+
+ asyncio.set_event_loop_policy(default_policy)
+
+ if ret:
+ return ret
+ if exc:
+ raise exc
diff --git a/sources/pyside6/PySide6/QtAsyncio/events.py b/sources/pyside6/PySide6/QtAsyncio/events.py
new file mode 100644
index 000000000..86b89014a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtAsyncio/events.py
@@ -0,0 +1,725 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+from PySide6.QtCore import (QCoreApplication, QDateTime, QDeadlineTimer,
+ QEventLoop, QObject, QTimer, QThread, Slot)
+
+from . import futures
+from . import tasks
+
+import asyncio
+import collections.abc
+import concurrent.futures
+import contextvars
+import enum
+import os
+import signal
+import socket
+import subprocess
+import typing
+import warnings
+
+__all__ = [
+ "QAsyncioEventLoopPolicy", "QAsyncioEventLoop",
+ "QAsyncioHandle", "QAsyncioTimerHandle",
+]
+
+
+class QAsyncioExecutorWrapper(QObject):
+ """
+ Executors in asyncio allow running synchronous code in a separate thread or
+ process without blocking the event loop or interrupting the asynchronous
+ program flow. Callables are scheduled for execution by calling submit() or
+ map() on an executor object.
+
+ Executors require a bit of extra work for QtAsyncio, as we can't use
+ naked Python threads; instead, we must make sure that the thread created
+ by executor.submit() has an event loop. This is achieved by not submitting
+ the callable directly, but a small wrapper that attaches a QEventLoop to
+ the executor thread, and then creates a zero-delay singleshot timer to push
+ the actual callable for the executor into this new event loop.
+ """
+
+ def __init__(self, func: typing.Callable, *args: typing.Tuple) -> None:
+ super().__init__()
+ self._loop: QEventLoop
+ self._func = func
+ self._args = args
+ self._result = None
+ self._exception = None
+
+ def _cb(self):
+ try:
+ # Call the synchronous callable that we submitted with submit() or
+ # map().
+ self._result = self._func(*self._args)
+ except BaseException as e:
+ self._exception = e
+ self._loop.exit()
+
+ def do(self):
+ # This creates a new event loop and dispatcher for the thread, if not
+ # already created.
+ self._loop = QEventLoop()
+ asyncio.events._set_running_loop(self._loop)
+
+ QTimer.singleShot(0, self._loop, lambda: self._cb())
+
+ self._loop.exec()
+ if self._exception is not None:
+ raise self._exception
+ return self._result
+
+ def exit(self):
+ self._loop.exit()
+
+
+class QAsyncioEventLoopPolicy(asyncio.AbstractEventLoopPolicy):
+ """
+ Event loop policies are expected to be deprecated with Python 3.13, with
+ subsequent removal in Python 3.15. At that point, part of the current
+ logic of the QAsyncioEventLoopPolicy constructor will have to be moved
+ to QtAsyncio.run() and/or to a loop factory class (to be provided as an
+ argument to asyncio.run()). In particular, this concerns the logic of
+ setting up the QCoreApplication and the SIGINT handler.
+
+ More details:
+ https://discuss.python.org/t/removing-the-asyncio-policy-system-asyncio-set-event-loop-policy-in-python-3-15/37553
+ """
+ def __init__(self,
+ application: typing.Optional[QCoreApplication] = None,
+ quit_qapp: bool = True,
+ handle_sigint: bool = False) -> None:
+ super().__init__()
+ if application is None:
+ if QCoreApplication.instance() is None:
+ application = QCoreApplication()
+ else:
+ application = QCoreApplication.instance()
+ self._application: QCoreApplication = application # type: ignore[assignment]
+
+ # Configure whether the QCoreApplication at the core of QtAsyncio
+ # should be shut down when asyncio finishes. A special case where one
+ # would want to disable this is test suites that want to reuse a single
+ # QCoreApplication instance across all unit tests, which would fail if
+ # this instance is shut down every time.
+ self._quit_qapp = quit_qapp
+
+ self._event_loop: typing.Optional[asyncio.AbstractEventLoop] = None
+
+ if handle_sigint:
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
+
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ if self._event_loop is None:
+ self._event_loop = QAsyncioEventLoop(self._application, quit_qapp=self._quit_qapp)
+ return self._event_loop
+
+ def set_event_loop(self, loop: typing.Optional[asyncio.AbstractEventLoop]) -> None:
+ self._event_loop = loop
+
+ def new_event_loop(self) -> asyncio.AbstractEventLoop:
+ return QAsyncioEventLoop(self._application, quit_qapp=self._quit_qapp)
+
+ def get_child_watcher(self) -> "asyncio.AbstractChildWatcher":
+ raise DeprecationWarning("Child watchers are deprecated since Python 3.12")
+
+ def set_child_watcher(self, watcher: "asyncio.AbstractChildWatcher") -> None:
+ raise DeprecationWarning("Child watchers are deprecated since Python 3.12")
+
+
+class QAsyncioEventLoop(asyncio.BaseEventLoop, QObject):
+ """
+ Implements the asyncio API:
+ https://docs.python.org/3/library/asyncio-eventloop.html
+ """
+
+ class ShutDownThread(QThread):
+ """
+ Used to shut down the default executor when calling
+ shutdown_default_executor(). As the executor is a ThreadPoolExecutor,
+ it must be shut down in a separate thread as all the threads from the
+ thread pool must join, which we want to do without blocking the event
+ loop.
+ """
+
+ def __init__(self, future: futures.QAsyncioFuture, loop: "QAsyncioEventLoop") -> None:
+ super().__init__()
+ self._future = future
+ self._loop = loop
+ self.started.connect(self.shutdown)
+
+ def run(self) -> None:
+ pass
+
+ def shutdown(self) -> None:
+ try:
+ self._loop._default_executor.shutdown(wait=True)
+ if not self._loop.is_closed():
+ self._loop.call_soon_threadsafe(self._future.set_result, None)
+ except Exception as e:
+ if not self._loop.is_closed():
+ self._loop.call_soon_threadsafe(self._future.set_exception, e)
+
+ def __init__(self,
+ application: QCoreApplication, quit_qapp: bool = True) -> None:
+ asyncio.BaseEventLoop.__init__(self)
+ QObject.__init__(self)
+
+ self._application: QCoreApplication = application
+
+ # Configure whether the QCoreApplication at the core of QtAsyncio
+ # should be shut down when asyncio finishes. A special case where one
+ # would want to disable this is test suites that want to reuse a single
+ # QCoreApplication instance across all unit tests, which would fail if
+ # this instance is shut down every time.
+ self._quit_qapp = quit_qapp
+
+ self._thread = QThread.currentThread()
+
+ self._closed = False
+
+ # These two flags are used to determine whether the loop was stopped
+ # from inside the loop (i.e., coroutine or callback called stop()) or
+ # from outside the loop (i.e., the QApplication is being shut down, for
+ # example, by the user closing the window or by calling
+ # QApplication.quit()). The different cases can trigger slightly
+ # different behaviors (see the comments where the flags are used).
+ # There are two variables for this as in a third case the loop is still
+ # running and both flags are False.
+ self._quit_from_inside = False
+ self._quit_from_outside = False
+
+ # A set of all asynchronous generators that are currently running.
+ self._asyncgens: typing.Set[collections.abc.AsyncGenerator] = set()
+
+ # Starting with Python 3.11, this must be an instance of
+ # ThreadPoolExecutor.
+ self._default_executor = concurrent.futures.ThreadPoolExecutor()
+
+ # The exception handler, if set with set_exception_handler(). The
+ # exception handler is currently called in two places: One, if an
+ # asynchonrous generator raises an exception when closed, and two, if
+ # an exception is raised during the execution of a task. Currently, the
+ # default exception handler just prints the exception to the console.
+ self._exception_handler: typing.Optional[typing.Callable] = self.default_exception_handler
+
+ # The task factory, if set with set_task_factory(). Otherwise, a new
+ # task is created with the QAsyncioTask constructor.
+ self._task_factory: typing.Optional[typing.Callable] = None
+
+ # The future that is currently being awaited with run_until_complete().
+ self._future_to_complete: typing.Optional[futures.QAsyncioFuture] = None
+
+ self._debug = bool(os.getenv("PYTHONASYNCIODEBUG", False))
+
+ self._application.aboutToQuit.connect(self._about_to_quit_cb)
+
+ # Running and stopping the loop
+
+ def _run_until_complete_cb(self, future: futures.QAsyncioFuture) -> None:
+ """
+ A callback that stops the loop when the future is done, used when
+ running the loop with run_until_complete().
+ """
+ if not future.cancelled():
+ if isinstance(future.exception(), (SystemExit, KeyboardInterrupt)):
+ return
+ future.get_loop().stop()
+
+ def run_until_complete(self,
+ future: futures.QAsyncioFuture) -> typing.Any: # type: ignore[override]
+ if self.is_closed():
+ raise RuntimeError("Event loop is closed")
+ if self.is_running():
+ raise RuntimeError("Event loop is already running")
+
+ arg_was_coro = not asyncio.futures.isfuture(future)
+ future = asyncio.tasks.ensure_future(future, loop=self) # type: ignore[assignment]
+ future.add_done_callback(self._run_until_complete_cb)
+ self._future_to_complete = future
+
+ try:
+ self.run_forever()
+ except Exception as e:
+ if arg_was_coro and future.done() and not future.cancelled():
+ future.exception()
+ raise e
+ finally:
+ future.remove_done_callback(self._run_until_complete_cb)
+ if not future.done():
+ raise RuntimeError("Event loop stopped before Future completed")
+
+ return future.result()
+
+ def run_forever(self) -> None:
+ if self.is_closed():
+ raise RuntimeError("Event loop is closed")
+ if self.is_running():
+ raise RuntimeError("Event loop is already running")
+ asyncio.events._set_running_loop(self)
+ self._application.exec()
+ asyncio.events._set_running_loop(None)
+
+ def _about_to_quit_cb(self):
+ """ A callback for the aboutToQuit signal of the QCoreApplication. """
+ if not self._quit_from_inside:
+ # If the aboutToQuit signal is emitted, the user is closing the
+ # application window or calling QApplication.quit(). In this case,
+ # we want to close the event loop, and we consider this a quit from
+ # outside the loop.
+ self._quit_from_outside = True
+ self.close()
+
+ def stop(self) -> None:
+ if self._future_to_complete is not None:
+ if self._future_to_complete.done():
+ self._future_to_complete = None
+ else:
+ # Do not stop the loop if there is a future still being awaited
+ # with run_until_complete().
+ return
+
+ self._quit_from_inside = True
+
+ # The user might want to keep the QApplication running after the event
+ # event loop finishes, which they can control with the quit_qapp
+ # argument.
+ if self._quit_qapp:
+ self._application.quit()
+
+ def is_running(self) -> bool:
+ return self._thread.loopLevel() > 0
+
+ def is_closed(self) -> bool:
+ return self._closed
+
+ def close(self) -> None:
+ if self.is_running() and not self._quit_from_outside:
+ raise RuntimeError("Cannot close a running event loop")
+ if self.is_closed():
+ return
+ if self._default_executor is not None:
+ self._default_executor.shutdown(wait=False)
+ self._closed = True
+
+ async def shutdown_asyncgens(self) -> None:
+ if not len(self._asyncgens):
+ return
+
+ results = await asyncio.tasks.gather(
+ *[asyncgen.aclose() for asyncgen in self._asyncgens],
+ return_exceptions=True)
+
+ for result, asyncgen in zip(results, self._asyncgens):
+ if isinstance(result, Exception):
+ self.call_exception_handler({
+ "message": f"Closing asynchronous generator {asyncgen}"
+ f"raised an exception",
+ "exception": result,
+ "asyncgen": asyncgen})
+
+ self._asyncgens.clear()
+
+ async def shutdown_default_executor(self, # type: ignore[override]
+ timeout: typing.Union[int, float, None] = None) -> None:
+ shutdown_successful = False
+ if timeout is not None:
+ deadline_timer = QDeadlineTimer(int(timeout * 1000))
+ else:
+ deadline_timer = QDeadlineTimer(QDeadlineTimer.Forever)
+
+ if self._default_executor is None:
+ return
+ future = self.create_future()
+ thread = QAsyncioEventLoop.ShutDownThread(future, self)
+ thread.start()
+ try:
+ await future
+ finally:
+ shutdown_successful = thread.wait(deadline_timer)
+
+ if timeout is not None and not shutdown_successful:
+ warnings.warn(
+ f"Could not shutdown the default executor within {timeout} seconds",
+ RuntimeWarning, stacklevel=2)
+ self._default_executor.shutdown(wait=False)
+
+ # Scheduling callbacks
+
+ def _call_soon_impl(self, callback: typing.Callable, *args: typing.Any,
+ context: typing.Optional[contextvars.Context] = None,
+ is_threadsafe: typing.Optional[bool] = False) -> asyncio.Handle:
+ return self._call_later_impl(0, callback, *args, context=context,
+ is_threadsafe=is_threadsafe)
+
+ def call_soon(self, callback: typing.Callable, *args: typing.Any,
+ context: typing.Optional[contextvars.Context] = None) -> asyncio.Handle:
+ return self._call_soon_impl(callback, *args, context=context, is_threadsafe=False)
+
+ def call_soon_threadsafe(self, callback: typing.Callable, *args: typing.Any,
+ context:
+ typing.Optional[contextvars.Context] = None) -> asyncio.Handle:
+ if self.is_closed():
+ raise RuntimeError("Event loop is closed")
+ if context is None:
+ context = contextvars.copy_context()
+ return self._call_soon_impl(callback, *args, context=context, is_threadsafe=True)
+
+ def _call_later_impl(self, delay: typing.Union[int, float],
+ callback: typing.Callable, *args: typing.Any,
+ context: typing.Optional[contextvars.Context] = None,
+ is_threadsafe: typing.Optional[bool] = False) -> asyncio.TimerHandle:
+ if not isinstance(delay, (int, float)):
+ raise TypeError("delay must be an int or float")
+ return self._call_at_impl(self.time() + delay, callback, *args, context=context,
+ is_threadsafe=is_threadsafe)
+
+ def call_later(self, delay: typing.Union[int, float],
+ callback: typing.Callable, *args: typing.Any,
+ context: typing.Optional[contextvars.Context] = None) -> asyncio.TimerHandle:
+ return self._call_later_impl(delay, callback, *args, context=context, is_threadsafe=False)
+
+ def _call_at_impl(self, when: typing.Union[int, float],
+ callback: typing.Callable, *args: typing.Any,
+ context: typing.Optional[contextvars.Context] = None,
+ is_threadsafe: typing.Optional[bool] = False) -> asyncio.TimerHandle:
+ """ All call_at() and call_later() methods map to this method. """
+ if not isinstance(when, (int, float)):
+ raise TypeError("when must be an int or float")
+ return QAsyncioTimerHandle(when, callback, args, self, context, is_threadsafe=is_threadsafe)
+
+ def call_at(self, when: typing.Union[int, float],
+ callback: typing.Callable, *args: typing.Any,
+ context: typing.Optional[contextvars.Context] = None) -> asyncio.TimerHandle:
+ return self._call_at_impl(when, callback, *args, context=context, is_threadsafe=False)
+
+ def time(self) -> float:
+ return QDateTime.currentMSecsSinceEpoch() / 1000
+
+ # Creating Futures and Tasks
+
+ def create_future(self) -> futures.QAsyncioFuture: # type: ignore[override]
+ return futures.QAsyncioFuture(loop=self)
+
+ def create_task(self, # type: ignore[override]
+ coro: typing.Union[collections.abc.Generator, collections.abc.Coroutine],
+ *, name: typing.Optional[str] = None,
+ context: typing.Optional[contextvars.Context] = None) -> tasks.QAsyncioTask:
+ if self._task_factory is None:
+ task = tasks.QAsyncioTask(coro, loop=self, name=name, context=context)
+ else:
+ task = self._task_factory(self, coro, context=context)
+ task.set_name(name)
+
+ return task
+
+ def set_task_factory(self, factory: typing.Optional[typing.Callable]) -> None:
+ if factory is not None and not callable(factory):
+ raise TypeError("The task factory must be a callable or None")
+ self._task_factory = factory
+
+ def get_task_factory(self) -> typing.Optional[typing.Callable]:
+ return self._task_factory
+
+ # Opening network connections
+
+ async def create_connection(
+ self, protocol_factory, host=None, port=None,
+ *, ssl=None, family=0, proto=0,
+ flags=0, sock=None, local_addr=None,
+ server_hostname=None,
+ ssl_handshake_timeout=None,
+ ssl_shutdown_timeout=None,
+ happy_eyeballs_delay=None, interleave=None):
+ raise NotImplementedError
+
+ async def create_datagram_endpoint(self, protocol_factory,
+ local_addr=None, remote_addr=None, *,
+ family=0, proto=0, flags=0,
+ reuse_address=None, reuse_port=None,
+ allow_broadcast=None, sock=None):
+ raise NotImplementedError
+
+ async def create_unix_connection(
+ self, protocol_factory, path=None, *,
+ ssl=None, sock=None,
+ server_hostname=None,
+ ssl_handshake_timeout=None,
+ ssl_shutdown_timeout=None):
+ raise NotImplementedError
+
+ # Creating network servers
+
+ async def create_server(
+ self, protocol_factory, host=None, port=None,
+ *, family=socket.AF_UNSPEC,
+ flags=socket.AI_PASSIVE, sock=None, backlog=100,
+ ssl=None, reuse_address=None, reuse_port=None,
+ ssl_handshake_timeout=None,
+ ssl_shutdown_timeout=None,
+ start_serving=True):
+ raise NotImplementedError
+
+ async def create_unix_server(
+ self, protocol_factory, path=None, *,
+ sock=None, backlog=100, ssl=None,
+ ssl_handshake_timeout=None,
+ ssl_shutdown_timeout=None,
+ start_serving=True):
+ raise NotImplementedError
+
+ async def connect_accepted_socket(
+ self, protocol_factory, sock,
+ *, ssl=None,
+ ssl_handshake_timeout=None,
+ ssl_shutdown_timeout=None):
+ raise NotImplementedError
+
+ # Transferring files
+
+ async def sendfile(self, transport, file, offset=0, count=None,
+ *, fallback=True):
+ raise NotImplementedError
+
+ # TLS Upgrade
+
+ async def start_tls(self, transport, protocol, sslcontext, *,
+ server_side=False,
+ server_hostname=None,
+ ssl_handshake_timeout=None,
+ ssl_shutdown_timeout=None):
+ raise NotImplementedError
+
+ # Watching file descriptors
+
+ def add_reader(self, fd, callback, *args):
+ raise NotImplementedError
+
+ def remove_reader(self, fd):
+ raise NotImplementedError
+
+ def add_writer(self, fd, callback, *args):
+ raise NotImplementedError
+
+ def remove_writer(self, fd):
+ raise NotImplementedError
+
+ # Working with socket objects directly
+
+ async def sock_recv(self, sock, nbytes):
+ raise NotImplementedError
+
+ async def sock_recv_into(self, sock, buf):
+ raise NotImplementedError
+
+ async def sock_recvfrom(self, sock, bufsize):
+ raise NotImplementedError
+
+ async def sock_recvfrom_into(self, sock, buf, nbytes=0):
+ raise NotImplementedError
+
+ async def sock_sendall(self, sock, data):
+ raise NotImplementedError
+
+ async def sock_sendto(self, sock, data, address):
+ raise NotImplementedError
+
+ async def sock_connect(self, sock, address):
+ raise NotImplementedError
+
+ async def sock_accept(self, sock):
+ raise NotImplementedError
+
+ async def sock_sendfile(self, sock, file, offset=0, count=None, *,
+ fallback=None):
+ raise NotImplementedError
+
+ # DNS
+
+ async def getaddrinfo(self, host, port, *,
+ family=0, type=0, proto=0, flags=0):
+ raise NotImplementedError
+
+ async def getnameinfo(self, sockaddr, flags=0):
+ raise NotImplementedError
+
+ # Working with pipes
+
+ async def connect_read_pipe(self, protocol_factory, pipe):
+ raise NotImplementedError
+
+ async def connect_write_pipe(self, protocol_factory, pipe):
+ raise NotImplementedError
+
+ # Unix signals
+
+ def add_signal_handler(self, sig, callback, *args):
+ raise NotImplementedError
+
+ def remove_signal_handler(self, sig):
+ raise NotImplementedError
+
+ # Executing code in thread or process pools
+
+ def run_in_executor(self,
+ executor: typing.Optional[concurrent.futures.ThreadPoolExecutor],
+ func: typing.Callable, *args: typing.Tuple) -> asyncio.futures.Future:
+ if self.is_closed():
+ raise RuntimeError("Event loop is closed")
+ if executor is None:
+ executor = self._default_executor
+
+ # Executors require a bit of extra work for QtAsyncio, as we can't use
+ # naked Python threads; instead, we must make sure that the thread
+ # created by executor.submit() has an event loop. This is achieved by
+ # not submitting the callable directly, but a small wrapper that
+ # attaches a QEventLoop to the executor thread, and then pushes the
+ # actual callable for the executor into this new event loop.
+ wrapper = QAsyncioExecutorWrapper(func, *args)
+ return asyncio.futures.wrap_future(
+ executor.submit(wrapper.do), loop=self
+ )
+
+ def set_default_executor(self,
+ executor: typing.Optional[
+ concurrent.futures.ThreadPoolExecutor]) -> None:
+ if not isinstance(executor, concurrent.futures.ThreadPoolExecutor):
+ raise TypeError("The executor must be a ThreadPoolExecutor")
+ self._default_executor = executor
+
+ # Error Handling API
+
+ def set_exception_handler(self, handler: typing.Optional[typing.Callable]) -> None:
+ if handler is not None and not callable(handler):
+ raise TypeError("The handler must be a callable or None")
+ self._exception_handler = handler
+
+ def get_exception_handler(self) -> typing.Optional[typing.Callable]:
+ return self._exception_handler
+
+ def default_exception_handler(self, context: typing.Dict[str, typing.Any]) -> None:
+ # TODO
+ if context["message"]:
+ print(context["message"])
+
+ def call_exception_handler(self, context: typing.Dict[str, typing.Any]) -> None:
+ if self._exception_handler is not None:
+ self._exception_handler(context)
+
+ # Enabling debug mode
+
+ def get_debug(self) -> bool:
+ # TODO: Part of the asyncio API but currently unused. More details:
+ # https://docs.python.org/3/library/asyncio-dev.html#asyncio-debug-mode
+ return self._debug
+
+ def set_debug(self, enabled: bool) -> None:
+ self._debug = enabled
+
+ # Running subprocesses
+
+ async def subprocess_exec(self, protocol_factory, *args,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ **kwargs):
+ raise NotImplementedError
+
+ async def subprocess_shell(self, protocol_factory, cmd, *,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ **kwargs):
+ raise NotImplementedError
+
+
+class QAsyncioHandle():
+ """
+ The handle enqueues a callback to be executed by the event loop, and allows
+ for this callback to be cancelled before it is executed. This callback will
+ typically execute the step function for a task. This makes the handle one
+ of the main components of asyncio.
+ """
+ class HandleState(enum.Enum):
+ PENDING = enum.auto()
+ CANCELLED = enum.auto()
+ DONE = enum.auto()
+
+ def __init__(self, callback: typing.Callable, args: typing.Tuple,
+ loop: QAsyncioEventLoop, context: typing.Optional[contextvars.Context],
+ is_threadsafe: typing.Optional[bool] = False) -> None:
+ self._callback = callback
+ self._args = args
+ self._loop = loop
+ self._context = context
+ self._is_threadsafe = is_threadsafe
+
+ self._timeout = 0
+
+ self._state = QAsyncioHandle.HandleState.PENDING
+ self._start()
+
+ def _start(self) -> None:
+ self._schedule_event(self._timeout, lambda: self._cb())
+
+ def _schedule_event(self, timeout: int, func: typing.Callable) -> None:
+ # Do not schedule events from asyncio when the app is quit from outside
+ # the event loop, as this would cause events to be enqueued after the
+ # event loop was destroyed.
+ if not self._loop.is_closed() and not self._loop._quit_from_outside:
+ if self._is_threadsafe:
+ # This singleShot overload will push func into self._loop
+ # instead of the current thread's loop. This allows scheduling
+ # a callback from a different thread, which is necessary for
+ # thread-safety.
+ # https://docs.python.org/3/library/asyncio-dev.html#asyncio-multithreading
+ QTimer.singleShot(timeout, self._loop, func)
+ else:
+ QTimer.singleShot(timeout, func)
+
+ @Slot()
+ def _cb(self) -> None:
+ """
+ A slot, enqueued into the event loop, that wraps around the actual
+ callback, typically the step function of a task.
+ """
+ if self._state == QAsyncioHandle.HandleState.PENDING:
+ if self._context is not None:
+ self._context.run(self._callback, *self._args)
+ else:
+ self._callback(*self._args)
+ self._state = QAsyncioHandle.HandleState.DONE
+
+ def cancel(self) -> None:
+ if self._state == QAsyncioHandle.HandleState.PENDING:
+ # The old timer that was created in _start will still trigger but
+ # _cb won't do anything, therefore the callback is effectively
+ # cancelled.
+ self._state = QAsyncioHandle.HandleState.CANCELLED
+
+ def cancelled(self) -> bool:
+ return self._state == QAsyncioHandle.HandleState.CANCELLED
+
+
+class QAsyncioTimerHandle(QAsyncioHandle, asyncio.TimerHandle):
+ def __init__(self, when: float, callback: typing.Callable, args: typing.Tuple,
+ loop: QAsyncioEventLoop, context: typing.Optional[contextvars.Context],
+ is_threadsafe: typing.Optional[bool] = False) -> None:
+ QAsyncioHandle.__init__(self, callback, args, loop, context, is_threadsafe)
+
+ self._when = when
+ time = self._loop.time()
+ self._timeout = round(max(self._when - time, 0) * 1000)
+
+ QAsyncioHandle._start(self)
+
+ def _start(self) -> None:
+ """
+ Overridden so that timer.start() is only called once at the end of the
+ constructor for both QtHandle and QtTimerHandle.
+ """
+ pass
+
+ def when(self) -> float:
+ return self._when
diff --git a/sources/pyside6/PySide6/QtAsyncio/futures.py b/sources/pyside6/PySide6/QtAsyncio/futures.py
new file mode 100644
index 000000000..cbb005fc9
--- /dev/null
+++ b/sources/pyside6/PySide6/QtAsyncio/futures.py
@@ -0,0 +1,117 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+from . import events
+
+import asyncio
+import contextvars
+import enum
+import typing
+
+
+class QAsyncioFuture():
+ """ https://docs.python.org/3/library/asyncio-future.html """
+
+ # Declare that this class implements the Future protocol. The field must
+ # exist and be boolean - True indicates 'await' or 'yield from', False
+ # indicates 'yield'.
+ _asyncio_future_blocking = False
+
+ class FutureState(enum.Enum):
+ PENDING = enum.auto()
+ CANCELLED = enum.auto()
+ DONE_WITH_RESULT = enum.auto()
+ DONE_WITH_EXCEPTION = enum.auto()
+
+ def __init__(self, *, loop: typing.Optional["events.QAsyncioEventLoop"] = None,
+ context: typing.Optional[contextvars.Context] = None) -> None:
+ self._loop: "events.QAsyncioEventLoop"
+ if loop is None:
+ self._loop = asyncio.events.get_event_loop() # type: ignore[assignment]
+ else:
+ self._loop = loop
+ self._context = context
+
+ self._state = QAsyncioFuture.FutureState.PENDING
+ self._result: typing.Any = None
+ self._exception: typing.Optional[BaseException] = None
+
+ self._cancel_message: typing.Optional[str] = None
+
+ # List of callbacks that are called when the future is done.
+ self._callbacks: typing.List[typing.Callable] = list()
+
+ def __await__(self):
+ if not self.done():
+ self._asyncio_future_blocking = True
+ yield self
+ if not self.done():
+ raise RuntimeError("await was not used with a Future or Future-like object")
+ return self.result()
+
+ __iter__ = __await__
+
+ def _schedule_callbacks(self, context: typing.Optional[contextvars.Context] = None):
+ """ A future can optionally have callbacks that are called when the future is done. """
+ for cb in self._callbacks:
+ self._loop.call_soon(
+ cb, self, context=context if context else self._context)
+
+ def result(self) -> typing.Union[typing.Any, Exception]:
+ if self._state == QAsyncioFuture.FutureState.DONE_WITH_RESULT:
+ return self._result
+ if self._state == QAsyncioFuture.FutureState.DONE_WITH_EXCEPTION and self._exception:
+ raise self._exception
+ if self._state == QAsyncioFuture.FutureState.CANCELLED:
+ if self._cancel_message:
+ raise asyncio.CancelledError(self._cancel_message)
+ else:
+ raise asyncio.CancelledError
+ raise asyncio.InvalidStateError
+
+ def set_result(self, result: typing.Any) -> None:
+ self._result = result
+ self._state = QAsyncioFuture.FutureState.DONE_WITH_RESULT
+ self._schedule_callbacks()
+
+ def set_exception(self, exception: Exception) -> None:
+ self._exception = exception
+ self._state = QAsyncioFuture.FutureState.DONE_WITH_EXCEPTION
+ self._schedule_callbacks()
+
+ def done(self) -> bool:
+ return self._state != QAsyncioFuture.FutureState.PENDING
+
+ def cancelled(self) -> bool:
+ return self._state == QAsyncioFuture.FutureState.CANCELLED
+
+ def add_done_callback(self, cb: typing.Callable, *,
+ context: typing.Optional[contextvars.Context] = None) -> None:
+ if self.done():
+ self._loop.call_soon(
+ cb, self, context=context if context else self._context)
+ else:
+ self._callbacks.append(cb)
+
+ def remove_done_callback(self, cb: typing.Callable) -> int:
+ original_len = len(self._callbacks)
+ self._callbacks = [_cb for _cb in self._callbacks if _cb != cb]
+ return original_len - len(self._callbacks)
+
+ def cancel(self, msg: typing.Optional[str] = None) -> bool:
+ if self.done():
+ return False
+ self._state = QAsyncioFuture.FutureState.CANCELLED
+ self._cancel_message = msg
+ self._schedule_callbacks()
+ return True
+
+ def exception(self) -> typing.Optional[BaseException]:
+ if self._state == QAsyncioFuture.FutureState.CANCELLED:
+ raise asyncio.CancelledError
+ if self.done():
+ return self._exception
+ raise asyncio.InvalidStateError
+
+ def get_loop(self) -> asyncio.AbstractEventLoop:
+ return self._loop
diff --git a/sources/pyside6/PySide6/QtAsyncio/tasks.py b/sources/pyside6/PySide6/QtAsyncio/tasks.py
new file mode 100644
index 000000000..7edc15093
--- /dev/null
+++ b/sources/pyside6/PySide6/QtAsyncio/tasks.py
@@ -0,0 +1,190 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+from . import events
+from . import futures
+
+import asyncio
+import collections.abc
+import concurrent.futures
+import contextvars
+import typing
+
+
+class QAsyncioTask(futures.QAsyncioFuture):
+ """ https://docs.python.org/3/library/asyncio-task.html """
+
+ def __init__(self, coro: typing.Union[collections.abc.Generator, collections.abc.Coroutine], *,
+ loop: typing.Optional["events.QAsyncioEventLoop"] = None,
+ name: typing.Optional[str] = None,
+ context: typing.Optional[contextvars.Context] = None) -> None:
+ super().__init__(loop=loop, context=context)
+
+ self._coro = coro # The coroutine for which this task was created.
+ self._name = name if name else "QtTask"
+
+ # The task creates a handle for its coroutine. The handle enqueues the
+ # task's step function as its callback in the event loop.
+ self._handle = self._loop.call_soon(self._step, context=self._context)
+
+ # The task step function executes the coroutine until it finishes,
+ # raises an exception or returns a future. If a future was returned,
+ # the task will await its completion (or exception).
+ self._future_to_await: typing.Optional[asyncio.Future] = None
+
+ self._cancelled = False
+ self._cancel_message: typing.Optional[str] = None
+
+ # https://docs.python.org/3/library/asyncio-extending.html#task-lifetime-support
+ asyncio._register_task(self) # type: ignore[arg-type]
+
+ def __repr__(self) -> str:
+ if self._state == futures.QAsyncioFuture.FutureState.PENDING:
+ state = "Pending"
+ elif self._state == futures.QAsyncioFuture.FutureState.DONE_WITH_RESULT:
+ state = "Done"
+ elif self._state == futures.QAsyncioFuture.FutureState.DONE_WITH_EXCEPTION:
+ state = f"Done with exception ({repr(self._exception)})"
+ elif self._state == futures.QAsyncioFuture.FutureState.CANCELLED:
+ state = "Cancelled"
+
+ return f"Task '{self.get_name()}' with state: {state}"
+
+ class QtTaskApiMisuseError(Exception):
+ pass
+
+ def set_result(self, result: typing.Any) -> None: # type: ignore[override]
+ # This function is not inherited from the Future APIs.
+ raise QAsyncioTask.QtTaskApiMisuseError("Tasks cannot set results")
+
+ def set_exception(self, exception: typing.Any) -> None: # type: ignore[override]
+ # This function is not inherited from the Future APIs.
+ raise QAsyncioTask.QtTaskApiMisuseError("Tasks cannot set exceptions")
+
+ def _step(self,
+ exception_or_future: typing.Union[
+ BaseException, futures.QAsyncioFuture, None] = None) -> None:
+ """
+ The step function is the heart of a task. It is scheduled in the event
+ loop repeatedly, executing the coroutine "step" by "step" (i.e.,
+ iterating through the asynchronous generator) until it finishes with an
+ exception or successfully. Each step can optionally receive an
+ exception or a future as a result from a previous step to handle.
+ """
+
+ if self.done():
+ return
+ result = None
+ self._future_to_await = None
+
+ if asyncio.futures.isfuture(exception_or_future):
+ try:
+ exception_or_future.result()
+ except BaseException as e:
+ exception_or_future = e
+
+ try:
+ asyncio._enter_task(self._loop, self) # type: ignore[arg-type]
+
+ # It is at this point that the coroutine is resumed for the current
+ # step (i.e. asynchronous generator iteration). It will now be
+ # executed until it yields (and potentially returns a future),
+ # raises an exception, is cancelled, or finishes successfully.
+
+ if isinstance(exception_or_future, BaseException):
+ # If the coroutine doesn't handle this exception, it propagates
+ # to the caller.
+ result = self._coro.throw(exception_or_future)
+ else:
+ result = self._coro.send(None)
+ except StopIteration as e:
+ self._state = futures.QAsyncioFuture.FutureState.DONE_WITH_RESULT
+ self._result = e.value
+ except (concurrent.futures.CancelledError, asyncio.exceptions.CancelledError) as e:
+ self._state = futures.QAsyncioFuture.FutureState.CANCELLED
+ self._exception = e
+ except BaseException as e:
+ self._state = futures.QAsyncioFuture.FutureState.DONE_WITH_EXCEPTION
+ self._exception = e
+ else:
+ if asyncio.futures.isfuture(result):
+ # If the coroutine yields a future, the task will await its
+ # completion, and at that point the step function will be
+ # called again.
+ result.add_done_callback(
+ self._step, context=self._context) # type: ignore[arg-type]
+ self._future_to_await = result
+ if self._cancelled:
+ # If the task was cancelled, then a new future should be
+ # cancelled as well. Otherwise, in some scenarios like
+ # a loop inside the task and with bad timing, if the new
+ # future is not cancelled, the task would continue running
+ # in this loop despite having been cancelled. This bad
+ # timing can occur especially if the first future finishes
+ # very quickly.
+ self._future_to_await.cancel(self._cancel_message)
+ elif result is None:
+ # If no future was yielded, we schedule the step function again
+ # without any arguments.
+ self._loop.call_soon(self._step, context=self._context)
+ else:
+ # This is not supposed to happen.
+ exception = RuntimeError(f"Bad task result: {result}")
+ self._loop.call_soon(self._step, exception, context=self._context)
+ finally:
+ asyncio._leave_task(self._loop, self) # type: ignore[arg-type]
+
+ if self._exception:
+ self._loop.call_exception_handler({
+ "message": (str(self._exception) if self._exception
+ else "An exception occurred during task "
+ "execution"),
+ "exception": self._exception,
+ "task": self,
+ "future": (exception_or_future
+ if asyncio.futures.isfuture(exception_or_future)
+ else None)
+ })
+
+ if self.done():
+ self._schedule_callbacks()
+
+ # https://docs.python.org/3/library/asyncio-extending.html#task-lifetime-support
+ asyncio._unregister_task(self) # type: ignore[arg-type]
+
+ def get_stack(self, *, limit=None) -> typing.List[typing.Any]:
+ # TODO
+ raise NotImplementedError("QtTask.get_stack is not implemented")
+
+ def print_stack(self, *, limit=None, file=None) -> None:
+ # TODO
+ raise NotImplementedError("QtTask.print_stack is not implemented")
+
+ def get_coro(self) -> typing.Union[collections.abc.Generator, collections.abc.Coroutine]:
+ return self._coro
+
+ def get_name(self) -> str:
+ return self._name
+
+ def set_name(self, value) -> None:
+ self._name = str(value)
+
+ def cancel(self, msg: typing.Optional[str] = None) -> bool:
+ if self.done():
+ return False
+ self._cancel_message = msg
+ self._handle.cancel()
+ if self._future_to_await is not None:
+ # A task that is awaiting a future must also cancel this future in
+ # order for the cancellation to be successful.
+ self._future_to_await.cancel(msg)
+ self._cancelled = True
+ return True
+
+ def uncancel(self) -> None:
+ # TODO
+ raise NotImplementedError("QtTask.uncancel is not implemented")
+
+ def cancelling(self) -> bool:
+ # TODO
+ raise NotImplementedError("QtTask.cancelling is not implemented")
diff --git a/sources/pyside6/PySide6/QtAxContainer/CMakeLists.txt b/sources/pyside6/PySide6/QtAxContainer/CMakeLists.txt
new file mode 100644
index 000000000..3857d8ddb
--- /dev/null
+++ b/sources/pyside6/PySide6/QtAxContainer/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtAxContainer)
+
+set(QtAxContainer_SRC
+${QtAxContainer_GEN_DIR}/qaxbase_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxbaseobject_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxbasewidget_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxobject_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxobjectinterface_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxscript_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxscriptengine_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxscriptmanager_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxselect_wrapper.cpp
+${QtAxContainer_GEN_DIR}/qaxwidget_wrapper.cpp
+# module is always needed
+${QtAxContainer_GEN_DIR}/qtaxcontainer_module_wrapper.cpp)
+
+configure_file("${QtAxContainer_SOURCE_DIR}/QtAxContainer_global.post.h.in"
+ "${QtAxContainer_BINARY_DIR}/QtAxContainer_global.post.h" @ONLY)
+
+set(QtAxContainer_include_dirs
+ ${QtAxContainer_SOURCE_DIR}
+ ${QtAxContainer_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+set(QtAxContainer_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}AxContainer_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}AxBase_LIBRARIES})
+
+set(QtAxContainer_deps QtWidgets)
+
+create_pyside_module(NAME QtAxContainer
+ INCLUDE_DIRS QtAxContainer_include_dirs
+ LIBRARIES QtAxContainer_libraries
+ DEPS QtAxContainer_deps
+ TYPESYSTEM_PATH QtAxContainer_SOURCE_DIR
+ SOURCES QtAxContainer_SRC
+ TYPESYSTEM_NAME ${QtAxContainer_BINARY_DIR}/typesystem_axcontainer.xml)
diff --git a/sources/pyside6/PySide6/QtAxContainer/QtAxContainer_global.post.h.in b/sources/pyside6/PySide6/QtAxContainer/QtAxContainer_global.post.h.in
new file mode 100644
index 000000000..f4033c4f5
--- /dev/null
+++ b/sources/pyside6/PySide6/QtAxContainer/QtAxContainer_global.post.h.in
@@ -0,0 +1 @@
+#include <QtAxContainer/QtAxContainer>
diff --git a/sources/pyside6/PySide6/QtAxContainer/typesystem_axcontainer.xml b/sources/pyside6/PySide6/QtAxContainer/typesystem_axcontainer.xml
new file mode 100644
index 000000000..4d1cbe91c
--- /dev/null
+++ b/sources/pyside6/PySide6/QtAxContainer/typesystem_axcontainer.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.QtAxContainer"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+ <rejection class="*" function-name="connectNotify"/>
+ <rejection class="*" function-name="queryInterface"/>
+ <rejection class="*" function-name="qt_metacall"/>
+ <rejection class="*" function-name="qt_static_metacall"/>
+
+ <object-type name="QAxBase">
+ <!-- PYSIDE-1410, Check for QVariantList first since it also is a QVariant -->
+ <modify-function signature="dynamicCall(const char*,QList&lt;QVariant&gt;&amp;)" overload-number="0"/>
+ <modify-function signature="dynamicCall(const char*,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)" overload-number="1"/>
+ <!-- Remove protected, internal function -->
+ <modify-function signature="dynamicCall(const char*,QList&lt;QVariant&gt;&amp;,unsigned)" remove="all"/>
+ </object-type>
+ <object-type name="QAxBaseObject"/>
+ <object-type name="QAxObject"/>
+ <object-type name="QAxObjectInterface"/>
+ <object-type name="QAxScript">
+ <enum-type name="FunctionFlags"/>
+ </object-type>
+ <object-type name="QAxScriptEngine">
+ <enum-type name="State"/>
+ </object-type>
+ <object-type name="QAxScriptManager">
+ <!-- Ax Servers only -->
+ <modify-function signature="addObject(QObject*)" remove="all"/>
+ </object-type>
+ <object-type name="QAxBaseWidget"/>
+ <object-type name="QAxSelect">
+ <enum-type name="SandboxingLevel"/>
+ </object-type>
+ <object-type name="QAxWidget"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtBluetooth/CMakeLists.txt b/sources/pyside6/PySide6/QtBluetooth/CMakeLists.txt
new file mode 100644
index 000000000..e063a4546
--- /dev/null
+++ b/sources/pyside6/PySide6/QtBluetooth/CMakeLists.txt
@@ -0,0 +1,56 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtBluetooth)
+
+set(QtBluetooth_OPTIONAL_SRC )
+set(QtBluetooth_DROPPED_ENTRIES )
+
+set(QtBluetooth_SRC
+ ${QtBluetooth_GEN_DIR}/qbluetooth_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothaddress_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothdevicediscoveryagent_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothdeviceinfo_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothhostinfo_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothlocaldevice_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothserver_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothservicediscoveryagent_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothserviceinfo_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothserviceinfo_alternative_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothserviceinfo_sequence_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothsocket_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qbluetoothuuid_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergyadvertisingdata_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergyadvertisingparameters_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergyadvertisingparameters_addressinfo_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergycharacteristic_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergycharacteristicdata_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergyconnectionparameters_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergycontroller_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergydescriptor_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergydescriptordata_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergyservice_wrapper.cpp
+ ${QtBluetooth_GEN_DIR}/qlowenergyservicedata_wrapper.cpp
+# module is always needed
+ ${QtBluetooth_GEN_DIR}/qtbluetooth_module_wrapper.cpp
+)
+
+set(QtBluetooth_include_dirs ${QtBluetooth_SOURCE_DIR}
+ ${QtBluetooth_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Bluetooth_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtBluetooth_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Bluetooth_LIBRARIES})
+
+set(QtBluetooth_deps QtCore)
+
+create_pyside_module(NAME QtBluetooth
+ INCLUDE_DIRS QtBluetooth_include_dirs
+ LIBRARIES QtBluetooth_libraries
+ DEPS QtBluetooth_deps
+ TYPESYSTEM_PATH QtBluetooth_SOURCE_DIR
+ SOURCES QtBluetooth_SRC
+ DROPPED_ENTRIES QtBluetooth_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml b/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml
new file mode 100644
index 000000000..a3687b6b0
--- /dev/null
+++ b/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtBluetooth"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <namespace-type name="QBluetooth">
+ <enum-type name="AttAccessConstraint" flags="AttAccessConstraints"/>
+ <enum-type name="Security" flags="SecurityFlags"/>
+ </namespace-type>
+ <value-type name="QBluetoothAddress"/>
+ <value-type name="QBluetoothHostInfo"/>
+ <object-type name="QBluetoothLocalDevice">
+ <enum-type name="Error"/>
+ <enum-type name="HostMode"/>
+ <enum-type name="Pairing"/>
+ </object-type>
+ <object-type name="QBluetoothDeviceDiscoveryAgent">
+ <enum-type name="DiscoveryMethod" flags="DiscoveryMethods"/>
+ <enum-type name="Error"/>
+ </object-type>
+ <value-type name="QBluetoothDeviceInfo">
+ <enum-type name="CoreConfiguration" flags="CoreConfigurations"/>
+ <enum-type name="Field" flags="Fields"/>
+ <enum-type name="MajorDeviceClass"/>
+ <enum-type name="MinorAudioVideoClass"/>
+ <enum-type name="MinorComputerClass"/>
+ <enum-type name="MinorHealthClass"/>
+ <enum-type name="MinorImagingClass"/>
+ <enum-type name="MinorMiscellaneousClass"/>
+ <enum-type name="MinorNetworkClass"/>
+ <enum-type name="MinorPeripheralClass"/>
+ <enum-type name="MinorPhoneClass"/>
+ <enum-type name="MinorToyClass"/>
+ <enum-type name="MinorWearableClass"/>
+ <enum-type name="ServiceClass" flags="ServiceClasses"/>
+ </value-type>
+ <object-type name="QBluetoothServiceDiscoveryAgent">
+ <enum-type name="DiscoveryMode"/>
+ <enum-type name="Error"/>
+ </object-type>
+ <object-type name="QBluetoothServer">
+ <enum-type name="Error"/>
+ </object-type>
+ <value-type name="QBluetoothServiceInfo">
+ <enum-type name="AttributeId"/>
+ <enum-type name="Protocol"/>
+ <value-type name="Alternative"/>
+ <value-type name="Sequence"/>
+ </value-type>
+ <object-type name="QBluetoothSocket">
+ <enum-type name="SocketError"/>
+ <enum-type name="SocketState"/>
+ </object-type>
+ <value-type name="QBluetoothUuid">
+ <enum-type name="CharacteristicType"/>
+ <enum-type name="DescriptorType"/>
+ <enum-type name="ProtocolUuid"/>
+ <enum-type name="ServiceClassUuid"/>
+ <modify-function signature="toUInt16(bool*)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toUInt32(bool*)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ </value-type>
+ <value-type name="QLowEnergyAdvertisingData">
+ <enum-type name="Discoverability"/>
+ </value-type>
+ <value-type name="QLowEnergyAdvertisingParameters">
+ <value-type name="AddressInfo"/>
+ <enum-type name="FilterPolicy"/>
+ <enum-type name="Mode"/>
+ </value-type>
+ <value-type name="QLowEnergyCharacteristic">
+ <enum-type name="PropertyType" flags="PropertyTypes"/>
+ </value-type>
+ <value-type name="QLowEnergyCharacteristicData"/>
+ <value-type name="QLowEnergyConnectionParameters"/>
+ <object-type name="QLowEnergyController">
+ <enum-type name="ControllerState"/>
+ <enum-type name="Error"/>
+ <enum-type name="RemoteAddressType"/>
+ <enum-type name="Role"/>
+ </object-type>
+ <value-type name="QLowEnergyDescriptor"/>
+ <value-type name="QLowEnergyDescriptorData"/>
+ <object-type name="QLowEnergyService">
+ <enum-type name="DiscoveryMode"/>
+ <enum-type name="ServiceError"/>
+ <enum-type name="ServiceState"/>
+ <enum-type name="ServiceType" flags="ServiceTypes"/>
+ <enum-type name="WriteMode"/>
+ </object-type>
+ <value-type name="QLowEnergyServiceData">
+ <enum-type name="ServiceType"/>
+ </value-type>
+
+ <!-- QtNetwork is pulled in via QtBluetoothDepends. -->
+ <suppress-warning text="^Scoped enum 'Q(Ocsp)|(Dtls).*' does not have a type entry.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtCharts/CMakeLists.txt b/sources/pyside6/PySide6/QtCharts/CMakeLists.txt
new file mode 100644
index 000000000..20126fdee
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCharts/CMakeLists.txt
@@ -0,0 +1,85 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtCharts)
+
+set(QtCharts_SRC
+${QtCharts_GEN_DIR}/qabstractaxis_wrapper.cpp
+${QtCharts_GEN_DIR}/qabstractbarseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qabstractseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qarealegendmarker_wrapper.cpp
+${QtCharts_GEN_DIR}/qareaseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qbarcategoryaxis_wrapper.cpp
+${QtCharts_GEN_DIR}/qbarlegendmarker_wrapper.cpp
+${QtCharts_GEN_DIR}/qbarmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qbarseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qbarset_wrapper.cpp
+${QtCharts_GEN_DIR}/qboxplotlegendmarker_wrapper.cpp
+${QtCharts_GEN_DIR}/qboxplotmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qboxplotseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qboxset_wrapper.cpp
+${QtCharts_GEN_DIR}/qcandlesticklegendmarker_wrapper.cpp
+${QtCharts_GEN_DIR}/qcandlestickmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qcandlestickseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qcandlestickset_wrapper.cpp
+${QtCharts_GEN_DIR}/qcategoryaxis_wrapper.cpp
+${QtCharts_GEN_DIR}/qchart_wrapper.cpp
+${QtCharts_GEN_DIR}/qchartview_wrapper.cpp
+${QtCharts_GEN_DIR}/qcoloraxis_wrapper.cpp
+${QtCharts_GEN_DIR}/qdatetimeaxis_wrapper.cpp
+${QtCharts_GEN_DIR}/qhbarmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qhboxplotmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qhcandlestickmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qhorizontalbarseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qhorizontalpercentbarseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qhorizontalstackedbarseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qhpiemodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qhxymodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qlegend_wrapper.cpp
+${QtCharts_GEN_DIR}/qlegendmarker_wrapper.cpp
+${QtCharts_GEN_DIR}/qlineseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qlogvalueaxis_wrapper.cpp
+${QtCharts_GEN_DIR}/qpercentbarseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qpielegendmarker_wrapper.cpp
+${QtCharts_GEN_DIR}/qpiemodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qpieseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qpieslice_wrapper.cpp
+${QtCharts_GEN_DIR}/qpolarchart_wrapper.cpp
+${QtCharts_GEN_DIR}/qscatterseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qsplineseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qstackedbarseries_wrapper.cpp
+${QtCharts_GEN_DIR}/qvalueaxis_wrapper.cpp
+${QtCharts_GEN_DIR}/qvbarmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qvboxplotmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qvcandlestickmodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qvpiemodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qvxymodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qxylegendmarker_wrapper.cpp
+${QtCharts_GEN_DIR}/qxymodelmapper_wrapper.cpp
+${QtCharts_GEN_DIR}/qxyseries_wrapper.cpp
+# module is always needed
+${QtCharts_GEN_DIR}/qtcharts_module_wrapper.cpp
+)
+
+set(QtCharts_include_dirs ${QtCharts_SOURCE_DIR}
+ ${QtCharts_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Charts_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+set(QtCharts_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Charts_LIBRARIES})
+
+set(QtCharts_deps QtCore QtGui QtWidgets)
+
+create_pyside_module(NAME QtCharts
+ INCLUDE_DIRS QtCharts_include_dirs
+ LIBRARIES QtCharts_libraries
+ DEPS QtCharts_deps
+ TYPESYSTEM_PATH QtCharts_SOURCE_DIR
+ SOURCES QtCharts_SRC)
diff --git a/sources/pyside6/PySide6/QtCharts/typesystem_charts.xml b/sources/pyside6/PySide6/QtCharts/typesystem_charts.xml
new file mode 100644
index 000000000..d4337df8e
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCharts/typesystem_charts.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtCharts"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+ <!-- PYSIDE-1101 Removing inherited method to avoid argument conflict
+ on the QChart::scroll overload -->
+ <rejection class="QGraphicsItem" function-name="scroll"/>
+ <object-type name="QAbstractAxis">
+ <enum-type name="AxisType"/>
+ </object-type>
+ <object-type name="QAbstractBarSeries">
+ <enum-type name="LabelsPosition"/>
+ <modify-function signature="append(QBarSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="append(QList&lt;QBarSet*&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insert(int,QBarSet*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="take(QBarSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstractSeries">
+ <enum-type name="SeriesType"/>
+ </object-type>
+ <object-type name="QAreaLegendMarker"/>
+ <object-type name="QAreaSeries">
+ <modify-function signature="setUpperSeries(QLineSeries*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setLowerSeries(QLineSeries*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QBarCategoryAxis"/>
+ <object-type name="QBarLegendMarker"/>
+ <object-type name="QBarModelMapper"/>
+ <object-type name="QBarSeries"/>
+ <object-type name="QBarSet"/>
+ <object-type name="QBoxPlotLegendMarker"/>
+ <object-type name="QBoxPlotModelMapper"/>
+ <object-type name="QBoxPlotSeries">
+ <modify-function signature="append(QBoxSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="append(QList&lt;QBoxSet*&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insert(int,QBoxSet*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="take(QBoxSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QBoxSet">
+ <enum-type name="ValuePositions" python-type="IntEnum"/>
+ </object-type>
+ <object-type name="QCandlestickLegendMarker"/>
+ <object-type name="QCandlestickModelMapper"/>
+ <object-type name="QCandlestickSeries">
+ <modify-function signature="append(QCandlestickSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="append(QList&lt;QCandlestickSet*&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insert(int,QCandlestickSet*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="take(QCandlestickSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QCandlestickSet"/>
+ <object-type name="QCategoryAxis">
+ <enum-type name="AxisLabelsPosition"/>
+ </object-type>
+ <object-type name="QChart">
+ <enum-type name="ChartType"/>
+ <enum-type name="ChartTheme"/>
+ <enum-type name="AnimationOption" flags="AnimationOptions"/>
+ <modify-function signature="addAxis(QAbstractAxis*,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addSeries(QAbstractSeries*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisX(QAbstractAxis*,QAbstractSeries*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisY(QAbstractAxis*,QAbstractSeries*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeAxis(QAbstractAxis*)">
+ <inject-code file="../glue/qtcharts.cpp" snippet="qchart-releaseownership"/>
+ </modify-function>
+ <modify-function signature="removeSeries(QAbstractSeries*)">
+ <inject-code file="../glue/qtcharts.cpp" snippet="qchart-releaseownership"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QChartView">
+ <enum-type name="RubberBand" flags="RubberBands"/>
+ <modify-function signature="QChartView(QChart*,QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setChart(QChart*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QColorAxis"/>
+ <object-type name="QDateTimeAxis"/>
+ <object-type name="QHBarModelMapper"/>
+ <object-type name="QHBoxPlotModelMapper"/>
+ <object-type name="QHCandlestickModelMapper"/>
+ <object-type name="QHorizontalBarSeries"/>
+ <object-type name="QHorizontalPercentBarSeries"/>
+ <object-type name="QHorizontalStackedBarSeries"/>
+ <object-type name="QHPieModelMapper"/>
+ <object-type name="QHXYModelMapper"/>
+ <object-type name="QLegend">
+ <enum-type name="MarkerShape"/>
+ </object-type>
+ <object-type name="QLegendMarker">
+ <enum-type name="LegendMarkerType"/>
+ </object-type>
+ <object-type name="QLineSeries"/>
+ <object-type name="QLogValueAxis"/>
+ <object-type name="QPercentBarSeries"/>
+ <object-type name="QPieLegendMarker"/>
+ <object-type name="QPieModelMapper"/>
+ <object-type name="QPieSlice">
+ <enum-type name="LabelPosition"/>
+ </object-type>
+ <object-type name="QPieSeries">
+ <modify-function signature="append(QPieSlice*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="append(QList&lt;QPieSlice*&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insert(int,QPieSlice*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="take(QPieSlice*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QPolarChart">
+ <enum-type name="PolarOrientation" flags="PolarOrientations"/>
+ <modify-function signature="addAxis(QAbstractAxis*,QPolarChart::PolarOrientation)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <!-- Compile error assigning default flags value -->
+ <modify-function signature="axes(QFlags&lt;QPolarChart::PolarOrientation&gt;,QAbstractSeries*)const" remove="all"/>
+ </object-type>
+ <object-type name="QScatterSeries">
+ <enum-type name="MarkerShape"/>
+ </object-type>
+ <object-type name="QSplineSeries"/>
+ <object-type name="QStackedBarSeries"/>
+ <object-type name="QValueAxis">
+ <enum-type name="TickType"/>
+ </object-type>
+ <object-type name="QVBarModelMapper"/>
+ <object-type name="QVBoxPlotModelMapper"/>
+ <object-type name="QVCandlestickModelMapper"/>
+ <object-type name="QVPieModelMapper"/>
+ <object-type name="QVXYModelMapper"/>
+ <object-type name="QXYLegendMarker"/>
+ <object-type name="QXYModelMapper"/>
+ <!-- Add numpy versions as separate functions since passing ndarrays to other
+ typecheck macros causes:
+ FIXME Subscripted generics cannot be used with class and instance checks -->
+ <object-type name="QXYSeries">
+ <enum-type name="PointConfiguration"/>
+ <include file-name="pyside_numpy.h" location="global"/>
+ <add-function signature="appendNp(PyArrayObject *@x@, PyArrayObject *@y@)">
+ <inject-code file="../glue/qtcharts.cpp" snippet="qxyseries-appendnp-numpy-x-y"/>
+ <inject-documentation format="target" mode="append">
+ Adds the list of data points specified by two
+ one-dimensional, equally sized numpy arrays representing the x, y values, respectively.
+ </inject-documentation>
+ </add-function>
+ <add-function signature="replaceNp(PyArrayObject *@x@, PyArrayObject *@y@)">
+ <inject-code file="../glue/qtcharts.cpp" snippet="qxyseries-replacenp-numpy-x-y"/>
+ <inject-documentation format="target" mode="append">
+ Replaces the current points with the points specified by two
+ one-dimensional, equally sized numpy arrays representing the x, y values, respectively.
+ </inject-documentation>
+ </add-function>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtConcurrent/CMakeLists.txt b/sources/pyside6/PySide6/QtConcurrent/CMakeLists.txt
new file mode 100644
index 000000000..134e44ed9
--- /dev/null
+++ b/sources/pyside6/PySide6/QtConcurrent/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtConcurrent)
+
+set(QtConcurrent_SRC
+${QtConcurrent_GEN_DIR}/qtconcurrent_wrapper.cpp
+${QtConcurrent_GEN_DIR}/qfuturevoid_wrapper.cpp
+${QtConcurrent_GEN_DIR}/qfutureqstring_wrapper.cpp
+${QtConcurrent_GEN_DIR}/qfuturewatchervoid_wrapper.cpp
+${QtConcurrent_GEN_DIR}/qfuturewatcherqstring_wrapper.cpp
+# module is always needed
+${QtConcurrent_GEN_DIR}/qtconcurrent_module_wrapper.cpp
+)
+
+set(QtConcurrent_include_dirs ${QtConcurrent_SOURCE_DIR}
+ ${QtConcurrent_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Concurrent_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtConcurrent_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Concurrent_LIBRARIES})
+
+set(QtConcurrent_deps QtCore)
+
+create_pyside_module(NAME QtConcurrent
+ INCLUDE_DIRS QtConcurrent_include_dirs
+ LIBRARIES QtConcurrent_libraries
+ DEPS QtConcurrent_deps
+ TYPESYSTEM_PATH QtConcurrent_SOURCE_DIR
+ SOURCES QtConcurrent_SRC)
diff --git a/sources/pyside6/PySide6/QtConcurrent/curr_errors.txt b/sources/pyside6/PySide6/QtConcurrent/curr_errors.txt
new file mode 100644
index 000000000..d8405c755
--- /dev/null
+++ b/sources/pyside6/PySide6/QtConcurrent/curr_errors.txt
@@ -0,0 +1,21 @@
+Generating class model... [OK]
+Generating enum model... [OK]
+Generating namespace model... [WARNING]
+ enum 'QtConcurrent::ThreadFunctionResult' does not have a type entry or is not an enum
+ enum 'QtConcurrent::ReduceQueueThrottleLimit' does not have a type entry or is not an enum
+
+
+Resolving typedefs... [OK]
+Fixing class inheritance... [OK]
+Detecting inconsistencies in class model... [OK]
+[OK]
+
+Done, 2 warnings (506 known issues)
+Scanning dependencies of target QtConcurrent
+[ 21%] Building CXX object PySide/QtConcurrent/CMakeFiles/QtConcurrent.dir/PySide/QtConcurrent/qtconcurrent_module_wrapper.cpp.o
+In file included from /Users/tismer/src/pyside-setup2/pyside_build/py3.4-qt5.4.2-64bit-debug/pyside/PySide/QtConcurrent/PySide/QtConcurrent/qtconcurrent_module_wrapper.cpp:30:
+/Users/tismer/src/pyside-setup2/pyside_build/py3.4-qt5.4.2-64bit-debug/pyside/PySide/QtConcurrent/PySide/QtConcurrent/pyside_qtconcurrent_python.h:44:10: fatal error:
+ 'qtconcurrentexception.h' file not found
+#include <qtconcurrentexception.h>
+ ^
+1 error generated.
diff --git a/sources/pyside6/PySide6/QtConcurrent/typesystem_concurrent.xml b/sources/pyside6/PySide6/QtConcurrent/typesystem_concurrent.xml
new file mode 100644
index 000000000..1892793b9
--- /dev/null
+++ b/sources/pyside6/PySide6/QtConcurrent/typesystem_concurrent.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtConcurrent"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+
+ <!-- Qt5: this is currently the minimum possible QtConcurrent support, by just extracting
+ the name space from QtCore -->
+ <namespace-type name="QtConcurrent" target-type="class">
+ <enum-type name="FutureResult"/>
+ <enum-type name="ReduceOption" flags="ReduceOptions"/>
+ <enum-type name="ThreadFunctionResult"/>
+ <extra-includes>
+ <include file-name="qtconcurrentreducekernel.h" location="global"/>
+ <include file-name="qtconcurrentthreadengine.h" location="global"/>
+ </extra-includes>
+ </namespace-type>
+
+ <typedef-type name="QFutureVoid" source="QFuture&lt;void&gt;" disable-wrapper="yes">
+ <include file-name="QtCore/qfuture.h" location="global"/>
+ </typedef-type>
+ <typedef-type name="QFutureQString" source="QFuture&lt;QString&gt;" disable-wrapper="yes">
+ <include file-name="QtCore/qfuture.h" location="global"/>
+ </typedef-type>
+ <typedef-type name="QFutureWatcherVoid" source="QFutureWatcher&lt;void&gt;">
+ <include file-name="QtCore/qfuturewatcher.h" location="global"/>
+ </typedef-type>
+ <typedef-type name="QFutureWatcherQString" source="QFutureWatcher&lt;QString&gt;">
+ <include file-name="QtCore/qfuturewatcher.h" location="global"/>
+ </typedef-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtCore/CMakeLists.txt b/sources/pyside6/PySide6/QtCore/CMakeLists.txt
new file mode 100644
index 000000000..f3e4be0f9
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/CMakeLists.txt
@@ -0,0 +1,291 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtCore)
+
+set(CMAKE_AUTOMOC ON)
+
+set(QtCore_DROPPED_ENTRIES )
+
+set(QtCore_static_sources
+ "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp"
+ "${QtCore_SOURCE_DIR}/glue/core_snippets.cpp"
+ "${QtCore_SOURCE_DIR}/glue/qtcorehelper.cpp"
+ "${QtCore_SOURCE_DIR}/glue/qiopipe.cpp"
+ "${pyside6_SOURCE_DIR}/qiopipe.h"
+)
+
+if(ENABLE_WIN)
+ set(SPECIFIC_OS_FILES
+ ${QtCore_GEN_DIR}/qwineventnotifier_wrapper.cpp
+ )
+else()
+ set(SPECIFIC_OS_FILES
+ ${QtCore_GEN_DIR}/qprocess_unixprocessparameters_wrapper.cpp)
+endif()
+
+set(QtCore_SRC
+${QtCore_GEN_DIR}/qabstractanimation_wrapper.cpp
+${QtCore_GEN_DIR}/qabstracteventdispatcher_timerinfo_wrapper.cpp
+${QtCore_GEN_DIR}/qabstracteventdispatcher_wrapper.cpp
+${QtCore_GEN_DIR}/qabstractitemmodel_wrapper.cpp
+${QtCore_GEN_DIR}/qabstractlistmodel_wrapper.cpp
+${QtCore_GEN_DIR}/qabstractnativeeventfilter_wrapper.cpp
+${QtCore_GEN_DIR}/qabstractproxymodel_wrapper.cpp
+${QtCore_GEN_DIR}/qabstracttablemodel_wrapper.cpp
+${QtCore_GEN_DIR}/qanimationgroup_wrapper.cpp
+${QtCore_GEN_DIR}/qbasicmutex_wrapper.cpp
+${QtCore_GEN_DIR}/qbasictimer_wrapper.cpp
+${QtCore_GEN_DIR}/qbitarray_wrapper.cpp
+${QtCore_GEN_DIR}/qbuffer_wrapper.cpp
+${QtCore_GEN_DIR}/qbytearray_frombase64result_wrapper.cpp
+${QtCore_GEN_DIR}/qbytearray_wrapper.cpp
+${QtCore_GEN_DIR}/qbytearraymatcher_wrapper.cpp
+${QtCore_GEN_DIR}/qcalendar_systemid_wrapper.cpp
+${QtCore_GEN_DIR}/qcalendar_wrapper.cpp
+${QtCore_GEN_DIR}/qcalendar_yearmonthday_wrapper.cpp
+${QtCore_GEN_DIR}/qcborarray_wrapper.cpp
+${QtCore_GEN_DIR}/qcborerror_wrapper.cpp
+${QtCore_GEN_DIR}/qcbormap_wrapper.cpp
+${QtCore_GEN_DIR}/qcborparsererror_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstreamreader_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstreamwriter_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstringresultbytearray_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstringresultstring_wrapper.cpp
+${QtCore_GEN_DIR}/qcborvalue_wrapper.cpp
+${QtCore_GEN_DIR}/qchildevent_wrapper.cpp
+${QtCore_GEN_DIR}/qcollator_wrapper.cpp
+${QtCore_GEN_DIR}/qcollatorsortkey_wrapper.cpp
+${QtCore_GEN_DIR}/qcommandlineoption_wrapper.cpp
+${QtCore_GEN_DIR}/qcommandlineparser_wrapper.cpp
+${QtCore_GEN_DIR}/qconcatenatetablesproxymodel_wrapper.cpp
+${QtCore_GEN_DIR}/qcoreapplication_wrapper.cpp
+${QtCore_GEN_DIR}/qcryptographichash_wrapper.cpp
+${QtCore_GEN_DIR}/qdatastream_wrapper.cpp
+${QtCore_GEN_DIR}/qdate_wrapper.cpp
+${QtCore_GEN_DIR}/qdatetime_wrapper.cpp
+${QtCore_GEN_DIR}/qdeadlinetimer_wrapper.cpp
+${QtCore_GEN_DIR}/qdir_wrapper.cpp
+${QtCore_GEN_DIR}/qdiriterator_wrapper.cpp
+${QtCore_GEN_DIR}/qdynamicpropertychangeevent_wrapper.cpp
+${QtCore_GEN_DIR}/qeasingcurve_wrapper.cpp
+${QtCore_GEN_DIR}/qelapsedtimer_wrapper.cpp
+${QtCore_GEN_DIR}/qevent_wrapper.cpp
+${QtCore_GEN_DIR}/qeventloop_wrapper.cpp
+${QtCore_GEN_DIR}/qfactoryinterface_wrapper.cpp
+${QtCore_GEN_DIR}/qfile_wrapper.cpp
+${QtCore_GEN_DIR}/qfiledevice_wrapper.cpp
+${QtCore_GEN_DIR}/qfileinfo_wrapper.cpp
+${QtCore_GEN_DIR}/qfileselector_wrapper.cpp
+${QtCore_GEN_DIR}/qfilesystemwatcher_wrapper.cpp
+${QtCore_GEN_DIR}/qfutureinterfacebase_wrapper.cpp
+${QtCore_GEN_DIR}/qgenericargument_wrapper.cpp
+${QtCore_GEN_DIR}/qgenericreturnargument_wrapper.cpp
+${QtCore_GEN_DIR}/qhashseed_wrapper.cpp
+${QtCore_GEN_DIR}/qidentityproxymodel_wrapper.cpp
+${QtCore_GEN_DIR}/qiodevice_wrapper.cpp
+${QtCore_GEN_DIR}/qiodevicebase_wrapper.cpp
+${QtCore_GEN_DIR}/qitemselection_wrapper.cpp
+${QtCore_GEN_DIR}/qitemselectionmodel_wrapper.cpp
+${QtCore_GEN_DIR}/qitemselectionrange_wrapper.cpp
+${QtCore_GEN_DIR}/qjsonarray_wrapper.cpp
+${QtCore_GEN_DIR}/qjsondocument_wrapper.cpp
+${QtCore_GEN_DIR}/qjsonparseerror_wrapper.cpp
+${QtCore_GEN_DIR}/qjsonvalue_wrapper.cpp
+${QtCore_GEN_DIR}/qkeycombination_wrapper.cpp
+${QtCore_GEN_DIR}/qlibrary_wrapper.cpp
+${QtCore_GEN_DIR}/qlibraryinfo_wrapper.cpp
+${QtCore_GEN_DIR}/qline_wrapper.cpp
+${QtCore_GEN_DIR}/qlinef_wrapper.cpp
+${QtCore_GEN_DIR}/qlocale_wrapper.cpp
+${QtCore_GEN_DIR}/qlockfile_wrapper.cpp
+${QtCore_GEN_DIR}/qloggingcategory_wrapper.cpp
+${QtCore_GEN_DIR}/qmargins_wrapper.cpp
+${QtCore_GEN_DIR}/qmarginsf_wrapper.cpp
+${QtCore_GEN_DIR}/qmessageauthenticationcode_wrapper.cpp
+${QtCore_GEN_DIR}/qmessagelogcontext_wrapper.cpp
+${QtCore_GEN_DIR}/qmetaclassinfo_wrapper.cpp
+${QtCore_GEN_DIR}/qmetaenum_wrapper.cpp
+${QtCore_GEN_DIR}/qmetamethod_wrapper.cpp
+${QtCore_GEN_DIR}/qmetaobject_connection_wrapper.cpp
+${QtCore_GEN_DIR}/qmetaobject_wrapper.cpp
+${QtCore_GEN_DIR}/qmetaproperty_wrapper.cpp
+${QtCore_GEN_DIR}/qmetatype_wrapper.cpp
+${QtCore_GEN_DIR}/qmimedata_wrapper.cpp
+${QtCore_GEN_DIR}/qmimedatabase_wrapper.cpp
+${QtCore_GEN_DIR}/qmimetype_wrapper.cpp
+${QtCore_GEN_DIR}/qmodelindex_wrapper.cpp
+${QtCore_GEN_DIR}/qmodelroledata_wrapper.cpp
+${QtCore_GEN_DIR}/qmutex_wrapper.cpp
+${QtCore_GEN_DIR}/qnativeipckey_wrapper.cpp
+${QtCore_GEN_DIR}/qobject_wrapper.cpp
+${QtCore_GEN_DIR}/qoperatingsystemversion_wrapper.cpp
+${QtCore_GEN_DIR}/qoperatingsystemversionbase_wrapper.cpp
+${QtCore_GEN_DIR}/qparallelanimationgroup_wrapper.cpp
+${QtCore_GEN_DIR}/qpauseanimation_wrapper.cpp
+${QtCore_GEN_DIR}/qpersistentmodelindex_wrapper.cpp
+${QtCore_GEN_DIR}/qpluginloader_wrapper.cpp
+${QtCore_GEN_DIR}/qpoint_wrapper.cpp
+${QtCore_GEN_DIR}/qpointf_wrapper.cpp
+${QtCore_GEN_DIR}/qprocess_wrapper.cpp
+${QtCore_GEN_DIR}/qprocessenvironment_wrapper.cpp
+${QtCore_GEN_DIR}/qpropertyanimation_wrapper.cpp
+${QtCore_GEN_DIR}/qrandomgenerator64_wrapper.cpp
+${QtCore_GEN_DIR}/qrandomgenerator_wrapper.cpp
+${QtCore_GEN_DIR}/qreadlocker_wrapper.cpp
+${QtCore_GEN_DIR}/qreadwritelock_wrapper.cpp
+${QtCore_GEN_DIR}/qrect_wrapper.cpp
+${QtCore_GEN_DIR}/qrectf_wrapper.cpp
+${QtCore_GEN_DIR}/qrecursivemutex_wrapper.cpp
+${QtCore_GEN_DIR}/qregularexpression_wrapper.cpp
+${QtCore_GEN_DIR}/qregularexpressionmatch_wrapper.cpp
+${QtCore_GEN_DIR}/qregularexpressionmatchiterator_wrapper.cpp
+${QtCore_GEN_DIR}/qresource_wrapper.cpp
+${QtCore_GEN_DIR}/qrunnable_wrapper.cpp
+${QtCore_GEN_DIR}/qsavefile_wrapper.cpp
+${QtCore_GEN_DIR}/qsemaphore_wrapper.cpp
+${QtCore_GEN_DIR}/qsemaphorereleaser_wrapper.cpp
+${QtCore_GEN_DIR}/qsequentialanimationgroup_wrapper.cpp
+${QtCore_GEN_DIR}/qsettings_wrapper.cpp
+${QtCore_GEN_DIR}/qsignalblocker_wrapper.cpp
+${QtCore_GEN_DIR}/qsignalmapper_wrapper.cpp
+${QtCore_GEN_DIR}/qsize_wrapper.cpp
+${QtCore_GEN_DIR}/qsizef_wrapper.cpp
+${QtCore_GEN_DIR}/qsocketdescriptor_wrapper.cpp
+${QtCore_GEN_DIR}/qsocketnotifier_wrapper.cpp
+${QtCore_GEN_DIR}/qsortfilterproxymodel_wrapper.cpp
+${QtCore_GEN_DIR}/qstandardpaths_wrapper.cpp
+${QtCore_GEN_DIR}/qstorageinfo_wrapper.cpp
+${QtCore_GEN_DIR}/qstringconverter_wrapper.cpp
+${QtCore_GEN_DIR}/qstringconverterbase_state_wrapper.cpp
+${QtCore_GEN_DIR}/qstringconverterbase_wrapper.cpp
+${QtCore_GEN_DIR}/qstringdecoder_wrapper.cpp
+${QtCore_GEN_DIR}/qstringencoder_wrapper.cpp
+${QtCore_GEN_DIR}/qstringlistmodel_wrapper.cpp
+${QtCore_GEN_DIR}/qsysinfo_wrapper.cpp
+${QtCore_GEN_DIR}/qsystemsemaphore_wrapper.cpp
+${QtCore_GEN_DIR}/qt_wrapper.cpp
+${QtCore_GEN_DIR}/qtcorehelper_qgenericargumentholder_wrapper.cpp
+${QtCore_GEN_DIR}/qtcorehelper_qgenericreturnargumentholder_wrapper.cpp
+${QtCore_GEN_DIR}/qtcorehelper_qiopipe_wrapper.cpp
+${QtCore_GEN_DIR}/qtcorehelper_qmutexlocker_wrapper.cpp
+${QtCore_GEN_DIR}/qtemporarydir_wrapper.cpp
+${QtCore_GEN_DIR}/qtemporaryfile_wrapper.cpp
+${QtCore_GEN_DIR}/qtextboundaryfinder_wrapper.cpp
+${QtCore_GEN_DIR}/qtextstream_wrapper.cpp
+${QtCore_GEN_DIR}/qtextstreammanipulator_wrapper.cpp
+${QtCore_GEN_DIR}/qthread_wrapper.cpp
+${QtCore_GEN_DIR}/qthreadpool_wrapper.cpp
+${QtCore_GEN_DIR}/qtime_wrapper.cpp
+${QtCore_GEN_DIR}/qtimeline_wrapper.cpp
+${QtCore_GEN_DIR}/qtimer_wrapper.cpp
+${QtCore_GEN_DIR}/qtimerevent_wrapper.cpp
+${QtCore_GEN_DIR}/qtimezone_offsetdata_wrapper.cpp
+${QtCore_GEN_DIR}/qtimezone_wrapper.cpp
+${QtCore_GEN_DIR}/qtranslator_wrapper.cpp
+${QtCore_GEN_DIR}/qtransposeproxymodel_wrapper.cpp
+${QtCore_GEN_DIR}/qurl_wrapper.cpp
+${QtCore_GEN_DIR}/qurlquery_wrapper.cpp
+${QtCore_GEN_DIR}/quuid_wrapper.cpp
+${QtCore_GEN_DIR}/qvariantanimation_wrapper.cpp
+${QtCore_GEN_DIR}/qversionnumber_wrapper.cpp
+${QtCore_GEN_DIR}/qwaitcondition_wrapper.cpp
+${QtCore_GEN_DIR}/qwritelocker_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamattribute_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamattributes_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamentitydeclaration_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamentityresolver_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamnamespacedeclaration_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamnotationdeclaration_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamreader_wrapper.cpp
+${QtCore_GEN_DIR}/qxmlstreamwriter_wrapper.cpp
+
+${SPECIFIC_OS_FILES}
+# module is always needed
+${QtCore_GEN_DIR}/qtcore_module_wrapper.cpp
+)
+
+get_property(QtCore_disabled_features TARGET Qt${QT_MAJOR_VERSION}::Core
+ PROPERTY QT_DISABLED_PUBLIC_FEATURES)
+
+if("permissions" IN_LIST QtCore_disabled_features)
+ list(APPEND QtCore_DROPPED_ENTRIES QPermission
+ QBluetoothPermission QCalendarPermission QCameraPermission
+ QContactsPermission QLocationPermission QMicrophonePermission)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Core: Dropping Permissions classes")
+else()
+ list(APPEND QtCore_SRC
+ ${QtCore_GEN_DIR}/qbluetoothpermission_wrapper.cpp
+ ${QtCore_GEN_DIR}/qcalendarpermission_wrapper.cpp
+ ${QtCore_GEN_DIR}/qcamerapermission_wrapper.cpp
+ ${QtCore_GEN_DIR}/qcontactspermission_wrapper.cpp
+ ${QtCore_GEN_DIR}/qlocationpermission_wrapper.cpp
+ ${QtCore_GEN_DIR}/qmicrophonepermission_wrapper.cpp
+ ${QtCore_GEN_DIR}/qpermission_wrapper.cpp)
+endif()
+
+if("sharedmemory" IN_LIST QtCore_disabled_features)
+ list(APPEND QtCore_DROPPED_ENTRIES QSharedMemory)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Core: Dropping QSharedMemory")
+else()
+ list(APPEND QtCore_SRC ${QtCore_GEN_DIR}/qsharedmemory_wrapper.cpp)
+endif()
+
+configure_file("${QtCore_SOURCE_DIR}/QtCore_global.post.h.in"
+ "${QtCore_BINARY_DIR}/QtCore_global.post.h" @ONLY)
+
+set(QtCore_glue_sources
+ "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp"
+ "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.h"
+)
+
+set(QtCore_include_dirs ${QtCore_SOURCE_DIR}
+ ${QtCore_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${pyside6_SOURCE_DIR}
+ ${libpyside_SOURCE_DIR}
+ )
+set(QtCore_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}
+ Qt::CorePrivate
+ )
+
+create_pyside_module(NAME QtCore
+ INCLUDE_DIRS QtCore_include_dirs
+ LIBRARIES QtCore_libraries
+ TYPESYSTEM_PATH QtCore_SOURCE_DIR
+ SOURCES QtCore_SRC
+ STATIC_SOURCES QtCore_static_sources
+ TYPESYSTEM_NAME ${QtCore_BINARY_DIR}/typesystem_core.xml
+ GLUE_SOURCES QtCore_glue_sources
+ DROPPED_ENTRIES QtCore_DROPPED_ENTRIES
+ )
+
+# Note: The permission API for Apple platforms only works if the Python application is packaged
+# with pyside6-deploy (uses Nuitka). Read "Notes for Developers" in Qt for Python documentation
+# for more information
+#
+# For Apple platforms, the Qt permission API implementations are in small static libraries.
+# In Qt C++, the application is linked directly to these static libraries during the build when
+# linking to the QtCore module as a post processing CMake step.
+# Being static plugins makes it difficult to add these plugins during Nuitka packaging step.
+# Thus, we link the static plugins to QtCore.abi3.so. However, to request the permissions
+# it is still required to have the necessary Information Property keys eg: NSCameraUsageDescription
+# in the Info.plist of the application bundle which Nuitka creates.
+if (APPLE)
+ set(permissions Camera Microphone Bluetooth Contacts Calendar)
+ foreach(permission IN LISTS permissions)
+ set(permission_plugin_name "QDarwin${permission}PermissionPlugin")
+ set(permission_plugin "${QT_CMAKE_EXPORT_NAMESPACE}::${permission_plugin_name}")
+ # Setting this property is necessary for Camera and Microphone. Otherwise it won't append
+ # the linker flags like -Wl,-u,_QDarwinMicrophonePermissionRequest which are required to
+ # link to qdarwinpermissionplugin_microphone_request.mm.o and find symbols like
+ # QDarwinMicrosphonePermissionHandler which handles requesting the actual permission
+ set_target_properties(QtCore PROPERTIES "_qt_has_${permission_plugin_name}_usage_description" TRUE)
+ # importing the plugin
+ qt6_import_plugins(QtCore INCLUDE ${permission_plugin})
+ endforeach()
+endif()
+
+install(FILES ${pyside6_SOURCE_DIR}/qtcorehelper.h ${pyside6_SOURCE_DIR}/qiopipe.h
+ DESTINATION include/PySide6/QtCore/)
diff --git a/sources/pyside6/PySide6/QtCore/QtCore_global.post.h.in b/sources/pyside6/PySide6/QtCore/QtCore_global.post.h.in
new file mode 100644
index 000000000..8383b9ae4
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/QtCore_global.post.h.in
@@ -0,0 +1,2 @@
+#include <qtcorehelper.h>
+#include <qiopipe.h>
diff --git a/sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp b/sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp
new file mode 100644
index 000000000..f6acf9d60
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/core_snippets.cpp
@@ -0,0 +1,346 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "core_snippets_p.h"
+#include "qtcorehelper.h"
+#include "pysideqobject.h"
+
+#include "shiboken.h"
+#ifndef Py_LIMITED_API
+# include <datetime.h>
+#endif
+#include "basewrapper.h"
+#include "autodecref.h"
+#include "pysideutils.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QMetaType>
+#include <QtCore/QObject>
+#include <QtCore/QRegularExpression>
+#include <QtCore/QStack>
+#include <QtCore/QVariant>
+
+// Helpers for QVariant conversion
+
+QMetaType QVariant_resolveMetaType(PyTypeObject *type)
+{
+ if (!PyObject_TypeCheck(type, SbkObjectType_TypeF()))
+ return {};
+ const char *typeName = Shiboken::ObjectType::getOriginalName(type);
+ if (!typeName)
+ return {};
+ const bool valueType = '*' != typeName[qstrlen(typeName) - 1];
+ // Do not convert user type of value
+ if (valueType && Shiboken::ObjectType::isUserType(type))
+ return {};
+ QMetaType metaType = QMetaType::fromName(typeName);
+ if (metaType.isValid())
+ return metaType;
+ // Do not resolve types to value type
+ if (valueType)
+ return {};
+ // Find in base types. First check tp_bases, and only after check tp_base, because
+ // tp_base does not always point to the first base class, but rather to the first
+ // that has added any python fields or slots to its object layout.
+ // See https://mail.python.org/pipermail/python-list/2009-January/520733.html
+ if (type->tp_bases) {
+ for (Py_ssize_t i = 0, size = PyTuple_GET_SIZE(type->tp_bases); i < size; ++i) {
+ auto baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(type->tp_bases, i));
+ const QMetaType derived = QVariant_resolveMetaType(baseType);
+ if (derived.isValid())
+ return derived;
+ }
+ } else if (type->tp_base) {
+ return QVariant_resolveMetaType(type->tp_base);
+ }
+ return {};
+}
+
+QVariant QVariant_convertToValueList(PyObject *list)
+{
+ if (PySequence_Size(list) < 0) {
+ // clear the error if < 0 which means no length at all
+ PyErr_Clear();
+ return {};
+ }
+
+ Shiboken::AutoDecRef element(PySequence_GetItem(list, 0));
+
+ auto *type = reinterpret_cast<PyTypeObject *>(element.object());
+ QMetaType metaType = QVariant_resolveMetaType(type);
+ if (!metaType.isValid())
+ return {};
+
+ const QByteArray listTypeName = QByteArrayLiteral("QList<") + metaType.name() + '>';
+ metaType = QMetaType::fromName(listTypeName);
+ if (!metaType.isValid())
+ return {};
+
+ Shiboken::Conversions::SpecificConverter converter(listTypeName);
+ if (!converter) {
+ qWarning("Type converter for: %s not registered.", listTypeName.constData());
+ return {};
+ }
+
+ QVariant var(metaType);
+ converter.toCpp(list, &var);
+ return var;
+}
+
+bool QVariant_isStringList(PyObject *list)
+{
+ if (!PySequence_Check(list)) {
+ // If it is not a list or a derived list class
+ // we assume that will not be a String list neither.
+ return false;
+ }
+
+ if (PySequence_Size(list) < 0) {
+ // clear the error if < 0 which means no length at all
+ PyErr_Clear();
+ return false;
+ }
+
+ Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
+ const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i);
+ if (PyUnicode_Check(item) == 0)
+ return false;
+ }
+ return true;
+}
+
+// Helpers for qAddPostRoutine
+
+namespace PySide {
+
+static QStack<PyObject *> globalPostRoutineFunctions;
+
+void globalPostRoutineCallback()
+{
+ Shiboken::GilState state;
+ for (auto *callback : globalPostRoutineFunctions) {
+ Shiboken::AutoDecRef result(PyObject_CallObject(callback, nullptr));
+ Py_DECREF(callback);
+ }
+ globalPostRoutineFunctions.clear();
+}
+
+void addPostRoutine(PyObject *callback)
+{
+ if (PyCallable_Check(callback)) {
+ globalPostRoutineFunctions << callback;
+ Py_INCREF(callback);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "qAddPostRoutine: The argument must be a callable object.");
+ }
+}
+} // namespace PySide
+
+// Helpers for QObject::findChild(ren)()
+
+static bool _findChildTypeMatch(const QObject *child, PyTypeObject *desiredType)
+{
+ auto *pyChildType = PySide::getTypeForQObject(child);
+ return pyChildType != nullptr && PyType_IsSubtype(pyChildType, desiredType);
+}
+
+static inline bool _findChildrenComparator(const QObject *child,
+ const QRegularExpression &name)
+{
+ return name.match(child->objectName()).hasMatch();
+}
+
+static inline bool _findChildrenComparator(const QObject *child,
+ const QString &name)
+{
+ return name.isNull() || name == child->objectName();
+}
+
+QObject *qObjectFindChild(const QObject *parent, const QString &name,
+ PyTypeObject *desiredType, Qt::FindChildOptions options)
+{
+ for (auto *child : parent->children()) {
+ if (_findChildrenComparator(child, name)
+ && _findChildTypeMatch(child, desiredType)) {
+ return child;
+ }
+ }
+
+ if (options.testFlag(Qt::FindChildrenRecursively)) {
+ for (auto *child : parent->children()) {
+ if (auto *obj = qObjectFindChild(child, name, desiredType, options))
+ return obj;
+ }
+ }
+ return nullptr;
+}
+
+template<typename T> // QString/QRegularExpression
+static void _findChildrenHelper(const QObject *parent, const T& name, PyTypeObject *desiredType,
+ Qt::FindChildOptions options, FindChildHandler handler)
+{
+ for (auto *child : parent->children()) {
+ if (_findChildrenComparator(child, name) && _findChildTypeMatch(child, desiredType))
+ handler(child);
+ if (options.testFlag(Qt::FindChildrenRecursively))
+ _findChildrenHelper(child, name, desiredType, options, handler);
+ }
+}
+
+void qObjectFindChildren(const QObject *parent, const QString &name,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler)
+{
+ _findChildrenHelper(parent, name, desiredType, options, handler);
+}
+
+void qObjectFindChildren(const QObject *parent, const QRegularExpression &pattern,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler)
+{
+ _findChildrenHelper(parent, pattern, desiredType, options, handler);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Helpers for translation:
+// PYSIDE-131: Use the class name as context where the calling function is
+// living. Derived Python classes have the wrong context.
+//
+// The original patch uses Python introspection to look up the current
+// function (from the frame stack) in the class __dict__ along the mro.
+//
+// The problem is that looking into the frame stack works for Python
+// functions, only. For including builtin function callers, the following
+// approach turned out to be much simpler:
+//
+// Walk the __mro__
+// - translate the string
+// - if the translated string is changed:
+// - return the translation.
+
+QString qObjectTr(PyTypeObject *type, const char *sourceText, const char *disambiguation, int n)
+{
+ PyObject *mro = type->tp_mro;
+ auto len = PyTuple_GET_SIZE(mro);
+ QString result = QString::fromUtf8(sourceText);
+ QString oldResult = result;
+ static auto *sbkObjectType = reinterpret_cast<PyTypeObject *>(SbkObject_TypeF());
+ for (Py_ssize_t idx = 0; idx < len - 1; ++idx) {
+ // Skip the last class which is `object`.
+ auto *type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ if (type == sbkObjectType)
+ continue;
+ const char *context = type->tp_name;
+ const char *dotpos = strrchr(context, '.');
+ if (dotpos != nullptr)
+ context = dotpos + 1;
+ result = QCoreApplication::translate(context, sourceText, disambiguation, n);
+ if (result != oldResult)
+ break;
+ }
+ return result;
+}
+
+bool PyDate_ImportAndCheck(PyObject *pyIn)
+{
+ if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+ return PyDate_Check(pyIn);
+}
+
+bool PyDateTime_ImportAndCheck(PyObject *pyIn)
+{
+ if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+ return PyDateTime_Check(pyIn);
+}
+
+bool PyTime_ImportAndCheck(PyObject *pyIn)
+{
+ if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+ return PyTime_Check(pyIn);
+}
+
+PyObject *invokeMetaMethod(const InvokeMetaMethodFunc &f,
+ const QtCoreHelper::QGenericArgumentHolder &a0,
+ const QtCoreHelper::QGenericArgumentHolder &a1,
+ const QtCoreHelper::QGenericArgumentHolder &a2,
+ const QtCoreHelper::QGenericArgumentHolder &a3,
+ const QtCoreHelper::QGenericArgumentHolder &a4,
+ const QtCoreHelper::QGenericArgumentHolder &a5,
+ const QtCoreHelper::QGenericArgumentHolder &a6,
+ const QtCoreHelper::QGenericArgumentHolder &a7,
+ const QtCoreHelper::QGenericArgumentHolder &a8,
+ const QtCoreHelper::QGenericArgumentHolder &a9)
+{
+ PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS
+ const bool resultB = f(a0.toGenericArgument(), a1.toGenericArgument(), a2.toGenericArgument(),
+ a3.toGenericArgument(), a4.toGenericArgument(), a5.toGenericArgument(),
+ a6.toGenericArgument(), a7.toGenericArgument(), a8.toGenericArgument(),
+ a9.toGenericArgument());
+ PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS
+ PyObject *result = resultB ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+
+// Convert a QGenericReturnArgument to Python for QMetaObject::invokeMethod
+static PyObject *convertGenericReturnArgument(const void *retData, QMetaType metaType)
+{
+ PyObject *result = nullptr;
+ switch (metaType.id()) {
+ case QMetaType::Bool:
+ result = *reinterpret_cast<const bool *>(retData) ? Py_True : Py_False;
+ Py_INCREF(result);
+ break;
+ case QMetaType::Int:
+ result = PyLong_FromLong(*reinterpret_cast<const int *>(retData));
+ break;
+ case QMetaType::Double:
+ result = PyFloat_FromDouble(*reinterpret_cast<const double *>(retData));
+ break;
+ case QMetaType::QString:
+ result = PySide::qStringToPyUnicode(*reinterpret_cast<const QString *>(retData));
+ break;
+ default: {
+ Shiboken::Conversions::SpecificConverter converter(metaType.name());
+ const auto type = converter.conversionType();
+ if (type == Shiboken::Conversions::SpecificConverter::InvalidConversion) {
+ PyErr_Format(PyExc_RuntimeError, "%s: Unable to find converter for \"%s\".",
+ __FUNCTION__, metaType.name());
+ return nullptr;
+ }
+ result = converter.toPython(retData);
+ }
+ }
+ return result;
+}
+
+PyObject *invokeMetaMethodWithReturn(const InvokeMetaMethodFuncWithReturn &f,
+ const QtCoreHelper::QGenericReturnArgumentHolder &r,
+ const QtCoreHelper::QGenericArgumentHolder &a0,
+ const QtCoreHelper::QGenericArgumentHolder &a1,
+ const QtCoreHelper::QGenericArgumentHolder &a2,
+ const QtCoreHelper::QGenericArgumentHolder &a3,
+ const QtCoreHelper::QGenericArgumentHolder &a4,
+ const QtCoreHelper::QGenericArgumentHolder &a5,
+ const QtCoreHelper::QGenericArgumentHolder &a6,
+ const QtCoreHelper::QGenericArgumentHolder &a7,
+ const QtCoreHelper::QGenericArgumentHolder &a8,
+ const QtCoreHelper::QGenericArgumentHolder &a9)
+{
+ PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS
+ const bool callResult = f(r.toGenericReturnArgument(),
+ a0.toGenericArgument(), a1.toGenericArgument(), a2.toGenericArgument(),
+ a3.toGenericArgument(), a4.toGenericArgument(), a5.toGenericArgument(),
+ a6.toGenericArgument(), a7.toGenericArgument(), a8.toGenericArgument(),
+ a9.toGenericArgument());
+ PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS
+ if (!callResult)
+ return PyErr_Format(PyExc_RuntimeError, "QMetaMethod invocation failed.");
+ return convertGenericReturnArgument(r.data(), r.metaType());
+}
diff --git a/sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h b/sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h
new file mode 100644
index 000000000..11e84b291
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/core_snippets_p.h
@@ -0,0 +1,105 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef CORE_SNIPPETS_P_H
+#define CORE_SNIPPETS_P_H
+
+#include "pysidemacros.h"
+
+#include <sbkpython.h>
+
+#include <QtCore/qnamespace.h>
+
+#include <functional>
+
+QT_FORWARD_DECLARE_CLASS(QGenericArgument)
+QT_FORWARD_DECLARE_CLASS(QGenericReturnArgument)
+QT_FORWARD_DECLARE_CLASS(QMetaType)
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_CLASS(QRegularExpression)
+QT_FORWARD_DECLARE_CLASS(QVariant);
+
+QT_BEGIN_NAMESPACE
+namespace QtCoreHelper {
+class QGenericArgumentHolder;
+class QGenericReturnArgumentHolder;
+}
+QT_END_NAMESPACE
+
+// Helpers for QVariant conversion
+
+QMetaType QVariant_resolveMetaType(PyTypeObject *type);
+
+QVariant QVariant_convertToValueList(PyObject *list);
+
+bool QVariant_isStringList(PyObject *list);
+
+// Helpers for qAddPostRoutine
+namespace PySide {
+void globalPostRoutineCallback();
+void addPostRoutine(PyObject *callback);
+}
+
+// Helpers for QObject::findChild(ren)()
+QObject *qObjectFindChild(const QObject *parent, const QString &name,
+ PyTypeObject *desiredType, Qt::FindChildOptions options);
+
+using FindChildHandler = std::function<void(QObject *)>;
+
+void qObjectFindChildren(const QObject *parent, const QString &name,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler);
+
+void qObjectFindChildren(const QObject *parent, const QRegularExpression &pattern,
+ PyTypeObject *desiredType, Qt::FindChildOptions options,
+ FindChildHandler handler);
+
+// Helpers for translation
+QString qObjectTr(PyTypeObject *type, const char *sourceText, const char *disambiguation, int n);
+
+bool PyDate_ImportAndCheck(PyObject *pyIn);
+bool PyDateTime_ImportAndCheck(PyObject *pyIn);
+bool PyTime_ImportAndCheck(PyObject *pyIn);
+
+// Helpers for QMetaObject::invokeMethod(), QMetaMethod::invoke(). The std::function
+// serves to abstract from QMetaObject/QMetaMethod invocation parameters.
+using InvokeMetaMethodFunc =
+ std::function<bool(QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,
+ QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,
+ QGenericArgument,QGenericArgument)>;
+
+using InvokeMetaMethodFuncWithReturn =
+ std::function<bool(QGenericReturnArgument,
+ QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,
+ QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,
+ QGenericArgument,QGenericArgument)>;
+
+// Call a void meta method from Python passing the argument holder helpers.
+PyObject *invokeMetaMethod(const InvokeMetaMethodFunc &f,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &);
+
+// Call a meta method with a return value from Python passing the argument holder
+// helpers.
+PyObject *invokeMetaMethodWithReturn(const InvokeMetaMethodFuncWithReturn &f,
+ const QtCoreHelper::QGenericReturnArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &,
+ const QtCoreHelper::QGenericArgumentHolder &);
+
+#endif // CORE_SNIPPETS_P_H
diff --git a/sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.cpp b/sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.cpp
new file mode 100644
index 000000000..e154b932a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.cpp
@@ -0,0 +1,123 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <sbkpython.h>
+#include <shiboken.h>
+#include <pysideweakref.h>
+
+#include <QtCore/QEasingCurve>
+
+#include "glue/qeasingcurve_glue.h"
+
+#define MAX_CUSTOM_FUNCTIONS 10
+
+static void deleteData(void *data);
+
+struct CustomFunctionsData
+{
+ static CustomFunctionsData m_list[MAX_CUSTOM_FUNCTIONS];
+
+ PySideEasingCurveFunctor *m_obj;
+ QEasingCurve::EasingFunction m_func;
+};
+
+CustomFunctionsData CustomFunctionsData::m_list[MAX_CUSTOM_FUNCTIONS];
+
+template<int N>
+struct CustomFunctions
+{
+ static void init()
+ {
+ CustomFunctionsData data;
+ data.m_obj = 0;
+ data.m_func = &CustomFunctions<N>::callback;
+ CustomFunctionsData::m_list[N] = data;
+
+ CustomFunctions<N-1>::init();
+ }
+
+ static qreal callback(qreal v)
+ {
+ return (*CustomFunctionsData::m_list[N].m_obj)(v);
+ }
+};
+
+template<>
+struct CustomFunctions<0>
+{
+ static void init()
+ {
+ CustomFunctionsData data;
+ data.m_obj = 0;
+ data.m_func = &CustomFunctions<0>::callback;
+ CustomFunctionsData::m_list[0] = data;
+ }
+
+ static qreal callback(qreal v)
+ {
+ return (*CustomFunctionsData::m_list[0].m_obj)(v);
+ }
+};
+
+void deleteData(void *data)
+{
+ delete (PySideEasingCurveFunctor *)(data);
+}
+
+void PySideEasingCurveFunctor::init()
+{
+ CustomFunctions<MAX_CUSTOM_FUNCTIONS-1>::init();
+}
+
+QEasingCurve::EasingFunction PySideEasingCurveFunctor::createCustomFuntion(PyObject *parent, PyObject *pyFunc)
+{
+ for(int i=0; i < MAX_CUSTOM_FUNCTIONS; i++) {
+ CustomFunctionsData &data = CustomFunctionsData::m_list[i];
+ if (data.m_obj == 0) {
+ data.m_obj = new PySideEasingCurveFunctor(i, parent, pyFunc);
+ return data.m_func;
+ }
+ }
+ //PyErr_Format(PyExc_RuntimeError, "PySide only supports %d custom functions simultaneously.", MAX_CUSTOM_FUNCTIONS);
+ return 0;
+}
+
+PySideEasingCurveFunctor::~PySideEasingCurveFunctor()
+{
+
+ CustomFunctionsData::m_list[m_index].m_obj = 0;
+ PyObject_SetAttr(m_parent, Shiboken::PyMagicName::ecf(), Py_None);
+}
+
+qreal PySideEasingCurveFunctor::operator()(qreal progress)
+{
+ Shiboken::GilState state;
+ PyObject *args = Py_BuildValue("(f)", progress);
+ PyObject *result = PyObject_CallObject(m_func, args);
+ qreal cppResult = 0.0;
+ if (result) {
+ Shiboken::Conversions::pythonToCppCopy(Shiboken::Conversions::PrimitiveTypeConverter<qreal>(), result, &cppResult);
+ Py_DECREF(result);
+ }
+ Py_DECREF(args);
+ return cppResult;
+}
+
+PyObject *PySideEasingCurveFunctor::callable()
+{
+ Py_INCREF(m_func);
+ return m_func;
+}
+
+PyObject *PySideEasingCurveFunctor::callable(PyObject *parent)
+{
+ return PyObject_GetAttr(parent, Shiboken::PyMagicName::ecf());
+}
+
+PySideEasingCurveFunctor::PySideEasingCurveFunctor(int index, PyObject *parent, PyObject *pyFunc)
+ : m_parent(parent), m_func(pyFunc), m_index(index)
+{
+ PyObject_SetAttr(m_parent, Shiboken::PyMagicName::ecf(), m_func);
+ PySide::WeakRef::create(m_parent, deleteData, this);
+}
+
diff --git a/sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.h b/sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.h
new file mode 100644
index 000000000..78adaae2e
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/qeasingcurve_glue.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef __QEASINGCURVE_GLUE__
+#define __QEASINGCURVE_GLUE__
+
+#include <sbkpython.h>
+#include <QtCore/QEasingCurve>
+
+class PySideEasingCurveFunctor
+{
+ public:
+ static void init();
+ static QEasingCurve::EasingFunction createCustomFuntion(PyObject *parent, PyObject *pyFunc);
+
+ qreal operator()(qreal progress);
+
+ PyObject *callable(); //Return New reference
+ static PyObject *callable(PyObject *parent); //Return New reference
+
+ ~PySideEasingCurveFunctor();
+ private:
+ PyObject *m_parent;
+ PyObject *m_func;
+ int m_index;
+
+ PySideEasingCurveFunctor(int index, PyObject *parent, PyObject *pyFunc);
+};
+
+#endif
diff --git a/sources/pyside6/PySide6/QtCore/glue/qiopipe.cpp b/sources/pyside6/PySide6/QtCore/glue/qiopipe.cpp
new file mode 100644
index 000000000..6799c0f32
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/qiopipe.cpp
@@ -0,0 +1,142 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qiopipe.h"
+
+#include <QtCore/private/qobject_p.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qiodevice.h>
+#include <QtCore/qpointer.h>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtCoreHelper
+{
+
+class QPipeEndPoint : public QIODevice
+{
+ Q_OBJECT
+
+public:
+ bool isSequential() const override;
+ qint64 bytesAvailable() const override;
+
+ void setRemoteEndPoint(QPipeEndPoint *other);
+
+protected:
+ qint64 readData(char *data, qint64 maxlen) override;
+ qint64 writeData(const char *data, qint64 len) override;
+
+private:
+ QByteArray m_buffer;
+ QPointer<QPipeEndPoint> m_remoteEndPoint;
+};
+
+class QIOPipePrivate final : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QIOPipe)
+public:
+ QIOPipePrivate();
+ ~QIOPipePrivate() {};
+
+ std::unique_ptr<QPipeEndPoint> end1;
+ std::unique_ptr<QPipeEndPoint> end2;
+};
+
+QIOPipe::QIOPipe(QObject *parent) : QObject(*(new QIOPipePrivate()), parent) { }
+
+bool QIOPipe::open(QIODevice::OpenMode mode)
+{
+ Q_D(QIOPipe);
+
+ if (!d->end1->open(mode))
+ return false;
+ switch (mode & QIODevice::ReadWrite) {
+ case QIODevice::WriteOnly:
+ case QIODevice::ReadOnly:
+ return d->end2->open(mode ^ QIODevice::ReadWrite);
+ default:
+ return d->end2->open(mode);
+ }
+}
+
+QIODevice *QIOPipe::end1() const
+{
+ Q_D(const QIOPipe);
+ return d->end1.get();
+}
+
+QIODevice *QIOPipe::end2() const
+{
+ Q_D(const QIOPipe);
+ return d->end2.get();
+}
+
+QIOPipePrivate::QIOPipePrivate() : end1(std::make_unique<QPipeEndPoint>()),
+ end2(std::make_unique<QPipeEndPoint>())
+{
+ end1->setRemoteEndPoint(end2.get());
+ end2->setRemoteEndPoint(end1.get());
+}
+
+bool QPipeEndPoint::isSequential() const
+{
+ return true;
+}
+
+qint64 QPipeEndPoint::bytesAvailable() const
+{
+ return m_buffer.size() + QIODevice::bytesAvailable();
+}
+
+void QPipeEndPoint::setRemoteEndPoint(QPipeEndPoint *other)
+{
+ m_remoteEndPoint = other;
+}
+
+qint64 QPipeEndPoint::readData(char *data, qint64 maxlen)
+{
+ maxlen = qMin(maxlen, static_cast<qint64>(m_buffer.size()));
+ if (maxlen <= 0)
+ return 0;
+
+ Q_ASSERT(maxlen > 0);
+ memcpy(data, m_buffer.data(), static_cast<size_t>(maxlen));
+ m_buffer = m_buffer.mid(maxlen);
+ return maxlen;
+}
+
+qint64 QPipeEndPoint::writeData(const char *data, qint64 len)
+{
+ if (!m_remoteEndPoint)
+ return -1;
+
+ if (len <= 0)
+ return 0;
+
+ QByteArray &buffer = m_remoteEndPoint->m_buffer;
+ const qint64 prevLen = buffer.size();
+ Q_ASSERT(prevLen >= 0);
+ len = qMin(len, std::numeric_limits<int>::max() - prevLen);
+
+ if (len == 0)
+ return 0;
+
+ Q_ASSERT(len > 0);
+ Q_ASSERT(prevLen + len > 0);
+ Q_ASSERT(prevLen + len <= std::numeric_limits<int>::max());
+
+ buffer.resize(prevLen + len);
+ memcpy(buffer.data() + prevLen, data, static_cast<size_t>(len));
+ Q_EMIT bytesWritten(len);
+ Q_EMIT m_remoteEndPoint->readyRead();
+ return len;
+}
+
+} // namespace QtCoreHelper
+
+QT_END_NAMESPACE
+
+#include "qiopipe.moc"
diff --git a/sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp b/sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp
new file mode 100644
index 000000000..948c0ce5c
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/glue/qtcorehelper.cpp
@@ -0,0 +1,108 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <qtcorehelper.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtCoreHelper {
+
+// Data classes for the generic argument data classes. The argument is freed
+// via QMetaType
+class QGenericArgumentData
+{
+public:
+ explicit QGenericArgumentData(const QMetaType &type, const void *aData) :
+ m_type(type), m_argument(m_type.name(), aData)
+ {
+ }
+
+ ~QGenericArgumentData()
+ {
+ if (m_type.isValid())
+ m_type.destroy(m_argument.data());
+ }
+
+ const QMetaType m_type;
+ const QGenericArgument m_argument;
+};
+
+class QGenericReturnArgumentData
+{
+public:
+ explicit QGenericReturnArgumentData(const QMetaType &type, void *aData) :
+ m_type(type), m_argument(m_type.name(), aData)
+ {
+ }
+
+ ~QGenericReturnArgumentData()
+ {
+ if (m_type.isValid())
+ m_type.destroy(m_argument.data());
+ }
+
+ const QMetaType m_type;
+ const QGenericReturnArgument m_argument;
+};
+
+QGenericArgumentHolder::QGenericArgumentHolder()
+{
+}
+
+QGenericArgumentHolder::QGenericArgumentHolder(const QMetaType &type, const void *aData) :
+ d(std::make_shared<QGenericArgumentData>(type, aData))
+{
+}
+
+QGenericArgumentHolder::QGenericArgumentHolder(const QGenericArgumentHolder &) = default;
+QGenericArgumentHolder::QGenericArgumentHolder(QGenericArgumentHolder &&) = default;
+QGenericArgumentHolder &QGenericArgumentHolder::operator=(const QGenericArgumentHolder &) = default;
+QGenericArgumentHolder &QGenericArgumentHolder::operator=(QGenericArgumentHolder &&) = default;
+QGenericArgumentHolder::~QGenericArgumentHolder() = default;
+
+QGenericArgument QGenericArgumentHolder::toGenericArgument() const
+{
+ return d ? d->m_argument : QGenericArgument{};
+}
+
+QMetaType QGenericArgumentHolder::metaType() const
+{
+ return d ? d->m_type : QMetaType{};
+}
+
+const void *QGenericArgumentHolder::data() const
+{
+ return d ? d->m_argument.data() : nullptr;
+}
+
+QGenericReturnArgumentHolder::QGenericReturnArgumentHolder(const QMetaType &type, void *aData) :
+ d(std::make_shared<QGenericReturnArgumentData>(type, aData))
+{
+}
+
+QGenericReturnArgumentHolder::QGenericReturnArgumentHolder(const QGenericReturnArgumentHolder &) = default;
+QGenericReturnArgumentHolder::QGenericReturnArgumentHolder(QGenericReturnArgumentHolder &&) = default;
+QGenericReturnArgumentHolder &QGenericReturnArgumentHolder::operator=(const QGenericReturnArgumentHolder &) = default;
+QGenericReturnArgumentHolder &QGenericReturnArgumentHolder::operator=(QGenericReturnArgumentHolder &&) = default;
+QGenericReturnArgumentHolder::~QGenericReturnArgumentHolder() = default;
+
+QGenericReturnArgument QGenericReturnArgumentHolder::toGenericReturnArgument() const
+{
+ return d->m_argument;
+}
+
+QMetaType QGenericReturnArgumentHolder::metaType() const
+{
+ return d->m_type;
+}
+
+const void *QGenericReturnArgumentHolder::data() const
+{
+ return d->m_argument.data();
+}
+
+} // namespace QtCoreHelper
+
+QT_END_NAMESPACE
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core.xml b/sources/pyside6/PySide6/QtCore/typesystem_core.xml
new file mode 100644
index 000000000..885b53874
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/typesystem_core.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtCore"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <?if windows?>
+ <load-typesystem name="QtCore/typesystem_core_win.xml" generate="yes"/>
+ <?endif?>
+ <load-typesystem name="QtCore/typesystem_core_common.xml" generate="yes"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
new file mode 100644
index 000000000..110f86f25
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml
@@ -0,0 +1,3630 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtCore">
+ <load-typesystem name="templates/common.xml" generate="no"/>
+ <load-typesystem name="templates/core_common.xml" generate="no"/>
+
+ <custom-type name="list of QAbstractAnimation"/>
+ <custom-type name="PySideSignalInstance"
+ check-function="PySide::Signal::checkInstanceType"/>
+<!--
+ <function signature="qChecksum(QByteArrayView data, Qt::ChecksumType)"/>
+-->
+ <extra-includes>
+ <include file-name="pysidemetatype.h" location="global"/>
+ <include file-name="pysideutils.h" location="global"/> <!-- QString conversion -->
+ <include file-name="signalmanager.h" location="global"/>
+ <!-- QtCoreHelper::QGenericReturnArgumentHolder -->
+ <include file-name="qtcorehelper.h" location="local"/>
+ </extra-includes>
+
+ <function signature="qFastCos(qreal)" since="4.6"/>
+ <function signature="qFastSin(qreal)" since="4.6"/>
+ <function signature="qFuzzyCompare(double,double)"/>
+ <function signature="qFuzzyIsNull(double)" since="4.6"/>
+ <function signature="qIsFinite(double)"/>
+ <function signature="qIsInf(double)"/>
+ <function signature="qIsNaN(double)"/>
+ <function signature="qIsNull(double)"/>
+ <!-- Qt5: gone <function signature="qRound(qreal)"/> -->
+ <function signature="qtTrId(const char*,int)" since="4.6"/>
+ <function signature="qVersion()">
+ <modify-function>
+ <modify-argument index="return" pyi-type="str"/>
+ </modify-function>
+ </function>
+ <!-- Move PyBuffer overload to front to avoid conversion PyBuffer->QByteArray -->
+ <function signature="qCompress(const uchar*,qsizetype,int)" overload-number="0">
+ <modify-function>
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qcompress-buffer"/>
+ </modify-function>
+ </function>
+ <function signature="qCompress(const QByteArray&amp;,int)" overload-number="1"/>
+ <!-- Move PyBuffer overload to front to avoid conversion PyBuffer->QByteArray -->
+ <function signature="qUncompress(const uchar*,qsizetype)" overload-number="0">
+ <modify-function>
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="quncompress-buffer"/>
+ </modify-function>
+ </function>
+ <function signature="qUncompress(const QByteArray&amp;)" overload-number="1"/>
+ <function signature="qFormatLogMessage(QtMsgType,const QMessageLogContext&amp;,const QString&amp;)"
+ doc-file="qtlogging"/>
+ <function signature="qSetMessagePattern(const QString&amp;)" doc-file="qtlogging"/>
+
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="include-pyside"/>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qarg_helper"/>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="darwin_permission_plugin"/>
+
+ <add-function signature="qDebug(const char*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="use-stream-for-format-security"/>
+ <modify-argument index="1" pyi-type="str"/>
+ </add-function>
+ <add-function signature="qCritical(const char*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="use-stream-for-format-security"/>
+ <modify-argument index="1" pyi-type="str"/>
+ </add-function>
+ <add-function signature="qFatal(const char*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qfatal"/>
+ <modify-argument index="1" pyi-type="str"/>
+ </add-function>
+ <add-function signature="qWarning(const char*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="use-stream-for-format-security"/>
+ <modify-argument index="1" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="Q_ARG(PyObject *@type@, PyObject *@value@)"
+ return-type="QtCoreHelper::QGenericArgumentHolder">
+ <inject-code file="../glue/qtcore.cpp" snippet="q_arg"/>
+ <inject-documentation format="target" mode="append">
+ This function takes a type (or a type string) and a value of that type
+ and returns an internal object that can be passed to
+ QMetaObject.invokeMethod(). See also Q_RETURN_ARG().
+ </inject-documentation>
+ </add-function>
+ <add-function signature="Q_RETURN_ARG(PyObject *@type@)"
+ return-type="QtCoreHelper::QGenericReturnArgumentHolder">
+ <inject-code file="../glue/qtcore.cpp" snippet="q_return_arg"/>
+ <inject-documentation format="target" mode="append">
+ This macro takes a type (or a type string) a value of which is then
+ returned by QMetaObject::invokeMethod(). See also Q_ARG().
+ </inject-documentation>
+ </add-function>
+
+ <!-- TODO: We do not support void* or const void* as arg -->
+ <rejection class="QMetaObject" function-name="activate"/>
+ <rejection class="QMetaObject" function-name="metacall"/>
+ <rejection class="QMetaObject" function-name="static_metacall"/>
+
+ <rejection class="QAlgorithmsPrivate"/>
+ <rejection class="QJsonPrivate"/>
+ <rejection class="QtGlobalStatic"/>
+ <rejection class="QtMetaTypePrivate"/>
+ <rejection class="QtPrivate"/>
+ <rejection class="QtSharedPointer"/>
+ <rejection class="QtStringBuilder"/>
+
+ <rejection class="q20"/>
+ <rejection class="q23"/>
+ <rejection class="q_has_char8_t"/>
+ <rejection class="QContainerInfo"/>
+ <rejection class="QHashPrivate"/>
+ <rejection class="q_no_char8_t"/>
+ <rejection class="Qt::Literals"/>
+ <rejection class="QtLiterals"/>
+ <rejection class="QtMetaContainerPrivate"/>
+ <rejection class="QtTsan"/>
+ <rejection class="QTypeTraits"/>
+ <rejection class="qxp"/>
+
+ <rejection class="QChildEvent" field-name="c"/>
+ <rejection class="QTimerEvent" field-name="id"/>
+ <rejection class="QEvent" field-name="t"/>
+ <rejection class="*" function-name="tr"/>
+ <!-- From Qt4.6 -->
+ <rejection class="*" field-name="d_ptr"/>
+ <rejection class="QMetaMethod" enum-name="Attributes"/>
+ <rejection class="QMetaMethod" field-name="data"/>
+ <!-- Note: Default parameter values of Disambiguated_t as defined by
+ QT6_DECL_NEW_OVERLOAD_TAIL are not seen by the clang parser since it
+ is relying on code snippets for the values. -->
+ <rejection class="Qt" field-name="Disambiguated"/>
+ <rejection class="" enum-name="QCborNegativeInteger"/>
+
+ <rejection class="*" argument-type="^qfloat16&amp;?$"/>
+ <rejection class="*" argument-type="QTSMFI"/>
+ <rejection class="*" argument-type="QTSMFC"/>
+ <rejection class="*" argument-type="QtPrivate::QSlotObjectBase*"/>
+ <rejection class="*" argument-type="^Q\w+Private( const)?\&amp;$"/>
+ <!-- Note: "QHelpModel(QHelpEnginePrivate*)" is needed -->
+ <rejection class="*" argument-type="^Q[^H]\w+Private( const)?\*$"/>
+ <rejection class="*" argument-type="Qt::Initialization"/>
+
+ <rejection class="*" argument-type="FILE*"/>
+ <rejection class="*" argument-type="std::chrono::milliseconds"/>
+ <rejection class="*" argument-type="^std::nullptr_t&amp;?$"/>
+ <rejection class="*" argument-type="^std::initializer_list&lt;.*$"/>
+
+ <!-- From Qt4.6 ^^^ -->
+
+ <enum-type name="QtMsgType" doc-file="qtlogging"/>
+ <enum-type name="QCborSimpleType" doc-file="qtcborcommon"/>
+ <enum-type name="QCborKnownTags" doc-file="qtcborcommon"/>
+ <enum-type name="QCborTag" doc-file="qtcborcommon"/>
+
+ <primitive-type name="qint8"/>
+ <primitive-type name="qint16"/>
+ <primitive-type name="qint32"/>
+ <primitive-type name="quint8"/>
+ <primitive-type name="quint16"/>
+ <primitive-type name="quint32"/>
+ <primitive-type name="quint64"/>
+ <primitive-type name="qreal"/>
+ <primitive-type name="qint64"/>
+ <primitive-type name="qlonglong" target-lang-api-name="PyLong"/>
+ <primitive-type name="qulonglong" target-lang-api-name="PyLong"/>
+ <primitive-type name="qsizetype" target-lang-api-name="PyLong"/>
+ <primitive-type name="size_t" target-lang-api-name="PyLong"/>
+ <primitive-type name="ushort" target-lang-api-name="PyLong"/>
+ <primitive-type name="uchar"/>
+ <primitive-type name="uint"/>
+ <primitive-type name="ulong"/>
+ <primitive-type name="int8_t"/>
+ <primitive-type name="uint8_t"/>
+ <primitive-type name="int16_t"/>
+ <primitive-type name="uint16_t"/>
+ <primitive-type name="int32_t"/>
+ <primitive-type name="uint32_t"/>
+ <primitive-type name="int64_t"/>
+ <primitive-type name="uint64_t"/>
+ <primitive-type name="intptr_t"/>
+ <primitive-type name="uintptr_t"/>
+
+ <?if windows darwin?>
+ <primitive-type name="Qt::HANDLE" target-lang-api-name="PyObject"/>
+ <?endif?>
+ <?if linux?>
+ <primitive-type name="Qt::HANDLE" target-lang-api-name="PyLong"/>
+ <?endif?>
+
+ <!-- Qt5: add the new pointer-ish types -->
+ <primitive-type name="qintptr" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pylong"/>
+ <target-to-native>
+ <add-conversion type="PyLong">
+ <insert-template name="shiboken_conversion_pylong_to_cpp"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="quintptr" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pylong-quintptr"/>
+ <target-to-native>
+ <add-conversion type="PyLong" file="../glue/qtcore.cpp" snippet="conversion-pylong-quintptr"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="qptrdiff" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pylong"/>
+ <target-to-native>
+ <add-conversion type="PyLong">
+ <insert-template name="shiboken_conversion_pylong_to_cpp"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="QFunctionPointer" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-qfunctionpointer-pylong"/>
+ <target-to-native>
+ <add-conversion type="PyLong" file="../glue/qtcore.cpp" snippet="conversion-pylong-qfunctionpointer"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="QString" target-lang-api-name="PyUnicode">
+ <include file-name="QString" location="global"/>
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode"/>
+ <target-to-native>
+ <add-conversion type="PyUnicode" file="../glue/qtcore.cpp" snippet="conversion-pyunicode"/>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="QStringView" target-lang-api-name="PyUnicode" view-on="QString">
+ <include file-name="QStringView" location="global"/>
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode"/>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="QLatin1String" target-lang-api-name="PyUnicode">
+ <include file-name="QtCore/qlatin1stringview.h" location="global"/>
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode-from-qlatin1string"/>
+ <target-to-native>
+ <add-conversion type="PyString" check="qLatin1StringCheck(%in)"
+ file="../glue/qtcore.cpp" snippet="conversion-pystring-qlatin1string"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="QAnyStringView" target-lang-api-name="PyUnicode" view-on="QString">
+ <include file-name="QAnyStringView" location="global"/>
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode-from-qanystringview"/>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="QChar">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode-qchar"/>
+ <target-to-native>
+ <add-conversion type="PyString" check="Shiboken::String::checkChar(%in)" file="../glue/qtcore.cpp" snippet="conversion-pystring-char"/>
+ <add-conversion type="PyLong" file="../glue/qtcore.cpp" snippet="conversion-pyint"/>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <primitive-type name="QVariant" target-lang-api-name="PyObject">
+ <extra-includes>
+ <include file-name="optional" location="global"/>
+ </extra-includes>
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-qvariant"/>
+ <target-to-native>
+ <add-conversion type="PyBool" file="../glue/qtcore.cpp" snippet="conversion-pybool"/>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="QString" check="Shiboken::String::check(%in)" file="../glue/qtcore.cpp" snippet="conversion-qstring"/>
+ <add-conversion type="QByteArray" file="../glue/qtcore.cpp" snippet="conversion-qbytearray"/>
+ <add-conversion type="PyFloat" check="PyFloat_CheckExact(%in)" file="../glue/qtcore.cpp" snippet="conversion-pyfloat"/>
+ <add-conversion type="PyLong" check="PyLong_CheckExact(%in)" file="../glue/qtcore.cpp" snippet="conversion-qlonglong"/>
+ <add-conversion type="SbkObject" file="../glue/qtcore.cpp" snippet="conversion-sbkobject"/>
+ <add-conversion type="PyDict" check="PyDict_CheckExact(%in)" file="../glue/qtcore.cpp" snippet="conversion-pydict"/>
+ <add-conversion type="PyList" check="PyList_Check(%in)" file="../glue/qtcore.cpp" snippet="conversion-pylist"/>
+ <add-conversion type="PyObject" file="../glue/qtcore.cpp" snippet="conversion-pyobject"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qvariant-conversion"/>
+ <primitive-type name="QStringList">
+ <include file-name="QStringList" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_cppsequence_to_pylist">
+ <replace from="%INTYPE_0" to="QString"/>
+ </insert-template>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve">
+ <replace from="%OUTTYPE_0" to="QString"/>
+ </insert-template>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <value-type name="QCborError">
+ <enum-type name="Code"/>
+ <include file-name="qcborcommon.h" location="global"/>
+ </value-type>
+
+ <value-type name="QCborParserError">
+ <include file-name="qcborvalue.h" location="global"/>
+ </value-type>
+
+ <value-type name="QCborValue">
+ <enum-type name="EncodingOption" flags="EncodingOptions"/>
+ <enum-type name="DiagnosticNotationOption" flags="DiagnosticNotationOptions"/>
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="QCborArray"/>
+ <value-type name="QCborMap"/>
+
+ <object-type name="QCborStreamReader">
+ <enum-type name="StringResultCode"/>
+ <enum-type name="Type"/>
+ <include file-name="qcborstream.h" location="global"/>
+ <value-type name="StringResult" generate="no"/>
+ <!-- 64bit (qsizetype = long long) -->
+ <modify-function signature="readStringChunk(char*,qsizetype)" remove="all"/>
+ <!-- 32bit (qsizetype = int) -->
+ <modify-function signature="readStringChunk(char*,int)" remove="all"/>
+ </object-type>
+ <typedef-type name="QCborStringResultString" source="QCborStreamReader::StringResult&lt;QString&gt;"/>
+ <typedef-type name="QCborStringResultByteArray" source="QCborStreamReader::StringResult&lt;QByteArray&gt;"/>
+ <object-type name="QCborStreamWriter">
+ <include file-name="qcborstream.h" location="global"/>
+ </object-type>
+
+ <primitive-type name="QJsonObject">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-qjsonobject"/>
+ <target-to-native>
+ <add-conversion type="PyDict" file="../glue/qtcore.cpp" snippet="conversion-qjsonobject-pydict"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <value-type name="QKeyCombination">
+ <!-- The following do-nothing function is needed for coercion of constructs like
+ QKeyCombination(Qt.CTRL | Qt.Key_B)
+ -->
+ <add-function signature="QKeyCombination(QKeyCombination)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="keycombination-from-keycombination"/>
+ </add-function>
+ <!-- This is just a copy of KeyModifier to handle Modifier the same -->
+ <add-function signature="QKeyCombination(Qt::Modifier @modifiers@, Qt::Key @key@)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="keycombination-from-modifier"/>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMetaType">
+ <extra-includes>
+ <include file-name="pysidemetatype.h" location="global"/>
+ </extra-includes>
+ <enum-type name="Type" python-type="IntEnum"/>
+ <enum-type name="TypeFlag" flags="TypeFlags"/>
+ <add-function signature="QMetaType(PyTypeObject*)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="metatype-from-type"/>
+ </add-function>
+ <!-- PYSIDE-1735: The class QMetaType.Type must be allowed because int is gone -->
+ <add-function signature="QMetaType(QMetaType::Type)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="metatype-from-metatype-type"/>
+ </add-function>
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="conversion-qmetatype-pytypeobject"/>
+ <target-to-native>
+ <add-conversion type="PyTypeObject" file="../glue/qtcore.cpp" snippet="conversion-pytypeobject-qmetatype"/>
+ </target-to-native>
+ </conversion-rule>
+ </value-type>
+
+ <value-type name="QNativeIpcKey" since="6.6">
+ <enum-type name="Type"/>
+ </value-type>
+
+ <container-type name="QSet" type="set">
+ <include file-name="QSet" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_cppsequence_to_pyset"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="shiboken_conversion_pyiterable_to_cppsetcontainer"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <!-- FIXME: Which one is it going to be? -->
+ <container-type name="QList" type="list"
+ opaque-containers="int:QIntList;QPoint:QPointList;QPointF:QPointFList">
+ <include file-name="QList" location="global"/>
+ <declare-function signature="append(T)" return-type="void"/>
+ <declare-function signature="insert(qsizetype,T)" return-type="void"/>
+ <declare-function signature="prepend(T)" return-type="void"/>
+ <declare-function signature="push_back(T)" return-type="void"/>
+ <declare-function signature="push_front(T)" return-type="void"/>
+ <declare-function signature="removeAll(T)" return-type="void"/>
+ <declare-function signature="removeOne(T)" return-type="void"/>
+ <!-- operator << needs to be declared in inheriting class -->
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_cppsequence_to_pylist"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <container-type name="QStack" type="stack">
+ <include file-name="QStack" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_cppsequence_to_pylist"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <container-type name="QQueue" type="queue">
+ <include file-name="QQueue" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_cppsequence_to_pylist"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <container-type name="QHash" type="hash">
+ <include file-name="QHash" location="global"/>
+ <!-- Include to make enum flags work. -->
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_qmap_to_pydict"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyDict">
+ <insert-template name="shiboken_conversion_pydict_to_qmap"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <container-type name="QMultiHash" type="multi-hash">
+ <include file-name="QMultiHash" location="global"/>
+ <!-- Include to make enum flags work. -->
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_qmultihash_to_pydict"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyDict">
+ <insert-template name="shiboken_conversion_pydict_to_qmultihash"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <value-type name="QHashSeed" since="6.2"/>
+
+ <container-type name="QMap" type="map">
+ <include file-name="QMap" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_qmap_to_pydict"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyDict">
+ <insert-template name="shiboken_conversion_pydict_to_qmap"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+ <container-type name="QMultiMap" type="multi-map">
+ <include file-name="QMultiMap" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_qmultimap_to_pydict"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyDict">
+ <insert-template name="shiboken_conversion_pydict_to_qmultihash"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <container-type name="QPair" type="pair">
+ <include file-name="QPair" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="shiboken_conversion_cpppair_to_pytuple"/>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="shiboken_conversion_pysequence_to_cpppair"/>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+ <rejection class="*" function-name="d_func"/>
+ <rejection class="*" function-name="data_ptr"/>
+ <rejection class="^(?!QSharedMemory).*$" function-name="detach"/>
+ <rejection class="*" function-name="isDetached"/>
+ <rejection class="*" field-name="d_ptr"/>
+ <rejection class="*" field-name="d"/>
+ <rejection class="*" field-name="staticMetaObject"/>
+ <!-- not support array in property -->
+ <rejection class="QUuid" field-name="data1"/>
+ <rejection class="QUuid" field-name="data2"/>
+ <rejection class="QUuid" field-name="data3"/>
+ <rejection class="QUuid" field-name="data4"/>
+ <!-- Internal -->
+ <rejection class="QCoreApplication" function-name="compressEvent"/>
+
+ <namespace-type name="Qt">
+ <extra-includes>
+ <include file-name="QtCore/QProperty" location="global"/>
+ </extra-includes>
+ <enum-type name="AlignmentFlag" python-type="IntFlag" flags="Alignment"/>
+ <enum-type name="AnchorPoint" since="4.6"/>
+ <enum-type name="ColorScheme" since="6.5"/>
+ <enum-type name="ApplicationAttribute"/>
+ <enum-type name="ApplicationState" flags="ApplicationStates"/>
+ <enum-type name="ArrowType"/>
+ <enum-type name="AspectRatioMode"/>
+ <enum-type name="Axis"/>
+ <enum-type name="BGMode"/>
+ <enum-type name="BrushStyle"/>
+ <enum-type name="CaseSensitivity"/>
+ <enum-type name="ChecksumType"/>
+ <enum-type name="CheckState"/>
+ <enum-type name="ClipOperation"/>
+ <enum-type name="ConnectionType"/>
+ <enum-type name="ContextMenuPolicy"/>
+ <enum-type name="CoordinateSystem" since="4.6"/>
+ <enum-type name="Corner"/>
+ <enum-type name="CursorShape"/>
+ <enum-type name="DateFormat"/>
+ <enum-type name="DayOfWeek"/>
+ <enum-type name="DockWidgetArea" flags="DockWidgetAreas"/>
+ <enum-type name="DockWidgetAreaSizes"/>
+ <enum-type name="DropAction" flags="DropActions"/>
+ <enum-type name="Edge" flags="Edges"/>
+ <enum-type name="EventPriority"/>
+ <enum-type name="FillRule"/>
+ <enum-type name="FindChildOption" flags="FindChildOptions"/>
+ <enum-type name="FocusPolicy" python-type="IntFlag"/>
+ <enum-type name="FocusReason"/>
+ <enum-type name="GestureFlag" flags="GestureFlags" since="4.6"/>
+ <enum-type name="GestureState" since="4.6"/>
+ <enum-type name="GestureType" python-type="IntEnum" since="4.6"/>
+ <enum-type name="GlobalColor"/>
+ <enum-type name="HighDpiScaleFactorRoundingPolicy"/>
+ <enum-type name="HitTestAccuracy"/>
+ <enum-type name="ImageConversionFlag" flags="ImageConversionFlags"/>
+ <enum-type name="InputMethodHint" flags="InputMethodHints" since="4.6"/>
+ <enum-type name="InputMethodQuery" flags="InputMethodQueries"/>
+ <enum-type name="EnterKeyType"/>
+ <enum-type name="ItemDataRole" python-type="IntEnum"/>
+ <enum-type name="ItemFlag" flags="ItemFlags"/>
+ <enum-type name="ItemSelectionMode"/>
+ <enum-type name="ItemSelectionOperation"/>
+ <enum-type name="Key" python-type="IntEnum"/>
+ <enum-type name="KeyboardModifier" flags="KeyboardModifiers"/>
+ <enum-type name="LayoutDirection"/>
+ <enum-type name="MaskMode"/>
+ <enum-type name="MatchFlag" flags="MatchFlags"/>
+ <enum-type name="Modifier" python-type="Flag"/>
+ <enum-type name="MouseButton" flags="MouseButtons"/>
+ <enum-type name="MouseEventFlag" flags="MouseEventFlags"/>
+ <enum-type name="MouseEventSource"/>
+ <enum-type name="NativeGestureType"/>
+ <enum-type name="NavigationMode" since="4.6"/>
+ <enum-type name="Orientation" flags="Orientations"/>
+ <enum-type name="PenCapStyle"/>
+ <enum-type name="PenJoinStyle"/>
+ <enum-type name="PenStyle"/>
+ <enum-type name="PermissionStatus" since="6.5"/>
+ <enum-type name="ReturnByValueConstant"/>
+ <enum-type name="ScreenOrientation" flags="ScreenOrientations"/>
+ <enum-type name="ScrollBarPolicy"/>
+ <enum-type name="ScrollPhase"/>
+ <enum-type name="ShortcutContext"/>
+ <enum-type name="SizeHint"/>
+ <enum-type name="SizeMode"/>
+ <enum-type name="SortOrder"/>
+ <enum-type name="SplitBehaviorFlags" flags="SplitBehavior"/>
+ <enum-type name="TabFocusBehavior"/>
+ <enum-type name="TextElideMode"/>
+ <enum-type name="TextFlag" python-type="IntFlag"/>
+ <enum-type name="TextFormat"/>
+ <enum-type name="TextInteractionFlag" flags="TextInteractionFlags"/>
+ <enum-type name="TileRule" since="4.6"/>
+ <enum-type name="TimerType"/>
+ <enum-type name="TimeSpec"/>
+ <enum-type name="ToolBarArea" flags="ToolBarAreas"/>
+ <enum-type name="ToolBarAreaSizes"/>
+ <enum-type name="ToolButtonStyle"/>
+ <enum-type name="TouchPointState" flags="TouchPointStates" since="4.6"/>
+ <enum-type name="TransformationMode"/>
+ <enum-type name="UIEffect"/>
+ <enum-type name="WhiteSpaceMode"/>
+ <enum-type name="WidgetAttribute"/>
+ <enum-type name="WindowFrameSection"/>
+ <enum-type name="WindowModality"/>
+ <enum-type name="WindowState" flags="WindowStates"/>
+ <enum-type name="WindowType" python-type="IntFlag" flags="WindowFlags"/>
+ <enum-type name="CursorMoveStyle" since="4.8" revision="4800"/>
+
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp"
+ snippet="qt-modifier"/>
+ </namespace-type>
+
+ <add-function signature="QEnum(PyObject*)" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qenum"/>
+ </add-function>
+ <add-function signature="QFlag(PyObject*)" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qflag"/>
+ </add-function>
+
+ <add-function signature="__init_feature__()">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-init-feature"/>
+ </add-function>
+
+ <add-function signature="qAbs(double)" return-type="double">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qabs"/>
+ </add-function>
+
+ <add-function signature="qAddPostRoutine(PyObject*)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-addpostroutine"/>
+ </add-function>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-qaddpostroutine"/>
+
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-version"/>
+
+ <!-- WARNING: There is an issue when adding this code to an external file -->
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-module-shutdown"/>
+ <add-function signature="__moduleShutdown()">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="moduleshutdown"/>
+ </add-function>
+
+ <!--signal/slot-->
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-pysideinit"/>
+
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qt-messagehandler"/>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qlatin1string-check"/>
+ <add-function signature="qInstallMessageHandler(PyObject)" return-type="PyObject">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-installmessagehandler"/>
+ </add-function>
+
+ <value-type name="QDeadlineTimer">
+ <enum-type name="ForeverConstant"/>
+ </value-type>
+
+ <value-type name="QElapsedTimer" since="4.7">
+ <enum-type name="ClockType" since="4.7"/>
+ </value-type>
+
+ <object-type name="QAbstractTableModel"
+ polymorphic-id-expression="qobject_cast&lt;QAbstractTableModel*&gt;(%B)">
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ </object-type>
+ <value-type name="QLine" hash-function="PySide::hash">
+ <extra-includes>
+ <include file-name="pysideqhash.h" location="global"/>
+ </extra-includes>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qline-hash"/>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="iiii"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+ <value-type name="QLineF">
+ <enum-type name="IntersectionType"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="dddd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <modify-function signature="intersects(const QLineF &amp;,QPointF*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtCore.QLineF.IntersectionType, PySide6.QtCore.QPointF]">
+ <replace-type modified-type="(intersectType, intersectionPoint)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qlinef-intersect"/>
+ </modify-function>
+ </value-type>
+ <object-type name="QResource">
+ <enum-type name="Compression"/>
+ <modify-function signature="data()const">
+ <inject-documentation format="target">
+ Returns a read only buffer object pointing to the segment of data that this resource represents. If the resource is compressed the data returns is compressed and qUncompress() must be used to access the data. If the resource is a directory None is returned.
+ </inject-documentation>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qresource-data"/>
+ </modify-function>
+
+ <modify-function signature="unregisterResource(const uchar*,const QString&amp;)" rename="unregisterResourceData">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qresource-registerResource"/>
+ </modify-function>
+ <modify-function signature="registerResource(const uchar*,const QString&amp;)" rename="registerResourceData">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qresource-registerResource"/>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QBasicTimer"/>
+ <value-type name="QByteArrayMatcher"/>
+ <value-type name="QCalendar">
+ <object-type name="SystemId"/> <!-- not default-constructible -->
+ <value-type name="YearMonthDay"/>
+ <enum-type name="System"/>
+ <enum-type identified-by-value="Unspecified"/>
+ </value-type>
+ <value-type name="QDate">
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="core-snippets-p-h"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyDate" check="PyDate_ImportAndCheck(%in)"
+ file="../glue/qtcore.cpp" snippet="conversion-qdate-pydate"/>
+ </target-to-native>
+ </conversion-rule>
+ <extra-includes>
+ <include file-name="datetime.h" location="global"/>
+ </extra-includes>
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="iii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="toPython()" return-type="PyObject">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdate-topython"/>
+ </add-function>
+ <modify-function signature="getDate(int*,int*,int*)const" >
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, int, int]">
+ <replace-type modified-type="(year, month, day)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdate-getdate"/>
+ </modify-function>
+ <modify-function signature="weekNumber(int*)const" >
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, int]">
+ <replace-type modified-type="(week, yearNumber)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdate-weeknumber"/>
+ </modify-function>
+ </value-type>
+ <value-type name="QDateTime">
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="core-snippets-p-h"/>
+ <enum-type name="YearRange"/>
+ <enum-type name="TransitionResolution" since="6.7"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyDateTime" check="PyDateTime_ImportAndCheck(%in)"
+ file="../glue/qtcore.cpp" snippet="conversion-qdatetime-pydatetime"/>
+ </target-to-native>
+ </conversion-rule>
+ <extra-includes>
+ <include file-name="datetime.h" location="global"/>
+ </extra-includes>
+ <!-- Somewhat internal constructor used to pickle QDateTime -->
+ <add-function signature="QDateTime(int,int,int,int,int,int,int,int=Qt::LocalTime)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-1"/>
+ </add-function>
+ <add-function signature="QDateTime(int,int,int,int,int,int)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-2"/>
+ </add-function>
+ <!-- PYSIDE-1735: Qt::TimeSpec is no more compatible with int -->
+ <add-function signature="QDateTime(int,int,int,int,int,int,int,Qt::TimeSpec=Qt::LocalTime)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-3"/>
+ </add-function>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i, %i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.date().year(), %CPPSELF.date().month(), %CPPSELF.date().day(), %CPPSELF.time().hour(), %CPPSELF.time().minute(), %CPPSELF.time().second(), %CPPSELF.time().msec(), (int)%CPPSELF.timeSpec()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="iiiiiiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.date().year(), %CPPSELF.date().month(), %CPPSELF.date().day(), %CPPSELF.time().hour(), %CPPSELF.time().minute(), %CPPSELF.time().second(), %CPPSELF.time().msec(), (int)%CPPSELF.timeSpec()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="toPython()" return-type="PyObject">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-topython"/>
+ </add-function>
+ </value-type>
+
+ <value-type name="QDir">
+ <enum-type name="Filter" flags="Filters"/>
+ <enum-type name="SortFlag" flags="SortFlags"/>
+
+ <!-- PYSIDE-1499: Replace QString by pathlib.Path (qdir.h) -->
+ <modify-function signature="QDir(const QString &amp;)">
+ <modify-argument index="1" pyi-type="Optional[PyPathLike]">
+ <replace-type modified-type="PyPathLike"/>
+ <rename to="path"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="QDir(const QString &amp;,const QString &amp;,QFlags&lt;QDir::SortFlag&gt;,QFlags&lt;QDir::Filter&gt;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="setPath(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="addSearchPath(const QString &amp;,const QString &amp;)">
+ <modify-argument index="2"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-2"/>
+ </modify-function>
+ <!-- PYSIDE-1499: End of insertion -->
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.path())"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QPermission" since="6.5">
+ <configuration condition="QT_CONFIG(permissions)"/>
+ </value-type>
+ <value-type name="QBluetoothPermission" since="6.5">
+ <configuration condition="QT_CONFIG(permissions)"/>
+ <enum-type name="CommunicationMode" flags="CommunicationModes" since="6.6"/>
+ </value-type>
+ <value-type name="QCalendarPermission" since="6.5">
+ <configuration condition="QT_CONFIG(permissions)"/>
+ <enum-type name="AccessMode"/>
+ </value-type>
+ <value-type name="QCameraPermission" since="6.5">
+ <configuration condition="QT_CONFIG(permissions)"/>
+ </value-type>
+ <value-type name="QContactsPermission" since="6.5">
+ <configuration condition="QT_CONFIG(permissions)"/>
+ <enum-type name="AccessMode"/>
+ </value-type>
+ <value-type name="QLocationPermission" since="6.5">
+ <configuration condition="QT_CONFIG(permissions)"/>
+ <enum-type name="Accuracy"/>
+ <enum-type name="Availability"/>
+ </value-type>
+ <value-type name="QMicrophonePermission" since="6.5">
+ <configuration condition="QT_CONFIG(permissions)"/>
+ </value-type>
+
+ <value-type name="QPoint">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="ii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="ii"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!--### Functions removed because they return references to Python imutable objects -->
+ <modify-function signature="rx()" remove="all"/>
+ <modify-function signature="ry()" remove="all"/>
+ <!--### -->
+ </value-type>
+ <value-type name="QPointF">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="dd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="dd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!--### Functions removed because they return references to Python imutable objects -->
+ <modify-function signature="rx()" remove="all"/>
+ <modify-function signature="ry()" remove="all"/>
+ <!--### -->
+ </value-type>
+ <value-type name="QRect">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <modify-function signature="getCoords(int*,int*,int*,int*)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getRect(int*,int*,int*,int*)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ </value-type>
+ <value-type name="QRectF">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!--
+ FIXME These functions return qreal. Will convert to double (format
+ string) mess things up in other architectures?
+ -->
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <modify-function signature="getCoords(qreal*,qreal*,qreal*,qreal*)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getRect(qreal*,qreal*,qreal*,qreal*)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ </value-type>
+ <value-type name="QSize">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="ii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="ii"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!--### Functions removed because they return references to Python imutable objects -->
+ <modify-function signature="rheight()" remove="all"/>
+ <modify-function signature="rwidth()" remove="all"/>
+ <!--### -->
+ </value-type>
+ <value-type name="QSizeF">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="dd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="dd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!--### Functions removed because they return references to Python imutable objects -->
+ <modify-function signature="rheight()" remove="all"/>
+ <modify-function signature="rwidth()" remove="all"/>
+ <!--### -->
+ </value-type>
+
+ <value-type name="QTime">
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="core-snippets-p-h"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyTime" check="PyTime_ImportAndCheck(%in)"
+ file="../glue/qtcore.cpp" snippet="conversion-qtime-pytime"/>
+ </target-to-native>
+ </conversion-rule>
+
+ <extra-includes>
+ <include file-name="datetime.h" location="global"/>
+ </extra-includes>
+
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="toPython()" return-type="PyObject">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qtime-topython"/>
+ </add-function>
+ </value-type>
+ <value-type name="QPersistentModelIndex">
+ <extra-includes>
+ <include file-name="QtCore/QList" location="global"/>
+ </extra-includes>
+ <!-- For signal QAbstractItemModel::layoutAboutToBeChanged(QList<QPersistentModelIndex>) -->
+ <inject-code class="target" position="end">
+ qRegisterMetaType&lt;QList&lt;QPersistentModelIndex&gt; &gt;("QList_QPersistentModelIndex");
+ </inject-code>
+ <modify-function signature="internalPointer()const">
+ <modify-argument index="return" pyi-type="Any"/>
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_internal_pointer" />
+ </inject-code>
+ </modify-function>
+ <modify-function signature="operator QModelIndex()const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="QTimeZone">
+ <configuration condition="QT_CONFIG(timezone)"/>
+ <enum-type name="Initialization" since="6.5"/>
+ <enum-type name="TimeType"/>
+ <enum-type name="NameType"/>
+ <value-type name="OffsetData">
+ <configuration condition="QT_CONFIG(timezone)"/>
+ </value-type>
+ </value-type>
+
+ <value-type name="QUuid">
+ <enum-type name="StringFormat"/>
+ <enum-type name="Variant"/>
+ <enum-type name="Version"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="'%s'"/>
+ <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.toString())"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.toString())"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMimeType"/>
+ <object-type name="QMimeDatabase">
+ <enum-type name="MatchMode"/>
+ </object-type>
+
+ <value-type name="QLocale">
+ <enum-type name="TagSeparator" since="6.7"/>
+ <enum-type name="Country"/>
+ <enum-type name="DataSizeFormat" flags="DataSizeFormats"/>
+ <enum-type name="FloatingPointPrecisionOption" python-type="IntEnum"/>
+ <enum-type name="FormatType"/>
+ <enum-type name="Language"/>
+ <enum-type name="LanguageCodeType" python-type="IntFlag" flags="LanguageCodeTypes" since="6.3"/>
+ <enum-type name="MeasurementSystem"/>
+ <enum-type name="NumberOption" flags="NumberOptions"/>
+ <enum-type name="Script" since="4.8" revision="4800"/>
+ <enum-type name="CurrencySymbolFormat" since="4.8" revision="4800"/>
+ <enum-type name="QuotationStyle" since="4.8" revision="4800"/>
+ <!--### All those C++ number types have the same representation in Python -->
+ <modify-function signature="toString(qulonglong)const" remove="all"/>
+ <modify-function signature="toString(ushort)const" remove="all"/>
+ <modify-function signature="toString(unsigned int)const" remove="all"/>
+ <modify-function signature="system()" remove="all"/>
+ <!--### -->
+ <extra-includes>
+ <include file-name="QDate" location="global"/>
+ </extra-includes>
+ <add-function signature="system()" return-type="QLocale" static="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qlocale_system"/>
+ <inject-documentation mode="append" format="target">
+ Returns a QLocale object initialized to the system locale.
+
+ The system locale may use system-specific sources for locale data, where available,
+ otherwise falling back on QLocale's built-in database entry for the language, script and
+ territory the system reports.
+
+ For example, on Windows, this locale will use the decimal/grouping characters and
+ date/time formats specified in the system configuration panel.
+
+ .. note:: Qt for Python on macOS will not reflect the user's region and language
+ preferences though QLocale::system(), but will instead reflect the environment
+ variables POSIX uses to specify locale, similar to Python's locale module. If the
+ system locale cannot be determined, which can be due to none of the variables 'LC_ALL',
+ 'LC_CTYPE', 'LANG' or 'LANGUAGE' being set by your environment, then the default POSIX
+ locale or 'C' locale is returned.
+
+ See also c().
+ </inject-documentation>
+ </add-function>
+ <modify-function signature="toTime(QString,QLocale::FormatType)const">
+ <modify-argument index="2">
+ <rename to="format"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="toDate(QString,QLocale::FormatType,int)const">
+ <modify-argument index="2">
+ <rename to="format"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="^toDate(Time)?\(QString,[^,]+,int\)const$">
+ <modify-argument index="3">
+ <replace-default-expression with="1900"/> <!-- private FirstTwoDigitYear -->
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="^toDate(Time)?\(QString,[^,]+,QCalendar,int\)const$">
+ <modify-argument index="4">
+ <replace-default-expression with="1900"/> <!-- private FirstTwoDigitYear -->
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="toUInt(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="(int, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toULongLong(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="(int, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toDouble(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[float, bool]">
+ <replace-type modified-type="(float, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toFloat(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[float, bool]">
+ <replace-type modified-type="(float, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toInt(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="(int, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toLongLong(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="(int, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toLong(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="(int, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toShort(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="(int, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toUShort(QString,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[int, bool]">
+ <replace-type modified-type="(int, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <!-- PYSIDE-2133, 2168 remove unsigned overloads of to(Currency)?String() to
+ ensure float overloads are used -->
+ <modify-function signature="^to(Currency)?String\(q?u.*$" remove="all"/>
+ <modify-function signature="^to(Currency)?String\(.*short.*$" remove="all"/>
+ <modify-function signature="^to.*\(.*QStringView.*$" remove="all"/>
+ </value-type>
+ <value-type name="QBitArray">
+ <add-function signature="__len__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbitarray-len"/>
+ </add-function>
+ <add-function signature="__getitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbitarray-getitem"/>
+ </add-function>
+ <add-function signature="__setitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbitarray-setitem"/>
+ </add-function>
+ </value-type>
+ <object-type name="QLockFile">
+ <enum-type name="LockError"/>
+ <modify-function signature="isLocked()const" allow-thread="yes"/>
+ <modify-function signature="lock()" allow-thread="yes"/>
+ <modify-function signature="removeStaleLockFile()" allow-thread="yes"/>
+ <modify-function signature="tryLock(int)" allow-thread="yes"/>
+ <modify-function signature="unlock()" allow-thread="yes"/>
+ <modify-function signature="getLockInfo(qint64*,QString*,QString*)const">
+ <modify-argument index="return" pyi-type="Tuple[int, str, str]">
+ <replace-type modified-type="(int, str, str)"/>
+ </modify-argument>
+ <modify-argument index="1"><remove-argument/></modify-argument>
+ <modify-argument index="2"><remove-argument/></modify-argument>
+ <modify-argument index="3"><remove-argument/></modify-argument>
+ <inject-code class="target" position="beginning"
+ file="../glue/qtcore.cpp" snippet="qlockfile-getlockinfo"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QMessageAuthenticationCode"/>
+ <object-type name="QSignalBlocker">
+ <add-function signature="__enter__()" return-type="QSignalBlocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
+ <add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qsignalblocker-unblock"/>
+ </add-function>
+ </object-type>
+ <value-type name="QStorageInfo"/>
+ <!-- QReadWriteLock does not have a copy ctor! -->
+ <object-type name="QReadWriteLock">
+ <enum-type name="RecursionMode"/>
+ <modify-function signature="lockForRead()" allow-thread="yes"/>
+ <modify-function signature="tryLockForRead(int)" allow-thread="yes"/>
+ <modify-function signature="lockForWrite()" allow-thread="yes"/>
+ <modify-function signature="tryLockForWrite(int)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QReadLocker">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="QReadLocker(QReadWriteLock*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="relock()" allow-thread="yes"/>
+ <add-function signature="__enter__()" return-type="QReadLocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
+ <add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
+ </add-function>
+ </object-type>
+ <object-type name="QWriteLocker">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="QWriteLocker(QReadWriteLock*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="relock()" allow-thread="yes"/>
+ <add-function signature="__enter__()" return-type="QWriteLocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
+ <add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
+ </add-function>
+ </object-type>
+ <object-type name="QDirIterator">
+ <enum-type name="IteratorFlag" flags="IteratorFlags"/>
+ </object-type>
+ <object-type name="QThread">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <inject-code file="../glue/qtcore.cpp" class="native" position="beginning" snippet="qthread_pthread_cleanup"/>
+ <enum-type name="Priority"/>
+ <modify-function signature="currentThreadId()" remove="all"/>
+ <modify-function signature="run()" allow-thread="yes">
+ <inject-code file="../glue/qtcore.cpp" class="native" position="beginning"
+ snippet="qthread_pthread_cleanup_install"/>
+ <inject-code file="../glue/qtcore.cpp" class="native" position="end"
+ snippet="qthread_pthread_cleanup_uninstall"/>
+ </modify-function>
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="int">
+ <inject-code file="../glue/qtcore.cpp" snippet="qthread_exec_"/>
+ </add-function>
+ <modify-function signature="msleep(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="sleep(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="usleep(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="wait(QDeadlineTimer)" allow-thread="yes"/>
+ <modify-function signature="wait(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="yieldCurrentThread()" allow-thread="yes"/>
+ <modify-function signature="start(QThread::Priority)" allow-thread="yes">
+ <modify-argument index="1">
+ <rename to="priority"/>
+ </modify-argument>
+ <!-- PYSIDE-535: PyPy 7.3.8 needs this call, which is actually a no-op in Python 3.10 -->
+ <inject-code file="../glue/qtcore.cpp" class="target" position="beginning"
+ snippet="qthread_init_pypy"/>
+ </modify-function>
+ <modify-function signature="exit(int)" allow-thread="yes"/>
+ </object-type>
+
+ <value-type name="QModelRoleData"/>
+
+ <object-type name="QAbstractItemModel">
+ <enum-type name="CheckIndexOption" flags="CheckIndexOptions"/>
+ <enum-type name="LayoutChangeHint"/>
+ <!-- This function was replaced by a added function -->
+ <modify-function signature="createIndex(int,int,const void*)const" remove="all"/>
+ <!-- This function is the same as createIndex(int, int, int)const -->
+ <modify-function signature="createIndex(int,int,quintptr)const">
+ <modify-argument index="3">
+ <replace-default-expression with="0"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="createIndex(int@row@,int@column@,PyObject*@ptr@)const" return-type="QModelIndex">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qabstractitemmodel-createindex"/>
+ <inject-documentation mode="append" format="target">
+ Creates a model index for the given row and column with the internal pointer ptr.
+ When using a QSortFilterProxyModel, its indexes have their own internal pointer.
+ It is not advisable to access this internal pointer outside of the model.
+ Use the data() function instead.
+ This function provides a consistent interface that model subclasses must use to create model indexes.
+
+ .. warning:: Because of some Qt/Python itegration rules, the ptr argument do not get the reference
+ incremented during the QModelIndex life time. So it is necessary to keep the object used
+ on ptr argument alive during the whole process.
+ Do not destroy the object if you are not sure about that.
+ </inject-documentation>
+ </add-function>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qabstractitemmodel"/>
+ <modify-function signature="mimeData(QList&lt;QModelIndex&gt;)const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="data(const QModelIndex&amp;,int)const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="dataChanged(const QModelIndex&amp;,const QModelIndex&amp;,const QVector&lt;int&gt;&amp;)" allow-thread="yes"/>
+ <modify-function signature="layoutAboutToBeChanged(const QList&lt;QPersistentModelIndex&gt;&amp;,QAbstractItemModel::LayoutChangeHint)" allow-thread="yes"/>
+ <modify-function signature="layoutChanged(const QList&lt;QPersistentModelIndex&gt;&amp;,QAbstractItemModel::LayoutChangeHint)" allow-thread="yes"/>
+ <modify-function signature="beginResetModel()" allow-thread="yes"/>
+ <modify-function signature="endResetModel()" allow-thread="yes"/>
+ </object-type>
+
+ <value-type name="QItemSelection">
+ <include file-name="QList" location="global"/>
+ <!-- Expose operator==, != inherited from QList, which the parser does
+ not see due to the TMP expression of the return type. -->
+ <add-function signature="operator==(const QItemSelection&amp;)" return-type="bool"/>
+ <add-function signature="operator!=(const QItemSelection&amp;)" return-type="bool"/>
+ <!-- For some reason, the empty selection is not seen. Maybe related to the new [default]
+ tag in Qt6?
+ PYSIDE-2756: The return-type attribute is unnecessary -->
+ <declare-function signature="QItemSelection()"/>
+ <!-- The __add__ function creates a result list, instead of using the inherited type.
+ Fixed by adding with the correct type. -->
+ <add-function signature="operator+(QItemSelection)" return-type="QItemSelection">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qitemselection-add"/>
+ </add-function>
+ </value-type>
+
+ <object-type name="QItemSelectionModel">
+ <extra-includes>
+ <include file-name="QItemSelection" location="global"/>
+ </extra-includes>
+ <enum-type name="SelectionFlag" flags="SelectionFlags"/>
+ </object-type>
+
+ <value-type name="QItemSelectionRange">
+ </value-type>
+ <object-type name="QAbstractProxyModel"
+ polymorphic-id-expression="qobject_cast&lt;QAbstractProxyModel*&gt;(%B)">
+ <extra-includes>
+ <include file-name="QItemSelection" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QConcatenateTablesProxyModel"/>
+ <object-type name="QSortFilterProxyModel">
+ <extra-includes>
+ <include file-name="QItemSelection" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <modify-function signature="setSourceModel(QAbstractItemModel*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QIdentityProxyModel"/>
+ <object-type name="QTransposeProxyModel"/>
+ <!-- QObject is created manually -->
+ <object-type name="QObject" parent-management="true">
+ <extra-includes>
+ <include file-name="QThread" location="global"/>
+ <include file-name="QCoreApplication" location="global"/>
+ <include file-name="signalmanager.h" location="local"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="core-snippets-p-h"/>
+ <modify-function signature="metaObject()const">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-metaobject"/>
+ <modify-argument index="return">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <!-- FIXME PYSIDE 7: Remove this (QT6_DECL_NEW_OVERLOAD_TAIL) -->
+ <modify-function signature="^moveToThread\(.*\)" remove="all"/>
+ <declare-function signature="moveToThread(QThread*)" return-type="bool"/>
+ <modify-function signature="deleteLater()">
+ <modify-argument index="this">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <!-- Invalidate-after-use stuff -->
+ <modify-function signature="childEvent(QChildEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="customEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="event(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="eventFilter(QObject*,QEvent*)">
+ <modify-argument index="2" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="timerEvent(QTimerEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <!-- End of Invalidate-after-use fix -->
+ <modify-function signature="parent()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setParent(QObject*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ <modify-argument index="1" pyi-type="Optional[PySide6.QtCore.QObject]"/>
+ </modify-function>
+ <!-- Manual overload order fixes PYSIDE-2627
+
+ The addition of the qobject-connect-4-context overload resulted in an
+ automatic overload ordering that prevented the right overload from
+ ever being called if the callable was a QObject. Set a manual order to
+ fix this. -->
+ <modify-function signature="connect(const QObject*,const char*,const char*,Qt::ConnectionType)const"
+ overload-number="0">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-1"/>
+ </modify-function>
+ <!-- static version -->
+ <modify-function signature="connect(const QObject*,QMetaMethod,const QObject*,QMetaMethod,Qt::ConnectionType)"
+ overload-number="1">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-2"/>
+ </modify-function>
+ <modify-function signature="connect(const QObject*,const char*,const QObject*,const char*,Qt::ConnectionType)"
+ overload-number="2">
+ <modify-argument index="5">
+ <rename to="type"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-3"/>
+ </modify-function>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect"/>
+ <add-function signature="connect(const QObject*@sender@,const char*@signal@,PyCallable*@functor@,Qt::ConnectionType@type@=Qt::AutoConnection)"
+ return-type="QMetaObject::Connection" static="yes" overload-number="3">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-4"/>
+ </add-function>
+ <add-function signature="connect(const QObject*@sender@,const char*@signal@,const QObject*@context@,PyCallable*@functor@,Qt::ConnectionType@type@=Qt::AutoConnection)"
+ return-type="QMetaObject::Connection" static="yes" overload-number="4">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-4-context"/>
+ </add-function>
+ <!-- static version -->
+ <add-function signature="connect(const char*@signal@,PyCallable*@functor@,Qt::ConnectionType@type@=Qt::AutoConnection)"
+ return-type="QMetaObject::Connection" overload-number="5">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-5"/>
+ </add-function>
+ <add-function signature="connect(const char*@signal@,const QObject*@receiver@,const char*@method@,Qt::ConnectionType@type@=Qt::AutoConnection)"
+ return-type="QMetaObject::Connection" overload-number="6">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-6"/>
+ </add-function>
+
+ <add-function signature="emit(const char*,...)" return-type="bool">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-emit"/>
+ </add-function>
+ <add-function signature="disconnect(const char*@signal@,PyCallable*@functor@)" return-type="bool">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-disconnect-1"/>
+ </add-function>
+ <add-function signature="disconnect(const QObject*@sender@,const char*@signal@,PyCallable*@functor@)" return-type="bool" static="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-disconnect-2"/>
+ </add-function>
+ <modify-function signature="disconnect(QMetaObject::Connection)">
+ <modify-argument index="1">
+ <rename to="connection"/>
+ </modify-argument>
+ </modify-function>
+
+
+ <add-function signature="findChild(PyTypeObject*@type@,const QString&amp;@name@={},Qt::FindChildOptions@options@=Qt::FindChildrenRecursively)"
+ return-type="PyObject*">
+ <inject-documentation format="target" mode="append">
+ To find the child of a certain QObject, the first argument of this function should be the child's type, and the second the name of the child:
+
+ ::
+
+ ...
+ parent = QWidget()
+ ...
+ # The first argument must be the child type
+ child1 = parent.findChild(QPushButton, "child_button")
+ child2 = parent.findChild(QWidget, "child_widget")
+
+ </inject-documentation>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchild-2"/>
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </add-function>
+ <add-function signature="findChildren(PyTypeObject*@type@,const QString&amp;@name@={},Qt::FindChildOptions@options@=Qt::FindChildrenRecursively)"
+ return-type="PySequence*" >
+ <inject-documentation format="target" mode="append">
+ Like the method *findChild*, the first parameter should be the child's type.
+ </inject-documentation>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchildren"/>
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </add-function>
+ <add-function signature="findChildren(PyTypeObject*@type@,const QRegularExpression&amp;@pattern@,Qt::FindChildOptions@options@=Qt::FindChildrenRecursively)"
+ return-type="PySequence*" >
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchildren"/>
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </add-function>
+
+ <add-function signature="tr(const char *@sourceText@, const char *@disambiguation@=nullptr, int @n@=-1)" return-type="QString" classmethod="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-tr"/>
+ <modify-argument index="1" pyi-type="str"/>
+ <modify-argument index="2" pyi-type="Optional[str]">
+ </modify-argument>
+ </add-function>
+
+ <modify-function signature="destroyed(QObject*)" allow-thread="yes">
+ <modify-argument index="1">
+ <rename to="object"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="sender()const" allow-thread="yes">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-sender"/>
+ </modify-function>
+
+ <!-- This is not supported due the lack of information durring the call with no arguments, this can cause a memory leak -->
+ <modify-function signature="disconnect(const char*,const QObject*,const char*)const">
+ <modify-argument index="1">
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-default-expression />
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstractListModel"
+ polymorphic-id-expression="qobject_cast&lt;QAbstractListModel*&gt;(%B)">
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ </object-type>
+ <value-type name="QUrlQuery"/>
+
+ <value-type name="QUrl">
+ <!-- Qt5: lots of changes -->
+ <enum-type name="ComponentFormattingOption" python-type="IntFlag" flags="ComponentFormattingOptions,FormattingOptions"/>
+ <!-- note: above duplication of attribute is not by default XML compliant! -->
+ <enum-type name="UrlFormattingOption" python-type="IntFlag"/>
+ <enum-type name="UserInputResolutionOption" flags="UserInputResolutionOptions"/>
+ <enum-type name="ParsingMode"/>
+ <enum-type name="AceProcessingOption" flags="AceProcessingOptions" since="6.3"/>
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ </extra-includes>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="'%s'"/>
+ <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.toString())"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.toString())"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <modify-function signature="fromLocalFile(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ </value-type>
+
+ <value-type name="QRegularExpression">
+ <enum-type name="WildcardConversionOption" flags="WildcardConversionOptions"/>
+ <enum-type name="MatchOption" flags="MatchOptions"/>
+ <enum-type name="MatchType"/>
+ <enum-type name="PatternOption" flags="PatternOptions"/>
+ </value-type>
+ <value-type name="QRegularExpressionMatch"/>
+ <value-type name="QRegularExpressionMatchIterator"/>
+
+ <value-type name="QFileInfo">
+ <extra-includes>
+ <include file-name="QDateTime" location="global"/>
+ <include file-name="QDir" location="global"/>
+ </extra-includes>
+
+ <!-- PYSIDE-1499: Replace QString by pathlib.Path (qfileinfo.h) -->
+ <modify-function signature="QFileInfo(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="QFileInfo(const QDir &amp;,const QString &amp;)">
+ <modify-argument index="2"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-2"/>
+ </modify-function>
+ <modify-function signature="setFile(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <!-- PYSIDE-1499: End of insertion -->
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.filePath())"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <!-- PYSIDE-1913: Disable isNull() for bool cast; __len__ should be used
+ instead so that b"" yields False. -->
+ <value-type name="QByteArray" isNull="false">
+ <enum-type name="Base64Option" flags="Base64Options"/>
+ <enum-type name="Base64DecodingStatus"/>
+ <value-type name="FromBase64Result"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyBytes" file="../glue/qtcore.cpp" snippet="conversion-qbytearray-pybytes"/>
+ <add-conversion type="PyByteArray" file="../glue/qtcore.cpp" snippet="conversion-qbytearray-pybytearray"/>
+ <add-conversion type="PyString" check="Shiboken::String::check(%in) &amp;&amp; !PyUnicode_Check(%in)" file="../glue/qtcore.cpp" snippet="conversion-qbytearray-pystring"/>
+ </target-to-native>
+ </conversion-rule>
+
+ <extra-includes>
+ <!-- qt5: this is a pre-defined macro <include file-name="QNoImplicitBoolCast" location="global"/> -->
+ </extra-includes>
+
+ <!-- ### These overloads must be removed accept strings with \x00 in their contents -->
+ <modify-function signature="append(const char*)" remove="all"/>
+ <modify-function signature="prepend(const char*)" remove="all"/>
+ <modify-function signature="operator==(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator==(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator>(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator>=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>=(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator&lt;(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;=(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator!=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator!=(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator+=(const char*)" remove="all"/>
+ <modify-function signature="operator+(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator+(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator+(QByteArray,const char*)" remove="all"/>
+ <add-function signature="operator+(PyBytes,QByteArray)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplus-1"/>
+ </add-function>
+ <add-function signature="operator+(PyByteArray, QByteArray)" return-type="QByteArray">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplus-2"/>
+ </add-function>
+ <add-function signature="operator+(PyByteArray)" return-type="QByteArray">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplus-3"/>
+ </add-function>
+ <add-function signature="operator+=(PyByteArray)" return-type="QByteArray">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplusequal"/>
+ </add-function>
+ <add-function signature="operator==(PyUnicode)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorequalequal"/>
+ </add-function>
+ <add-function signature="operator!=(PyUnicode)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatornotequal"/>
+ </add-function>
+ <add-function signature="operator&gt;(PyUnicode)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorgreater"/>
+ </add-function>
+ <add-function signature="operator&gt;=(PyUnicode)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorgreaterequal"/>
+ </add-function>
+ <add-function signature="operator&lt;(PyUnicode)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorlower"/>
+ </add-function>
+ <add-function signature="operator&lt;=(PyUnicode)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorlowerequal"/>
+ </add-function>
+ <!-- ### -->
+
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-repr"/>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="N"/>
+ <replace from="%REDUCE_ARGS" to="PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size())"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QByteArray(PyByteArray)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-2"/>
+ </add-function>
+ <add-function signature="QByteArray(PyBytes)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-3"/>
+ </add-function>
+ <!-- buffer protocol -->
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-bufferprotocol"/>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qbytearray-py3"/>
+
+ <modify-function signature="data()">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-data"/>
+ </modify-function>
+
+ <!-- removed functions -->
+ <!--### Functions removed because they return STL-like iterators -->
+ <modify-function signature="begin()" remove="all"/>
+ <modify-function signature="begin()const" remove="all"/>
+ <modify-function signature="constBegin()const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <modify-function signature="constEnd()const" remove="all"/>
+ <modify-function signature="end()" remove="all"/>
+ <modify-function signature="end()const" remove="all"/>
+ <!--### -->
+
+ <!--### Functions removed because they provide useless overloads from Python point of view -->
+ <modify-function signature="number(uint,int)" remove="all"/>
+ <modify-function signature="number(qulonglong,int)" remove="all"/>
+ <modify-function signature="operator+=(const char*)" remove="all"/>
+ <modify-function signature="operator+(char,QByteArray)" remove="all"/>
+ <modify-function signature="operator==(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator!=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>=(const char*,QByteArray)" remove="all"/>
+ <!-- Those types have the same representation in Python, an overload
+ would be useless and cause overflow errors. -->
+ <modify-function signature="setNum(uint,int)" remove="all"/>
+ <modify-function signature="setNum(ushort,int)" remove="all"/>
+ <modify-function signature="setNum(float,char,int)" remove="all"/>
+ <modify-function signature="setNum(short,int)" remove="all"/>
+ <modify-function signature="setNum(long,int)" remove="all"/>
+ <modify-function signature="setNum(ulong,int)" remove="all"/>
+ <modify-function signature="setNum(qulonglong,int)" remove="all"/>
+ <modify-function signature="number(uint,int)" remove="all"/>
+ <modify-function signature="number(long,int)" remove="all"/>
+ <modify-function signature="number(ulong,int)" remove="all"/>
+ <modify-function signature="number(qulonglong,int)" remove="all"/>
+
+ <!--### -->
+
+ <modify-function signature="operator const char*()const" remove="all"/>
+ <modify-function signature="operator const void*()const" remove="all"/>
+
+ <!--### STL compatibility functions not supported by PySide -->
+ <modify-function signature="push_back(char)" remove="all"/>
+ <modify-function signature="push_back(const QByteArray&amp;)" remove="all"/>
+ <modify-function signature="push_back(const char*)" remove="all"/>
+ <modify-function signature="push_front(char)" remove="all"/>
+ <modify-function signature="push_front(const QByteArray&amp;)" remove="all"/>
+ <modify-function signature="push_front(const char*)" remove="all"/>
+ <!--### -->
+
+ <modify-function signature="toLong(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toLongLong(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toShort(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toUInt(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toULong(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toULongLong(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toInt(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toUShort(bool*,int)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*,arg"/>
+ </inject-code>
+ </modify-function>
+ <!-- QByteArray(const char *) do the job of this constructor -->
+ <modify-function signature="toDouble(bool*)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="toFloat(bool*)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ <add-function signature="__str__" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-str"/>
+ </add-function>
+ <add-function signature="__len__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-len"/>
+ </add-function>
+ <add-function signature="__getitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-getitem"/>
+ </add-function>
+ <add-function signature="__mgetitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-mgetitem"/>
+ </add-function>
+ <add-function signature="__setitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-setitem"/>
+ </add-function>
+ <add-function signature="__msetitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-msetitem"/>
+ </add-function>
+ </value-type>
+ <primitive-type name="QByteArrayView" view-on="QByteArray">
+ <conversion-rule>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pybytes"/>
+ </conversion-rule>
+ </primitive-type>
+
+ <value-type name="QTextBoundaryFinder">
+ <enum-type name="BoundaryReason" flags="BoundaryReasons"/>
+ <enum-type name="BoundaryType"/>
+ <!-- There's no QChar in PySide -->
+ <modify-function signature="QTextBoundaryFinder(QTextBoundaryFinder::BoundaryType,const QChar*,qsizetype,unsigned char*,qsizetype)" remove="all"/>
+ </value-type>
+ <object-type name="QXmlStreamEntityResolver"/>
+
+ <object-type name="QAbstractEventDispatcher">
+ <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>)" allow-thread="yes"/>
+ <!-- Qt5: had to add this recursive object def. This was crucial to get rid of "pure virtual" -->
+ <value-type name="TimerInfo"/>
+ </object-type>
+
+ <object-type name="QAbstractNativeEventFilter">
+ <!-- see QWidget::nativeEvent(), QWindow::nativeEvent() -->
+ <modify-function signature="nativeEventFilter(const QByteArray&amp;,void*,qintptr*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion_variables"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code position="end">
+ <insert-template name="return_native_eventfilter"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QEventLoop">
+ <enum-type name="ProcessEventsFlag" flags="ProcessEventsFlags"/>
+ <modify-function signature="exec(QFlags&lt;QEventLoop::ProcessEventsFlag>)" allow-thread="yes"/>
+ <add-function signature="exec_(QFlags&lt;QEventLoop::ProcessEventsFlag> @flags@ = QEventLoop::AllEvents)" return-type="int">
+ <inject-code file="../glue/qtcore.cpp" snippet="exec_arg1"/>
+ </add-function>
+ <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>)" allow-thread="yes"/>
+ <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>,int)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QFileDevice">
+ <enum-type name="FileError"/>
+ <enum-type name="FileTime"/>
+ <enum-type name="MemoryMapFlag" flags="MemoryMapFlags"/>
+ <enum-type name="Permission" flags="Permissions"/>
+ <enum-type name="FileHandleFlag" flags="FileHandleFlags"/>
+ <extra-includes>
+ <!-- Qt5: private <include file-name="QAbstractFileEngine" location="global"/> -->
+ </extra-includes>
+ <modify-function signature="unmap(uchar*)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qfiledevice-unmap"/>
+ </modify-function>
+ <modify-function signature="map(qint64,qint64,QFlags&lt;QFileDevice::MemoryMapFlag&gt;)">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qfiledevice-map"/>
+ </modify-function>
+ <modify-function signature="flush()" allow-thread="yes"/>
+ </object-type>
+
+ <object-type name="QFile">
+ <!-- PYSIDE-1499: Replace QString by pathlib.Path (qfile.h) -->
+ <modify-function signature="QFile(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="QFile(const QString &amp;,QObject *)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="setFileName(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="rename(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="link(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="copy(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="permissions(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="setPermissions(const QString &amp;,QFlags&lt;QFileDevice::Permission&gt;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <!-- PYSIDE-1499: End of insertion -->
+
+ <modify-function signature="open(QFlags&lt;QIODeviceBase::OpenModeFlag&gt;)" allow-thread="yes"/>
+ <modify-function signature="open(int,QFlags&lt;QIODeviceBase::OpenModeFlag&gt;,QFlags&lt;QFileDevice::FileHandleFlag&gt;)" allow-thread="yes"/>
+ <modify-function signature="copy(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="copy(const QString&amp;,const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="link(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="link(const QString&amp;,const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="remove()" allow-thread="yes"/>
+ <modify-function signature="remove(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="rename(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="rename(const QString&amp;,const QString&amp;)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QSaveFile"/>
+ <object-type name="QFileSelector"/>
+
+ <object-type name="QIODevice">
+ <modify-function signature="open(QFlags&lt;QIODeviceBase::OpenModeFlag>)" allow-thread="yes"/>
+ <modify-function signature="close()" allow-thread="yes"/>
+ <modify-function signature="seek(qint64)" allow-thread="yes"/>
+ <modify-function signature="readAll()" allow-thread="yes"/>
+ <modify-function signature="peek(qint64)" allow-thread="yes"/>
+ <modify-function signature="write(const QByteArray&amp;)" allow-thread="yes"/>
+ <modify-function signature="waitForReadyRead(int)" allow-thread="yes"/>
+ <modify-function signature="waitForBytesWritten(int)" allow-thread="yes"/>
+ <modify-function signature="peek(char*,qint64)" remove="all"/>
+ <add-function signature="peek(PyBuffer@buffer@,qint64@maxlen@)" return-type="qint64">
+ <modify-argument index="1" pyi-type="bytearray"/>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qiodevice-bufferedread"/>
+ </add-function>
+ <modify-function signature="read(char*,qint64)" remove="all"/>
+ <add-function signature="read(PyBuffer@buffer@,qint64@maxlen@)" return-type="qint64">
+ <modify-argument index="1" pyi-type="bytearray"/>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qiodevice-bufferedread"/>
+ </add-function>
+ <modify-function signature="readLine(char*,qint64)" remove="all"/>
+ <add-function signature="readLine(PyBuffer@buffer@,qint64@maxlen@)" return-type="qint64">
+ <modify-argument index="1" pyi-type="bytearray"/>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qiodevice-bufferedread"/>
+ </add-function>
+ <!-- ### write(str) do the job -->
+ <modify-function signature="write(const char*,qint64)" remove="all"/>
+ <modify-function signature="write(const char*)" remove="all"/>
+ <modify-function signature="getChar(char*)">
+ <modify-argument index="1">
+ <remove-argument />
+ <remove-default-expression />
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_char*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="readData(char*,qint64)">
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qiodevice-readData"/>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code class="native" position="end" file="../glue/qtcore.cpp" snippet="return-readData"/>
+ </modify-function>
+ <modify-function signature="readLineData(char*,qint64)">
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qiodevice-readData"/>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code class="native" position="end" file="../glue/qtcore.cpp" snippet="return-readData"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QIODeviceBase">
+ <enum-type name="OpenModeFlag" flags="OpenMode"/>
+ </object-type>
+ <object-type name="QCryptographicHash">
+ <enum-type name="Algorithm"/>
+ <modify-function signature="addData(const char*,qsizetype)">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qcryptographichash-adddata"/>
+ </modify-function>
+ </object-type>
+ <value-type name="QOperatingSystemVersionBase" since="6.3">
+ <enum-type name="OSType"/>
+ </value-type>
+ <value-type name="QOperatingSystemVersionUnexported" since="6.3" generate="false"/>
+ <value-type name="QOperatingSystemVersion">
+ <modify-function signature="QOperatingSystemVersion(const QOperatingSystemVersionBase&amp;)" remove="all"/>
+ </value-type>
+ <object-type name="QLibrary">
+ <enum-type name="LoadHint" flags="LoadHints"/>
+ </object-type>
+ <object-type name="QLibraryInfo">
+ <enum-type name="LibraryPath"/>
+ <modify-function signature="build()">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qlibraryinfo_build"/>
+ </modify-function>
+ </object-type>
+ <namespace-type name="QtCoreHelper" visible="no">
+ <object-type name="QMutexLocker" copyable="no">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <!-- PYSIDE-1271: Creating locking capable objects inside sections that
+ contain allow-thread, require the classes to also allow having threads.
+ The lack of the option here, was generating a deadlock when running a
+ QMutexLocker inside a QThread::run.
+ The reason of having this change is due to the new way of handling the GIL
+ in the Qt calls on the whole PySide6 module, that started on 5.14.2-->
+ <modify-function signature="QMutexLocker(QMutex*)" allow-thread="yes">
+ <modify-argument index="1">
+ <reference-count action="set" variable-name="mutex()const0"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QMutexLocker(QRecursiveMutex*)" allow-thread="yes">
+ <modify-argument index="1">
+ <reference-count action="set" variable-name="recursiveMutex()const0"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="relock()" allow-thread="yes"/>
+ <modify-function signature="mutex()const">
+ <modify-argument index="return">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="recursiveMutex()const">
+ <modify-argument index="return">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="__enter__()" return-type="QtCoreHelper::QMutexLocker">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
+ <add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
+ </add-function>
+ </object-type>
+ <object-type name="QIOPipe"/>
+ <value-type name="QGenericArgumentHolder"/>
+ <value-type name="QGenericReturnArgumentHolder"/>
+ </namespace-type>
+
+ <!-- Qt5 addition -->
+ <object-type name="QBasicMutex">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="lock()" allow-thread="yes"/>
+ <modify-function signature="tryLock()" allow-thread="yes"/>
+ </object-type>
+
+ <object-type name="QMutex">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="tryLock(int)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QRecursiveMutex">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="lock()" allow-thread="yes"/>
+ <modify-function signature="tryLock(int)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QRandomGenerator">
+ <modify-function signature="global()" rename="global_"/>
+ <modify-function signature="operator()()" remove="all"/>
+ <modify-function signature="generate(quint32*,quint32*)" remove="all"/>
+ </object-type>
+ <object-type name="QRandomGenerator64">
+ <modify-function signature="global()" rename="global_"/>
+ <modify-function signature="operator()()" remove="all"/>
+ </object-type>
+ <object-type name="QSemaphore">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="acquire(int)" allow-thread="yes"/>
+ <modify-function signature="tryAcquire(int,int)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QSemaphoreReleaser">
+ <configuration condition="QT_CONFIG(thread)"/>
+ </object-type>
+
+ <value-type name="QSocketDescriptor">
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qsocketdescriptor"/>
+ </value-type>
+ <object-type name="QSocketNotifier">
+ <enum-type name="Type"/>
+ <add-function signature="QSocketNotifier(PyObject*, QSocketNotifier::Type, QObject*@parent@=nullptr)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qsocketnotifier"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QTemporaryFile">
+ <extra-includes>
+ <!-- Qt5: private <include file-name="QAbstractFileEngine" location="global"/> -->
+ </extra-includes>
+ <modify-function signature="createNativeFile(QFile&amp;)" allow-thread="yes"/>
+ <modify-function signature="createNativeFile(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="open()" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QTemporaryDir"/>
+ <object-type name="QMimeData">
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QUrl" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QTimeLine">
+ <enum-type name="Direction"/>
+ <enum-type name="State"/>
+ </object-type>
+ <object-type name="QTranslator">
+ <modify-function signature="load(const uchar*,int,QString)" allow-thread="yes">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <inject-code file="../glue/qtcore.cpp" snippet="qtranslator-load"/>
+ </modify-function>
+ <modify-function signature="translate(const char*,const char*, const char*,int)const">
+ <modify-argument index="1" pyi-type="str"/>
+ <modify-argument index="2" pyi-type="str"/>
+ <modify-argument index="3" pyi-type="Optional[str]"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QWaitCondition">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="wait(QMutex*,QDeadlineTimer)" allow-thread="yes"/>
+ <modify-function signature="wait(QMutex*,unsigned long)" allow-thread="yes"/>
+ <modify-function signature="wait(QReadWriteLock*,QDeadlineTimer)" allow-thread="yes"/>
+ <modify-function signature="wait(QReadWriteLock*,unsigned long)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QFileSystemWatcher">
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QBuffer">
+ <!-- ### setData(QByteArray) do the job -->
+ <modify-function signature="setData(const char*,qsizetype)" remove="all"/>
+ <!-- Disambiguate from Qt3DRender/qbuffer.h -->
+ <include file-name="QtCore/qbuffer.h" location="global"/>
+ </object-type>
+ <object-type name="QTimer">
+ <extra-includes>
+ <include file-name="pysidestaticstrings.h" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qtimer-singleshot-functorclass"/>
+ <modify-function signature="singleShot(int,const QObject*,const char*)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qtimer-singleshot-direct-mapping"/>
+ </modify-function>
+ <add-function signature="singleShot(int@msec@,PyCallable*@functor@)" static="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qtimer-singleshot-functor"/>
+ </add-function>
+ <add-function signature="singleShot(int@msec@,const QObject*@context@,PyCallable*@functor@)" static="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qtimer-singleshot-functor-context"/>
+ </add-function>
+ </object-type>
+ <object-type name="QProcess">
+ <configuration condition="QT_CONFIG(process)"/>
+ <enum-type name="ExitStatus"/>
+ <enum-type name="InputChannelMode"/>
+ <enum-type name="ProcessChannel"/>
+ <enum-type name="ProcessChannelMode"/>
+ <enum-type name="ProcessError"/>
+ <enum-type name="ProcessState"/>
+
+ <?if !windows?>
+ <enum-type name="UnixProcessFlag" flags="UnixProcessFlags" since="6.6"/>
+ <value-type name="UnixProcessParameters" since="6.6"/>
+ <?endif?>
+
+ <modify-function signature="waitForStarted(int)" allow-thread="yes"/>
+ <modify-function signature="waitForBytesWritten(int)" allow-thread="yes"/>
+ <modify-function signature="waitForFinished(int)" allow-thread="yes"/>
+ <modify-function signature="readAllStandardOutput()" allow-thread="yes"/>
+ <modify-function signature="readAllStandardError()" allow-thread="yes"/>
+ <modify-function signature="execute(QString,QStringList)" allow-thread="yes"/>
+ <modify-function signature="startDetached(QString,QStringList,QString,qint64*)">
+ <modify-argument index="4">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, int]">
+ <replace-type modified-type="(retval, pid)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qprocess-startdetached"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QSignalMapper"/>
+
+ <object-type name="QCollatorSortKey"/>
+ <object-type name="QCollator"/>
+
+ <object-type name="QCommandLineOption">
+ <enum-type name="Flag" flags="Flags"/>
+ </object-type>
+ <object-type name="QCommandLineParser">
+ <enum-type name="OptionsAfterPositionalArgumentsMode"/>
+ <enum-type name="SingleDashWordOptionMode"/>
+ </object-type>
+
+ <object-type name="QCoreApplication">
+ <!--Qt5: gone <enum-type name="Encoding"/> -->
+ <enum-type identified-by-value="ApplicationFlags" since="4.8" revision="4800"/>
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QTranslator" location="global"/>
+ <include file-name="pysidecleanup.h" location="global"/>
+ <include file-name="pysideqapp.h" location="global"/>
+ </extra-includes>
+ <add-function signature="QCoreApplication(QStringList@args@)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qcoreapplication-1"/>
+ <inject-documentation format="target" mode="append">
+ Constructs a Qt kernel application. Kernel applications are applications
+ without a graphical user interface. These type of applications are used
+ at the console or as server processes.
+
+ The *args* argument is processed by the application, and made available
+ in a more convenient form by the :meth:`~PySide6.QtCore.QCoreApplication.arguments()`
+ method.
+ </inject-documentation>
+ </add-function>
+ <add-function signature="QCoreApplication()">
+ <inject-code file="../glue/qtcore.cpp" snippet="qcoreapplication-2"/>
+ </add-function>
+ <!-- Addition for qApp.
+ To be fixed: This function deletes a little too much ATM that is missing later
+ when creating a new qApp. -->
+ <add-function signature="shutdown()">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="moduleshutdown"/>
+ </add-function>
+
+ <!-- blocking functions -->
+ <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag&gt;,int)" allow-thread="yes"/>
+ <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag&gt;)" allow-thread="yes"/>
+ <modify-function signature="sendEvent(QObject*,QEvent*)" allow-thread="yes"/>
+ <modify-function signature="sendPostedEvents(QObject*,int)" allow-thread="yes"/>
+ <modify-function signature="instance()">
+ <modify-argument index="return" pyi-type="Optional[PySide6.QtCore.QCoreApplication]"/>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qcoreapplication-instance"/>
+ </modify-function>
+
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="int">
+ <inject-code file="../glue/qtcore.cpp" snippet="exec_"/>
+ </add-function>
+ <modify-function signature="notify(QObject*,QEvent*)" allow-thread="yes">
+ <modify-argument index="2" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="QCoreApplication(int &amp;,char **,int)" access="private"/>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qcoreapplication-init"/>
+ <modify-function signature="postEvent(QObject*,QEvent*,int)">
+ <modify-argument index="2">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="translate(const char*,const char*,const char *,int)">
+ <modify-argument index="1" pyi-type="str"/>
+ <modify-argument index="2" pyi-type="str"/>
+ <modify-argument index="3" pyi-type="Optional[str]"/>
+ </modify-function>
+ <?if !no_QPermission?>
+ <declare-function signature="checkPermission(const QBluetoothPermission &amp; @permission@)" return-type="Qt::PermissionStatus" since="6.5" />
+ <declare-function signature="checkPermission(const QCalendarPermission &amp; @permission@)" return-type="Qt::PermissionStatus" since="6.5" />
+ <declare-function signature="checkPermission(const QCameraPermission &amp; @permission@)" return-type="Qt::PermissionStatus" since="6.5" />
+ <declare-function signature="checkPermission(const QContactsPermission &amp; @permission@)" return-type="Qt::PermissionStatus" since="6.5" />
+ <declare-function signature="checkPermission(const QLocationPermission &amp; @permission@)" return-type="Qt::PermissionStatus" since="6.5" />
+ <declare-function signature="checkPermission(const QMicrophonePermission &amp; @permission@)" return-type="Qt::PermissionStatus" since="6.5" />
+ <add-function signature="requestPermission(const QBluetoothPermission &amp; @permission@, const QObject* @context@, PyCallable* @functor@)" since="6.5">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qcoreapplication-requestpermission"/>
+ </add-function>
+ <add-function signature="requestPermission(const QCalendarPermission &amp; @permission@, const QObject* @context@, PyCallable* @functor@)" since="6.5">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qcoreapplication-requestpermission"/>
+ </add-function>
+ <add-function signature="requestPermission(const QCameraPermission &amp; @permission@, const QObject* @context@, PyCallable* @functor@)" since="6.5">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qcoreapplication-requestpermission"/>
+ </add-function>
+ <add-function signature="requestPermission(const QContactsPermission &amp; @permission@, const QObject* @context@, PyCallable* @functor@)" since="6.5">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qcoreapplication-requestpermission"/>
+ </add-function>
+ <add-function signature="requestPermission(const QLocationPermission &amp; @permission@, const QObject* @context@, PyCallable* @functor@)" since="6.5">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qcoreapplication-requestpermission"/>
+ </add-function>
+ <add-function signature="requestPermission(const QMicrophonePermission &amp; @permission@, const QObject* @context@, PyCallable* @functor@)" since="6.5">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qcoreapplication-requestpermission"/>
+ </add-function>
+ <?endif?>
+ </object-type>
+ <object-type name="QSettings">
+ <enum-type name="Format"/>
+ <enum-type name="Scope"/>
+ <enum-type name="Status"/>
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="settings-value-helpers"/>
+ <!-- PYSIDE-1010:
+ We remove the original implementation of value() to include the optional parameter -->
+ <modify-function signature="value(QAnyStringView,const QVariant&amp;)const" remove="all"/>
+ <add-function signature="value(const QString&amp;, const QVariant&amp; @defaultValue@ = {}, PyObject* @type@ = nullptr)" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qsettings-value"/>
+ <inject-documentation mode="append" format="target">
+ Custom overload that adds an optional named parameter to the function ``value()``
+ to automatically cast the type that is being returned by the function.
+
+ An example of this situation could be an ini file that contains
+ the value of a one-element list::
+
+ settings.setValue('var', ['a'])
+
+ The the ini file will be::
+
+ [General]
+ var=a # we cannot know that this is a list!
+
+ Once we read it, we could specify if we want
+ the default behavior, a str, or to cast the output
+ to a list.
+
+ settings.value('var') # Will get "a"
+ settings.value('var', type=list) # Will get ["a"]
+ </inject-documentation>
+ </add-function>
+ </object-type>
+ <object-type name="QEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::None"
+ qt-register-metatype="base">
+ <enum-type name="Type" python-type="IntEnum"/>
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtcore.cpp" snippet="repr-qevent"/>
+ </add-function>
+ </object-type>
+ <object-type name="QChildEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::ChildAdded || %B-&gt;type() == QEvent::ChildPolished || %B-&gt;type() == QEvent::ChildRemoved">
+ <modify-function signature="child()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QTimerEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::Timer"/>
+ <object-type name="QDynamicPropertyChangeEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::DynamicPropertyChange"/>
+
+
+ <object-type name="QDataStream" stream="yes">
+ <enum-type name="FloatingPointPrecision" since="4.6"/>
+ <enum-type name="Status"/>
+ <enum-type name="Version" python-type="IntEnum"/>
+ <enum-type name="ByteOrder"/>
+ <extra-includes>
+ <include file-name="QtCore/QtCore" location="global"/>
+ </extra-includes>
+
+ <!-- ### Replaced by write<TYPE> methods -->
+ <modify-function signature="operator&gt;&gt;(qint8&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(bool&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(quint8&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(qint16&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(quint16&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(qint32&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(quint32&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(qint64&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(quint64&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(float&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(double&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(char*&amp;)" remove="all"/>
+ <!-- ### -->
+
+ <!-- ### Replaced by read<TYPE> methods -->
+ <modify-function signature="operator&lt;&lt;(qint8)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(bool)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(quint8)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(qint16)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(quint16)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(qint32)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(quint32)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(qint64)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(quint64)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(float)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(double)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(const char*)" remove="all"/>
+ <!-- ### -->
+ <add-function signature="operator&lt;&lt;(const QString&amp;)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeQString(const QString&amp;)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="readQString()" return-type="QString">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="writeQChar(const QChar&amp;)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="readQChar()" return-type="QChar">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="writeQStringList(const QStringList&amp;)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="readQStringList()" return-type="QStringList">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="writeQVariant(const QVariant&amp;)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="readQVariant()" return-type="QVariant">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <modify-function signature="readRawData(char*,qint64)">
+ <modify-argument index="return" pyi-type="bytes"/>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qdatastream-readrawdata"/>
+ </modify-function>
+ <add-function signature="writeRawData(PyBuffer)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtcore.cpp" snippet="qdatastream-writerawdata-pybuffer"/>
+ </add-function>
+ <modify-function signature="writeRawData(const char*,qint64)">
+ <modify-argument index="1" pyi-type="str"/>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qdatastream-writerawdata"/>
+ </modify-function>
+
+ <!-- Extra functions for primitive type handling -->
+ <add-function signature="readBool()" return-type="bool">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readInt8()" return-type="qint8">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readUInt8()" return-type="quint8">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readUInt16()" return-type="quint16">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readInt16()" return-type="qint16">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readInt32()" return-type="qint32">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readUInt32()" return-type="quint32">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readInt64()" return-type="qint64">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readUInt64()" return-type="quint64">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readFloat()" return-type="float">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readDouble()" return-type="qreal">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+ <add-function signature="readString()" return-type="QString">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
+ </add-function>
+
+ <add-function signature="writeBool(bool)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeInt8(qint8)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeUInt8(quint8)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeUInt16(quint16)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeInt16(qint16)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeInt32(qint32)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeUInt32(quint32)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeInt64(qint64)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeUInt64(quint64)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeFloat(float)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeDouble(qreal)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <add-function signature="writeString(QString)">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
+ </add-function>
+ <modify-function signature="readBytes(char*&amp;,qint64&amp;)">
+ <modify-argument index="return">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatastream-read-bytes"/>
+ </modify-function>
+ <modify-function signature="readBytes(char*&amp;,uint&amp;)" remove="all"/>
+
+ <modify-function signature="writeBytes(const char*,qint64)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ <conversion-rule class="native">
+ <insert-template name="pybuffer_const_char"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="uint_remove"/>
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <value-type name="QTextStreamManipulator" default-constructor="QTextStreamManipulator(0, 0)">
+ <!-- Since exec() here doesn't need an allow-threads, we don't modify the original -->
+ <add-function signature="exec_(QTextStream &amp;)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qtextstreammanipulator-exec"/>
+ </add-function>
+ </value-type>
+ <object-type name="QTextStream" stream="yes">
+ <enum-type name="FieldAlignment"/>
+ <enum-type name="NumberFlag" flags="NumberFlags"/>
+ <enum-type name="RealNumberNotation"/>
+ <enum-type name="Status"/>
+ <!-- Removed because it expect QString to be mutable -->
+ <modify-function signature="QTextStream(QString*,QFlags&lt;QIODeviceBase::OpenModeFlag&gt;)" remove="all"/>
+ <!-- Qt5.5: Removed because it expect QString to be mutable -->
+ <modify-function signature="readLineInto(QString*,qint64)"/>
+ <!-- Removed because we use the non-const version -->
+ <modify-function signature="QTextStream(const QByteArray&amp;,QFlags&lt;QIODeviceBase::OpenModeFlag&gt;)" remove="all"/>
+
+ <!-- Removed because it expect QString to be mutable -->
+ <modify-function signature="setString(QString*,QFlags&lt;QIODeviceBase::OpenModeFlag&gt;)" remove="all"/>
+
+ <modify-function signature="operator&lt;&lt;(const void*)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(float)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(qlonglong)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(qulonglong)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(short)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(int)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(unsigned int)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(unsigned short)" remove="all"/>
+ <modify-function signature="operator&lt;&lt;(const char*)" remove="all"/>
+
+ <modify-function signature="operator&gt;&gt;(char*)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(char&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(float&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(double&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(qlonglong&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(qulonglong&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(long&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(int&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(short&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(unsigned long&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(unsigned int&amp;)" remove="all"/>
+ <modify-function signature="operator&gt;&gt;(unsigned short&amp;)" remove="all"/>
+ <!-- Removed because it expect QChar to be mutable -->
+ <modify-function signature="operator&gt;&gt;(QChar&amp;)" remove="all"/>
+ <!-- Removed because it expect QString to be mutable -->
+ <modify-function signature="operator&gt;&gt;(QString&amp;)" remove="all"/>
+
+ <modify-function signature="string()const">
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="return-qstring-ref"/>
+ </modify-function>
+
+ <modify-function signature="flush()" allow-thread="yes"/>
+ <modify-function signature="read(qint64)" allow-thread="yes"/>
+ <modify-function signature="readLine(qint64)" allow-thread="yes"/>
+ <modify-function signature="readAll()" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QStandardPaths">
+ <enum-type name="StandardLocation"/>
+ <enum-type name="LocateOption" flags="LocateOptions"/>
+ </object-type>
+ <object-type name="QSystemSemaphore">
+ <configuration condition="#ifndef QT_NO_SYSTEMSEMAPHORE"/>
+ <enum-type name="AccessMode"/>
+ <enum-type name="SystemSemaphoreError"/>
+ </object-type>
+
+ <object-type name="QThreadPool">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <modify-function signature="clear()" allow-thread="yes"/>
+ <modify-function signature="activeThreadCount()const" allow-thread="yes"/>
+ <modify-function signature="releaseThread()" allow-thread="yes"/>
+ <modify-function signature="reserveThread()" allow-thread="yes"/>
+ <modify-function signature="setMaxThreadCount(int)" allow-thread="yes"/>
+ <modify-function signature="waitForDone(int)" allow-thread="yes"/>
+ <modify-function signature="start(QRunnable*,int)" allow-thread="yes">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="start(PyCallable,int @priority@=0)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtcore.cpp"
+ snippet="std-function-void-lambda"/>
+ <inject-code class="target" position="beginning"
+ file="../glue/qtcore.cpp"
+ snippet="qthreadpool-start"/>
+ </add-function>
+ <modify-function signature="tryStart(QRunnable*)" allow-thread="yes">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="tryStart(PyCallable)" return-type="bool">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtcore.cpp"
+ snippet="std-function-void-lambda"/>
+ <inject-code class="target" position="beginning"
+ file="../glue/qtcore.cpp"
+ snippet="qthreadpool-trystart"/>
+ </add-function>
+ <modify-function signature="tryTake(QRunnable*)" allow-thread="yes"/>
+
+ <modify-function signature="globalInstance()" >
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="releaseownership"/>
+ </modify-function>
+ </object-type>
+ <value-type name="QXmlStreamAttribute"/>
+ <value-type name="QXmlStreamAttributes">
+ <modify-function signature="push_back(QXmlStreamAttribute)" remove="all"/>
+ <modify-function signature="pop_back()" remove="all"/>
+ <modify-function signature="push_front(QXmlStreamAttribute)" remove="all"/>
+ <modify-function signature="pop_front()" remove="all"/>
+ <modify-function signature="toList()const" remove="all"/>
+ <!-- Remove methods from QList -->
+ <modify-function signature="fromList(const QList&lt;QXmlStreamAttribute&gt; &amp;)" remove="all"/>
+ <modify-function signature="operator+=(QVector&lt;QXmlStreamAttribute&gt;)" remove="all"/>
+ <!-- Expose operator==, != inherited from QList, which the parser does
+ not see due to the TMP expression of the return type. -->
+ <add-function signature="operator==(const QXmlStreamAttributes&amp;)" return-type="bool"/>
+ <add-function signature="operator!=(const QXmlStreamAttributes&amp;)" return-type="bool"/>
+ </value-type>
+ <value-type name="QXmlStreamNamespaceDeclaration"/>
+ <value-type name="QXmlStreamNotationDeclaration"/>
+ <value-type name="QXmlStreamEntityDeclaration"/>
+ <object-type name="QXmlStreamReader">
+ <enum-type name="Error"/>
+ <enum-type name="TokenType"/>
+ <enum-type name="ReadElementTextBehaviour" since="4.6"/>
+ </object-type>
+ <object-type name="QXmlStreamWriter">
+ <!-- Removed because it expect QString to be mutable -->
+ <modify-function signature="QXmlStreamWriter(QString*)" remove="all"/>
+ </object-type>
+ <value-type name="QModelIndex">
+ <modify-function signature="internalPointer()const">
+ <modify-argument index="return" pyi-type="Any"/>
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_internal_pointer" />
+ </inject-code>
+ </modify-function>
+ <modify-function signature="model()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <object-type name="QFutureInterfaceBase">
+ <configuration condition="QT_CONFIG(future)"/>
+ <enum-type name="State"/>
+ <enum-type name="CancelMode" since="6.3"/>
+ </object-type>
+ <value-type name="QFuture" generate="no">
+ <include file-name="QtCore/qfuture.h" location="global"/>
+ <configuration condition="QT_CONFIG(future)"/>
+ <modify-function signature="waitForFinished()" allow-thread="yes"/>
+ </value-type>
+ <object-type name="QFutureWatcherBase" generate="no">
+ <configuration condition="QT_CONFIG(future)"/>
+ <modify-function signature="futureInterface()" remove="all"/>
+ <modify-function signature="futureInterface() const" remove="all"/>
+ </object-type>
+ <object-type name="QFutureWatcher" generate="no">
+ <include file-name="QtCore/qfuturewatcher.h" location="global"/>
+ <configuration condition="QT_CONFIG(future)"/>
+ </object-type>
+
+ <!--// FIXME PYSIDE 7: Remove in favor of QtCoreHelper::QGenericArgumentHolder for
+ QMetaObject.invokeMethod? It was left as is in case someone has some hack
+ with a void pointer for this, but it does not really make sense (PYSIDE-1898). -->
+ <value-type name="QGenericArgument">
+ <include file-name="qobjectdefs.h" location="global"/>
+ </value-type>
+
+ <value-type name="QGenericReturnArgument">
+ <include file-name="qobjectdefs.h" location="global"/>
+ </value-type>
+
+ <object-type name="QMessageLogContext"/>
+
+ <value-type name="QMetaMethod">
+ <extra-includes>
+ <include file-name="pysidesignal.h" location="global"/>
+ <include file-name="glue/core_snippets_p.h" location="local"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetamethod-invoke-helpers"/>
+ <enum-type name="Access"/>
+ <enum-type name="MethodType"/>
+ <add-function signature="fromSignal(PySideSignalInstance@signal@)"
+ return-type="QMetaMethod" static="true">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetamethod-from-signal"/>
+ <inject-documentation format="target" mode="append">
+ Returns the meta-method that corresponds to the given signal, or an invalid QMetaMethod
+ if signal is not a signal of the class.
+ </inject-documentation>
+ </add-function>
+ <add-function signature="invoke(QObject*@object@,Qt::ConnectionType@type@,
+ QtCoreHelper::QGenericReturnArgumentHolder@ret@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetamethod-invoke-conn-type-return-arg"/>
+ </add-function>
+ <add-function signature="invoke(QObject*@object@,
+ QtCoreHelper::QGenericReturnArgumentHolder@ret@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetamethod-invoke-return-arg"/>
+ </add-function>
+ <add-function signature="invoke(QObject*@object@,Qt::ConnectionType@type@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetamethod-invoke-conn-type"/>
+ </add-function>
+ <add-function signature="invoke(QObject*@object@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetamethod-invoke"/>
+ </add-function>
+ <!-- This isn't part of Qt public API -->
+ <modify-function signature="attributes()const" remove="all"/>
+ <modify-function signature="getParameterTypes(int*)const" remove="all"/>
+ <modify-field name="mobj" remove="yes"/>
+ </value-type>
+ <object-type name="QMetaObject">
+ <enum-type name="Call"/>
+ <include file-name="qobjectdefs.h" location="global"/>
+ <extra-includes>
+ <include file-name="dynamicqmetaobject.h" location="global"/>
+ <include file-name="pysidemetatype.h" location="global"/>
+ <include file-name="glue/core_snippets_p.h" location="local"/>
+ <include file-name="pysideutils.h" location="global"/> <!-- QString conversion -->
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetaobject-invokemethod-helpers"/>
+ <!-- This isn't part of Qt public API -->
+ <modify-function signature="connect(const QObject*,int,const QObject*,int,int,int*)" remove="all"/>
+ <value-type name="Connection" operator-bool="true">
+ <include file-name="qobjectdefs.h" location="global"/>
+ <!-- Declare operator bool, as the class uses some RestrictedBool trick -->
+ <declare-function signature="operator bool() const" return-type="bool"/>
+ </value-type>
+ <modify-function signature="^invokeMethod\(" allow-thread="yes"/>
+ <add-function signature="invokeMethod(QObject*@object@,const char *@member@,Qt::ConnectionType@type@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ static="yes" return-type="bool">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetaobject-invokemethod-conn-type-arg"/>
+ </add-function>
+ <add-function signature="invokeMethod(QObject*@object@,const char *@member@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ static="yes" return-type="bool">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetaobject-invokemethod-arg"/>
+ </add-function>
+ <add-function signature="invokeMethod(QObject*@object@,const char *@member@,Qt::ConnectionType@type@,
+ QtCoreHelper::QGenericReturnArgumentHolder@ret@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ static="yes" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetaobject-invokemethod-conn-type-return-arg"/>
+ </add-function>
+ <add-function signature="invokeMethod(QObject*@object@,const char *@member@,
+ QtCoreHelper::QGenericReturnArgumentHolder@ret@,
+ QtCoreHelper::QGenericArgumentHolder@val0@={},
+ QtCoreHelper::QGenericArgumentHolder@val1@={},
+ QtCoreHelper::QGenericArgumentHolder@val2@={},
+ QtCoreHelper::QGenericArgumentHolder@val3@={},
+ QtCoreHelper::QGenericArgumentHolder@val4@={},
+ QtCoreHelper::QGenericArgumentHolder@val5@={},
+ QtCoreHelper::QGenericArgumentHolder@val6@={},
+ QtCoreHelper::QGenericArgumentHolder@val7@={},
+ QtCoreHelper::QGenericArgumentHolder@val8@={},
+ QtCoreHelper::QGenericArgumentHolder@val9@={})"
+ static="yes" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp"
+ snippet="qmetaobject-invokemethod-return-arg"/>
+ </add-function>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qmetaobject-repr"/>
+ </add-function>
+ <modify-function signature="indexOfClassInfo(const char *)">
+ <modify-argument index="1" pyi-type="str"/>
+ </modify-function>
+ <modify-function signature="indexOfConstructor(const char *)">
+ <modify-argument index="1" pyi-type="str"/>
+ </modify-function>
+ <modify-function signature="indexOfEnumerator(const char *)">
+ <modify-argument index="1" pyi-type="str"/>
+ </modify-function>
+ <modify-function signature="indexOfMethod(const char *)">
+ <modify-argument index="1" pyi-type="str"/>
+ </modify-function>
+ <modify-function signature="indexOfProperty(const char *)">
+ <modify-argument index="1" pyi-type="str"/>
+ </modify-function>
+ <modify-function signature="indexOfSignal(const char *)">
+ <modify-argument index="1" pyi-type="str"/>
+ </modify-function>
+ <modify-function signature="indexOfSlot(const char *)">
+ <modify-argument index="1" pyi-type="str"/>
+ </modify-function>
+ </object-type>
+ <value-type name="QMetaProperty" >
+ <!-- This isn't part of Qt public API -->
+ <modify-function signature="enclosingMetaObject()const" remove="all"/>
+ <modify-function signature="write(QObject*,const QVariant &amp;)const">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qmetaproperty_write_enum"/>
+ </modify-function>
+ </value-type>
+ <value-type name="QMetaClassInfo">
+ <!-- This isn't part of Qt public API -->
+ <modify-function signature="enclosingMetaObject()const" remove="all"/>
+ </value-type>
+
+ <value-type name="QMetaEnum">
+ <modify-function signature="keyToValue(const char*,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="keysToValue(const char*,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <!-- This isn't part of Qt public API -->
+ <modify-function signature="enclosingMetaObject()const" remove="all"/>
+ </value-type>
+
+ <!-- From Qt4.6 -->
+ <object-type name="QAbstractAnimation" since="4.6">
+ <enum-type name="DeletionPolicy"/>
+ <enum-type name="Direction"/>
+ <enum-type name="State"/>
+ </object-type>
+
+ <object-type name="QAnimationGroup" since="4.6">
+ <modify-function signature="addAnimation(QAbstractAnimation*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="insertAnimation(int,QAbstractAnimation*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="removeAnimation(QAbstractAnimation*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="takeAnimation(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="clear()" >
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qanimationgroup-clear"/>
+ </modify-function>
+ </object-type>
+
+ <!-- We will use inject code to implement the function below -->
+ <rejection class="QEasingCurve" function-name="setCustomType"/>
+ <rejection class="QEasingCurve" function-name="customType"/>
+ <value-type name="QEasingCurve" since="4.6">
+ <extra-includes>
+ <include file-name="pysideweakref.h" location="global"/>
+ <include file-name="glue/qeasingcurve_glue.h" location="local"/>
+ </extra-includes>
+ <inject-code file="../glue/qtcore.cpp" snippet="qeasingcurve"/>
+ <enum-type name="Type"/>
+ <add-function signature="setCustomType(PyObject*)">
+ <inject-code file="../glue/qtcore.cpp" snippet="qeasingcurve-setcustomtype"/>
+ </add-function>
+ <add-function signature="customType()" return-type="PyObject">
+ <inject-code file="../glue/qtcore.cpp" snippet="qeasingcurve-customtype"/>
+ </add-function>
+ </value-type>
+
+ <value-type name="QJsonArray">
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ </extra-includes>
+ </value-type>
+
+ <value-type name="QJsonDocument">
+ <enum-type name="JsonFormat"/>
+ </value-type>
+
+ <rejection class="QJsonDocument" field-name="BinaryFormatTag"/>
+
+ <value-type name="QJsonParseError">
+ <enum-type name="ParseError"/>
+ </value-type>
+
+ <value-type name="QJsonValue">
+ <enum-type name="Type"/>
+ <extra-includes>
+ <include file-name="QVariant" location="global"/>
+ <include file-name="QJsonArray" location="global"/>
+ <include file-name="QJsonObject" location="global"/>
+ </extra-includes>
+ </value-type>
+
+ <value-type name="QMargins" since="4.6"/>
+ <value-type name="QMarginsF"/>
+
+ <object-type name="QParallelAnimationGroup" since="4.6"/>
+
+ <object-type name="QPauseAnimation" since="4.6"/>
+
+ <value-type name="QProcessEnvironment" since="4.6">
+ <configuration condition="QT_CONFIG(processenvironment)"/>
+ <enum-type name="Initialization" since="6.3"/>
+ </value-type>
+
+ <object-type name="QPropertyAnimation" since="4.6"/>
+
+ <object-type name="QSequentialAnimationGroup" since="4.6"/>
+
+ <object-type name="QVariantAnimation" since="4.6"/>
+
+ <value-type name="QVersionNumber">
+ <modify-function signature="fromString(QAnyStringView,qsizetype*)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <!-- From Qt4.6 ^^^ -->
+
+ <add-function signature="SIGNAL(const char*)" return-type="str">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-signal"/>
+ <modify-argument index="1" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="SLOT(const char*)" return-type="str">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-slot"/>
+ <modify-argument index="1" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="QT_TR_NOOP(PyObject)" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_argument"><replace from="#" to="1"/></insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QT_TR_NOOP_UTF8(PyObject)" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_argument"><replace from="#" to="1"/></insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QT_TRANSLATE_NOOP(PyObject,PyObject)" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_argument"><replace from="#" to="2"/></insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QT_TRANSLATE_NOOP3(PyObject,PyObject,PyObject)" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_argument"><replace from="#" to="2"/></insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QT_TRANSLATE_NOOP_UTF8(PyObject)" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_argument"><replace from="#" to="1"/></insert-template>
+ </inject-code>
+ </add-function>
+
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qt-registerresourcedata"/>
+ <add-function signature="qRegisterResourceData(int,PyBytes,PyBytes,PyBytes)" return-type="bool">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qregisterresourcedata"/>
+ </add-function>
+ <add-function signature="qUnregisterResourceData(int,PyBytes,PyBytes,PyBytes)" return-type="bool">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qunregisterresourcedata"/>
+ </add-function>
+
+ <object-type name="QFactoryInterface"/>
+ <object-type name="QRunnable">
+ <configuration condition="QT_CONFIG(thread)"/>
+ <add-function signature="create(PyObject* @functionToRun@)" static="yes" return-type="QRunnable*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qrunnable_create"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QPluginLoader"/>
+ <object-type name="QStringListModel"/>
+
+ <object-type name="QSharedMemory">
+ <configuration condition="#ifndef QT_NO_SHAREDMEMORY"/>
+ <enum-type name="AccessMode"/>
+ <enum-type name="SharedMemoryError"/>
+ <modify-function signature="data()">
+ <inject-code class="target" position="end"
+ file="../glue/qtcore.cpp" snippet="qsharedmemory_data_readwrite"/>
+ </modify-function>
+ <modify-function signature="constData()const">
+ <inject-code class="target" position="end"
+ file="../glue/qtcore.cpp" snippet="qsharedmemory_data_readonly"/>
+ </modify-function>
+ <modify-function signature="data()const" remove="all"/>
+ </object-type>
+
+ <object-type name="QStringConverterBase">
+ <enum-type name="Flag" flags="Flags"/>
+ <object-type name="State"/>
+ </object-type>
+ <object-type name="QStringConverter">
+ <enum-type name="Encoding"/>
+ </object-type>
+ <object-type name="QStringEncoder">
+ <modify-function signature="appendToBuffer(char*,QStringView)" remove="all"/>
+ </object-type>
+ <object-type name="QStringDecoder"/>
+
+ <object-type name="QSysInfo">
+ <enum-type name="Endian"/>
+ <enum-type name="Sizes"/>
+ </object-type>
+
+ <object-type name="QLoggingCategory"/>
+
+ <add-function signature="qCDebug(PyObject *, const char *)">
+ <extra-includes>
+ <include file-name="qloggingcategory.h" location="global" />
+ </extra-includes>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qloggingcategory_to_cpp">
+ qCDebug((*category), "%s", %2);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="qCCritical(PyObject *, const char *)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qloggingcategory_to_cpp">
+ qCCritical((*category), "%s", %2);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="qCInfo(PyObject *, const char *)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qloggingcategory_to_cpp">
+ qCInfo((*category), "%s", %2);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="qCWarning(PyObject *, const char *)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qloggingcategory_to_cpp">
+ qCWarning((*category), "%s", %2);
+ </inject-code>
+ </add-function>
+
+ <suppress-warning text="^.*enum 'Qt::Initialization' does not have a type entry.*$"/>
+ <suppress-warning text="^.*Enum 'QRandomGenerator::System'.*does not have a type entry.*$"/>
+
+ <suppress-warning text="^Anonymous enum.*does not have a type entry.*$"/>
+ <suppress-warning text="Visibility of function '*' modified in class '*'"/>
+ <suppress-warning text="Shadowing: *"/>
+ <suppress-warning text="^namespace '.*' does not have a type entry.*$"/>
+ <!-- QCborStreamReader: Suppress warnings about 32/64bit signatures not found depending on qsizetype -->
+ <suppress-warning text="^signature 'readStringChunk\(char.*in 'QCborStreamReader' not found.*$"/>
+
+ <!-- TODO: this need be removed -->
+ <suppress-warning text="^skipping.*function '.*', unmatched return type '.*$"/>
+ <suppress-warning text="^skipping.*function '.*', unmatched type '.*$"/>
+ <suppress-warning text="skipping protected field 'QStringConverter::iface' with unmatched type 'QStringConverter::Interface'"/>
+ <suppress-warning text="^skipping public field 'Qt::.*' with unmatched type 'Qt::.*ordering'$"/>
+ <suppress-warning text="skipping public field 'Qt::Uninitialized' with unmatched type 'Qt::Initialization'"/>
+ <suppress-warning text="skipping public field 'State::clearFn' with unmatched type 'void'"/>
+ <suppress-warning text="template baseclass 'QListSpecialMethods&lt;T&gt;' of 'QList' is not known"/>
+ <suppress-warning text="^.*inherits from a non polymorphic type.*QIODeviceBase.*type discovery based on RTTI is impossible.*$"/>
+ <suppress-warning text="Base class 'QOperatingSystemVersionUnexported' of class 'QOperatingSystemVersion' not found in the type system for setting up inheritance."/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_win.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_win.xml
new file mode 100644
index 000000000..e2984afd9
--- /dev/null
+++ b/sources/pyside6/PySide6/QtCore/typesystem_core_win.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtCore">
+ <extra-includes>
+ <include file-name="QtCore/qt_windows.h" location="global"/>
+ </extra-includes>
+ <primitive-type name="HWND">
+ <!-- Qt5: Add this include there to insert ti in the global qtcore header (needed by qprocess_wrapper) -->
+ <include file-name="wtypes.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ return PyCapsule_New(%in, nullptr, nullptr);
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PyNone">
+ %out = 0;
+ </add-conversion>
+ <add-conversion check="checkPyCapsuleOrPyCObject(%in)" type="PyObject">
+ %out = (%OUTTYPE)PyCapsule_GetPointer(%in, nullptr);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <inject-code class="native" position="beginning">
+ <insert-template name="checkPyCapsuleOrPyCObject_func"/>
+ </inject-code>
+
+ <object-type name="QWinEventNotifier"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtDBus/CMakeLists.txt b/sources/pyside6/PySide6/QtDBus/CMakeLists.txt
new file mode 100644
index 000000000..5ee8dc67c
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDBus/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtDBus)
+
+set(QtDBus_SRC
+ ${QtDBus_GEN_DIR}/qdbus_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusabstractadaptor_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusabstractinterface_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusabstractinterfacebase_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusargument_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusconnection_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusconnectioninterface_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbuscontext_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbuserror_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusinterface_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusmessage_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusobjectpath_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbuspendingcall_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbuspendingcallwatcher_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qtdbushelper_qdbusreply_wrapper.cpp
+ #${QtDBus_GEN_DIR}/qdbuspendingreply_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusserver_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusservicewatcher_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbussignature_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusunixfiledescriptor_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusvariant_wrapper.cpp
+ ${QtDBus_GEN_DIR}/qdbusvirtualobject_wrapper.cpp
+# module is always needed
+ ${QtDBus_GEN_DIR}/qtdbus_module_wrapper.cpp
+)
+
+configure_file("${QtDBus_SOURCE_DIR}/QtDBus_global.post.h.in"
+ "${QtDBus_BINARY_DIR}/QtDBus_global.post.h" @ONLY)
+
+set(QtDBus_include_dirs ${QtDBus_SOURCE_DIR}
+ ${QtDBus_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}DBus_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtDBus_libraries pyside6 ${Qt${QT_MAJOR_VERSION}DBus_LIBRARIES})
+
+set(QtDBus_deps QtCore)
+
+create_pyside_module(NAME QtDBus
+ INCLUDE_DIRS QtDBus_include_dirs
+ LIBRARIES QtDBus_libraries
+ DEPS QtDBus_deps
+ TYPESYSTEM_PATH QtDBus_SOURCE_DIR
+ SOURCES QtDBus_SRC)
+
+install(FILES ${pyside6_SOURCE_DIR}/qtdbushelper.h DESTINATION include/PySide6/QtDBus)
diff --git a/sources/pyside6/PySide6/QtDBus/QtDBus_global.post.h.in b/sources/pyside6/PySide6/QtDBus/QtDBus_global.post.h.in
new file mode 100644
index 000000000..299d6bdb1
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDBus/QtDBus_global.post.h.in
@@ -0,0 +1 @@
+#include <qtdbushelper.h>
diff --git a/sources/pyside6/PySide6/QtDBus/typesystem_dbus.xml b/sources/pyside6/PySide6/QtDBus/typesystem_dbus.xml
new file mode 100644
index 000000000..ebed22257
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDBus/typesystem_dbus.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtDBus"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+
+ <namespace-type name="QDBus">
+ <enum-type name="CallMode"/>
+ </namespace-type>
+
+ <object-type name="QDBusAbstractAdaptor"/>
+ <object-type name="QDBusAbstractInterfaceBase"/>
+ <object-type name="QDBusAbstractInterface">
+ <!-- Those are template argument lists (see also callWithArgumentList() -->
+ <declare-function signature="call(const QString&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(const QString&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ <declare-function signature="call(QDBus::CallMode,const QString&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;,const QVariant&amp;)"
+ return-type="QDBusMessage"/>
+ </object-type>
+ <value-type name="QDBusArgument">
+ <enum-type name="ElementType"/>
+ </value-type>
+ <value-type name="QDBusConnection">
+ <enum-type name="BusType"/>
+ <enum-type name="ConnectionCapability" flags="ConnectionCapabilities"/>
+ <enum-type name="RegisterOption" flags="RegisterOptions"/>
+ <enum-type name="UnregisterMode"/>
+ <enum-type name="VirtualObjectRegisterOption" flags="VirtualObjectRegisterOptions"/>
+ <modify-function signature="interface()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <!-- PYSIDE-2547, hangs -->
+ <modify-function signature="^connect\(.*\)$" allow-thread="yes"/>
+ </value-type>
+ <object-type name="QDBusConnectionInterface">
+ <enum-type name="RegisterServiceReply"/>
+ <enum-type name="ServiceQueueOptions"/>
+ <enum-type name="ServiceReplacementOptions"/>
+ <!-- Original functions are rejected since they return ::QDBusReply<T> -->
+ <declare-function signature="registeredServiceNames()const"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="registerService(const QString&amp;,QDBusConnectionInterface::ServiceQueueOptions,QDBusConnectionInterface::ServiceReplacementOptions)"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="activatableServiceNames()const"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="serviceOwner(const QString&amp;)const"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="isServiceRegistered(const QString&amp;)const"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="unregisterService(const QString&amp;)"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="servicePid(const QString&amp;)const"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="serviceUid(const QString&amp;)const"
+ return-type="QtDBusHelper::QDBusReply"/>
+ <declare-function signature="startService(const QString&amp;)"
+ return-type="QtDBusHelper::QDBusReply"/>
+ </object-type>
+ <value-type name="QDBusContext"/>
+ <value-type name="QDBusError">
+ <enum-type name="ErrorType"/>
+ </value-type>
+ <object-type name="QDBusInterface" qt-metaobject="no">
+ <inject-documentation format="target" mode="append">
+ DBus signals can be captured with string-based connections
+ (see :ref:`signals-and-slots-strings`).
+ </inject-documentation>
+ </object-type>
+ <value-type name="QDBusMessage">
+ <enum-type name="MessageType"/>
+ </value-type>
+ <value-type name="QDBusObjectPath"/>
+ <object-type name="QDBusPendingCall"/>
+ <object-type name="QDBusPendingCallWatcher"/>
+
+ <namespace-type name="QtDBusHelper" visible="no">
+ <object-type name="QDBusReply"/>
+ </namespace-type>
+
+ <object-type name="QDBusServer"/>
+ <object-type name="QDBusServiceWatcher">
+ <enum-type name="WatchModeFlag" flags="WatchMode"/>
+ </object-type>
+ <object-type name="QDBusSignature"/>
+ <object-type name="QDBusUnixFileDescriptor"/>
+ <value-type name="QDBusVariant"/>
+ <object-type name="QDBusVirtualObject"/>
+ <suppress-warning text='^.*Unable to translate type "QDBusReply&lt;.*$'/>
+ <suppress-warning text='^.*QDBusPendingCallWatcher inherits from a non polymorphic type.*$'/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtDataVisualization/CMakeLists.txt b/sources/pyside6/PySide6/QtDataVisualization/CMakeLists.txt
new file mode 100644
index 000000000..1276b424f
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDataVisualization/CMakeLists.txt
@@ -0,0 +1,71 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtDataVisualization)
+
+list(APPEND QtDataVisualization_src "${QtDataVisualization_SOURCE_DIR}/qtdatavisualization_helper.cpp")
+
+set(QtDataVisualization_SRC
+${QtDataVisualization_GEN_DIR}/qabstract3daxis_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qcategory3daxis_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qlogvalue3daxisformatter_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qvalue3daxis_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qvalue3daxisformatter_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qabstract3dseries_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qabstractdataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qbar3dseries_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qbardataitem_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qbardataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qcustom3ditem_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qcustom3dlabel_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qcustom3dvolume_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qheightmapsurfacedataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qitemmodelbardataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qitemmodelscatterdataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qitemmodelsurfacedataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qscatter3dseries_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qscatterdataitem_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qscatterdataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qsurface3dseries_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qsurfacedataitem_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qsurfacedataproxy_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dbars_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dcamera_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dlight_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dobject_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dscatter_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dscene_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dsurface_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qabstract3dgraph_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dinputhandler_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qabstract3dinputhandler_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/qtouch3dinputhandler_wrapper.cpp
+${QtDataVisualization_GEN_DIR}/q3dtheme_wrapper.cpp
+# module is always needed
+${QtDataVisualization_GEN_DIR}/qtdatavisualization_module_wrapper.cpp
+)
+
+set(QtDataVisualization_include_dirs ${QtDataVisualization_SOURCE_DIR}
+ ${QtDataVisualization_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}DataVisualization_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR})
+
+set(QtDataVisualization_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}DataVisualization_LIBRARIES})
+
+set(QtDataVisualization_deps QtCore QtGui)
+
+create_pyside_module(NAME QtDataVisualization
+ INCLUDE_DIRS QtDataVisualization_include_dirs
+ LIBRARIES QtDataVisualization_libraries
+ DEPS QtDataVisualization_deps
+ TYPESYSTEM_PATH QtDataVisualization_SOURCE_DIR
+ SOURCES QtDataVisualization_SRC
+ STATIC_SOURCES QtDataVisualization_src)
+
+install(FILES ${pyside6_SOURCE_DIR}/qtdatavisualization_helper.h
+ DESTINATION include/PySide6/QtDataVisualization)
diff --git a/sources/pyside6/PySide6/QtDataVisualization/qtdatavisualization_helper.cpp b/sources/pyside6/PySide6/QtDataVisualization/qtdatavisualization_helper.cpp
new file mode 100644
index 000000000..8ad31a77a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDataVisualization/qtdatavisualization_helper.cpp
@@ -0,0 +1,97 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qtdatavisualization_helper.h"
+
+#include <sbknumpyview.h>
+
+#include <QtCore/QDebug>
+
+namespace QtDataVisualizationHelper {
+
+template <class T>
+static void populateArray(double xStart, double deltaX, double zStart, double deltaZ,
+ qsizetype xSize, qsizetype zSize, qsizetype zStrideBytes,
+ const T *data, QSurfaceDataArray *result)
+{
+ result->reserve(zSize);
+ const qsizetype zStride = zStrideBytes / sizeof(T);
+ double z = zStart;
+ for (qsizetype zi = 0; zi < zSize; ++zi) {
+ auto *row = new QSurfaceDataRow;
+ row->reserve(xSize);
+ result->append(row);
+
+ double x = xStart;
+ auto *rowDataEnd = data + xSize;
+ for (auto *d = data; d < rowDataEnd; ++d) {
+ row->append(QSurfaceDataItem(QVector3D(x, *d, z)));
+ x += deltaX;
+ }
+
+ data += zStride;
+ z += deltaZ;
+ }
+}
+
+QSurfaceDataArray *surfaceDataFromNp(double xStart, double deltaX, double zStart, double deltaZ,
+ PyObject *pyData)
+{
+ static const char funcName[] = "QSurfaceDataProxy.resetArrayNp";
+
+ auto *result = new QSurfaceDataArray;
+
+ auto view = Shiboken::Numpy::View::fromPyObject(pyData);
+ if (!view) {
+ PyErr_Format(PyExc_TypeError, "Invalid array passed to %s", funcName);
+ return result;
+ }
+ if (view.ndim != 2) {
+ PyErr_Format(PyExc_TypeError, "%s expects a 2 dimensional array (%d)", view.ndim);
+ return result;
+ }
+
+ const qsizetype zSize = view.dimensions[0];
+ const qsizetype xSize = view.dimensions[1];
+ if (zSize == 0 || xSize == 0)
+ return result;
+
+ switch (view.type) {
+ case Shiboken::Numpy::View::Int16:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const int16_t *>(view.data), result);
+ break;
+ case Shiboken::Numpy::View::Unsigned16:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const uint16_t *>(view.data), result);
+ break;
+ case Shiboken::Numpy::View::Int:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const int *>(view.data), result);
+ break;
+ case Shiboken::Numpy::View::Unsigned:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const unsigned *>(view.data), result);
+ break;
+ case Shiboken::Numpy::View::Int64:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const int64_t *>(view.data), result);
+ break;
+ case Shiboken::Numpy::View::Unsigned64:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const uint64_t *>(view.data), result);
+ break;
+ case Shiboken::Numpy::View::Float:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const float *>(view.data), result);
+ break;
+ case Shiboken::Numpy::View::Double:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const double *>(view.data), result);
+
+ break;
+ }
+ return result;
+}
+
+} // namespace QtDataVisualizationHelper
diff --git a/sources/pyside6/PySide6/QtDataVisualization/typesystem_datavisualization.xml b/sources/pyside6/PySide6/QtDataVisualization/typesystem_datavisualization.xml
new file mode 100644
index 000000000..70014e3dc
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDataVisualization/typesystem_datavisualization.xml
@@ -0,0 +1,476 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtDataVisualization"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+
+ <extra-includes>
+ <include file-name="qtdatavisualization_helper.h" location="global"/>
+ </extra-includes>
+
+ <load-typesystem name="templates/datavisualization_common.xml" generate="no" />
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no" />
+
+ <function signature="qDefaultSurfaceFormat(bool)"/>
+
+ <primitive-type name="QBarDataArray">
+ <include file-name="qbardataproxy.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="cppqlistofptrtoqlists_to_py_conversion">
+ <replace from="%INTYPE_0" to="QBarDataItem"/>
+ </insert-template>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="py_to_cppqlistofptrtoqlists_conversion">
+ <replace from="%OUTTYPE_0" to="QBarDataItem"/>
+ </insert-template>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="QSurfaceDataArray">
+ <include file-name="qsurfacedataproxy.h" location="global"/>
+ <conversion-rule>
+ <native-to-target>
+ <insert-template name="cppqlistofptrtoqlists_to_py_conversion">
+ <replace from="%INTYPE_0" to="QSurfaceDataItem"/>
+ </insert-template>
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="PySequence">
+ <insert-template name="py_to_cppqlistofptrtoqlists_conversion">
+ <replace from="%OUTTYPE_0" to="QSurfaceDataItem"/>
+ </insert-template>
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <object-type name="QAbstract3DAxis">
+ <enum-type name="AxisOrientation"/>
+ <enum-type name="AxisType"/>
+ </object-type>
+ <object-type name="QCategory3DAxis"/>
+ <object-type name="QLogValue3DAxisFormatter"/>
+ <object-type name="QValue3DAxis">
+ <modify-function signature="setFormatter(QValue3DAxisFormatter *)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QValue3DAxisFormatter">
+ <inject-code class="native" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="qvalue3daxisformatter-friend"/>
+ <modify-function signature="createNewInstance() const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="populateCopy(QValue3DAxisFormatter&amp;)const">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <!-- PYSIDE-2025: gridPositions(), labelPositions(), labelStrings() return
+ non-const-references to lists for modifications. Add setters for them. -->
+ <add-function signature="setGridPositions(const QList&lt;float&gt;&amp;@grid_positions@)">
+ <inject-documentation format="target" mode="append">
+ Sets the normalized grid line positions to ``grid_positions``.
+ </inject-documentation>
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="qvalue3daxisformatter-setgridpositions"/>
+ </add-function>
+ <add-function signature="setLabelPositions(const QList&lt;float&gt;&amp;@label_positions@)">
+ <inject-documentation format="target" mode="append">
+ Sets the normalized label positions to ``label_positions``.
+ </inject-documentation>
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="qvalue3daxisformatter-setlabelpositions"/>
+ </add-function>
+ <add-function signature="setLabelStrings(const QStringList&amp;@label_strings@)">
+ <inject-documentation format="target" mode="append">
+ Sets the label strings to ``label_strings``.
+ </inject-documentation>
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="qvalue3daxisformatter-setlabelstrings"/>
+ </add-function>
+ </object-type>
+ <object-type name="QAbstract3DSeries">
+ <enum-type name="Mesh"/>
+ <enum-type name="SeriesType"/>
+ </object-type>
+ <object-type name="QAbstractDataProxy">
+ <enum-type name="DataType"/>
+ </object-type>
+ <object-type name="QBar3DSeries">
+ <modify-function signature="setDataProxy(QBarDataProxy*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="QBarDataItem"/>
+ <object-type name="QBarDataProxy">
+ <modify-function signature="resetArray(QBarDataArray*)" remove="all"/>
+ <add-function signature="resetArray(const QBarDataArray&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-resetarray"/>
+ </add-function>
+ <modify-function signature="resetArray(QBarDataArray*,const QStringList&amp;,const QStringList&amp;)"
+ remove="all"/>
+ <add-function signature="resetArray(const QBarDataArray&amp;,const QStringList&amp;,const QStringList&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-resetarray2"/>
+ </add-function>
+ <modify-function signature="resetArray(QBarDataArray*,const QStringList&amp;,const QStringList&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- PYSIDE-1438: Replace all add/set/insertRow() taking a 'QList*' by overloads
+ taking 'const QList &' since an allocated list needs to be passed. -->
+ <modify-function signature="addRow(QList&lt;QBarDataItem&gt;*)" remove="all"/>
+ <add-function signature="addRow(const QList&lt;QBarDataItem&gt;&amp;)" return-type="int">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-addrow"/>
+ </add-function>
+ <modify-function signature="addRow(QList&lt;QBarDataItem&gt;*,const QString&amp;)" remove="all"/>
+ <add-function signature="addRow(const QList&lt;QBarDataItem&gt;&amp;,const QString&amp;)"
+ return-type="int">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-addrow-string"/>
+ </add-function>
+
+ <modify-function signature="insertRow(int,QList&lt;QBarDataItem&gt;*)" remove="all"/>
+ <add-function signature="insertRow(int,const QList&lt;QBarDataItem&gt;&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-insertrow"/>
+ </add-function>
+ <modify-function signature="insertRow(int,QList&lt;QBarDataItem&gt;*,const QString&amp;)" remove="all"/>
+ <add-function signature="insertRow(int,const QList&lt;QBarDataItem&gt;&amp;, const QString&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-insertrow-string"/>
+ </add-function>
+
+ <modify-function signature="setRow(int,QList&lt;QBarDataItem&gt;*)" remove="all"/>
+ <add-function signature="setRow(int,const QList&lt;QBarDataItem&gt;&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-setrow"/>
+ </add-function>
+ <modify-function signature="setRow(int,QList&lt;QBarDataItem&gt;*,const QString&amp;)" remove="all"/>
+ <add-function signature="setRow(int,const QList&lt;QBarDataItem&gt;&amp;,const QString&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-setrow-string"/>
+ </add-function>
+
+ <modify-function signature="addRows(const QBarDataArray&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRows(const QBarDataArray&amp;, const QStringList&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRows(int, const QBarDataArray&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRows(int, const QBarDataArray&amp;, const QStringList&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setRows(int, const QBarDataArray&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setRows(int, const QBarDataArray&amp;, const QStringList&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QCustom3DItem"/>
+ <object-type name="QCustom3DLabel"/>
+ <object-type name="QCustom3DVolume">
+ <modify-function signature="setTextureData(QList&lt;uchar&gt;*)" remove="all"/>
+ <add-function signature="setTextureData(const QList&lt;uchar&gt;&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="qcustom3dvolume-settexturedata"/>
+ </add-function>
+ </object-type>
+ <object-type name="QHeightMapSurfaceDataProxy"/>
+ <object-type name="QItemModelBarDataProxy">
+ <enum-type name="MultiMatchBehavior"/>
+ </object-type>
+ <object-type name="QItemModelScatterDataProxy"/>
+ <object-type name="QItemModelSurfaceDataProxy">
+ <enum-type name="MultiMatchBehavior"/>
+ </object-type>
+ <object-type name="QScatter3DSeries">
+ <modify-function signature="setDataProxy(QScatterDataProxy*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="QScatterDataItem"/>
+ <object-type name="QScatterDataProxy">
+ <modify-function signature="resetArray(QList&lt;QScatterDataItem&gt;*)"
+ remove="all"/>
+ <add-function signature="resetArray(QList&lt;QScatterDataItem&gt;*)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="scatterdataproxy-resetarray"/>
+ </add-function>
+ <modify-function signature="addItem(const QScatterDataItem&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addItems(const QList&lt;QScatterDataItem&gt;&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertItem(int, const QScatterDataItem&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertItems(int, const QList&lt;QScatterDataItem&gt;&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItem(int, const QScatterDataItem&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItems(int, const QList&lt;QScatterDataItem&gt;&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QSurface3DSeries">
+ <enum-type name="DrawFlag" flags="DrawFlags"/>
+ <modify-function signature="QSurface3DSeries(QSurfaceDataProxy*,QObject*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setDataProxy(QSurfaceDataProxy*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="QSurfaceDataItem"/>
+ <object-type name="QSurfaceDataProxy">
+ <inject-code class="native" position="beginning">
+ #include &lt;sbknumpycheck.h&gt;
+ #include &lt;qtdatavisualization_helper.h&gt;
+ </inject-code>
+ <!-- PYSIDE-1438: Replace all add/set/insertRow() taking a 'QList*' by overloads
+ taking 'const QList &' since an allocated list needs to be passed. -->
+ <modify-function signature="addRow(QList&lt;QSurfaceDataItem&gt;*)" remove="all"/>
+ <add-function signature="addRow(const QList&lt;QSurfaceDataItem&gt;&amp;)" return-type="int">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-addrow"/>
+ </add-function>
+
+ <modify-function signature="insertRow(int,QList&lt;QSurfaceDataItem&gt;*)" remove="all"/>
+ <add-function signature="insertRow(int,const QList&lt;QSurfaceDataItem&gt;&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-insertrow"/>
+ </add-function>
+
+ <modify-function signature="setRow(int,QList&lt;QSurfaceDataItem&gt;*)" remove="all"/>
+ <add-function signature="setRow(int,const QList&lt;QSurfaceDataItem&gt;&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-setrow"/>
+ </add-function>
+
+ <modify-function signature="resetArray(QSurfaceDataArray*)" remove="all"/>
+ <add-function signature="resetArray(const QSurfaceDataArray&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="dataproxy-resetarray"/>
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </add-function>
+
+ <add-function signature="resetArrayNp(double@x@,double@deltaX@,double@z@,double@deltaZ@,PyArrayObject*@data@)">
+ <inject-code file="../glue/qtdatavisualization.cpp"
+ snippet="qsurfacedataproxy-resetarraynp"/>
+ <inject-documentation format="target" mode="append">
+ Populates the data from a 2 dimensional numpy array containing the y
+ values for a range starting a ``x``, ``z`` with steps of ``deltaX``,
+ ``deltaZ``, respectively.
+ </inject-documentation>
+ </add-function>
+
+ </object-type>
+ <object-type name="Q3DBars">
+ <modify-function signature="addAxis(QAbstract3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseAxis(QAbstract3DAxis*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setColumnAxis(QCategory3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setRowAxis(QCategory3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="Q3DCamera">
+ <enum-type name="CameraPreset"/>
+ </object-type>
+ <object-type name="Q3DLight"/>
+ <object-type name="Q3DObject"/>
+ <object-type name="Q3DScatter">
+ <modify-function signature="addAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setAxisX(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisY(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisZ(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="Q3DScene"/>
+ <object-type name="Q3DSurface">
+ <modify-function signature="addAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setAxisX(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisY(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisZ(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstract3DGraph">
+ <enum-type name="ElementType"/>
+ <enum-type name="OptimizationHint" flags="OptimizationHints"/>
+ <enum-type name="SelectionFlag" flags="SelectionFlags"/>
+ <enum-type name="ShadowQuality"/>
+ <modify-function signature="addCustomItem(QCustom3DItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addInputHandler(QAbstract3DInputHandler*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addTheme(Q3DTheme*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseCustomItem(QCustom3DItem*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="releaseInputHandler(QAbstract3DInputHandler*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="releaseTheme(Q3DTheme*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setActiveInputHandler(QAbstract3DInputHandler*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setActiveTheme(Q3DTheme*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="Q3DInputHandler"/>
+ <object-type name="QAbstract3DInputHandler">
+ <enum-type name="InputView"/>
+ </object-type>
+ <object-type name="QTouch3DInputHandler"/>
+ <object-type name="Q3DTheme">
+ <enum-type name="ColorStyle"/>
+ <enum-type name="Theme"/>
+ </object-type>
+ <extra-includes>
+ <include file-name="qutils.h" location="global"/>
+ </extra-includes>
+
+ <!-- QtQml/QtNetwork are pulled in via QtDataVisualizationDepends. -->
+ <suppress-warning text="^Scoped enum 'Q(Ocsp)|(Dtls)|(Qml).*' does not have a type entry.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtDesigner/CMakeLists.txt b/sources/pyside6/PySide6/QtDesigner/CMakeLists.txt
new file mode 100644
index 000000000..e91532b87
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/CMakeLists.txt
@@ -0,0 +1,70 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtDesigner)
+
+qt_wrap_cpp(QtDesigner_static_src "${pyside6_SOURCE_DIR}/qpydesignerextensions.h")
+list(APPEND QtDesigner_static_src "${QtDesigner_SOURCE_DIR}/qpydesignercustomwidgetcollection.cpp")
+
+set(QtDesigner_SRC
+${QtDesigner_GEN_DIR}/qabstractextensionfactory_wrapper.cpp
+${QtDesigner_GEN_DIR}/qabstractextensionmanager_wrapper.cpp
+${QtDesigner_GEN_DIR}/qabstractformbuilder_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesigneractioneditorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignercontainerextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignercustomwidgetcollectioninterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignercustomwidgetinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerdnditeminterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerdynamicpropertysheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformeditorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowcursorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowmanagerinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerformwindowtoolinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignermembersheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerobjectinspectorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerpropertyeditorinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerpropertysheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignertaskmenuextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerwidgetboxinterface_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerwidgetboxinterface_category_wrapper.cpp
+${QtDesigner_GEN_DIR}/qdesignerwidgetboxinterface_widget_wrapper.cpp
+${QtDesigner_GEN_DIR}/qextensionmanager_wrapper.cpp
+${QtDesigner_GEN_DIR}/qextensionfactory_wrapper.cpp
+${QtDesigner_GEN_DIR}/qformbuilder_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignercustomwidgetcollection_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignercontainerextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignermembersheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignerpropertysheetextension_wrapper.cpp
+${QtDesigner_GEN_DIR}/qpydesignertaskmenuextension_wrapper.cpp
+
+# module is always needed
+${QtDesigner_GEN_DIR}/qtdesigner_module_wrapper.cpp
+)
+
+configure_file("${QtDesigner_SOURCE_DIR}/QtDesigner_global.pre.h.in"
+ "${QtDesigner_BINARY_DIR}/QtDesigner_global.pre.h" @ONLY)
+configure_file("${QtDesigner_SOURCE_DIR}/QtDesigner_global.post.h.in"
+ "${QtDesigner_BINARY_DIR}/QtDesigner_global.post.h" @ONLY)
+
+set(QtDesigner_include_dirs ${QtDesigner_SOURCE_DIR}
+ ${QtDesigner_BINARY_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+set(QtDesigner_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Designer_LIBRARIES})
+
+set(QtDesigner_deps QtWidgets)
+
+create_pyside_module(NAME QtDesigner
+ INCLUDE_DIRS QtDesigner_include_dirs
+ LIBRARIES QtDesigner_libraries
+ DEPS QtDesigner_deps
+ TYPESYSTEM_PATH QtDesigner_SOURCE_DIR
+ SOURCES QtDesigner_SRC
+ STATIC_SOURCES QtDesigner_static_src
+ TYPESYSTEM_NAME ${QtDesigner_BINARY_DIR}/typesystem_designer.xml)
+
+install(FILES ${pyside6_SOURCE_DIR}/qpydesignerextensions.h DESTINATION include/PySide6/QtDesigner)
diff --git a/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in
new file mode 100644
index 000000000..e5537a6cf
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.post.h.in
@@ -0,0 +1 @@
+#include <qpydesignerextensions.h>
diff --git a/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in
new file mode 100644
index 000000000..195acbaa7
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/QtDesigner_global.pre.h.in
@@ -0,0 +1,3 @@
+// Not included by the module header
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
diff --git a/sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp b/sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp
new file mode 100644
index 000000000..31f8ec152
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp
@@ -0,0 +1,223 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <qpydesignerextensions.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QVariant>
+
+#include <shiboken.h>
+#include <bindingmanager.h>
+
+QT_BEGIN_NAMESPACE
+
+static QString pyStringToQString(PyObject *s)
+{
+ const char *utf8 = _PepUnicode_AsString(s);
+ return utf8 ? QString::fromUtf8(utf8) : QString();
+}
+
+// Return a string from keyword argument dict
+static QString kwdString(PyObject *kwds, PyObject *key)
+{
+ QString result;
+ if (PyDict_Contains(kwds, key)) {
+ if (auto value = PyDict_GetItem(kwds, key))
+ result = pyStringToQString(value);
+ }
+ return result;
+}
+
+// Return a bool from keyword argument dict
+static bool kwdBool(PyObject *kwds, PyObject *key)
+{
+ bool result = false;
+ if (PyDict_Contains(kwds, key)) {
+ if (auto value = PyDict_GetItem(kwds, key))
+ result = PyObject_IsTrue(value);
+ }
+ return result;
+}
+
+// PyDesignerCustomWidget: A custom widget registered by type
+// (similar to what is done by QUiLoader.registerCustomWidget()).
+class PyDesignerCustomWidget : public QDesignerCustomWidgetInterface
+{
+public:
+ explicit PyDesignerCustomWidget(PyObject *pyTypeObject) :
+ m_pyTypeObject(pyTypeObject) {}
+
+ QString name() const override;
+ QString group() const override { return m_group; }
+ QString toolTip() const override { return m_toolTip; }
+ QString whatsThis() const override { return toolTip(); }
+ QString includeFile() const override { return m_includeFile; }
+ QIcon icon() const override { return m_icon; }
+ bool isContainer() const override { return m_container; }
+
+ QWidget *createWidget(QWidget *parent) override;
+
+ bool isInitialized() const override { return m_core != nullptr; }
+ void initialize(QDesignerFormEditorInterface *core) override;
+
+ QString domXml() const override { return m_domXml; }
+
+ void setGroup(const QString &group) { m_group = group; }
+ void setToolTip(const QString &toolTip) { m_toolTip = toolTip; }
+ void setIncludeFile(const QString &includeFile) { m_includeFile = includeFile; }
+ void setIcon(const QIcon &icon) { m_icon = icon; }
+ void setDomXml(const QString &domXml) { m_domXml = domXml; }
+ void setContainer(bool container) { m_container = container; }
+
+private:
+ const char *utf8Name() const;
+
+ QDesignerFormEditorInterface *m_core = nullptr;
+ QString m_group;
+ QString m_toolTip;
+ QString m_includeFile;
+ QIcon m_icon;
+ QString m_domXml;
+ PyObject *m_pyTypeObject = nullptr;
+ bool m_container = false;
+};
+
+const char *PyDesignerCustomWidget::utf8Name() const
+{
+ return reinterpret_cast<PyTypeObject *>(m_pyTypeObject)->tp_name;
+}
+
+QString PyDesignerCustomWidget::name() const
+{
+ return QString::fromUtf8(utf8Name());
+}
+
+QWidget *PyDesignerCustomWidget::createWidget(QWidget *parent)
+{
+ // This is a copy of the similar function used for QUiLoader
+ // (see sources/pyside6/plugins/uitools/customwidget.cpp)
+ // Create a python instance and return cpp object
+ PyObject *pyParent = nullptr;
+ bool unknownParent = false;
+ if (parent) {
+ pyParent = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(parent));
+ if (pyParent) {
+ Py_INCREF(pyParent);
+ } else {
+ static Shiboken::Conversions::SpecificConverter converter("QWidget*");
+ pyParent = converter.toPython(&parent);
+ unknownParent = true;
+ }
+ } else {
+ Py_INCREF(Py_None);
+ pyParent = Py_None;
+ }
+
+ Shiboken::AutoDecRef pyArgs(PyTuple_New(1));
+ PyTuple_SET_ITEM(pyArgs, 0, pyParent); // tuple will keep pyParent reference
+
+ // Call python constructor
+ auto result = reinterpret_cast<SbkObject *>(PyObject_CallObject(m_pyTypeObject, pyArgs));
+ if (!result) {
+ qWarning("Unable to create a Python custom widget of type \"%s\".", utf8Name());
+ PyErr_Print();
+ return nullptr;
+ }
+
+ if (unknownParent) // if parent does not exist in python, transfer the ownership to cpp
+ Shiboken::Object::releaseOwnership(result);
+ else
+ Shiboken::Object::setParent(pyParent, reinterpret_cast<PyObject *>(result));
+
+ return reinterpret_cast<QWidget *>(Shiboken::Object::cppPointer(result, Py_TYPE(result)));
+}
+
+void PyDesignerCustomWidget::initialize(QDesignerFormEditorInterface *core)
+{
+ m_core = core;
+}
+
+// QPyDesignerCustomWidgetCollection: A QDesignerCustomWidgetCollectionInterface
+// implementation that is instantiated as a singleton and stored as a dynamic
+// property of QCoreApplication. The PySide Designer plugin retrieves it from
+// there. Provides static convenience functions for registering types
+// or adding QDesignerCustomWidgetInterface instances.
+
+static QPyDesignerCustomWidgetCollection *collectionInstance = nullptr;
+
+static const char propertyName[] = "__qt_PySideCustomWidgetCollection";
+
+static void cleanup()
+{
+ delete collectionInstance;
+ collectionInstance = nullptr;
+}
+
+QPyDesignerCustomWidgetCollection::QPyDesignerCustomWidgetCollection() = default;
+
+QPyDesignerCustomWidgetCollection::~QPyDesignerCustomWidgetCollection()
+{
+ qDeleteAll(m_customWidgets);
+}
+
+QList<QDesignerCustomWidgetInterface *> QPyDesignerCustomWidgetCollection::customWidgets() const
+{
+ return m_customWidgets;
+}
+
+QPyDesignerCustomWidgetCollection *QPyDesignerCustomWidgetCollection::instance()
+{
+ if (collectionInstance == nullptr) {
+ collectionInstance = new QPyDesignerCustomWidgetCollection();
+ if (auto coreApp = QCoreApplication::instance()) {
+ QDesignerCustomWidgetCollectionInterface *c = collectionInstance;
+ coreApp->setProperty(propertyName, QVariant::fromValue<void *>(c));
+ qAddPostRoutine(cleanup);
+ } else {
+ qWarning("%s: Cannot find QCoreApplication instance.", Q_FUNC_INFO);
+ }
+ }
+ return collectionInstance;
+}
+
+// Register a custom widget by type and optional keyword arguments providing
+// the parameters of QDesignerCustomWidgetInterface.
+bool QPyDesignerCustomWidgetCollection::_registerCustomWidgetHelper(PyObject *typeArg, PyObject *kwds)
+{
+ if (!PyType_Check(typeArg)) {
+ PyErr_SetString(PyExc_TypeError, "registerCustomWidget() requires a type argument.");
+ return false;
+ }
+
+ auto pyCustomWidget = new PyDesignerCustomWidget(typeArg);
+
+ static PyObject *xmlKey = Shiboken::String::createStaticString("xml");
+ pyCustomWidget->setDomXml(kwdString(kwds, xmlKey));
+ static PyObject *toolTipKey = Shiboken::String::createStaticString("tool_tip");
+ pyCustomWidget->setToolTip(kwdString(kwds, toolTipKey));
+ static PyObject *groupKey = Shiboken::String::createStaticString("group");
+ pyCustomWidget->setGroup(kwdString(kwds, groupKey));
+ static PyObject *moduleKey = Shiboken::String::createStaticString("module");
+ pyCustomWidget->setIncludeFile(kwdString(kwds, moduleKey));
+ static PyObject *containerKey = Shiboken::String::createStaticString("container");
+ pyCustomWidget->setContainer(kwdBool(kwds, containerKey));
+ static PyObject *iconKey = Shiboken::String::createStaticString("icon");
+ const QString iconPath = kwdString(kwds, iconKey);
+ if (!iconPath.isEmpty()) {
+ QIcon icon(iconPath);
+ if (icon.availableSizes().isEmpty())
+ qWarning("%s: Cannot load icon from '%s'.", __FUNCTION__, qPrintable(iconPath));
+ else
+ pyCustomWidget->setIcon(icon);
+ }
+
+ addCustomWidget(pyCustomWidget);
+ return true;
+}
+
+void QPyDesignerCustomWidgetCollection::addCustomWidget(QDesignerCustomWidgetInterface *c)
+{
+ instance()->m_customWidgets.append(c);
+}
+
+QT_END_NAMESPACE
diff --git a/sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml b/sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml
new file mode 100644
index 000000000..7d37cbddf
--- /dev/null
+++ b/sources/pyside6/PySide6/QtDesigner/typesystem_designer.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtDesigner"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <rejection class="qdesigner_internal"/>
+
+ <object-type name="QAbstractExtensionFactory"/>
+ <object-type name="QAbstractExtensionManager"/>
+ <object-type name="QAbstractFormBuilder"/>
+ <object-type name="QDesignerActionEditorInterface"/>
+ <object-type name="QDesignerContainerExtension"/>
+ <object-type name="QDesignerCustomWidgetCollectionInterface"/>
+ <object-type name="QDesignerCustomWidgetInterface">
+ <modify-function signature="createWidget(QWidget*)">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <!-- QDesignerDnDItemInterface has abstract functions dealing with the
+ unexposed DomUI classes, we cannot generate a wrapper. -->
+ <object-type name="QDesignerDnDItemInterface" disable-wrapper="yes">
+ <enum-type name="DropType"/>
+ </object-type>
+ <object-type name="QDesignerDynamicPropertySheetExtension"/>
+ <object-type name="QDesignerFormEditorInterface"/>
+ <object-type name="QDesignerFormWindowCursorInterface">
+ <enum-type name="MoveMode"/>
+ <enum-type name="MoveOperation"/>
+ </object-type>
+ <!-- QDesignerFormWindowInterface has abstract functions dealing with private
+ class QtResourceSet, so, we cannot generate a wrapper. -->
+ <object-type name="QDesignerFormWindowInterface" disable-wrapper="yes">
+ <enum-type name="FeatureFlag" flags="Feature"/>
+ <enum-type name="ResourceFileSaveMode"/>
+ </object-type>
+ <object-type name="QDesignerFormWindowManagerInterface">
+ <enum-type name="Action"/>
+ <enum-type name="ActionGroup"/>
+ </object-type>
+ <object-type name="QDesignerFormWindowToolInterface"/>
+ <object-type name="QDesignerMemberSheetExtension"/>
+ <object-type name="QDesignerObjectInspectorInterface"/>
+ <object-type name="QDesignerPropertyEditorInterface"/>
+ <object-type name="QDesignerPropertySheetExtension"/>
+ <object-type name="QDesignerTaskMenuExtension"/>
+ <object-type name="QDesignerWidgetBoxInterface">
+ <value-type name="Category">
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="Widget">
+ <enum-type name="Type"/>
+ </value-type>
+ </object-type>
+ <object-type name="QExtensionManager"/>
+ <object-type name="QExtensionFactory"/>
+ <object-type name="QFormBuilder"/>
+ <object-type name="QPyDesignerCustomWidgetCollection" disable-wrapper="yes">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ <modify-function signature="addCustomWidget(QDesignerCustomWidgetInterface*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <!-- Force VARARGS/keyword arguments by giving a default parameters -->
+ <add-function signature='registerCustomWidget(PyObject*@customWidgetType@,const QString&amp; @xml@ = {}, const QString&amp; @tool_tip@ = {}, const QString&amp; @group@ = {}, const QString&amp; @module@ = {}, bool @container@ = false, const QString&amp; @icon@ = {})'
+ return-type='void' static='true'>
+ <inject-code class="target" position="beginning" file="../glue/qtdesigner.cpp" snippet="qtdesigner-registercustomwidget"/>
+ </add-function>
+ </object-type>
+ <object-type name="QPyDesignerContainerExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QPyDesignerMemberSheetExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QPyDesignerPropertySheetExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QPyDesignerTaskMenuExtension">
+ <extra-includes>
+ <include file-name="qpydesignerextensions.h" location="global"/>
+ </extra-includes>
+ </object-type>
+
+ <!-- Suppress all QString */int * out parameters -->
+ <suppress-warning text="^There's no user provided way.*handle the primitive type.*$"/>
+ <suppress-warning text="^.*skipping abstract function.*QtResourceSet.*$"/>
+ <suppress-warning text="^.*skipping abstract function.*DomUI.*$"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtGraphs/CMakeLists.txt b/sources/pyside6/PySide6/QtGraphs/CMakeLists.txt
new file mode 100644
index 000000000..59cef220b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGraphs/CMakeLists.txt
@@ -0,0 +1,100 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtGraphs)
+
+set(QtGraphs_DROPPED_ENTRIES)
+
+list(APPEND QtGraphs_src "${QtGraphs_SOURCE_DIR}/qtgraphs_helper.cpp")
+
+set(QtGraphs_SRC
+# 3D
+${QtGraphs_GEN_DIR}/qabstract3daxis_wrapper.cpp
+${QtGraphs_GEN_DIR}/qcategory3daxis_wrapper.cpp
+${QtGraphs_GEN_DIR}/qlogvalue3daxisformatter_wrapper.cpp
+${QtGraphs_GEN_DIR}/qvalue3daxis_wrapper.cpp
+${QtGraphs_GEN_DIR}/qvalue3daxisformatter_wrapper.cpp
+${QtGraphs_GEN_DIR}/qabstract3dseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qabstractdataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/qbar3dseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qbardataitem_wrapper.cpp
+${QtGraphs_GEN_DIR}/qbardataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/qcustom3ditem_wrapper.cpp
+${QtGraphs_GEN_DIR}/qcustom3dlabel_wrapper.cpp
+${QtGraphs_GEN_DIR}/qcustom3dvolume_wrapper.cpp
+${QtGraphs_GEN_DIR}/qheightmapsurfacedataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/qitemmodelbardataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/qitemmodelscatterdataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/qitemmodelsurfacedataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/qscatter3dseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qscatterdataitem_wrapper.cpp
+${QtGraphs_GEN_DIR}/qscatterdataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/qsurface3dseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qsurfacedataitem_wrapper.cpp
+${QtGraphs_GEN_DIR}/qsurfacedataproxy_wrapper.cpp
+${QtGraphs_GEN_DIR}/q3dbars_wrapper.cpp
+${QtGraphs_GEN_DIR}/q3dscatter_wrapper.cpp
+${QtGraphs_GEN_DIR}/q3dscene_wrapper.cpp
+${QtGraphs_GEN_DIR}/q3dsurface_wrapper.cpp
+${QtGraphs_GEN_DIR}/qabstract3dgraph_wrapper.cpp
+${QtGraphs_GEN_DIR}/q3dinputhandler_wrapper.cpp
+${QtGraphs_GEN_DIR}/qabstract3dinputhandler_wrapper.cpp
+${QtGraphs_GEN_DIR}/qtouch3dinputhandler_wrapper.cpp
+${QtGraphs_GEN_DIR}/q3dtheme_wrapper.cpp
+# 2D
+${QtGraphs_GEN_DIR}/qbarcategoryaxis_wrapper.cpp
+${QtGraphs_GEN_DIR}/qabstractaxis_wrapper.cpp
+${QtGraphs_GEN_DIR}/qvalueaxis_wrapper.cpp
+${QtGraphs_GEN_DIR}/qabstractbarseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qbarseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qbarset_wrapper.cpp
+${QtGraphs_GEN_DIR}/qlineseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qabstractseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qscatterseries_wrapper.cpp
+${QtGraphs_GEN_DIR}/qgraphtheme_wrapper.cpp
+${QtGraphs_GEN_DIR}/qseriestheme_wrapper.cpp
+${QtGraphs_GEN_DIR}/qxyseries_wrapper.cpp
+# module is always needed
+${QtGraphs_GEN_DIR}/qtgraphs_module_wrapper.cpp
+)
+
+set(QtGraphs_include_dirs ${QtGraphs_SOURCE_DIR}
+ ${QtGraphs_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}QtNetwork_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}QuickWidgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Graphs_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick3D_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuick_GEN_DIR}
+ ${QtQuickWidgets_GEN_DIR}
+ ${QtQuick3D_GEN_DIR})
+
+set(QtGraphs_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Graphs_LIBRARIES})
+
+set(QtGraphs_deps QtCore QtNetwork QtGui QtWidgets QtQml QtQuick QtQuickWidgets QtQuick3D)
+
+check_qt_opengl("Graphs" QtGraphs_include_dirs QtGraphs_deps
+ QtGraphs_DROPPED_ENTRIES)
+
+create_pyside_module(NAME QtGraphs
+ INCLUDE_DIRS QtGraphs_include_dirs
+ LIBRARIES QtGraphs_libraries
+ DEPS QtGraphs_deps
+ TYPESYSTEM_PATH QtGraphs_SOURCE_DIR
+ SOURCES QtGraphs_SRC
+ STATIC_SOURCES QtGraphs_src
+ DROPPED_ENTRIES QtGraphs_DROPPED_ENTRIES)
+
+install(FILES ${pyside6_SOURCE_DIR}/qtgraphs_helper.h
+ DESTINATION include/PySide6/QtGraphs)
diff --git a/sources/pyside6/PySide6/QtGraphs/qtgraphs_helper.cpp b/sources/pyside6/PySide6/QtGraphs/qtgraphs_helper.cpp
new file mode 100644
index 000000000..19fe4f818
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGraphs/qtgraphs_helper.cpp
@@ -0,0 +1,97 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qtgraphs_helper.h"
+
+#include <sbknumpyview.h>
+
+#include <QtCore/QDebug>
+
+namespace QtGraphsHelper {
+
+template <class T>
+static void populateArray(double xStart, double deltaX, double zStart, double deltaZ,
+ qsizetype xSize, qsizetype zSize, qsizetype zStrideBytes,
+ const T *data, QSurfaceDataArray *result)
+{
+ result->reserve(zSize);
+ const qsizetype zStride = zStrideBytes / sizeof(T);
+ double z = zStart;
+ for (qsizetype zi = 0; zi < zSize; ++zi) {
+ QSurfaceDataRow row;
+ row.reserve(xSize);
+
+ double x = xStart;
+ auto *rowDataEnd = data + xSize;
+ for (auto *d = data; d < rowDataEnd; ++d) {
+ row.append(QSurfaceDataItem(QVector3D(x, *d, z)));
+ x += deltaX;
+ }
+ result->append(row);
+
+ data += zStride;
+ z += deltaZ;
+ }
+}
+
+QSurfaceDataArray surfaceDataFromNp(double xStart, double deltaX, double zStart, double deltaZ,
+ PyObject *pyData)
+{
+ static const char funcName[] = "QSurfaceDataProxy.resetArrayNp";
+
+ QSurfaceDataArray result;
+
+ auto view = Shiboken::Numpy::View::fromPyObject(pyData);
+ if (!view) {
+ PyErr_Format(PyExc_TypeError, "Invalid array passed to %s", funcName);
+ return result;
+ }
+ if (view.ndim != 2) {
+ PyErr_Format(PyExc_TypeError, "%s expects a 2 dimensional array (%d)", view.ndim);
+ return result;
+ }
+
+ const qsizetype zSize = view.dimensions[0];
+ const qsizetype xSize = view.dimensions[1];
+ if (zSize == 0 || xSize == 0)
+ return result;
+
+ switch (view.type) {
+ case Shiboken::Numpy::View::Int16:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const int16_t *>(view.data), &result);
+ break;
+ case Shiboken::Numpy::View::Unsigned16:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const uint16_t *>(view.data), &result);
+ break;
+ case Shiboken::Numpy::View::Int:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const int *>(view.data), &result);
+ break;
+ case Shiboken::Numpy::View::Unsigned:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const unsigned *>(view.data), &result);
+ break;
+ case Shiboken::Numpy::View::Int64:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const int64_t *>(view.data), &result);
+ break;
+ case Shiboken::Numpy::View::Unsigned64:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const uint64_t *>(view.data), &result);
+ break;
+ case Shiboken::Numpy::View::Float:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const float *>(view.data), &result);
+ break;
+ case Shiboken::Numpy::View::Double:
+ populateArray(xStart, deltaX, zStart, deltaZ, xSize, zSize, view.stride[0],
+ reinterpret_cast<const double *>(view.data), &result);
+
+ break;
+ }
+ return result;
+}
+
+} // namespace QtGraphsHelper
diff --git a/sources/pyside6/PySide6/QtGraphs/typesystem_graphs.xml b/sources/pyside6/PySide6/QtGraphs/typesystem_graphs.xml
new file mode 100644
index 000000000..43e4458be
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGraphs/typesystem_graphs.xml
@@ -0,0 +1,303 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtGraphs"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+
+ <extra-includes>
+ <include file-name="qtgraphs_helper.h" location="global"/>
+ </extra-includes>
+
+ <load-typesystem name="templates/datavisualization_common.xml" generate="no" />
+ <load-typesystem name="QtQuickWidgets/typesystem_quickwidgets.xml" generate="no" />
+
+ <function signature="qDefaultSurfaceFormat(bool)"/>
+
+
+ <object-type name="QAbstract3DAxis">
+ <enum-type name="AxisOrientation"/>
+ <enum-type name="AxisType"/>
+ </object-type>
+ <object-type name="QCategory3DAxis"/>
+ <object-type name="QLogValue3DAxisFormatter"/>
+ <object-type name="QValue3DAxis">
+ <modify-function signature="setFormatter(QValue3DAxisFormatter *)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QValue3DAxisFormatter">
+ <modify-function signature="createNewInstance() const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstract3DSeries">
+ <enum-type name="Mesh"/>
+ <enum-type name="SeriesType"/>
+ </object-type>
+ <object-type name="QAbstractDataProxy">
+ <enum-type name="DataType"/>
+ </object-type>
+ <object-type name="QBar3DSeries">
+ <modify-function signature="setDataProxy(QBarDataProxy*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="QBarDataItem"/>
+ <object-type name="QBarDataProxy">
+ </object-type>
+ <object-type name="QCustom3DItem"/>
+ <object-type name="QCustom3DLabel"/>
+ <object-type name="QCustom3DVolume">
+ <modify-function signature="setTextureData(QList&lt;uchar&gt;*)" remove="all"/>
+ <add-function signature="setTextureData(const QList&lt;uchar&gt;&amp;)">
+ <inject-code class="target" position="beginning" file="../glue/qtdatavisualization.cpp"
+ snippet="qcustom3dvolume-settexturedata"/>
+ </add-function>
+ </object-type>
+ <object-type name="QHeightMapSurfaceDataProxy"/>
+ <object-type name="QItemModelBarDataProxy">
+ <enum-type name="MultiMatchBehavior"/>
+ </object-type>
+ <object-type name="QItemModelScatterDataProxy"/>
+ <object-type name="QItemModelSurfaceDataProxy">
+ <enum-type name="MultiMatchBehavior"/>
+ </object-type>
+ <object-type name="QScatter3DSeries">
+ <modify-function signature="setDataProxy(QScatterDataProxy*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="QScatterDataItem"/>
+ <object-type name="QScatterDataProxy">
+ </object-type>
+ <object-type name="QSurface3DSeries">
+ <enum-type name="DrawFlag" flags="DrawFlags"/>
+ <modify-function signature="QSurface3DSeries(QSurfaceDataProxy*,QObject*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setDataProxy(QSurfaceDataProxy*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="QSurfaceDataItem"/>
+ <object-type name="QSurfaceDataProxy">
+ <inject-code class="native" position="beginning">
+ #include &lt;sbknumpycheck.h&gt;
+ #include &lt;qtgraphs_helper.h&gt;
+ </inject-code>
+ <add-function signature="resetArrayNp(double@x@,double@deltaX@,double@z@,double@deltaZ@,PyArrayObject*@data@)">
+ <inject-code file="../glue/qtgraphs.cpp"
+ snippet="graphs-qsurfacedataproxy-resetarraynp"/>
+ <inject-documentation format="target" mode="append">
+ Populates the data from a 2 dimensional numpy array containing the y
+ values for a range starting a ``x``, ``z`` with steps of ``deltaX``,
+ ``deltaZ``, respectively.
+ </inject-documentation>
+ </add-function>
+
+ </object-type>
+ <object-type name="Q3DBars">
+ <modify-function signature="addAxis(QAbstract3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseAxis(QAbstract3DAxis*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setColumnAxis(QCategory3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setRowAxis(QCategory3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="Q3DScatter">
+ <modify-function signature="addAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setAxisX(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisY(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisZ(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="Q3DScene"/>
+ <object-type name="Q3DSurface">
+ <modify-function signature="addAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseAxis(QValue3DAxis*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setAxisX(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisY(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAxisZ(QValue3DAxis*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstract3DGraph">
+ <enum-type name="ElementType"/>
+ <enum-type name="OptimizationHint" flags="OptimizationHints"/>
+ <enum-type name="RenderingMode"/>
+ <enum-type name="SelectionFlag" flags="SelectionFlags"/>
+ <enum-type name="ShadowQuality"/>
+ <enum-type name="CameraPreset" since="6.7"/>
+ <modify-function signature="addCustomItem(QCustom3DItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addInputHandler(QAbstract3DInputHandler*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addTheme(Q3DTheme*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseCustomItem(QCustom3DItem*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="releaseInputHandler(QAbstract3DInputHandler*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="releaseTheme(Q3DTheme*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
+ </modify-function>
+ <modify-function signature="setActiveInputHandler(QAbstract3DInputHandler*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setActiveTheme(Q3DTheme*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="Q3DInputHandler"/>
+ <object-type name="QAbstract3DInputHandler">
+ <enum-type name="InputView"/>
+ </object-type>
+ <object-type name="QTouch3DInputHandler"/>
+ <object-type name="Q3DTheme">
+ <enum-type name="ColorStyle"/>
+ <enum-type name="Theme"/>
+ </object-type>
+
+ <!-- 2D -->
+ <object-type name="QBarCategoryAxis"/>
+ <object-type name="QAbstractAxis">
+ <enum-type name="AxisType"/>
+ </object-type>
+ <object-type name="QValueAxis"/>
+ <object-type name="QAbstractBarSeries">
+ <enum-type name="LabelsPosition"/>
+ <modify-function signature="append(QBarSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="append(QList&lt;QBarSet*&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insert(int,QBarSet*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="take(QBarSet*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QBarSeries"/>
+ <object-type name="QBarSet"/>
+ <object-type name="QLineSeries"/>
+ <object-type name="QAbstractSeries">
+ <enum-type name="SeriesType"/>
+ </object-type>
+ <object-type name="QScatterSeries"/>
+ <object-type name="QGraphTheme">
+ <enum-type name="ColorTheme"/>
+ </object-type>
+ <object-type name="QSeriesTheme">
+ <enum-type name="SeriesColorTheme"/>
+ </object-type>
+ <object-type name="QXYSeries">
+ </object-type>
+
+ <extra-includes>
+ <include file-name="qutils.h" location="global"/>
+ </extra-includes>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtGui/CMakeLists.txt b/sources/pyside6/PySide6/QtGui/CMakeLists.txt
new file mode 100644
index 000000000..c868b6c88
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/CMakeLists.txt
@@ -0,0 +1,355 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtGui)
+
+qt_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside6_SOURCE_DIR}/qpytextobject.h")
+
+set(QtGui_DROPPED_ENTRIES)
+
+# Exclude sources that have clashing static helper functions named "iterator_..."
+set(QtGui_SRC_UNITY_EXCLUDED_SRC
+ ${QtGui_GEN_DIR}/qtextframe_iterator_wrapper.cpp
+ ${QtGui_GEN_DIR}/qtextblock_iterator_wrapper.cpp
+ ${QtGui_GEN_DIR}/qshaderversion_wrapper.cpp
+)
+
+set_property(SOURCE ${QtGui_SRC_UNITY_EXCLUDED_SRC}
+ PROPERTY SKIP_UNITY_BUILD_INCLUSION ON)
+
+set(QtGui_SRC_RHI
+${QtGui_GEN_DIR}/qrhi_wrapper.cpp
+${QtGui_GEN_DIR}/qrhibuffer_wrapper.cpp
+${QtGui_GEN_DIR}/qrhicolorattachment_wrapper.cpp
+${QtGui_GEN_DIR}/qrhicommandbuffer_wrapper.cpp
+${QtGui_GEN_DIR}/qrhicomputepipeline_wrapper.cpp
+${QtGui_GEN_DIR}/qrhidepthstencilclearvalue_wrapper.cpp
+${QtGui_GEN_DIR}/qrhidriverinfo_wrapper.cpp
+${QtGui_GEN_DIR}/qrhigraphicspipeline_targetblend_wrapper.cpp
+${QtGui_GEN_DIR}/qrhigraphicspipeline_wrapper.cpp
+${QtGui_GEN_DIR}/qrhigraphicspipeline_stencilopstate_wrapper.cpp
+${QtGui_GEN_DIR}/qrhiinitparams_wrapper.cpp
+${QtGui_GEN_DIR}/qrhinativehandles_wrapper.cpp
+${QtGui_GEN_DIR}/qrhinullinitparams_wrapper.cpp
+${QtGui_GEN_DIR}/qrhireadbackdescription_wrapper.cpp
+${QtGui_GEN_DIR}/qrhireadbackresult_wrapper.cpp
+${QtGui_GEN_DIR}/qrhirenderbuffer_wrapper.cpp
+${QtGui_GEN_DIR}/qrhirenderpassdescriptor_wrapper.cpp
+${QtGui_GEN_DIR}/qrhirendertarget_wrapper.cpp
+${QtGui_GEN_DIR}/qrhiresource_wrapper.cpp
+${QtGui_GEN_DIR}/qrhiresourceupdatebatch_wrapper.cpp
+${QtGui_GEN_DIR}/qrhisampler_wrapper.cpp
+${QtGui_GEN_DIR}/qrhiscissor_wrapper.cpp
+${QtGui_GEN_DIR}/qrhishaderresourcebinding_textureandsampler_wrapper.cpp
+${QtGui_GEN_DIR}/qrhishaderresourcebinding_data_storagebufferdata_wrapper.cpp
+${QtGui_GEN_DIR}/qrhishaderresourcebinding_data_storageimagedata_wrapper.cpp
+${QtGui_GEN_DIR}/qrhishaderresourcebinding_data_wrapper.cpp
+${QtGui_GEN_DIR}/qrhishaderresourcebinding_wrapper.cpp
+${QtGui_GEN_DIR}/qrhishaderresourcebindings_wrapper.cpp
+${QtGui_GEN_DIR}/qrhishaderstage_wrapper.cpp
+${QtGui_GEN_DIR}/qrhistats_wrapper.cpp
+${QtGui_GEN_DIR}/qrhiswapchain_wrapper.cpp
+${QtGui_GEN_DIR}/qrhiswapchainrendertarget_wrapper.cpp
+${QtGui_GEN_DIR}/qrhitexture_wrapper.cpp
+${QtGui_GEN_DIR}/qrhitexturecopydescription_wrapper.cpp
+${QtGui_GEN_DIR}/qrhitexturerendertarget_wrapper.cpp
+${QtGui_GEN_DIR}/qrhitexturerendertargetdescription_wrapper.cpp
+${QtGui_GEN_DIR}/qrhitexturesubresourceuploaddescription_wrapper.cpp
+${QtGui_GEN_DIR}/qrhitextureuploaddescription_wrapper.cpp
+${QtGui_GEN_DIR}/qrhitextureuploadentry_wrapper.cpp
+${QtGui_GEN_DIR}/qrhivertexinputattribute_wrapper.cpp
+${QtGui_GEN_DIR}/qrhivertexinputbinding_wrapper.cpp
+${QtGui_GEN_DIR}/qrhivertexinputlayout_wrapper.cpp
+${QtGui_GEN_DIR}/qrhiviewport_wrapper.cpp
+${QtGui_GEN_DIR}/qshader_wrapper.cpp
+${QtGui_GEN_DIR}/qshadercode_wrapper.cpp
+${QtGui_GEN_DIR}/qshaderkey_wrapper.cpp
+)
+
+if (ENABLE_WIN)
+ list(APPEND QtGui_SRC_RHI
+ ${QtGui_GEN_DIR}/qrhid3d11initparams_wrapper.cpp
+ ${QtGui_GEN_DIR}/qrhid3d11nativehandles_wrapper.cpp
+ ${QtGui_GEN_DIR}/qrhid3d12initparams_wrapper.cpp
+ ${QtGui_GEN_DIR}/qrhid3d12nativehandles_wrapper.cpp)
+elseif (ENABLE_MAC)
+ list(APPEND QtGui_SRC_RHI
+ ${QtGui_GEN_DIR}/qrhimetalinitparams_wrapper.cpp)
+endif()
+
+set(QtGui_SRC
+${QtGui_SRC_UNITY_EXCLUDED_SRC}
+${QtGui_GEN_DIR}/qabstractfileiconprovider_wrapper.cpp
+${QtGui_GEN_DIR}/qabstracttextdocumentlayout_paintcontext_wrapper.cpp
+${QtGui_GEN_DIR}/qabstracttextdocumentlayout_selection_wrapper.cpp
+${QtGui_GEN_DIR}/qabstracttextdocumentlayout_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessible_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibleactioninterface_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibleeditabletextinterface_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibleevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibleobject_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibleselectioninterface_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessiblestatechangeevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletablecellinterface_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletablemodelchangeevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletextcursorevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletextinsertevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletextinterface_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletextremoveevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletextselectionevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibletextupdateevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessiblevaluechangeevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessiblevalueinterface_wrapper.cpp
+${QtGui_GEN_DIR}/qaction_wrapper.cpp
+${QtGui_GEN_DIR}/qactionevent_wrapper.cpp
+${QtGui_GEN_DIR}/qactiongroup_wrapper.cpp
+${QtGui_GEN_DIR}/qbackingstore_wrapper.cpp
+${QtGui_GEN_DIR}/qbitmap_wrapper.cpp
+${QtGui_GEN_DIR}/qbrush_wrapper.cpp
+${QtGui_GEN_DIR}/qchildwindowevent_wrapper.cpp
+${QtGui_GEN_DIR}/qclipboard_wrapper.cpp
+${QtGui_GEN_DIR}/qcloseevent_wrapper.cpp
+${QtGui_GEN_DIR}/qcolor_wrapper.cpp
+${QtGui_GEN_DIR}/qcolorspace_wrapper.cpp
+${QtGui_GEN_DIR}/qcolorconstants_wrapper.cpp
+${QtGui_GEN_DIR}/qcolorconstants_svg_wrapper.cpp
+${QtGui_GEN_DIR}/qcolortransform_wrapper.cpp
+${QtGui_GEN_DIR}/qconicalgradient_wrapper.cpp
+${QtGui_GEN_DIR}/qcontextmenuevent_wrapper.cpp
+${QtGui_GEN_DIR}/qcursor_wrapper.cpp
+${QtGui_GEN_DIR}/qdesktopservices_wrapper.cpp
+${QtGui_GEN_DIR}/qdoublevalidator_wrapper.cpp
+${QtGui_GEN_DIR}/qdrag_wrapper.cpp
+${QtGui_GEN_DIR}/qdragenterevent_wrapper.cpp
+${QtGui_GEN_DIR}/qdragleaveevent_wrapper.cpp
+${QtGui_GEN_DIR}/qdragmoveevent_wrapper.cpp
+${QtGui_GEN_DIR}/qdropevent_wrapper.cpp
+${QtGui_GEN_DIR}/qenterevent_wrapper.cpp
+${QtGui_GEN_DIR}/qeventpoint_wrapper.cpp
+${QtGui_GEN_DIR}/qexposeevent_wrapper.cpp
+${QtGui_GEN_DIR}/qfileopenevent_wrapper.cpp
+${QtGui_GEN_DIR}/qfocusevent_wrapper.cpp
+${QtGui_GEN_DIR}/qfont_wrapper.cpp
+${QtGui_GEN_DIR}/qfont_tag_wrapper.cpp
+${QtGui_GEN_DIR}/qfontdatabase_wrapper.cpp
+${QtGui_GEN_DIR}/qfontinfo_wrapper.cpp
+${QtGui_GEN_DIR}/qfontmetrics_wrapper.cpp
+${QtGui_GEN_DIR}/qfontmetricsf_wrapper.cpp
+${QtGui_GEN_DIR}/qglyphrun_wrapper.cpp
+${QtGui_GEN_DIR}/qgradient_wrapper.cpp
+${QtGui_GEN_DIR}/qguiapplication_wrapper.cpp
+${QtGui_GEN_DIR}/qhelpevent_wrapper.cpp
+${QtGui_GEN_DIR}/qhideevent_wrapper.cpp
+${QtGui_GEN_DIR}/qhoverevent_wrapper.cpp
+${QtGui_GEN_DIR}/qicon_wrapper.cpp
+${QtGui_GEN_DIR}/qicondragevent_wrapper.cpp
+${QtGui_GEN_DIR}/qiconengine_scaledpixmapargument_wrapper.cpp
+${QtGui_GEN_DIR}/qiconengine_wrapper.cpp
+${QtGui_GEN_DIR}/qimage_wrapper.cpp
+${QtGui_GEN_DIR}/qimageiohandler_wrapper.cpp
+${QtGui_GEN_DIR}/qimagereader_wrapper.cpp
+${QtGui_GEN_DIR}/qimagewriter_wrapper.cpp
+${QtGui_GEN_DIR}/qinputdevice_wrapper.cpp
+${QtGui_GEN_DIR}/qinputevent_wrapper.cpp
+${QtGui_GEN_DIR}/qinputmethod_wrapper.cpp
+${QtGui_GEN_DIR}/qinputmethodevent_attribute_wrapper.cpp
+${QtGui_GEN_DIR}/qinputmethodevent_wrapper.cpp
+${QtGui_GEN_DIR}/qinputmethodqueryevent_wrapper.cpp
+${QtGui_GEN_DIR}/qintvalidator_wrapper.cpp
+${QtGui_GEN_DIR}/qkeyevent_wrapper.cpp
+${QtGui_GEN_DIR}/qkeysequence_wrapper.cpp
+${QtGui_GEN_DIR}/qlineargradient_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix2x2_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix2x3_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix2x4_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix3x2_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix3x3_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix3x4_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix4x2_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix4x3_wrapper.cpp
+${QtGui_GEN_DIR}/qmatrix4x4_wrapper.cpp
+${QtGui_GEN_DIR}/qmouseevent_wrapper.cpp
+${QtGui_GEN_DIR}/qmoveevent_wrapper.cpp
+${QtGui_GEN_DIR}/qmovie_wrapper.cpp
+${QtGui_GEN_DIR}/qnativegestureevent_wrapper.cpp
+${QtGui_GEN_DIR}/qnativeinterface_wrapper.cpp
+${QtGui_GEN_DIR}/qoffscreensurface_wrapper.cpp
+${QtGui_GEN_DIR}/qpagedpaintdevice_wrapper.cpp
+${QtGui_GEN_DIR}/qpagelayout_wrapper.cpp
+${QtGui_GEN_DIR}/qpageranges_wrapper.cpp
+${QtGui_GEN_DIR}/qpageranges_range_wrapper.cpp
+${QtGui_GEN_DIR}/qpagesize_wrapper.cpp
+${QtGui_GEN_DIR}/qpaintdevice_wrapper.cpp
+${QtGui_GEN_DIR}/qpaintdevicewindow_wrapper.cpp
+${QtGui_GEN_DIR}/qpaintengine_wrapper.cpp
+${QtGui_GEN_DIR}/qpaintenginestate_wrapper.cpp
+${QtGui_GEN_DIR}/qpainter_pixmapfragment_wrapper.cpp
+${QtGui_GEN_DIR}/qpainter_wrapper.cpp
+${QtGui_GEN_DIR}/qpainterpath_element_wrapper.cpp
+${QtGui_GEN_DIR}/qpainterpath_wrapper.cpp
+${QtGui_GEN_DIR}/qpainterpathstroker_wrapper.cpp
+${QtGui_GEN_DIR}/qpaintevent_wrapper.cpp
+${QtGui_GEN_DIR}/qpalette_wrapper.cpp
+${QtGui_GEN_DIR}/qpdfwriter_wrapper.cpp
+${QtGui_GEN_DIR}/qpen_wrapper.cpp
+${QtGui_GEN_DIR}/qpicture_wrapper.cpp
+${QtGui_GEN_DIR}/qpixmap_wrapper.cpp
+${QtGui_GEN_DIR}/qpixmapcache_key_wrapper.cpp
+${QtGui_GEN_DIR}/qpixmapcache_wrapper.cpp
+${QtGui_GEN_DIR}/qpixelformat_wrapper.cpp
+${QtGui_GEN_DIR}/qplatformsurfaceevent_wrapper.cpp
+${QtGui_GEN_DIR}/qpointerevent_wrapper.cpp
+${QtGui_GEN_DIR}/qpointingdevice_wrapper.cpp
+${QtGui_GEN_DIR}/qpointingdeviceuniqueid_wrapper.cpp
+${QtGui_GEN_DIR}/qpolygon_wrapper.cpp
+${QtGui_GEN_DIR}/qpolygonf_wrapper.cpp
+${QtGui_GEN_DIR}/qpytextobject_wrapper.cpp
+${QtGui_GEN_DIR}/qquaternion_wrapper.cpp
+${QtGui_GEN_DIR}/qradialgradient_wrapper.cpp
+${QtGui_GEN_DIR}/qregularexpressionvalidator_wrapper.cpp
+${QtGui_GEN_DIR}/qrgba64_wrapper.cpp
+${QtGui_GEN_DIR}/qregion_wrapper.cpp
+${QtGui_GEN_DIR}/qresizeevent_wrapper.cpp
+${QtGui_GEN_DIR}/qsessionmanager_wrapper.cpp
+${QtGui_GEN_DIR}/qshortcutevent_wrapper.cpp
+${QtGui_GEN_DIR}/qshowevent_wrapper.cpp
+${QtGui_GEN_DIR}/qsinglepointevent_wrapper.cpp
+${QtGui_GEN_DIR}/qstandarditem_wrapper.cpp
+${QtGui_GEN_DIR}/qstandarditemmodel_wrapper.cpp
+${QtGui_GEN_DIR}/qstatustipevent_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessible_state_wrapper.cpp
+${QtGui_GEN_DIR}/qaccessibleinterface_wrapper.cpp
+${QtGui_GEN_DIR}/qscreen_wrapper.cpp
+${QtGui_GEN_DIR}/qshortcut_wrapper.cpp
+${QtGui_GEN_DIR}/qrasterwindow_wrapper.cpp
+${QtGui_GEN_DIR}/qrawfont_wrapper.cpp
+${QtGui_SRC_RHI}
+${QtGui_GEN_DIR}/qscrollevent_wrapper.cpp
+${QtGui_GEN_DIR}/qscrollprepareevent_wrapper.cpp
+${QtGui_GEN_DIR}/qstatictext_wrapper.cpp
+${QtGui_GEN_DIR}/qstylehints_wrapper.cpp
+${QtGui_GEN_DIR}/qsurface_wrapper.cpp
+${QtGui_GEN_DIR}/qsurfaceformat_wrapper.cpp
+${QtGui_GEN_DIR}/qsyntaxhighlighter_wrapper.cpp
+${QtGui_GEN_DIR}/qtabletevent_wrapper.cpp
+${QtGui_GEN_DIR}/qtextblock_wrapper.cpp
+${QtGui_GEN_DIR}/qtextblockformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtextblockgroup_wrapper.cpp
+${QtGui_GEN_DIR}/qtextblockuserdata_wrapper.cpp
+${QtGui_GEN_DIR}/qtextcharformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtextcursor_wrapper.cpp
+${QtGui_GEN_DIR}/qtextdocument_wrapper.cpp
+${QtGui_GEN_DIR}/qtextdocumentfragment_wrapper.cpp
+${QtGui_GEN_DIR}/qtextdocumentwriter_wrapper.cpp
+${QtGui_GEN_DIR}/qtextformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtextfragment_wrapper.cpp
+${QtGui_GEN_DIR}/qtextframe_wrapper.cpp
+${QtGui_GEN_DIR}/qtextframeformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtextimageformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtextinlineobject_wrapper.cpp
+${QtGui_GEN_DIR}/qtextitem_wrapper.cpp
+${QtGui_GEN_DIR}/qtextlayout_formatrange_wrapper.cpp
+${QtGui_GEN_DIR}/qtextlayout_wrapper.cpp
+${QtGui_GEN_DIR}/qtextlength_wrapper.cpp
+${QtGui_GEN_DIR}/qtextline_wrapper.cpp
+${QtGui_GEN_DIR}/qtextlist_wrapper.cpp
+${QtGui_GEN_DIR}/qtextlistformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtextobject_wrapper.cpp
+${QtGui_GEN_DIR}/qtextobjectinterface_wrapper.cpp
+${QtGui_GEN_DIR}/qtextoption_tab_wrapper.cpp
+${QtGui_GEN_DIR}/qtextoption_wrapper.cpp
+${QtGui_GEN_DIR}/qtexttable_wrapper.cpp
+${QtGui_GEN_DIR}/qtexttablecell_wrapper.cpp
+${QtGui_GEN_DIR}/qtexttablecellformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtexttableformat_wrapper.cpp
+${QtGui_GEN_DIR}/qtguihelper_qoverridecursorguard_wrapper.cpp
+${QtGui_GEN_DIR}/qtoolbarchangeevent_wrapper.cpp
+${QtGui_GEN_DIR}/qtouchevent_wrapper.cpp
+${QtGui_GEN_DIR}/qtransform_wrapper.cpp
+${QtGui_GEN_DIR}/qt_wrapper.cpp
+${QtGui_GEN_DIR}/qundocommand_wrapper.cpp
+${QtGui_GEN_DIR}/qundogroup_wrapper.cpp
+${QtGui_GEN_DIR}/qundostack_wrapper.cpp
+${QtGui_GEN_DIR}/qvalidator_wrapper.cpp
+${QtGui_GEN_DIR}/qvector2d_wrapper.cpp
+${QtGui_GEN_DIR}/qvector3d_wrapper.cpp
+${QtGui_GEN_DIR}/qvector4d_wrapper.cpp
+${QtGui_GEN_DIR}/qwhatsthisclickedevent_wrapper.cpp
+${QtGui_GEN_DIR}/qwheelevent_wrapper.cpp
+${QtGui_GEN_DIR}/qwindow_wrapper.cpp
+${QtGui_GEN_DIR}/qwindowstatechangeevent_wrapper.cpp
+# module is always needed
+${QtGui_GEN_DIR}/qtgui_module_wrapper.cpp
+)
+
+get_property(QtGui_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Gui
+ PROPERTY QT_ENABLED_PUBLIC_FEATURES)
+
+if("xcb" IN_LIST QtGui_enabled_features)
+ list(APPEND QtGui_SRC
+ ${QtGui_GEN_DIR}/qnativeinterface_qx11application_wrapper.cpp)
+elseif(WIN32)
+ list(APPEND QtGui_SRC
+ ${QtGui_GEN_DIR}/qnativeinterface_qwindowsscreen_wrapper.cpp)
+endif()
+
+if("opengl" IN_LIST QtGui_enabled_features OR "opengles2" IN_LIST QtGui_enabled_features
+ OR "opengles3" IN_LIST QtGui_enabled_features)
+ list(APPEND QtGui_SRC
+ ${QtGui_GEN_DIR}/qopenglcontextgroup_wrapper.cpp
+ ${QtGui_GEN_DIR}/qopenglextrafunctions_wrapper.cpp
+ ${QtGui_GEN_DIR}/qopenglfunctions_wrapper.cpp
+ ${QtGui_GEN_DIR}/qopenglcontext_wrapper.cpp
+ ${QtGui_GEN_DIR}/qrhigles2initparams_wrapper.cpp
+ ${QtGui_GEN_DIR}/qrhigles2nativehandles_wrapper.cpp)
+else()
+ list(APPEND QtGui_DROPPED_ENTRIES
+ QOpenGLContext QOpenGLContextGroup QOpenGLPaintDevice
+ QOpenGLExtraFunctions QOpenGLFunctions
+ QRhiGles2InitParams QRhiGles2NativeHandles)
+endif()
+
+set(QtGui_private_include_dirs
+ ${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_PRIVATE_INCLUDE_DIRS})
+
+if (${CMAKE_SYSTEM_NAME} STREQUAL "Android")
+ if (QT_FEATURE_opengles2)
+ # add openGL ES 2.0
+ find_package(GLESv2 REQUIRED)
+ else()
+ message(FATAL_ERROR "QtGui requires OpenGL ES 2.0 on Android")
+ endif()
+endif()
+
+configure_file("${QtGui_SOURCE_DIR}/QtGui_global.post.h.in"
+ "${QtGui_BINARY_DIR}/QtGui_global.post.h" @ONLY)
+
+set(QtGui_include_dirs ${QtGui_SOURCE_DIR}
+ ${QtGui_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${QtGui_private_include_dirs}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ )
+set(QtGui_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES})
+set(QtGui_deps QtCore)
+
+create_pyside_module(NAME QtGui
+ INCLUDE_DIRS QtGui_include_dirs
+ LIBRARIES QtGui_libraries
+ DEPS QtGui_deps
+ TYPESYSTEM_PATH QtGui_SOURCE_DIR
+ SOURCES QtGui_SRC
+ STATIC_SOURCES QPYTEXTOBJECT_MOC
+ TYPESYSTEM_NAME ${QtGui_BINARY_DIR}/typesystem_gui.xml
+ DROPPED_ENTRIES QtGui_DROPPED_ENTRIES
+ ADDITIONAL_INCLUDE_DIRS QtGui_private_include_dirs)
+
+install(FILES ${pyside6_SOURCE_DIR}/qpytextobject.h
+ ${pyside6_SOURCE_DIR}/qtguihelper.h
+ DESTINATION include/PySide6/QtGui/)
+
diff --git a/sources/pyside6/PySide6/QtGui/QtGui_global.post.h.in b/sources/pyside6/PySide6/QtGui/QtGui_global.post.h.in
new file mode 100644
index 000000000..e5a0eeb90
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/QtGui_global.post.h.in
@@ -0,0 +1,6 @@
+#include "qpytextobject.h" // PySide class
+#include <rhi/qrhi.h>
+#include <rhi/qrhi_platform.h>
+#include <rhi/qshader.h>
+#include <qtguihelper.h>
+void qt_set_sequence_auto_mnemonic(bool b);
diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui.xml
new file mode 100644
index 000000000..858989404
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/typesystem_gui.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtGui"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <?if windows?>
+ <load-typesystem name="QtGui/typesystem_gui_win.xml" generate="yes"/>
+ <?endif?>
+ <?if darwin?>
+ <load-typesystem name="QtGui/typesystem_gui_mac.xml" generate="yes"/>
+ <?endif?>
+ <?if unix !darwin?>
+ <load-typesystem name="QtGui/typesystem_gui_x11.xml" generate="yes"/>
+ <?endif?>
+ <load-typesystem name="QtGui/typesystem_gui_common.xml" generate="yes"/>
+ <load-typesystem name="QtGui/typesystem_gui_rhi.xml" generate="yes"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml
new file mode 100644
index 000000000..feb2dc11b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml
@@ -0,0 +1,3182 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtGui">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="templates/common.xml" generate="no"/>
+ <load-typesystem name="templates/core_common.xml" generate="no"/>
+ <load-typesystem name="templates/gui_common.xml" generate="no"/>
+ <load-typesystem name="templates/opengl_common.xml" generate="no"/>
+
+ <rejection class="^Q.*$" argument-type="^QPlatform.*$"/>
+ <function signature="qAlpha(uint)"/>
+ <function signature="qBlue(uint)"/>
+ <function signature="qGray(int,int,int)"/>
+ <function signature="qGray(uint)"/>
+ <function signature="qGreen(uint)"/>
+ <function signature="qIsGray(uint)"/>
+ <function signature="qRed(uint)"/>
+ <function signature="qRgb(int,int,int)"/>
+ <function signature="qRgba(int,int,int,int)"/>
+ <!-- qFuzzyCompare() are declared as friend functions of the respective classes only. -->
+ <declare-function signature="qFuzzyCompare(QTransform,QTransform)" return-type="bool"/>
+ <function signature="qFuzzyCompare(QTransform,QTransform)"/>
+ <declare-function signature="qFuzzyCompare(QQuaternion,QQuaternion)" return-type="bool"/>
+ <function signature="qFuzzyCompare(QQuaternion,QQuaternion)"/>
+ <declare-function signature="qFuzzyCompare(QMatrix4x4,QMatrix4x4)" return-type="bool"/>
+ <function signature="qFuzzyCompare(QMatrix4x4,QMatrix4x4)"/>
+ <declare-function signature="qFuzzyCompare(QVector2D,QVector2D)" return-type="bool"/>
+ <function signature="qFuzzyCompare(QVector2D,QVector2D)"/>
+ <declare-function signature="qFuzzyCompare(QVector3D,QVector3D)" return-type="bool"/>
+ <function signature="qFuzzyCompare(QVector3D,QVector3D)"/>
+ <declare-function signature="qFuzzyCompare(QVector4D,QVector4D)" return-type="bool"/>
+ <function signature="qFuzzyCompare(QVector4D,QVector4D)"/>
+ <function signature="qPixelFormatRgba(uchar,uchar,uchar,uchar,QPixelFormat::AlphaUsage,QPixelFormat::AlphaPosition,QPixelFormat::AlphaPremultiplied,QPixelFormat::TypeInterpretation)"/>
+ <function signature="qPixelFormatGrayscale(uchar,QPixelFormat::TypeInterpretation)"/>
+ <function signature="qPixelFormatAlpha(uchar,QPixelFormat::TypeInterpretation)"/>
+ <function signature="qPixelFormatCmyk(uchar,uchar,QPixelFormat::AlphaUsage,QPixelFormat::AlphaPosition,QPixelFormat::TypeInterpretation)"/>
+ <function signature="qPixelFormatHsl(uchar,uchar,QPixelFormat::AlphaUsage,QPixelFormat::AlphaPosition,QPixelFormat::TypeInterpretation)"/>
+ <function signature="qPixelFormatHsv(uchar,uchar,QPixelFormat::AlphaUsage,QPixelFormat::AlphaPosition,QPixelFormat::TypeInterpretation)"/>
+ <function signature="qPixelFormatYuv(QPixelFormat::YUVLayout,uchar,QPixelFormat::AlphaUsage,QPixelFormat::AlphaPosition,QPixelFormat::AlphaPremultiplied,QPixelFormat::TypeInterpretation,QPixelFormat::ByteOrder)"/>
+ <function signature="qt_set_sequence_auto_mnemonic(bool)"/>
+
+ <rejection class="^QOpenGL.*$" argument-type="^const GLboolean ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^GLchar\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?GLchar ?\*(const)?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^char\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?char ?\*\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="GLintptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="GLsizeiptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="^GLu?int64 ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^GLenum ?\*$"/> <!-- glGetProgramBinary -->
+ <rejection class="^QOpenGL.*$" argument-type="GLsync"/>
+ <rejection class="^QOpenGL.*$" argument-type="^GLubyte( const)?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?QMatrix.x. ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="qopengl_GLintptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="qopengl_GLsizeiptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="QOpenGLTextureHelper*"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?QVector.D ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?void ?\*\*$"/>
+
+ <!--
+ Event classes have a lot of non-documented protected fields, those fields
+ are removed from PySide because they are Qt implementation details,
+ besides the fact they are accessible by ordinary event methods.
+ -->
+
+ <rejection class="^Q.*Event$" field-name="^m_.*$"/>
+
+ <rejection class="QFont" enum-name="ResolveProperties"/>
+ <rejection class="QPolygon" function-name="putPoints"/>
+ <rejection class="QPolygon" function-name="setPoints"/>
+ <rejection class="QPolygon" function-name="setPoint"/>
+ <rejection class="QPolygon" function-name="point"/>
+ <rejection class="QPaintEngine" function-name="fix_neg_rect"/>
+
+ <inject-code class="native" position="beginning" file="../glue/qtgui.cpp"
+ snippet="gui-declarations"/>
+
+ <!-- For Qt::mightBeRichText(QString), Qt::convertFromPlainText(QString,Qt::WhiteSpaceMode)
+ Match on files from '/QtGui/' (shadow build) or '/gui/' (developer build)
+ or '/QtGui.framework' (macOS) -->
+ <namespace-type name="Qt" files="^.*/(gui|QtGui)[/.].*\.h$" extends="PySide6.QtCore"/>
+
+ <primitive-type name="WId" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtgui.cpp" snippet="return-pylong-voidptr"/>
+ <target-to-native>
+ <add-conversion type="PyLong" file="../glue/qtgui.cpp" snippet="conversion-pylong"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+
+ <object-type name="QAbstractFileIconProvider">
+ <enum-type name="IconType"/>
+ <enum-type name="Option" flags="Options"/>
+ </object-type>
+
+ <value-type name="QAccessible">
+ <extra-includes>
+ <include file-name="QtGui/QAccessibleInterface" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning"
+ file="../glue/qtgui.cpp"
+ snippet="qaccessible-pysidefactory"/>
+ <value-type name="State"/>
+ <enum-type name="Event"/>
+ <enum-type name="Role"/>
+ <enum-type name="Text"/>
+ <enum-type name="RelationFlag" flags="Relation"/>
+ <enum-type name="InterfaceType"/>
+ <enum-type name="TextBoundaryType"/>
+ <add-function signature="installFactory(PyCallable)" static="yes">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp"
+ snippet="qaccessible-installfactory"/>
+ </add-function>
+ </value-type>
+
+ <object-type name="QAccessibleActionInterface"/>
+ <object-type name="QAccessibleEditableTextInterface"/>
+ <object-type name="QAccessibleInterface"/>
+ <object-type name="QAccessibleObject" qt-register-metatype="base"/>
+ <object-type name="QAccessibleSelectionInterface" since="6.7"/>
+ <object-type name="QAccessibleTableCellInterface"/>
+ <object-type name="QAccessibleTextInterface"/>
+ <object-type name="QAccessibleValueInterface"/>
+
+ <object-type name="QAccessibleEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::InvalidEvent"/>
+ <object-type name="QAccessibleStateChangeEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::StateChanged"/>
+ <object-type name="QAccessibleTableModelChangeEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::TableModelChanged">
+ <enum-type name="ModelChangeType"/>
+ </object-type>
+ <object-type name="QAccessibleTextCursorEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::TextCaretMoved"/>
+ <object-type name="QAccessibleTextInsertEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::TextInserted"/>
+ <object-type name="QAccessibleTextRemoveEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::TextRemoved"/>
+ <object-type name="QAccessibleTextSelectionEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::TextSelectionChanged"/>
+ <object-type name="QAccessibleTextUpdateEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::TextUpdated"/>
+ <object-type name="QAccessibleValueChangeEvent"
+ polymorphic-id-expression="%B-&gt;type() == QAccessible::ValueChanged"/>
+
+ <object-type name="QAction">
+ <enum-type name="ActionEvent"/>
+ <enum-type name="MenuRole"/>
+ <enum-type name="Priority" since="4.6"/>
+ <!-- PYSIDE-1627 QAction::menu()/setMenu() are templates -->
+ <add-function signature="menu()const" return-type="QObject*">
+ <inject-code file="../glue/qtgui.cpp" snippet="qaction-menu"/>
+ </add-function>
+ <declare-function signature="setMenu(QObject*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </declare-function>
+ <modify-function signature="triggered(bool)" allow-thread="yes"/>
+ <add-function signature="setShortcut(Qt::Key)">
+ <inject-code file="../glue/qtgui.cpp" snippet="set-qtkey-shortcut"/>
+ </add-function>
+ </object-type>
+ <object-type name="QActionGroup">
+ <enum-type name="ExclusionPolicy"/>
+ <modify-function signature="addAction(QAction*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeAction(QAction*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QShortcut">
+ <add-function signature="QShortcut(QKeySequence&amp;,QObject*,PyCallable*,Qt::ShortcutContext=Qt::WindowShortcut)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qshortcut-1"/>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qshortcut-2"/>
+ </add-function>
+ <add-function signature="QShortcut(QKeySequence::StandardKey,QObject*,PyCallable*,Qt::ShortcutContext=Qt::WindowShortcut)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qshortcut-1"/>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qshortcut-2"/>
+ </add-function>
+ </object-type>
+
+ <value-type name="QTransform">
+ <enum-type name="TransformationType"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f, %f, %f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS"
+ to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m13(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.m23(), %CPPSELF.m31(), %CPPSELF.m32(), %CPPSELF.m33()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="ddddddddd"/>
+ <replace from="%REDUCE_ARGS"
+ to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m13(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.m23(), %CPPSELF.m31(), %CPPSELF.m32(), %CPPSELF.m33()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <modify-function signature="map(qreal,qreal,qreal*,qreal*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <!-- ### This is just an overload to "map(qreal,qreal,qreal*,qreal*)const" and can be discarded in Python -->
+ <modify-function signature="map(int,int,int*,int*)const" remove="all"/>
+ <!-- ### -->
+
+ <modify-function signature="inverted(bool*)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtGui.QTransform, bool]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ <add-function signature="quadToQuad(QPolygonF&amp;,QPolygonF&amp;)" return-type="PyObject*" static="true">
+ <inject-code file="../glue/qtgui.cpp" snippet="qtransform-quadtoquad"/>
+ </add-function>
+ <add-function signature="quadToSquare(QPolygonF &amp;)" return-type="PyObject*" static="true">
+ <inject-code file="../glue/qtgui.cpp" snippet="qtransform-quadtosquare"/>
+ </add-function>
+
+ <add-function signature="squareToQuad(QPolygonF &amp;)" return-type="PyObject*" static="true">
+ <inject-code file="../glue/qtgui.cpp" snippet="qtransform-squaretoquad"/>
+ </add-function>
+ <!-- Disambiguate from Qt3DCore/qtransform.h -->
+ <include file-name="QtGui/qtransform.h" location="global"/>
+ </value-type>
+
+ <value-type name="QGlyphRun">
+ <enum-type name="GlyphRunFlag" flags="GlyphRunFlags"/>
+ </value-type>
+
+ <value-type name="QStaticText">
+ <enum-type name="PerformanceHint"/>
+ </value-type>
+ <value-type name="QTextFragment"/>
+ <value-type name="QBitmap" >
+ <modify-function signature="fromData(QSize,const uchar*,QImage::Format)">
+ <modify-argument index="2">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code file="../glue/qtgui.cpp" snippet="qbitmap-fromdata"/>
+ </modify-function>
+ </value-type>
+ <value-type name="QTextInlineObject"/>
+ <value-type name="QTextDocumentFragment"/>
+ <value-type name="QTextOption">
+ <!-- PYSIDE-2088, Avoid MSVC signedness issues -->
+ <enum-type name="Flag" flags="Flags" cpp-type="unsigned"/>
+ <enum-type name="TabType"/>
+ <enum-type name="WrapMode"/>
+ <value-type name="Tab"/>
+ </value-type>
+ <value-type name="QTextLine" >
+ <enum-type name="CursorPosition"/>
+ <enum-type name="Edge"/>
+ <modify-function signature="cursorToX(int*,QTextLine::Edge)const" remove="all"/>
+ <modify-function signature="cursorToX(int,QTextLine::Edge)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qtextline-cursortox"/>
+ </modify-function>
+ <modify-function signature="xToCursor(qreal,QTextLine::CursorPosition)const">
+ <modify-argument index="2">
+ <rename to="edge"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <value-type name="QTextTableFormat"/>
+ <value-type name="QTextImageFormat"/>
+ <value-type name="QTextFrameFormat" >
+ <enum-type name="BorderStyle"/>
+ <enum-type name="Position"/>
+ </value-type>
+ <value-type name="QTextLength">
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="QPainterPath">
+ <enum-type name="ElementType"/>
+ <value-type name="Element">
+ <include file-name="QPainterPath" location="global"/>
+ </value-type>
+ </value-type>
+ <value-type name="QPalette">
+ <enum-type name="ColorGroup"/>
+ <enum-type name="ColorRole"/>
+ </value-type>
+ <object-type name="QInputMethod">
+ <enum-type name="Action"/>
+ </object-type>
+ <value-type name="QKeySequence">
+ <enum-type name="SequenceFormat"/>
+ <enum-type name="SequenceMatch"/>
+ <enum-type name="StandardKey"/>
+
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qkeysequence-repr"/>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="(*%CPPSELF)[0], (*%CPPSELF)[1], (*%CPPSELF)[2], (*%CPPSELF)[3]"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <modify-function signature="operator[](uint)const" remove="all"/>
+ <add-function signature="__getitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qkeysequence-getitem"/>
+ </add-function>
+
+ <!-- ### Not necessary due the PySide QVariant conversion rules -->
+ <modify-function signature="operator QVariant()const" remove="all"/>
+ </value-type>
+ <value-type name="QPicture" >
+ <modify-function signature="load(QIODevice*)" allow-thread="yes"/>
+ <modify-function signature="load(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="save(QIODevice*)" allow-thread="yes"/>
+ <modify-function signature="save(const QString&amp;)" allow-thread="yes"/>
+ <!-- See bug 759 -->
+ <modify-function signature="data()const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <inject-code file="../glue/qtgui.cpp" snippet="qpicture-data"/>
+ </modify-function>
+ <modify-function signature="setData(const char*,uint)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ <conversion-rule class="target">
+ <insert-template name="const_char_pybuffer"/>
+ </conversion-rule>
+ <conversion-rule class="native">
+ <insert-template name="pybuffer_const_char"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="uint_remove"/>
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <value-type name="QRegion" >
+ <enum-type name="RegionType"/>
+ <add-function signature="__len__">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qregion-len"/>
+ </add-function>
+ <add-function signature="__getitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qregion-getitem"/>
+ </add-function>
+ <!-- ### This operator does not make sense in Python. -->
+ <modify-function signature="operator&amp;=(QRegion)" remove="all"/>
+ <modify-function signature="operator&amp;=(QRect)" remove="all"/>
+ <!-- ### -->
+ </value-type>
+
+ <value-type name="QTextBlock">
+ <value-type name="iterator" >
+ <include file-name="QTextBlock" location="global"/>
+ <!-- ### These operators where removed because they don't make sense in Python.
+ The iterator methods (__iter__, next) replace this functionality. -->
+ <modify-function signature="operator++()" remove="all"/>
+ <modify-function signature="operator--()" remove="all"/>
+ <!-- ### -->
+ <add-function signature="__iter__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="__iter__"/>
+ </inject-code>
+ </add-function>
+ <add-function signature="__next__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="__next__">
+ <replace from="%CPPSELF_TYPE" to="QTextBlock::iterator"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+ <add-function signature="__iter__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="__iter_parent__">
+ <replace from="%CPPSELF_TYPE" to="QTextBlock::iterator"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <modify-function signature="setUserData(QTextBlockUserData*)">
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qtextblock-setuserdata"/>
+ </modify-function>
+ <modify-function signature="userData()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qtextblock-userdata"/>
+ </modify-function>
+ </value-type>
+ <value-type name="QTextBlockFormat">
+ <enum-type name="LineHeightTypes" since="4.8" revision="4800"/>
+ <enum-type name="MarkerType"/>
+ </value-type>
+ <value-type name="QTextTableCellFormat"/>
+ <value-type name="QTextCharFormat" >
+ <enum-type name="FontPropertiesInheritanceBehavior"/>
+ <enum-type name="UnderlineStyle"/>
+ <enum-type name="VerticalAlignment"/>
+ </value-type>
+ <value-type name="QTextFormat" >
+ <enum-type name="FormatType" python-type="IntEnum"/>
+ <enum-type name="ObjectTypes" python-type="IntEnum"/>
+ <enum-type name="PageBreakFlag" flags="PageBreakFlags"/>
+ <enum-type name="Property" python-type="IntEnum"/>
+ </value-type>
+ <value-type name="QTextListFormat">
+ <enum-type name="Style"/>
+ </value-type>
+ <value-type name="QPolygon">
+ <extra-includes>
+ <include file-name="QTransform" location="global"/>
+ </extra-includes>
+ <!-- Expose operator==, != inherited from QList, which the parser does
+ not see due to the TMP expression of the return type. -->
+ <add-function signature="operator==(const QPolygon&amp;)" return-type="bool"/>
+ <add-function signature="operator!=(const QPolygon&amp;)" return-type="bool"/>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qpolygon-reduce">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="N"/>
+ <replace from="%REDUCE_ARGS" to="points"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!-- ### "QPolygon(int, const int*)" is an internal constructor. -->
+ <modify-function signature="QPolygon(int,const int*)" remove="all"/>
+ <!-- ### A QList parameter, for no defined type, will generate wrong code. -->
+ <modify-function signature="operator+=(QList&lt;QPoint&gt;)" remove="all"/>
+ <add-function signature="operator&lt;&lt;(QPoint)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpolygon-operatorlowerlower"/>
+ </add-function>
+ <add-function signature="operator&lt;&lt;(QList&lt;QPoint&gt;)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpolygon-operatorlowerlower"/>
+ </add-function>
+ <!-- ### -->
+ </value-type>
+ <value-type name="QPolygonF">
+ <extra-includes>
+ <include file-name="QTransform" location="global"/>
+ </extra-includes>
+ <!-- ### A QList parameter, for no defined type, will generate wrong code. -->
+ <modify-function signature="operator+=(QList&lt;QPointF&gt;)" remove="all"/>
+ <!-- ### See bug 777 -->
+ <modify-function signature="operator&lt;&lt;(QList&lt;QPointF&gt;)" remove="all"/>
+ <!-- ### -->
+ </value-type>
+ <value-type name="QIcon" >
+ <enum-type name="Mode"/>
+ <enum-type name="State"/>
+ <enum-type name="ThemeIcon" since="6.7"/>
+ <modify-function signature="QIcon(QIconEngine*)">
+ <modify-argument index="1">
+ <no-null-pointer/>
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <!-- PYSIDE-1669: Replace implicit conversion by a better explicit version -->
+ <add-function signature="addPixmap(PyPathLike@path@)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qicon-addpixmap"/>
+ </add-function>
+ </value-type>
+
+ <value-type name="QPixmap" >
+ <add-function signature="QPixmap(const QImage&amp;@image@)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qpixmap"/>
+ </add-function>
+ <modify-function signature="QPixmap(const char*const[])">
+ <modify-argument index="1">
+ <replace-type modified-type="PySequence"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="load_xpm"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="QPixmap(const QString &amp;, const char *, QFlags&lt;Qt::ImageConversionFlag&gt;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <!-- ### Operator ! doesn't make sense in Python. -->
+ <modify-function signature="operator!()const" remove="all"/>
+
+ <modify-function signature="loadFromData(const uchar*,uint,const char*,QFlags&lt;Qt::ImageConversionFlag&gt;)">
+ <inject-documentation format="target" mode="append">
+ This method must be used with an QPixmap object, not the class:
+
+ ::
+
+ # Wrong
+ pixmap = QPixmap.loadFromData(...)
+
+ # Right
+ pixmap = QPixmap().loadFromData(...)
+
+ </inject-documentation>
+ <modify-argument index="1">
+ <replace-type modified-type="PyBytes"/>
+ <conversion-rule class="native">
+ <insert-template name="pybytes_const_uchar"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="pybytes_uint"/>
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <value-type name="QTextCursor" >
+ <extra-includes>
+ <include file-name="QTextBlock" location="global"/>
+ <include file-name="QTextDocumentFragment" location="global"/>
+ </extra-includes>
+ <enum-type name="MoveMode"/>
+ <enum-type name="MoveOperation"/>
+ <enum-type name="SelectionType"/>
+ <modify-function signature="selectedTableCells(int*,int*,int*,int*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ <inject-code class="native" position="end">
+ <insert-template name="fix_native_return_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="currentFrame()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="currentTable()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="currentList()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertTable(int,int,const QTextTableFormat &amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertTable(int,int)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="QConicalGradient" polymorphic-id-expression="%B-&gt;type() == QGradient::ConicalGradient"/>
+ <value-type name="QFontInfo"/>
+ <value-type name="QRadialGradient" polymorphic-id-expression="%B-&gt;type() == QGradient::RadialGradient"/>
+ <value-type name="QFont" >
+ <enum-type name="Capitalization"/>
+ <enum-type name="SpacingType"/>
+ <enum-type name="Stretch" python-type="IntEnum"/>
+ <enum-type name="Style"/>
+ <enum-type name="StyleHint"/>
+ <enum-type name="StyleStrategy" python-type="Flag"/>
+ <enum-type name="Weight" python-type="IntEnum"/>
+ <enum-type name="HintingPreference" since="4.8" revision="4800"/>
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ </extra-includes>
+ <value-type name="Tag" since="6.7"/>
+ <!-- PYSIDE-1685: QFont(QString) should be checked first, else it will be interpreted as sequence -->
+ <modify-function signature="QFont(const QString&amp;,int,int, bool)" overload-number="0"/>
+ <modify-function signature="QFont(const QStringList &amp;,int,int, bool)" overload-number="1"/>
+ <modify-function signature="setStyleHint(QFont::StyleHint,QFont::StyleStrategy)">
+ <modify-argument index="2">
+ <rename to="strategy"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <value-type name="QTextTableCell" >
+ <extra-includes>
+ <include file-name="QTextCursor" location="global"/>
+ </extra-includes>
+ </value-type> <!--
+ <function signature="QImageCleanupFunction(void*)">
+ <extra-includes>
+ <include file-name="QImage" location="global"/>
+ </extra-includes>
+ </function> -->
+ <primitive-type name="QImageCleanupFunction"/>
+
+ <value-type name="QImage">
+ <enum-type name="Format"/>
+ <enum-type name="InvertMode"/>
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qimage-decref-image-data"/>
+
+ <modify-function signature="load(const QString&amp;, const char*)" allow-thread="yes"/>
+ <modify-function signature="load(QIODevice*,const char*)" allow-thread="yes"/>
+ <modify-function signature="save(const QString&amp;,const char*,int)const" allow-thread="yes"/>
+ <modify-function signature="save(QIODevice*,const char*,int)const" allow-thread="yes"/>
+ <modify-function signature="QImage(uchar*,int,int,qsizetype,QImage::Format,QImageCleanupFunction,void*)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code>
+ <insert-template name="qimage_buffer_constructor">
+ <replace from="%ARGS" to="%2, %3, %4, %5"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="QImage(uchar*,int,int,QImage::Format,QImageCleanupFunction,void*)">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ </modify-argument>
+ <inject-code>
+ <insert-template name="qimage_buffer_constructor">
+ <replace from="%ARGS" to="%2, %3, %4"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="QImage(const QString&amp;, const char *)" allow-thread="yes">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+
+ <add-function signature="QImage(QString&amp;,int,int,int,QImage::Format)">
+ <inject-code>
+ <insert-template name="qimage_buffer_constructor">
+ <replace from="%ARGS" to="%2, %3, %4, %5"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QImage(QString&amp;,int,int,QImage::Format)">
+ <inject-code>
+ <insert-template name="qimage_buffer_constructor">
+ <replace from="%ARGS" to="%2, %3, %4"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!-- The non-const versions are already used -->
+ <modify-function signature="QImage(const uchar*,int,int,qsizetype,QImage::Format,QImageCleanupFunction,void*)" remove="all"/>
+ <modify-function signature="QImage(const uchar*,int,int,QImage::Format,QImageCleanupFunction,void*)" remove="all"/>
+ <!-- ### -->
+
+ <modify-function signature="QImage(const char*const[])">
+ <modify-argument index="1">
+ <replace-type modified-type="PySequence"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="load_xpm"/>
+ </inject-code>
+ </modify-function>
+ <!-- ### There is already an fromData with a QByteArray type (that is convertible from Python's str) as the first type. -->
+ <modify-function signature="fromData(const uchar*,int,const char*)" remove="all"/>
+ <!-- ### There is already an loadFromData with a QByteArray type (that is convertible from Python's str) as the first type. -->
+ <modify-function signature="loadFromData(const uchar*,int,const char*)" remove="all"/>
+
+ <modify-function signature="constBits()const" since="4.7">
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-constbits"/>
+ </modify-function>
+ <modify-function signature="bits()">
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-bits"/>
+ </modify-function>
+ <modify-function signature="constScanLine(int)const" since="4.7">
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-constscanline"/>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="scanLine(int)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-scanline"/>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ </modify-function>
+ <!--
+ Only the non-const version of bits() and scanLine() is exported to Python
+ If the user don't want to detach the QImage data he must use constBits or constScanLine
+ as Python doesn't have the concept of constness.
+ -->
+ <modify-function signature="bits()const" remove="all"/>
+ <modify-function signature="scanLine(int)const" remove="all"/>
+ <modify-function signature="invertPixels(QImage::InvertMode)">
+ <modify-argument index="1">
+ <rename to="mode"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="QCursor" >
+ <extra-includes>
+ <include file-name="QPixmap" location="global"/>
+ <include file-name="Qt" location="global"/>
+ </extra-includes>
+ </value-type>
+ <value-type name="QFontDatabase" >
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ </extra-includes>
+ <enum-type name="SystemFont"/>
+ <enum-type name="WritingSystem"/>
+ </value-type>
+ <value-type name="QPen">
+ <extra-includes>
+ <include file-name="QBrush" location="global"/>
+ </extra-includes>
+ </value-type>
+ <value-type name="QBrush">
+ <extra-includes>
+ <include file-name="QPixmap" location="global"/>
+ </extra-includes>
+ </value-type>
+
+ <value-type name="QColor">
+ <enum-type name="NameFormat"/>
+ <enum-type name="Spec"/>
+ <extra-includes>
+ <include file-name="QVariant" location="global"/>
+ </extra-includes>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="qcolor_repr"/>
+ </inject-code>
+ </add-function>
+ <add-function signature="__str__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="qcolor_repr"/>
+ </inject-code>
+ </add-function>
+ <add-function signature="__setstate__(PyObject*)" return-type="PyObject">
+ <inject-code file="../glue/qtgui.cpp" snippet="qcolor-setstate"/>
+ </add-function>
+ <add-function signature="__reduce__" return-type="PyObject">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qcolor-reduce"/>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qcolor-totuple"/>
+ </add-function>
+ <!-- ### "QColor(QColor::Spec)" is an internal method. -->
+ <modify-function signature="QColor(QColor::Spec)" remove="all"/>
+ <!-- ### Constructor removed because we already have an overload using QString. -->
+ <modify-function signature="QColor(const char*)" remove="all"/>
+ <!-- ### -->
+ <add-function signature="QColor(QVariant)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qcolor"/>
+ </add-function>
+ <!-- get* methods. Inject code -->
+ <modify-function signature="getCmyk(int*,int*,int*,int*,int*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="5">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getCmykF(float*,float*,float*,float*,float*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="5">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*,number*">
+ <replace from="$TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getHsl(int*,int*,int*,int*)const" since="4.6">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getHslF(float*,float*,float*,float*)const" since="4.6">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getHsv(int*,int*,int*,int*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getHsvF(float*,float*,float*,float*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getRgb(int*,int*,int*,int*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getRgbF(float*,float*,float*,float*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ </value-type>
+
+ <namespace-type name="QColorConstants">
+ <extra-includes>
+ <include file-name="QColor" location="global"/>
+ </extra-includes>
+ <namespace-type name="Svg">
+ <extra-includes>
+ <include file-name="QColor" location="global"/>
+ </extra-includes>
+ </namespace-type>
+ </namespace-type>
+
+ <value-type name="QColorSpace">
+ <enum-type name="NamedColorSpace"/>
+ <enum-type name="Primaries"/>
+ <enum-type name="TransferFunction"/>
+ </value-type>
+
+ <value-type name="QColorTransform"/>
+
+ <value-type name="QRgba64"/>
+
+ <value-type name="QFontMetricsF" >
+
+ <modify-function signature="boundingRect(QChar)const" rename="boundingRectChar">
+ <modify-argument index="1">
+ <replace-type modified-type="char"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="QFontCharFix"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="horizontalAdvance(QChar)const" rename="horizontalAdvanceChar">
+ <modify-argument index="1">
+ <replace-type modified-type="char"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="QFontCharFix"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="boundingRect(QRectF,int,QString,int,int*)const">
+ <modify-argument index="5">
+ <replace-type modified-type="PyObject"/>
+ <array/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetricsf-boundingrect"/>
+ </modify-function>
+
+ <modify-function signature="size(int,QString,int,int*)const">
+ <modify-argument index="4">
+ <replace-type modified-type="PyObject"/>
+ <array/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetricsf-size"/>
+ </modify-function>
+ </value-type>
+ <value-type name="QFontMetrics" >
+
+ <modify-function signature="boundingRect(QChar)const" rename="boundingRectChar">
+ <modify-argument index="1">
+ <replace-type modified-type="char"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="QFontCharFix"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="horizontalAdvance(QChar)const" rename="horizontalAdvanceChar">
+ <modify-argument index="1">
+ <replace-type modified-type="char"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="QFontCharFix"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="boundingRect(int,int,int,int,int,QString,int,int*)const">
+ <modify-argument index="8">
+ <replace-type modified-type="PyObject"/>
+ <array/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetrics-boundingrect-1"/>
+ </modify-function>
+
+ <modify-function signature="boundingRect(QRect,int,QString,int,int*)const">
+ <modify-argument index="5">
+ <replace-type modified-type="PyObject"/>
+ <array/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetrics-boundingrect-2"/>
+ </modify-function>
+
+ <modify-function signature="size(int,QString,int,int*)const">
+ <modify-argument index="4">
+ <replace-type modified-type="PyObject"/>
+ <array/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetrics-size"/>
+ </modify-function>
+ </value-type>
+ <value-type name="QGradient" polymorphic-id-expression="%B-&gt;type() == QGradient::NoGradient">
+ <enum-type name="CoordinateMode"/>
+ <enum-type name="InterpolationMode"/>
+ <enum-type name="Preset"/>
+ <enum-type name="Spread"/>
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="QLinearGradient" polymorphic-id-expression="%B-&gt;type() == QGradient::LinearGradient"/>
+ <object-type name="QPaintDevice">
+ <enum-type name="PaintDeviceMetric"/>
+ </object-type>
+ <object-type name="QPagedPaintDevice">
+ <enum-type name="PdfVersion"/>
+ </object-type>
+ <object-type name="QAbstractTextDocumentLayout">
+ <value-type name="PaintContext" >
+ <include file-name="QAbstractTextDocumentLayout" location="global"/>
+ </value-type>
+ <value-type name="Selection"/>
+ <modify-function signature="setPaintDevice(QPaintDevice*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="draw(QPainter*,QAbstractTextDocumentLayout::PaintContext)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawInlineObject(QPainter*,QRectF,QTextInlineObject,int,QTextFormat)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="update(const QRectF &amp;)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QPyTextObject"/>
+
+ <object-type name="QDesktopServices" since="4.2">
+ <modify-function signature="openUrl(const QUrl&amp;)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QDoubleValidator">
+ <enum-type name="Notation"/>
+ </object-type>
+ <object-type name="QIconEngine">
+ <object-type name="ScaledPixmapArgument"/>
+ <enum-type name="IconEngineHook"/>
+ <modify-function signature="paint(QPainter*,QRect,QIcon::Mode,QIcon::State)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="read(QDataStream&amp;)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="write(QDataStream&amp;)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <!-- ### This makes little sense in Python. Could be reassessed later. -->
+ <modify-function signature="virtual_hook(int,void*)" remove="all"/>
+ </object-type>
+ <object-type name="QImageWriter">
+ <enum-type name="ImageWriterError"/>
+ <modify-function signature="setDevice(QIODevice*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="write(const QImage&amp;)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QIntValidator"/>
+
+ <object-type name="QPainterPathStroker" copyable="false"/>
+ <object-type name="QPixmapCache">
+ <value-type name="Key"/>
+ <add-function signature="find(QPixmapCache::Key&amp;)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpixmapcache-find"/>
+ </add-function>
+ <add-function signature="find(const QString&amp;)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpixmapcache-find"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QRegularExpressionValidator"/>
+
+ <object-type name="QStandardItem">
+ <enum-type name="ItemType"/>
+ <modify-function signature="operator&lt;(QStandardItem)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="read(QDataStream&amp;)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="write(QDataStream&amp;)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+
+ <modify-function signature="appendColumn(const QList&lt;QStandardItem*&gt; &amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="appendRow(const QList&lt;QStandardItem*&gt; &amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="appendRow(QStandardItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="appendRows(const QList&lt;QStandardItem*&gt; &amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="insertColumn(int,const QList&lt;QStandardItem*&gt; &amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRow(int,const QList&lt;QStandardItem*&gt; &amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRows(int,const QList&lt;QStandardItem*&gt; &amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setChild(int,int,QStandardItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditem-setchild-1"/>
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setChild(int,QStandardItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditem-setchild-2"/>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="takeChild(int,int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="clone()const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QSyntaxHighlighter">
+ <modify-function signature="setCurrentBlockUserData(QTextBlockUserData*)">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setDocument(QTextDocument*)">
+ <modify-argument index="1" pyi-type="Optional[PySide6.QtGui.QTextDocument]">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="document()const">
+ <modify-argument index="this">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QTextBlockGroup"/>
+ <object-type name="QTextBlockUserData"/>
+ <object-type name="QTextItem">
+ <enum-type name="RenderFlag" flags="RenderFlags"/>
+ </object-type>
+ <object-type name="QTextList"/>
+ <object-type name="QTextObject"/>
+ <object-type name="QTextObjectInterface" >
+ <modify-function signature="drawObject(QPainter*,QRectF,QTextDocument*,int,QTextFormat)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QValidator">
+ <enum-type name="State"/>
+ <modify-function signature="fixup(QString &amp;)const">
+ <modify-argument index="return">
+ <replace-type modified-type="QString"/>
+ </modify-argument>
+ <inject-code class="native" position="end">
+ <insert-template name="return_QString_native"/>
+ </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qstring-return"/>
+ </modify-function>
+ <modify-function signature="validate(QString &amp;,int &amp;)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="validator_conversionrule"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_tuple_QValidator_QString_int"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QActionEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::ActionAdded || %B-&gt;type() == QEvent::ActionRemoved || %B-&gt;type() == QEvent::ActionChanged"/>
+ <object-type name="QCloseEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Close"/>
+ <object-type name="QContextMenuEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::ContextMenu">
+ <enum-type name="Reason"/>
+ </object-type>
+
+ <value-type name="QEventPoint">
+ <enum-type name="State"/>
+ </value-type>
+ <object-type name="QDragEnterEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::DragEnter">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QDragLeaveEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::DragLeave">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QDragMoveEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::DragMove">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QDropEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Drop">
+ <modify-function signature="source()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QChildWindowEvent" since="6.7"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::ChildWindowAdded || %B-&gt;type() == QEvent::ChildWindowRemoved"/>
+ <object-type name="QEnterEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::Enter"/>
+ <object-type name="QExposeEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Expose"/>
+ <object-type name="QFileOpenEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::FileOpen"/>
+ <object-type name="QFocusEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::FocusIn || %B-&gt;type() == QEvent::FocusOut">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QHelpEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::ToolTip || %B-&gt;type() == QEvent::WhatsThis"/>
+ <object-type name="QHideEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Hide"/>
+ <object-type name="QHoverEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::HoverEnter || %B-&gt;type() == QEvent::HoverLeave || %B-&gt;type() == QEvent::HoverMove"/>
+ <object-type name="QIconDragEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::IconDrag"/>
+
+ <object-type name="QInputMethodEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::InputMethod">
+ <!-- only declare this if ndef QT_NO_INPUTMETHOD -->
+ <enum-type name="AttributeType"/>
+ <value-type name="Attribute">
+ <include file-name="QInputMethodEvent" location="global"/>
+ </value-type>
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ <!-- endif ndef QT_NO_INPUTMETHOD -->
+ </object-type>
+ <object-type name="QInputMethodQueryEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::InputMethodQuery"/>
+
+ <object-type name="QMoveEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Move">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QNativeGestureEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::NativeGesture"/>
+ <object-type name="QPlatformSurfaceEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::PlatformSurface">
+ <enum-type name="SurfaceEventType"/>
+ </object-type>
+ <object-type name="QResizeEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Resize">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QShortcutEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::Shortcut">
+ </object-type>
+ <object-type name="QShowEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::Show"/>
+ <object-type name="QSinglePointEvent"/>
+ <object-type name="QStatusTipEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::StatusTip"/>
+ <object-type name="QTabletEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::TabletMove || %B-&gt;type() == QEvent::TabletPress || %B-&gt;type() == QEvent::TabletRelease">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QToolBarChangeEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::ToolBarChange"/>
+ <object-type name="QWhatsThisClickedEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::WhatsThisClicked"/>
+ <object-type name="QWheelEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Wheel">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+
+ <object-type name="QWindowStateChangeEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::WindowStateChange">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QInputEvent"/>
+ <object-type name="QKeyEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::KeyPress || %B-&gt;type() == QEvent::KeyRelease || %B-&gt;type() == QEvent::ShortcutOverride">
+ <add-function signature="operator!=(QKeySequence::StandardKey)">
+ <inject-code class="target" file="../glue/qtgui.cpp" snippet="qkeyevent-operatornotequal"/>
+ </add-function>
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QMouseEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::MouseButtonDblClick || %B-&gt;type() == QEvent::MouseButtonPress || %B-&gt;type() == QEvent::MouseButtonRelease || %B-&gt;type() == QEvent::MouseMove">
+ <modify-function signature="globalPos() const" deprecated="yes"/>
+ <modify-function signature="localPos() const" deprecated="yes"/>
+ <modify-function signature="pos() const" deprecated="yes"/>
+ <modify-function signature="windowPos() const" deprecated="yes"/>
+ <modify-function signature="screenPos() const" deprecated="yes"/>
+ <modify-function signature="x() const" deprecated="yes"/>
+ <modify-function signature="y() const" deprecated="yes"/>
+ <modify-function signature="globalX() const" deprecated="yes"/>
+ <modify-function signature="globalY() const" deprecated="yes"/>
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QPaintEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Paint"/>
+ <object-type name="QScrollEvent" polymorphic-id-expression="%B-&gt;type() == QEvent::Scroll">
+ <enum-type name="ScrollState"/>
+ </object-type>
+ <object-type name="QPointerEvent" copyable= "false">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QScrollPrepareEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::ScrollPrepare"/>
+
+ <object-type name="QTextFrame" >
+ <extra-includes>
+ <include file-name="QTextCursor" location="global"/>
+ </extra-includes>
+ <value-type name="iterator" >
+ <include file-name="QTextFrame" location="global"/>
+ <add-function signature="__iter__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="__iter__"/>
+ </inject-code>
+ </add-function>
+ <add-function signature="__next__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="__next__">
+ <replace from="%CPPSELF_TYPE" to="QTextFrame::iterator"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+ <add-function signature="__iter__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="__iter_parent__">
+ <replace from="%CPPSELF_TYPE" to="QTextFrame::iterator"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </object-type>
+ <object-type name="QImageIOHandler">
+ <extra-includes>
+ <include file-name="QRect" location="global"/>
+ </extra-includes>
+ <enum-type name="ImageOption"/>
+ <enum-type name="Transformation" flags="Transformations"/>
+ <modify-function signature="setDevice(QIODevice*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QImageReader">
+ <extra-includes>
+ <include file-name="QColor" location="global"/>
+ <include file-name="QRect" location="global"/>
+ <include file-name="QSize" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QImage" location="global"/>
+ </extra-includes>
+ <enum-type name="ImageReaderError"/>
+ <!-- ### This method does not make sense in Python.
+ Update: perhaps it does, but no one is missing it. -->
+ <modify-function signature="read(QImage*)" remove="all"/>
+ <modify-function signature="read()" allow-thread="yes"/>
+ <modify-function signature="setDevice(QIODevice*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QMovie">
+ <extra-includes>
+ <include file-name="QColor" location="global"/>
+ <include file-name="QImage" location="global"/>
+ <include file-name="QPixmap" location="global"/>
+ <include file-name="QRect" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <enum-type name="CacheMode"/>
+ <enum-type name="MovieState"/>
+ <!-- ### "cacheMode()" is an internal method. -->
+ <modify-function signature="setDevice(QIODevice*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QDrag">
+ <extra-includes>
+ <include file-name="QPoint" location="global"/>
+ <include file-name="QPixmap" location="global"/>
+ </extra-includes>
+ <modify-function signature="QDrag(QObject*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="source()const">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="target()const">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setMimeData(QMimeData*)">
+ <modify-argument index="1">
+ <!-- TODO: maybe this is not the best solution -->
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="exec(QFlags&lt;Qt::DropAction&gt;)" allow-thread="yes"/>
+ <add-function signature="exec_(QFlags&lt;Qt::DropAction&gt; @supportedActions@ = Qt::MoveAction)" return-type="Qt::DropAction">
+ <inject-code file="../glue/qtgui.cpp" snippet="qdrag-exec-arg1"/>
+ </add-function>
+ <modify-function signature="exec(QFlags&lt;Qt::DropAction&gt;,Qt::DropAction)" allow-thread="yes"/>
+ <add-function signature="exec_(QFlags&lt;Qt::DropAction&gt;,Qt::DropAction)" return-type="Qt::DropAction">
+ <inject-code file="../glue/qtgui.cpp" snippet="qdrag-exec-arg2"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QStandardItemModel" polymorphic-id-expression="qobject_cast&lt;QStandardItemModel*&gt;(%B)">
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <modify-function signature="takeItem(int,int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeHorizontalHeaderItem(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeVerticalHeaderItem(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="verticalHeaderItem(int)const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="horizontalHeaderItem(int)const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="invisibleRootItem()const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="item(int,int)const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="itemFromIndex(const QModelIndex&amp;)const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="itemPrototype()const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="appendRow(const QList&lt;QStandardItem*&gt;&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="appendRow(QStandardItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="insertRow(int,QStandardItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setHorizontalHeaderItem(int,QStandardItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setItem(int,int,QStandardItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-setitem-1"/>
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItem(int,QStandardItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-setitem-2"/>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemPrototype(const QStandardItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setVerticalHeaderItem(int,QStandardItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-setverticalheaderitem"/>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="takeColumn(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="takeRow(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="findItems(const QString&amp;,QFlags&lt;Qt::MatchFlag&gt;,int)const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="insertColumn(int,const QList&lt;QStandardItem*&gt;&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="insertRow(int,const QList&lt;QStandardItem*&gt;&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="appendColumn(const QList&lt;QStandardItem*&gt;&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="clear()">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-clear"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QClipboard">
+ <extra-includes>
+ <include file-name="QImage" location="global"/>
+ <include file-name="QPixmap" location="global"/>
+ </extra-includes>
+ <enum-type name="Mode"/>
+ <modify-function signature="setPixmap(const QPixmap&amp;, QClipboard::Mode)">
+ <modify-argument index="1" pyi-type="PySide6.QtGui.QPixmap"/>
+ </modify-function>
+ <add-function signature="setPixmap(PyPathLike@path@)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qclipboard-setpixmap"/>
+ </add-function>
+ <modify-function signature="setImage(const QImage&amp;, QClipboard::Mode)">
+ <modify-argument index="1" pyi-type="PySide6.QtGui.QImage"/>
+ </modify-function>
+ <add-function signature="setImage(PyPathLike@path@)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qclipboard-setimage"/>
+ </add-function>
+ <modify-function signature="setMimeData(QMimeData*,QClipboard::Mode)" allow-thread="yes">
+ <modify-argument index="1">
+ <!-- TODO: maybe this is not the best solution -->
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="text(QString&amp;,QClipboard::Mode)const">
+ <modify-argument index="return" pyi-type="Tuple[str, PySide6.QtGui.QClipboard.Mode]">
+ <replace-type modified-type="(retval, subtype)"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qclipboard-text"/>
+ </modify-function>
+ <modify-function signature="mimeData(QClipboard::Mode)const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QPaintEngineState">
+ <extra-includes>
+ <include file-name="QPainterPath" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QTextLayout">
+ <extra-includes>
+ <include file-name="QTextOption" location="global"/>
+ </extra-includes>
+ <enum-type name="CursorMode"/>
+ <enum-type name="GlyphRunRetrievalFlag" flags="GlyphRunRetrievalFlags" since="6.5"/>
+ <value-type name="FormatRange">
+ <include file-name="QTextLayout" location="global"/>
+ </value-type>
+ </object-type>
+ <object-type name="QTextDocument">
+ <extra-includes>
+ <include file-name="QTextBlock" location="global"/>
+ <include file-name="QTextFormat" location="global"/>
+ <include file-name="QTextCursor" location="global"/>
+ </extra-includes>
+ <enum-type name="FindFlag" flags="FindFlags"/>
+ <enum-type name="MarkdownFeature" flags="MarkdownFeatures"/>
+ <enum-type name="MetaInformation"/>
+ <enum-type name="ResourceType" python-type="IntEnum"/>
+ <enum-type name="Stacks" since="4.7"/>
+ <modify-function signature="setDocumentLayout(QAbstractTextDocumentLayout*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="object(int)const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="objectForFormat(const QTextFormat&amp;)const">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="createObject(const QTextFormat&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="print(QPagedPaintDevice*)const" allow-thread="yes" rename="print_"/>
+ </object-type>
+ <object-type name="QTextDocumentWriter" since="4.5"/>
+ <object-type name="QTextTable">
+ <extra-includes>
+ <include file-name="QTextCursor" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QPaintEngine">
+ <enum-type name="DirtyFlag" flags="DirtyFlags"/>
+ <enum-type name="PaintEngineFeature" flags="PaintEngineFeatures"/>
+ <enum-type name="PolygonDrawMode"/>
+ <enum-type name="Type"/>
+ <modify-function signature="begin(QPaintDevice*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="updateState(QPaintEngineState)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawTextItem(QPointF,QTextItem)">
+ <modify-argument index="2" invalidate-after-use="yes"/>
+ </modify-function>
+ <extra-includes>
+ <include file-name="QVarLengthArray" location="global"/>
+ </extra-includes>
+ <!-- ### "setPaintDevice(QPaintDevice*)" is an internal method. -->
+ <modify-function signature="setPaintDevice(QPaintDevice*)" remove="all"/>
+ </object-type>
+
+ <object-type name="QPainter">
+ <extra-includes>
+ <include file-name="QPainterPath" location="global"/>
+ <include file-name="QPixmap" location="global"/>
+ <include file-name="pyside_numpy.h" location="global"/>
+ </extra-includes>
+ <enum-type name="CompositionMode"/>
+ <enum-type name="PixmapFragmentHint" flags="PixmapFragmentHints" since="4.7"/>
+ <enum-type name="RenderHint" flags="RenderHints"/>
+ <value-type name="PixmapFragment" since="4.7">
+ <include file-name="QPainter" location="global"/>
+ </value-type>
+
+ <!-- ### "drawText(...)" is an internal method. -->
+ <modify-function signature="drawText(const QPointF&amp;,const QString&amp;,int,int)" remove="all"/>
+
+
+ <modify-function signature="drawConvexPolygon(const QPoint*,int)" remove="all"/>
+ <add-function signature="drawConvexPolygon(QList&lt;QPoint>)">
+ <inject-code>
+ <insert-template name="qpainter_drawlist"/>
+ </inject-code>
+ </add-function>
+ <modify-function signature="drawConvexPolygon(const QPointF*,int)" remove="all"/>
+ <add-function signature="drawConvexPolygon(QList&lt;QPointF>)">
+ <inject-code>
+ <insert-template name="qpainter_drawlist"/>
+ </inject-code>
+ </add-function>
+ <!-- ### Overloads using QList<T> does the job of these methods -->
+ <modify-function signature="drawLines(const QLine*,int)" remove="all"/>
+ <modify-function signature="drawLines(const QPoint*,int)" remove="all"/>
+ <modify-function signature="drawLines(const QPointF*,int)" remove="all"/>
+ <modify-function signature="drawRects(const QRect*,int)" remove="all"/>
+ <!-- ### -->
+ <!-- PYSIDE-1540: Preferably use the QPolygon overloads first to avoid
+ a costly sequence type check on QPolygon. -->
+ <modify-function signature="drawPoints(const QPoint*,int)" remove="all"/>
+ <add-function signature="drawPoints(QList&lt;QPoint>)" overload-number="2">
+ <inject-code>
+ <insert-template name="qpainter_drawlist"/>
+ </inject-code>
+ </add-function>
+ <add-function signature="drawPoints(QList&lt;QPointF>)" overload-number="3">
+ <inject-code>
+ <insert-template name="qpainter_drawlist"/>
+ </inject-code>
+ </add-function>
+ <modify-function signature="drawPoints(const QPolygon&amp;)" overload-number="0"/>
+ <modify-function signature="drawPoints(const QPolygonF&amp;)" overload-number="1"/>
+ <!-- Add numpy versions as separate functions since passing ndarrays to other
+ typecheck macros causes:
+ FIXME Subscripted generics cannot be used with class and instance checks -->
+ <add-function signature="drawPointsNp(PyArrayObject *@x@, PyArrayObject *@y@)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpainter-drawpointsnp-numpy-x-y"/>
+ <inject-documentation format="target" mode="append">
+ Draws the points specified by two one-dimensional, equally sized numpy arrays
+ representing the x, y values, respectively.
+ </inject-documentation>
+ </add-function>
+
+ <modify-function signature="drawPolygon(const QPoint*,int,Qt::FillRule)" remove="all"/>
+ <add-function signature="drawPolygon(QList&lt;QPoint>,Qt::FillRule)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpainter-drawpolygon"/>
+ </add-function>
+ <modify-function signature="drawPolygon(const QPointF*,int,Qt::FillRule)" remove="all"/>
+ <add-function signature="drawPolygon(QList&lt;QPointF>,Qt::FillRule)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpainter-drawpolygon"/>
+ </add-function>
+ <modify-function signature="drawPolyline(const QPoint*,int)" remove="all"/>
+ <add-function signature="drawPolyline(QList&lt;QPoint>)">
+ <inject-code>
+ <insert-template name="qpainter_drawlist"/>
+ </inject-code>
+ </add-function>
+ <!-- PYSIDE-1366: Preferably use the QPolygon overloads first to avoid
+ a costly sequence type check on QPolygon. -->
+ <modify-function signature="drawPolyline(const QPointF*,int)" remove="all"/>
+ <modify-function signature="drawPolyline(const QPolygon&amp;)" overload-number="0"/>
+ <modify-function signature="drawPolyline(const QPolygonF&amp;)" overload-number="1"/>
+ <add-function signature="drawPolyline(QList&lt;QPointF>)">
+ <inject-code>
+ <insert-template name="qpainter_drawlist"/>
+ </inject-code>
+ </add-function>
+ <modify-function signature="drawTiledPixmap(const QRect&amp;,const QPixmap&amp;,const QPoint&amp;)">
+ <modify-argument index="3">
+ <rename to="pos"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QPainter(QPaintDevice*)">
+ <modify-argument index="1">
+ <no-null-pointer/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="begin(QPaintDevice*)">
+ <modify-argument index="1">
+ <no-null-pointer/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="drawText(QRectF,int,QString,QRectF*)">
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="QRectF"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,QRectF*"/>
+ </inject-code>
+ <inject-documentation format="target" mode="prepend">
+ The function returns the bounding rectangle enclosing the whole text.
+ </inject-documentation>
+ </modify-function>
+ <modify-function signature="drawText(QRect,int,QString,QRect*)">
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="QRect"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,QRect*"/>
+ </inject-code>
+ <inject-documentation format="target" mode="prepend">
+ The function returns the bounding rectangle enclosing the whole text.
+ </inject-documentation>
+ </modify-function>
+ <modify-function signature="drawText(int,int,int,int,int,QString,QRect*)">
+ <modify-argument index="7">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,QRect*"/>
+ </inject-code>
+ <inject-documentation format="target" mode="prepend">
+ The function returns the bounding rectangle enclosing the whole text.
+ </inject-documentation>
+ </modify-function>
+ <add-function signature="__enter__()" return-type="QPainter">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpainter-enter"/>
+ </add-function>
+ <add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qpainter-exit"/>
+ </add-function>
+ </object-type>
+
+ <value-type name="QGenericMatrix" generate="no"/>
+ <value-type name="QMatrix2x2" since="4.6">
+ <modify-function signature="QMatrix2x2(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="4"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="4"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix2x2(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="4"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="4"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix2x3" since="4.6">
+ <modify-function signature="QMatrix2x3(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="6"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="6"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix2x3(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="6"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="6"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix2x4" since="4.6">
+ <modify-function signature="QMatrix2x4(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="8"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="8"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix2x4(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="8"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="8"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix3x2" since="4.6">
+ <modify-function signature="QMatrix3x2(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="6"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="6"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix3x2(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="6"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="6"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix3x3" since="4.6">
+ <modify-function signature="QMatrix3x3(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="9"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="9"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix3x3(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="9"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="9"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix3x4" since="4.6">
+ <modify-function signature="QMatrix3x4(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="12"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="12"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix3x4(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="12"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="12"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix4x2" since="4.6">
+ <modify-function signature="QMatrix4x2(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="8"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="8"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix4x2(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="8"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="8"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix4x3" since="4.6">
+ <modify-function signature="QMatrix4x3(const float*)" remove="all"/>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="12"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="12"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="QMatrix4x3(PySequence*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_constructor">
+ <replace from="%SIZE" to="12"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ <add-function signature="data()" return-type="float">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="12"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <value-type name="QMatrix4x4" since="4.6">
+ <enum-type name="Flag" flags="Flags"/>
+
+ <!-- Qt5: HAIRY TRICK ALERT ahead!
+ Qt5 partially replaced 'qreal' by float.
+ That had the side effect that all matrix types did not work any longer.
+
+ Reason (I guess):
+
+ The signature "QList<qreal>" is needed by the __reduce__ methods,
+ but created by some other object used elsewhere.
+ After the matrix type was changed, "QList<float>" was created nowhere.
+
+ I don't know an explicit way to produce the right conversion function, so what I did
+ was to create a dummy function and immediately delete it again.
+ This has the desired effect of creating the implicitly needed "QList<float>"
+ conversion, although the dummy function goes away.
+
+ Q: Do you know a better solution?
+ -->
+ <add-function signature="__dummy(const QList&lt;float &gt; &amp;)"/>
+ <modify-function signature="__dummy(const QList&lt;float &gt; &amp;)" remove="all"/>
+ <!-- that was the trick ^^^^^^^^^^^^^^^^^^^^^^ -->
+
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code_matrix">
+ <replace from="%MATRIX_SIZE" to="16"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code_matrix">
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="16"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!-- ### "QMatrix4x4(const float*,int,int)" is an internal constructor. -->
+ <modify-function signature="QMatrix4x4(const float*,int,int)" remove="all"/>
+
+ <modify-function signature="QMatrix4x4(const float*)">
+ <modify-argument index="1">
+ <replace-type modified-type="PySequence"/>
+ <array/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qmatrix4x4"/>
+ </modify-function>
+ <modify-function signature="data()">
+ <inject-code class="target" position="beginning">
+ <insert-template name="matrix_data_function">
+ <replace from="%MATRIX_SIZE" to="16"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="Tuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qmatrix4x4-copydatato"/>
+ </modify-function>
+
+ <modify-function signature="inverted(bool*)const">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtGui.QMatrix4x4, bool]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+
+ <!-- ### "constData() const" and "data() const" are unnecessary in Python and their function is performed by "data()". -->
+ <modify-function signature="data()const" remove="all"/>
+ <modify-function signature="constData()const" remove="all"/>
+ <!-- ### -->
+ <modify-function signature="operator()(int,int)const" remove="all"/>
+ <modify-function signature="operator()(int,int)" remove="all"/>
+ <add-function signature="__mgetitem__" return-type="PyObject*">
+ <inject-code file="../glue/qtgui.cpp" snippet="qmatrix4x4-mgetitem"/>
+ </add-function>
+ </value-type>
+
+ _______ end of matrix block _______ -->
+
+ <value-type name="QQuaternion" since="4.6">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.scalar(), %CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.scalar(), %CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <!-- There can be only one return type. -->
+ <modify-function signature="getAxisAndAngle(float*,float*,float*,float*)const" remove="all"/>
+ <modify-function signature="getAxisAndAngle(QVector3D*,float*)const">
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtGui.QVector3D, float]">
+ <replace-type modified-type="(QVector3D, float)"/>
+ </modify-argument>
+ <modify-argument index="1"><remove-argument/></modify-argument>
+ <modify-argument index="2"><remove-argument/></modify-argument>
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qquaternion-getaxisandangle-vector3d-float"/>
+ </modify-function>
+ <modify-function signature="getEulerAngles(float*,float*,float*)const">
+ <modify-argument index="return" pyi-type="Tuple[float, float, float]">
+ <replace-type modified-type="(float, float, float)"/>
+ </modify-argument>
+ <modify-argument index="1"><remove-argument/></modify-argument>
+ <modify-argument index="2"><remove-argument/></modify-argument>
+ <modify-argument index="3"><remove-argument/></modify-argument>
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qquaternion-geteulerangles"/>
+ </modify-function>
+ </value-type>
+
+ <object-type name="QTouchEvent" since="4.6">
+ <add-function signature="__repr__" return-type="PyObject">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_qdebug_gui"/>
+ </inject-code>
+ </add-function>
+ </object-type>
+
+ <object-type name="QInputDevice">
+ <enum-type name="Capability" flags="Capabilities"/>
+ <enum-type name="DeviceType" flags="DeviceTypes"/>
+ </object-type>
+
+ <value-type name="QVector2D" since="4.6">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="dd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="dd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ </value-type>
+ <value-type name="QVector3D" since="4.6">
+ <extra-includes>
+ <include file-name="QMatrix4x4" location="global"/>
+ </extra-includes>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="ddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="ddd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ </value-type>
+ <value-type name="QVector4D" since="4.6">
+ <extra-includes>
+ <include file-name="QMatrix4x4" location="global"/>
+ </extra-includes>
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="repr_code">
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__reduce__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="reduce_code">
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+
+ <add-function signature="toTuple" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="to_tuple">
+ <replace from="%TT_FORMAT" to="dddd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()"/>
+ </insert-template>
+ </inject-code>
+ </add-function>
+ </value-type>
+
+ <object-type name="QSessionManager">
+ <extra-includes>
+ </extra-includes>
+ <enum-type name="RestartHint"/>
+ <!-- ### -->
+ </object-type>
+
+ <!-- Qt5: here the new QWindow stuff and what it pulls in -->
+ <object-type name="QBackingStore"/>
+ <object-type name="QSurface">
+ <enum-type name="SurfaceClass"/>
+ <enum-type name="SurfaceType"/>
+ </object-type>
+ <rejection class="QSurface" field-name="m_reserved"/>
+ <value-type name="QSurfaceFormat">
+ <enum-type name="ColorSpace"/>
+ <enum-type name="FormatOption" flags="FormatOptions"/>
+ <enum-type name="OpenGLContextProfile"/>
+ <enum-type name="RenderableType"/>
+ <enum-type name="SwapBehavior"/>
+ </value-type>
+ <object-type name="QOffscreenSurface"/>
+ <primitive-type name="QPlatformSurface">
+ <extra-includes>
+ <include file-name="QtGui/qpa/qplatformsurface.h" location="global"/>
+ </extra-includes>
+ </primitive-type>
+
+ <object-type name="QWindow" delete-in-main-thread="true" polymorphic-base="true">
+ <enum-type name="AncestorMode"/>
+ <enum-type name="Visibility"/>
+ <modify-function signature="raise()" rename="raise_"/>
+ <!-- see QWidget::nativeEvent(), QAbstractNativeEventFilter::nativeEventFilter() -->
+ <modify-function signature="nativeEvent(const QByteArray &amp;,void*,qintptr*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion_variables"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code position="end">
+ <insert-template name="return_native_eventfilter"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="fromWinId(WId)">
+ <modify-argument index="1">
+ <replace-type modified-type="long"/>
+ </modify-argument>
+ <inject-code file="../glue/qtgui.cpp" snippet="qwindow-fromWinId"/>
+ </modify-function>
+ <modify-function signature="show()" allow-thread="yes"/>
+ <modify-function signature="showFullScreen()" allow-thread="yes"/>
+ <modify-function signature="showMaximized()" allow-thread="yes"/>
+ <modify-function signature="showMinimized()" allow-thread="yes"/>
+ <modify-function signature="showNormal()" allow-thread="yes"/>
+ </object-type>
+
+ <object-type name="QGuiApplication">
+ <extra-includes>
+ <include file-name="QBasicTimer" location="global"/>
+ <include file-name="QFont" location="global"/>
+ <include file-name="QFontMetrics" location="global"/>
+ <include file-name="QPalette" location="global"/>
+ <include file-name="QIcon" location="global"/>
+ <include file-name="QLocale" location="global"/>
+ <include file-name="pysideqapp.h" location="global"/>
+ <include file-name="pysidecleanup.h" location="global"/>
+ <!-- QOverrideCursorGuard -->
+ <include file-name="qtguihelper.h" location="local"/>
+ </extra-includes>
+ <modify-function signature="QGuiApplication(int&amp;,char**,int)" access="private"/>
+ <add-function signature="QGuiApplication(QStringList)">
+ <inject-code file="../glue/qtgui.cpp" snippet="qguiapplication-1"/>
+ </add-function>
+ <add-function signature="QGuiApplication()">
+ <inject-code file="../glue/qtgui.cpp" snippet="qguiapplication-2"/>
+ </add-function>
+ <inject-code class="native" position="beginning" file="../glue/qtgui.cpp" snippet="qguiapplication-init"/>
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="int">
+ <inject-code file="../glue/qtgui.cpp" snippet="qguiapplication-exec"/>
+ </add-function>
+ <add-function signature="nativeInterface()const" return-type="PyObject">
+ <modify-argument index="return"> <!-- Suppress return value heuristics -->
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qguiapplication-nativeInterface"/>
+ </add-function>
+ <modify-function signature="setOverrideCursor(const QCursor&amp;)">
+ <modify-argument index="return" pyi-type="PyObject">
+ <replace-type modified-type="QtGuiHelper::QOverrideCursorGuard*"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp"
+ snippet="qguiapplication-setoverridecursor"/>
+ </modify-function>
+ </object-type>
+
+ <namespace-type name="QNativeInterface" private="yes" since="6.7">
+ <object-type name="QX11Application" private="yes" disable-wrapper="yes"
+ force-abstract="yes">
+ <configuration condition="QT_CONFIG(xcb)"/>
+ <modify-function signature="display()const">
+ <modify-argument index="return">
+ <replace-type modified-type="int"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp"
+ snippet="qx11application-resource-ptr"/>
+ </modify-function>
+ <modify-function signature="connection()const">
+ <modify-argument index="return">
+ <replace-type modified-type="int"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp"
+ snippet="qx11application-resource-ptr"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QWindowsScreen" private="yes" disable-wrapper="yes"
+ force-abstract="yes">
+ <configuration condition="#ifdef Q_OS_WIN"/>
+ </object-type>
+ </namespace-type>
+
+ <object-type name="QOpenGLContext">
+ <enum-type name="OpenGLModuleType"/>
+ </object-type>
+ <object-type name="QOpenGLContextGroup"/>
+ <!-- Compile error on Windows: QOpenGLPaintDevice::QOpenGLPaintDevice(const QOpenGLPaintDevice &)': attempting to reference a deleted function
+ <object-type name="QOpenGLPaintDevice"/>
+ -->
+ <object-type name="QOpenGLExtraFunctions">
+ <extra-includes>
+ <include file-name="QtCore/QVarLengthArray" location="global"/>
+ <include file-name="sbkcpptonumpy.h" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qopenglextrafunctions-glgeti-v-return-size"/>
+
+ <!-- Exlusions due to compile errors -->
+ <modify-function signature="glEndTransformFeedback()" remove="all"/>
+ <modify-function signature="glPauseTransformFeedback()" remove="all"/>
+ <modify-function signature="glResumeTransformFeedback()" remove="all"/>
+ <modify-function signature="^glClearBuffer.*\(.*\*.*$">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glDebugMessageControl(GLenum,GLenum,GLenum,GLsizei,const GLuint*,GLboolean)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glDeleteProgramPipelines(GLsizei,const GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glDeleteQueries(GLsizei,const GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glDeleteSamplers(GLsizei,const GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glDeleteTransformFeedbacks(GLsizei,const GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glDeleteVertexArrays(GLsizei,const GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glDrawBuffers(GLsizei,const GLenum*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGenProgramPipelines(GLsizei,GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGenQueries(GLsizei,GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGenSamplers(GLsizei,GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGenTransformFeedbacks(GLsizei,GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGenVertexArrays(GLsizei,GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetActiveUniformBlockiv(GLuint,GLuint,GLenum,GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetActiveUniformsiv(GLuint,GLsizei,const GLuint*,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetFramebufferParameteriv(GLenum,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetBooleani_v(GLenum,GLuint,GLboolean*)">
+ <modify-argument index="return" pyi-type="Union[bool,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qopenglextrafunctions-glgetbooleani-v"/>
+ </modify-function>
+ <!-- FIXME PYSIDE 7: Use the remove array modification and use
+ the version with return value instead -->
+ <modify-function signature="glGetIntegeri_v(GLenum,GLuint,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <add-function signature="glGetIntegeri_v(GLuint,GLuint)" return-type="PyObject">
+ <modify-argument index="return" pyi-type="Union[int,numpy.ndarray]"/>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qopenglextrafunctions-glgetintegeri-v"/>
+ </add-function>
+ <modify-function signature="glGetInternalformativ(GLenum,GLenum,GLenum,GLsizei,GLint*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetMultisamplefv(GLenum,GLuint,GLfloat*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetProgramInterfaceiv(GLuint,GLenum,GLenum,GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetProgramPipelineiv(GLuint,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetProgramResourceiv(GLuint,GLenum,GLuint,GLsizei,const GLenum*,GLsizei,GLsizei*,GLint*)">
+ <modify-argument index="5"><array/></modify-argument>
+ <modify-argument index="7"><array/></modify-argument>
+ <modify-argument index="8"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetQueryObjectuiv(GLuint,GLenum,GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetQueryiv(GLenum,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetSamplerParameterfv(GLuint,GLenum,GLfloat*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetSamplerParameteriv(GLuint,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetSamplerParameterIiv(GLuint,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetSamplerParameterIuiv(GLuint,GLenum,GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetTexLevelParameteriv(GLenum,GLint,GLenum,GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetTexLevelParameterfv(GLenum,GLint,GLenum,GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetTexParameterIiv(GLenum,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetTexParameterIuiv(GLenum,GLenum,GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetnUniformiv(GLuint,GLint,GLsizei,GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetnUniformuiv(GLuint,GLint,GLsizei,GLuint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetUniformuiv(GLuint,GLint,GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetVertexAttribIiv(GLuint,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetVertexAttribIuiv(GLuint,GLenum,GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glInvalidateFramebuffer(GLenum,GLsizei,const GLenum*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glInvalidateSubFramebuffer(GLenum,GLsizei,const GLenum*,GLint,GLint,GLsizei,GLsizei)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform1fv(GLuint,GLint,GLsizei,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform1iv(GLuint,GLint,GLsizei,const GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform1uiv(GLuint,GLint,GLsizei,const GLuint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform2fv(GLuint,GLint,GLsizei,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform2iv(GLuint,GLint,GLsizei,const GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform2uiv(GLuint,GLint,GLsizei,const GLuint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform3fv(GLuint,GLint,GLsizei,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform3iv(GLuint,GLint,GLsizei,const GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform3uiv(GLuint,GLint,GLsizei,const GLuint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform4fv(GLuint,GLint,GLsizei,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform4iv(GLuint,GLint,GLsizei,const GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniform4uiv(GLuint,GLint,GLsizei,const GLuint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix2fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix2x3fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix2x4fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix3fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix3x2fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix3x4fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix4fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix4x2fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glProgramUniformMatrix4x3fv(GLuint,GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="5"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^glSamplerParameterI?u?[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^glTexParameterI?u?[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniform1uiv(GLint,GLsizei,const GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniform2uiv(GLint,GLsizei,const GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniform3uiv(GLint,GLsizei,const GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniform4uiv(GLint,GLsizei,const GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniformMatrix2x3fv(GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniformMatrix2x4fv(GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniformMatrix3x2fv(GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniformMatrix3x4fv(GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniformMatrix4x2fv(GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glUniformMatrix4x3fv(GLint,GLsizei,GLboolean,const GLfloat*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glVertexAttribI4iv(GLuint,const GLint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glVertexAttribI4uiv(GLuint,const GLuint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetStringi(GLenum,GLuint)">
+ <modify-argument index="return">
+ <replace-type modified-type="QString"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp"
+ snippet="glgetstring-return"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QOpenGLFunctions">
+ <extra-includes>
+ <include file-name="QtCore/QVarLengthArray" location="global"/>
+ <include file-name="sbkcpptonumpy.h" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qopenglfunctions-glgetv-return-size"/>
+
+ <enum-type name="OpenGLFeature" flags="OpenGLFeatures"/>
+ <add-function signature="glGetShaderSource(GLuint @shader@)" return-type="const char *">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="glgetshadersource"/>
+ </add-function>
+ <add-function signature="glShaderSource(GLuint @shader@,const QString &amp; @source@)">
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="glshadersource"/>
+ </add-function>
+ <modify-function signature="glGetAttachedShaders(GLuint,GLsizei,GLsizei*,GLuint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetBufferParameteriv(GLenum,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetFramebufferAttachmentParameteriv(GLenum,GLenum,GLenum,GLint*)">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetBooleanv(GLenum,GLboolean*)">
+ <modify-argument index="return" pyi-type="Union[bool,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qopenglfunctions-glgetbooleanv"/>
+ </modify-function>
+ <!-- FIXME PYSIDE 7: Use the remove array modification and use
+ the version with return value instead -->
+ <modify-function signature="glGetFloatv(GLenum,GLfloat*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <add-function signature="glGetFloatv(GLuint)" return-type="PyObject">
+ <modify-argument index="return" pyi-type="Union[float,numpy.ndarray]"/>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qopenglfunctions-glgetfloatv"/>
+ </add-function>
+ <!-- FIXME PYSIDE 7: Use the remove array modification and use
+ the version with return value instead -->
+ <modify-function signature="glGetIntegerv(GLenum,GLint*)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <add-function signature="glGetIntegerv(GLuint)" return-type="PyObject">
+ <modify-argument index="return" pyi-type="Union[int,numpy.ndarray]"/>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qopenglfunctions-glgetintegerv"/>
+ </add-function>
+ <modify-function signature="glGetProgramiv(GLuint,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetRenderbufferParameteriv(GLenum,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetShaderiv(GLuint,GLenum,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetShaderPrecisionFormat(GLenum,GLenum,GLint*,GLint*)">
+ <modify-argument index="3"><array/></modify-argument>
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^glDelete.*s\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^glGen[A-Z].*s\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^gl(Get)?TexParameterI?u?[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^glUniformMatrix\dfv\(.*$">
+ <modify-argument index="4"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^gl(Get)?Uniform\d?.v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^glVertexAttrib\dfv\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="^glGetVertexAttrib[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="glGetString(GLenum)">
+ <modify-argument index="return">
+ <replace-type modified-type="QString"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="glGetString_return_QString"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="glShaderBinary(GLint,const GLuint*,GLenum,const void*,GLint)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ </object-type>
+ <!-- Classes are result of a macro expansion in src/gui/opengl/qopenglversionfunctions.h
+ <object-type name="QOpenGLFunctions_1_0"/>
+ <object-type name="QOpenGLFunctions_1_1"/>
+ <object-type name="QOpenGLFunctions_1_2"/>
+ <object-type name="QOpenGLFunctions_1_3"/>
+ <object-type name="QOpenGLFunctions_1_4"/>
+ <object-type name="QOpenGLFunctions_1_5"/>
+ <object-type name="QOpenGLFunctions_2_0">
+ <object-type name="QOpenGLFunctions_2_1"/>
+ <object-type name="QOpenGLFunctions_3_0"/>
+ <object-type name="QOpenGLFunctions_3_1"/>
+ <object-type name="QOpenGLFunctions_3_2_Compatibility"/>
+ <object-type name="QOpenGLFunctions_3_2_Core"/>
+ <object-type name="QOpenGLFunctions_3_3_Compatibility"/>
+ <object-type name="QOpenGLFunctions_3_3_Core"/>
+ <object-type name="QOpenGLFunctions_4_0_Compatibility"/>
+ <object-type name="QOpenGLFunctions_4_0_Core"/>
+ <object-type name="QOpenGLFunctions_4_1_Compatibility"/>
+ <object-type name="QOpenGLFunctions_4_1_Core"/>
+ <object-type name="QOpenGLFunctions_4_2_Compatibility"/>
+ <object-type name="QOpenGLFunctions_4_2_Core"/>
+ <object-type name="QOpenGLFunctions_4_3_Compatibility"/>
+ <object-type name="QOpenGLFunctions_4_3_Core"/>
+ <object-type name="QOpenGLFunctions_4_4_Compatibility" since="5.5/>
+ <object-type name="QOpenGLFunctions_4_4_Core"/>
+ <object-type name="QOpenGLFunctions_4_5_Compatibility/>
+ <object-type name="QOpenGLFunctions_4_5_Core"/>
+ <object-type name="QOpenGLFunctions_ES2"/>
+ -->
+ <value-type name="QPageLayout">
+ <enum-type name="Mode"/>
+ <enum-type name="Orientation"/>
+ <enum-type name="Unit"/>
+ </value-type>
+ <value-type name="QPageRanges">
+ <value-type name="Range"/>
+ </value-type>
+ <value-type name="QPageSize">
+ <enum-type name="PageSizeId"/>
+ <enum-type name="Unit"/>
+ <enum-type name="SizeMatchPolicy"/>
+ </value-type>
+ <object-type name="QPaintDeviceWindow"/>
+ <value-type name="QPixelFormat">
+ <enum-type name="AlphaUsage"/>
+ <enum-type name="AlphaPosition"/>
+ <enum-type name="AlphaPremultiplied"/>
+ <enum-type name="ByteOrder"/>
+ <enum-type name="ColorModel"/>
+ <enum-type name="TypeInterpretation"/>
+ <enum-type name="YUVLayout"/>
+ </value-type>
+ <object-type name="QPdfWriter"/>
+ <object-type name="QPointingDevice">
+ <enum-type name="PointerType" flags="PointerTypes"/>
+ <enum-type name="GrabTransition"/>
+ </object-type>
+ <value-type name="QPointingDeviceUniqueId"/>
+ <value-type name="QRawFont">
+ <enum-type name="AntialiasingType"/>
+ <enum-type name="LayoutFlag" flags="LayoutFlags"/>
+ <modify-function signature="advancesForGlyphIndexes(const quint32*,QPointF*,int)const" remove="all"/>
+ <modify-function signature="advancesForGlyphIndexes(const quint32*,QPointF*,int,QFlags&lt;QRawFont::LayoutFlag&gt;)const" remove="all"/>
+ <modify-function signature="glyphIndexesForChars(const QChar*,int,quint32*,int*)const" remove="all"/>
+ <modify-function signature="loadFromData(const QByteArray&amp;,qreal, QFont::HintingPreference)" allow-thread="yes"/>
+ <modify-function signature="loadFromFile(const QString&amp;,qreal, QFont::HintingPreference)" allow-thread="yes"/>
+ </value-type>
+ <object-type name="QRasterWindow"/>
+ <object-type name="QScreen">
+ <modify-function signature="grabWindow(WId,int,int,int,int)">
+ <modify-argument index="1">
+ <replace-type modified-type="long"/>
+ </modify-argument>
+ <inject-code file="../glue/qtgui.cpp" snippet="qscreen-grabWindow"/>
+ </modify-function>
+ <add-function signature="nativeInterface()const" return-type="PyObject">
+ <modify-argument index="return"> <!-- Suppress return value heuristics -->
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp"
+ snippet="qscreen-nativeInterface"/>
+ </add-function>
+ </object-type>
+ <object-type name="QStyleHints"/>
+
+ <object-type name="QUndoCommand">
+ <modify-function signature="mergeWith(const QUndoCommand*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QUndoGroup">
+ <modify-function signature="addStack(QUndoStack*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeStack(QUndoStack*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QUndoStack">
+ <modify-function signature="createUndoAction(QObject*,const QString&amp;)const">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="createRedoAction(QObject*,const QString&amp;)const">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="push(QUndoCommand*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <namespace-type name="QtGuiHelper" visible="no">
+ <object-type name="QOverrideCursorGuard" copyable="no">
+ <add-function signature="__enter__()" return-type="QtGuiHelper::QOverrideCursorGuard">
+ <inject-code file="../glue/qtcore.cpp" snippet="default-enter"/>
+ </add-function>
+ <add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
+ <inject-code>%CPPSELF.restoreOverrideCursor();</inject-code>
+ </add-function>
+ </object-type>
+ </namespace-type>
+
+ <opaque-container name="QList" opaque-containers="QVector2D:QVector2DList;QVector3D:QVector3DList;QVector4D:QVector4DList"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_mac.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_mac.xml
new file mode 100644
index 000000000..c4f16911e
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_mac.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtGui"/>
diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_rhi.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_rhi.xml
new file mode 100644
index 000000000..22ab56e20
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_rhi.xml
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtGui">
+ <value-type name="QRhiDepthStencilClearValue" since="6.6" private="yes"/>
+ <value-type name="QRhiViewport" since="6.6" private="yes"/>
+ <value-type name="QRhiScissor" since="6.6" private="yes"/>
+ <value-type name="QRhiVertexInputBinding" since="6.6" private="yes">
+ <enum-type name="Classification"/>
+ </value-type>
+ <value-type name="QRhiVertexInputAttribute" since="6.6" private="yes">
+ <enum-type name="Format"/>
+ </value-type>
+ <value-type name="QRhiVertexInputLayout" since="6.6" private="yes">
+ <add-function signature="setBindings(QList&lt;QRhiVertexInputBinding&gt;@bindings@)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qrhi-initializer-list"/>
+ </add-function>
+ <add-function signature="setAttributes(QList&lt;QRhiVertexInputAttribute&gt;@attributes@)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qrhi-initializer-list"/>
+ </add-function>
+ </value-type>
+ <value-type name="QRhiShaderStage" since="6.6" private="yes">
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="QRhiShaderResourceBinding" since="6.6" private="yes">
+ <enum-type name="Type"/>
+ <enum-type name="StageFlag" flags="StageFlags"/>
+ <value-type name="TextureAndSampler" private="yes"/>
+ <value-type name="Data" private="yes">
+ <value-type name="StorageImageData" private="yes"/>
+ <value-type name="StorageBufferData" private="yes"/>
+ </value-type>
+ </value-type>
+ <value-type name="QRhiColorAttachment" since="6.6" private="yes"/>
+ <value-type name="QRhiTextureRenderTargetDescription" since="6.6" private="yes">
+ <add-function signature="setColorAttachments(QList&lt;QRhiColorAttachment&gt;@bcolor_attachments@)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qrhi-initializer-list"/>
+ </add-function>
+ </value-type>
+ <value-type name="QRhiTextureSubresourceUploadDescription" since="6.6" private="yes"/>
+ <value-type name="QRhiTextureUploadEntry" since="6.6" private="yes"/>
+ <value-type name="QRhiTextureUploadDescription" since="6.6" private="yes">
+ <add-function signature="setEntries(QList&lt;QRhiTextureUploadEntry&gt;@entries@)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qrhi-initializer-list"/>
+ </add-function>
+ </value-type>
+ <value-type name="QRhiTextureCopyDescription" since="6.6" private="yes"/>
+ <value-type name="QRhiReadbackDescription" since="6.6" private="yes"/>
+ <value-type name="QRhiNativeHandles" since="6.6" private="yes"/>
+ <object-type name="QRhiResource" since="6.6" private="yes">
+ <enum-type name="Type"/>
+ </object-type>
+ <object-type name="QRhiBuffer" since="6.6" private="yes">
+ <enum-type name="Type"/>
+ <enum-type name="UsageFlag" flags="UsageFlags"/>
+ <!-- const char * mixup -->
+ <modify-function signature="beginFullDynamicBufferUpdateForCurrentFrame()" remove="all"/>
+ </object-type>
+ <object-type name="QRhiTexture" since="6.6" private="yes">
+ <enum-type name="Format"/>
+ <enum-type name="Flag" flags="Flags"/>
+ </object-type>
+ <object-type name="QRhiSampler" since="6.6" private="yes">
+ <enum-type name="Filter"/>
+ <enum-type name="AddressMode"/>
+ <enum-type name="CompareOp"/>
+ </object-type>
+ <object-type name="QRhiRenderBuffer" since="6.6" private="yes">
+ <enum-type name="Type"/>
+ <enum-type name="Flag" flags="Flags"/>
+ </object-type>
+ <object-type name="QRhiRenderPassDescriptor" since="6.6" private="yes"/>
+ <object-type name="QRhiRenderTarget" since="6.6" private="yes"/>
+ <object-type name="QRhiSwapChainRenderTarget" since="6.6" private="yes"/>
+ <object-type name="QRhiTextureRenderTarget" since="6.6" private="yes">
+ <enum-type name="Flag" flags="Flags"/>
+ </object-type>
+ <object-type name="QRhiShaderResourceBindings" since="6.6" private="yes">
+ <enum-type name="UpdateFlag" flags="UpdateFlags"/>
+ <modify-field name="BINDING_PREALLOC" remove="true"/>
+ <add-function signature="setBindings(QList&lt;QRhiShaderResourceBinding&gt;@bindings@)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp" snippet="qrhi-initializer-list"/>
+ </add-function>
+ </object-type>
+ <object-type name="QRhiGraphicsPipeline" since="6.6" private="yes">
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="BlendOp"/>
+ <enum-type name="Topology"/>
+ <enum-type name="CullMode"/>
+ <enum-type name="FrontFace"/>
+ <enum-type name="ColorMaskComponent" flags="ColorMask"/>
+ <enum-type name="BlendFactor"/>
+ <enum-type name="CompareOp"/>
+ <enum-type name="StencilOp"/>
+ <enum-type name="PolygonMode"/>
+ <value-type name="StencilOpState" private="yes"/>
+ <value-type name="TargetBlend" private="yes"/>
+ <add-function signature="setShaderStages(QList&lt;QRhiShaderStage&gt;@stages@)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp"
+ snippet="qrhi-initializer-list"/>
+ </add-function>
+ <add-function signature="setTargetBlends(QList&lt;QRhiGraphicsPipeline::TargetBlend&gt;@blends@)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp"
+ snippet="qrhi-initializer-list"/>
+ </add-function>
+ </object-type>
+ <object-type name="QRhiSwapChain" since="6.6" private="yes">
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="Format"/>
+ <enum-type name="StereoTargetBuffer"/>
+ </object-type>
+ <object-type name="QRhiComputePipeline" since="6.6" private="yes">
+ <enum-type name="Flag" flags="Flags"/>
+ </object-type>
+ <object-type name="QRhiCommandBuffer" since="6.6" private="yes">
+ <enum-type name="BeginPassFlag" flags="BeginPassFlags"/>
+ <enum-type name="IndexFormat"/>
+ <modify-function signature="^setVertexInput\(.*\)$" remove="all"/>
+ <add-function signature="setVertexInput(int@startBinding@,QList&lt;std::pair&lt;QRhiBuffer*,quint32&gt;&gt;@bindings@,QRhiBuffer*@indexBuf@=nullptr,quint32@indexOffset@=0,QRhiCommandBuffer::IndexFormat @indexFormat@ = QRhiCommandBuffer::IndexUInt16)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtgui.cpp"
+ snippet="qrhi-commandbuffer-setvertexinput"/>
+ </add-function>
+ </object-type>
+ <value-type name="QRhiReadbackResult" since="6.6" private="yes"/>
+ <object-type name="QRhiResourceUpdateBatch" since="6.6" private="yes"/>
+ <value-type name="QRhiDriverInfo" since="6.6" private="yes">
+ <enum-type name="DeviceType"/>
+ </value-type>
+ <value-type name="QRhiStats" since="6.6" private="yes"/>
+ <value-type name="QRhiInitParams" since="6.6" private="yes"/>
+ <value-type name="QRhiNullInitParams" since="6.6" private="yes"/>
+ <value-type name="QRhiGles2InitParams" since="6.6" private="yes"/>
+ <value-type name="QRhiGles2NativeHandles" since="6.6" private="yes"/>
+ <?if windows?>
+ <value-type name="QRhiD3D11InitParams" since="6.6" private="yes"/>
+ <value-type name="QRhiD3D11NativeHandles" since="6.6" private="yes"/>
+ <value-type name="QRhiD3D12InitParams" since="6.6" private="yes"/>
+ <value-type name="QRhiD3D12NativeHandles" since="6.6" private="yes"/>
+ <?endif?>
+ <?if darwin?>
+ <value-type name="QRhiMetalInitParams" since="6.6" private="yes"/>
+ <?endif?>
+
+ <object-type name="QRhi" since="6.6" private="yes">
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="Implementation"/>
+ <enum-type name="FrameOpResult"/>
+ <enum-type name="Feature"/>
+ <enum-type name="BeginFrameFlag" flags="BeginFrameFlags"/>
+ <enum-type name="EndFrameFlag" flags="EndFrameFlags"/>
+ <enum-type name="ResourceLimit"/>
+ </object-type>
+
+ <value-type name="QShader" since="6.6" private="yes">
+ <enum-type name="Stage"/>
+ <enum-type name="Source"/>
+ <enum-type name="Variant"/>
+ <enum-type name="SerializedFormatVersion"/>
+ </value-type>
+ <value-type name="QShaderCode" since="6.6" private="yes"/>
+ <value-type name="QShaderKey" since="6.6" private="yes"/>
+ <value-type name="QShaderVersion" since="6.6" private="yes">
+ <enum-type name="Flag" flags="Flags"/>
+ </value-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_win.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_win.xml
new file mode 100644
index 000000000..b3b8a75b6
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_win.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtGui">
+ <primitive-type name="HBITMAP" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtgui.cpp" snippet="return-pylong-voidptr"/>
+ <target-to-native>
+ <add-conversion type="PyLong" file="../glue/qtgui.cpp"
+ snippet="conversion-pylong"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="HICON" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtgui.cpp" snippet="return-pylong-voidptr"/>
+ <target-to-native>
+ <add-conversion type="PyLong" file="../glue/qtgui.cpp"
+ snippet="conversion-pylong"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="HMONITOR" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtgui.cpp" snippet="return-pylong-voidptr"/>
+ <target-to-native>
+ <add-conversion type="PyLong" file="../glue/qtgui.cpp"
+ snippet="conversion-pylong"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <primitive-type name="HRGN" target-lang-api-name="PyLong">
+ <conversion-rule>
+ <native-to-target file="../glue/qtgui.cpp" snippet="return-pylong-voidptr"/>
+ <target-to-native>
+ <add-conversion type="PyLong" file="../glue/qtgui.cpp"
+ snippet="conversion-pylong"/>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml
new file mode 100644
index 000000000..70331e29c
--- /dev/null
+++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_x11.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtGui">
+ <custom-type name="_XDisplay"/>
+ <custom-type name="xcb_connection_t"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtHelp/CMakeLists.txt b/sources/pyside6/PySide6/QtHelp/CMakeLists.txt
new file mode 100644
index 000000000..7bf46dcef
--- /dev/null
+++ b/sources/pyside6/PySide6/QtHelp/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtHelp)
+
+set(QtHelp_SRC
+${QtHelp_GEN_DIR}/qcompressedhelpinfo_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpcontentitem_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpcontentmodel_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpcontentwidget_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpglobal_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpengine_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpenginecore_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpfilterdata_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpfilterengine_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpfiltersettingswidget_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpindexmodel_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpindexwidget_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelplink_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpsearchengine_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpsearchquery_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpsearchquerywidget_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpsearchresult_wrapper.cpp
+${QtHelp_GEN_DIR}/qhelpsearchresultwidget_wrapper.cpp
+# module is always needed
+${QtHelp_GEN_DIR}/qthelp_module_wrapper.cpp
+)
+
+configure_file("${QtHelp_SOURCE_DIR}/QtHelp_global.pre.h.in"
+ "${QtHelp_BINARY_DIR}/QtHelp_global.pre.h" @ONLY)
+
+set(QtHelp_include_dirs ${QtHelp_SOURCE_DIR}
+ ${QtHelp_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Help_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ )
+set(QtHelp_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Help_LIBRARIES})
+
+set(QtHelp_deps QtWidgets)
+
+create_pyside_module(NAME QtHelp
+ INCLUDE_DIRS QtHelp_include_dirs
+ LIBRARIES QtHelp_libraries
+ DEPS QtHelp_deps
+ TYPESYSTEM_PATH QtHelp_SOURCE_DIR
+ SOURCES QtHelp_SRC)
diff --git a/sources/pyside6/PySide6/QtHelp/QtHelp_global.pre.h.in b/sources/pyside6/PySide6/QtHelp/QtHelp_global.pre.h.in
new file mode 100644
index 000000000..003b22ae6
--- /dev/null
+++ b/sources/pyside6/PySide6/QtHelp/QtHelp_global.pre.h.in
@@ -0,0 +1,3 @@
+// QVersionNumber is only forward-declared in QtHelp
+
+#include <QtCore/QVersionNumber>
diff --git a/sources/pyside6/PySide6/QtHelp/typesystem_help.xml b/sources/pyside6/PySide6/QtHelp/typesystem_help.xml
new file mode 100644
index 000000000..5fa30e034
--- /dev/null
+++ b/sources/pyside6/PySide6/QtHelp/typesystem_help.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.QtHelp"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <value-type name="QCompressedHelpInfo"/>
+ <value-type name="QHelpContentItem">
+ <modify-function signature="parent()const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <object-type name="QHelpContentModel" polymorphic-id-expression="qobject_cast&lt;QHelpContentModel*&gt;(%B)"/>
+ <object-type name="QHelpContentWidget"/>
+ <value-type name="QHelpGlobal"/>
+ <object-type name="QHelpEngine"/>
+ <object-type name="QHelpEngineCore"/>
+ <value-type name="QHelpFilterData"/>
+ <object-type name="QHelpFilterEngine"/>
+ <object-type name="QHelpFilterSettingsWidget"/>
+ <object-type name="QHelpIndexModel"/>
+ <object-type name="QHelpIndexWidget"/>
+ <value-type name="QHelpLink"/>
+ <object-type name="QHelpSearchEngine"/>
+ <value-type name="QHelpSearchQuery">
+ <enum-type name="FieldName"/>
+ </value-type>
+ <object-type name="QHelpSearchQueryWidget"/>
+ <object-type name="QHelpSearchResult"/>
+ <object-type name="QHelpSearchResultWidget"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtHttpServer/CMakeLists.txt b/sources/pyside6/PySide6/QtHttpServer/CMakeLists.txt
new file mode 100644
index 000000000..c931f064f
--- /dev/null
+++ b/sources/pyside6/PySide6/QtHttpServer/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtHttpServer)
+
+set(QtHttpServer_SRC
+ ${QtHttpServer_GEN_DIR}/qabstracthttpserver_wrapper.cpp
+ ${QtHttpServer_GEN_DIR}/qfuturehttpserverresponse_wrapper.cpp
+ ${QtHttpServer_GEN_DIR}/qhttpserver_wrapper.cpp
+ ${QtHttpServer_GEN_DIR}/qhttpserverresponder_wrapper.cpp
+ ${QtHttpServer_GEN_DIR}/qhttpserverrequest_wrapper.cpp
+ ${QtHttpServer_GEN_DIR}/qhttpserverresponse_wrapper.cpp
+ ${QtHttpServer_GEN_DIR}/qhttpserverrouter_wrapper.cpp
+ ${QtHttpServer_GEN_DIR}/qhttpserverrouterrule_wrapper.cpp
+# module is always needed
+ ${QtHttpServer_GEN_DIR}/qthttpserver_module_wrapper.cpp)
+
+set(QtHttpServer_include_dirs ${QtHttpServer_SOURCE_DIR}
+ ${QtHttpServer_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Concurrent_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebSockets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtConcurrent_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtWebSockets_GEN_DIR})
+
+set(QtHttpServer_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}HttpServer_LIBRARIES})
+
+set(QtHttpServer_deps QtCore QtConcurrent QtNetwork QtWebSockets)
+
+create_pyside_module(NAME QtHttpServer
+ INCLUDE_DIRS QtHttpServer_include_dirs
+ LIBRARIES QtHttpServer_libraries
+ DEPS QtHttpServer_deps
+ TYPESYSTEM_PATH QtHttpServer_SOURCE_DIR
+ SOURCES QtHttpServer_SRC)
diff --git a/sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml b/sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml
new file mode 100644
index 000000000..026a8758a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtHttpServer/typesystem_httpserver.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtHttpServer"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtConcurrent/typesystem_concurrent.xml" generate="no"/>
+ <load-typesystem name="QtWebSockets/typesystem_websockets.xml" generate="no"/>
+
+ <typedef-type name="QFutureHttpServerResponse" source="QFuture&lt;QHttpServerResponse&gt;"/>
+ <!-- virtual void missingHandler(const QHttpServerRequest &, QHttpServerResponder &&) = 0 -->
+ <object-type name="QAbstractHttpServer" disable-wrapper="yes"/>
+ <object-type name="QHttpServer">
+ <extra-includes>
+ <include file-name="QtHttpServer/QHttpServerRequest" location="global"/>
+ <include file-name="QtHttpServer/QHttpServerRouterRule" location="global"/>
+ </extra-includes>
+ <add-function signature="route(const QString &amp;@rule@, PyCallable @callback@)"
+ return-type="bool">
+ <inject-code class="target" position="beginning" file="../glue/qhttpserver.cpp"
+ snippet="qhttpserver-route"/>
+ </add-function>
+ <add-function signature="afterRequest(PyCallable @callback@)">
+ <inject-code class="target" position="beginning" file="../glue/qhttpserver.cpp"
+ snippet="qhttpserver-afterrequest"/>
+ </add-function>
+ </object-type>
+ <object-type name="QHttpServerResponder">
+ <enum-type name="StatusCode"/>
+ </object-type>
+ <object-type name="QHttpServerRequest">
+ <enum-type name="Method" flags="Methods"/>
+ </object-type>
+ <object-type name="QHttpServerResponse"/>
+ <object-type name="QHttpServerRouter"/>
+ <object-type name="QHttpServerRouterRule"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtLocation/CMakeLists.txt b/sources/pyside6/PySide6/QtLocation/CMakeLists.txt
new file mode 100644
index 000000000..db5777e04
--- /dev/null
+++ b/sources/pyside6/PySide6/QtLocation/CMakeLists.txt
@@ -0,0 +1,70 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtLocation)
+
+set(QtLocation_OPTIONAL_SRC )
+set(QtLocation_DROPPED_ENTRIES )
+
+set(QtLocation_SRC
+${QtLocation_GEN_DIR}/qgeocodereply_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeomaneuver_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeoroute_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeoroutereply_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeoroutesegment_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeoserviceprovider_wrapper.cpp
+${QtLocation_GEN_DIR}/qplace_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacecontentreply_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacedetailsreply_wrapper.cpp
+${QtLocation_GEN_DIR}/qplaceicon_wrapper.cpp
+${QtLocation_GEN_DIR}/qplaceidreply_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacemanager_wrapper.cpp
+${QtLocation_GEN_DIR}/qplaceuser_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeocodingmanager_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeocodingmanagerengine_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeorouterequest_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeoroutingmanager_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeoroutingmanagerengine_wrapper.cpp
+${QtLocation_GEN_DIR}/qgeoserviceproviderfactory_wrapper.cpp
+${QtLocation_GEN_DIR}/qplaceattribute_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacecategory_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacecontactdetail_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacecontent_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacecontentrequest_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacemanagerengine_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacematchreply_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacematchrequest_wrapper.cpp
+${QtLocation_GEN_DIR}/qplaceproposedsearchresult_wrapper.cpp
+${QtLocation_GEN_DIR}/qplaceratings_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacereply_wrapper.cpp
+${QtLocation_GEN_DIR}/qplaceresult_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacesearchreply_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacesearchrequest_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacesearchresult_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacesearchsuggestionreply_wrapper.cpp
+${QtLocation_GEN_DIR}/qplacesupplier_wrapper.cpp
+# module is always needed
+${QtLocation_GEN_DIR}/qtlocation_module_wrapper.cpp
+)
+
+
+set(QtLocation_include_dirs ${QtLocation_SOURCE_DIR}
+ ${QtLocation_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Location_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtPositioning_GEN_DIR})
+
+set(QtLocation_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Location_LIBRARIES})
+
+set(QtLocation_deps QtCore QtPositioning)
+
+create_pyside_module(NAME QtLocation
+ INCLUDE_DIRS QtLocation_include_dirs
+ LIBRARIES QtLocation_libraries
+ DEPS QtLocation_deps
+ TYPESYSTEM_PATH QtLocation_SOURCE_DIR
+ SOURCES QtLocation_SRC
+ DROPPED_ENTRIES QtLocation_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtLocation/typesystem_location.xml b/sources/pyside6/PySide6/QtLocation/typesystem_location.xml
new file mode 100644
index 000000000..e35b7bd11
--- /dev/null
+++ b/sources/pyside6/PySide6/QtLocation/typesystem_location.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtLocation"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtPositioning/typesystem_positioning.xml" generate="no"/>
+ <object-type name="QGeoCodeReply">
+ <enum-type name="Error"/>
+ </object-type>
+ <value-type name="QGeoManeuver">
+ <enum-type name="InstructionDirection"/>
+ </value-type>
+ <value-type name="QGeoRoute"/>
+ <object-type name="QGeoRouteReply">
+ <enum-type name="Error"/>
+ </object-type>
+ <value-type name="QGeoRouteSegment"/>
+ <object-type name="QGeoServiceProvider">
+ <enum-type name="Error"/>
+ <enum-type name="RoutingFeature" flags="RoutingFeatures"/>
+ <enum-type name="GeocodingFeature" flags="GeocodingFeatures"/>
+ <enum-type name="MappingFeature" flags="MappingFeatures"/>
+ <enum-type name="PlacesFeature" flags="PlacesFeatures"/>
+ <enum-type name="NavigationFeature" flags="NavigationFeatures"/>
+ </object-type>
+ <value-type name="QPlace"/>
+ <object-type name="QPlaceContentReply"/>
+ <object-type name="QPlaceDetailsReply"/>
+ <value-type name="QPlaceIcon"/>
+ <object-type name="QPlaceIdReply">
+ <enum-type name="OperationType"/>
+ </object-type>
+ <object-type name="QPlaceManager"/>
+ <value-type name="QPlaceUser"/>
+ <object-type name="QGeoCodingManager"/>
+ <object-type name="QGeoCodingManagerEngine"/>
+ <object-type name="QGeoRouteRequest">
+ <enum-type name="TravelMode" flags="TravelModes"/>
+ <enum-type name="FeatureType" flags="FeatureTypes"/>
+ <enum-type name="FeatureWeight" flags="FeatureWeights"/>
+ <enum-type name="RouteOptimization" flags="RouteOptimizations"/>
+ <enum-type name="SegmentDetail" flags="SegmentDetails"/>
+ <enum-type name="ManeuverDetail" flags="ManeuverDetails"/>
+ </object-type>
+ <object-type name="QGeoRoutingManager"/>
+ <object-type name="QGeoRoutingManagerEngine"/>
+ <object-type name="QGeoServiceProviderFactory"/>
+ <value-type name="QPlaceAttribute"/>
+ <value-type name="QPlaceCategory"/>
+ <value-type name="QPlaceContactDetail"/>
+ <value-type name="QPlaceContent">
+ <enum-type name="Type"/>
+ <enum-type name="DataTag" since="6.5"/>
+ </value-type>
+ <value-type name="QPlaceContentRequest"/>
+ <object-type name="QPlaceManagerEngine"/>
+ <object-type name="QPlaceMatchReply"/>
+ <value-type name="QPlaceMatchRequest"/>
+ <object-type name="QPlaceProposedSearchResult"/>
+ <value-type name="QPlaceRatings"/>
+ <object-type name="QPlaceReply">
+ <enum-type name="Error"/>
+ <enum-type name="Type"/>
+ </object-type>
+ <object-type name="QPlaceResult"/>
+ <object-type name="QPlaceSearchReply"/>
+ <object-type name="QPlaceSearchRequest">
+ <enum-type name="RelevanceHint"/>
+ </object-type>
+ <object-type name="QPlaceSearchResult">
+ <enum-type name="SearchResultType"/>
+ </object-type>
+ <object-type name="QPlaceSearchSuggestionReply"/>
+ <value-type name="QPlaceSupplier"/>
+
+ <!-- QtQml, QtNetwork are pulled in via QtLocationDepends. -->
+ <suppress-warning text="^Scoped enum 'Q(Ocsp)|(Dtls)|(Qml).*' does not have a type entry.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtMultimedia/CMakeLists.txt b/sources/pyside6/PySide6/QtMultimedia/CMakeLists.txt
new file mode 100644
index 000000000..e40c5a2ed
--- /dev/null
+++ b/sources/pyside6/PySide6/QtMultimedia/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtMultimedia)
+
+set(QtMultimedia_SRC
+${QtMultimedia_GEN_DIR}/qaudiobuffer_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudiodecoder_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudiodevice_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudioformat_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudioinput_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudiooutput_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudiosink_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudiosource_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qaudio_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qcameraformat_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qcameradevice_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qcamera_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qcapturablewindow_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qimagecapture_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediacapturesession_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediadevices_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediaformat_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediametadata_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediaplayer_wrapper.cpp
+# ${QtMultimedia_GEN_DIR}/qmediaplaylist_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediarecorder_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediatimerange_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qmediatimerange_interval_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qscreencapture_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qsoundeffect_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qtvideo_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qvideoframe_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qvideoframe_paintoptions_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qvideoframeformat_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qvideosink_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qwavedecoder_wrapper.cpp
+${QtMultimedia_GEN_DIR}/qwindowcapture_wrapper.cpp
+
+# module is always needed
+${QtMultimedia_GEN_DIR}/qtmultimedia_module_wrapper.cpp
+)
+
+set(QtMultimedia_include_dirs ${QtMultimedia_SOURCE_DIR}
+ ${QtMultimedia_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Multimedia_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtNetwork_GEN_DIR})
+
+set(QtMultimedia_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Multimedia_LIBRARIES})
+
+set(QtMultimedia_deps QtCore QtGui QtNetwork)
+
+create_pyside_module(NAME QtMultimedia
+ INCLUDE_DIRS QtMultimedia_include_dirs
+ LIBRARIES QtMultimedia_libraries
+ DEPS QtMultimedia_deps
+ TYPESYSTEM_PATH QtMultimedia_SOURCE_DIR
+ SOURCES QtMultimedia_SRC)
diff --git a/sources/pyside6/PySide6/QtMultimedia/typesystem_multimedia.xml b/sources/pyside6/PySide6/QtMultimedia/typesystem_multimedia.xml
new file mode 100644
index 000000000..2791f695a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtMultimedia/typesystem_multimedia.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtMultimedia"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+
+ <namespace-type name="QAudio">
+ <enum-type name="Error"/>
+ <enum-type name="State"/>
+ <enum-type name="VolumeScale"/>
+ <inject-code class="target" position="end"
+ file="../glue/qtmultimedia.cpp"
+ snippet="qtaudio-namespace-compatibility-alias"/>
+ </namespace-type>
+
+ <namespace-type name="QtVideo" since="6.7">
+ <enum-type name="Rotation"/>
+ </namespace-type>
+
+ <value-type name="QAudioBuffer">
+ <add-function signature="data()" return-type="PyBuffer">
+ <inject-code file="../glue/qtmultimedia.cpp" snippet="qaudiobuffer-data"/>
+ </add-function>
+ <add-function signature="constData()" return-type="PyBuffer">
+ <inject-code file="../glue/qtmultimedia.cpp" snippet="qaudiobuffer-const-data"/>
+ </add-function>
+ </value-type>
+ <object-type name="QAudioDecoder">
+ <enum-type name="Error"/>
+ </object-type>
+ <value-type name="QAudioFormat">
+ <enum-type name="SampleFormat" since="6.1"/>
+ <enum-type name="ChannelConfig"/>
+ <enum-type name="AudioChannelPosition" since="6.2"/>
+ <modify-function signature="normalizedSampleValue(const void*)const">
+ <modify-argument index="1">
+ <replace-type modified-type="PyBuffer"/>
+ <conversion-rule class="native">
+ <insert-template name="pybuffer_const_char"/>
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ <value-type name="QAudioDevice">
+ <enum-type name="Mode"/>
+ </value-type>
+
+ <object-type name="QAudioInput"/>
+ <object-type name="QAudioOutput"/>
+
+ <object-type name="QAudioSource">
+ <modify-function signature="start()" allow-thread="true">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="start(QIODevice*)" allow-thread="true">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="stop()" allow-thread="true"/>
+ </object-type>
+
+ <object-type name="QAudioSink">
+ <modify-function signature="start()" allow-thread="true">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="start(QIODevice*)" allow-thread="true">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="stop()" allow-thread="true"/>
+ </object-type>
+
+ <object-type name="QCamera">
+ <enum-type name="Error"/>
+ <enum-type name="ExposureMode" since="6.1"/>
+ <enum-type name="Feature" flags="Features" since="6.1"/>
+ <enum-type name="FlashMode" since="6.1"/>
+ <enum-type name="FocusMode" since="6.1"/>
+ <enum-type name="TorchMode" since="6.1"/>
+ <enum-type name="WhiteBalanceMode" since="6.1"/>
+ </object-type>
+ <value-type name="QCameraFormat" since="6.1"/>
+ <value-type name="QCameraDevice">
+ <enum-type name="Position" since="6.1"/>
+ </value-type>
+
+ <value-type name="QCapturableWindow" since="6.6"/>
+
+ <object-type name="QImageCapture">
+ <enum-type name="Error"/>
+ <enum-type name="FileFormat"/>
+ <enum-type name="Quality"/>
+ </object-type>
+
+ <object-type name="QMediaCaptureSession" since="6.1"/>
+
+ <object-type name="QMediaDevices" since="6.1"/>
+
+ <value-type name="QMediaFormat" since="6.1">
+ <enum-type name="AudioCodec"/>
+ <enum-type name="ConversionMode"/>
+ <enum-type name="FileFormat"/>
+ <enum-type name="VideoCodec"/>
+ <enum-type name="ResolveFlags"/>
+ </value-type>
+
+ <value-type name="QMediaMetaData" since="6.1">
+ <enum-type name="Key"/>
+ </value-type>
+ <object-type name="QMediaPlayer">
+ <enum-type name="MediaStatus"/>
+ <enum-type name="PlaybackState" since="6.1"/>
+ <enum-type name="Error"/>
+ <enum-type name="Loops" python-type="IntEnum" since="6.2.3"/>
+ </object-type>
+ <!-- see qtmultimedia/5773f7214c7430a98dea3974c0597cb3ee0ea7f5 might reappear in 6.3
+ <object-type name="QMediaPlaylist"/>
+ -->
+ <object-type name="QMediaRecorder">
+ <enum-type name="Error" since="6.1"/>
+ <enum-type name="EncodingMode" since="6.1"/>
+ <enum-type name="RecorderState" since="6.1"/>
+ <enum-type name="Quality" since="6.1"/>
+ </object-type>
+ <value-type name="QMediaTimeRange">
+ <value-type name="Interval"/>
+ </value-type>
+
+ <object-type name="QScreenCapture" since="6.5">
+ <enum-type name="Error"/>
+ </object-type>
+
+ <object-type name="QSoundEffect">
+ <enum-type name="Loop"/>
+ <enum-type name="Status"/>
+ </object-type>
+
+ <value-type name="QVideoFrame">
+ <enum-type name="HandleType"/>
+ <enum-type name="MapMode" since="6.1"/>
+ <enum-type name="RotationAngle" since="6.2.3"/>
+ <modify-function signature="bits(int)">
+ <inject-code file="../glue/qtmultimedia.cpp" snippet="qvideoframe-bits"/>
+ </modify-function>
+ <modify-function signature="bits(int)const" remove="all"/>
+ <value-type name="PaintOptions">
+ <enum-type name="PaintFlag" flags="PaintFlags"/>
+ </value-type>
+ </value-type>
+ <value-type name="QVideoFrameFormat" since="6.1">
+ <enum-type name="ColorSpace" since="6.4"/>
+ <enum-type name="ColorTransfer" since="6.4"/>
+ <enum-type name="ColorRange" since="6.4"/>
+ <enum-type name="Direction"/>
+ <enum-type name="PixelFormat"/>
+ <enum-type name="YCbCrColorSpace"/>
+ </value-type>
+
+ <object-type name="QWaveDecoder">
+ <!-- No implementation -->
+ <modify-function signature="setIODevice(QIODevice*)" remove="all"/>
+ </object-type>
+
+ <object-type name="QWindowCapture" since="6.6">
+ <enum-type name="Error"/>
+ </object-type>
+
+ <object-type name="QVideoSink" since="6.1"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtMultimediaWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtMultimediaWidgets/CMakeLists.txt
new file mode 100644
index 000000000..c3988551e
--- /dev/null
+++ b/sources/pyside6/PySide6/QtMultimediaWidgets/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtMultimediaWidgets)
+
+set(QtMultimediaWidgets_SRC
+${QtMultimediaWidgets_GEN_DIR}/qgraphicsvideoitem_wrapper.cpp
+${QtMultimediaWidgets_GEN_DIR}/qvideowidget_wrapper.cpp
+# module is always needed
+${QtMultimediaWidgets_GEN_DIR}/qtmultimediawidgets_module_wrapper.cpp
+)
+
+set(QtMultimediaWidgets_include_dirs ${QtMultimediaWidgets_SOURCE_DIR}
+ ${QtMultimediaWidgets_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Multimedia_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}MultimediaWidgets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtMultimedia_GEN_DIR})
+
+set(QtMultimediaWidgets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}MultimediaWidgets_LIBRARIES})
+
+
+set(QtMultimediaWidgets_deps QtCore QtGui QtNetwork QtWidgets QtMultimedia)
+
+create_pyside_module(NAME QtMultimediaWidgets
+ INCLUDE_DIRS QtMultimediaWidgets_include_dirs
+ LIBRARIES QtMultimediaWidgets_libraries
+ DEPS QtMultimediaWidgets_deps
+ TYPESYSTEM_PATH QtMultimediaWidgets_SOURCE_DIR
+ SOURCES QtMultimediaWidgets_SRC)
diff --git a/sources/pyside6/PySide6/QtMultimediaWidgets/typesystem_multimediawidgets.xml b/sources/pyside6/PySide6/QtMultimediaWidgets/typesystem_multimediawidgets.xml
new file mode 100644
index 000000000..05b4e2456
--- /dev/null
+++ b/sources/pyside6/PySide6/QtMultimediaWidgets/typesystem_multimediawidgets.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtMultimediaWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtMultimedia/typesystem_multimedia.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <object-type name="QGraphicsVideoItem"/>
+ <object-type name="QVideoWidget"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtNetwork/CMakeLists.txt b/sources/pyside6/PySide6/QtNetwork/CMakeLists.txt
new file mode 100644
index 000000000..529e2e86b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtNetwork/CMakeLists.txt
@@ -0,0 +1,121 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtNetwork)
+
+set(QtNetwork_DROPPED_ENTRIES )
+
+set(QtNetwork_SRC
+${QtNetwork_GEN_DIR}/qabstractnetworkcache_wrapper.cpp
+${QtNetwork_GEN_DIR}/qabstractsocket_wrapper.cpp
+${QtNetwork_GEN_DIR}/qauthenticator_wrapper.cpp
+${QtNetwork_GEN_DIR}/qdnsdomainnamerecord_wrapper.cpp
+${QtNetwork_GEN_DIR}/qdnshostaddressrecord_wrapper.cpp
+${QtNetwork_GEN_DIR}/qdnslookup_wrapper.cpp
+${QtNetwork_GEN_DIR}/qdnsmailexchangerecord_wrapper.cpp
+${QtNetwork_GEN_DIR}/qdnsservicerecord_wrapper.cpp
+${QtNetwork_GEN_DIR}/qdnstextrecord_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhostaddress_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhostinfo_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhstspolicy_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhttp1configuration_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhttpheaders_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhttpmultipart_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhttppart_wrapper.cpp
+${QtNetwork_GEN_DIR}/qhttp2configuration_wrapper.cpp
+${QtNetwork_GEN_DIR}/qipv6address_wrapper.cpp
+${QtNetwork_GEN_DIR}/qlocalserver_wrapper.cpp
+${QtNetwork_GEN_DIR}/qlocalsocket_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkaccessmanager_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkaddressentry_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkcachemetadata_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkcookie_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkcookiejar_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkdatagram_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkdiskcache_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkinformation_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkinterface_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkproxy_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkproxyfactory_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkproxyquery_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkreply_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkrequest_wrapper.cpp
+${QtNetwork_GEN_DIR}/qnetworkrequestfactory_wrapper.cpp
+${QtNetwork_GEN_DIR}/qpassworddigestor_wrapper.cpp
+${QtNetwork_GEN_DIR}/qrestaccessmanager_wrapper.cpp
+${QtNetwork_GEN_DIR}/qrestreply_wrapper.cpp
+${QtNetwork_GEN_DIR}/qssl_wrapper.cpp
+${QtNetwork_GEN_DIR}/qsslcertificate_wrapper.cpp
+${QtNetwork_GEN_DIR}/qsslcertificateextension_wrapper.cpp
+${QtNetwork_GEN_DIR}/qsslellipticcurve_wrapper.cpp
+${QtNetwork_GEN_DIR}/qtcpserver_wrapper.cpp
+${QtNetwork_GEN_DIR}/qtcpsocket_wrapper.cpp
+${QtNetwork_GEN_DIR}/qudpsocket_wrapper.cpp
+# module is always needed
+${QtNetwork_GEN_DIR}/qtnetwork_module_wrapper.cpp
+)
+
+get_property(QtNetwork_disabled_features TARGET Qt${QT_MAJOR_VERSION}::Network
+ PROPERTY QT_DISABLED_PUBLIC_FEATURES)
+
+if("ssl" IN_LIST QtNetwork_disabled_features)
+ list(APPEND QtNetwork_DROPPED_ENTRIES QOcspResponse QSslCipher
+ QSslConfiguration QSslDiffieHellmanParameters QSslError
+ QSslKey QSslPreSharedKeyAuthenticator QSslSocket QSslServer)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping SSL classes")
+else()
+ # Problems with operator==(QSslEllipticCurve,QSslEllipticCurve)
+ # check_qt_class(QtNetwork QSslEllipticCurve QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
+ list(APPEND QtNetwork_SRC
+ ${QtNetwork_GEN_DIR}/qsslcipher_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslconfiguration_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qssldiffiehellmanparameters_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslerror_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslkey_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslpresharedkeyauthenticator_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslserver_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslsocket_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qocspresponse_wrapper.cpp)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding SSL classes")
+endif()
+
+if("dtls" IN_LIST QtNetwork_disabled_features)
+ list(APPEND QtNetwork_DROPPED_ENTRIES QDtls QDtlsClientVerifier)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping DTLS classes")
+else()
+ list(APPEND QtNetwork_SRC
+ ${QtNetwork_GEN_DIR}/qdtls_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qdtlsclientverifier_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qdtlsclientverifier_generatorparameters_wrapper.cpp)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding DTLS classes")
+endif()
+
+if("sctp" IN_LIST QtNetwork_disabled_features)
+ list(APPEND QtNetwork_DROPPED_ENTRIES QSctpServer QSctpSocket)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping SCTP classes")
+else()
+ list(APPEND QtNetwork_SRC
+ ${QtNetwork_GEN_DIR}/qsctpserver_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsctpsocket_wrapper.cpp)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding SCTP classes")
+endif()
+
+set(QtNetwork_include_dirs ${QtNetwork_SOURCE_DIR}
+ ${QtNetwork_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtNetwork_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES})
+
+set(QtNetwork_deps QtCore)
+
+create_pyside_module(NAME QtNetwork
+ INCLUDE_DIRS QtNetwork_include_dirs
+ LIBRARIES QtNetwork_libraries
+ DEPS QtNetwork_deps
+ TYPESYSTEM_PATH QtNetwork_SOURCE_DIR
+ SOURCES QtNetwork_SRC
+ DROPPED_ENTRIES QtNetwork_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtNetwork/typesystem_network.xml b/sources/pyside6/PySide6/QtNetwork/typesystem_network.xml
new file mode 100644
index 000000000..4dc7c9b0a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtNetwork/typesystem_network.xml
@@ -0,0 +1,475 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtNetwork"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+
+ <rejection class="QTlsPrivate"/>
+
+ <enum-type name="QDtlsError">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </enum-type>
+ <enum-type name="QOcspCertificateStatus">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </enum-type>
+ <enum-type name="QOcspRevocationReason">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </enum-type>
+
+ <namespace-type name="QPasswordDigestor">
+ <extra-includes>
+ <include file-name="qpassworddigestor.h" location="global"/>
+ </extra-includes>
+ </namespace-type>
+
+ <namespace-type name="QSsl">
+ <enum-type name="AlertLevel"/>
+ <enum-type name="AlertType"/>
+ <enum-type name="AlternativeNameEntryType"/>
+ <enum-type name="EncodingFormat"/>
+ <enum-type name="ImplementedClass" since="6.1"/>
+ <enum-type name="KeyAlgorithm"/>
+ <enum-type name="KeyType"/>
+ <enum-type name="SslOption" flags="SslOptions"/>
+ <enum-type name="SslProtocol"/>
+ <enum-type name="SupportedFeature" since="6.1"/>
+ <extra-includes>
+ <include file-name="qssl.h" location="global"/>
+ </extra-includes>
+ </namespace-type>
+
+ <rejection class="QIPv6Address" field-name="c"/>
+
+ <object-type name="QAbstractSocket">
+ <enum-type name="BindFlag" flags="BindMode"/>
+ <enum-type name="NetworkLayerProtocol"/>
+ <enum-type name="PauseMode" flags="PauseModes"/>
+ <enum-type name="SocketError"/>
+ <enum-type name="SocketOption" since="4.6"/>
+ <enum-type name="SocketState"/>
+ <enum-type name="SocketType"/>
+ <modify-function signature="connectToHost(const QString&amp;,quint16,QFlags&lt;QIODeviceBase::OpenModeFlag>,QAbstractSocket::NetworkLayerProtocol)" allow-thread="yes"/>
+ <modify-function signature="connectToHost(const QHostAddress&amp;,quint16,QFlags&lt;QIODeviceBase::OpenModeFlag>)" allow-thread="yes"/>
+ <modify-function signature="disconnectFromHost()" allow-thread="yes"/>
+ <modify-function signature="waitForConnected(int)" allow-thread="yes"/>
+ <modify-function signature="waitForDisconnected(int)" allow-thread="yes"/>
+ <modify-function signature="waitForBytesWritten(int)" allow-thread="yes"/>
+ <modify-function signature="waitForReadyRead(int)" allow-thread="yes"/>
+ </object-type>
+
+ <value-type name="QDnsDomainNameRecord"/>
+ <value-type name="QDnsHostAddressRecord"/>
+ <object-type name="QDnsLookup">
+ <enum-type name="Error"/>
+ <enum-type name="Type"/>
+ </object-type>
+ <value-type name="QDnsMailExchangeRecord"/>
+ <value-type name="QDnsServiceRecord"/>
+ <value-type name="QDnsTextRecord"/>
+
+ <object-type name="QDtls">
+ <enum-type name="HandshakeState"/>
+ <configuration condition="QT_CONFIG(dtls)"/>
+ </object-type>
+ <object-type name="QDtlsClientVerifier">
+ <configuration condition="QT_CONFIG(dtls)"/>
+ <value-type name="GeneratorParameters">
+ <configuration condition="QT_CONFIG(dtls)"/>
+ </value-type>
+ </object-type>
+
+ <value-type name="QHstsPolicy">
+ <enum-type name="PolicyFlag" flags="PolicyFlags"/>
+ </value-type>
+ <value-type name="QHttp1Configuration"/>
+ <value-type name="QHttpHeaders" since="6.7">
+ <enum-type name="WellKnownHeader"/>
+ </value-type>
+ <object-type name="QHttpMultiPart">
+ <enum-type name="ContentType"/>
+ </object-type>
+ <value-type name="QHttpPart"/>
+ <value-type name="QHttp2Configuration"/>
+
+ <object-type name="QTcpServer">
+ <modify-function signature="waitForNewConnection(int,bool*)" allow-thread="yes">
+ <!-- FIXME removing default expression means user will always have to pass a value, but he wouldn't have to -->
+ <modify-argument index="1">
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, bool]">
+ <replace-type modified-type="(retval, timedOut)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+ <value-type name="QOcspResponse">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+ <object-type name="QTcpSocket"/>
+ <object-type name="QUdpSocket">
+ <modify-function signature="readDatagram(char*,qint64,QHostAddress*,quint16*)" allow-thread="yes">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtCore.QByteArray, PySide6.QtNetwork.QHostAddress, int]">
+ <replace-type modified-type="(data, address, port)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qudpsocket-readdatagram"/>
+ </modify-function>
+ <modify-function signature="writeDatagram(const QByteArray&amp;,const QHostAddress&amp;,quint16)" allow-thread="yes"/>
+ <!-- ### writeDatagram(QByteArray, ...) does the trick -->
+ <modify-function signature="writeDatagram(const char*,qint64,const QHostAddress&amp;,quint16)" remove="all"/>
+ <!-- ### -->
+ </object-type>
+
+ <object-type name="QLocalServer">
+ <enum-type name="SocketOption" flags="SocketOptions"/>
+ <modify-function signature="waitForNewConnection(int,bool*)" allow-thread="yes">
+ <!-- FIXME -->
+ <modify-argument index="1">
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ <modify-argument index="return" pyi-type="Tuple[bool, bool]">
+ <replace-type modified-type="(retval, timedOut)"/>
+ </modify-argument>
+
+ </modify-function>
+ </object-type>
+ <object-type name="QLocalSocket">
+ <enum-type name="LocalSocketError"/>
+ <enum-type name="SocketOption" flags="SocketOptions"/>
+ <enum-type name="LocalSocketState"/>
+ </object-type>
+ <object-type name="QNetworkAccessManager">
+ <enum-type name="Operation"/>
+ <modify-function signature="createRequest(QNetworkAccessManager::Operation,const QNetworkRequest&amp;,QIODevice*)">
+ <modify-argument index="3" invalidate-after-use="yes"/>
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="get(const QNetworkRequest&amp;)" allow-thread="yes"/>
+ <modify-function signature="post(const QNetworkRequest &amp;,QIODevice*)" allow-thread="yes"/>
+ <modify-function signature="post(const QNetworkRequest &amp;,const QByteArray &amp;)" allow-thread="yes"/>
+ <modify-function signature="put(const QNetworkRequest &amp;,QIODevice*)" allow-thread="yes"/>
+ <modify-function signature="put(const QNetworkRequest &amp;,const QByteArray &amp;)" allow-thread="yes"/>
+ <modify-function signature="sendCustomRequest(const QNetworkRequest &amp;,const QByteArray &amp;,QIODevice*)" allow-thread="yes" since="4.7"/>
+ <modify-function signature="setCache(QAbstractNetworkCache*)">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setCookieJar(QNetworkCookieJar*)">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QNetworkInformation">
+ <enum-type name="Reachability"/>
+ <enum-type name="Feature" flags="Features"/>
+ <enum-type name="TransportMedium" since="6.3"/>
+ </object-type>
+ <object-type name="QNetworkCookieJar"/>
+ <value-type name="QNetworkDatagram"/>
+ <object-type name="QNetworkReply">
+ <enum-type name="NetworkError"/>
+ </object-type>
+
+ <value-type name="QHostAddress">
+ <enum-type name="ConversionModeFlag" flags="ConversionMode"/>
+ <enum-type name="SpecialAddress"/>
+ <!-- ### QHostAddress(QIPv6Address) does this -->
+ <modify-function signature="QHostAddress(const quint8*)" remove="all"/>
+ <!-- ### -->
+ <modify-function signature="setAddress(const quint8*)" remove="all"/>
+ </value-type>
+
+ <value-type name="QHostInfo">
+ <inject-code class="native" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qhostinfo-lookuphost-functor"/>
+ <enum-type name="HostInfoError"/>
+ <add-function signature="lookupHost(const QString &amp;,PyCallable)">
+ <inject-code class="target" position="beginning"
+ file="../glue/qtnetwork.cpp"
+ snippet="qhostinfo-lookuphost-callable"/>
+ </add-function>
+ </value-type>
+
+ <value-type name="QNetworkAddressEntry">
+ <enum-type name="DnsEligibilityStatus"/>
+ <configuration condition="#ifndef QT_NO_NETWORKINTERFACE"/>
+ </value-type>
+
+ <value-type name="QNetworkInterface">
+ <enum-type name="InterfaceFlag" flags="InterfaceFlags"/>
+ <enum-type name="InterfaceType"/>
+ <configuration condition="#ifndef QT_NO_NETWORKINTERFACE"/>
+ </value-type>
+
+ <value-type name="QNetworkProxy">
+ <enum-type name="Capability" flags="Capabilities"/>
+ <enum-type name="ProxyType"/>
+ </value-type>
+
+ <object-type name="QNetworkProxyFactory"/>
+ <value-type name="QNetworkProxyQuery">
+ <enum-type name="QueryType"/>
+ </value-type>
+
+ <value-type name="QIPv6Address">
+ <add-function signature="__len__">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qipv6address-len"/>
+ </add-function>
+ <add-function signature="__getitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qipv6address-getitem"/>
+ </add-function>
+ <add-function signature="__setitem__">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qipv6address-setitem"/>
+ </add-function>
+ </value-type>
+
+ <value-type name="QAuthenticator"/>
+ <value-type name="QNetworkCookie">
+ <enum-type name="RawForm"/>
+ <enum-type name="SameSite" since="6.1"/>
+ <extra-includes>
+ <include file-name="QDateTime" location="global"/>
+ </extra-includes>
+ </value-type>
+ <value-type name="QNetworkRequest">
+ <enum-type name="Attribute"/>
+ <enum-type name="LoadControl"/>
+ <enum-type name="Priority"/>
+ <enum-type name="CacheLoadControl"/>
+ <enum-type name="KnownHeaders"/>
+ <enum-type name="RedirectPolicy"/>
+ <enum-type name="TransferTimeoutConstant"/>
+ </value-type>
+ <value-type name="QNetworkRequestFactory" since="6.7"/>
+ <object-type name="QAbstractNetworkCache"/>
+ <object-type name="QNetworkDiskCache"/>
+ <value-type name="QNetworkCacheMetaData"/>
+
+ <object-type name="QRestAccessManager" since="6.7">
+ <inject-code class="native" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-functor"/>
+
+ <add-function signature="deleteResource(QNetworkRequest@request@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-callback"/>
+ </add-function>
+
+ <add-function signature="get(QNetworkRequest@request@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-callback"/>
+ </add-function>
+ <add-function signature="get(QNetworkRequest@request@,QByteArray@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="get(QNetworkRequest@request@,QIODevice*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="get(QNetworkRequest@request@,QJsonDocument@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+
+ <add-function signature="head(QNetworkRequest@request@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-callback"/>
+ </add-function>
+
+ <add-function signature="patch(QNetworkRequest@request@,QByteArray@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="patch(QNetworkRequest@request@,QIODevice*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="patch(QNetworkRequest@request@,QJsonDocument@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="patch(QNetworkRequest@request@,QVariantMap@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+
+ <add-function signature="post(QNetworkRequest@request@,QByteArray@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="post(QNetworkRequest@request@,QHttpMultiPart*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="post(QNetworkRequest@request@,QIODevice*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="post(QNetworkRequest@request@,QJsonDocument@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="post(QNetworkRequest@request@,QVariantMap@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+
+ <add-function signature="put(QNetworkRequest@request@,QByteArray@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="put(QNetworkRequest@request@,QHttpMultiPart*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="put(QNetworkRequest@request@,QIODevice*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="put(QNetworkRequest@request@,QJsonDocument@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+ <add-function signature="put(QNetworkRequest@request@,QVariantMap@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-data-callback"/>
+ </add-function>
+
+ <add-function signature="sendCustomRequest(QNetworkRequest@request@,QByteArray@method@,QByteArray@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-method-data-callback"/>
+ </add-function>
+ <add-function signature="sendCustomRequest(QNetworkRequest@request@,QByteArray@method@,QHttpMultiPart*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-method-data-callback"/>
+ </add-function>
+ <add-function signature="sendCustomRequest(QNetworkRequest@request@,QByteArray@method@,QIODevice*@data@,QObject*@context@,PyCallable*@slot@)"
+ return-type="QNetworkReply*">
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestaccessmanager-method-data-callback"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QRestReply" since="6.7">
+ <add-function signature="readJson()" return-type="PyObject">
+ <modify-argument index="return"
+ pyi-type="Tuple[Optional[PySide6.QtCore.QJsonDocument],PySide6.QtCore.QJsonParseError]"/>
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp"
+ snippet="qrestreply-readjson"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QSctpServer">
+ <configuration condition="QT_CONFIG(sctp)"/>
+ </object-type>
+ <object-type name="QSctpSocket">
+ <configuration condition="QT_CONFIG(sctp)"/>
+ </object-type>
+
+ <!-- The following entries may be present in the system or not. Keep this section organized. -->
+ <value-type name="QSslCertificate">
+ <enum-type name="PatternSyntax"/>
+ <enum-type name="SubjectInfo"/>
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <value-type name="QSslCertificateExtension">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <value-type name="QSslCipher">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <value-type name="QSslConfiguration">
+ <enum-type name="NextProtocolNegotiationStatus"/>
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <value-type name="QSslDiffieHellmanParameters">
+ <enum-type name="Error"/>
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <value-type name="QSslEllipticCurve">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <value-type name="QSslError">
+ <enum-type name="SslError"/>
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <value-type name="QSslKey"/>
+ <object-type name="QSslSocket">
+ <enum-type name="SslMode"/>
+ <enum-type name="PeerVerifyMode"/>
+ <modify-function signature="connectToHostEncrypted(const QString&amp;,quint16,QFlags&lt;QIODeviceBase::OpenModeFlag>,QAbstractSocket::NetworkLayerProtocol)" allow-thread="yes"/>
+ <modify-function signature="waitForEncrypted(int)" allow-thread="yes"/>
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </object-type>
+
+ <value-type name="QSslPreSharedKeyAuthenticator">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </value-type>
+
+ <object-type name="QSslServer" since="6.4">
+ <configuration condition="QT_CONFIG(ssl)"/>
+ </object-type>
+
+ <!-- The above entries may be present in the system or not. Keep this section organized. -->
+</typesystem>
+
diff --git a/sources/pyside6/PySide6/QtNetworkAuth/CMakeLists.txt b/sources/pyside6/PySide6/QtNetworkAuth/CMakeLists.txt
new file mode 100644
index 000000000..4d9498e4d
--- /dev/null
+++ b/sources/pyside6/PySide6/QtNetworkAuth/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtNetworkAuth)
+
+set(QtNetworkAuth_SRC
+${QtNetworkAuth_GEN_DIR}/qabstractoauth_wrapper.cpp
+${QtNetworkAuth_GEN_DIR}/qabstractoauth2_wrapper.cpp
+${QtNetworkAuth_GEN_DIR}/qabstractoauthreplyhandler_wrapper.cpp
+${QtNetworkAuth_GEN_DIR}/qoauth1_wrapper.cpp
+${QtNetworkAuth_GEN_DIR}/qoauth1signature_wrapper.cpp
+${QtNetworkAuth_GEN_DIR}/qoauth2authorizationcodeflow_wrapper.cpp
+${QtNetworkAuth_GEN_DIR}/qoauthhttpserverreplyhandler_wrapper.cpp
+${QtNetworkAuth_GEN_DIR}/qoauthoobreplyhandler_wrapper.cpp
+# module is always needed
+${QtNetworkAuth_GEN_DIR}/qtnetworkauth_module_wrapper.cpp
+)
+
+set(QtNetworkAuth_include_dirs ${QtNetworkAuth_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}NetworkAuth_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtNetworkAuth_GEN_DIR})
+
+set(QtNetworkAuth_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}NetworkAuth_LIBRARIES})
+
+set(QtNetworkAuth_deps QtNetwork)
+
+create_pyside_module(NAME QtNetworkAuth
+ INCLUDE_DIRS QtNetworkAuth_include_dirs
+ LIBRARIES QtNetworkAuth_libraries
+ DEPS QtNetworkAuth_deps
+ TYPESYSTEM_PATH QtNetworkAuth_SOURCE_DIR
+ SOURCES QtNetworkAuth_SRC)
diff --git a/sources/pyside6/PySide6/QtNetworkAuth/typesystem_networkauth.xml b/sources/pyside6/PySide6/QtNetworkAuth/typesystem_networkauth.xml
new file mode 100644
index 000000000..bedfc5a28
--- /dev/null
+++ b/sources/pyside6/PySide6/QtNetworkAuth/typesystem_networkauth.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.QtNetworkAuth"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+ <object-type name="QAbstractOAuth">
+ <enum-type name="ContentType"/>
+ <enum-type name="Error"/>
+ <enum-type name="Stage"/>
+ <enum-type name="Status"/>
+ <inject-code class="native" position="beginning" file="../glue/qtnetworkauth.cpp"
+ snippet="qabstractoauth-lookuphost-functor"/>
+ <modify-function signature="setReplyHandler(QAbstractOAuthReplyHandler*)">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="setModifyParametersFunction(PyObject* @modifyParametersFunction@)">
+ <inject-code class="target" position="beginning" file="../glue/qtnetworkauth.cpp" snippet="qabstractoauth-setmodifyparametersfunction"/>
+ </add-function>
+ </object-type>
+ <object-type name="QAbstractOAuth2">
+ <modify-function signature="head(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="get(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="post(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="post(const QUrl&amp;,const QByteArray&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="post(const QUrl&amp;,QHttpMultiPart*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="put(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="put(const QUrl&amp;,const QByteArray&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="put(const QUrl&amp;,QHttpMultiPart*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="deleteResource(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstractOAuthReplyHandler"/>
+ <object-type name="QOAuth1">
+ <enum-type name="SignatureMethod"/>
+ <modify-function signature="head(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="get(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="post(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="put(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="deleteResource(const QUrl&amp;,const QMap&lt;QString,QVariant&gt;&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="QOAuth1Signature">
+ <enum-type name="HttpRequestMethod"/>
+ </value-type>
+ <object-type name="QOAuth2AuthorizationCodeFlow"/>
+ <object-type name="QOAuthHttpServerReplyHandler"/>
+ <object-type name="QOAuthOobReplyHandler"/>
+
+ <suppress-warning text="^.*Typedef used on signal QAbstractOAuth.*$"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtNfc/CMakeLists.txt b/sources/pyside6/PySide6/QtNfc/CMakeLists.txt
new file mode 100644
index 000000000..b94249a55
--- /dev/null
+++ b/sources/pyside6/PySide6/QtNfc/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtNfc)
+
+set(QtNfc_SRC
+ ${QtNfc_GEN_DIR}/qndeffilter_record_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qndeffilter_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qndefmessage_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qndefnfciconrecord_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qndefnfcsmartposterrecord_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qndefrecord_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qndefnfctextrecord_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qndefnfcurirecord_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qnearfieldmanager_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qnearfieldtarget_wrapper.cpp
+ ${QtNfc_GEN_DIR}/qnearfieldtarget_requestid_wrapper.cpp
+# module is always needed
+ ${QtNfc_GEN_DIR}/qtnfc_module_wrapper.cpp)
+
+set(QtNfc_include_dirs ${QtNfc_SOURCE_DIR}
+ ${QtNfc_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Nfc_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtNfc_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Nfc_LIBRARIES})
+
+set(QtNfc_deps QtCore)
+
+create_pyside_module(NAME QtNfc
+ INCLUDE_DIRS QtNfc_include_dirs
+ LIBRARIES QtNfc_libraries
+ DEPS QtNfc_deps
+ TYPESYSTEM_PATH QtNfc_SOURCE_DIR
+ SOURCES QtNfc_SRC)
diff --git a/sources/pyside6/PySide6/QtNfc/typesystem_nfc.xml b/sources/pyside6/PySide6/QtNfc/typesystem_nfc.xml
new file mode 100644
index 000000000..b548227f0
--- /dev/null
+++ b/sources/pyside6/PySide6/QtNfc/typesystem_nfc.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtNfc"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <value-type name="QNdefFilter">
+ <value-type name="Record"/>
+ </value-type>
+ <value-type name="QNdefMessage"/>
+ <value-type name="QNdefNfcIconRecord"/>
+ <value-type name="QNdefNfcSmartPosterRecord">
+ <enum-type name="Action"/>
+ </value-type>
+ <value-type name="QNdefNfcTextRecord">
+ <enum-type name="Encoding"/>
+ </value-type>
+ <value-type name="QNdefNfcUriRecord"/>
+ <value-type name="QNdefRecord">
+ <enum-type name="TypeNameFormat"/>
+ </value-type>
+ <object-type name="QNearFieldManager">
+ <enum-type name="AdapterState"/>
+ </object-type>
+ <object-type name="QNearFieldTarget">
+ <enum-type name="AccessMethod" flags="AccessMethods"/>
+ <enum-type name="Error"/>
+ <enum-type name="Type"/>
+ <value-type name="RequestId"/>
+ </object-type>
+ <!-- QtNetwork is pulled in via QtNfcDepends. -->
+ <suppress-warning text="^Scoped enum 'Q(Ocsp)|(Dtls).*' does not have a type entry.*$"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtOpenGL/CMakeLists.txt b/sources/pyside6/PySide6/QtOpenGL/CMakeLists.txt
new file mode 100644
index 000000000..5bf8b5f3b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/CMakeLists.txt
@@ -0,0 +1,100 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtOpenGL)
+
+set(QtOpenGL_DROPPED_ENTRIES)
+
+set(QtOpenGL_static_sources
+ "${QtOpenGL_SOURCE_DIR}/glue/utils.cpp"
+)
+
+set(QtOpenGL_SRC
+${QtOpenGL_GEN_DIR}/qabstractopenglfunctions_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopengldebuglogger_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopengldebugmessage_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglframebufferobjectformat_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglpaintdevice_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglpixeltransferoptions_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglshaderprogram_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopengltexture_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopengltextureblitter_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglversionprofile_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglvertexarrayobject_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglvertexarrayobject_binder_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglwindow_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglbuffer_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglshader_wrapper.cpp
+${QtOpenGL_GEN_DIR}/qopenglframebufferobject_wrapper.cpp
+# module is always needed
+${QtOpenGL_GEN_DIR}/qtopengl_module_wrapper.cpp
+)
+
+get_property(QtGui_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Gui
+ PROPERTY QT_ENABLED_PUBLIC_FEATURES)
+
+if("opengles2" IN_LIST QtGui_enabled_features)
+ list(APPEND QtOpenGL_DROPPED_ENTRIES QOpenGLTimeMonitor QOpenGLTimerQuery
+ QOpenGLVersionFunctionsFactory)
+ list(APPEND QtOpenGL_SRC ${QtOpenGL_GEN_DIR}/qopenglfunctions_es2_wrapper.cpp)
+ message(STATUS "Qt${QT_MAJOR_VERSION}Gui: Dropping Desktop OpenGL classes (GLES2)")
+else()
+ list(APPEND QtOpenGL_DROPPED_ENTRIES QOpenGLFunctions_ES2)
+ list(APPEND QtOpenGL_SRC
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_1_0_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_1_1_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_1_2_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_1_3_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_1_4_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_1_5_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_2_0_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_2_1_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_3_0_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_3_1_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_3_2_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_3_2_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_3_3_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_3_3_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_0_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_0_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_1_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_1_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_2_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_2_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_3_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_3_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_4_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_4_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_5_compatibility_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglfunctions_4_5_core_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopenglversionfunctionsfactory_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopengltimemonitor_wrapper.cpp
+ ${QtOpenGL_GEN_DIR}/qopengltimerquery_wrapper.cpp)
+ message(STATUS "Qt${QT_MAJOR_VERSION}OpenGL: Adding Desktop OpenGL classes")
+endif()
+
+
+configure_file("${QtOpenGL_SOURCE_DIR}/QtOpenGL_global.post.h.in"
+ "${QtOpenGL_BINARY_DIR}/QtOpenGL_global.post.h" @ONLY)
+
+set(QtOpenGL_include_dirs ${QtOpenGL_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtOpenGL_GEN_DIR}
+ )
+set(QtOpenGL_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}OpenGL_LIBRARIES})
+set(QtOpenGL_deps QtGui)
+
+create_pyside_module(NAME QtOpenGL
+ INCLUDE_DIRS QtOpenGL_include_dirs
+ LIBRARIES QtOpenGL_libraries
+ DEPS QtOpenGL_deps
+ TYPESYSTEM_PATH QtOpenGL_SOURCE_DIR
+ SOURCES QtOpenGL_SRC
+ STATIC_SOURCES QtOpenGL_static_sources
+ DROPPED_ENTRIES QtOpenGL_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtOpenGL/QtOpenGL_global.post.h.in b/sources/pyside6/PySide6/QtOpenGL/QtOpenGL_global.post.h.in
new file mode 100644
index 000000000..571b245a3
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/QtOpenGL_global.post.h.in
@@ -0,0 +1,35 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+#include <QtGui/qtgui-config.h>
+
+#if QT_CONFIG(opengles2)
+# include <QtOpenGL/qopenglfunctions_es2.h>
+#elif QT_CONFIG(opengl)
+# include <QtOpenGL/qopenglfunctions_1_0.h>
+# include <QtOpenGL/qopenglfunctions_1_1.h>
+# include <QtOpenGL/qopenglfunctions_1_2.h>
+# include <QtOpenGL/qopenglfunctions_1_3.h>
+# include <QtOpenGL/qopenglfunctions_1_4.h>
+# include <QtOpenGL/qopenglfunctions_1_5.h>
+# include <QtOpenGL/qopenglfunctions_2_0.h>
+# include <QtOpenGL/qopenglfunctions_2_1.h>
+# include <QtOpenGL/qopenglfunctions_3_0.h>
+# include <QtOpenGL/qopenglfunctions_3_1.h>
+# include <QtOpenGL/qopenglfunctions_3_2_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_3_2_core.h>
+# include <QtOpenGL/qopenglfunctions_3_3_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_3_3_core.h>
+# include <QtOpenGL/qopenglfunctions_4_0_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_4_0_core.h>
+# include <QtOpenGL/qopenglfunctions_4_1_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_4_1_core.h>
+# include <QtOpenGL/qopenglfunctions_4_2_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_4_2_core.h>
+# include <QtOpenGL/qopenglfunctions_4_3_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_4_3_core.h>
+# include <QtOpenGL/qopenglfunctions_4_4_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_4_4_core.h>
+# include <QtOpenGL/qopenglfunctions_4_5_compatibility.h>
+# include <QtOpenGL/qopenglfunctions_4_5_core.h>
+# include <QtOpenGL/qopenglversionfunctionsfactory.h>
+#endif
diff --git a/sources/pyside6/PySide6/QtOpenGL/glue/utils.cpp b/sources/pyside6/PySide6/QtOpenGL/glue/utils.cpp
new file mode 100644
index 000000000..27a8a9fdf
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/glue/utils.cpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtGui/QOpenGLFunctions>
+
+// Return the number of return values of the glGetBoolean/Double/Integerv functions
+// cf https://registry.khronos.org/OpenGL-Refpages/gl4/html/glGet.xhtml
+int glGetVReturnSize(GLenum pname)
+{
+ switch (pname) {
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_DEPTH_RANGE:
+ case GL_MAX_VIEWPORT_DIMS:
+#if !QT_CONFIG(opengles2)
+ case GL_POINT_SIZE_RANGE:
+ case GL_SMOOTH_LINE_WIDTH_RANGE:
+ case GL_VIEWPORT_BOUNDS_RANGE:
+#endif
+ return 2;
+ case GL_BLEND_COLOR:
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_COLOR_WRITEMASK:
+ case GL_SCISSOR_BOX:
+ case GL_VIEWPORT:
+ return 4;
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ return GL_NUM_COMPRESSED_TEXTURE_FORMATS;
+ default:
+ break;
+ }
+ return 1;
+}
+
+// Return the number of return values of the indexed
+// glGetBoolean/Double/Integeri_v functions
+// cf https://registry.khronos.org/OpenGL-Refpages/gl4/html/glGet.xhtml
+int glGetI_VReturnSize(GLenum pname)
+{
+ return pname == GL_VIEWPORT ? 4 : 1;
+}
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_includes.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_includes.xml
new file mode 100644
index 000000000..56ff7bcda
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_includes.xml
@@ -0,0 +1 @@
+<inject-code class="native" position="beginning" file="../glue/qtopengl.cpp" snippet="glgeti-vreturnsize_declaration"/>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_modifications.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_modifications.xml
new file mode 100644
index 000000000..f0e6084cf
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgeti_v_modifications.xml
@@ -0,0 +1,18 @@
+<modify-function signature="glGetBooleani_v(GLenum,GLuint,GLboolean*)">
+ <modify-argument index="return" pyi-type="Union[bool,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglextrafunctions-glgetbooleani-v"/>
+</modify-function>
+<modify-function signature="glGetIntegeri_v(GLenum,GLuint,GLint*)">
+ <modify-argument index="return" pyi-type="Union[int,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglextrafunctions-glgetintegeri-v"/>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_includes.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_includes.xml
new file mode 100644
index 000000000..3f48f19b8
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_includes.xml
@@ -0,0 +1,5 @@
+<extra-includes>
+ <include file-name="QtCore/QVarLengthArray" location="global"/>
+ <include file-name="sbkcpptonumpy.h" location="global"/>
+</extra-includes>
+<inject-code class="native" position="beginning" file="../glue/qtopengl.cpp" snippet="glgetvreturnsize_declaration"/>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_modifications.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_modifications.xml
new file mode 100644
index 000000000..b5fab57ba
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_glgetv_modifications.xml
@@ -0,0 +1,36 @@
+<modify-function signature="glGetBooleanv(GLenum,GLboolean*)">
+ <modify-argument index="return" pyi-type="Union[bool,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglfunctions-glgetbooleanv"/>
+</modify-function>
+<modify-function signature="glGetDoublev(GLenum,GLdouble*)">
+ <modify-argument index="return" pyi-type="Union[float,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglfunctions-glgetdoublev"/>
+</modify-function>
+<modify-function signature="glGetFloatv(GLenum,GLfloat*)">
+ <modify-argument index="return" pyi-type="Union[float,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglfunctions-glgetfloatv"/>
+</modify-function>
+<modify-function signature="glGetIntegerv(GLenum,GLint*)">
+ <modify-argument index="return" pyi-type="Union[int,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglfunctions-glgetintegerv"/>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl.xml
new file mode 100644
index 000000000..efbd16056
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl.xml
@@ -0,0 +1,723 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtOpenGL"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no" />
+ <load-typesystem name="templates/opengl_common.xml" generate="no" />
+
+ <rejection class="^QOpenGL.*$" argument-type="^const GLboolean ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^GLchar\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?GLchar ?\*(const)?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^char\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?char ?\*\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="GLintptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="GLsizeiptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="GLsync"/>
+ <rejection class="^QOpenGL.*$" argument-type="^GLubyte( const)?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?QMatrix.x. ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="qopengl_GLintptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="qopengl_GLsizeiptr"/>
+ <rejection class="^QOpenGL.*$" argument-type="QOpenGLTextureHelper*"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?QVector.D ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?void ?\*\*$"/>
+
+ <!-- Reject any non-const array of the version functions -->
+ <rejection class="^QOpenGLFunctions.*$" function-name="^glGet(Buffer|VertexAttrib)?Pointer.*$"/>
+ <rejection class="^QOpenGLFunctions.*$" function-name="^glMultiDrawElements.*$"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glAreTexturesResident"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateBuffers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateFramebuffers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateProgramPipelines"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateQueries"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateRenderbuffers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateSamplers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateTextures"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateTransformFeedbacks"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glCreateVertexArrays"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glFeedbackBuffer"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenBuffers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenFramebuffers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenProgramPipelines"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenQueries"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenRenderbuffers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenSamplers"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenTextures"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenTransformFeedbacks"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGenVertexArrays"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetActiveAtomicCounterBufferiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetActiveSubroutineUniformiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetActiveUniformBlockiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetActiveUniformsiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetAttachedShaders"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetBufferParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetClipPlane"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetColorTableParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetColorTableParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetConvolutionParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetConvolutionParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetFramebufferAttachmentParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetFramebufferParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetHistogramParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetHistogramParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetInternalformativ"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetLightfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetLightiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMapdv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMapfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMapiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMaterialfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMaterialiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMinmaxParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMinmaxParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetMultisamplefv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetNamedBufferParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetNamedFramebufferAttachmentParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetNamedFramebufferParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetNamedRenderbufferParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnMapdv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnMapfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnMapiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnPixelMapfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnPixelMapuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnPixelMapusv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnUniformdv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnUniformfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnUniformiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetnUniformuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetPixelMapfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetPixelMapuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetPixelMapusv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetProgramInterfaceiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetProgramiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetProgramPipelineiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetProgramResourceiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetProgramStageiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetQueryIndexediv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetQueryiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetQueryObjectiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetQueryObjectuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetRenderbufferParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetSamplerParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetSamplerParameterIiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetSamplerParameterIuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetSamplerParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetShaderiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetShaderPrecisionFormat"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexEnvfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexEnviv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexGendv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexGenfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexGeniv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexLevelParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexLevelParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexParameterIiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexParameterIuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTexParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTextureLevelParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTextureLevelParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTextureParameterfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTextureParameterIiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTextureParameterIuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTextureParameteriv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTransformFeedbacki_v"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetTransformFeedbackiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetUniformdv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetUniformfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetUniformiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetUniformSubroutineuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetUniformuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexArrayIndexediv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexArrayiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexAttribdv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexAttribfv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexAttribIiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexAttribIuiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexAttribiv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glGetVertexAttribLdv"/>
+ <rejection class="^QOpenGLFunctions_\d_\d.*$" function-name="glSelectBuffer"/>
+
+ <object-type name="QOpenGLBuffer">
+ <enum-type name="Access"/>
+ <enum-type name="RangeAccessFlag" flags="RangeAccessFlags"/>
+ <enum-type name="Type"/>
+ <enum-type name="UsagePattern"/>
+ <modify-function signature="allocate(const void*,int)">
+ <modify-argument index="1" pyi-type="bytes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QOpenGLDebugLogger">
+ <enum-type name="LoggingMode"/>
+ </object-type>
+ <value-type name="QOpenGLDebugMessage">
+ <enum-type name="Source" flags="Sources"/>
+ <enum-type name="Type" flags="Types"/>
+ <enum-type name="Severity" flags="Severities"/>
+ </value-type>
+
+ <object-type name="QOpenGLFunctions_1_0">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ </object-type>
+ <object-type name="QOpenGLFunctions_1_1">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ </object-type>
+ <object-type name="QOpenGLFunctions_1_2">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ </object-type>
+ <object-type name="QOpenGLFunctions_1_3">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ </object-type>
+ <object-type name="QOpenGLFunctions_1_4">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ </object-type>
+ <object-type name="QOpenGLFunctions_1_5">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ </object-type>
+ <object-type name="QOpenGLFunctions_2_0">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ </object-type>
+ <object-type name="QOpenGLFunctions_2_1">
+ &glgetv_includes;
+ &glgetv_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ </object-type>
+ <object-type name="QOpenGLFunctions_3_0">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ </object-type>
+ <object-type name="QOpenGLFunctions_3_1">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ </object-type>
+ <object-type name="QOpenGLFunctions_3_2_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ </object-type>
+ <object-type name="QOpenGLFunctions_3_2_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ </object-type>
+ <object-type name="QOpenGLFunctions_3_3_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications3_3a;
+ </object-type>
+ <object-type name="QOpenGLFunctions_3_3_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_0_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications3_3a;
+ &opengl_modifications4_0;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_0_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications4_0;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_1_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications3_3a;
+ &opengl_modifications4_1;
+ &opengl_modifications4_0;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_1_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ &opengl_modifications_va;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_2_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications3_3a;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_2_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ &opengl_modifications_va;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_3_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications3_3a;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ &opengl_modifications4_3;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_3_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications4_0;
+ &opengl_modifications4_3;
+ &opengl_modifications4_1;
+ &opengl_modifications_va;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_4_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications3_3a;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ &opengl_modifications4_3;
+ &opengl_modifications4_4;
+ &opengl_modifications4_4_core;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_4_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ &opengl_modifications_va;
+ &opengl_modifications4_3;
+ &opengl_modifications4_4;
+ &opengl_modifications4_4_core;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_5_Compatibility">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_0_compat;
+ &opengl_modifications1_1;
+ &opengl_modifications1_1_compat;
+ &opengl_modifications1_2_compat;
+ &opengl_modifications1_3_compat;
+ &opengl_modifications1_4;
+ &opengl_modifications1_4_compat;
+ &opengl_modifications2_0;
+ &opengl_modifications2_0_compat;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications3_3a;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ &opengl_modifications4_3;
+ &opengl_modifications4_4;
+ &opengl_modifications4_4_core;
+ &opengl_modifications4_5;
+ </object-type>
+ <object-type name="QOpenGLFunctions_4_5_Core">
+ &glgetv_includes;
+ &glgeti_v_includes;
+ &glgetv_modifications;
+ &glgeti_v_modifications;
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ &opengl_modifications1_4;
+ &opengl_modifications2_0;
+ &opengl_modifications2_1;
+ &opengl_modifications3_0;
+ &opengl_modifications3_3;
+ &opengl_modifications4_0;
+ &opengl_modifications4_1;
+ &opengl_modifications4_3;
+ &opengl_modifications4_4;
+ &opengl_modifications4_4_core;
+ &opengl_modifications4_5;
+ &opengl_modifications_va;
+ </object-type>
+ <object-type name="QOpenGLFunctions_ES2">
+ &opengl_modifications1_0;
+ &opengl_modifications1_1;
+ </object-type>
+
+ <object-type name="QOpenGLVersionFunctionsFactory">
+ <extra-includes>
+ <include file-name="QtOpenGL/qopenglfunctions_1_0.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_1_1.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_1_2.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_1_3.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_1_4.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_1_5.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_2_0.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_2_1.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_3_0.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_3_1.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_3_2_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_3_2_core.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_3_3_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_3_3_core.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_0_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_0_core.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_1_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_1_core.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_2_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_2_core.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_3_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_3_core.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_4_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_4_core.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_5_compatibility.h" location="global"/>
+ <include file-name="QtOpenGL/qopenglfunctions_4_5_core.h" location="global"/>
+ </extra-includes>
+ <modify-function signature="get(const QOpenGLVersionProfile &amp;,QOpenGLContext *)">
+ <inject-code class="target" position="beginning" file="../glue/qtopengl.cpp"
+ snippet="qopenglversionfunctionsfactory-get"/>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QOpenGLFramebufferObject">
+ <enum-type name="Attachment"/>
+ <enum-type name="FramebufferRestorePolicy"/>
+ </object-type>
+ <value-type name="QOpenGLFramebufferObjectFormat"/>
+ <object-type name="QAbstractOpenGLFunctions"/>
+ <value-type name="QOpenGLPixelTransferOptions"/>
+ <object-type name="QOpenGLShader">
+ <enum-type name="ShaderTypeBit" flags="ShaderType"/>
+ </object-type>
+ <object-type name="QOpenGLPaintDevice"/>
+ <object-type name="QOpenGLShaderProgram">
+ <modify-function signature="setAttributeArray(int,const float*,int,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setAttributeArray(const char*,const float*,int,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setAttributeValue(int,const float*,int,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setAttributeValue(const char*,const float*,int,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setUniformValueArray(int,const float*,int,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setUniformValueArray(int,const GLint*,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setUniformValueArray(int,const GLuint*,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setUniformValueArray(const char*,const float*,int,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setUniformValueArray(const char*,const GLint*,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="setUniformValueArray(const char*,const GLuint*,int)">
+ <modify-argument index="2"><array/></modify-argument>
+ </modify-function>
+ <!-- Add explicit signatures for the setUniformValue functions -->
+ <modify-function signature="^setUniformValue\(const char\*,(float|int|uint)\)$" remove="all"/>
+ <!-- No need for a signature for GLuint, since Qt (internally) calls the same function: glUniform1i -->
+ <add-function signature="setUniformValue1f(const char*, float)" return-type="void">
+ <inject-code file="../glue/qtopengl.cpp" snippet="qopenglshaderprogram_setuniformvalue_float"/>
+ </add-function>
+ <add-function signature="setUniformValue1i(const char*, GLint)" return-type="void">
+ <inject-code file="../glue/qtopengl.cpp" snippet="qopenglshaderprogram_setuniformvalue_int"/>
+ </add-function>
+ <add-function signature="setUniformValue1f(GLint, float)" return-type="void">
+ <inject-code file="../glue/qtopengl.cpp" snippet="qopenglshaderprogram_setuniformvalue_float"/>
+ </add-function>
+ <add-function signature="setUniformValue1i(GLint, GLint)" return-type="void">
+ <inject-code file="../glue/qtopengl.cpp" snippet="qopenglshaderprogram_setuniformvalue_int"/>
+ </add-function>
+ </object-type>
+ <object-type name="QOpenGLTexture">
+ <enum-type name="BindingTarget"/>
+ <enum-type name="CoordinateDirection"/>
+ <enum-type name="ComparisonFunction"/>
+ <enum-type name="ComparisonMode"/>
+ <enum-type name="CubeMapFace"/>
+ <enum-type name="DepthStencilMode"/>
+ <enum-type name="Feature" flags="Features"/>
+ <enum-type name="Filter"/>
+ <enum-type name="MipMapGeneration"/>
+ <enum-type name="PixelFormat"/>
+ <enum-type name="PixelType"/>
+ <enum-type name="SwizzleComponent"/>
+ <enum-type name="SwizzleValue"/>
+ <enum-type name="Target"/>
+ <enum-type name="TextureFormat"/>
+ <enum-type name="TextureFormatClass"/>
+ <enum-type name="TextureUnitReset"/>
+ <enum-type name="WrapMode"/>
+ <modify-function signature="borderColor(unsigned int*)const" remove="all"/>
+ <modify-function signature="borderColor(int*)const" remove="all"/>
+ <modify-function signature="borderColor(float*)const" remove="all"/>
+ </object-type>
+ <object-type name="QOpenGLTextureBlitter">
+ <enum-type name="Origin"/>
+ </object-type>
+ <object-type name="QOpenGLTimeMonitor"/>
+ <object-type name="QOpenGLTimerQuery"/>
+ <object-type name="QOpenGLWindow">
+ <enum-type name="UpdateBehavior"/>
+ </object-type>
+ <value-type name="QOpenGLVersionProfile"/>
+ <object-type name="QOpenGLVertexArrayObject">
+ <object-type name="Binder">
+ <add-function signature="__enter__()" return-type="QOpenGLVertexArrayObject::Binder">
+ <inject-code file="../glue/qtopengl.cpp" snippet="vao-binder-enter"/>
+ </add-function>
+ <add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
+ <inject-code file="../glue/qtopengl.cpp" snippet="vao-binder-exit"/>
+ </add-function>
+ </object-type>
+ </object-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0.xml
new file mode 100644
index 000000000..152efad9e
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0.xml
@@ -0,0 +1,15 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glGetStringi?\(.*$">
+ <modify-argument index="return">
+ <replace-type modified-type="QString"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="glGetString_return_QString"/>
+ </inject-code>
+</modify-function>
+<modify-function signature="^glTexParameterI?u?[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0_compat.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0_compat.xml
new file mode 100644
index 000000000..a5f8ee77a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_0_compat.xml
@@ -0,0 +1,67 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glBitmap\(.*$" remove="all"/>
+<modify-function signature="^glColor[34][a-z]{1,2}v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="glClipPlane(GLenum,const GLdouble*)">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glEvalCoord\d[a-z]{1,2}v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glFog[fi]v\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glIndex[a-z]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glLoadMatrix[df]\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glLight[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glLightModel[fi]v\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glMap1[df]\(.*$">
+ <modify-argument index="6"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glMap2[df]\(.*$">
+ <modify-argument index="10"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glMaterial[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glMultMatrix[df]\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glNormal3.v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glPixelMap[a-z]{1,2}v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glPolygonStipple\(.*$" remove="all"/>
+<modify-function signature="^glRasterPos\d[a-z]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glRect[dfis]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glTexCoord\d[dfis]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glTexEnv[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glTexGen[dfi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glVertex\d[dfis]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1.xml
new file mode 100644
index 000000000..1601a19c3
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1.xml
@@ -0,0 +1,8 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<!-- Except glGenLists/glDeleteLists -->
+<modify-function signature="^glDelete[A-KM-Z].*s\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1_compat.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1_compat.xml
new file mode 100644
index 000000000..8e9293fd6
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_1_compat.xml
@@ -0,0 +1,11 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glPrioritizeTextures\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glIndexubv\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_2_compat.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_2_compat.xml
new file mode 100644
index 000000000..58d395e3a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_2_compat.xml
@@ -0,0 +1,10 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glColorTableParameter[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glConvolutionParameter[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_3_compat.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_3_compat.xml
new file mode 100644
index 000000000..90903b33b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_3_compat.xml
@@ -0,0 +1,10 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^gl(Load|Mult)TransposeMatrix[df]\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glMultiTexCoord\d[a-z]v\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4.xml
new file mode 100644
index 000000000..7cd5f74ea
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4.xml
@@ -0,0 +1,11 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glMultiDrawArrays\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glPointParameter[fi]v\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4_compat.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4_compat.xml
new file mode 100644
index 000000000..56da84116
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications1_4_compat.xml
@@ -0,0 +1,13 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glFogCoord[df]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glSecondaryColor3u?[bdfis]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glWindowPos[23][dfis]v\(.*$">
+ <modify-argument index="1"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0.xml
new file mode 100644
index 000000000..5b342087e
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0.xml
@@ -0,0 +1,13 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glDrawBuffers\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glUniformMatrix\d[df]v\(.*$">
+ <modify-argument index="4"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glUniform\d?.v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0_compat.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0_compat.xml
new file mode 100644
index 000000000..b0c804c11
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_0_compat.xml
@@ -0,0 +1 @@
+&typesystem_opengl_modifications_va.xml;
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_1.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_1.xml
new file mode 100644
index 000000000..741fbf7d8
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications2_1.xml
@@ -0,0 +1,7 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glUniformMatrix\dx\d[a-z]v\(.*$">
+ <modify-argument index="4"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_0.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_0.xml
new file mode 100644
index 000000000..782400768
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_0.xml
@@ -0,0 +1,10 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glClearBufferu?[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glUniform\duiv\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3.xml
new file mode 100644
index 000000000..c7e883b87
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3.xml
@@ -0,0 +1,10 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glSamplerParameterI?u?[dfi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glVertexAttribP\duiv\(.*$">
+ <modify-argument index="4"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3a.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3a.xml
new file mode 100644
index 000000000..95956d164
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications3_3a.xml
@@ -0,0 +1,21 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+Present from 3.3..4.5 except 4.4 Core/4.5 Core
+-->
+<modify-function signature="^glColorP[34]uiv\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glMultiTexCoordP\duiv\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^gl(Normal|SecondaryColor)P3uiv\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glTexCoordP\duiv\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glVertexP\duiv\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_0.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_0.xml
new file mode 100644
index 000000000..a66a74895
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_0.xml
@@ -0,0 +1,10 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glPatchParameterfv\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glUniformSubroutinesuiv\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_1.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_1.xml
new file mode 100644
index 000000000..0fb6cd49a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_1.xml
@@ -0,0 +1,40 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^gl(DepthRange|Scissor|Viewport)Arrayv\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="glGetDoublei_v(GLenum,GLuint,GLdouble*)">
+ <modify-argument index="return" pyi-type="Union[float,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglextrafunctions-glgetdoublei-v"/>
+</modify-function>
+<modify-function signature="glGetFloati_v(GLenum,GLuint,GLfloat*)">
+ <modify-argument index="return" pyi-type="Union[float,numpy.ndarray]">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qopenglextrafunctions-glgetfloati-v"/>
+</modify-function>
+<modify-function signature="^glProgramUniform\du?[dfi]v\(.*$">
+ <modify-argument index="4"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glProgramUniformMatrix\d[df]v\(.*$">
+ <modify-argument index="5"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glProgramUniformMatrix\dx\d[df]v\(.*$">
+ <modify-argument index="5"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^gl(Scissor|Viewport)Indexedf?v\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glShaderBinary\(GLsizei,const GLuint\*,.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_3.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_3.xml
new file mode 100644
index 000000000..74298677d
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_3.xml
@@ -0,0 +1,7 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glInvalidate(Sub)?Framebuffer\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4.xml
new file mode 100644
index 000000000..cf90e4e0b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4.xml
@@ -0,0 +1,20 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glBindBuffersBase\(.*$">
+ <modify-argument index="4"><array/></modify-argument>
+</modify-function>
+<modify-function signature="glBindBuffersRange(GLenum,GLuint,GLsizei,const GLuint*,const GLintptr*,const GLsizeiptr*)">
+ <modify-argument index="4"><array/></modify-argument>
+ <modify-argument index="5"><array/></modify-argument>
+ <modify-argument index="6"><array/></modify-argument>
+</modify-function>
+<modify-function signature="glBindVertexBuffers(GLuint,GLsizei,const GLuint*,const GLintptr*,const GLsizei*)">
+ <modify-argument index="3"><array/></modify-argument>
+ <modify-argument index="4"><array/></modify-argument>
+ <modify-argument index="5"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glBind(ImageTextures|Samplers|Textures)\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4_core.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4_core.xml
new file mode 100644
index 000000000..3f1291db7
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_4_core.xml
@@ -0,0 +1,7 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glDebugMessageControl\(.*$">
+ <modify-argument index="5"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5.xml
new file mode 100644
index 000000000..826727736
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5.xml
@@ -0,0 +1,21 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glClearNamedFramebufferu?[fi]v\(.*$">
+ <modify-argument index="4"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glInvalidateNamedFramebuffer(Sub)?Data\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glNamedFramebufferDrawBuffers\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="^glTextureParameterI?u?[fi]v\(.*$">
+ <modify-argument index="3"><array/></modify-argument>
+</modify-function>
+<modify-function signature="glVertexArrayVertexBuffers(GLuint, GLuint,GLsizei,const GLuint *,const GLintptr*,const GLsizei*)">
+ <modify-argument index="4"><array/></modify-argument>
+ <modify-argument index="5"><array/></modify-argument>
+ <modify-argument index="6"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5_core.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5_core.xml
new file mode 100644
index 000000000..5b7c30fe5
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications4_5_core.xml
@@ -0,0 +1,5 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+ Remove me!
+-->
diff --git a/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications_va.xml b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications_va.xml
new file mode 100644
index 000000000..624281645
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGL/typesystem_opengl_modifications_va.xml
@@ -0,0 +1,7 @@
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<modify-function signature="^glVertexAttrib[IL]?\dN?u?[bdfis]v\(.*$">
+ <modify-argument index="2"><array/></modify-argument>
+</modify-function>
diff --git a/sources/pyside6/PySide6/QtOpenGLWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtOpenGLWidgets/CMakeLists.txt
new file mode 100644
index 000000000..8c7386130
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGLWidgets/CMakeLists.txt
@@ -0,0 +1,33 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtOpenGLWidgets)
+
+set(QtOpenGLWidgets_SRC
+${QtOpenGLWidgets_GEN_DIR}/qopenglwidget_wrapper.cpp
+# module is always needed
+${QtOpenGLWidgets_GEN_DIR}/qtopenglwidgets_module_wrapper.cpp
+)
+
+set(QtOpenGLWidgets_include_dirs ${QtOpenGLWidgets_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtOpenGLWidgets_GEN_DIR})
+
+set(QtOpenGLWidgets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}OpenGLWidgets_LIBRARIES})
+
+set(QtOpenGLWidgets_deps QtOpenGL QtWidgets)
+
+create_pyside_module(NAME QtOpenGLWidgets
+ INCLUDE_DIRS QtOpenGLWidgets_include_dirs
+ LIBRARIES QtOpenGLWidgets_libraries
+ DEPS QtOpenGLWidgets_deps
+ TYPESYSTEM_PATH QtOpenGLWidgets_SOURCE_DIR
+ SOURCES QtOpenGLWidgets_SRC)
diff --git a/sources/pyside6/PySide6/QtOpenGLWidgets/typesystem_openglwidgets.xml b/sources/pyside6/PySide6/QtOpenGLWidgets/typesystem_openglwidgets.xml
new file mode 100644
index 000000000..1e308a3f2
--- /dev/null
+++ b/sources/pyside6/PySide6/QtOpenGLWidgets/typesystem_openglwidgets.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtOpenGLWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no" />
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
+
+ <object-type name="QOpenGLWidget">
+ <enum-type name="UpdateBehavior"/>
+ <enum-type name="TargetBuffer" since="6.5"/>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtPdf/CMakeLists.txt b/sources/pyside6/PySide6/QtPdf/CMakeLists.txt
new file mode 100644
index 000000000..5b9c1457d
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPdf/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtPdf)
+
+set(QtPdf_SRC
+${QtPdf_GEN_DIR}/qpdfbookmarkmodel_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdfdocument_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdfdocumentrenderoptions_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdfpagerenderer_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdflink_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdflinkmodel_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdfpagenavigator_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdfsearchmodel_wrapper.cpp
+${QtPdf_GEN_DIR}/qpdfselection_wrapper.cpp
+# module is always needed
+${QtPdf_GEN_DIR}/qtpdf_module_wrapper.cpp
+)
+
+set(QtPdf_include_dirs ${QtPdf_SOURCE_DIR}
+ ${QtPdf_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtNetwork_GEN_DIR})
+
+set(QtPdf_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Pdf_LIBRARIES})
+
+set(QtPdf_deps QtCore QtGui QtNetwork)
+
+create_pyside_module(NAME QtPdf
+ INCLUDE_DIRS QtPdf_include_dirs
+ LIBRARIES QtPdf_libraries
+ DEPS QtPdf_deps
+ TYPESYSTEM_PATH QtPdf_SOURCE_DIR
+ SOURCES QtPdf_SRC
+ TYPESYSTEM_NAME ${QtPdf_BINARY_DIR}/typesystem_pdf.xml)
diff --git a/sources/pyside6/PySide6/QtPdf/typesystem_pdf.xml b/sources/pyside6/PySide6/QtPdf/typesystem_pdf.xml
new file mode 100644
index 000000000..e008e4880
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPdf/typesystem_pdf.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtPdf"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <object-type name="QPdfBookmarkModel">
+ <enum-type name="Role" python-type="IntEnum"/>
+ </object-type>
+ <object-type name="QPdfDocument">
+ <enum-type name="Status"/>
+ <enum-type name="Error"/>
+ <enum-type name="MetaDataField"/>
+ <enum-type name="PageModelRole"/>
+ </object-type>
+ <value-type name="QPdfDocumentRenderOptions">
+ <enum-type name="RenderFlag" flags="RenderFlags" since="6.5"/>
+ <enum-type name="Rotation" since="6.5"/>
+ </value-type>
+ <object-type name="QPdfPageRenderer">
+ <enum-type name="RenderMode"/>
+ </object-type>
+ <value-type name="QPdfLink"/>
+ <object-type name="QPdfPageNavigator"/>
+ <object-type name="QPdfSearchModel">
+ <enum-type name="Role"/>
+ </object-type>
+ <object-type name="QPdfLinkModel" since="6.6">
+ <enum-type name="Role"/>
+ </object-type>
+ <object-type name="QPdfSelection"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtPdfWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtPdfWidgets/CMakeLists.txt
new file mode 100644
index 000000000..de1335f8a
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPdfWidgets/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtPdfWidgets)
+
+set(QtPdfWidgets_SRC
+${QtPdfWidgets_GEN_DIR}/qpdfpageselector_wrapper.cpp
+${QtPdfWidgets_GEN_DIR}/qpdfview_wrapper.cpp
+# module is always needed
+${QtPdfWidgets_GEN_DIR}/qtpdfwidgets_module_wrapper.cpp
+)
+
+set(QtPdfWidgets_include_dirs ${QtPdfWidgets_SOURCE_DIR}
+ ${QtPdfWidgets_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Pdf_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtPdf_GEN_DIR})
+
+set(QtPdfWidgets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}PdfWidgets_LIBRARIES})
+
+set(QtPdfWidgets_deps QtCore QtGui QtNetwork QtWidgets QtPdf)
+
+create_pyside_module(NAME QtPdfWidgets
+ INCLUDE_DIRS QtPdfWidgets_include_dirs
+ LIBRARIES QtPdfWidgets_libraries
+ DEPS QtPdfWidgets_deps
+ TYPESYSTEM_PATH QtPdfWidgets_SOURCE_DIR
+ SOURCES QtPdfWidgets_SRC
+ TYPESYSTEM_NAME ${QtPdfWidgets_BINARY_DIR}/typesystem_pdfwidgets.xml)
diff --git a/sources/pyside6/PySide6/QtPdfWidgets/typesystem_pdfwidgets.xml b/sources/pyside6/PySide6/QtPdfWidgets/typesystem_pdfwidgets.xml
new file mode 100644
index 000000000..5df72075c
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPdfWidgets/typesystem_pdfwidgets.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtPdfWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+ <load-typesystem name="QtPdf/typesystem_pdf.xml" generate="no"/>
+ <object-type name="QPdfPageSelector" since="6.6"/>
+ <object-type name="QPdfView">
+ <enum-type name="PageMode"/>
+ <enum-type name="ZoomMode"/>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtPositioning/CMakeLists.txt b/sources/pyside6/PySide6/QtPositioning/CMakeLists.txt
new file mode 100644
index 000000000..cad6dcb74
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPositioning/CMakeLists.txt
@@ -0,0 +1,60 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtPositioning)
+
+set(QtPositioning_OPTIONAL_SRC )
+set(QtPositioning_DROPPED_ENTRIES )
+
+set(QtPositioning_SRC
+${QtPositioning_GEN_DIR}/qgeoaddress_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeoareamonitorinfo_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeoareamonitorsource_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeolocation_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeocircle_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeocoordinate_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeopath_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeopolygon_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeopositioninfo_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeopositioninfosource_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeopositioninfosourcefactory_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeorectangle_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeosatelliteinfo_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeosatelliteinfosource_wrapper.cpp
+${QtPositioning_GEN_DIR}/qgeoshape_wrapper.cpp
+${QtPositioning_GEN_DIR}/qnmeapositioninfosource_wrapper.cpp
+${QtPositioning_GEN_DIR}/qnmeasatelliteinfosource_wrapper.cpp
+# module is always needed
+${QtPositioning_GEN_DIR}/qtpositioning_module_wrapper.cpp
+)
+
+set(QtPositioning_include_dirs ${QtPositioning_SOURCE_DIR}
+ ${QtPositioning_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Positioning_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtPositioning_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Positioning_LIBRARIES})
+
+set(QtPositioning_deps QtCore)
+
+create_pyside_module(NAME QtPositioning
+ INCLUDE_DIRS QtPositioning_include_dirs
+ LIBRARIES QtPositioning_libraries
+ DEPS QtPositioning_deps
+ TYPESYSTEM_PATH QtPositioning_SOURCE_DIR
+ SOURCES QtPositioning_SRC
+ DROPPED_ENTRIES QtPositioning_DROPPED_ENTRIES)
+
+if (APPLE)
+ # The QtLocation permission plugin cannot be linked to QtCore.abi3.so because for a framework
+ # build of Qt, the QtCore framework bundle must be loaded before calling
+ # Q_IMPORT_PLUGIN(QDarwinLocationPermissionPlugin)
+ set(permission_plugin_name "QDarwinLocationPermissionPlugin")
+ set(permission_plugin "${QT_CMAKE_EXPORT_NAMESPACE}::${permission_plugin_name}")
+ set_target_properties(QtPositioning PROPERTIES "_qt_has_${permission_plugin_name}_usage_description" TRUE)
+ # importing the plugin
+ qt6_import_plugins(QtPositioning INCLUDE ${permission_plugin})
+endif()
diff --git a/sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml b/sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml
new file mode 100644
index 000000000..8dac3f00d
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPositioning/typesystem_positioning.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtPositioning"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <inject-code class="native" position="beginning" file="../glue/qtpositioning.cpp"
+ snippet="darwin_location_permission_plugin"/>
+ <value-type name="QGeoAddress"/>
+ <value-type name="QGeoAreaMonitorInfo"/>
+ <object-type name="QGeoAreaMonitorSource">
+ <enum-type name="Error"/>
+ <enum-type name="AreaMonitorFeature" flags="AreaMonitorFeatures"/>
+ </object-type>
+ <value-type name="QGeoLocation"/>
+ <value-type name="QGeoCircle"/>
+ <value-type name="QGeoCoordinate">
+ <enum-type name="CoordinateType"/>
+ <enum-type name="CoordinateFormat"/>
+ </value-type>
+ <value-type name="QGeoPath"/>
+ <value-type name="QGeoPolygon"/>
+ <value-type name="QGeoPositionInfo">
+ <enum-type name="Attribute"/>
+ </value-type>
+ <object-type name="QGeoPositionInfoSource">
+ <enum-type name="Error"/>
+ <enum-type name="PositioningMethod" flags="PositioningMethods"/>
+ </object-type>
+ <object-type name="QGeoPositionInfoSourceFactory"/>
+ <value-type name="QGeoRectangle"/>
+ <value-type name="QGeoSatelliteInfo">
+ <enum-type name="Attribute"/>
+ <enum-type name="SatelliteSystem"/>
+ </value-type>
+ <object-type name="QGeoSatelliteInfoSource">
+ <enum-type name="Error"/>
+ </object-type>
+ <value-type name="QGeoShape">
+ <enum-type name="ShapeType"/>
+ </value-type>
+ <object-type name="QNmeaPositionInfoSource">
+ <enum-type name="UpdateMode"/>
+ </object-type>
+ <object-type name="QNmeaSatelliteInfoSource">
+ <enum-type name="UpdateMode"/>
+ <enum-type name="SatelliteInfoParseStatus"/>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtPrintSupport/CMakeLists.txt b/sources/pyside6/PySide6/QtPrintSupport/CMakeLists.txt
new file mode 100644
index 000000000..fb0db5f83
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPrintSupport/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtPrintSupport)
+
+set(QtPrintSupport_SRC
+${QtPrintSupport_GEN_DIR}/qabstractprintdialog_wrapper.cpp
+${QtPrintSupport_GEN_DIR}/qpagesetupdialog_wrapper.cpp
+${QtPrintSupport_GEN_DIR}/qprintdialog_wrapper.cpp
+${QtPrintSupport_GEN_DIR}/qprintengine_wrapper.cpp
+${QtPrintSupport_GEN_DIR}/qprinter_wrapper.cpp
+${QtPrintSupport_GEN_DIR}/qprinterinfo_wrapper.cpp
+${QtPrintSupport_GEN_DIR}/qprintpreviewdialog_wrapper.cpp
+${QtPrintSupport_GEN_DIR}/qprintpreviewwidget_wrapper.cpp
+# module is always needed
+${QtPrintSupport_GEN_DIR}/qtprintsupport_module_wrapper.cpp
+)
+
+set(QtPrintSupport_include_dirs ${QtPrintSupport_SOURCE_DIR}
+ ${QtPrintSupport_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+set(QtPrintSupport_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_LIBRARIES})
+
+set(QtPrintSupport_deps QtWidgets)
+create_pyside_module(NAME QtPrintSupport
+ INCLUDE_DIRS QtPrintSupport_include_dirs
+ LIBRARIES QtPrintSupport_libraries
+ DEPS QtPrintSupport_deps
+ TYPESYSTEM_PATH QtPrintSupport_SOURCE_DIR
+ SOURCES QtPrintSupport_SRC
+ TYPESYSTEM_NAME ${QtPrintSupport_BINARY_DIR}/typesystem_printsupport.xml)
diff --git a/sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport.xml b/sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport.xml
new file mode 100644
index 000000000..46973a5f9
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtPrintSupport"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+ <load-typesystem name="QtPrintSupport/typesystem_printsupport_common.xml" generate="yes"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport_common.xml b/sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport_common.xml
new file mode 100644
index 000000000..126902b73
--- /dev/null
+++ b/sources/pyside6/PySide6/QtPrintSupport/typesystem_printsupport_common.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtPrintSupport">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <object-type name="QPageSetupDialog">
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="int">
+ <inject-code file="../glue/qtprintsupport.cpp" snippet="exec" />
+ </add-function>
+ </object-type>
+
+ <object-type name="QAbstractPrintDialog">
+ <enum-type name="PrintDialogOption" flags="PrintDialogOptions"/>
+ <enum-type name="PrintRange"/>
+ </object-type>
+
+ <object-type name="QPrintDialog">
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="int">
+ <inject-code file="../glue/qtprintsupport.cpp" snippet="exec" />
+ </add-function>
+ </object-type>
+ <object-type name="QPrintEngine">
+ <enum-type name="PrintEnginePropertyKey"/>
+ </object-type>
+ <value-type name="QPrinterInfo"/>
+ <rejection class="QPrinter" function-name="printerSelectionOption"/>
+ <rejection class="QPrinter" function-name="setPrinterSelectionOption"/>
+
+ <object-type name="QPrinter" >
+ <enum-type name="ColorMode"/>
+ <enum-type name="DuplexMode"/>
+ <enum-type name="OutputFormat"/>
+ <enum-type name="PageOrder"/>
+ <enum-type name="PaperSource"/>
+ <enum-type name="PrintRange"/>
+ <enum-type name="PrinterMode"/>
+ <enum-type name="PrinterState"/>
+ <enum-type name="Unit"/>
+ <modify-function signature="setEngines(QPrintEngine*,QPaintEngine*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <extra-includes>
+ <include file-name="QPrinterInfo" location="global"/>
+ </extra-includes>
+ <!-- fixme: Check if this is still required in Qt 6:
+ bool QPagedPaintDevice::setPageSize(QPageSize)
+ void QPagedPaintDevice::setPageSize(QPagedPaintDevice::PageSize) -->
+ <add-function signature="setPageSize(const QPageSize&amp;)" return-type="bool">
+ <inject-code file="../glue/qtprintsupport.cpp" snippet="setpagesize" />
+ </add-function>
+ </object-type>
+
+ <object-type name="QPrintPreviewDialog"/>
+ <object-type name="QPrintPreviewWidget">
+ <enum-type name="ViewMode"/>
+ <enum-type name="ZoomMode"/>
+ <modify-function signature="print()" rename="print_"/>
+ </object-type>
+
+</typesystem>
+
diff --git a/sources/pyside6/PySide6/QtQml/CMakeLists.txt b/sources/pyside6/PySide6/QtQml/CMakeLists.txt
new file mode 100644
index 000000000..87de1d7dd
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQml/CMakeLists.txt
@@ -0,0 +1,76 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtQml)
+
+qt_wrap_cpp(QPYQMLPARSERSTATUS_MOC "${pyside6_SOURCE_DIR}/qpyqmlparserstatus.h")
+qt_wrap_cpp(QPYQMLPROPERTYVALUESOURCE_MOC "${pyside6_SOURCE_DIR}/qpyqmlpropertyvaluesource.h")
+
+set(QtQml_static_sources "${QtQml_SOURCE_DIR}/pysideqmlvolatilebool.cpp"
+ "${QPYQMLPARSERSTATUS_MOC}"
+ "${QPYQMLPROPERTYVALUESOURCE_MOC}")
+
+set(QtQml_SRC
+${QtQml_GEN_DIR}/qjsengine_wrapper.cpp
+${QtQml_GEN_DIR}/qjsmanagedvalue_wrapper.cpp
+${QtQml_GEN_DIR}/qjsprimitivevalue_wrapper.cpp
+${QtQml_GEN_DIR}/qjsvalue_wrapper.cpp
+${QtQml_GEN_DIR}/qjsvalueiterator_wrapper.cpp
+${QtQml_GEN_DIR}/qpyqmlparserstatus_wrapper.cpp
+${QtQml_GEN_DIR}/qpyqmlpropertyvaluesource_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlabstracturlinterceptor_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlapplicationengine_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlcomponent_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlcontext_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlcontext_propertypair_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlerror_wrapper.cpp
+${QtQml_GEN_DIR}/qqmldebuggingenabler_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlengine_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlexpression_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlextensioninterface_wrapper.cpp
+${QtQml_GEN_DIR}/qqmltypesextensioninterface_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlextensionplugin_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlfile_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlfileselector_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlimageproviderbase_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlincubator_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlincubationcontroller_wrapper.cpp
+#${QtQml_GEN_DIR}/qqmllistproperty_wrapper.cpp
+${QtQml_GEN_DIR}/qqmllistreference_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlparserstatus_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlproperty_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlpropertymap_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlpropertyvaluesource_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlscriptstring_wrapper.cpp
+${QtQml_GEN_DIR}/qqmlnetworkaccessmanagerfactory_wrapper.cpp
+# module is always needed
+${QtQml_GEN_DIR}/qtqml_module_wrapper.cpp
+)
+
+configure_file("${QtQml_SOURCE_DIR}/QtQml_global.post.h.in"
+ "${QtQml_BINARY_DIR}/QtQml_global.post.h" @ONLY)
+
+set(QtQml_include_dirs ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${libpysideqml_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQml_GEN_DIR})
+
+set(QtQml_libraries pyside6 pyside6qml
+ ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES})
+
+set(QtQml_deps QtNetwork)
+
+create_pyside_module(NAME QtQml
+ INCLUDE_DIRS QtQml_include_dirs
+ LIBRARIES QtQml_libraries
+ DEPS QtQml_deps
+ TYPESYSTEM_PATH QtQml_SOURCE_DIR
+ SOURCES QtQml_SRC
+ STATIC_SOURCES QtQml_static_sources)
diff --git a/sources/pyside6/PySide6/QtQml/QtQml_global.post.h.in b/sources/pyside6/PySide6/QtQml/QtQml_global.post.h.in
new file mode 100644
index 000000000..64c563753
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQml/QtQml_global.post.h.in
@@ -0,0 +1,2 @@
+#include "qpyqmlparserstatus.h"
+#include "qpyqmlpropertyvaluesource.h"
diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp b/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp
new file mode 100644
index 000000000..ca3dfebed
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp
@@ -0,0 +1,161 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmlvolatilebool.h"
+
+#include <pep384ext.h>
+#include <signature.h>
+
+#include <QtCore/QDebug>
+
+// Volatile Bool used for QQmlIncubationController::incubateWhile(std::atomic<bool> *, int)
+
+// Generated headers containing the definition of struct
+// QtQml_VolatileBoolObject. It is injected to avoid "pyside6_qtqml_python.h"
+// depending on other headers.
+#include "pyside6_qtcore_python.h"
+#include "pyside6_qtqml_python.h"
+
+// VolatileBool (volatile bool) type definition.
+
+static PyObject *
+QtQml_VolatileBoolObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"x", 0};
+ PyObject *x = Py_False;
+ long ok;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", const_cast<char **>(kwlist), &x))
+ return nullptr;
+ ok = PyObject_IsTrue(x);
+ if (ok < 0)
+ return nullptr;
+
+ auto *self = PepExt_TypeCallAlloc<QtQml_VolatileBoolObject>(type, 0);
+
+ if (self != nullptr)
+ self->flag = new AtomicBool(ok);
+
+ return reinterpret_cast<PyObject *>(self);
+}
+
+static void QtQml_VolatileBoolObject_dealloc(PyObject *self)
+{
+ auto volatileBool = reinterpret_cast<QtQml_VolatileBoolObject *>(self);
+ delete volatileBool->flag;
+ Sbk_object_dealloc(self);
+}
+
+static PyObject *
+QtQml_VolatileBoolObject_get(QtQml_VolatileBoolObject *self)
+{
+ if (*self->flag) {
+ Py_RETURN_TRUE;
+ }
+ Py_RETURN_FALSE;
+}
+
+static PyObject *
+QtQml_VolatileBoolObject_set(QtQml_VolatileBoolObject *self, PyObject *args)
+{
+ PyObject *value = Py_False;
+ long ok;
+
+ if (!PyArg_ParseTuple(args, "O:bool", &value)) {
+ return nullptr;
+ }
+
+ ok = PyObject_IsTrue(value);
+ if (ok < 0)
+ return PyErr_Format(PyExc_TypeError, "Not a boolean value.");
+
+ *self->flag = ok > 0;
+
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef QtQml_VolatileBoolObject_methods[] = {
+ {"get", reinterpret_cast<PyCFunction>(QtQml_VolatileBoolObject_get), METH_NOARGS,
+ "B.get() -> Bool. Returns the value of the volatile boolean"
+ },
+ {"set", reinterpret_cast<PyCFunction>(QtQml_VolatileBoolObject_set), METH_VARARGS,
+ "B.set(a) -> None. Sets the value of the volatile boolean"
+ },
+ {nullptr, nullptr, 0, nullptr} /* Sentinel */
+};
+
+static PyObject *
+QtQml_VolatileBoolObject_repr(QtQml_VolatileBoolObject *self)
+{
+ PyObject *s;
+
+ if (*self->flag)
+ s = PyBytes_FromFormat("%s(True)",
+ Py_TYPE(self)->tp_name);
+ else
+ s = PyBytes_FromFormat("%s(False)",
+ Py_TYPE(self)->tp_name);
+ Py_XINCREF(s);
+ return s;
+}
+
+static PyObject *
+QtQml_VolatileBoolObject_str(QtQml_VolatileBoolObject *self)
+{
+ PyObject *s;
+
+ if (*self->flag)
+ s = PyBytes_FromFormat("%s(True) -> %p",
+ Py_TYPE(self)->tp_name, self->flag);
+ else
+ s = PyBytes_FromFormat("%s(False) -> %p",
+ Py_TYPE(self)->tp_name, self->flag);
+ Py_XINCREF(s);
+ return s;
+}
+
+static PyTypeObject *createVolatileBoolType()
+{
+ PyType_Slot QtQml_VolatileBoolType_slots[] = {
+ {Py_tp_repr, reinterpret_cast<void *>(QtQml_VolatileBoolObject_repr)},
+ {Py_tp_str, reinterpret_cast<void *>(QtQml_VolatileBoolObject_str)},
+ {Py_tp_methods, reinterpret_cast<void *>(QtQml_VolatileBoolObject_methods)},
+ {Py_tp_new, reinterpret_cast<void *>(QtQml_VolatileBoolObject_new)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(QtQml_VolatileBoolObject_dealloc)},
+ {0, 0}
+ };
+
+ PyType_Spec QtQml_VolatileBoolType_spec = {
+ "2:PySide6.QtQml.VolatileBool",
+ sizeof(QtQml_VolatileBoolObject),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ QtQml_VolatileBoolType_slots,
+ };
+
+ return SbkType_FromSpec(&QtQml_VolatileBoolType_spec);
+}
+
+PyTypeObject *QtQml_VolatileBool_TypeF(void)
+{
+ static auto *type = createVolatileBoolType();
+ return type;
+}
+
+static const char *VolatileBool_SignatureStrings[] = {
+ "PySide6.QtQml.VolatileBool.get(self)->bool",
+ "PySide6.QtQml.VolatileBool.set(self,a:object)",
+ nullptr}; // Sentinel
+
+void initQtQmlVolatileBool(PyObject *module)
+{
+ if (InitSignatureStrings(QtQml_VolatileBool_TypeF(), VolatileBool_SignatureStrings) < 0) {
+ PyErr_Print();
+ qWarning() << "Error initializing VolatileBool type.";
+ return;
+ }
+
+ Py_INCREF(QtQml_VolatileBool_TypeF());
+ PyModule_AddObject(module, PepType_GetNameStr(QtQml_VolatileBool_TypeF()),
+ reinterpret_cast<PyObject *>(QtQml_VolatileBool_TypeF()));
+}
diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.h b/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.h
new file mode 100644
index 000000000..fd3707aba
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.h
@@ -0,0 +1,15 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLVOLATILEBOOL_H
+#define PYSIDEQMLVOLATILEBOOL_H
+
+#include <sbkpython.h>
+
+PyTypeObject *QtQml_VolatileBool_TypeF(void);
+
+#define VolatileBool_Check(op) (Py_TYPE(op) == QtQml_VolatileBool_TypeF())
+
+void initQtQmlVolatileBool(PyObject *module);
+
+#endif // PYSIDEQMLVOLATILEBOOL_H
diff --git a/sources/pyside6/PySide6/QtQml/typesystem_qml.xml b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml
new file mode 100644
index 000000000..3392ef379
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQml/typesystem_qml.xml
@@ -0,0 +1,340 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtQml"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+
+ <rejection class="QQmlPrivate"/>
+
+ <inject-code class="target" position="declaration">
+ // Volatile Bool Ptr type definition for QQmlIncubationController::incubateWhile(std::atomic&lt;bool&gt; *, int)
+ #include &lt;atomic&gt;
+
+ using AtomicBool = std::atomic&lt;bool&gt;;
+
+ struct QtQml_VolatileBoolObject {
+ PyObject_HEAD
+ AtomicBool *flag;
+ };
+ </inject-code>
+
+ <inject-code class="native" position="beginning">
+ #include &lt;pysideqml.h&gt;
+ #include &lt;pysideqmlregistertype.h&gt;
+ #include &lt;pysideqmlattached.h&gt;
+ #include "pysideqmlvolatilebool.h"
+ </inject-code>
+
+ <!-- This is to inform the generator that the VolatileBool python type exists -->
+ <custom-type name="VolatileBool" check-function="VolatileBool_Check"/>
+ <primitive-type name="bool volatile" target-lang-api-name="VolatileBool">
+ <!-- No conversion rules are specified here, because the generator does not handle
+ pointer to primitive types without function adjustment.
+ See commit ff0b861b59b41387e771d9cd565e13de8b2750d1 or search for changePStr
+ in generator tests folder. -->
+ </primitive-type>
+
+ <enum-type name="QQmlModuleImportSpecialVersions" doc-file="qqmlengine"/>
+
+ <!-- expose QQmlIncubationController::incubateWhile() (see
+ QtQml_VolatileBoolTypeF/pysideqmlvolatilebool.h) -->
+ <namespace-type name="std" generate="no">
+ <value-type name="atomic" generate="no"/>
+ </namespace-type>
+
+ <add-function signature="qmlAttachedPropertiesObject(PyTypeObject*@type_obj@,QObject*,bool=true)"
+ return-type="QObject*">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlattachedpropertiesobject"/>
+ </add-function>
+
+ <add-function signature="qmlRegisterType(PyTypeObject@type_obj@,const char*@uri@,int@version_major@,int@version_minor@,const char*@qml_name@)" return-type="int">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlregistertype"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qmlregistertype"/>
+ <modify-argument index="2" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="qmlRegisterSingletonType(PyTypeObject@type_obj@,const char*@uri@,int@version_major@,int@version_minor@,const char*@qml_name@,PyObject*@callback@)" return-type="int">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlregistersingletontype_qobject_callback"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qmlregistersingletontype_qobject_callback"/>
+ <modify-argument index="2" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="qmlRegisterSingletonType(PyTypeObject@type_obj@,const char*@uri@,int@version_major@,int@version_minor@,const char*@qml_name@)" return-type="int">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlregistersingletontype_qobject_nocallback"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qmlregistersingletontype_qobject_nocallback"/>
+ <modify-argument index="2" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="qmlRegisterSingletonType(const char*@uri@,int@version_major@,int@version_minor@,const char*@qml_name@,PyObject*@callback@)" return-type="int">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlregistersingletontype_qjsvalue"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qmlregistersingletontype_qjsvalue"/>
+ <modify-argument index="1" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="qmlRegisterSingletonInstance(PyTypeObject@type_obj@,const char*@uri@,int@version_major@,int@version_minor@,const char*@qml_name@,PyObject*@callback@)" return-type="int">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlregistersingletoninstance"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qmlregistersingletoninstance"/>
+ <modify-argument index="2" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="qmlRegisterUncreatableType(PyTypeObject@type_obj@,const char*@uri@,int@version_major@,int@version_minor@,const char*@qml_name@,const char*@message@)" return-type="int">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlregisteruncreatabletype"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qmlregisteruncreatabletype"/>
+ <modify-argument index="2" pyi-type="str"/>
+ </add-function>
+
+ <add-function signature="QmlElement(PyObject*)" return-type="PyObject*">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlelement"/>
+ </add-function>
+
+ <add-function signature="QmlAnonymous(PyObject*)" return-type="PyObject*">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlanonymous"/>
+ </add-function>
+
+ <add-function signature="QmlSingleton(PyObject*)" return-type="PyObject*">
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlsingleton"/>
+ </add-function>
+
+ <function signature="qjsEngine(const QObject*)">
+ <modify-function>
+ <modify-argument index="return" pyi-type="Optional[PySide6.QtQml.QJSEngine]"/>
+ </modify-function>
+ </function>
+ <function signature="qmlClearTypeRegistrations()" doc-file="qqmlengine"/>
+ <function signature="qmlContext(const QObject*)">
+ <modify-function>
+ <modify-argument index="return" pyi-type="Optional[PySide6.QtQml.QQmlContext]"/>
+ </modify-function>
+ </function>
+ <function signature="qmlEngine(const QObject*)">
+ <modify-function>
+ <modify-argument index="return" pyi-type="Optional[PySide6.QtQml.QQmlEngine]"/>
+ </modify-function>
+ </function>
+ <function signature="qmlProtectModule(const char*,int)" doc-file="qqmlengine"/>
+ <function signature="qmlRegisterModule(const char*,int,int)" doc-file="qqmlengine"/>
+ <function signature="qmlTypeId(const char*,int,int,const char*)" doc-file="qqmlengine"/>
+ <function signature="qmlRegisterType(const QUrl &amp;,const char *,int,int,const char *)"
+ doc-file="qqmlengine"/>
+ <function signature="qmlRegisterSingletonType(const QUrl &amp;,const char *,int,int,const char *)"
+ doc-file="qqmlengine"/>
+ <function signature="qmlRegisterUncreatableMetaObject(const QMetaObject&amp;,const char*,int,int, const char*,const QString&amp;)"
+ doc-file="qqmlengine"/>
+
+ <enum-type identified-by-value="QML_HAS_ATTACHED_PROPERTIES">
+ <extra-includes>
+ <include file-name="QtQml" location="global"/>
+ </extra-includes>
+ </enum-type>
+
+ <inject-code class="target" position="end" file="../glue/qtqml.cpp" snippet="init"/>
+
+ <object-type name="QJSEngine">
+ <enum-type name="Extension" flags="Extensions"/>
+ <enum-type name="ObjectOwnership"/>
+ <add-function signature="toScriptValue(const QVariant&amp;)" return-type="QJSValue">
+ <inject-code class="target" position="end" file="../glue/qtqml.cpp" snippet="qjsengine-toscriptvalue"/>
+ </add-function>
+ </object-type>
+ <object-type name="QJSManagedValue">
+ <enum-type name="Type"/>
+ </object-type>
+ <value-type name="QJSPrimitiveValue">
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="QJSValue">
+ <enum-type name="ErrorType"/>
+ <enum-type name="SpecialValue"/>
+ <enum-type name="ObjectConversionBehavior" since="6.1"/>
+ </value-type>
+ <object-type name="QJSValueIterator"/>
+ <object-type name="QQmlAbstractUrlInterceptor">
+ <enum-type name="DataType"/>
+ </object-type>
+ <object-type name="QQmlApplicationEngine">
+ <!-- PYSIDE-1681: QQmlApplicationEngine constructor, load() and similar need
+ allow-thread in case there is a message handler installed
+ (qInstallMessageHandler) -->
+ <modify-function signature="^QQmlApplicationEngine\(.*\)$" allow-thread="yes"/>
+ <!-- PYSIDE-1736 In the presence of load(QString)/load(QUrl), check for Path/string
+ first to avoid an implicit conversion from string to QUrl. -->
+ <modify-function signature="load(const QString &amp;)" allow-thread="yes" overload-number="1">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="load(const QUrl &amp;)" allow-thread="yes" overload-number="2"/>
+ <modify-function signature="loadFromModule(QAnyStringView,QAnyStringView)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QQmlComponent">
+ <enum-type name="CompilationMode"/>
+ <enum-type name="Status"/>
+ <modify-function signature="QQmlComponent(QObject*)" allow-thread="yes"/>
+ <modify-function signature="QQmlComponent(QQmlEngine*,QObject*)" allow-thread="yes"/>
+ <modify-function signature="QQmlComponent(QQmlEngine*,QString,QObject*)" allow-thread="yes"/>
+ <modify-function signature="QQmlComponent(QQmlEngine*,QString,QQmlComponent::CompilationMode,QObject*)" allow-thread="yes"/>
+ <modify-function signature="QQmlComponent(QQmlEngine*,QUrl,QObject*)" allow-thread="yes"/>
+ <modify-function signature="QQmlComponent(QQmlEngine*,QUrl,QQmlComponent::CompilationMode,QObject*)" allow-thread="yes"/>
+ <modify-function signature="loadFromModule(QAnyStringView,QAnyStringView,QQmlComponent::CompilationMode)" allow-thread="yes"/>
+ <modify-function signature="loadUrl(QUrl)" allow-thread="yes"/>
+ <modify-function signature="loadUrl(QUrl,QQmlComponent::CompilationMode)" allow-thread="yes"/>
+ <modify-function signature="setData(QByteArray,QUrl)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QQmlContext">
+ <value-type name="PropertyPair"/>
+ </object-type>
+ <value-type name="QQmlError">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtqml.cpp" snippet="qmlerrror-repr"/>
+ </add-function>
+ </value-type>
+ <object-type name="QQmlDebuggingEnabler">
+ <enum-type name="StartMode"/>
+ </object-type>
+
+ <object-type name="QQmlEngine">
+ <modify-function signature="addImageProvider(const QString&amp;,QQmlImageProviderBase*)">
+ <modify-argument index="2">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addImportPath(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <modify-function signature="addPluginPath(const QString &amp;)">
+ <modify-argument index="1"><replace-type modified-type="PyPathLike"/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qfile-path-1"/>
+ </modify-function>
+ <add-function signature="singletonInstance(int@qmlTypeId@)"
+ return-type="QObject*">
+ <!-- Suppress return value heuristics -->
+ <modify-argument index="return"
+ pyi-type="Union[PySide6.QtCore.QObject, PySide6.QtQml.QJSValue, None]">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ <inject-code class="target" file="../glue/qtqml.cpp"
+ snippet="qqmlengine-singletoninstance-qmltypeid"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qqmlengine-singletoninstance-qmltypeid"/>
+ </add-function>
+ <add-function signature="singletonInstance(QString@uri@,QString@typeName@)"
+ return-type="QObject*">
+ <!-- Suppress return value heuristics -->
+ <modify-argument index="return"
+ pyi-type="Union[PySide6.QtCore.QObject, PySide6.QtQml.QJSValue, None]">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ <inject-code class="target" file="../glue/qtqml.cpp"
+ snippet="qqmlengine-singletoninstance-typename"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtqml_functions.rst"
+ snippet="qqmlengine-singletoninstance-typename"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QQmlExpression">
+ <modify-function signature="evaluate(bool*)" allow-thread="yes">
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[Any, bool]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+ <interface-type name="QQmlTypesExtensionInterface"/>
+ <interface-type name="QQmlExtensionInterface"/>
+ <object-type name="QQmlExtensionPlugin"/>
+ <!-- Possible qRegisterMetaType issues ? -->
+ <object-type name="QQmlFile">
+ <enum-type name="Status"/>
+ </object-type>
+ <object-type name="QQmlFileSelector"/>
+ <object-type name="QQmlImageProviderBase">
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="ImageType"/>
+ </object-type>
+ <object-type name="QQmlIncubator">
+ <enum-type name="IncubationMode"/>
+ <enum-type name="Status"/>
+ </object-type>
+ <object-type name="QQmlIncubationController">
+ <extra-includes>
+ <include file-name="pysideqmlvolatilebool.h" location="local"/>
+ </extra-includes>
+ <modify-function signature="incubateWhile(std::atomic&lt;bool&gt;*,int)" allow-thread="yes">
+ <modify-argument index="1">
+ The replace type is needed to use the VolatileBool_Check macro instead of
+ a template conversion function with "volatile bool" as argument.
+ <replace-type modified-type="VolatileBool"/>
+ <conversion-rule class="native">
+ auto volatileBool = reinterpret_cast&lt;QtQml_VolatileBoolObject *&gt;(%PYARG_1);
+ std::atomic&lt;bool&gt; *%out = volatileBool->flag;
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <!-- TODO: QQmlListProperty is a template class, and thus should probably be treated like a
+ container-type tag, which implies custom code for conversion. Not sure there's a use case to
+ allow instantiating or deriving from the class though, given that a separate custom ListProperty
+ type is provided by the module. Plus meta type registration would have to be taken into account
+ for the QML parts.
+ <value-type name="QQmlListProperty"/>-->
+ <value-type name="QQmlListReference"/>
+ <object-type name="QQmlParserStatus"/>
+ <object-type name="QPyQmlParserStatus"/>
+ <value-type name="QQmlProperty">
+ <enum-type name="PropertyTypeCategory"/>
+ <enum-type name="Type"/>
+ </value-type>
+ <object-type name="QQmlPropertyMap"/>
+ <object-type name="QQmlPropertyValueSource"/>
+ <object-type name="QPyQmlPropertyValueSource"/>
+ <value-type name="QQmlScriptString">
+ <modify-function signature="numberLiteral(bool*)const" allow-thread="yes">
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[float, bool]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="booleanLiteral(bool*)const" allow-thread="yes">
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, bool]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_bool*"/>
+ </inject-code>
+ </modify-function>
+ </value-type>
+ <object-type name="QQmlNetworkAccessManagerFactory">
+ <modify-function signature="create(QObject*)">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <!-- Suppress anonymous enum warning -->
+ <suppress-warning text="Anonymous enum (QmlCurrentSingletonTypeRegistrationVersion) does not have a type entry"/>
+ <suppress-warning text="Enum 'QQmlModuleImportSpecialVersions' does not have a type entry"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtQuick/CMakeLists.txt b/sources/pyside6/PySide6/QtQuick/CMakeLists.txt
new file mode 100644
index 000000000..775230242
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick/CMakeLists.txt
@@ -0,0 +1,119 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtQuick)
+
+set(QtQuick_DROPPED_ENTRIES)
+
+set(QtQuick_registerType "${QtQuick_SOURCE_DIR}/pysidequickregistertype.cpp")
+
+# Exclude sources that have clashing static helper functions named "renderstate_..."
+set(QtQuick_SRC_UNITY_EXCLUDED_SRC
+ ${QtQuick_GEN_DIR}/qsgrendernode_renderstate_wrapper.cpp
+ ${QtQuick_GEN_DIR}/qsgmaterialshader_renderstate_wrapper.cpp
+)
+
+set_property(SOURCE ${QtQuick_SRC_UNITY_EXCLUDED_SRC}
+ PROPERTY SKIP_UNITY_BUILD_INCLUSION ON)
+
+set(QtQuick_SRC
+${QtQuick_SRC_UNITY_EXCLUDED_SRC}
+${QtQuick_GEN_DIR}/qquickasyncimageprovider_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickgraphicsconfiguration_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickgraphicsdevice_wrapper.cpp
+${QtQuick_GEN_DIR}/qquicktexturefactory_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickimageprovider_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickimageresponse_wrapper.cpp
+${QtQuick_GEN_DIR}/qquicktransform_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickitem_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickitem_updatepaintnodedata_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickitemgrabresult_wrapper.cpp
+${QtQuick_GEN_DIR}/qsharedpointer_qquickitemgrabresult_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickpainteditem_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickrendercontrol_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickrendertarget_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickrhiitemrenderer_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickrhiitem_wrapper.cpp
+${QtQuick_GEN_DIR}/qquicktextdocument_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickview_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickwindow_wrapper.cpp
+${QtQuick_GEN_DIR}/qquickwindow_graphicsstateinfo_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgbasicgeometrynode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgclipnode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgdynamictexture_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgflatcolormaterial_wrapper.cpp
+${QtQuick_GEN_DIR}/qsggeometry_attribute_wrapper.cpp
+${QtQuick_GEN_DIR}/qsggeometry_attributeset_wrapper.cpp
+${QtQuick_GEN_DIR}/qsggeometry_coloredpoint2d_wrapper.cpp
+${QtQuick_GEN_DIR}/qsggeometry_point2d_wrapper.cpp
+${QtQuick_GEN_DIR}/qsggeometry_texturedpoint2d_wrapper.cpp
+${QtQuick_GEN_DIR}/qsggeometry_wrapper.cpp
+${QtQuick_GEN_DIR}/qsggeometrynode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgimagenode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgmaterial_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgmaterialshader_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgmaterialshader_graphicspipelinestate_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgmaterialtype_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgninepatchnode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgnode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgnodevisitor_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgopacitynode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgopaquetexturematerial_wrapper.cpp
+#${QtQuick_GEN_DIR}/qsgsimplematerial_wrapper.cpp
+#${QtQuick_GEN_DIR}/qsgsimplematerialshader_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgrectanglenode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgrendernode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgrootnode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgsimplerectnode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgsimpletexturenode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgrendererinterface_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgtextnode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgtexture_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgtexturematerial_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgtextureprovider_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgtransformnode_wrapper.cpp
+${QtQuick_GEN_DIR}/qsgvertexcolormaterial_wrapper.cpp
+# module is always needed
+${QtQuick_GEN_DIR}/qtquick_module_wrapper.cpp
+)
+
+set(QtQuick_include_dirs ${QtQuick_SOURCE_DIR}
+ ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuick_GEN_DIR})
+
+set(QtQuick_libraries pyside6 pyside6qml
+ ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES})
+
+set(QtQuick_deps QtGui QtNetwork QtQml)
+
+check_qt_opengl("Quick" QtQuick_include_dirs QtQuick_deps
+ QtQuick_DROPPED_ENTRIES)
+
+if (Qt${QT_MAJOR_VERSION}OpenGL_FOUND)
+ list(APPEND QtQuick_SRC
+ ${QtQuick_GEN_DIR}/qquickframebufferobject_wrapper.cpp
+ ${QtQuick_GEN_DIR}/qquickframebufferobject_renderer_wrapper.cpp)
+else()
+ list(APPEND QtQuick_DROPPED_ENTRIES QQuickFramebufferObject)
+endif()
+
+create_pyside_module(NAME QtQuick
+ INCLUDE_DIRS QtQuick_include_dirs
+ LIBRARIES QtQuick_libraries
+ DEPS QtQuick_deps
+ TYPESYSTEM_PATH QtQuick_SOURCE_DIR
+ SOURCES QtQuick_SRC
+ STATIC_SOURCES QtQuick_registerType
+ DROPPED_ENTRIES QtQuick_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp b/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp
new file mode 100644
index 000000000..f7749b4e7
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.cpp
@@ -0,0 +1,76 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysidequickregistertype.h"
+
+#include <pyside.h>
+#include <pysideqmlregistertype.h>
+#include <pyside_p.h>
+#include <shiboken.h>
+
+#include <QtQuick/QQuickPaintedItem>
+
+#if QT_CONFIG(opengl) || QT_CONFIG(opengles2) || QT_CONFIG(opengles3)
+# include <QtQuick/QQuickFramebufferObject>
+#endif
+
+bool pyTypeObjectInheritsFromClass(PyTypeObject *pyObjType, const char *classPtrName)
+{
+ PyTypeObject *classPyType = Shiboken::Conversions::getPythonTypeObject(classPtrName);
+ bool isDerived = PySequence_Contains(pyObjType->tp_mro,
+ reinterpret_cast<PyObject *>(classPyType));
+ return isDerived;
+}
+
+template <class WrappedClass>
+bool registerTypeIfInheritsFromClass(const char *classPtrName,
+ PyTypeObject *typeToRegister,
+ QQmlPrivate::RegisterTypeAndRevisions *type)
+{
+ if (!pyTypeObjectInheritsFromClass(typeToRegister, classPtrName))
+ return false;
+ type->parserStatusCast =
+ QQmlPrivate::StaticCastSelector<WrappedClass, QQmlParserStatus>::cast();
+ type->valueSourceCast =
+ QQmlPrivate::StaticCastSelector<WrappedClass, QQmlPropertyValueSource>::cast();
+ type->valueInterceptorCast =
+ QQmlPrivate::StaticCastSelector<WrappedClass, QQmlPropertyValueInterceptor>::cast();
+ return true;
+}
+
+bool quickRegisterType(PyObject *pyObj, QQmlPrivate::RegisterTypeAndRevisions *type)
+{
+ using namespace Shiboken;
+
+ PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj);
+ PyTypeObject *qQuickItemPyType =
+ Shiboken::Conversions::getPythonTypeObject("QQuickItem*");
+ bool isQuickItem = PySequence_Contains(pyObjType->tp_mro,
+ reinterpret_cast<PyObject *>(qQuickItemPyType));
+
+ // Register only classes that inherit QQuickItem or its children.
+ if (!isQuickItem)
+ return false;
+
+ return registerTypeIfInheritsFromClass<QQuickPaintedItem>("QQuickPaintedItem*",
+ pyObjType, type)
+#if QT_CONFIG(opengl) || QT_CONFIG(opengles2) || QT_CONFIG(opengles3)
+ || registerTypeIfInheritsFromClass<QQuickFramebufferObject>("QQuickFramebufferObject*",
+ pyObjType, type)
+#endif
+ || registerTypeIfInheritsFromClass<QQuickItem>("QQuickItem*",
+ pyObjType, type);
+}
+
+void PySide::initQuickSupport(PyObject *module)
+{
+ Q_UNUSED(module);
+ // We need to manually register a pointer version of these types in order for them to be used as property types.
+ qRegisterMetaType<QQuickPaintedItem*>("QQuickPaintedItem*");
+#if QT_CONFIG(opengl) || QT_CONFIG(opengles2) || QT_CONFIG(opengles3)
+ qRegisterMetaType<QQuickFramebufferObject*>("QQuickFramebufferObject*");
+#endif
+ qRegisterMetaType<QQuickItem*>("QQuickItem*");
+
+ Qml::setQuickRegisterItemFunction(quickRegisterType);
+}
diff --git a/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.h b/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.h
new file mode 100644
index 000000000..89e0ced67
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick/pysidequickregistertype.h
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_QUICK_REGISTER_TYPE_H
+#define PYSIDE_QUICK_REGISTER_TYPE_H
+
+#include <sbkpython.h>
+
+namespace PySide
+{
+void initQuickSupport(PyObject *module);
+}
+
+#endif // PYSIDE_QUICK_REGISTER_TYPE_H
diff --git a/sources/pyside6/PySide6/QtQuick/typesystem_quick.xml b/sources/pyside6/PySide6/QtQuick/typesystem_quick.xml
new file mode 100644
index 000000000..61aed6005
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick/typesystem_quick.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtQuick"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <!-- QQuickFramebufferObject::Renderer needs QOpenGLFramebufferObject -->
+ <?if !no_QtOpenGL?>
+ <load-typesystem name="QtOpenGL/typesystem_opengl.xml" generate="no"/>
+ <?endif?>
+ <load-typesystem name="QtQml/typesystem_qml.xml" generate="no"/>
+
+ <smart-pointer-type name="QSharedPointer" type="shared" getter="data"
+ reset-method="reset"/>
+
+ <extra-includes>
+ <include file-name="pysidequickregistertype.h" location="local"/>
+ </extra-includes>
+
+ <inject-code class="target" position="end" file="../glue/qtquick.cpp" snippet="qtquick"/>
+
+ <object-type name="QQuickAsyncImageProvider">
+ <modify-function signature="requestImageResponse(const QString&amp;,const QSize&amp;)">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QQuickFramebufferObject">
+ <object-type name="Renderer"/>
+ <modify-function signature="createRenderer()const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <value-type name="QQuickGraphicsConfiguration"/>
+ <value-type name="QQuickGraphicsDevice">
+ <!-- PYSIDE-1726, after qtbase/696d94b132b2f352b5e6b889ad91c2437417fae8,
+ the functions are defined with dummy types when Vulkan is not present. -->
+ <modify-function signature="^fromPhysicalDevice\(.*$" remove="all"/>
+ <modify-function signature="^fromDeviceObjects\(.*$" remove="all"/>
+ </value-type>
+
+ <object-type name="QQuickTextureFactory"/>
+ <object-type name="QQuickImageProvider"/>
+ <object-type name="QQuickImageResponse"/>
+
+ <object-type name="QQuickTransform"/>
+ <object-type name="QQuickItem" delete-in-main-thread="true" polymorphic-base="true">
+ <value-type name="UpdatePaintNodeData"/>
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="ItemChange"/>
+ <enum-type name="TransformOrigin"/>
+ <modify-function signature="itemTransform(QQuickItem*,bool*)const" allow-thread="yes">
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, PySide6.QtGui.QTransform]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="updatePaintNode(QSGNode*,QQuickItem::UpdatePaintNodeData*)">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- TODO: Find a way to wrap `union ItemChangeData {}` -->
+ </object-type>
+
+ <object-type name="QQuickRhiItemRenderer" since="6.7"/>
+ <object-type name="QQuickRhiItem" since="6.7">
+ <enum-type name="TextureFormat"/>
+ </object-type>
+
+ <object-type name="QQuickItemGrabResult"/>
+
+ <object-type name="QQuickPaintedItem">
+ <enum-type name="RenderTarget"/>
+ <enum-type name="PerformanceHint" flags="PerformanceHints"/>
+ </object-type>
+
+ <object-type name="QQuickRenderControl"/>
+ <value-type name="QQuickRenderTarget">
+ <!-- PYSIDE-1726, after qtbase/696d94b132b2f352b5e6b889ad91c2437417fae8,
+ the function is defined with dummy types when Vulkan is not present. -->
+ <modify-function signature="^fromVulkanImage\(.*$" remove="all"/>
+ </value-type>
+
+ <object-type name="QQuickTextDocument">
+ <enum-type name="Status" since="6.7"/>
+ </object-type>
+
+ <object-type name="QQuickView">
+ <enum-type name="ResizeMode"/>
+ <enum-type name="Status"/>
+ </object-type>
+
+ <object-type name="QQuickWindow">
+ <enum-type name="CreateTextureOption" flags="CreateTextureOptions"/>
+ <enum-type name="RenderStage"/>
+ <enum-type name="SceneGraphError"/>
+ <enum-type name="TextRenderType"/>
+ <value-type name="GraphicsStateInfo"/>
+ </object-type>
+
+ <object-type name="QSGBasicGeometryNode">
+ <modify-function signature="setGeometry(QSGGeometry*)">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QSGClipNode"/>
+ <object-type name="QSGDynamicTexture"/>
+ <object-type name="QSGFlatColorMaterial"/>
+ <object-type name="QSGGeometry">
+ <extra-includes>
+ <include file-name="algorithm" location="global"/>
+ </extra-includes>
+ <enum-type name="DataPattern"/>
+ <enum-type name="AttributeType"/>
+ <enum-type name="DrawingMode" python-type="IntEnum"/>
+ <enum-type name="Type"/>
+ <value-type name="Attribute"/>
+ <value-type name="AttributeSet"/>
+ <value-type name="ColoredPoint2D"/>
+ <value-type name="Point2D"/>
+ <value-type name="TexturedPoint2D"/>
+ <modify-function signature="vertexDataAsPoint2D()">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <inject-code class="target" file="../glue/qtquick.cpp" snippet="qsgeometry-vertexdataaspoint2d"/>
+ </modify-function>
+ <add-function signature="setVertexDataAsPoint2D(const QList&lt;QSGGeometry::Point2D&gt;&amp;@points@)">
+ <inject-code class="target" file="../glue/qtquick.cpp" snippet="qsgeometry-setvertexdataaspoint2d"/>
+ <inject-documentation format="target" mode="append">
+ Sets the vertex data from a list of QSGGeometry.Point2D.
+ The list size must match the allocated number of vertexes
+ as returned by QSGGeometry.vertexCount().
+ </inject-documentation>
+ </add-function>
+
+ </object-type>
+ <object-type name="QSGGeometryNode">
+ <modify-function signature="setMaterial(QSGMaterial*)">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setOpaqueMaterial(QSGMaterial*)">
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QSGImageNode">
+ <enum-type name="TextureCoordinatesTransformFlag" flags="TextureCoordinatesTransformMode"/>
+ </object-type>
+
+ <object-type name="QSGMaterial">
+ <enum-type name="Flag" flags="Flags"/>
+ </object-type>
+ <object-type name="QSGMaterialShader">
+ <enum-type name="Stage"/>
+ <enum-type name="Flag" flags="Flags"/>
+ <value-type name="RenderState">
+ <enum-type name="DirtyState" flags="DirtyStates"/>
+ </value-type>
+ <value-type name="GraphicsPipelineState">
+ <enum-type name="BlendFactor"/>
+ <enum-type name="ColorMaskComponent" flags="ColorMask"/>
+ <enum-type name="CullMode"/>
+ <enum-type name="PolygonMode"/>
+ </value-type>
+ <modify-function signature="updateSampledImage(QSGMaterialShader::RenderState&amp;,int,QSGTexture**,QSGMaterial*,QSGMaterial*)" remove="all"/>
+ <!-- Private QRhi class -->
+ <modify-function signature="setShader(QSGMaterialShader::Stage,QShader)" remove="all"/>
+ </object-type>
+ <object-type name="QSGMaterialType"/>
+ <object-type name="QSGNinePatchNode"/>
+ <object-type name="QSGNode">
+ <enum-type name="DirtyStateBit" flags="DirtyState"/>
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="NodeType"/>
+ </object-type>
+ <object-type name="QSGNodeVisitor"/>
+
+ <object-type name="QSGOpacityNode"/>
+ <object-type name="QSGOpaqueTextureMaterial"/>
+ <object-type name="QSGSimpleRectNode"/>
+ <object-type name="QSGSimpleTextureNode">
+ <enum-type name="TextureCoordinatesTransformFlag" flags="TextureCoordinatesTransformMode"/>
+ </object-type>
+ <object-type name="QSGTextNode" since="6.7">
+ <enum-type name="TextStyle"/>
+ <enum-type name="RenderType"/>
+ </object-type>
+ <object-type name="QSGRectangleNode"/>
+ <object-type name="QSGRendererInterface">
+ <enum-type name="GraphicsApi"/>
+ <enum-type name="Resource"/>
+ <enum-type name="ShaderType"/>
+ <enum-type name="ShaderCompilationType" flags="ShaderCompilationTypes"/>
+ <enum-type name="ShaderSourceType" flags="ShaderSourceTypes"/>
+ <enum-type name="RenderMode"/>
+ </object-type>
+ <object-type name="QSGRenderNode">
+ <enum-type name="StateFlag" flags="StateFlags"/>
+ <enum-type name="RenderingFlag" flags="RenderingFlags"/>
+ <object-type name="RenderState"/>
+ </object-type>
+ <object-type name="QSGRootNode"/>
+ <object-type name="QSGTexture">
+ <enum-type name="AnisotropyLevel"/>
+ <enum-type name="Filtering"/>
+ <enum-type name="WrapMode"/>
+ </object-type>
+ <object-type name="QSGTextureMaterial"/>
+ <object-type name="QSGTextureProvider"/>
+ <object-type name="QSGTransformNode"/>
+ <object-type name="QSGVertexColorMaterial"/>
+
+ <!-- These currently don't work because they are template classes, and the generator chokes on
+ them. Making these work properly would require fixing the parsing of template classes,
+ allowing creation of State structures and passing them to the template classes, as well as
+ implementing some mechanism of registration of the custom template classes, kind of how
+ it's done for qt quick items.
+ <object-type name="QSGSimpleMaterial"/>
+ <object-type name="QSGSimpleMaterialShader"/>
+ -->
+
+ <suppress-warning text="^signature.*fromVulkanImage.*not found.*$"/>
+ <suppress-warning text="^signature.*fromPhysicalDevice.*not found.*$"/>
+ <suppress-warning text="^signature.*fromDeviceObjects.*not found.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt b/sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt
new file mode 100644
index 000000000..37f8ebfb1
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick3D/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtQuick3D)
+
+set (QtQuick3D_DROPPED_ENTRIES)
+
+set(QtQuick3D_SRC
+${QtQuick3D_GEN_DIR}/qquick3d_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dobject_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dgeometry_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dgeometry_attribute_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dgeometry_targetattribute_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dinstancing_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dinstancing_instancetableentry_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3drenderextension_wrapper.cpp
+${QtQuick3D_GEN_DIR}/qquick3dtexturedata_wrapper.cpp
+# module is always needed
+${QtQuick3D_GEN_DIR}/qtquick3d_module_wrapper.cpp
+)
+
+set(QtQuick3D_include_dirs ${QtQuick3D_SOURCE_DIR}
+ ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Core_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_PRIVATE_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick3D_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuick_GEN_DIR}
+ ${QtQuick3D_GEN_DIR})
+
+set(QtQuick3D_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Quick3D_LIBRARIES})
+
+set(QtQuick3D_deps QtGui QtNetwork QtQml QtQuick)
+
+check_qt_opengl("Quick3D" QtQuick3D_include_dirs QtQuick3D_deps
+ QtQuick3D_DROPPED_ENTRIES)
+
+create_pyside_module(NAME QtQuick3D
+ INCLUDE_DIRS QtQuick3D_include_dirs
+ LIBRARIES QtQuick3D_libraries
+ DEPS QtQuick3D_deps
+ TYPESYSTEM_PATH QtQuick3D_SOURCE_DIR
+ SOURCES QtQuick3D_SRC
+ DROPPED_ENTRIES QtQuick3D_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml b/sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml
new file mode 100644
index 000000000..fe8f4e700
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuick3D/typesystem_quick3d.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtQuick3D"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtQuick/typesystem_quick.xml" generate="no"/>
+
+ <object-type name="QQuick3D"/>
+ <object-type name="QQuick3DObject">
+ <enum-type name="ItemChange"/>
+ <modify-function signature="QQuick3DObject(QQuick3DObject*)" remove="all"/>
+ </object-type>
+ <object-type name="QQuick3DGeometry">
+ <value-type name="Attribute">
+ <enum-type name="Semantic"/>
+ <enum-type name="ComponentType"/>
+ </value-type>
+ <value-type name="TargetAttribute" since="6.6"/>
+ <enum-type name="PrimitiveType"/>
+ </object-type>
+ <object-type name="QQuick3DInstancing">
+ <value-type name="InstanceTableEntry"/>
+ </object-type>
+ <object-type name="QQuick3DTextureData">
+ <enum-type name="Format"/>
+ </object-type>
+ <object-type name="QQuick3DRenderExtension" since="6.7"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtQuickControls2/CMakeLists.txt b/sources/pyside6/PySide6/QtQuickControls2/CMakeLists.txt
new file mode 100644
index 000000000..9951d2e1e
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuickControls2/CMakeLists.txt
@@ -0,0 +1,46 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtQuickControls2)
+
+set (QtQuickControls2_DROPPED_ENTRIES)
+
+set(QtQuickControls2_SRC
+${QtQuickControls2_GEN_DIR}/qquickstyle_wrapper.cpp
+${QtQuickControls2_GEN_DIR}/qquickattachedpropertypropagator_wrapper.cpp
+# module is always needed
+${QtQuickControls2_GEN_DIR}/qtquickcontrols2_module_wrapper.cpp
+)
+
+
+set(QtQuickControls2_include_dirs ${QtQuickControls2_SOURCE_DIR}
+ ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}QuickControls2_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuick_GEN_DIR}
+ ${QtQuickControls2_GEN_DIR})
+
+set(QtQuickControls2_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}QuickControls2_LIBRARIES})
+
+set(QtQuickControls2_deps QtGui QtNetwork QtQml QtQuick)
+
+check_qt_opengl("QuickControls2" QtQuickControls2_include_dirs QtQuickControls2_deps
+ QtQuickControls2_DROPPED_ENTRIES)
+
+create_pyside_module(NAME QtQuickControls2
+ INCLUDE_DIRS QtQuickControls2_include_dirs
+ LIBRARIES QtQuickControls2_libraries
+ DEPS QtQuickControls2_deps
+ TYPESYSTEM_PATH QtQuickControls2_SOURCE_DIR
+ SOURCES QtQuickControls2_SRC
+ DROPPED_ENTRIES QtQuickControls2_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtQuickControls2/typesystem_quickcontrols2.xml b/sources/pyside6/PySide6/QtQuickControls2/typesystem_quickcontrols2.xml
new file mode 100644
index 000000000..72fc05226
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuickControls2/typesystem_quickcontrols2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtQuickControls2"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtQuick/typesystem_quick.xml" generate="no"/>
+
+ <object-type name="QQuickStyle"/>
+ <object-type name="QQuickAttachedPropertyPropagator"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtQuickTest/CMakeLists.txt b/sources/pyside6/PySide6/QtQuickTest/CMakeLists.txt
new file mode 100644
index 000000000..8e3fb4d57
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuickTest/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtQuickTest)
+
+set (QtQuickTest_DROPPED_ENTRIES)
+
+set(QtQuickTest_SRC
+# module is always needed
+${QtQuickTest_GEN_DIR}/qtquicktest_module_wrapper.cpp
+)
+
+set(QtQuickTest_include_dirs ${QtQuickTest_SOURCE_DIR}
+ ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtOpenGL_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuick_GEN_DIR}
+ ${QtQuickTest_GEN_DIR})
+
+set(QtQuickTest_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}QuickTest_LIBRARIES})
+
+set(QtQuickTest_deps QtGui QtNetwork QtQml QtQuick)
+
+check_qt_opengl("QuickTest" QtQuickTest_include_dirs QtQuickTest_deps
+ QtQuickTest_DROPPED_ENTRIES)
+
+create_pyside_module(NAME QtQuickTest
+ INCLUDE_DIRS QtQuickTest_include_dirs
+ LIBRARIES QtQuickTest_libraries
+ DEPS QtQuickTest_deps
+ TYPESYSTEM_PATH QtQuickTest_SOURCE_DIR
+ SOURCES QtQuickTest_SRC
+ DROPPED_ENTRIES QtQuickTest_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtQuickTest/typesystem_quicktest.xml b/sources/pyside6/PySide6/QtQuickTest/typesystem_quicktest.xml
new file mode 100644
index 000000000..b6ef754e7
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuickTest/typesystem_quicktest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtQuickTest"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+
+ <extra-includes>
+ <include file-name="QtQuickTest/quicktest.h" location="global"/>
+ <include file-name="QtCore/QDir" location="global"/>
+ <include file-name="pysideqobject.h" location="global"/>
+ <include file-name="vector" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning"
+ file="../glue/qtquicktest.cpp" snippet="call-quick-test-main"/>
+
+ <add-function signature="QUICK_TEST_MAIN(QString@name@,QStringList@argv@={},QString@dir@={})"
+ return-type="int">
+ <inject-code file="../glue/qtquicktest.cpp" snippet="quick-test-main"/>
+ <inject-documentation format="target" mode="append"
+ file="../doc/qtquicktest.rst"
+ snippet="quick_test_main_documentation"/>
+ </add-function>
+ <add-function signature="QUICK_TEST_MAIN_WITH_SETUP(QString@name@,PyTypeObject*@setup@,QStringList@argv@={},QString@dir@={})"
+ return-type="int">
+ <inject-code file="../glue/qtquicktest.cpp" snippet="quick-test-main_with_setup"/>
+ <inject-documentation format="target" mode="append"
+ file="../doc/qtquicktest.rst"
+ snippet="quick_test_main_with_setup_documentation"/>
+ </add-function>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtQuickWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtQuickWidgets/CMakeLists.txt
new file mode 100644
index 000000000..883010bee
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuickWidgets/CMakeLists.txt
@@ -0,0 +1,48 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtQuickWidgets)
+
+set (QtQuickWidgets_DROPPED_ENTRIES)
+
+set(QtQuickWidgets_SRC
+${QtQuickWidgets_GEN_DIR}/qquickwidget_wrapper.cpp
+# module is always needed
+${QtQuickWidgets_GEN_DIR}/qtquickwidgets_module_wrapper.cpp
+)
+
+set(QtQuickWidgets_include_dirs ${QtQuickWidgets_SOURCE_DIR}
+ ${QtQml_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}QuickWidgets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtOpenGL_GEN_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtQuick_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtQuickWidgets_GEN_DIR})
+
+set(QtQuickWidgets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}QuickWidgets_LIBRARIES})
+
+set(QtQuickWidgets_deps QtGui QtQml QtQuick QtWidgets QtNetwork)
+
+check_qt_opengl("QuickWidgets" QtQuickWidgets_include_dirs QtQuickWidgets_deps
+ QtQuickWidgets_DROPPED_ENTRIES)
+
+create_pyside_module(NAME QtQuickWidgets
+ INCLUDE_DIRS QtQuickWidgets_include_dirs
+ LIBRARIES QtQuickWidgets_libraries
+ DEPS QtQuickWidgets_deps
+ TYPESYSTEM_PATH QtQuickWidgets_SOURCE_DIR
+ SOURCES QtQuickWidgets_SRC
+ DROPPED_ENTRIES QtQuickWidgets_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtQuickWidgets/typesystem_quickwidgets.xml b/sources/pyside6/PySide6/QtQuickWidgets/typesystem_quickwidgets.xml
new file mode 100644
index 000000000..4f4484cb0
--- /dev/null
+++ b/sources/pyside6/PySide6/QtQuickWidgets/typesystem_quickwidgets.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtQuickWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtQuick/typesystem_quick.xml" generate="no"/>
+ <load-typesystem name="QtQml/typesystem_qml.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+
+ <object-type name="QQuickWidget">
+ <enum-type name="ResizeMode"/>
+ <enum-type name="Status"/>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtRemoteObjects/CMakeLists.txt b/sources/pyside6/PySide6/QtRemoteObjects/CMakeLists.txt
new file mode 100644
index 000000000..07835b2f6
--- /dev/null
+++ b/sources/pyside6/PySide6/QtRemoteObjects/CMakeLists.txt
@@ -0,0 +1,53 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtRemoteObjects)
+
+set(QtRemoteObjects_SRC
+${QtRemoteObjects_GEN_DIR}/qabstractitemmodelreplica_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qconnectionabstractserver_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectabstractpersistedstore_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectdynamicreplica_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjecthost_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjecthostbase_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectnode_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectpendingcall_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectpendingcallwatcher_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectregistry_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectregistryhost_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectreplica_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qtremoteobjects_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectsettingsstore_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qremoteobjectsourcelocationinfo_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qtroclientfactory_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qtroclientiodevice_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qtroiodevicebase_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qtroserverfactory_wrapper.cpp
+${QtRemoteObjects_GEN_DIR}/qtroserveriodevice_wrapper.cpp
+
+# module is always needed
+${QtRemoteObjects_GEN_DIR}/qtremoteobjects_module_wrapper.cpp
+)
+
+set(QtRemoteObjects_include_dirs ${QtRemoteObjects_SOURCE_DIR}
+ ${QtRemoteObjects_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}RemoteObjects_INCLUDE_DIRS}
+ ${SHIBOKEN_INCLUDE_DIR}
+ ${libpyside_SOURCE_DIR}
+ ${SHIBOKEN_PYTHON_INCLUDE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR})
+
+set(QtRemoteObjects_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}RemoteObjects_LIBRARIES})
+
+set(QtRemoteObjects_deps QtCore QtNetwork)
+
+create_pyside_module(NAME QtRemoteObjects
+ INCLUDE_DIRS QtRemoteObjects_include_dirs
+ LIBRARIES QtRemoteObjects_libraries
+ DEPS QtRemoteObjects_deps
+ TYPESYSTEM_PATH QtRemoteObjects_SOURCE_DIR
+ SOURCES QtRemoteObjects_SRC
+ TYPESYSTEM_NAME ${QtRemoteObjects_BINARY_DIR}/typesystem_remoteobjects.xml
+ )
diff --git a/sources/pyside6/PySide6/QtRemoteObjects/typesystem_remoteobjects.xml b/sources/pyside6/PySide6/QtRemoteObjects/typesystem_remoteobjects.xml
new file mode 100644
index 000000000..86e4d9093
--- /dev/null
+++ b/sources/pyside6/PySide6/QtRemoteObjects/typesystem_remoteobjects.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtRemoteObjects"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="templates/core_common.xml" generate="no"/>
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+
+ <rejection class="QRemoteObjectStringLiterals"/>
+ <rejection class="*" function-name="getTypeNameAndMetaobjectFromClassInfo"/>
+ <rejection class="QtRemoteObjects" field-name="staticMetaObject"/>
+ <namespace-type name="QtRemoteObjects">
+ <enum-type name="InitialAction"/>
+ <enum-type name="QRemoteObjectPacketTypeEnum"/>
+ </namespace-type>
+ <object-type name="QAbstractItemModelReplica"/>
+ <object-type name="QConnectionAbstractServer"/>
+ <object-type name="QRemoteObjectAbstractPersistedStore"/>
+ <object-type name="QRemoteObjectDynamicReplica"/>
+ <object-type name="QRemoteObjectHost"/>
+ <object-type name="QRemoteObjectHostBase">
+ <enum-type name="AllowedSchemas"/>
+ </object-type>
+ <object-type name="QRemoteObjectNode">
+ <enum-type name="ErrorCode"/>
+ </object-type>
+ <object-type name="QRemoteObjectPendingCall">
+ <enum-type name="Error"/>
+ </object-type>
+ <object-type name="QRemoteObjectPendingCallWatcher"/>
+ <object-type name="QRemoteObjectRegistry"/>
+ <object-type name="QRemoteObjectRegistryHost"/>
+ <object-type name="QRemoteObjectReplica">
+ <enum-type name="State"/>
+ <!-- protected: <enum-type name="ConstructorType"/> -->
+ </object-type>
+ <object-type name="QRemoteObjectSettingsStore"/>
+ <value-type name="QRemoteObjectSourceLocationInfo"/>
+ <object-type name="QtROClientFactory"/>
+ <object-type name="QtROClientIoDevice"/>
+ <object-type name="QtROIoDeviceBase"/>
+ <object-type name="QtROServerFactory"/>
+ <object-type name="QtROServerIoDevice"/>
+
+ <suppress-warning text="^.*Typedef used on signal QRemoteObject.*$"/>
+ <suppress-warning text="^QRemoteObjectPendingCallWatcher inherits from a non polymorphic type.*$"/>
+ <suppress-warning text="^Enum 'QRemoteObjectReplica::ConstructorType'.*does not have a type entry.*$"/>
+ <suppress-warning text="Stripping argument #1 of void QRemoteObjectReplica::QRemoteObjectReplica(QRemoteObjectReplica::ConstructorType) due to unmatched type &quot;QRemoteObjectReplica::ConstructorType&quot; with default expression &quot;DefaultConstructor&quot;."/>
+ <suppress-warning text="skipping protected field 'QRemoteObjectReplica::d_impl' with unmatched type 'QSharedPointer'"/>
+ <!-- QtNetwork is pulled in via QtRemoteObjectsDepends. -->
+ <suppress-warning text="^Scoped enum 'Q(Ocsp)|(Dtls).*' does not have a type entry.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtScxml/CMakeLists.txt b/sources/pyside6/PySide6/QtScxml/CMakeLists.txt
new file mode 100644
index 000000000..1b0eab0ce
--- /dev/null
+++ b/sources/pyside6/PySide6/QtScxml/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtScxml)
+
+set(QtScxml_OPTIONAL_SRC )
+set(QtScxml_DROPPED_ENTRIES )
+
+set(QtScxml_SRC
+${QtScxml_GEN_DIR}/qscxmlcompiler_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlcompiler_loader_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlcppdatamodel_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmldatamodel_foreachloopbody_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmldatamodel_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlevent_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmldynamicscxmlservicefactory_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlinvokableservice_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlinvokableservicefactory_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlnulldatamodel_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlstaticscxmlservicefactory_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlstatemachine_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmltabledata_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlerror_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlexecutablecontent_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlexecutablecontent_assignmentinfo_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlexecutablecontent_evaluatorinfo_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlexecutablecontent_foreachinfo_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlexecutablecontent_invokeinfo_wrapper.cpp
+${QtScxml_GEN_DIR}/qscxmlexecutablecontent_parameterinfo_wrapper.cpp
+# module is always needed
+${QtScxml_GEN_DIR}/qtscxml_module_wrapper.cpp
+)
+
+set(QtScxml_include_dirs ${QtScxml_SOURCE_DIR}
+ ${QtScxml_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Scxml_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtScxml_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Scxml_LIBRARIES})
+
+set(QtScxml_deps QtCore)
+
+create_pyside_module(NAME QtScxml
+ INCLUDE_DIRS QtScxml_include_dirs
+ LIBRARIES QtScxml_libraries
+ DEPS QtScxml_deps
+ TYPESYSTEM_PATH QtScxml_SOURCE_DIR
+ SOURCES QtScxml_SRC
+ DROPPED_ENTRIES QtScxml_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtScxml/typesystem_scxml.xml b/sources/pyside6/PySide6/QtScxml/typesystem_scxml.xml
new file mode 100644
index 000000000..ba8820570
--- /dev/null
+++ b/sources/pyside6/PySide6/QtScxml/typesystem_scxml.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtScxml"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <object-type name="QScxmlCompiler">
+ <object-type name="Loader"/>
+ </object-type>
+ <object-type name="QScxmlCppDataModel"/>
+ <!-- PYSIDE-2340: Force value conversion for QScxmlStateMachine::connectToEvent()
+ which expects "func(const QScxmlEvent &)" -->
+ <value-type name="QScxmlEvent">
+ <enum-type name="EventType"/>
+ </value-type>
+ <object-type name="QScxmlDynamicScxmlServiceFactory"/>
+ <object-type name="QScxmlInvokableService"/>
+ <object-type name="QScxmlInvokableServiceFactory"/>
+ <object-type name="QScxmlStaticScxmlServiceFactory"/>
+ <object-type name="QScxmlStateMachine">
+ <modify-function signature="submitEvent(QScxmlEvent*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QScxmlTableData"/>
+ <object-type name="QScxmlDataModel">
+ <!-- Needs to have exports fixed -->
+ <interface-type name="ForeachLoopBody"/>
+ <modify-function signature="^evaluateTo(String|Bool|Variant)\(.*bool ?\*.*$">
+ <modify-argument index="2">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,arg,bool*"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+ <value-type name="QScxmlError"/>
+ <namespace-type name="QScxmlExecutableContent">
+ <value-type name="AssignmentInfo"/>
+ <value-type name="EvaluatorInfo"/>
+ <value-type name="ForeachInfo"/>
+ <value-type name="InvokeInfo"/>
+ <value-type name="ParameterInfo"/>
+ </namespace-type>
+ <object-type name="QScxmlNullDataModel"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtSensors/CMakeLists.txt b/sources/pyside6/PySide6/QtSensors/CMakeLists.txt
new file mode 100644
index 000000000..0152d2884
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSensors/CMakeLists.txt
@@ -0,0 +1,94 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtSensors)
+
+set(QtSensors_OPTIONAL_SRC )
+set(QtSensors_DROPPED_ENTRIES )
+
+set(QtSensors_SRC
+# overrides QObject::metaObject() by private method
+# ${QtSensors_GEN_DIR}/qsensorgesture_wrapper.cpp
+# ${QtSensors_GEN_DIR}/qsensorgesturemanager_wrapper.cpp
+# ${QtSensors_GEN_DIR}/qsensorgestureplugininterface_wrapper.cpp
+# ${QtSensors_GEN_DIR}/qsensorgesturerecognizer_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qaccelerometer_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qaccelerometerfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qaccelerometerreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qambientlightfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qambientlightreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qambientlightsensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qambienttemperaturefilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qambienttemperaturereading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qambienttemperaturesensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qcompass_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qcompassfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qcompassreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qgyroscope_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qgyroscopefilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qgyroscopereading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qhumidityfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qhumidityreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qhumiditysensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qirproximityfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qirproximityreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qirproximitysensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qlidfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qlidreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qlidsensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qlightfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qlightreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qlightsensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qmagnetometer_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qmagnetometerfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qmagnetometerreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qorientationfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qorientationreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qorientationsensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qpressurefilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qpressurereading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qpressuresensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qproximityfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qproximityreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qproximitysensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qrotationfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qrotationreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qrotationsensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensorfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensorreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qoutputrange_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensorbackend_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensorbackendfactory_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensormanager_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensorchangesinterface_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qsensorplugininterface_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qtapfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qtapreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qtapsensor_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qtiltfilter_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qtiltreading_wrapper.cpp
+ ${QtSensors_GEN_DIR}/qtiltsensor_wrapper.cpp
+# module is always needed
+ ${QtSensors_GEN_DIR}/qtsensors_module_wrapper.cpp
+)
+
+set(QtSensors_include_dirs ${QtSensors_SOURCE_DIR}
+ ${QtSensors_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Sensors_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtSensors_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Sensors_LIBRARIES})
+
+set(QtSensors_deps QtCore)
+
+create_pyside_module(NAME QtSensors
+ INCLUDE_DIRS QtSensors_include_dirs
+ LIBRARIES QtSensors_libraries
+ DEPS QtSensors_deps
+ TYPESYSTEM_PATH QtSensors_SOURCE_DIR
+ SOURCES QtSensors_SRC
+ DROPPED_ENTRIES QtSensors_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtSensors/typesystem_sensors.xml b/sources/pyside6/PySide6/QtSensors/typesystem_sensors.xml
new file mode 100644
index 000000000..4efd08277
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSensors/typesystem_sensors.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtSensors"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+<!-- overrides QObject::metaObject() by private method
+ <object-type name="QSensorGesture"/>
+-->
+<!-- Disabled by
+ 5991224e6713eef4a456c408fcf797662fa2a66c in qt/qtsensors :
+ https://codereview.qt-project.org/c/qt/qtsensors/+/364924
+ <object-type name="QSensorGestureManager"/>
+ <object-type name="QSensorGesturePluginInterface"/>
+ <object-type name="QSensorGestureRecognizer"/>
+-->
+ <object-type name="QAccelerometer">
+ <enum-type name="AccelerationMode"/>
+ </object-type>
+ <object-type name="QAccelerometerFilter"/>
+ <object-type name="QAccelerometerReading"/>
+ <object-type name="QAmbientLightFilter"/>
+ <object-type name="QAmbientLightReading">
+ <enum-type name="LightLevel"/>
+ </object-type>
+ <object-type name="QAmbientLightSensor"/>
+ <object-type name="QAmbientTemperatureFilter"/>
+ <object-type name="QAmbientTemperatureReading"/>
+ <object-type name="QAmbientTemperatureSensor"/>
+ <object-type name="QCompass"/>
+ <object-type name="QCompassFilter"/>
+ <object-type name="QCompassReading"/>
+ <object-type name="QGyroscope"/>
+ <object-type name="QGyroscopeFilter"/>
+ <object-type name="QGyroscopeReading"/>
+ <object-type name="QHumidityFilter"/>
+ <object-type name="QHumidityReading"/>
+ <object-type name="QHumiditySensor"/>
+ <object-type name="QIRProximityFilter"/>
+ <object-type name="QIRProximityReading"/>
+ <object-type name="QIRProximitySensor"/>
+ <object-type name="QLidFilter"/>
+ <object-type name="QLidReading"/>
+ <object-type name="QLidSensor"/>
+ <object-type name="QLightFilter"/>
+ <object-type name="QLightReading"/>
+ <object-type name="QLightSensor"/>
+ <object-type name="QMagnetometer"/>
+ <object-type name="QMagnetometerFilter"/>
+ <object-type name="QMagnetometerReading"/>
+ <object-type name="QOrientationFilter"/>
+ <object-type name="QOrientationReading">
+ <enum-type name="Orientation"/>
+ </object-type>
+ <object-type name="QOrientationSensor"/>
+ <object-type name="QPressureFilter"/>
+ <object-type name="QPressureReading"/>
+ <object-type name="QPressureSensor"/>
+ <object-type name="QProximityFilter"/>
+ <object-type name="QProximityReading"/>
+ <object-type name="QProximitySensor"/>
+ <object-type name="QRotationFilter"/>
+ <object-type name="QRotationReading"/>
+ <object-type name="QRotationSensor"/>
+ <object-type name="QSensor">
+ <enum-type name="Feature"/>
+ <enum-type name="AxesOrientationMode"/>
+ </object-type>
+ <object-type name="QSensorFilter"/>
+ <object-type name="QSensorReading"/>
+ <value-type name="qoutputrange"/>
+ <object-type name="QSensorBackend"/>
+ <object-type name="QSensorBackendFactory"/>
+ <object-type name="QSensorManager"/>
+ <object-type name="QSensorChangesInterface"/>
+ <object-type name="QSensorPluginInterface"/>
+ <object-type name="QTapFilter"/>
+ <object-type name="QTapReading">
+ <enum-type name="TapDirection"/>
+ </object-type>
+ <object-type name="QTapSensor"/>
+ <object-type name="QTiltFilter"/>
+ <object-type name="QTiltReading"/>
+ <object-type name="QTiltSensor"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtSerialBus/CMakeLists.txt b/sources/pyside6/PySide6/QtSerialBus/CMakeLists.txt
new file mode 100644
index 000000000..310a8b0f0
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSerialBus/CMakeLists.txt
@@ -0,0 +1,66 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtSerialBus)
+
+set(QtSerialBus_OPTIONAL_SRC )
+set(QtSerialBus_DROPPED_ENTRIES )
+
+set(QtSerialBus_SRC
+ ${QtSerialBus_GEN_DIR}/qcanbus_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanbusdevice_filter_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanbusdevice_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanbusdeviceinfo_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanbusfactory_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanbusframe_timestamp_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanbusframe_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcandbcfileparser_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanframeprocessor_parseresult_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanframeprocessor_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanmessagedescription_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcansignaldescription_multiplexvaluerange_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcansignaldescription_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qcanuniqueiddescription_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusclient_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusdataunit_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusdevice_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusdeviceidentification_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusexceptionresponse_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbuspdu_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusreply_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusrequest_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusresponse_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusrtuserialclient_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusrtuserialserver_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbusserver_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbustcpclient_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbustcpconnectionobserver_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qmodbustcpserver_wrapper.cpp
+ ${QtSerialBus_GEN_DIR}/qtcanbus_wrapper.cpp
+# module is always needed
+ ${QtSerialBus_GEN_DIR}/qtserialbus_module_wrapper.cpp
+)
+
+set(QtSerialBus_include_dirs ${QtSerialBus_SOURCE_DIR}
+ ${QtSerialBus_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}SerialPort_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}SerialBus_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtSerialPort_GEN_DIR})
+
+set(QtSerialBus_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}SerialBus_LIBRARIES})
+
+set(QtSerialBus_deps QtCore QtNetwork QtSerialPort)
+
+create_pyside_module(NAME QtSerialBus
+ INCLUDE_DIRS QtSerialBus_include_dirs
+ LIBRARIES QtSerialBus_libraries
+ DEPS QtSerialBus_deps
+ TYPESYSTEM_PATH QtSerialBus_SOURCE_DIR
+ SOURCES QtSerialBus_SRC
+ DROPPED_ENTRIES QtSerialBus_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtSerialBus/typesystem_serialbus.xml b/sources/pyside6/PySide6/QtSerialBus/typesystem_serialbus.xml
new file mode 100644
index 000000000..fdd2b1483
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSerialBus/typesystem_serialbus.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.QtSerialBus"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+ <load-typesystem name="QtSerialPort/typesystem_serialport.xml" generate="no"/>
+
+ <namespace-type name="QtCanBus">
+ <enum-type name="DataSource"/>
+ <enum-type name="DataFormat"/>
+ <enum-type name="MultiplexState"/>
+ <enum-type name="UniqueId"/>
+ </namespace-type>
+
+ <object-type name="QCanBus">
+ <!-- Remove errorMessage argument, return tuple instead. -->
+ <modify-function signature="availableDevices(QString,QString*)const">
+ <modify-argument index="2">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="tuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning"
+ file="../glue/qtserialbus.cpp" snippet="qcanbus-available-devices"/>
+ <inject-documentation format="target" mode="append">
+ The function returns a tuple of (device_list, error_string).
+ </inject-documentation>
+ </modify-function>
+ <modify-function signature="createDevice(QString,QString,QString*)const">
+ <modify-argument index="3">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return"> <!-- Suppress return value heuristics -->
+ <define-ownership class="target" owner="default"/>
+ <replace-type modified-type="tuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning"
+ file="../glue/qtserialbus.cpp" snippet="qcanbus-createdevice"/>
+ <inject-documentation format="target" mode="append">
+ The function returns a tuple of (device, error_string).
+ </inject-documentation>
+ </modify-function>
+ </object-type>
+ <object-type name="QCanBusDevice">
+ <enum-type name="CanBusError"/>
+ <enum-type name="CanBusDeviceState"/>
+ <enum-type name="CanBusStatus"/>
+ <enum-type name="ConfigurationKey"/>
+ <enum-type name="Direction" flags="Directions"/>
+ <modify-function signature="deviceInfo()const" access="final"/>
+ <value-type name="Filter">
+ <enum-type name="FormatFilter" flags="FormatFilters"/>
+ </value-type>
+ </object-type>
+ <value-type name="QCanBusDeviceInfo"> <!-- deleted default constructor -->
+ <modify-function signature="swap(QCanBusDeviceInfo&amp;)" remove="all"/>
+ </value-type>
+ <object-type name="QCanBusFactory"/>
+ <value-type name="QCanBusFrame">
+ <enum-type name="FrameType"/>
+ <enum-type name="FrameError" flags="FrameErrors"/>
+ <value-type name="TimeStamp"/>
+ </value-type>
+ <object-type name="QCanDbcFileParser">
+ <enum-type name="Error"/>
+ </object-type>
+ <object-type name="QCanFrameProcessor">
+ <enum-type name="Error"/>
+ <value-type name="ParseResult"/>
+ </object-type>
+ <value-type name="QCanMessageDescription"/>
+ <value-type name="QCanSignalDescription">
+ <value-type name="MultiplexValueRange"/>
+ </value-type>
+ <value-type name="QCanUniqueIdDescription"/>
+ <object-type name="QModbusClient"/>
+ <value-type name="QModbusDataUnit">
+ <enum-type name="RegisterType"/>
+ </value-type>
+ <object-type name="QModbusDevice">
+ <enum-type name="Error"/>
+ <enum-type name="State"/>
+ <enum-type name="ConnectionParameter"/>
+ <enum-type name="IntermediateError"/>
+ </object-type>
+ <value-type name="QModbusDeviceIdentification">
+ <enum-type name="ObjectId"/>
+ <enum-type name="ReadDeviceIdCode"/>
+ <enum-type name="ConformityLevel"/>
+ </value-type>
+ <object-type name="QModbusPdu">
+ <enum-type name="ExceptionCode"/>
+ <enum-type name="FunctionCode"/>
+ <modify-field name="ExceptionByte" remove="true"/> <!-- Link error -->
+ </object-type>
+ <object-type name="QModbusExceptionResponse"/>
+ <object-type name="QModbusResponse"/>
+ <object-type name="QModbusReply">
+ <enum-type name="ReplyType"/>
+ </object-type>
+ <object-type name="QModbusRequest"/>
+ <object-type name="QModbusRtuSerialClient"/>
+ <object-type name="QModbusRtuSerialServer"/>
+ <object-type name="QModbusServer">
+ <enum-type name="Option"/>
+ </object-type>
+ <object-type name="QModbusTcpClient"/>
+ <object-type name="QModbusTcpConnectionObserver"/>
+ <object-type name="QModbusTcpServer"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtSerialPort/CMakeLists.txt b/sources/pyside6/PySide6/QtSerialPort/CMakeLists.txt
new file mode 100644
index 000000000..564fc9969
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSerialPort/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtSerialPort)
+
+set(QtSerialPort_OPTIONAL_SRC )
+set(QtSerialPort_DROPPED_ENTRIES )
+
+set(QtSerialPort_SRC
+ ${QtSerialPort_GEN_DIR}/qserialport_wrapper.cpp
+ ${QtSerialPort_GEN_DIR}/qserialportinfo_wrapper.cpp
+# module is always needed
+ ${QtSerialPort_GEN_DIR}/qtserialport_module_wrapper.cpp
+)
+
+set(QtSerialPort_include_dirs ${QtSerialPort_SOURCE_DIR}
+ ${QtSerialPort_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}SerialPort_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtSerialPort_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}SerialPort_LIBRARIES})
+
+set(QtSerialPort_deps QtCore)
+
+create_pyside_module(NAME QtSerialPort
+ INCLUDE_DIRS QtSerialPort_include_dirs
+ LIBRARIES QtSerialPort_libraries
+ DEPS QtSerialPort_deps
+ TYPESYSTEM_PATH QtSerialPort_SOURCE_DIR
+ SOURCES QtSerialPort_SRC
+ DROPPED_ENTRIES QtSerialPort_DROPPED_ENTRIES)
diff --git a/sources/pyside6/PySide6/QtSerialPort/typesystem_serialport.xml b/sources/pyside6/PySide6/QtSerialPort/typesystem_serialport.xml
new file mode 100644
index 000000000..0cbd3c7f7
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSerialPort/typesystem_serialport.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtSerialPort"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <object-type name="QSerialPort">
+ <enum-type name="BaudRate" python-type="IntEnum"/>
+ <enum-type name="DataBits"/>
+ <enum-type name="Direction" flags="Directions"/>
+ <enum-type name="FlowControl"/>
+ <enum-type name="Parity"/>
+ <enum-type name="PinoutSignal" flags="PinoutSignals"/>
+ <enum-type name="SerialPortError"/>
+ <enum-type name="StopBits"/>
+ </object-type>
+ <value-type name="QSerialPortInfo"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtSpatialAudio/CMakeLists.txt b/sources/pyside6/PySide6/QtSpatialAudio/CMakeLists.txt
new file mode 100644
index 000000000..966c0ffe8
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSpatialAudio/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtSpatialAudio)
+
+set(QtSpatialAudio_SRC
+${QtSpatialAudio_GEN_DIR}/qambientsound_wrapper.cpp
+${QtSpatialAudio_GEN_DIR}/qaudioengine_wrapper.cpp
+${QtSpatialAudio_GEN_DIR}/qaudiolistener_wrapper.cpp
+${QtSpatialAudio_GEN_DIR}/qaudioroom_wrapper.cpp
+${QtSpatialAudio_GEN_DIR}/qspatialsound_wrapper.cpp
+
+# module is always needed
+${QtSpatialAudio_GEN_DIR}/qtspatialaudio_module_wrapper.cpp
+)
+
+set(QtSpatialAudio_include_dirs ${QtSpatialAudio_SOURCE_DIR}
+ ${QtSpatialAudio_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Multimedia_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}SpatialAudio_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtMultimedia_GEN_DIR})
+
+set(QtSpatialAudio_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}SpatialAudio_LIBRARIES})
+
+set(QtSpatialAudio_deps QtCore QtGui QtNetwork QtMultimedia)
+
+create_pyside_module(NAME QtSpatialAudio
+ INCLUDE_DIRS QtSpatialAudio_include_dirs
+ LIBRARIES QtSpatialAudio_libraries
+ DEPS QtSpatialAudio_deps
+ TYPESYSTEM_PATH QtSpatialAudio_SOURCE_DIR
+ SOURCES QtSpatialAudio_SRC)
diff --git a/sources/pyside6/PySide6/QtSpatialAudio/typesystem_spatialaudio.xml b/sources/pyside6/PySide6/QtSpatialAudio/typesystem_spatialaudio.xml
new file mode 100644
index 000000000..b9c2557af
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSpatialAudio/typesystem_spatialaudio.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtSpatialAudio"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+ <load-typesystem name="QtMultimedia/typesystem_multimedia.xml" generate="no"/>
+
+ <object-type name="QAmbientSound">
+ <enum-type name="Loops"/>
+ </object-type>
+
+ <object-type name="QAudioEngine">
+ <enum-type name="OutputMode"/>
+ </object-type>
+
+ <object-type name="QAudioListener"/>
+
+ <object-type name="QAudioRoom">
+ <enum-type name="Material"/>
+ <enum-type name="Wall"/>
+ </object-type>
+
+ <object-type name="QSpatialSound">
+ <enum-type name="Loops"/>
+ <enum-type name="DistanceModel"/>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtSql/CMakeLists.txt b/sources/pyside6/PySide6/QtSql/CMakeLists.txt
new file mode 100644
index 000000000..fedebe642
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSql/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtSql)
+
+set(QtSql_SRC
+${QtSql_GEN_DIR}/qsql_wrapper.cpp
+${QtSql_GEN_DIR}/qsqldatabase_wrapper.cpp
+${QtSql_GEN_DIR}/qsqldriver_wrapper.cpp
+${QtSql_GEN_DIR}/qsqldrivercreatorbase_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlerror_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlfield_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlindex_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlquery_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlquerymodel_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlrecord_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlrelation_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlrelationaldelegate_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlrelationaltablemodel_wrapper.cpp
+${QtSql_GEN_DIR}/qsqlresult_wrapper.cpp
+${QtSql_GEN_DIR}/qsqltablemodel_wrapper.cpp
+# module is always needed
+${QtSql_GEN_DIR}/qtsql_module_wrapper.cpp
+)
+
+configure_file("${QtSql_SOURCE_DIR}/QtSql_global.pre.h.in"
+ "${QtSql_BINARY_DIR}/QtSql_global.pre.h" @ONLY)
+
+set(QtSql_include_dirs ${QtSql_SOURCE_DIR}
+ ${QtSql_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Sql_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+# Link to QtWidgets to enable QSqlRelationalDelegate
+set(QtSql_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Sql_LIBRARIES})
+
+set(QtSql_deps QtWidgets)
+
+create_pyside_module(NAME QtSql
+ INCLUDE_DIRS QtSql_include_dirs
+ LIBRARIES QtSql_libraries
+ DEPS QtSql_deps
+ TYPESYSTEM_PATH QtSql_SOURCE_DIR
+ SOURCES QtSql_SRC)
diff --git a/sources/pyside6/PySide6/QtSql/QtSql_global.pre.h.in b/sources/pyside6/PySide6/QtSql/QtSql_global.pre.h.in
new file mode 100644
index 000000000..c56bc78c1
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSql/QtSql_global.pre.h.in
@@ -0,0 +1,5 @@
+// QT_WIDGETS_LIB must be defined for QSqlRelationalDelegate to become visible.
+
+#if @Qt6Widgets_FOUND@
+# define QT_WIDGETS_LIB
+#endif
diff --git a/sources/pyside6/PySide6/QtSql/typesystem_sql.xml b/sources/pyside6/PySide6/QtSql/typesystem_sql.xml
new file mode 100644
index 000000000..70c3e6f69
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSql/typesystem_sql.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtSql"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <rejection class="QSqlDriverCreator"/>
+ <rejection class="QSqlDriverPlugin"/>
+
+ <namespace-type name="QSql">
+ <enum-type name="Location"/>
+ <enum-type name="ParamTypeFlag" flags="ParamType"/>
+ <enum-type name="TableType"/>
+ <enum-type name="NumericalPrecisionPolicy"/>
+ <extra-includes>
+ <include file-name="QtSql/qtsqlglobal.h" location="global"/>
+ </extra-includes>
+ </namespace-type>
+
+ <value-type name="QSqlDatabase">
+ <extra-includes>
+ <include file-name="QSqlQuery" location="global"/>
+ <include file-name="QSqlError" location="global"/>
+ <include file-name="QSqlIndex" location="global"/>
+ <include file-name="QSqlRecord" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <modify-function signature="exec(QString)const" allow-thread="yes"/>
+ <add-function signature="exec_(QString @query@ = QString())const" return-type="QSqlQuery">
+ <inject-code file="../glue/qtsql.cpp" snippet="qsqldatabase-exec"/>
+ </add-function>
+ <modify-function signature="open()" allow-thread="yes"/>
+ <modify-function signature="open(const QString&amp;, const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="commit()" allow-thread="yes"/>
+ <modify-function signature="rollback()" allow-thread="yes"/>
+ <modify-function signature="transaction()" allow-thread="yes"/>
+ <modify-function signature="registerSqlDriver(const QString&amp;,QSqlDriverCreatorBase*)">
+ <modify-argument index="2">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
+ <value-type name="QSqlQuery">
+ <enum-type name="BatchExecutionMode"/>
+ <extra-includes>
+ <include file-name="QSqlError" location="global"/>
+ <include file-name="QSqlRecord" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <!-- exec() -->
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="bool">
+ <inject-code file="../glue/qtsql.cpp" snippet="simple-exec"/>
+ </add-function>
+ <!-- exec(QString) -->
+ <modify-function signature="exec(const QString&amp;)" allow-thread="yes"/>
+ <add-function signature="exec_(const QString&amp;)" return-type="bool">
+ <inject-code file="../glue/qtsql.cpp" snippet="qsqlquery-exec"/>
+ </add-function>
+ <modify-function signature="prepare(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="clear()" allow-thread="yes"/>
+ <modify-function signature="last()" allow-thread="yes"/>
+ <modify-function signature="first()" allow-thread="yes"/>
+ <modify-function signature="previous()" allow-thread="yes"/>
+ <modify-function signature="next()" allow-thread="yes"/>
+ <modify-function signature="seek(int,bool)" allow-thread="yes"/>
+ </value-type>
+
+ <value-type name="QSqlRecord">
+ <extra-includes>
+ <include file-name="QSqlField" location="global"/>
+ </extra-includes>
+ </value-type>
+
+ <value-type name="QSqlError">
+ <enum-type name="ErrorType"/>
+ </value-type>
+
+ <value-type name="QSqlIndex"/>
+
+ <value-type name="QSqlRelation"/>
+
+ <object-type name="QSqlRelationalDelegate"/>
+
+ <value-type name="QSqlField">
+ <enum-type name="RequiredStatus"/>
+ </value-type>
+
+ <object-type name="QSqlDriver">
+ <enum-type name="DbmsType"/>
+ <enum-type name="DriverFeature"/>
+ <enum-type name="IdentifierType"/>
+ <enum-type name="NotificationSource"/>
+ <enum-type name="StatementType"/>
+ <extra-includes>
+ <include file-name="QSqlQuery" location="global"/>
+ <include file-name="QSqlError" location="global"/>
+ <include file-name="QSqlIndex" location="global"/>
+ <include file-name="QSqlRecord" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <modify-function signature="beginTransaction()" allow-thread="yes"/>
+ <modify-function signature="commitTransaction()" allow-thread="yes"/>
+ <modify-function signature="rollbackTransaction()" allow-thread="yes"/>
+ <modify-function signature="open(const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,int,const QString&amp;)" allow-thread="yes"/>
+ <!-- ### This is too low level for Python, and pointer would be useless for the Python programmer -->
+ <modify-function signature="handle()const" remove="all"/>
+ <!-- ### -->
+ </object-type>
+
+ <object-type name="QSqlQueryModel">
+ <extra-includes>
+ <include file-name="QSqlError" location="global"/>
+ <include file-name="QSqlQuery" location="global"/>
+ <include file-name="QSqlRecord" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <!-- FIXME: PYSIDE7: Handle setQuery(QSqlQuery&&) in some way?
+ QTBUG-91766/PYSIDE-2394. allow-thread for PYSIDE-1931 -->
+ <modify-function signature="setQuery(QSqlQuery)" allow-thread="yes"
+ deprecated="false"/>
+ <modify-function signature="setQuery(QString,QSqlDatabase)" allow-thread="yes"/>
+ <!-- FIXME: PYSIDE7: Probably needs a fix, make QSqlQuery an object type?
+ QTBUG-105048/PYSIDE-2300 -->
+ <declare-function signature="query()" return-type="QSqlQuery"/>
+ </object-type>
+ <object-type name="QSqlRelationalTableModel">
+ <enum-type name="JoinMode"/>
+ <extra-includes>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <modify-function signature="select()" allow-thread="yes"/> <!-- PYSIDE-1931 -->
+ </object-type>
+ <object-type name="QSqlResult">
+ <enum-type name="BindingSyntax"/>
+ <enum-type name="VirtualHookOperation"/>
+ <extra-includes>
+ <include file-name="QSqlError" location="global"/>
+ <include file-name="QSqlQuery" location="global"/>
+ <include file-name="QSqlRecord" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <!-- ### This isn't part of Qt public API -->
+ <modify-function signature="virtual_hook(int,void*)" remove="all"/>
+ <!-- ### -->
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="bool">
+ <inject-code file="../glue/qtsql.cpp" snippet="qsqlresult-exec"/>
+ </add-function>
+ <modify-function signature="fetchLast()" allow-thread="yes"/>
+ <modify-function signature="fetchFirst()" allow-thread="yes"/>
+ <modify-function signature="fetchNext()" allow-thread="yes"/>
+ <modify-function signature="fetchPrevious()" allow-thread="yes"/>
+ <modify-function signature="fetch(int)" allow-thread="yes"/>
+ <modify-function signature="prepare(QString)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QSqlTableModel">
+ <enum-type name="EditStrategy"/>
+ <extra-includes>
+ <include file-name="QSqlIndex" location="global"/>
+ <include file-name="QStringList" location="global"/>
+ <include file-name="QSize" location="global"/>
+ </extra-includes>
+ <modify-function signature="select()" allow-thread="yes"/> <!-- PYSIDE-1931 -->
+ </object-type>
+ <object-type name="QSqlDriverCreatorBase">
+ <extra-includes>
+ <include file-name="QSqlDriver" location="global"/>
+ </extra-includes>
+ </object-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt b/sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt
new file mode 100644
index 000000000..2b4cc348d
--- /dev/null
+++ b/sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtStateMachine)
+
+set(QtStateMachine_SRC
+${QtStateMachine_GEN_DIR}/qabstractstate_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qabstracttransition_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qeventtransition_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qkeyeventtransition_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qmouseeventtransition_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qfinalstate_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qhistorystate_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qsignaltransition_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qstate_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qstatemachine_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qstatemachine_signalevent_wrapper.cpp
+${QtStateMachine_GEN_DIR}/qstatemachine_wrappedevent_wrapper.cpp
+# module is always needed
+${QtStateMachine_GEN_DIR}/qtstatemachine_module_wrapper.cpp
+)
+
+set(QtStateMachine_include_dirs ${QtStateMachine_SOURCE_DIR}
+ ${QtStateMachine_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR})
+
+set(QtStateMachine_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}StateMachine_LIBRARIES})
+
+set(QtStateMachine_deps QtGui)
+
+create_pyside_module(NAME QtStateMachine
+ INCLUDE_DIRS QtStateMachine_include_dirs
+ LIBRARIES QtStateMachine_libraries
+ DEPS QtStateMachine_deps
+ TYPESYSTEM_PATH QtStateMachine_SOURCE_DIR
+ SOURCES QtStateMachine_SRC
+ TYPESYSTEM_NAME ${QtStateMachine_BINARY_DIR}/typesystem_statemachine.xml)
diff --git a/sources/pyside6/PySide6/QtStateMachine/typesystem_statemachine.xml b/sources/pyside6/PySide6/QtStateMachine/typesystem_statemachine.xml
new file mode 100644
index 000000000..0e29f240f
--- /dev/null
+++ b/sources/pyside6/PySide6/QtStateMachine/typesystem_statemachine.xml
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtStateMachine"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+
+ <object-type name="QAbstractState">
+ <modify-function signature="machine()const">
+ <modify-argument index="this">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QAbstractTransition">
+ <enum-type name="TransitionType"/>
+
+ <modify-function signature="QAbstractTransition(QState*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addAnimation(QAbstractAnimation*)">
+ <modify-argument index="1">
+ <reference-count action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="removeAnimation(QAbstractAnimation*)">
+ <modify-argument index="1">
+ <reference-count action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setTargetState(QAbstractState*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="targetState()const">
+ <modify-argument index="return">
+ <reference-count action="set" variable-name="setTargetState(QAbstractState*)1"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="targetStates()const">
+ <modify-argument index="return">
+ <reference-count action="set" variable-name="setTargetState(QAbstractState*)1"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setTargetStates(QList&lt;QAbstractState*&gt;)">
+ <modify-argument index="1">
+ <reference-count action="set" variable-name="setTargetState(QAbstractState*)1"/>
+ </modify-argument>
+ </modify-function>
+
+ </object-type>
+
+ <object-type name="QEventTransition">
+ <modify-function signature="QEventTransition(QState*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="QEventTransition(QObject*,QEvent::Type,QState*)">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ </object-type>
+
+ <object-type name="QKeyEventTransition"/>
+ <object-type name="QMouseEventTransition"/>
+
+ <object-type name="QFinalState"/>
+
+ <object-type name="QHistoryState">
+ <enum-type name="HistoryType"/>
+ <modify-documentation xpath='description/code'>
+ &lt;code>machine = QStateMachine()
+
+s1 = QState()
+s11 = QState(s1)
+s12 = QState(s1)
+
+s1h = QHistoryState(s1)
+s1h.setDefaultState(s11)
+
+machine.addState(s1)
+
+s2 = QState()
+machine.addState(s2)
+
+button = QPushButton()
+# Clicking the button will cause the state machine to enter the child state
+# that s1 was in the last time s1 was exited, or the history state's default
+# state if s1 has never been entered.
+s1.addTransition(button.clicked, s1h)&lt;/code>
+ </modify-documentation>
+ </object-type>
+
+ <object-type name="QSignalTransition">
+ <add-function signature="QSignalTransition(PyObject*,QState*)" return-type="QSignalTransition*">
+ <modify-argument index="2">
+ <replace-default-expression with="0"/>
+ </modify-argument>
+ <inject-code file="../glue/qtstatemachine.cpp" snippet="qsignaltransition"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QState">
+ <enum-type name="ChildMode"/>
+ <enum-type name="RestorePolicy"/>
+ <modify-function signature="addTransition(QAbstractTransition*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="assignProperty(QObject*,const char*,QVariant)">
+ <modify-argument index="2" pyi-type="str"/>
+ </modify-function>
+
+ <modify-function signature="addTransition(const QObject*,const char*,QAbstractState*)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2" pyi-type="str"/>
+ <inject-code class="target" position="beginning" file="../glue/qtstatemachine.cpp"
+ snippet="qstate-addtransition-1"/>
+ </modify-function>
+ <modify-function signature="addTransition(QAbstractState*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- FIXME: the proper signature for this added function would be something like
+ addTransition(PySide2.QtCore.Signal, QAbstractState*)
+ but that depends on bug #362. -->
+ <add-function signature="addTransition(PyObject*,QAbstractState*)" return-type="QSignalTransition*">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtstatemachine.cpp"
+ snippet="qstate-addtransition-2"/>
+ </add-function>
+
+ <modify-function signature="removeTransition(QAbstractTransition*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QStateMachine">
+ <enum-type name="Error"/>
+ <enum-type name="EventPriority"/>
+
+ <object-type name="SignalEvent"/>
+ <object-type name="WrappedEvent"/>
+
+ <modify-function signature="addState(QAbstractState*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeState(QAbstractState*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <add-function signature="configuration()" return-type="QSet&lt;QAbstractState*&gt;">
+ <inject-code class="target" position="beginning" file="../glue/qtstatemachine.cpp"
+ snippet="qstatemachine-configuration"/>
+ </add-function>
+
+ <!-- Replaced by a added function -->
+ <modify-function signature="defaultAnimations()const" remove="all"/>
+ <add-function signature="defaultAnimations()" return-type="QList&lt;QAbstractAnimation*&gt;">
+ <inject-code class="target" position="beginning" file="../glue/qtstatemachine.cpp"
+ snippet="qstatemachine-defaultanimations"/>
+ </add-function>
+ </object-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtSvg/CMakeLists.txt b/sources/pyside6/PySide6/QtSvg/CMakeLists.txt
new file mode 100644
index 000000000..5451380cc
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSvg/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtSvg)
+
+set(QtSvg_SRC
+${QtSvg_GEN_DIR}/qsvggenerator_wrapper.cpp
+${QtSvg_GEN_DIR}/qsvgrenderer_wrapper.cpp
+${QtSvg_GEN_DIR}/qtsvg_wrapper.cpp
+# module is always needed
+${QtSvg_GEN_DIR}/qtsvg_module_wrapper.cpp
+)
+
+set(QtSvg_include_dirs ${QtSvg_SOURCE_DIR}
+ ${QtSvg_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Svg_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR})
+
+set(QtSvg_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Svg_LIBRARIES})
+
+
+set(QtSvg_deps QtGui)
+
+create_pyside_module(NAME QtSvg
+ INCLUDE_DIRS QtSvg_include_dirs
+ LIBRARIES QtSvg_libraries
+ DEPS QtSvg_deps
+ TYPESYSTEM_PATH QtSvg_SOURCE_DIR
+ SOURCES QtSvg_SRC)
diff --git a/sources/pyside6/PySide6/QtSvg/typesystem_svg.xml b/sources/pyside6/PySide6/QtSvg/typesystem_svg.xml
new file mode 100644
index 000000000..4803f4d93
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSvg/typesystem_svg.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtSvg"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+
+ <object-type name="QSvgRenderer"/>
+ <namespace-type name="QtSvg" since="6.7">
+ <enum-type name="Option" flags="Options"/>
+ </namespace-type>
+
+ <object-type name="QSvgGenerator">
+ <enum-type name="SvgVersion" since="6.5"/>
+ <modify-function signature="setOutputDevice(QIODevice*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="outputDevice()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtSvgWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtSvgWidgets/CMakeLists.txt
new file mode 100644
index 000000000..6bd3aedc1
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSvgWidgets/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtSvgWidgets)
+
+set(QtSvgWidgets_SRC
+${QtSvgWidgets_GEN_DIR}/qgraphicssvgitem_wrapper.cpp
+${QtSvgWidgets_GEN_DIR}/qsvgwidget_wrapper.cpp
+# module is always needed
+${QtSvgWidgets_GEN_DIR}/qtsvgwidgets_module_wrapper.cpp
+)
+
+set(QtSvgWidgets_include_dirs ${QtSvgWidgets_SOURCE_DIR}
+ ${QtSvgWidgets_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Svg_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}SvgWidgets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtSvg_GEN_DIR})
+
+set(QtSvgWidgets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}SvgWidgets_LIBRARIES})
+
+set(QtSvgWidgets_deps QtSvg QtWidgets)
+
+create_pyside_module(NAME QtSvgWidgets
+ INCLUDE_DIRS QtSvgWidgets_include_dirs
+ LIBRARIES QtSvgWidgets_libraries
+ DEPS QtSvgWidgets_deps
+ TYPESYSTEM_PATH QtSvgWidgets_SOURCE_DIR
+ SOURCES QtSvgWidgets_SRC)
diff --git a/sources/pyside6/PySide6/QtSvgWidgets/typesystem_svgwidgets.xml b/sources/pyside6/PySide6/QtSvgWidgets/typesystem_svgwidgets.xml
new file mode 100644
index 000000000..36bda1ea3
--- /dev/null
+++ b/sources/pyside6/PySide6/QtSvgWidgets/typesystem_svgwidgets.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtSvgWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtSvg/typesystem_svg.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <object-type name="QSvgWidget"/>
+
+ <object-type name="QGraphicsSvgItem">
+ <modify-function signature="QGraphicsSvgItem(QGraphicsItem*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QGraphicsSvgItem(const QString&amp;,QGraphicsItem*)">
+ <modify-argument index="this">
+ <parent index="2" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtTest/CMakeLists.txt b/sources/pyside6/PySide6/QtTest/CMakeLists.txt
new file mode 100644
index 000000000..86bb2a731
--- /dev/null
+++ b/sources/pyside6/PySide6/QtTest/CMakeLists.txt
@@ -0,0 +1,46 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtTest)
+
+set(QtTest_SRC
+${QtTest_GEN_DIR}/qtest_pysideqtoucheventsequence_wrapper.cpp
+${QtTest_GEN_DIR}/qabstractitemmodeltester_wrapper.cpp
+${QtTest_GEN_DIR}/qsignalspy_wrapper.cpp
+${QtTest_GEN_DIR}/qtest_wrapper.cpp
+# module is always needed
+${QtTest_GEN_DIR}/qttest_module_wrapper.cpp
+)
+
+configure_file("${QtTest_SOURCE_DIR}/QtTest_global.pre.h.in"
+ "${QtTest_BINARY_DIR}/QtTest_global.pre.h" @ONLY)
+
+configure_file("${QtTest_SOURCE_DIR}/QtTest_global.post.h.in"
+ "${QtTest_BINARY_DIR}/QtTest_global.post.h" @ONLY)
+
+set(QtTest_include_dirs ${QtTest_SOURCE_DIR}
+ ${QtTest_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Test_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+# Link to QtGui/QtWidgets to enable gui/widget-specific inline functions
+set(QtTest_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Test_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES})
+
+set(QtTest_deps QtWidgets)
+
+create_pyside_module(NAME QtTest
+ INCLUDE_DIRS QtTest_include_dirs
+ LIBRARIES QtTest_libraries
+ DEPS QtTest_deps
+ TYPESYSTEM_PATH QtTest_SOURCE_DIR
+ SOURCES QtTest_SRC)
diff --git a/sources/pyside6/PySide6/QtTest/QtTest_global.post.h.in b/sources/pyside6/PySide6/QtTest/QtTest_global.post.h.in
new file mode 100644
index 000000000..ccd18153c
--- /dev/null
+++ b/sources/pyside6/PySide6/QtTest/QtTest_global.post.h.in
@@ -0,0 +1 @@
+#include "pysideqtesttouch.h"
diff --git a/sources/pyside6/PySide6/QtTest/QtTest_global.pre.h.in b/sources/pyside6/PySide6/QtTest/QtTest_global.pre.h.in
new file mode 100644
index 000000000..da5534b82
--- /dev/null
+++ b/sources/pyside6/PySide6/QtTest/QtTest_global.pre.h.in
@@ -0,0 +1,5 @@
+// QT_WIDGETS_LIB changes code generation in pysideqtesttouch.h
+
+#if @Qt6Widgets_FOUND@
+# define QT_WIDGETS_LIB
+#endif
diff --git a/sources/pyside6/PySide6/QtTest/typesystem_test.xml b/sources/pyside6/PySide6/QtTest/typesystem_test.xml
new file mode 100644
index 000000000..2fc4f23cd
--- /dev/null
+++ b/sources/pyside6/PySide6/QtTest/typesystem_test.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtTest"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <rejection class="QTest::Internal"/>
+ <rejection class="QTestPrivate"/>
+
+ <rejection class="QTest" function-name="qCompare"/>
+ <rejection class="QTest" function-name="qVerify"/>
+ <rejection class="QTest" function-name="toHexRepresentation"/>
+ <rejection class="QTest" function-name="qFail"/>
+ <rejection class="QTest" function-name="qInit"/>
+ <rejection class="QTest" function-name="qExec"/>
+ <rejection class="QTest" function-name="qData"/>
+ <rejection class="QTest" function-name="qWarn"/>
+ <rejection class="QTest" function-name="toString"/>
+ <rejection class="QTest" function-name="useVerifyThrowsException"/>
+
+ <rejection class="QTest" function-name="compare_helper"/>
+ <rejection class="QTest" function-name="toPrettyUnicode"/>
+
+ <rejection class="QTest" field-name="lastMouseTimestamp"/>
+
+ <!-- Qt5: this new stuff below belongs to QtGui. I keep it here for now, after a long odyssey.
+
+ The problem that costed my days of bug hunting is the fact that shiboken gives
+ misleading error messages. The messages that I could not get rid of were
+
+ signature 'generateTouchEvent(QWidget*,QInputDevice*,bool)' for function modification in 'QTest' not found. Possible candidates:
+ signature 'generateTouchEvent(QWindow*,QInputDevice*,bool)' for function modification in 'QTest' not found. Possible candidates:
+
+ I always thought that for some reason the functions were not recognized, or the arguments somehow
+ do not match their declaration. Only late in the project, I learnt that also
+ a simply missing type name in the argument list leads to this message.
+
+ <object-type name="QInputDevice">
+ <enum-type name="CapabilityFlag" flags="Capabilities"/>
+ <enum-type name="DeviceType"/>
+ </object-type>
+ ^^^ this is now moved into QtGui -->
+
+ <object-type name="QAbstractItemModelTester">
+ <enum-type name="FailureReportingMode"/>
+ </object-type>
+
+ <object-type name="QSignalSpy"> <!-- Inherits QList<QVariantList> -->
+ <extra-includes>
+ <include file-name="pysidesignal.h" location="global"/>
+ </extra-includes>
+ <declare-function signature="count()const" return-type="qsizetype"/>
+ <declare-function signature="size()const" return-type="qsizetype"/>
+ <declare-function signature="at(qsizetype)const" return-type="QVariantList"/>
+ <add-function signature="QSignalSpy(PySideSignalInstance@signal@)">
+ <inject-code class="target" position="beginning" file="../glue/qttest.cpp" snippet="qsignalspy-signal"/>
+ <inject-documentation format="target" mode="append">
+ Constructs a new QSignalSpy that listens for emissions of the signal.
+ </inject-documentation>
+ </add-function>
+ </object-type>
+
+ <namespace-type name="QTest">
+ <!-- Qt5: private <enum-type name="AttributeIndex" since="4.6"/> -->
+ <enum-type name="KeyAction"/>
+ <!-- Qt5: private <enum-type name="LogElementType" since="4.6"/> -->
+ <enum-type name="MouseAction"/>
+ <enum-type name="QBenchmarkMetric" since="4.7"/>
+ <enum-type name="TestFailMode"/>
+ <enum-type name="ComparisonOperation" since="6.4"/>
+ <extra-includes>
+ <include file-name="QtTest" location="global"/>
+ </extra-includes>
+
+ <object-type name="PySideQTouchEventSequence" target-lang-name="QTouchEventSequence" since="4.6" >
+ <modify-function signature="press(int,const QPoint&amp;,QWidget*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="press(int,const QPoint&amp;,QWindow*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="move(int,const QPoint&amp;,QWidget*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="move(int,const QPoint&amp;,QWindow*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="release(int,const QPoint&amp;,QWidget*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="release(int,const QPoint&amp;,QWindow*)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="stationary(int)">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <modify-function signature="generateTouchEvent(QWidget*,QPointingDevice*,bool)" rename="touchEvent" since="4.6">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="generateTouchEvent(QWindow*,QPointingDevice*,bool)" rename="touchEvent" since="4.6">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </namespace-type>
+
+ <rejection class="QTestEventList"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtTextToSpeech/CMakeLists.txt b/sources/pyside6/PySide6/QtTextToSpeech/CMakeLists.txt
new file mode 100644
index 000000000..9f0bd2fc3
--- /dev/null
+++ b/sources/pyside6/PySide6/QtTextToSpeech/CMakeLists.txt
@@ -0,0 +1,31 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtTextToSpeech)
+
+set(QtTextToSpeech_SRC
+${QtTextToSpeech_GEN_DIR}/qtexttospeech_wrapper.cpp
+${QtTextToSpeech_GEN_DIR}/qtexttospeechengine_wrapper.cpp
+${QtTextToSpeech_GEN_DIR}/qvoice_wrapper.cpp
+# module is always needed
+${QtTextToSpeech_GEN_DIR}/qttexttospeech_module_wrapper.cpp
+)
+
+set(QtTextToSpeech_include_dirs ${QtTextToSpeech_SOURCE_DIR}
+ ${QtTextToSpeech_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}TextToSpeech_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtTextToSpeech_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}TextToSpeech_LIBRARIES})
+
+set(QtTextToSpeech_deps QtCore QtMultimedia)
+
+create_pyside_module(NAME QtTextToSpeech
+ INCLUDE_DIRS QtTextToSpeech_include_dirs
+ LIBRARIES QtTextToSpeech_libraries
+ DEPS QtTextToSpeech_deps
+ TYPESYSTEM_PATH QtTextToSpeech_SOURCE_DIR
+ SOURCES QtTextToSpeech_SRC)
diff --git a/sources/pyside6/PySide6/QtTextToSpeech/typesystem_texttospeech.xml b/sources/pyside6/PySide6/QtTextToSpeech/typesystem_texttospeech.xml
new file mode 100644
index 000000000..70751e9d9
--- /dev/null
+++ b/sources/pyside6/PySide6/QtTextToSpeech/typesystem_texttospeech.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtTextToSpeech"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+
+ <object-type name="QTextToSpeech">
+ <enum-type name="State"/>
+ <enum-type name="BoundaryHint"/>
+ <enum-type name="ErrorReason"/>
+ <enum-type name="Capability" flags="Capabilities" since="6.6"/>
+ </object-type>
+ <object-type name="QTextToSpeechEngine"/>
+ <value-type name="QVoice">
+ <enum-type name="Gender"/>
+ <enum-type name="Age"/>
+ </value-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtUiTools/CMakeLists.txt b/sources/pyside6/PySide6/QtUiTools/CMakeLists.txt
new file mode 100644
index 000000000..e16d2d585
--- /dev/null
+++ b/sources/pyside6/PySide6/QtUiTools/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtUiTools)
+
+set(QtUiTools_SRC
+${QtUiTools_GEN_DIR}/quiloader_wrapper.cpp
+# module is always needed
+${QtUiTools_GEN_DIR}/qtuitools_module_wrapper.cpp
+)
+
+set(QtUiTools_glue_sources
+ "${QtUiTools_SOURCE_DIR}/glue/plugins.h"
+)
+
+set(QtUiTools_include_dirs ${QtUiTools_SOURCE_DIR}
+ ${QtUiTools_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Xml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Designer_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}UiTools_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${plugins_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR})
+
+set(QtUiTools_libraries pyside6
+ uiplugin
+ ${Qt${QT_MAJOR_VERSION}UiTools_LIBRARIES})
+
+set(QtUiTools_deps QtWidgets)
+
+configure_file("${QtUiTools_SOURCE_DIR}/QtUiTools_global.pre.h.in"
+ "${QtUiTools_BINARY_DIR}/QtUiTools_global.pre.h" @ONLY)
+
+create_pyside_module(NAME QtUiTools
+ INCLUDE_DIRS QtUiTools_include_dirs
+ LIBRARIES QtUiTools_libraries
+ DEPS QtUiTools_deps
+ TYPESYSTEM_PATH QtUiTools_SOURCE_DIR
+ SOURCES QtUiTools_SRC
+ GLUE_SOURCES QtUiTools_glue_sources)
diff --git a/sources/pyside6/PySide6/QtUiTools/QtUiTools_global.pre.h.in b/sources/pyside6/PySide6/QtUiTools/QtUiTools_global.pre.h.in
new file mode 100644
index 000000000..addfe080f
--- /dev/null
+++ b/sources/pyside6/PySide6/QtUiTools/QtUiTools_global.pre.h.in
@@ -0,0 +1,7 @@
+// Those classes are only forward-declared in QtUiLoader
+
+#include <QtWidgets/QLayout>
+#include <QtWidgets/QWidget>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtCore/QDir>
diff --git a/sources/pyside6/PySide6/QtUiTools/glue/plugins.h b/sources/pyside6/PySide6/QtUiTools/glue/plugins.h
new file mode 100644
index 000000000..04ec149ff
--- /dev/null
+++ b/sources/pyside6/PySide6/QtUiTools/glue/plugins.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include "customwidgets.h"
+
+#include <QtCore/qpluginloader.h>
+
+static inline PyCustomWidgets *findPlugin()
+{
+ const auto &instances = QPluginLoader::staticInstances();
+ for (QObject *o : instances) {
+ if (auto plugin = qobject_cast<PyCustomWidgets *>(o))
+ return plugin;
+ }
+ return nullptr;
+}
+
+static void registerCustomWidget(PyObject *obj)
+{
+ static PyCustomWidgets *const plugin = findPlugin();
+
+ if (plugin)
+ plugin->registerWidgetType(obj);
+ else
+ qWarning("Qt for Python: Failed to find the static QUiLoader plugin.");
+}
+
+#endif
diff --git a/sources/pyside6/PySide6/QtUiTools/typesystem_uitools.xml b/sources/pyside6/PySide6/QtUiTools/typesystem_uitools.xml
new file mode 100644
index 000000000..9cfa176c8
--- /dev/null
+++ b/sources/pyside6/PySide6/QtUiTools/typesystem_uitools.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+
+<typesystem package="PySide6.QtUiTools"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+
+ <object-type name="QUiLoader">
+ <extra-includes>
+ <include file-name="glue/plugins.h" location="local"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtuitools.cpp" snippet="uitools-loadui"/>
+ <inject-code file="../glue/qtuitools.cpp" snippet="quiloader"/>
+ <add-function signature="registerCustomWidget(PyObject*@customWidgetType@)" return-type="void">
+ <inject-documentation format="target" mode="append" file="../doc/qtuitools.rst"
+ snippet="quiloader-registercustomwidget"/>
+ <inject-code class="target" position="beginning" file="../glue/qtuitools.cpp"
+ snippet="quiloader-registercustomwidget"/>
+ </add-function>
+ <modify-function signature="createAction(QObject*,const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="createActionGroup(QObject*,const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="createLayout(const QString&amp;,QObject*,const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="2" action="add"/>
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="createWidget(const QString&amp;,QWidget*,const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="2" action="add"/>
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="load(QIODevice*,QWidget*)">
+ <modify-argument index="2">
+ <replace-default-expression with="0"/>
+ <rename to="parentWidget"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <define-ownership class="target" owner="target"/>
+ </modify-argument>
+ <inject-code file="../glue/qtuitools.cpp" snippet="quiloader-load-1"/>
+ </modify-function>
+
+ <!-- Syntax sugar -->
+ <add-function signature="load(PyPathLike,QWidget*@parentWidget@=nullptr)" return-type="QWidget*">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="target"/>
+ </modify-argument>
+ <inject-code file="../glue/qtuitools.cpp" snippet="quiloader-load-2"/>
+ </add-function>
+ </object-type>
+
+ <!--
+ After the removal of the 'pysideuic' Python module, many users were unable to generate and
+ load UI classes dynamically.
+ This function was created to provide an equivalent solution to the 'loadUiType' function from
+ Riverbank's PyQt.
+ -->
+ <add-function signature="loadUiType(const QString&amp; @uifile@)" return-type="PyObject*">
+ <inject-code file="../glue/qtuitools.cpp" snippet="loaduitype"/>
+ <inject-documentation format="target" mode="append" file="../doc/qtuitools.rst"
+ snippet="loaduitype"/>
+ </add-function>
+
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtWebChannel/CMakeLists.txt b/sources/pyside6/PySide6/QtWebChannel/CMakeLists.txt
new file mode 100644
index 000000000..4c06edd2f
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebChannel/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtWebChannel)
+
+set(QtWebChannel_SRC
+${QtWebChannel_GEN_DIR}/qwebchannel_wrapper.cpp
+${QtWebChannel_GEN_DIR}/qwebchannelabstracttransport_wrapper.cpp
+# module is always needed
+${QtWebChannel_GEN_DIR}/qtwebchannel_module_wrapper.cpp
+)
+
+set(QtWebChannel_include_dirs ${QtWebChannel_SOURCE_DIR}
+ ${QtWebChannel_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR})
+
+set(QtWebChannel_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}WebChannel_LIBRARIES})
+
+set(QtWebChannel_deps QtCore)
+
+create_pyside_module(NAME QtWebChannel
+ INCLUDE_DIRS QtWebChannel_include_dirs
+ LIBRARIES QtWebChannel_libraries
+ DEPS QtWebChannel_deps
+ TYPESYSTEM_PATH QtWebChannel_SOURCE_DIR
+ SOURCES QtWebChannel_SRC)
diff --git a/sources/pyside6/PySide6/QtWebChannel/typesystem_webchannel.xml b/sources/pyside6/PySide6/QtWebChannel/typesystem_webchannel.xml
new file mode 100644
index 000000000..c08a9b187
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebChannel/typesystem_webchannel.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtWebChannel"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+
+ <object-type name="QWebChannel"/>
+ <object-type name="QWebChannelAbstractTransport">
+ <extra-includes>
+ <include file-name="QJsonObject" location="global"/>
+ </extra-includes>
+ </object-type>
+ <!-- Not sure if this will be useful, but commented out for now because
+ the QML module is not yet wrapped.
+ <object-type name="QQmlWebChannel"/> -->
+
+ <!-- QtQml/QtNetwork are pulled in via QtQtWebChannelDepends. -->
+ <suppress-warning text="^Scoped enum 'Q(Ocsp)|(Dtls)|(Qml).*' does not have a type entry.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtWebEngineCore/CMakeLists.txt b/sources/pyside6/PySide6/QtWebEngineCore/CMakeLists.txt
new file mode 100644
index 000000000..0cdaf2f91
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebEngineCore/CMakeLists.txt
@@ -0,0 +1,75 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtWebEngineCore)
+
+set(QtWebEngineCore_SRC
+${QtWebEngineCore_GEN_DIR}/qwebenginecertificateerror_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineclientcertificateselection_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineclientcertificatestore_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginecontextmenurequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginecookiestore_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginecookiestore_filterrequest_wrapper.cpp
+# FIXME ${QtWebEngineCore_GEN_DIR}/qwebenginedesktopmediarequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginedownloadrequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginefilesystemaccessrequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginefindtextresult_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginefullscreenrequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineglobalsettings_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineglobalsettings_dnsmode_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginehistory_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginehistoryitem_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginehistorymodel_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginehttprequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginenavigationrequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineloadinginfo_wrapper.cpp
+# FIXME ${QtWebEngineCore_GEN_DIR}/qwebenginemediasourcemodel_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginenewwindowrequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginenotification_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginepage_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineprofile_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginequotarequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineregisterprotocolhandlerrequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginescript_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginescriptcollection_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginesettings_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineurlrequestinfo_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineurlrequestinterceptor_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineurlrequestjob_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineurlscheme_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebengineurlschemehandler_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginewebauthpinrequest_wrapper.cpp
+${QtWebEngineCore_GEN_DIR}/qwebenginewebauthuxrequest_wrapper.cpp
+# module is always needed
+${QtWebEngineCore_GEN_DIR}/qtwebenginecore_module_wrapper.cpp
+)
+
+set(QtWebEngineCore_include_dirs
+ ${QtWebEngineCore_SOURCE_DIR}
+ ${QtWebEngineCore_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtPrintSupport_GEN_DIR}
+ ${QtWebChannel_GEN_DIR})
+
+set(QtWebEngineCore_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}WebEngineCore_LIBRARIES})
+
+set(QtWebEngineCore_deps QtCore QtGui QtNetwork QtPrintSupport QtWebChannel)
+
+create_pyside_module(NAME QtWebEngineCore
+ INCLUDE_DIRS QtWebEngineCore_include_dirs
+ LIBRARIES QtWebEngineCore_libraries
+ DEPS QtWebEngineCore_deps
+ TYPESYSTEM_PATH QtWebEngineCore_SOURCE_DIR
+ SOURCES QtWebEngineCore_SRC)
+
diff --git a/sources/pyside6/PySide6/QtWebEngineCore/typesystem_webenginecore.xml b/sources/pyside6/PySide6/QtWebEngineCore/typesystem_webenginecore.xml
new file mode 100644
index 000000000..da9259ccc
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebEngineCore/typesystem_webenginecore.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtWebEngineCore"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+ <load-typesystem name="QtPrintSupport/typesystem_printsupport.xml" generate="no"/>
+ <load-typesystem name="QtWebChannel/typesystem_webchannel.xml" generate="no"/>
+
+ <rejection class="extensions"/>
+
+ <function signature="qWebEngineChromiumVersion()"/>
+ <function signature="qWebEngineChromiumSecurityPatchVersion()"/>
+ <function signature="qWebEngineVersion()"/>
+
+ <value-type name="QWebEngineClientCertificateSelection"/>
+ <object-type name="QWebEngineClientCertificateStore"/>
+
+ <object-type name="QWebEngineCookieStore">
+ <inject-code class="native" position="beginning" file="../glue/qtwebenginecore.cpp"
+ snippet="qwebenginecookiestore-functor"/>
+ <value-type name="FilterRequest" />
+ <add-function signature="setCookieFilter(PyCallable* @filterCallback@)">
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginecore.cpp"
+ snippet="qwebenginecookiestore-setcookiefilter"/>
+ </add-function>
+ </object-type>
+
+ <value-type name="QWebEngineCertificateError">
+ <enum-type name="Type"/>
+ </value-type>
+
+ <object-type name="QWebEngineContextMenuRequest">
+ <enum-type name="EditFlag" flags="EditFlags"/>
+ <enum-type name="MediaFlag" flags="MediaFlags"/>
+ <enum-type name="MediaType"/>
+ </object-type>
+
+ <object-type name="QWebEngineDownloadRequest">
+ <enum-type name="DownloadInterruptReason"/>
+ <enum-type name="DownloadState"/>
+ <enum-type name="SavePageFormat"/>
+ </object-type>
+
+ <value-type name="QWebEngineFileSystemAccessRequest">
+ <enum-type name="AccessFlag" flags="AccessFlags"/>
+ <enum-type name="HandleType"/>
+ <!-- No default constructor -->
+ <modify-function signature="swap(QWebEngineFileSystemAccessRequest&amp;)" remove="all"/>
+ </value-type>
+
+ <value-type name="QWebEngineFullScreenRequest"/>
+
+ <object-type name="QWebEngineHistory"/>
+ <value-type name="QWebEngineHistoryItem">
+ <!-- No default constructor -->
+ <modify-function signature="swap(QWebEngineHistoryItem&amp;)" remove="all"/>
+ </value-type>
+ <object-type name="QWebEngineHistoryModel">
+ <enum-type name="Roles"/>
+ </object-type>
+
+ <object-type name="QWebEngineNavigationRequest">
+ <enum-type name="NavigationType"/>
+ <enum-type name="NavigationRequestAction"/>
+ </object-type>
+
+ <object-type name="QWebEngineNotification"/>
+
+ <object-type name="QWebEnginePage">
+ <enum-type name="LifecycleState"/>
+ <enum-type name="WebAction"/>
+ <enum-type name="FindFlag" flags="FindFlags"/>
+ <enum-type name="WebWindowType"/>
+ <enum-type name="PermissionPolicy"/>
+ <enum-type name="NavigationType"/>
+ <enum-type name="Feature"/>
+ <enum-type name="FileSelectionMode"/>
+ <enum-type name="JavaScriptConsoleMessageLevel"/>
+ <enum-type name="RenderProcessTerminationStatus"/>
+ <add-function signature="javaScriptPromptPyOverride(QUrl@securityOrigin@,QString@msg@,QString@defaultValue@)"
+ return-type="std::pair&lt;bool,QString&gt;" python-override="true"/>
+ <modify-function signature="javaScriptPrompt(QUrl,QString,QString,QString*)">
+ <inject-code class="shell" position="override" file="../glue/qtwebenginecore.cpp"
+ snippet="qwebenginepage-javascriptprompt-virtual-redirect"/>
+ <modify-argument index="return" pyi-type="Tuple[bool, str]"/>
+ <modify-argument index="4"><remove-default-expression/><remove-argument/></modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginecore.cpp"
+ snippet="qwebenginepage-javascriptprompt-return"/>
+ </modify-function>
+ <add-function signature="findText(const QString &amp;,QWebEnginePage::FindFlags,PyObject*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginewidgets.cpp" snippet="qwebenginepage-findtext"/>
+ </add-function>
+ <add-function signature="toPlainText(PyObject*) const">
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginewidgets.cpp" snippet="qwebenginepage-convertto"/>
+ </add-function>
+ <add-function signature="toHtml(PyObject*) const">
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginewidgets.cpp" snippet="qwebenginepage-convertto"/>
+ </add-function>
+ <add-function signature="runJavaScript(const QString &amp;,quint32,PyObject*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginewidgets.cpp" snippet="qwebenginepage-runjavascript"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QWebEngineProfile">
+ <extra-includes>
+ <include file-name="QtWebEngineCore/QWebEngineNotification" location="global"/>
+ </extra-includes>
+ <inject-code class="native" position="beginning" file="../glue/qtwebenginecore.cpp"
+ snippet="qwebengineprofile-functor"/>
+ <enum-type name="HttpCacheType"/>
+ <enum-type name="PersistentCookiesPolicy"/>
+ <add-function signature="setNotificationPresenter(PyCallable* @notificationPresenter@)">
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginecore.cpp" snippet="qwebengineprofile-setnotificationpresenter"/>
+ </add-function>
+ </object-type>
+
+ <object-type name="QWebEngineNewWindowRequest">
+ <enum-type name="DestinationType"/>
+ </object-type>
+
+ <value-type name="QWebEngineScript">
+ <enum-type name="InjectionPoint"/>
+ <enum-type name="ScriptWorldId" python-type="IntEnum"/>
+ </value-type>
+
+ <object-type name="QWebEngineScriptCollection"/>
+
+ <object-type name="QWebEngineSettings">
+ <enum-type name="FontFamily"/>
+ <enum-type name="FontSize"/>
+ <enum-type name="UnknownUrlSchemePolicy"/>
+ <enum-type name="WebAttribute"/>
+ </object-type>
+
+ <object-type name="QWebEngineHttpRequest">
+ <enum-type name="Method"/>
+ </object-type>
+
+ <value-type name="QWebEngineLoadingInfo">
+ <enum-type name="ErrorDomain"/>
+ <enum-type name="LoadStatus"/>
+ </value-type>
+
+ <value-type name="QWebEngineRegisterProtocolHandlerRequest"/>
+
+ <value-type name="QWebEngineFindTextResult"/>
+
+ <object-type name="QWebEngineQuotaRequest"/>
+
+ <object-type name="QWebEngineUrlRequestInfo">
+ <enum-type name="NavigationType"/>
+ <enum-type name="ResourceType"/>
+ </object-type>
+
+ <object-type name="QWebEngineUrlRequestInterceptor"/>
+
+ <object-type name="QWebEngineUrlRequestJob">
+ <enum-type name="Error"/>
+ </object-type>
+ <value-type name="QWebEngineUrlScheme">
+ <enum-type name="Syntax"/>
+ <enum-type name="SpecialPort"/>
+ <enum-type name="Flag" flags="Flags"/>
+ </value-type>
+
+ <object-type name="QWebEngineUrlSchemeHandler"/>
+
+ <!-- FIXME not in snapshot yet
+ <value-type name="QWebEngineDesktopMediaRequest" since="6.7"/>
+ <object-type name="QWebEngineMediaSourceModel" since="6.7"/>
+ -->
+ <value-type name="QWebEngineWebAuthPinRequest" since="6.7"/>
+ <object-type name="QWebEngineWebAuthUxRequest" since="6.7">
+ <enum-type name="WebAuthUxState"/>
+ <enum-type name="PinEntryReason"/>
+ <enum-type name="PinEntryError"/>
+ <enum-type name="RequestFailureReason"/>
+ </object-type>
+ <namespace-type name="QWebEngineGlobalSettings">
+ <enum-type name="SecureDnsMode"/>
+ <value-type name="DnsMode"/>
+ </namespace-type>
+
+ <!-- QtQml is pulled in via QtWebEngineCoreDepends. -->
+ <suppress-warning text="^Scoped enum 'QQml.*' does not have a type entry.*$"/>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtWebEngineQuick/CMakeLists.txt b/sources/pyside6/PySide6/QtWebEngineQuick/CMakeLists.txt
new file mode 100644
index 000000000..d87dc55a4
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebEngineQuick/CMakeLists.txt
@@ -0,0 +1,43 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtWebEngineQuick)
+
+set(QtWebEngineQuick_SRC
+${QtWebEngineQuick_GEN_DIR}/qquickwebengineprofile_wrapper.cpp
+${QtWebEngineQuick_GEN_DIR}/qtwebenginequick_wrapper.cpp
+# module is always needed
+${QtWebEngineQuick_GEN_DIR}/qtwebenginequick_module_wrapper.cpp
+)
+
+set(QtWebEngineQuick_include_dirs
+ ${QtWebEngineQuick_SOURCE_DIR}
+ ${QtWebEngineQuick_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtWebEngineCore_GEN_DIR}
+ ${QtPrintSupport_GEN_DIR}
+ ${QtQml_GEN_DIR}
+ ${QtWebChannel_GEN_DIR})
+
+set(QtWebEngineQuick_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}WebEngineQuick_LIBRARIES})
+
+set(QtWebEngineQuick_deps QtQml QtWebEngineCore)
+
+create_pyside_module(NAME QtWebEngineQuick
+ INCLUDE_DIRS QtWebEngineQuick_include_dirs
+ LIBRARIES QtWebEngineQuick_libraries
+ DEPS QtWebEngineQuick_deps
+ TYPESYSTEM_PATH QtWebEngineQuick_SOURCE_DIR
+ SOURCES QtWebEngineQuick_SRC)
diff --git a/sources/pyside6/PySide6/QtWebEngineQuick/typesystem_webenginequick.xml b/sources/pyside6/PySide6/QtWebEngineQuick/typesystem_webenginequick.xml
new file mode 100644
index 000000000..2e7d22334
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebEngineQuick/typesystem_webenginequick.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtWebEngineQuick"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtQml/typesystem_qml.xml" generate="no"/>
+ <load-typesystem name="QtWebEngineCore/typesystem_webenginecore.xml" generate="no"/>
+
+ <namespace-type name="QtWebEngineQuick"/> <!-- initialize() -->
+
+ <object-type name="QQuickWebEngineProfile">
+ <enum-type name="HttpCacheType"/>
+ <enum-type name="PersistentCookiesPolicy"/>
+ </object-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtWebEngineWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtWebEngineWidgets/CMakeLists.txt
new file mode 100644
index 000000000..9da97243c
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebEngineWidgets/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtWebEngineWidgets)
+
+set(QtWebEngineWidgets_SRC
+${QtWebEngineWidgets_GEN_DIR}/qwebengineview_wrapper.cpp
+# module is always needed
+${QtWebEngineWidgets_GEN_DIR}/qtwebenginewidgets_module_wrapper.cpp
+)
+
+set(QtWebEngineWidgets_include_dirs
+ ${QtWebEngineWidgets_SOURCE_DIR}
+ ${QtWebEngineWidgets_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebEngineWidgets_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${QtWebEngineWidgets_GEN_DIR}
+ ${QtNetwork_GEN_DIR}
+ ${QtWebEngineCore_GEN_DIR}
+ ${QtPrintSupport_GEN_DIR}
+ ${QtWebChannel_GEN_DIR})
+
+set(QtWebEngineWidgets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}WebEngineWidgets_LIBRARIES})
+
+set(QtWebEngineWidgets_deps QtGui QtWidgets QtNetwork QtPrintSupport QtWebChannel QtWebEngineCore)
+
+create_pyside_module(NAME QtWebEngineWidgets
+ INCLUDE_DIRS QtWebEngineWidgets_include_dirs
+ LIBRARIES QtWebEngineWidgets_libraries
+ DEPS QtWebEngineWidgets_deps
+ TYPESYSTEM_PATH QtWebEngineWidgets_SOURCE_DIR
+ SOURCES QtWebEngineWidgets_SRC)
+
+
+
diff --git a/sources/pyside6/PySide6/QtWebEngineWidgets/typesystem_webenginewidgets.xml b/sources/pyside6/PySide6/QtWebEngineWidgets/typesystem_webenginewidgets.xml
new file mode 100644
index 000000000..61874856b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebEngineWidgets/typesystem_webenginewidgets.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtWebEngineWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+ <load-typesystem name="QtWebEngineCore/typesystem_webenginecore.xml" generate="no"/>
+ <load-typesystem name="QtPrintSupport/typesystem_printsupport.xml" generate="no"/>
+
+ <object-type name="QWebEngineView">
+ <add-function signature="findText(const QString &amp;,QWebEnginePage::FindFlags,PyObject*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwebenginewidgets.cpp" snippet="qwebenginepage-findtext"/>
+ </add-function>
+ </object-type>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtWebSockets/CMakeLists.txt b/sources/pyside6/PySide6/QtWebSockets/CMakeLists.txt
new file mode 100644
index 000000000..5ff07555b
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebSockets/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtWebSockets)
+
+set(QtWebSockets_SRC
+${QtWebSockets_GEN_DIR}/qmaskgenerator_wrapper.cpp
+${QtWebSockets_GEN_DIR}/qwebsocket_wrapper.cpp
+${QtWebSockets_GEN_DIR}/qwebsocketcorsauthenticator_wrapper.cpp
+${QtWebSockets_GEN_DIR}/qwebsockethandshakeoptions_wrapper.cpp
+${QtWebSockets_GEN_DIR}/qwebsocketprotocol_wrapper.cpp
+${QtWebSockets_GEN_DIR}/qwebsocketserver_wrapper.cpp
+# module is always needed
+${QtWebSockets_GEN_DIR}/qtwebsockets_module_wrapper.cpp
+)
+
+set(QtWebSockets_include_dirs ${QtWebSockets_SOURCE_DIR}
+ ${QtWebSockets_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}WebSockets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtWebSockets_GEN_DIR}
+ ${QtNetwork_GEN_DIR})
+
+set(QtWebSockets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}WebSockets_LIBRARIES})
+
+set(QtWebSockets_deps QtNetwork)
+
+create_pyside_module(NAME QtWebSockets
+ INCLUDE_DIRS QtWebSockets_include_dirs
+ LIBRARIES QtWebSockets_libraries
+ DEPS QtWebSockets_deps
+ TYPESYSTEM_PATH QtWebSockets_SOURCE_DIR
+ SOURCES QtWebSockets_SRC)
diff --git a/sources/pyside6/PySide6/QtWebSockets/typesystem_websockets.xml b/sources/pyside6/PySide6/QtWebSockets/typesystem_websockets.xml
new file mode 100644
index 000000000..2d8d95898
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWebSockets/typesystem_websockets.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtWebSockets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
+
+ <object-type name="QMaskGenerator"/>
+
+ <object-type name="QWebSocket">
+ <extra-includes>
+ <include file-name="QTcpSocket" location="global"/>
+ </extra-includes>
+ </object-type>
+
+ <object-type name="QWebSocketCorsAuthenticator"/>
+
+ <value-type name="QWebSocketHandshakeOptions" since="6.4"/>
+
+ <namespace-type name="QWebSocketProtocol">
+ <enum-type name="Version"/>
+ <enum-type name="CloseCode"/>
+ </namespace-type>
+
+ <object-type name="QWebSocketServer">
+ <enum-type name="SslMode"/>
+ <extra-includes>
+ <include file-name="QWebSocketCorsAuthenticator" location="global"/>
+ </extra-includes>
+ </object-type>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt
new file mode 100644
index 000000000..1a77181f2
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt
@@ -0,0 +1,226 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtWidgets)
+
+set(QtWidgets_SRC
+${QtWidgets_GEN_DIR}/qaccessiblewidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qabstractbutton_wrapper.cpp
+${QtWidgets_GEN_DIR}/qabstractgraphicsshapeitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qabstractitemdelegate_wrapper.cpp
+${QtWidgets_GEN_DIR}/qabstractitemview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qabstractscrollarea_wrapper.cpp
+${QtWidgets_GEN_DIR}/qabstractslider_wrapper.cpp
+${QtWidgets_GEN_DIR}/qabstractspinbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qapplication_wrapper.cpp
+${QtWidgets_GEN_DIR}/qboxlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qbuttongroup_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcalendarwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcheckbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcolordialog_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcolormap_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcolumnview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcombobox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcommandlinkbutton_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcommonstyle_wrapper.cpp
+${QtWidgets_GEN_DIR}/qcompleter_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdatawidgetmapper_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdateedit_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdatetimeedit_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdial_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdialog_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdialogbuttonbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdockwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qdoublespinbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qerrormessage_wrapper.cpp
+${QtWidgets_GEN_DIR}/qfiledialog_wrapper.cpp
+${QtWidgets_GEN_DIR}/qfileiconprovider_wrapper.cpp
+${QtWidgets_GEN_DIR}/qfilesystemmodel_wrapper.cpp
+${QtWidgets_GEN_DIR}/qfocusframe_wrapper.cpp
+${QtWidgets_GEN_DIR}/qfontcombobox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qfontdialog_wrapper.cpp
+${QtWidgets_GEN_DIR}/qformlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qformlayout_takerowresult_wrapper.cpp
+${QtWidgets_GEN_DIR}/qframe_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgesture_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgestureevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgesturerecognizer_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsanchor_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsanchorlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsblureffect_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicscolorizeeffect_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsdropshadoweffect_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicseffect_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsellipseitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsgridlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsitemanimation_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsitemgroup_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicslayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicslayoutitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicslinearlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicslineitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsobject_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsopacityeffect_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicspathitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicspixmapitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicspolygonitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsproxywidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsrectitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsrotation_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscale_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscene_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscenecontextmenuevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscenedragdropevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicssceneevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscenehelpevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscenehoverevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscenemouseevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscenemoveevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicssceneresizeevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsscenewheelevent_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicssimpletextitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicstextitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicstransform_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicsview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgraphicswidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgridlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qgroupbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qhboxlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qheaderview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qinputdialog_wrapper.cpp
+${QtWidgets_GEN_DIR}/qitemdelegate_wrapper.cpp
+${QtWidgets_GEN_DIR}/qitemeditorcreatorbase_wrapper.cpp
+${QtWidgets_GEN_DIR}/qitemeditorfactory_wrapper.cpp
+${QtWidgets_GEN_DIR}/qkeysequenceedit_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlabel_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlayoutitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlcdnumber_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlineedit_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlistview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlistwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qlistwidgetitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qmainwindow_wrapper.cpp
+${QtWidgets_GEN_DIR}/qmdiarea_wrapper.cpp
+${QtWidgets_GEN_DIR}/qmdisubwindow_wrapper.cpp
+${QtWidgets_GEN_DIR}/qmenu_wrapper.cpp
+${QtWidgets_GEN_DIR}/qmenubar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qmessagebox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qpangesture_wrapper.cpp
+${QtWidgets_GEN_DIR}/qpinchgesture_wrapper.cpp
+${QtWidgets_GEN_DIR}/qplaintextdocumentlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qplaintextedit_wrapper.cpp
+${QtWidgets_GEN_DIR}/qprogressbar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qprogressdialog_wrapper.cpp
+${QtWidgets_GEN_DIR}/qproxystyle_wrapper.cpp
+${QtWidgets_GEN_DIR}/qpushbutton_wrapper.cpp
+${QtWidgets_GEN_DIR}/qradiobutton_wrapper.cpp
+${QtWidgets_GEN_DIR}/qrhiwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qrubberband_wrapper.cpp
+${QtWidgets_GEN_DIR}/qscrollarea_wrapper.cpp
+${QtWidgets_GEN_DIR}/qscrollbar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qscroller_wrapper.cpp
+${QtWidgets_GEN_DIR}/qscrollerproperties_wrapper.cpp
+${QtWidgets_GEN_DIR}/qsizegrip_wrapper.cpp
+${QtWidgets_GEN_DIR}/qsizepolicy_wrapper.cpp
+${QtWidgets_GEN_DIR}/qslider_wrapper.cpp
+${QtWidgets_GEN_DIR}/qspaceritem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qspinbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qsplashscreen_wrapper.cpp
+${QtWidgets_GEN_DIR}/qsplitter_wrapper.cpp
+${QtWidgets_GEN_DIR}/qsplitterhandle_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstackedlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstackedwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstatusbar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyle_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleditemdelegate_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstylefactory_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstylehintreturn_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstylehintreturnmask_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstylehintreturnvariant_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoption_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionbutton_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptioncombobox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptioncomplex_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiondockwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionfocusrect_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionframe_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiongraphicsitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiongroupbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionheader_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionheaderv2_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionmenuitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionprogressbar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionrubberband_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionsizegrip_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionslider_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionspinbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiontab_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiontabbarbase_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiontabwidgetframe_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiontitlebar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiontoolbar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiontoolbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptiontoolbutton_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstyleoptionviewitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qstylepainter_wrapper.cpp
+${QtWidgets_GEN_DIR}/qswipegesture_wrapper.cpp
+${QtWidgets_GEN_DIR}/qsystemtrayicon_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtabbar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtableview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtablewidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtablewidgetitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtablewidgetselectionrange_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtabwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtapandholdgesture_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtapgesture_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtextbrowser_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtextedit_extraselection_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtextedit_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtilerules_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtimeedit_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtoolbar_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtoolbox_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtoolbutton_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtooltip_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtreeview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtreewidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtreewidgetitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qtreewidgetitemiterator_wrapper.cpp
+${QtWidgets_GEN_DIR}/qundoview_wrapper.cpp
+${QtWidgets_GEN_DIR}/qvboxlayout_wrapper.cpp
+${QtWidgets_GEN_DIR}/qwhatsthis_wrapper.cpp
+${QtWidgets_GEN_DIR}/qwidget_wrapper.cpp
+${QtWidgets_GEN_DIR}/qwidgetaction_wrapper.cpp
+${QtWidgets_GEN_DIR}/qwidgetitem_wrapper.cpp
+${QtWidgets_GEN_DIR}/qwizard_wrapper.cpp
+${QtWidgets_GEN_DIR}/qwizardpage_wrapper.cpp
+
+${SPECIFIC_OS_FILES}
+# module is always needed
+${QtWidgets_GEN_DIR}/qtwidgets_module_wrapper.cpp
+)
+
+set(QtWidgets_include_dirs ${QtWidgets_SOURCE_DIR}
+ ${QtWidgets_BINARY_DIR}
+ ${pyside6_SOURCE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR})
+
+set(QtWidgets_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES})
+
+set(QtWidgets_deps QtGui)
+
+create_pyside_module(NAME QtWidgets
+ INCLUDE_DIRS QtWidgets_include_dirs
+ LIBRARIES QtWidgets_libraries
+ DEPS QtWidgets_deps
+ TYPESYSTEM_PATH QtWidgets_SOURCE_DIR
+ SOURCES QtWidgets_SRC
+ TYPESYSTEM_NAME ${QtWidgets_BINARY_DIR}/typesystem_widgets.xml)
diff --git a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets.xml b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets.xml
new file mode 100644
index 000000000..93a7151fc
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets_common.xml" generate="yes"/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml
new file mode 100644
index 000000000..b1188a514
--- /dev/null
+++ b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml
@@ -0,0 +1,3420 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtWidgets"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="templates/core_common.xml" generate="no"/>
+ <load-typesystem name="templates/widgets_common.xml" generate="no"/>
+
+
+
+ <!-- Qt5: Beware forgetting the following rejection!
+ There are anonymous enums "enum { Type = 1 }" etc. in these QGraphics classes, but they
+ don't show up as "enum_1", but pretend they were a real enum field, not a value.
+
+ """
+ Generating class model... [WARNING]
+ enum 'QGraphicsItem::UserType' does not have a type entry or is not an enum
+ enum 'QGraphicsWidget::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsProxyWidget::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsEllipseItem::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsPixmapItem::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsSimpleTextItem::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsTextItem::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsItemGroup::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsRectItem::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsLineItem::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsPathItem::Type' does not have a type entry or is not an enum
+ enum 'QGraphicsPolygonItem::Type' does not have a type entry or is not an enum
+ """
+ -->
+ <rejection class="QMdi"/>
+
+ <function signature="qDrawShadeLine(QPainter*,int,int,int,int,const QPalette&amp;,bool,int,int)"/>
+ <function signature="qDrawShadeLine(QPainter*,const QPoint,const QPoint,const QPalette&amp;,bool,int,int)"/>
+ <function signature="qDrawShadeRect(QPainter*,int,int,int,int,const QPalette&amp;,bool,int,int,const QBrush*)"/>
+ <function signature="qDrawShadeRect(QPainter*,const QRect &amp;,const QPalette&amp;,bool,int,int,const QBrush*)"/>
+ <function signature="qDrawShadePanel(QPainter*,int,int,int,int,const QPalette&amp;,bool,int,const QBrush*)"/>
+ <function signature="qDrawShadePanel(QPainter*,const QRect&amp;,const QPalette&amp;,bool,int,const QBrush*)"/>
+ <function signature="qDrawWinButton(QPainter*,int,int,int,int,const QPalette&amp;,bool,const QBrush*)"/>
+ <function signature="qDrawWinButton(QPainter*,const QRect&amp;,const QPalette&amp;,bool,const QBrush*)"/>
+ <function signature="qDrawWinPanel(QPainter*,int,int,int,int,const QPalette&amp;,bool,const QBrush*)"/>
+ <function signature="qDrawWinPanel(QPainter*,const QRect&amp;,const QPalette&amp;,bool,const QBrush*)"/>
+ <function signature="qDrawPlainRect(QPainter*,int,int,int,int,const QColor&amp;,int,const QBrush*)"/>
+ <function signature="qDrawPlainRect(QPainter*,const QRect&amp;,const QColor&amp;,int,const QBrush*)"/>
+ <function signature="qDrawPlainRoundedRect(QPainter*,int,int,int,int,qreal,qreal,const QColor&amp;,int,const QBrush*)" since="6.7"/>
+ <function signature="qDrawPlainRoundedRect(QPainter*,const QRect&amp;,qreal,qreal,const QColor&amp;,int,const QBrush *)" since="6.7"/>
+
+ <object-type name="QStyleOption" polymorphic-id-expression="%B-&gt;type == QStyleOption::SO_Default"
+ polymorphic-name-function="styleOptionType">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qstyleoption-typename"/>
+ <enum-type name="OptionType"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionGraphicsItem"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionGraphicsItem *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionSizeGrip"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionSizeGrip *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionButton"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionButton *&gt;(%B) != nullptr">
+ <enum-type name="ButtonFeature" flags="ButtonFeatures"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionComboBox"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionComboBox *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionComplex"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionComplex *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionDockWidget"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionDockWidget *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionFocusRect" polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionFocusRect *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionFrame"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionFrame *&gt;(%B) != nullptr">
+ <enum-type name="FrameFeature" flags="FrameFeatures"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionGroupBox"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionGroupBox *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionHeader"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionHeader *&gt;(%B) != nullptr">
+ <enum-type name="SectionPosition"/>
+ <enum-type name="SelectedPosition"/>
+ <enum-type name="SortIndicator"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionHeaderV2">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionMenuItem"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionMenuItem *&gt;(%B) != nullptr">
+ <enum-type name="CheckType"/>
+ <enum-type name="MenuItemType"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionProgressBar"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionProgressBar *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionRubberBand"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionRubberBand *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionSlider"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionSlider *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionSpinBox"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionSpinBox *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionTab"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionTab *&gt;(%B) != nullptr">
+ <enum-type name="CornerWidget" flags="CornerWidgets"/>
+ <enum-type name="SelectedPosition"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ <enum-type name="TabFeature" flags="TabFeatures"/>
+ <enum-type name="TabPosition"/>
+ </object-type>
+ <object-type name="QStyleOptionTabBarBase"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionTabBarBase *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionTabWidgetFrame"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionTabWidgetFrame *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionTitleBar" polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionTitleBar *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleOptionToolBar"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionToolBar *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ <enum-type name="ToolBarFeature" flags="ToolBarFeatures"/>
+ <enum-type name="ToolBarPosition"/>
+ </object-type>
+ <object-type name="QStyleOptionToolBox"
+ polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionToolBox *&gt;(%B) != nullptr">
+ <enum-type name="SelectedPosition"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ <enum-type name="TabPosition"/>
+ </object-type>
+ <object-type name="QStyleOptionToolButton" polymorphic-id-expression="qstyleoption_cast&lt;const QStyleOptionToolButton *&gt;(%B) != nullptr">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ <enum-type name="ToolButtonFeature" flags="ToolButtonFeatures"/>
+ </object-type>
+ <value-type name="QStyleOptionViewItem"
+ polymorphic-id-expression="%B-&gt;type == QStyleOptionViewItem::Type &amp;&amp; %B-&gt;version == QStyleOptionViewItem::Version">
+ <enum-type name="Position"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ <enum-type name="ViewItemFeature" flags="ViewItemFeatures"/>
+ <enum-type name="ViewItemPosition"/>
+ </value-type>
+
+ <object-type name="QAccessibleWidget"/>
+ <value-type name="QColormap">
+ <enum-type name="Mode"/>
+ </value-type>
+ <value-type name="QSizePolicy">
+ <enum-type name="ControlType" flags="ControlTypes"/>
+ <enum-type name="Policy"/>
+ <enum-type name="PolicyFlag" python-type="IntFlag"/>
+ </value-type>
+ <value-type name="QTableWidgetSelectionRange"/>
+
+ <value-type name="QTreeWidgetItemIterator" >
+ <modify-function signature="QTreeWidgetItemIterator(QTreeWidget*,QFlags&lt;QTreeWidgetItemIterator::IteratorFlag&gt;)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <add-function signature="__iter__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ <insert-template name="__iter__"/>
+ </inject-code>
+ </add-function>
+ <add-function signature="__next__()" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtreewidgetitemiterator-next"/>
+ </add-function>
+
+ <add-function signature="value()" return-type="QTreeWidgetItem*">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtreewidgetitemiterator-value"/>
+ </add-function>
+ <enum-type name="IteratorFlag" flags="IteratorFlags"/>
+ <!-- ### See bug 778 -->
+ <modify-function signature="operator++(int)" remove="all"/>
+ <modify-function signature="operator--(int)" remove="all"/>
+ <modify-function signature="operator++()" remove="all"/>
+ <modify-function signature="operator--()" remove="all"/>
+ <!-- ### Operator* doesn't make sense in Python. -->
+ <modify-function signature="operator*()const" remove="all"/>
+ <!-- ### -->
+ </value-type>
+
+ <object-type name="QLayoutItem">
+
+ <modify-function signature="widget()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="layout()">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="spacerItem()">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <!-- Register Qt meta type only for base class QGraphicsItem as registering
+ QGraphicsItemGroup* breaks QGraphicsItem::itemChange()), PYSIDE-1887 -->
+ <object-type name="QGraphicsItem" qt-register-metatype="base" parent-management="true">
+ <enum-type name="CacheMode"/>
+ <enum-type name="Extension"/>
+ <enum-type name="GraphicsItemChange"/>
+ <enum-type name="GraphicsItemFlag" flags="GraphicsItemFlags"/>
+ <enum-type name="PanelModality" since="4.6"/>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qgraphicsitem"/>
+ <modify-function signature="setParentItem(QGraphicsItem*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="scene()const">
+ <inject-code position="end" file="../glue/qtwidgets.cpp" snippet="qgraphicsitem-scene-return-parenting"/>
+ <modify-argument index="this">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="parentItem()const">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ <modify-argument index="this">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="parentWidget()const">
+ <modify-argument index="this">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="paint(QPainter*,const QStyleOptionGraphicsItem*,QWidget*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="collidesWithItem(const QGraphicsItem*,Qt::ItemSelectionMode)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="contextMenuEvent(QGraphicsSceneContextMenuEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dragEnterEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dragLeaveEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dragMoveEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dropEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="focusInEvent(QFocusEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="focusOutEvent(QFocusEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="hoverEnterEvent(QGraphicsSceneHoverEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="hoverLeaveEvent(QGraphicsSceneHoverEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="hoverMoveEvent(QGraphicsSceneHoverEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="inputMethodEvent(QInputMethodEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="isBlockedByModalPanel(QGraphicsItem**)const" since="4.6">
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, PySide6.QtWidgets.QGraphicsItem]">
+ <replace-type modified-type="(retval, blockingPanel)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qgraphicsitem-isblockedbymodalpanel"/>
+ </modify-function>
+ <modify-function signature="itemTransform(const QGraphicsItem*,bool*)const">
+ <modify-argument index="2">
+ <remove-argument />
+ <remove-default-expression />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtGui.QTransform, bool]">
+ <replace-type modified-type="(QTransform, bool ok)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,bool*"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="isObscuredBy(const QGraphicsItem*)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="keyPressEvent(QKeyEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="keyReleaseEvent(QKeyEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mouseDoubleClickEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mouseMoveEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mousePressEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mouseReleaseEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="sceneEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="sceneEventFilter(QGraphicsItem*,QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ <modify-argument index="2" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="wheelEvent(QGraphicsSceneWheelEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="setGraphicsEffect(QGraphicsEffect*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <!-- ### These methods are internal on Qt. -->
+ <modify-function signature="supportsExtension(QGraphicsItem::Extension)const" remove="all"/>
+ <modify-function signature="setExtension(QGraphicsItem::Extension,QVariant)" remove="all"/>
+ <!-- ### -->
+ </object-type>
+ <object-type name="QAbstractGraphicsShapeItem"/>
+ <object-type name="QAbstractItemView">
+ <enum-type name="CursorAction"/>
+ <enum-type name="DragDropMode"/>
+ <enum-type name="DropIndicatorPosition"/>
+ <enum-type name="EditTrigger" flags="EditTriggers"/>
+ <enum-type name="ScrollHint"/>
+ <enum-type name="ScrollMode"/>
+ <enum-type name="SelectionBehavior"/>
+ <enum-type name="SelectionMode"/>
+ <enum-type name="State"/>
+ <modify-function signature="setModel(QAbstractItemModel*)">
+ <modify-argument index="1" pyi-type="Optional[PySide6.QtCore.QAbstractItemModel]">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setSelectionModel(QItemSelectionModel*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemDelegate(QAbstractItemDelegate*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemDelegateForColumn(int,QAbstractItemDelegate*)">
+ <modify-argument index="2">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemDelegateForRow(int,QAbstractItemDelegate*)">
+ <modify-argument index="2">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="model()const">
+ <modify-argument index="return">
+ <!-- Defining ownership as "default" avoids the object to be automatically
+ set as parent of the returned pointer. -->
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="selectionModel()const">
+ <modify-argument index="return">
+ <!-- Defining ownership as "default" avoids the object to be automatically
+ set as parent of the returned pointer. -->
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setIndexWidget(const QModelIndex &amp;,QWidget*)" allow-thread="yes">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="edit(QModelIndex,QAbstractItemView::EditTrigger,QEvent*)">
+ <modify-argument index="3" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="selectionCommand(QModelIndex,const QEvent*)const">
+ <modify-argument index="2" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstractSlider">
+ <enum-type name="SliderAction"/>
+ <enum-type name="SliderChange"/>
+ </object-type>
+ <object-type name="QCheckBox"/>
+ <object-type name="QCommonStyle">
+ </object-type>
+ <object-type name="QDataWidgetMapper">
+ <enum-type name="SubmitPolicy"/>
+ <modify-function signature="addMapping(QWidget*,int)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addMapping(QWidget*,int,QByteArray)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeMapping(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemDelegate(QAbstractItemDelegate*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setModel(QAbstractItemModel*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QDateEdit"/>
+ <object-type name="QDialog">
+ <enum-type name="DialogCode" python-type="IntEnum"/>
+ <modify-function signature="exec()" allow-thread="yes">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qdialog-exec-remove-parent-relation"/>
+ </modify-function>
+ <add-function signature="exec_()" return-type="int">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qapplication-exec"/>
+ </add-function>
+ </object-type>
+ <object-type name="QDialogButtonBox">
+ <enum-type name="ButtonLayout"/>
+ <enum-type name="ButtonRole"/>
+ <enum-type name="StandardButton" flags="StandardButtons"/>
+ <modify-function signature="addButton(QAbstractButton*,QDialogButtonBox::ButtonRole)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeButton(QAbstractButton*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QFileIconProvider"/>
+ <object-type name="QWizard">
+ <enum-type name="WizardButton"/>
+ <enum-type name="WizardOption" flags="WizardOptions"/>
+ <enum-type name="WizardPixmap"/>
+ <enum-type name="WizardStyle"/>
+ <modify-function signature="addPage(QWizardPage*)">
+ <modify-argument index="1">
+ <no-null-pointer/>
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setPage(int,QWizardPage*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setButton(QWizard::WizardButton,QAbstractButton*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QWizardPage">
+ <extra-includes>
+ <include file-name="pysidesignal.h" location="global"/>
+ </extra-includes>
+ <modify-function signature="wizard()const">
+ <modify-argument index="this">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="registerField(const QString&amp;,QWidget*,const char*,const char*)" allow-thread="yes">
+ <modify-argument index="3" pyi-type="str" rename="property"/>
+ <modify-argument index="4" pyi-type="str" rename="changed_signal"/>
+ </modify-function>
+ <add-function signature="registerField(const QString&amp;@name@,QWidget*@widget@,const char*@property@,PySideSignalInstance@changedSignal@)">
+ <modify-argument index="3" pyi-type="str"/>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qwizardpage-registerfield"/>
+ </add-function>
+ </object-type>
+ <object-type name="QFocusFrame">
+ <modify-function signature="setWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QFontComboBox">
+ <enum-type name="FontFilter" flags="FontFilters"/>
+ </object-type>
+ <object-type name="QFontDialog">
+ <enum-type name="FontDialogOption" flags="FontDialogOptions"/>
+ <modify-function signature="getFont(bool*,QWidget*)" allow-thread="yes">
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, PySide6.QtGui.QFont]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="bool*_fix,arg"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getFont(bool*,QFont,QWidget*,QString,QFlags&lt;QFontDialog::FontDialogOption&gt;)" allow-thread="yes">
+ <modify-argument index="1">
+ <remove-argument />
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, PySide6.QtGui.QFont]">
+ <replace-type modified-type="PyTuple"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="bool*_fix,arg,arg,arg,arg"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsEllipseItem"/>
+ <object-type name="QGraphicsItemAnimation">
+ <modify-function signature="setItem(QGraphicsItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setTimeLine(QTimeLine*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <extra-includes>
+ <include file-name="QPair" location="global"/>
+ </extra-includes>
+ </object-type>
+ <object-type name="QGraphicsItemGroup">
+ <modify-function signature="addToGroup(QGraphicsItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsLineItem"/>
+ <object-type name="QGraphicsPathItem"/>
+ <object-type name="QGraphicsPixmapItem">
+ <enum-type name="ShapeMode"/>
+ </object-type>
+ <object-type name="QGraphicsPolygonItem"/>
+ <object-type name="QGraphicsRectItem"/>
+ <object-type name="QGraphicsSimpleTextItem"/>
+ <object-type name="QHBoxLayout"/>
+ <object-type name="QHeaderView">
+ <enum-type name="ResizeMode"/>
+ <modify-function signature="paintSection(QPainter*,QRect,int)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QItemDelegate">
+ <!-- ### "doLayout(...)" is an internal method. -->
+ <modify-function signature="doLayout(QStyleOptionViewItem,QRect*,QRect*,QRect*,bool)const" remove="all"/>
+ <!-- ### -->
+ <modify-function signature="drawCheck(QPainter*,QStyleOptionViewItem,QRect,Qt::CheckState)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawDecoration(QPainter*,QStyleOptionViewItem,QRect,QPixmap)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawDisplay(QPainter*,QStyleOptionViewItem,QRect,QString)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawFocus(QPainter*,QStyleOptionViewItem,QRect)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="setItemEditorFactory(QItemEditorFactory*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QItemEditorCreatorBase">
+ <modify-function signature="createWidget(QWidget*)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QItemEditorFactory">
+ <modify-function signature="registerEditor(int,QItemEditorCreatorBase*)">
+ <modify-argument index="2">
+ <reference-count action="set"/>
+ </modify-argument>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qitemeditorfactory-registereditor"/>
+ </modify-function>
+ <modify-function signature="setDefaultFactory(QItemEditorFactory*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qitemeditorfactory-setdefaultfactory"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QListView">
+ <enum-type name="Flow"/>
+ <enum-type name="LayoutMode"/>
+ <enum-type name="Movement"/>
+ <enum-type name="ResizeMode"/>
+ <enum-type name="ViewMode"/>
+ </object-type>
+ <object-type name="QColumnView">
+ <modify-function signature="setPreviewWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QMainWindow">
+ <enum-type name="DockOption" flags="DockOptions"/>
+ <modify-function signature="setCentralWidget(QWidget*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="replace_child">
+ <replace from="$FUNCTION_GET_OLD" to="centralWidget"/>
+ <replace from="$CHILD_TYPE" to="QWidget"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="setMenuBar(QMenuBar*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="replace_child">
+ <replace from="$FUNCTION_GET_OLD" to="menuBar"/>
+ <replace from="$CHILD_TYPE" to="QMenuBar"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="setMenuWidget(QWidget*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="replace_child">
+ <replace from="$FUNCTION_GET_OLD" to="menuWidget"/>
+ <replace from="$CHILD_TYPE" to="QWidget"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="setStatusBar(QStatusBar*)">
+ <inject-code class="target" position="beginning">
+ <insert-template name="replace_child">
+ <replace from="$FUNCTION_GET_OLD" to="statusBar"/>
+ <replace from="$CHILD_TYPE" to="QStatusBar"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="addDockWidget(Qt::DockWidgetArea,QDockWidget*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addDockWidget(Qt::DockWidgetArea,QDockWidget*,Qt::Orientation)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <!-- this fuction is declared when not defined QT_NO_TOOLBA -->
+ <modify-function signature="addToolBar(Qt::ToolBarArea,QToolBar*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addToolBar(QToolBar*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addToolBar(const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <!--- END QT_NO_TOOLBAR -->
+ <modify-function signature="removeDockWidget(QDockWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeToolBar(QToolBar*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeDockWidget(QDockWidget*)">
+ <modify-argument index="2">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ </object-type>
+ <object-type name="QMdiArea">
+ <enum-type name="AreaOption" flags="AreaOptions"/>
+ <enum-type name="ViewMode"/>
+ <enum-type name="WindowOrder"/>
+ <modify-function signature="addSubWindow(QWidget*,QFlags&lt;Qt::WindowType&gt;)" >
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeSubWindow(QWidget*)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QMdiSubWindow">
+ <enum-type name="SubWindowOption" flags="SubWindowOptions"/>
+ <modify-function signature="setWidget(QWidget*)" allow-thread="yes">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setSystemMenu(QMenu*)" allow-thread="yes">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QMenu">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-glue"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-addaction-glue"/>
+ <!-- exec() -->
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="QAction*">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qmenu-exec-1"/>
+ </add-function>
+ <!-- exec(QPoint, QAction) -->
+ <modify-function signature="exec(const QPoint&amp;,QAction*)" allow-thread="yes"/>
+ <add-function signature="exec_(const QPoint&amp;,QAction* @action@ = nullptr)" return-type="QAction*">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qmenu-exec-2"/>
+ </add-function>
+ <!-- exec(QList<QPoint>, QPoint, QAction, QWidget) -->
+ <modify-function signature="exec(QList&lt;QAction*>,const QPoint&amp;,QAction*,QWidget*)" allow-thread="yes"/>
+ <add-function signature="exec_(QList&lt;QAction*>,const QPoint&amp;,QAction* @at@ = nullptr,QWidget* @parent@ = nullptr)" return-type="QAction*">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qmenu-exec-3"/>
+ </add-function>
+ <modify-function signature="addMenu(QMenu*)">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addMenu(const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addMenu(const QIcon &amp;,const QString &amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertMenu(QAction*,QMenu*)">
+ <modify-argument index="return">
+ <parent index="2" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addMenu(const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addMenu(const QIcon &amp;,const QString &amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <!-- ### "setNoReplayFor(QWidget*)" is an internal method. -->
+ <modify-function signature="setNoReplayFor(QWidget*)" remove="all"/>
+
+ <!-- FIXME PYSIDE7: Remove in favor of widgets methods -->
+ <modify-function signature="addAction(const QString&amp;,const QObject*,const char*,const QKeySequence&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <add-function signature="addAction(QString&amp;@text@,PyObject*,QKeySequence&amp;@shortcut@)">
+ <modify-argument index="3">
+ <replace-default-expression with="0"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-addaction-1"/>
+ </add-function>
+
+ <add-function signature="addAction(QIcon&amp;,QString&amp;@text@,PyObject*,QKeySequence&amp;@shortcut@)">
+ <modify-argument index="4">
+ <replace-default-expression with="0"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-addaction-2"/>
+ </add-function>
+ <modify-function signature="addAction(const QIcon&amp;,const QString&amp;,const QObject*,const char*,const QKeySequence&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="clear()">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qmenu-clear"/>
+ </modify-function>
+
+ </object-type>
+
+ <object-type name="QMenuBar">
+ <modify-function signature="addMenu(QMenu*)">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addSeparator()">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertMenu(QAction*,QMenu*)">
+ <modify-argument index="return">
+ <parent index="2" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertSeparator(QAction*)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="clear()">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qmenubar-clear"/>
+ </modify-function>
+
+ </object-type>
+ <object-type name="QProgressBar">
+ <enum-type name="Direction"/>
+ </object-type>
+ <object-type name="QProxyStyle">
+ <modify-function signature="QProxyStyle(QStyle*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QPushButton"/>
+ <object-type name="QScrollArea">
+ <modify-function signature="setWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QSpacerItem"/>
+ <object-type name="QStatusBar">
+ <modify-function signature="addWidget(QWidget*,int)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addPermanentWidget(QWidget*,int)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertWidget(int,QWidget*,int)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertPermanentWidget(int,QWidget*,int)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QStyleFactory">
+ <modify-function signature="create(const QString&amp;)">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QStyleHintReturn">
+ <enum-type name="HintReturnType"/>
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleHintReturnVariant">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStyleHintReturnMask">
+ <enum-type name="StyleOptionType"/>
+ <enum-type name="StyleOptionVersion"/>
+ </object-type>
+ <object-type name="QStylePainter"/>
+ <object-type name="QTableView">
+ <modify-function signature="setHorizontalHeader(QHeaderView*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setVerticalHeader(QHeaderView*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QTimeEdit"/>
+ <object-type name="QToolBox">
+ <modify-function signature="addItem(QWidget*,const QIcon&amp;,const QString&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addItem(QWidget*,const QString&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertItem(int,QWidget*,const QIcon&amp;,const QString&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertItem(int,QWidget*,const QString&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeItem(int)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtoolbox-removeitem"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QToolButton">
+ <enum-type name="ToolButtonPopupMode"/>
+ <modify-function signature="setDefaultAction(QAction*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setMenu(QMenu*)">
+ </modify-function>
+ </object-type>
+ <object-type name="QToolTip"/>
+ <object-type name="QTreeView">
+ <modify-function signature="drawBranches(QPainter*,QRect,QModelIndex)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawRow(QPainter*,QStyleOptionViewItem,QModelIndex)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="setHeader(QHeaderView*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QUndoView">
+ <modify-function signature="setGroup(QUndoGroup*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setStack(QUndoStack*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QUndoView(QUndoGroup*,QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QUndoView(QUndoStack*,QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QVBoxLayout"/>
+
+ <object-type name="QWhatsThis"/>
+ <object-type name="QWidgetAction">
+ <modify-function signature="setDefaultWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="releaseWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QWidgetItem" polymorphic-id-expression="%B-&gt;widget()"/>
+
+ <object-type name="QGraphicsSceneContextMenuEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneContextMenu">
+ <enum-type name="Reason"/>
+ </object-type>
+ <object-type name="QGraphicsSceneDragDropEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneDragEnter || %B-&gt;type() == QEvent::GraphicsSceneDragLeave || %B-&gt;type() == QEvent::GraphicsSceneDragMove || %B-&gt;type() == QEvent::GraphicsSceneDrop" >
+ <!-- ### "setMimeData(const QMimeData*)" is an internal method. -->
+ <modify-function signature="setMimeData(const QMimeData*)" remove="all"/>
+ <!-- ### "setSource(QWidget*)" is an internal method. -->
+ <modify-function signature="setSource(QWidget*)" remove="all"/>
+ <!-- ### -->
+ </object-type>
+ <object-type name="QGraphicsSceneEvent" copyable="false" qt-register-metatype="base">
+ <!-- ### "setWidget(QWidget*)" is an internal method. -->
+ <modify-function signature="setWidget(QWidget*)" remove="all"/>
+ </object-type>
+ <object-type name="QGraphicsSceneMoveEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneMove"/>
+ <object-type name="QGraphicsSceneResizeEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneResize"/>
+ <object-type name="QGraphicsSceneHelpEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneHelp"/>
+ <object-type name="QGraphicsSceneHoverEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneHoverEnter || %B-&gt;type() == QEvent::GraphicsSceneHoverLeave || %B-&gt;type() == QEvent::GraphicsSceneHoverMove"/>
+ <object-type name="QGraphicsSceneMouseEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneMouseDoubleClick || %B-&gt;type() == QEvent::GraphicsSceneMouseMove || %B-&gt;type() == QEvent::GraphicsSceneMousePress || %B-&gt;type() == QEvent::GraphicsSceneMouseRelease"/>
+ <object-type name="QGraphicsSceneWheelEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::GraphicsSceneWheel"/>
+
+ <object-type name="QGestureEvent"
+ polymorphic-id-expression="%B-&gt;type() == QEvent::Gesture || %B-&gt;type() == QEvent::GestureOverride" since="4.6">
+ <modify-function signature="activeGestures()const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="canceledGestures()const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="gestures()const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="gesture(Qt::GestureType)const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="widget()const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QAbstractButton">
+ <add-function signature="setShortcut(Qt::Key)">
+ <inject-code file="../glue/qtgui.cpp" snippet="set-qtkey-shortcut"/>
+ </add-function>
+ </object-type>
+ <object-type name="QStyle">
+ <enum-type name="ComplexControl" python-type="IntEnum"/>
+ <enum-type name="ContentsType" python-type="IntEnum"/>
+ <enum-type name="ControlElement" python-type="IntEnum"/>
+ <enum-type name="PixelMetric" python-type="IntEnum"/>
+ <enum-type name="PrimitiveElement" python-type="IntEnum"/>
+ <enum-type name="RequestSoftwareInputPanel" since="4.6"/>
+ <enum-type name="StandardPixmap" python-type="IntEnum"/>
+ <enum-type name="StateFlag" flags="State"/>
+ <enum-type name="StyleHint" python-type="IntEnum"/>
+ <enum-type name="SubControl" flags="SubControls"/>
+ <enum-type name="SubElement" python-type="IntEnum"/>
+ <modify-function signature="drawComplexControl(QStyle::ComplexControl,const QStyleOptionComplex*,QPainter*,const QWidget*)const">
+ <modify-argument index="3" invalidate-after-use="yes"/>
+ <modify-argument index="4">
+ <rename to="widget"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="drawControl(QStyle::ControlElement,const QStyleOption*,QPainter*,const QWidget*)const">
+ <modify-argument index="3" invalidate-after-use="yes"/>
+ <modify-argument index="4">
+ <rename to="widget"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="drawPrimitive(QStyle::PrimitiveElement,const QStyleOption*,QPainter*,const QWidget*)const">
+ <modify-argument index="3" invalidate-after-use="yes"/>
+ <modify-argument index="4">
+ <rename to="widget"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="hitTestComplexControl(QStyle::ComplexControl,const QStyleOptionComplex*,const QPoint&amp;,const QWidget*)const">
+ <modify-argument index="4">
+ <rename to="widget"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="styleHint(QStyle::StyleHint,const QStyleOption*,const QWidget*,QStyleHintReturn*)const">
+ <modify-argument index="4" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawItemPixmap(QPainter*,QRect,int,QPixmap)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawItemText(QPainter*,QRect,int,QPalette,bool,QString,QPalette::ColorRole)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QColorDialog">
+ <enum-type name="ColorDialogOption" flags="ColorDialogOptions"/>
+ <modify-function signature="getColor(const QColor&amp;,QWidget*,const QString&amp;,QFlags&lt;QColorDialog::ColorDialogOption>)" allow-thread="yes"/>
+ </object-type>
+
+ <object-type name="QLayout" polymorphic-base="true">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qwidget-retrieveobjectname"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
+ <enum-type name="SizeConstraint"/>
+
+ <modify-function signature="itemAt(int)const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp"
+ snippet="addownership-item-at"/>
+ </modify-function>
+
+ <modify-function signature="removeWidget(QWidget*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="removeownership-1"/>
+ </modify-function>
+ <modify-function signature="removeItem(QLayoutItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="removeownership-1"/>
+ </modify-function>
+
+ <modify-function signature="replaceWidget(QWidget*,QWidget*,QFlags&lt;Qt::FindChildOption&gt;)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
+ </modify-function>
+
+ <modify-function signature="parentWidget()const">
+ <modify-argument index="this">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="takeAt(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addItem(QLayoutItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+
+ <modify-function signature="addWidget(QWidget*)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="addChildWidget(QWidget*)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="addChildLayout(QLayout*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="setMenuBar(QWidget*)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+
+ <modify-function signature="getContentsMargins(int*,int*,int*,int*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ <inject-code class="native" position="end">
+ <insert-template name="fix_native_return_number*,number*,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+
+ <add-function signature="setAlignment(QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-setalignment"/>
+ </add-function>
+
+ </object-type>
+
+ <object-type name="QStackedLayout">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qwidget-retrieveobjectname"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
+ <enum-type name="StackingMode"/>
+ <modify-function signature="insertWidget(int,QWidget*)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
+ </modify-function>
+ <modify-function signature="addWidget(QWidget*)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QBoxLayout">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qwidget-retrieveobjectname"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
+
+ <enum-type name="Direction"/>
+
+ <modify-function signature="addWidget(QWidget*,int,QFlags&lt;Qt::AlignmentFlag&gt;)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+
+ <modify-function signature="addLayout(QLayout*,int)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+
+ <modify-function signature="insertWidget(int,QWidget*,int,QFlags&lt;Qt::AlignmentFlag&gt;)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
+ </modify-function>
+ <modify-function signature="insertLayout(int,QLayout*,int)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
+ </modify-function>
+ <modify-function signature="insertItem(int,QLayoutItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
+ </modify-function>
+ <modify-function signature="addSpacerItem(QSpacerItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="insertSpacerItem(int,QSpacerItem*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QGridLayout">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qwidget-retrieveobjectname"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
+ <modify-function signature="itemAtPosition (int,int)const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp"
+ snippet="addownership-item-at"/>
+ </modify-function>
+ <modify-function signature="addWidget(QWidget*,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="4">
+ <rename to="alignment"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="addWidget(QWidget*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="6">
+ <rename to="alignment"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="addLayout(QLayout*,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="4">
+ <rename to="alignment"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="addLayout(QLayout*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="6">
+ <rename to="alignment"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="addItem(QLayoutItem*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="4">
+ <rename to="rowSpan"/>
+ </modify-argument>
+ <modify-argument index="5">
+ <rename to="columnSpan"/>
+ </modify-argument>
+ <modify-argument index="6">
+ <rename to="alignment"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
+ </modify-function>
+ <modify-function signature="getItemPosition(int,int*,int*,int*,int*)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject*"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="5">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qgridlayout-getitemposition"/>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QGraphicsView">
+ <extra-includes>
+ <include file-name="QPainterPath" location="global"/>
+ <include file-name="QVarLengthArray" location="global"/>
+ </extra-includes>
+ <enum-type name="CacheModeFlag" flags="CacheMode"/>
+ <enum-type name="DragMode"/>
+ <enum-type name="OptimizationFlag" flags="OptimizationFlags"/>
+ <enum-type name="ViewportAnchor"/>
+ <enum-type name="ViewportUpdateMode"/>
+ <modify-function signature="setScene(QGraphicsScene*)">
+ <modify-argument index="1" pyi-type="Optional[PySide6.QtWidgets.QGraphicsScene]">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="scene()const">
+ <inject-code position="end" file="../glue/qtwidgets.cpp" snippet="qgraphicsitem-scene-return-parenting"/>
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="itemAt(int,int)const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="itemAt(QPoint)const">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="drawBackground(QPainter*,QRectF)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawForeground(QPainter*,QRectF)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+
+ <!-- TODO: Support conversions on virtual function -->
+ <modify-function signature="drawItems(QPainter*,int,QGraphicsItem*[],const QStyleOptionGraphicsItem[])">
+ <modify-argument index="2">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="pysequencesize_int"/>
+ </conversion-rule>
+ </modify-argument>
+
+ <modify-argument index="3">
+ <replace-type modified-type="PySequence"/>
+ <conversion-rule class="native">
+ <insert-template name="qgraphicsitem_pysequence"/>
+ </conversion-rule>
+
+ <conversion-rule class="target">
+ <insert-template name="qgraphicsitem_pyobject"/>
+ </conversion-rule>
+ </modify-argument>
+
+ <modify-argument index="4">
+ <replace-type modified-type="PySequence"/>
+ <conversion-rule class="target">
+ <insert-template name="qstyleoptiongraphicsitem_pyobject"/>
+ </conversion-rule>
+
+ <conversion-rule class="native">
+ <insert-template name="pysequence_qstyleoptiongraphicsitem"/>
+ </conversion-rule>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QInputDialog">
+ <enum-type name="InputDialogOption"/>
+ <enum-type name="InputMode"/>
+
+ <modify-function signature="getInt(QWidget*,const QString&amp;,const QString&amp;,int,int,int,int,bool*,QFlags&lt;Qt::WindowType&gt;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[int, bool]"/>
+ <modify-argument index="8">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_arg,arg,arg,arg,arg,arg,arg,bool*,arg"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="getItem(QWidget*,const QString&amp;,const QString&amp;,const QStringList&amp;,int,bool,bool*,QFlags&lt;Qt::WindowType&gt;,QFlags&lt;Qt::InputMethodHint&gt;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[str, bool]"/>
+ <modify-argument index="7">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_arg,arg,arg,arg,arg,arg,bool*,arg"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="getMultiLineText(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,bool*,QFlags&lt;Qt::WindowType&gt;,QFlags&lt;Qt::InputMethodHint&gt;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[str, bool]"/>
+ <modify-argument index="5">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_arg,arg,arg,arg,bool*,arg,arg"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="getText(QWidget*,const QString&amp;,const QString&amp;,QLineEdit::EchoMode,const QString&amp;,bool*,QFlags&lt;Qt::WindowType&gt;,QFlags&lt;Qt::InputMethodHint&gt;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[str, bool]"/>
+ <modify-argument index="6">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_arg,arg,arg,arg,arg,bool*,arg"/>
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="getDouble(QWidget*,const QString&amp;,const QString&amp;,double,double,double,int,bool*,QFlags&lt;Qt::WindowType&gt;,double)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[float, bool]"/>
+ <modify-argument index="8">
+ <remove-default-expression/>
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_arg,arg,arg,arg,arg,arg,arg,bool*,arg,arg"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QGraphicsScene">
+ <extra-includes>
+ <include file-name="QVarLengthArray" location="global"/>
+ </extra-includes>
+ <enum-type name="ItemIndexMethod"/>
+ <enum-type name="SceneLayer" flags="SceneLayers"/>
+
+ <!-- Qt5: note: this was called 'obsolete'. Is that true? -->
+ <modify-function signature="drawItems(QPainter*,int,QGraphicsItem*[],const QStyleOptionGraphicsItem[],QWidget*)" remove="all"/>
+
+ <modify-function signature="createItemGroup(const QList&lt;QGraphicsItem*&gt;&amp;)">
+ <modify-argument index="1">
+ <parent index="return" action="add"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="destroyItemGroup(QGraphicsItemGroup*)">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsscene-destroyitemgroup"/>
+ </modify-function>
+
+ <modify-function signature="contextMenuEvent(QGraphicsSceneContextMenuEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dragEnterEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dragLeaveEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dragMoveEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawBackground(QPainter*,QRectF)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="drawForeground(QPainter*,QRectF)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="dropEvent(QGraphicsSceneDragDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="focusInEvent(QFocusEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="focusOutEvent(QFocusEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="helpEvent(QGraphicsSceneHelpEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="inputMethodEvent(QInputMethodEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="keyPressEvent(QKeyEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="keyReleaseEvent(QKeyEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mouseDoubleClickEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mouseMoveEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mousePressEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="mouseReleaseEvent(QGraphicsSceneMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="wheelEvent(QGraphicsSceneWheelEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="addItem(QGraphicsItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addEllipse(const QRectF&amp;,const QPen&amp;,const QBrush&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addEllipse(qreal,qreal,qreal,qreal,const QPen&amp;,const QBrush&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addLine(const QLineF&amp;,const QPen&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addLine(qreal,qreal,qreal,qreal,const QPen&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addPath(const QPainterPath&amp;,const QPen&amp;,const QBrush&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addPixmap(const QPixmap&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addPolygon(const QPolygonF&amp;,const QPen&amp;,const QBrush&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRect(const QRectF&amp;,const QPen&amp;,const QBrush&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRect(qreal,qreal,qreal,qreal,const QPen&amp;,const QBrush&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addText(const QString&amp;,const QFont&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addSimpleText(const QString&amp;,const QFont&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addWidget(QWidget*,QFlags&lt;Qt::WindowType&gt;)">
+ <!-- TODO: Add a keeper attribute to reference-count tag to do what this inject code do. -->
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsscene-addwidget"/>
+ </modify-function>
+
+ <modify-function signature="clear()">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsscene-clear"/>
+ </modify-function>
+
+ <modify-function signature="removeItem(QGraphicsItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setFocusItem(QGraphicsItem*,Qt::FocusReason)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QCalendarWidget">
+ <enum-type name="HorizontalHeaderFormat"/>
+ <enum-type name="SelectionMode"/>
+ <enum-type name="VerticalHeaderFormat"/>
+ <extra-includes>
+ <include file-name="QTextCharFormat" location="global"/>
+ </extra-includes>
+ <modify-function signature="paintCell(QPainter*,QRect,QDate)const">
+ <modify-argument invalidate-after-use="yes" index="1"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QTreeWidget">
+ <modify-function signature="mimeData(const QList&lt;QTreeWidgetItem*&gt;&amp;)const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemWidget(QTreeWidgetItem*,int,QWidget*)" allow-thread="yes">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="dropMimeData(QTreeWidgetItem*,int,const QMimeData*,Qt::DropAction)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="addTopLevelItem(QTreeWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addTopLevelItems(const QList&lt;QTreeWidgetItem*&gt; &amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addTopLevelItem(QTreeWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertTopLevelItem(int,QTreeWidgetItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertTopLevelItems(int,const QList&lt;QTreeWidgetItem*&gt; &amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setHeaderItem(QTreeWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeTopLevelItem(int)">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="clear()">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtreewidget-clear"/>
+ </modify-function>
+ <modify-function signature="removeItemWidget(QTreeWidgetItem*,int)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QAbstractItemDelegate">
+ <enum-type name="EndEditHint"/>
+ <modify-function signature="paint(QPainter*,QStyleOptionViewItem,QModelIndex)const">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="editorEvent(QEvent*,QAbstractItemModel*,QStyleOptionViewItem,QModelIndex)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="createEditor(QWidget*,QStyleOptionViewItem,QModelIndex)const">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QTableWidgetItem" >
+ <enum-type name="ItemType" python-type="IntEnum"/>
+ <modify-function signature="read(QDataStream&amp;)" allow-thread="yes">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="write(QDataStream&amp;)const" allow-thread="yes">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QListWidgetItem" >
+ <enum-type name="ItemType" python-type="IntEnum"/>
+ <modify-function signature="QListWidgetItem(const QString&amp;,QListWidget*,int)">
+ <modify-argument index="this">
+ <parent index="2" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QListWidgetItem(const QIcon&amp;,const QString&amp;,QListWidget*,int)">
+ <modify-argument index="this">
+ <parent index="3" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QListWidgetItem(QListWidget*,int)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="listWidget()const">
+ <modify-argument index="return">
+ <define-ownership owner="target"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="read(QDataStream&amp;)" allow-thread="yes">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="write(QDataStream&amp;)const" allow-thread="yes">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsTextItem">
+ <!-- a QObject so main-thread delete redundant -->
+ <extra-includes>
+ <include file-name="QTextCursor" location="global"/>
+ </extra-includes>
+ <modify-function signature="setDocument(QTextDocument*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QCompleter">
+ <enum-type name="CompletionMode"/>
+ <enum-type name="ModelSorting"/>
+ <modify-function signature="setModel(QAbstractItemModel*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setPopup(QAbstractItemView*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setWidget(QWidget*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QTreeWidgetItem" hash-function="qHash" parent-management="true">
+ <enum-type name="ChildIndicatorPolicy"/>
+ <enum-type name="ItemType" python-type="IntEnum"/>
+ <modify-function signature="read(QDataStream&amp;)" allow-thread="yes">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="write(QDataStream&amp;)const" allow-thread="yes">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="QTreeWidgetItem(QTreeWidget*,int)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QTreeWidgetItem(QTreeWidget*,const QStringList&amp;,int)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QTreeWidgetItem(QTreeWidget*,QTreeWidgetItem*,int)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QTreeWidgetItem(QTreeWidgetItem*,int)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QTreeWidgetItem(QTreeWidgetItem*,const QStringList &amp;,int)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="QTreeWidgetItem(QTreeWidgetItem*,QTreeWidgetItem*,int)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addChild(QTreeWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addChildren(const QList&lt;QTreeWidgetItem*&gt; &amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertChild(int,QTreeWidgetItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertChildren(int,const QList&lt;QTreeWidgetItem*&gt; &amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeChild(QTreeWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeChild(int)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeChildren()">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="parent()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qtreewidgetitem"/>
+ </modify-function>
+ <modify-function signature="treeWidget()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qtreewidgetitem"/>
+ </modify-function>
+
+ </object-type>
+ <object-type name="QListWidget">
+ <modify-function signature="mimeData(const QList&lt;QListWidgetItem*&gt;&amp;)const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemWidget(QListWidgetItem*,QWidget*)" allow-thread="yes">
+ <modify-argument index="2">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addItem(QListWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertItem(int,QListWidgetItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeItem(int)">
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="clear()">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlistwidget-clear"/>
+ </modify-function>
+ <modify-function signature="removeItemWidget(QListWidgetItem*)" allow-thread="yes"/>
+ </object-type>
+
+ <object-type name="QWidget" delete-in-main-thread="true" polymorphic-base="true">
+ <!-- see QWindow::nativeEvent(), QAbstractNativeEventFilter::nativeEventFilter() -->
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-addaction-glue"/>
+ <inject-code class="native" position="beginning">
+ #include &lt;QtWidgets/qapplication.h&gt;
+ </inject-code>
+ <modify-function signature="nativeEvent(const QByteArray &amp;,void*,qintptr*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion_variables"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code position="end">
+ <insert-template name="return_native_eventfilter"/>
+ </inject-code>
+ </modify-function>
+
+ <extra-includes>
+ <include file-name="QApplication" location="global"/>
+ <include file-name="QIcon" location="global"/>
+ <include file-name="QMessageBox" location="global"/>
+ <include file-name="QStyle" location="global"/>
+ </extra-includes>
+
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qwidget-retrieveobjectname"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-glue"/>
+
+ <enum-type name="RenderFlag" flags="RenderFlags"/>
+
+ <modify-function signature="setParent(QWidget*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ <modify-argument index="1" pyi-type="Optional[PySide6.QtWidgets.QWidget]"/>
+ </modify-function>
+
+ <modify-function signature="setParent(QWidget*,QFlags&lt;Qt::WindowType&gt;)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ <modify-argument index="1" pyi-type="Optional[PySide6.QtWidgets.QWidget]"/>
+ </modify-function>
+
+ <modify-function signature="parentWidget()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="nativeParentWidget()const"> <!-- Suppress return value heuristics -->
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="actionEvent(QActionEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="changeEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="closeEvent(QCloseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="contextMenuEvent(QContextMenuEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="dragEnterEvent(QDragEnterEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="dragLeaveEvent(QDragLeaveEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="dragMoveEvent(QDragMoveEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="dropEvent(QDropEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="enterEvent(QEnterEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="focusInEvent(QFocusEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="focusOutEvent(QFocusEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="hideEvent(QHideEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="inputMethodEvent(QInputMethodEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="keyPressEvent(QKeyEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="keyReleaseEvent(QKeyEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="leaveEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="mouseDoubleClickEvent(QMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="mouseMoveEvent(QMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="mousePressEvent(QMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="mouseReleaseEvent(QMouseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="moveEvent(QMoveEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="paintEvent(QPaintEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="resizeEvent(QResizeEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="showEvent(QShowEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="tabletEvent(QTabletEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="wheelEvent(QWheelEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes">
+ <rename to="event"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setStyle(QStyle*)">
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qwidget-setstyle"/>
+ </modify-function>
+ <modify-function signature="style()const">
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qwidget-style"/>
+ <modify-argument index="return">
+ <define-ownership owner="default"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="render(QPainter*,QPoint,QRegion,QFlags&lt;QWidget::RenderFlag&gt;)">
+ <modify-argument index="2">
+ <!-- Removed because the render(QPainter*) overload conflicts with the identical function in QGraphicsView -->
+ <remove-default-expression/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setFocusProxy(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addAction(const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addAction(const QIcon&amp;,const QString&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addAction(const QString&amp;,const QKeySequence&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addAction(const QIcon&amp;,const QString&amp;,const QKeySequence&amp;)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="addAction(const QString&amp;,const QObject*,const char*,Qt::ConnectionType)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="addAction(QString&amp;@text@,PyObject*@callable@)"
+ return-type="QAction*">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-addaction-2"/>
+ </add-function>
+
+ <modify-function signature="addAction(const QIcon&amp;,const QString&amp;,const QObject*,const char*,Qt::ConnectionType)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="addAction(QIcon&amp;@icon@,QString&amp;@text@,PyObject*@callable@)"
+ return-type="QAction*">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-addaction-3"/>
+ </add-function>
+
+ <modify-function signature="addAction(const QString&amp;,const QKeySequence&amp;,const QObject*,const char*,Qt::ConnectionType)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="addAction(QString&amp;@text@,QKeySequence&amp;@shortcut@,PyObject*@callable@)"
+ return-type="QAction*">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-addaction-3"/>
+ </add-function>
+
+ <modify-function signature="addAction(const QIcon&amp;,const QString&amp;,const QKeySequence&amp;,const QObject*,const char*,Qt::ConnectionType)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <add-function signature="addAction(QIcon&amp;@icon@,QString&amp;@text@,QKeySequence&amp;@shortcut@,PyObject*@callable@)"
+ return-type="QAction*">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-addaction-4"/>
+ </add-function>
+
+ <modify-function signature="insertAction(QAction*,QAction*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="setLayout(QLayout*)" allow-thread="yes">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-setlayout"/>
+ </modify-function>
+ <modify-function signature="raise()" rename="raise_"/>
+ <modify-function signature="setParent(QWidget*,QFlags&lt;Qt::WindowType>)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ <modify-argument index="1" pyi-type="Optional[PySide6.QtWidgets.QWidget]"/>
+ </modify-function>
+
+ <modify-function signature="window()const">
+ <modify-argument index="return">
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QMessageBox">
+ <enum-type name="ButtonRole"/>
+ <enum-type name="Icon"/>
+ <enum-type name="StandardButton" python-type="IntFlag" flags="StandardButtons"/>
+ <enum-type name="Option" flags="Options" since="6.6"/>
+ <modify-function signature="removeButton(QAbstractButton*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <extra-includes>
+ <include file-name="QPixmap" location="global"/>
+ </extra-includes>
+
+ <!-- FIXME PYSIDE-7: Remove deprecated overloads -->
+ <modify-function signature="critical(QWidget*,const QString&amp;,const QString&amp;,QFlags&lt;QMessageBox::StandardButton&gt;,QMessageBox::StandardButton)" allow-thread="yes"/>
+ <modify-function signature="critical(QWidget*,const QString&amp;,const QString&amp;,QMessageBox::StandardButton,QMessageBox::StandardButton)"
+ allow-thread="yes"/>
+ <modify-function signature="information(QWidget*,const QString&amp;,const QString&amp;,QFlags&lt;QMessageBox::StandardButton&gt;,QMessageBox::StandardButton)" allow-thread="yes"/>
+ <modify-function signature="information(QWidget*,const QString&amp;,const QString&amp;,QMessageBox::StandardButton,QMessageBox::StandardButton)"
+ allow-thread="yes"/>
+ <modify-function signature="question(QWidget*,const QString&amp;,const QString&amp;,QFlags&lt;QMessageBox::StandardButton&gt;,QMessageBox::StandardButton)" allow-thread="yes"/>
+ <modify-function signature="question(QWidget*,const QString&amp;,const QString&amp;,QMessageBox::StandardButton,QMessageBox::StandardButton)"
+ allow-thread="yes"/>
+ <modify-function signature="warning(QWidget*,const QString&amp;,const QString&amp;,QFlags&lt;QMessageBox::StandardButton&gt;,QMessageBox::StandardButton)" allow-thread="yes"/>
+ <modify-function signature="warning(QWidget*,const QString&amp;,const QString&amp;,QMessageBox::StandardButton,QMessageBox::StandardButton)"
+ allow-thread="yes"/>
+ <modify-function signature="QMessageBox(const QString&amp;,const QString&amp;,QMessageBox::Icon,int,int,int,QWidget*,QFlags&lt;Qt::WindowType&gt;)" remove="all"/>
+ <modify-function signature="critical(QWidget*,const QString&amp;,const QString&amp;,int,int,int)" remove="all"/>
+ <modify-function signature="critical(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,int,int)" remove="all"/>
+ <modify-function signature="information(QWidget*,const QString&amp;,const QString&amp;,int,int,int)" remove="all"/>
+ <modify-function signature="information(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,int,int)" remove="all"/>
+ <modify-function signature="question(QWidget*,const QString&amp;,const QString&amp;,int,int,int)" remove="all"/>
+ <modify-function signature="question(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,int,int)" remove="all"/>
+ <modify-function signature="warning(QWidget*,const QString&amp;,const QString&amp;,int,int,int)" remove="all"/>
+ <modify-function signature="warning(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,int,int)" remove="all"/>
+ <modify-function signature="about(QWidget*,const QString&amp;,const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="aboutQt(QWidget*,const QString&amp;)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QAbstractSpinBox">
+ <enum-type name="ButtonSymbols"/>
+ <enum-type name="CorrectionMode"/>
+ <enum-type name="StepEnabledFlag" flags="StepEnabled"/>
+ <enum-type name="StepType"/>
+ <modify-function signature="setLineEdit(QLineEdit*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="fixup(QString &amp;)const">
+ <modify-argument index="return">
+ <replace-type modified-type="QString"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qstring-return"/>
+ </modify-function>
+ <modify-function signature="validate(QString &amp;,int &amp;)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="validator_conversionrule"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code class="target" position="end">
+ <insert-template name="return_tuple_QValidator_QString_int"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QTabWidget">
+ <enum-type name="TabPosition"/>
+ <enum-type name="TabShape"/>
+ <modify-function signature="addTab(QWidget*,const QString&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addTab(QWidget*,const QIcon&amp;,const QString&amp;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertTab(int,QWidget*,const QIcon&amp;,const QString&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertTab(int,QWidget*,const QString&amp;)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setCornerWidget(QWidget*,Qt::Corner)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setTabBar(QTabBar*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <!-- This function need be re-implemented in inject code -->
+ <modify-function signature="removeTab(int)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtabwidget-removetab"/>
+ </modify-function>
+ <modify-function signature="clear()">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtabwidget-clear"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QDateTimeEdit">
+ <enum-type name="Section" flags="Sections"/>
+ <modify-function signature="setCalendarWidget(QCalendarWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QSlider">
+ <enum-type name="TickPosition"/>
+ </object-type>
+ <object-type name="QProgressDialog">
+ <modify-function signature="setBar(QProgressBar*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setLabel(QLabel*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setCancelButton(QPushButton*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QLabel">
+ <modify-function signature="setBuddy(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="pixmap(Qt::ReturnByValueConstant)const" remove="all"/>
+ <modify-function signature="picture(Qt::ReturnByValueConstant)const" remove="all"/>
+ <modify-function signature="setMovie(QMovie *)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QFileDialog">
+ <enum-type name="AcceptMode"/>
+ <enum-type name="DialogLabel"/>
+ <enum-type name="FileMode"/>
+ <enum-type name="Option" flags="Options"/>
+ <enum-type name="ViewMode"/>
+ <extra-includes>
+ <include file-name="QUrl" location="global"/>
+ <include file-name="QAbstractProxyModel" location="global"/>
+ </extra-includes>
+ <modify-function signature="setIconProvider(QAbstractFileIconProvider*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemDelegate(QAbstractItemDelegate*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+
+ <modify-function signature="getExistingDirectory(QWidget*,const QString&amp;,const QString&amp;,QFlags&lt;QFileDialog::Option>)" allow-thread="yes"/>
+ <modify-function signature="getExistingDirectoryUrl(QWidget*,const QString&amp;,const QUrl&amp;,QFlags&lt;QFileDialog::Option>,const QStringList&amp;)" allow-thread="yes"/>
+ <modify-function signature="getOpenFileName(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[str, str]">
+ <replace-type modified-type="(fileName, selectedFilter)"/>
+ </modify-argument>
+ <modify-argument index="5">
+ <replace-type modified-type="QString"/>
+ <replace-default-expression with="QString()"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
+ </modify-function>
+ <modify-function signature="getOpenFileNames(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[List[str], str]">
+ <replace-type modified-type="(fileNames, selectedFilter)"/>
+ </modify-argument>
+ <modify-argument index="5">
+ <replace-type modified-type="QString"/>
+ <replace-default-expression with="QString()"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
+ </modify-function>
+
+ <modify-function signature="getOpenFileUrl(QWidget*,const QString&amp;,const QUrl&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;,const QStringList&amp;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtCore.QUrl, str]">
+ <replace-type modified-type="(fileName, selectedFilter)"/>
+ </modify-argument>
+ <modify-argument index="5">
+ <replace-type modified-type="QString"/>
+ <replace-default-expression with="QString()"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
+ </modify-function>
+
+ <modify-function signature="getOpenFileUrls(QWidget*,const QString&amp;,const QUrl&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;,const QStringList&amp;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[List[PySide6.QtCore.QUrl], str]">
+ <replace-type modified-type="(fileName, selectedFilter)"/>
+ </modify-argument>
+ <modify-argument index="5">
+ <replace-type modified-type="QString"/>
+ <replace-default-expression with="QString()"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
+ </modify-function>
+
+ <modify-function signature="getSaveFileName(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[str, str]">
+ <replace-type modified-type="(fileName, selectedFilter)"/>
+ </modify-argument>
+ <modify-argument index="5">
+ <replace-type modified-type="QString"/>
+ <replace-default-expression with="QString()"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
+ </modify-function>
+
+ <modify-function signature="getSaveFileUrl(QWidget*,const QString&amp;,const QUrl&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;,const QStringList&amp;)" allow-thread="yes">
+ <modify-argument index="return" pyi-type="Tuple[PySide6.QtCore.QUrl, str]">
+ <replace-type modified-type="(fileName, selectedFilter)"/>
+ </modify-argument>
+ <modify-argument index="5">
+ <replace-type modified-type="QString"/>
+ <replace-default-expression with="QString()"/>
+ </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
+ </modify-function>
+
+ </object-type>
+
+ <object-type name="QErrorMessage"/>
+ <object-type name="QTabBar">
+ <extra-includes>
+ <include file-name="QIcon" location="global"/>
+ </extra-includes>
+ <enum-type name="Shape"/>
+ <enum-type name="SelectionBehavior"/>
+ <enum-type name="ButtonPosition"/>
+ </object-type>
+ <object-type name="QRadioButton"/>
+ <object-type name="QScrollBar"/>
+ <object-type name="QAbstractScrollArea">
+ <enum-type name="SizeAdjustPolicy"/>
+ <modify-function signature="setViewport(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addScrollBarWidget(QWidget*,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setCornerWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setHorizontalScrollBar(QScrollBar*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setVerticalScrollBar(QScrollBar*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setViewport(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setupViewport(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="viewportEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QRubberBand">
+ <enum-type name="Shape"/>
+ <modify-function signature="QRubberBand(QRubberBand::Shape,QWidget*)">
+ <modify-argument index="this">
+ <parent index="2" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <rename to="parent"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QTableWidget">
+ <modify-function signature="mimeData(const QList&lt;QTableWidgetItem*&gt;&amp;)const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setHorizontalHeaderItem(int,QTableWidgetItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItem(int,int,QTableWidgetItem*)">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeHorizontalHeaderItem(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeVerticalHeaderItem(int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="takeItem(int,int)">
+ <modify-argument index="return">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemPrototype(const QTableWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setVerticalHeaderItem(int,QTableWidgetItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setCellWidget(int,int,QWidget*)" allow-thread="yes">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeCellWidget(int,int)" allow-thread="yes"/>
+ <modify-function signature="setCurrentItem(QTableWidgetItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setCurrentItem(QTableWidgetItem*,QFlags&lt;QItemSelectionModel::SelectionFlag&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QSplitter">
+ <modify-function signature="getRange(int,int*,int*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_args,number*,number*">
+ <replace from="$TYPE" to="int"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="addWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertWidget(int,QWidget*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QGroupBox">
+ <modify-function signature="clicked(bool)" allow-thread="yes"/>
+ </object-type>
+ <object-type name="QStackedWidget">
+ <modify-function signature="addWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertWidget(int,QWidget*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setCurrentWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QSplitterHandle"/>
+ <object-type name="QDial"/>
+ <object-type name="QKeySequenceEdit"/>
+ <object-type name="QLineEdit">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-addaction-glue"/>
+ <enum-type name="ActionPosition"/>
+ <enum-type name="EchoMode"/>
+ <modify-function signature="setCompleter(QCompleter*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setValidator(const QValidator*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="del()" rename="del_"/>
+
+ <add-function signature="addAction(QAction*)">
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlineedit-addaction"/>
+ </add-function>
+
+ </object-type>
+ <object-type name="QLCDNumber">
+ <enum-type name="Mode"/>
+ <enum-type name="SegmentStyle"/>
+ </object-type>
+ <object-type name="QSplashScreen">
+ <!-- Override QWidget.painter -->
+ <modify-function signature="repaint()" remove="all"/>
+ <modify-function signature="drawContents(QPainter*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QDockWidget">
+ <enum-type name="DockWidgetFeature" flags="DockWidgetFeatures"/>
+ <modify-function signature="setTitleBarWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QFrame">
+ <enum-type name="Shadow" python-type="IntEnum"/>
+ <enum-type name="Shape" python-type="IntEnum"/>
+ <enum-type name="StyleMask"/>
+ </object-type>
+ <object-type name="QSpinBox"/>
+ <object-type name="QTextBrowser"/>
+ <object-type name="QDoubleSpinBox"/>
+ <object-type name="QButtonGroup">
+ <modify-function signature="addButton(QAbstractButton*,int)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ <no-null-pointer/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeButton(QAbstractButton*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ <no-null-pointer/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setId(QAbstractButton*,int)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QToolBar">
+ <modify-function signature="addSeparator()">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addWidget(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertWidget(QAction*,QWidget*)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertSeparator(QAction*)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="clear()">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtoolbar-clear"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QComboBox">
+ <enum-type name="InsertPolicy"/>
+ <enum-type name="SizeAdjustPolicy"/>
+ <modify-function signature="setCompleter(QCompleter*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setValidator(const QValidator*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItemDelegate(QAbstractItemDelegate*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ <no-null-pointer/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setView(QAbstractItemView*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setLineEdit(QLineEdit*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setModel(QAbstractItemModel*)">
+ <modify-argument index="1">
+ <no-null-pointer/>
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QTextEdit">
+ <enum-type name="AutoFormattingFlag" flags="AutoFormatting"/>
+ <enum-type name="LineWrapMode"/>
+ <value-type name="ExtraSelection" >
+ <include file-name="QTextEdit" location="global"/>
+ </value-type>
+ <extra-includes>
+ <include file-name="QTextCursor" location="global"/>
+ </extra-includes>
+ <modify-function signature="createMimeDataFromSelection() const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setDocument(QTextDocument*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertFromMimeData(const QMimeData*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="print(QPagedPaintDevice*)const" rename="print_"/>
+ </object-type>
+
+ <object-type name="QApplication">
+ <extra-includes>
+ <include file-name="QBasicTimer" location="global"/>
+ <include file-name="QFont" location="global"/>
+ <include file-name="QFontMetrics" location="global"/>
+ <include file-name="QPalette" location="global"/>
+ <include file-name="QIcon" location="global"/>
+ <include file-name="QLocale" location="global"/>
+ <include file-name="QStyle" location="global"/>
+ <include file-name="pysideqapp.h" location="global"/>
+ <include file-name="pysidecleanup.h" location="global"/>
+ </extra-includes>
+ <modify-function signature="QApplication(int&amp;,char**,int)" access="private"/>
+ <add-function signature="QApplication(QStringList)">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qapplication-1"/>
+ </add-function>
+ <add-function signature="QApplication()">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qapplication-2"/>
+ </add-function>
+ <modify-function signature="setStyle(QStyle*)">
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qapplication-setStyle"/>
+ </modify-function>
+ <modify-function signature="exec()" allow-thread="yes"/>
+ <add-function signature="exec_()" return-type="int">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qapplication-exec"/>
+ </add-function>
+ <modify-function signature="notify(QObject*,QEvent*)" allow-thread="yes"/>
+ <modify-function signature="alert(QWidget*,int)" allow-thread="yes"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qapplication-init"/>
+ </object-type>
+
+ <object-type name="QCommandLinkButton"/>
+ <!-- FIXME PYSIDE7: Move to QtGui -->
+ <object-type name="QFileSystemModel" polymorphic-id-expression="qobject_cast&lt;QFileSystemModel*&gt;(%B)">
+ <enum-type name="Roles" python-type="IntEnum"/>
+ <enum-type name="Option" flags="Options"/>
+ <modify-function signature="setIconProvider(QAbstractFileIconProvider*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QFormLayout">
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp"
+ snippet="qwidget-retrieveobjectname"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
+
+ <enum-type name="FieldGrowthPolicy"/>
+ <enum-type name="ItemRole"/>
+ <enum-type name="RowWrapPolicy"/>
+
+ <value-type name="TakeRowResult">
+ <include file-name="QFormLayout" location="global"/>
+ </value-type>
+
+ <modify-function signature="getLayoutPosition(QLayout*,int*,QFormLayout::ItemRole*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qformlayout-fix-args" />
+ </modify-function>
+ <modify-function signature="getWidgetPosition(QWidget*,int*,QFormLayout::ItemRole*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qformlayout-fix-args" />
+ </modify-function>
+ <modify-function signature="getItemPosition(int,int*,QFormLayout::ItemRole*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qformlayout-fix-args" />
+ </modify-function>
+
+ <modify-function signature="addRow(QWidget*,QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRow(QLayout*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRow(QWidget*,QLayout*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRow(QWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRow(QString,QLayout*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addRow(QString,QWidget*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRow(int,QLayout*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRow(int,QWidget*,QLayout*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRow(int,QWidget*,QWidget*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRow(int,QWidget*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRow(int,QString,QLayout*)">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertRow(int,QString,QWidget*)">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setLayout(int,QFormLayout::ItemRole,QLayout*)">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setWidget(int,QFormLayout::ItemRole,QWidget*)">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setItem(int,QFormLayout::ItemRole,QLayoutItem*)">
+ <modify-argument index="3">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsGridLayout" >
+ <modify-function signature="addItem(QGraphicsLayoutItem*,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="addItem(QGraphicsLayoutItem*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAlignment(QGraphicsLayoutItem*,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsLayout">
+ <modify-function signature="getContentsMargins(qreal*,qreal*,qreal*,qreal*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ <inject-code class="native" position="end">
+ <insert-template name="fix_native_return_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="widgetEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsLayoutItem" copyable="false" qt-register-metatype="base"
+ parent-management="true">
+ <modify-function signature="getContentsMargins(qreal*,qreal*,qreal*,qreal*)const">
+ <modify-argument index="0">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ <inject-code class="native" position="end">
+ <insert-template name="fix_native_return_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="setParentLayoutItem(QGraphicsLayoutItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsLinearLayout" >
+ <modify-function signature="addItem(QGraphicsLayoutItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertItem(int,QGraphicsLayoutItem*)">
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="removeItem(QGraphicsLayoutItem*)">
+ <modify-argument index="1">
+ <parent index="this" action="remove"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setAlignment(QGraphicsLayoutItem*,QFlags&lt;Qt::AlignmentFlag&gt;)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setStretchFactor(QGraphicsLayoutItem*,int)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QGraphicsProxyWidget">
+ <modify-function signature="QGraphicsProxyWidget(QGraphicsItem*,QFlags&lt;Qt::WindowType&gt;)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="createProxyForChildWidget(QWidget*)">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="newProxyWidget(const QWidget*)">
+ <modify-argument index="return">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setWidget(QWidget*)" allow-thread="yes">
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsproxywidget-setwidget"/>
+ </modify-function>
+ </object-type>
+ <!-- a QObject so main-thread delete redundant -->
+ <object-type name="QGraphicsWidget">
+ <modify-function signature="getContentsMargins(qreal*,qreal*,qreal*,qreal*)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="getWindowFrameMargins(qreal*,qreal*,qreal*,qreal*)const">
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ </modify-argument>
+ <modify-argument index="1">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+
+ <inject-code class="target" position="beginning">
+ <insert-template name="fix_number*,number*,number*,number*">
+ <replace from="$TYPE" to="qreal"/>
+ </insert-template>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="setLayout(QGraphicsLayout*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="changeEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="closeEvent(QCloseEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="grabKeyboardEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="grabMouseEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="hideEvent(QHideEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="moveEvent(QGraphicsSceneMoveEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="paintWindowFrame(QPainter*,const QStyleOptionGraphicsItem*,QWidget*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="resizeEvent(QGraphicsSceneResizeEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="showEvent(QShowEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="ungrabKeyboardEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="ungrabMouseEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="windowFrameEvent(QEvent*)">
+ <modify-argument index="1" invalidate-after-use="yes"/>
+ </modify-function>
+ <modify-function signature="setStyle(QStyle*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setTabOrder(QGraphicsWidget*,QGraphicsWidget*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QPlainTextDocumentLayout"/>
+ <object-type name="QPlainTextEdit">
+ <enum-type name="LineWrapMode"/>
+ <modify-function signature="createMimeDataFromSelection() const">
+ <modify-argument index="return">
+ <define-ownership class="native" owner="c++"/>
+ <define-ownership class="target" owner="default"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setDocument(QTextDocument*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="insertFromMimeData(const QMimeData*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="print(QPagedPaintDevice*)const" rename="print_"/>
+ </object-type>
+ <object-type name="QStyledItemDelegate">
+ <modify-function signature="setItemEditorFactory(QItemEditorFactory*)">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setEditorData(QWidget*,QModelIndex)const">
+ <modify-argument index="1">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="setModelData(QWidget*,QAbstractItemModel*,QModelIndex)const">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <object-type name="QGesture" since="4.6">
+ <enum-type name="GestureCancelPolicy"/>
+ </object-type>
+ <object-type name="QGestureRecognizer" since="4.6">
+ <enum-type name="ResultFlag" flags="Result"/>
+ <modify-function signature="create(QObject*)">
+ <modify-argument index="return">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="registerRecognizer(QGestureRecognizer*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QTapAndHoldGesture" since="4.6"/>
+ <object-type name="QTapGesture" since="4.6"/>
+ <object-type name="QGraphicsAnchor" since="4.6"/>
+ <object-type name="QGraphicsAnchorLayout" since="4.6"/>
+ <object-type name="QGraphicsBlurEffect" since="4.6">
+ <enum-type name="BlurHint" flags="BlurHints"/>
+ </object-type>
+ <object-type name="QGraphicsColorizeEffect" since="4.6"/>
+ <object-type name="QGraphicsDropShadowEffect" since="4.6"/>
+
+ <object-type name="QGraphicsEffect" since="4.6">
+ <enum-type name="ChangeFlag" flags="ChangeFlags"/>
+ <enum-type name="PixmapPadMode"/>
+ </object-type>
+
+ <object-type name="QGraphicsObject" since="4.6" default-superclass="QGraphicsItem"/>
+ <object-type name="QGraphicsOpacityEffect" since="4.6"/>
+ <object-type name="QGraphicsRotation" since="4.6"/>
+ <object-type name="QGraphicsScale" since="4.6"/>
+ <object-type name="QGraphicsTransform" since="4.6"/>
+ <object-type name="QPanGesture" since="4.6"/>
+ <object-type name="QPinchGesture" since="4.6">
+ <enum-type name="ChangeFlag" flags="ChangeFlags"/>
+ </object-type>
+
+ <object-type name="QRhiWidget" since="6.7">
+ <enum-type name="Api"/>
+ <enum-type name="TextureFormat"/>
+ </object-type>
+
+ <object-type name="QSwipeGesture" since="4.6">
+ <enum-type name="SwipeDirection"/>
+ </object-type>
+
+ <value-type name="QTileRules" since="4.6"/>
+
+ <object-type name="QScroller">
+ <enum-type name="State"/>
+ <enum-type name="ScrollerGestureType"/>
+ <enum-type name="Input"/>
+ </object-type>
+ <value-type name="QScrollerProperties">
+ <enum-type name="OvershootPolicy"/>
+ <enum-type name="FrameRates"/>
+ <enum-type name="ScrollMetric"/>
+ </value-type>
+
+ <object-type name="QSizeGrip"/>
+
+ <object-type name="QSystemTrayIcon">
+ <enum-type name="ActivationReason"/>
+ <enum-type name="MessageIcon"/>
+ <modify-function signature="setContextMenu(QMenu*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <!-- The above entries may be present in the system or not. Keep this section organized. -->
+
+ <suppress-warning text="signal 'activated' in class 'QCompleter' is overloaded."/>
+ <suppress-warning text="signal 'highlighted' in class 'QCompleter' is overloaded."/>
+</typesystem>
diff --git a/sources/pyside6/PySide6/QtXml/CMakeLists.txt b/sources/pyside6/PySide6/QtXml/CMakeLists.txt
new file mode 100644
index 000000000..b0e4630dd
--- /dev/null
+++ b/sources/pyside6/PySide6/QtXml/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(QtXml)
+
+set(QtXml_SRC
+${QtXml_GEN_DIR}/qdomattr_wrapper.cpp
+${QtXml_GEN_DIR}/qdomcdatasection_wrapper.cpp
+${QtXml_GEN_DIR}/qdomcharacterdata_wrapper.cpp
+${QtXml_GEN_DIR}/qdomcomment_wrapper.cpp
+${QtXml_GEN_DIR}/qdomdocument_wrapper.cpp
+${QtXml_GEN_DIR}/qdomdocument_parseresult_wrapper.cpp
+${QtXml_GEN_DIR}/qdomdocumentfragment_wrapper.cpp
+${QtXml_GEN_DIR}/qdomdocumenttype_wrapper.cpp
+${QtXml_GEN_DIR}/qdomelement_wrapper.cpp
+${QtXml_GEN_DIR}/qdomentity_wrapper.cpp
+${QtXml_GEN_DIR}/qdomentityreference_wrapper.cpp
+${QtXml_GEN_DIR}/qdomimplementation_wrapper.cpp
+${QtXml_GEN_DIR}/qdomnamednodemap_wrapper.cpp
+${QtXml_GEN_DIR}/qdomnode_wrapper.cpp
+${QtXml_GEN_DIR}/qdomnodelist_wrapper.cpp
+${QtXml_GEN_DIR}/qdomnotation_wrapper.cpp
+${QtXml_GEN_DIR}/qdomprocessinginstruction_wrapper.cpp
+${QtXml_GEN_DIR}/qdomtext_wrapper.cpp
+# module is always needed
+${QtXml_GEN_DIR}/qtxml_module_wrapper.cpp
+)
+
+set(QtXml_include_dirs ${QtXml_SOURCE_DIR}
+ ${QtXml_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Xml_INCLUDE_DIRS}
+ ${libpyside_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ )
+set(QtXml_libraries pyside6
+ ${Qt${QT_MAJOR_VERSION}Xml_LIBRARIES})
+set(QtXml_deps QtCore)
+
+create_pyside_module(NAME QtXml
+ INCLUDE_DIRS QtXml_include_dirs
+ LIBRARIES QtXml_libraries
+ DEPS QtXml_deps
+ TYPESYSTEM_PATH QtXml_SOURCE_DIR
+ SOURCES QtXml_SRC)
diff --git a/sources/pyside6/PySide6/QtXml/typesystem_xml.xml b/sources/pyside6/PySide6/QtXml/typesystem_xml.xml
new file mode 100644
index 000000000..3661a67bf
--- /dev/null
+++ b/sources/pyside6/PySide6/QtXml/typesystem_xml.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem package="PySide6.QtXml"
+ namespace-begin="QT_BEGIN_NAMESPACE" namespace-end="QT_END_NAMESPACE">
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
+ <load-typesystem name="templates/core_common.xml" generate="no" />
+
+ <rejection class="QDomNode" field-name="impl"/>
+
+ <value-type name="QDomAttr"/>
+ <value-type name="QDomCDATASection"/>
+ <value-type name="QDomCharacterData"/>
+ <value-type name="QDomComment"/>
+
+
+ <value-type name="QDomDocument">
+ <enum-type name="ParseOption" flags="ParseOptions" since="6.5"/>
+ <!-- will be replaced in inject code -->
+
+ <value-type name="ParseResult"/>
+
+ <modify-function signature="setContent(const QByteArray&amp;,bool,QString*,int*,int*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="5">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, str, int, int]">
+ <replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
+ </modify-function>
+ <modify-function signature="setContent(const QString&amp;,bool,QString*,int*,int*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="5">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, str, int, int]">
+ <replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
+ </modify-function>
+ <modify-function signature="setContent(QIODevice*,bool,QString*,int*,int*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="5">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, str, int, int]">
+ <replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
+ </modify-function>
+ <modify-function signature="setContent(const QByteArray&amp;,QString*,int*,int*)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, str, int, int]">
+ <replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
+ </modify-function>
+ <modify-function signature="setContent(QIODevice*,QString*,int*,int*)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, str, int, int]">
+ <replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
+ </modify-function>
+ <modify-function signature="setContent(const QString&amp;,QString*,int*,int*)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="3">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ <remove-default-expression/>
+ </modify-argument>
+ <modify-argument index="return" pyi-type="Tuple[bool, str, int, int]">
+ <replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
+ </modify-function>
+ </value-type>
+
+ <value-type name="QDomDocumentFragment"/>
+ <value-type name="QDomDocumentType"/>
+ <value-type name="QDomEntity"/>
+ <value-type name="QDomEntityReference"/>
+ <value-type name="QDomImplementation">
+ <enum-type name="InvalidDataPolicy"/>
+ </value-type>
+
+ <value-type name="QDomNamedNodeMap"/>
+
+ <value-type name="QDomNode">
+ <enum-type name="EncodingPolicy"/>
+ <enum-type name="NodeType"/>
+ <modify-function signature="save(QTextStream&amp;,int,QDomNode::EncodingPolicy)const" allow-thread="yes"/>
+ </value-type>
+
+ <value-type name="QDomNodeList"/>
+ <value-type name="QDomNotation"/>
+ <value-type name="QDomProcessingInstruction"/>
+
+ <value-type name="QDomText"/>
+
+ <value-type name="QDomElement">
+ <!-- PYSIDE-1372
+ We will leave only one for int, and one for float since Python
+ doesn't have other variations on the primitive types.
+ Only 'qlonglong' and 'double' will be available from the Qt API.
+ TODO: This will require a better review of the shiboken primitive
+ types converters, since this situation might happen on
+ different signatures.
+ -->
+ <modify-function signature="setAttribute(const QString&amp;, uint)" remove="all"/>
+ <modify-function signature="setAttribute(const QString&amp;, float)" remove="all"/>
+ <modify-function signature="setAttribute(const QString&amp;, int)" remove="all"/>
+ <modify-function signature="setAttribute(const QString&amp;, qulonglong)" remove="all"/>
+ </value-type>
+
+</typesystem>
+
diff --git a/sources/pyside6/PySide6/__feature__.pyi.in b/sources/pyside6/PySide6/__feature__.pyi.in
new file mode 100644
index 000000000..c9a8907d1
--- /dev/null
+++ b/sources/pyside6/PySide6/__feature__.pyi.in
@@ -0,0 +1,10 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+snake_case = 0x01
+true_property = 0x02
+
+all_feature_names = [
+ "snake_case",
+ "true_property",
+]
diff --git a/sources/pyside6/PySide6/__init__.py.in b/sources/pyside6/PySide6/__init__.py.in
new file mode 100644
index 000000000..d0a4ecc37
--- /dev/null
+++ b/sources/pyside6/PySide6/__init__.py.in
@@ -0,0 +1,124 @@
+import os
+import sys
+from pathlib import Path
+from textwrap import dedent
+
+# __all__ is also corrected below.
+__all__ = list("Qt" + body for body in
+ "@all_module_shortnames@"
+ .split(";"))
+__version__ = "@FINAL_PACKAGE_VERSION@"
+__version_info__ = (@BINDING_API_MAJOR_VERSION@, @BINDING_API_MINOR_VERSION@, @BINDING_API_MICRO_VERSION@, "@BINDING_API_PRE_RELEASE_VERSION_TYPE@", "@BINDING_API_PRE_RELEASE_VERSION@")
+
+
+def _additional_dll_directories(package_dir):
+ # Find shiboken6 relative to the package directory.
+ root = Path(package_dir).parent
+ # Check for a flat .zip as deployed by cx_free(PYSIDE-1257)
+ if root.suffix == '.zip':
+ return []
+ shiboken6 = root / 'shiboken6'
+ if shiboken6.is_dir(): # Standard case, only shiboken6 is needed
+ return [shiboken6]
+ # The below code is for the build process when generate_pyi.py
+ # is executed in the build directory. We need libpyside and Qt in addition.
+ shiboken6 = Path(root).parent / 'shiboken6' / 'libshiboken'
+ if not shiboken6.is_dir():
+ raise ImportError(str(shiboken6) + ' does not exist')
+ result = [shiboken6, root / 'libpyside']
+ libpysideqml = root / 'libpysideqml'
+ if libpysideqml.is_dir():
+ result.append(libpysideqml)
+ for path in os.environ.get('PATH').split(';'):
+ if path:
+ if (Path(path) / 'qmake.exe').exists():
+ result.append(path)
+ break
+ return result
+
+
+def _setupQtDirectories():
+ # On Windows we need to explicitly import the shiboken6 module so
+ # that the libshiboken.dll dependency is loaded by the time a
+ # Qt module is imported. Otherwise due to PATH not containing
+ # the shiboken6 module path, the Qt module import would fail
+ # due to the missing libshiboken dll.
+ # In addition, as of Python 3.8, the shiboken package directory
+ # must be added to the DLL search paths so that shiboken6.dll
+ # is found.
+ # We need to do the same on Linux and macOS, because we do not
+ # embed rpaths into the PySide6 libraries that would point to
+ # the libshiboken library location. Importing the module
+ # loads the libraries into the process memory beforehand, and
+ # thus takes care of it for us.
+
+ pyside_package_dir = Path(__file__).parent.resolve()
+
+ if sys.platform == 'win32' and sys.version_info[0] == 3 and sys.version_info[1] >= 8:
+ for dir in _additional_dll_directories(pyside_package_dir):
+ os.add_dll_directory(os.fspath(dir))
+
+ try:
+ # PYSIDE-1497: we use the build dir or install dir or site-packages, whatever the path
+ # setting dictates. There is no longer a difference in path structure.
+ from shiboken6 import Shiboken
+ except Exception:
+ paths = ', '.join(sys.path)
+ print(f"PySide6/__init__.py: Unable to import Shiboken from {paths}",
+ file=sys.stderr)
+ raise
+
+ if sys.platform == 'win32':
+ # PATH has to contain the package directory, otherwise plugins
+ # won't be able to find their required Qt libraries (e.g. the
+ # svg image plugin won't find Qt5Svg.dll).
+ os.environ['PATH'] = os.fspath(pyside_package_dir) + os.pathsep + os.environ['PATH']
+
+ # On Windows, add the PySide6\openssl folder (created by setup.py's
+ # --openssl option) to the PATH so that the SSL DLLs can be found
+ # when Qt tries to dynamically load them. Tell Qt to load them and
+ # then reset the PATH.
+ openssl_dir = pyside_package_dir / 'openssl'
+ if openssl_dir.exists():
+ path = os.environ['PATH']
+ try:
+ os.environ['PATH'] = os.fspath(openssl_dir) + os.pathsep + path
+ try:
+ from . import QtNetwork
+ except ImportError:
+ pass
+ else:
+ QtNetwork.QSslSocket.supportsSsl()
+ finally:
+ os.environ['PATH'] = path
+
+
+def _find_all_qt_modules():
+ # Since the wheel split, the __all__ variable cannot be computed statically,
+ # because we don't know all modules in advance.
+
+ # Instead, we look into the file system and quickly build a list of all
+ # existing .pyi files, because importing is not desired and also impossible during import.
+ # By using the initially created list, we can keep some order intact.
+ location = Path(__file__).resolve().parent
+
+ # Note: We should _not_ call this function while still building, but use the existing value!
+ in_build = Path("@CMAKE_BINARY_DIR@") in location.parents
+
+ if in_build:
+ return __all__
+
+ files = os.listdir(location)
+ unordered = set(name[:-4] for name in files if name.startswith("Qt") and name.endswith(".pyi"))
+ ordered_part = __all__
+ result = []
+ for name in ordered_part:
+ if name in unordered:
+ result.append(name)
+ unordered.remove(name)
+ result.extend(unordered)
+ return result
+
+
+__all__ = _find_all_qt_modules()
+_setupQtDirectories()
diff --git a/sources/pyside6/PySide6/_config.py.in b/sources/pyside6/PySide6/_config.py.in
new file mode 100644
index 000000000..27ee0789b
--- /dev/null
+++ b/sources/pyside6/PySide6/_config.py.in
@@ -0,0 +1,17 @@
+built_modules = list(name for name in
+ "@all_module_shortnames@"
+ .split(";"))
+
+shiboken_library_soversion = str(@SHIBOKEN_SO_VERSION@)
+pyside_library_soversion = str(@PYSIDE_SO_VERSION@)
+
+version = "@FINAL_PACKAGE_VERSION@"
+version_info = (@BINDING_API_MAJOR_VERSION@, @BINDING_API_MINOR_VERSION@, @BINDING_API_MICRO_VERSION@, "@BINDING_API_PRE_RELEASE_VERSION_TYPE@", "@BINDING_API_PRE_RELEASE_VERSION@")
+
+@PACKAGE_BUILD_DATE@
+@PACKAGE_BUILD_COMMIT_DATE@
+@PACKAGE_BUILD_COMMIT_HASH@
+@PACKAGE_BUILD_COMMIT_HASH_DESCRIBED@
+@PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
+@PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT@
+@QT_MACOS_DEPLOYMENT_TARGET@
diff --git a/sources/pyside6/PySide6/doc/qtqml_functions.rst b/sources/pyside6/PySide6/doc/qtqml_functions.rst
new file mode 100644
index 000000000..31801b245
--- /dev/null
+++ b/sources/pyside6/PySide6/doc/qtqml_functions.rst
@@ -0,0 +1,152 @@
+// @snippet qmlregistersingletoninstance
+.. py:function:: qmlRegisterSingletonInstance(pytype: type,\
+ uri: str,\
+ versionMajor: int,\
+ versionMinor: int,\
+ typeName: str,\
+ instanceObject: object) -> int
+
+ :param type pytype: Python class
+ :param str uri: uri to use while importing the component in QML
+ :param int versionMajor: major version
+ :param int versionMinor: minor version
+ :param str typeName: name exposed to QML
+ :param object instanceObject: singleton object to be registered
+ :return: int (the QML type id)
+
+This function registers a singleton Python object *instanceObject*, with a
+particular *uri* and *typeName*. Its version is a combination of *versionMajor*
+and *versionMinor*. Use this function to register an object of the given type
+*pytype* as a singleton type.
+// @snippet qmlregistersingletoninstance
+
+// @snippet qmlregistersingletontype_qobject_nocallback
+.. py:function:: qmlRegisterSingletonType(pytype: type, uri: str, versionMajor: int, versionMinor: int, typeName: str) -> int
+
+ :param type pytype: Python class
+ :param str uri: uri to use while importing the component in QML
+ :param int versionMajor: major version
+ :param int versionMinor: minor version
+ :param str typeName: name exposed to QML
+ :return: int (the QML type id)
+
+This function registers a Python type as a singleton in the QML system.
+
+Alternatively, the :ref:`QmlSingleton` decorator can be used.
+// @snippet qmlregistersingletontype_qobject_nocallback
+
+// @snippet qmlregistersingletontype_qobject_callback
+.. py:function:: qmlRegisterSingletonType(pytype: type, uri: str, versionMajor: int, versionMinor: int, typeName: str, callback: object) -> int
+
+ :param type pytype: Python class
+ :param str uri: uri to use while importing the component in QML
+ :param int versionMajor: major version
+ :param int versionMinor: minor version
+ :param str typeName: name exposed to QML
+ :param object callback: Python callable (to handle Python type)
+ :return: int (the QML type id)
+
+This function registers a Python type as a singleton in the QML system using
+the provided callback (which gets a QQmlEngine as a parameter) to generate the
+singleton.
+// @snippet qmlregistersingletontype_qobject_callback
+
+// @snippet qmlregistersingletontype_qjsvalue
+.. py:function:: qmlRegisterSingletonType(uri: str, versionMajor: int, versionMinor: int, typeName: str, callback: object) -> int
+
+ :param str uri: uri to use while importing the component in QML
+ :param int versionMajor: major version
+ :param int versionMinor: minor version
+ :param str typeName: name exposed to QML
+ :param object callback: Python callable (to handle QJSValue)
+ :return: int (the QML type id)
+
+This function registers a QJSValue as a singleton in the QML system using the
+provided callback (which gets a QQmlEngine as a parameter) to generate the
+singleton.
+// @snippet qmlregistersingletontype_qjsvalue
+
+// @snippet qmlregistertype
+.. py:function:: qmlRegisterType(pytype: type, uri: str, versionMajor: int, versionMinor: int, qmlName: str) -> int
+
+ :param type pytype: Python class
+ :param str uri: uri to use while importing the component in QML
+ :param int versionMajor: major version
+ :param int versionMinor: minor version
+ :param str qmlName: name exposed to QML
+ :return: int (the QML type id)
+
+This function registers the Python *type* in the QML system with the name
+*qmlName*, in the library imported from *uri* having the version number
+composed from *versionMajor* and *versionMinor*. For example, this registers a
+Python class 'MySliderItem' as a QML type named 'Slider' for version '1.0' of a
+module called 'com.mycompany.qmlcomponents':
+
+ ::
+
+ qmlRegisterType(MySliderItem, "com.mycompany.qmlcomponents", 1, 0, "Slider")
+
+Once this is registered, the type can be used in QML by importing the specified
+module name and version number:
+
+ ::
+
+ import com.mycompany.qmlcomponents 1.0
+
+ Slider { ... }
+
+Note that it's perfectly reasonable for a library to register types to older
+versions than the actual version of the library. Indeed, it is normal for the
+new library to allow QML written to previous versions to continue to work, even
+if more advanced versions of some of its types are available.
+// @snippet qmlregistertype
+
+// @snippet qmlregisteruncreatabletype
+.. py:function:: qmlRegisterUncreatableType(pytype: type, uri: str, versionMajor: int, versionMinor: int, qmlName: str, noCreationReason: str) -> int
+
+ :param type pytype: Python class
+ :param str uri: uri to use while importing the component in QML
+ :param int versionMajor: major version
+ :param int versionMinor: minor version
+ :param str qmlName: name exposed to QML
+ :param str noCreationReason: Error message shown when trying to create the QML type
+ :return: int (the QML type id)
+
+This function registers the Python *type* in the QML system as an uncreatable
+type with the name *qmlName*, in the library imported from *uri* having the
+version number composed from *versionMajor* and *versionMinor*, showing
+*noCreationReason* as an error message when creating the type is attempted. For
+example, this registers a Python class 'MySliderItem' as a QML type named
+'Slider' for version '1.0' of a module called 'com.mycompany.qmlcomponents':
+
+ ::
+ qmlRegisterUncreatableType(MySliderItem, "com.mycompany.qmlcomponents", 1, 0, "Slider", "Slider cannot be created.")
+
+Note that it's perfectly reasonable for a library to register types to older
+versions than the actual version of the library. Indeed, it is normal for the
+new library to allow QML written to previous versions to continue to work, even
+if more advanced versions of some of its types are available.
+
+Alternatively, the :ref:`QmlUncreatable` decorator can be used.
+// @snippet qmlregisteruncreatabletype
+
+// @snippet qqmlengine-singletoninstance-qmltypeid
+Returns the instance of a singleton type that was registered under qmlTypeId.
+For ``QObject``-derived singleton types, the ``QObject`` instance is returned,
+otherwise a ``QJSValue`` or ``None``.
+
+It is recommended to store the QML type id, e.g. as a static member in the
+singleton class. The lookup via qmlTypeId() is costly.
+// @snippet qqmlengine-singletoninstance-qmltypeid
+
+// @snippet qqmlengine-singletoninstance-typename Returns the instance of a
+singleton type named typeName from the module specified by uri.
+For ``QObject``-derived singleton types, the ``QObject`` instance is returned,
+otherwise a ``QJSValue`` or ``None``.
+
+This method can be used as an alternative to calling qmlTypeId followed by the
+id based overload of singletonInstance. This is convenient when one only needs
+to do a one time setup of a singleton; if repeated access to the singleton is
+required, caching its typeId will allow faster subsequent access via the
+type-id based overload.
+// @snippet qqmlengine-singletoninstance-typename
diff --git a/sources/pyside6/PySide6/doc/qtquicktest.rst b/sources/pyside6/PySide6/doc/qtquicktest.rst
new file mode 100644
index 000000000..9df2af071
--- /dev/null
+++ b/sources/pyside6/PySide6/doc/qtquicktest.rst
@@ -0,0 +1,62 @@
+// @snippet quick_test_main_documentation
+
+Sets up the entry point for a Qt Quick Test application.
+The ``name`` argument uniquely identifies this set of tests.
+
+``sys.argv`` should be passed to the ``argv`` argument to ensure
+propagation of the command line arguments.
+
+.. note:: The function assumes that your test sources are in the current
+ directory, unless the ``QUICK_TEST_SOURCE_DIR`` environment
+ variable is set or a directory is passed in ``dir``.
+
+The following snippet demonstrates the use of this function:
+
+.. code-block:: Python
+
+ import sys
+ from PySide6.QtQuickTest import QUICK_TEST_MAIN
+
+ ex = QUICK_TEST_MAIN("example", sys.argv)
+ sys.exit(ex)
+
+
+// @snippet quick_test_main_documentation
+
+// @snippet quick_test_main_with_setup_documentation
+
+Sets up the entry point for a Qt Quick Test application.
+The ``name`` argument uniquely identifies this set of tests.
+
+``sys.argv`` should be passed to the ``argv`` argument to ensure
+propagation of the command line arguments.
+
+This function is identical to ``QUICK_TEST_MAIN()``, except that it takes an
+additional argument ``setup``, the type of a ``QObject``-derived
+class which will be instantiated. With this class, it is possible to define
+additional setup code to execute before running the QML test.
+
+The following snippet demonstrates the use of this function:
+
+.. code-block:: Python
+
+ import sys
+ from PySide6.QtQuickTest import QUICK_TEST_MAIN_WITH_SETUP
+
+ class CustomTestSetup(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ @Slot(QQmlEngine)
+ def qmlEngineAvailable(self, qmlEngine):
+ pass
+
+ ex = QUICK_TEST_MAIN_WITH_SETUP("qquicktestsetup", CustomTestSetup, sys.argv)
+ sys.exit(ex)
+
+
+.. note:: The function assumes that your test sources are in the current
+ directory, unless the ``QUICK_TEST_SOURCE_DIR`` environment
+ variable is set or a directory is passed in ``dir``.
+
+// @snippet quick_test_main_with_setup_documentation
diff --git a/sources/pyside6/PySide6/doc/qtuitools.rst b/sources/pyside6/PySide6/doc/qtuitools.rst
new file mode 100644
index 000000000..a8856f1af
--- /dev/null
+++ b/sources/pyside6/PySide6/doc/qtuitools.rst
@@ -0,0 +1,68 @@
+// @snippet quiloader-registercustomwidget
+Registers a Python created custom widget to QUiLoader, so it can be recognized
+when loading a `.ui` file. The custom widget type is passed via the
+``customWidgetType`` argument. This is needed when you want to override a
+virtual method of some widget in the interface, since duck punching will not
+work with widgets created by QUiLoader based on the contents of the `.ui` file.
+
+(Remember that
+`duck punching virtual methods is an invitation for your own demise! <https://doc.qt.io/qtforpython/shiboken6/wordsofadvice.html#duck-punching-and-virtual-methods>`_)
+
+Let's see an obvious example. If you want to create a new widget it's probable you'll end up
+overriding :class:`~PySide6.QtGui.QWidget`'s :meth:`~PySide6.QtGui.QWidget.paintEvent` method.
+
+.. code-block:: python
+
+ class Circle(QWidget):
+ def paintEvent(self, event):
+ with QPainter(self) as painter:
+ painter.setPen(self.pen)
+ painter.setBrush(QBrush(self.color))
+ painter.drawEllipse(event.rect().center(), 20, 20)
+
+ # ...
+
+ loader = QUiLoader()
+ loader.registerCustomWidget(Circle)
+ circle = loader.load('circle.ui')
+ circle.show()
+
+ # ...
+// @snippet quiloader-registercustomwidget
+
+// @snippet loaduitype
+.. currentmodule:: PySide6.QtUiTools
+
+loadUiType
+***********
+.. py:function:: loadUiType(uifile: str) -> tuple(object, object)
+
+ :param str uifile: The name of the `.ui` file
+ :return: tuple(object, object)
+
+This function generates and loads a `.ui` file at runtime, and it returns
+a `tuple` containing the reference to the Python class, and the base class.
+
+We recommend not to use this approach as the workflow should be to generate a Python file
+from the `.ui` file, and then import and load it to use it, but we do understand that
+there are some corner cases when such functionality is required.
+
+The internal process relies on `uic` being in the PATH.
+The `pyside6-uic` wrapper uses a shipped `uic` that is located in the
+`site-packages/PySide6/uic`, so PATH needs to be updated to use that if there
+is no `uic` in the system.
+
+A simple use case is::
+
+ from PySide6.QtUiTools import loadUiType
+
+ generated_class, base_class = loadUiType("themewidget.ui")
+ # the values will be:
+ # (<class '__main__.Ui_ThemeWidgetForm'>, <class 'PySide6.QtWidgets.QWidget'>)
+
+ widget = base_class()
+ form = generated_class()
+ form.setupUi(widget)
+ # form.a_widget_member.a_method_of_member()
+ widget.show()
+// @snippet loaduitype
diff --git a/sources/pyside6/PySide6/global.h.in b/sources/pyside6/PySide6/global.h.in
new file mode 100644
index 000000000..9a1e001fe
--- /dev/null
+++ b/sources/pyside6/PySide6/global.h.in
@@ -0,0 +1,20 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/qnamespace.h>
+
+#if @ENABLE_MAC@
+# define Q_OS_MAC
+#endif
+#if @ENABLE_WIN@
+# define Q_OS_WIN
+#endif
+#if @ENABLE_UNIX@
+# define Q_OS_UNIX
+#endif
+
+// There are symbols in Qt that exist in Debug but
+// not in release
+#define QT_NO_DEBUG
+
+// Here are now all configured modules appended:
diff --git a/sources/pyside6/PySide6/glue/qhttpserver.cpp b/sources/pyside6/PySide6/glue/qhttpserver.cpp
new file mode 100644
index 000000000..b6e485e2c
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qhttpserver.cpp
@@ -0,0 +1,50 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// Note: Lambdas need to be inline, QTBUG-104481
+// @snippet qhttpserver-route
+QString rule = %CONVERTTOCPP[QString](%PYARG_1);
+auto *callable = %PYARG_2;
+
+bool cppResult = %CPPSELF.%FUNCTION_NAME(rule,
+ [callable](const QHttpServerRequest &request) -> QString {
+ Shiboken::GilState state;
+ auto *requestPtr = &request;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist, 0,
+ %CONVERTTOPYTHON[QHttpServerRequest *](requestPtr));
+ PyObject *ret = PyObject_CallObject(callable, arglist);
+ if (PyErr_Occurred())
+ PyErr_Print();
+ if (ret == nullptr)
+ return QString{};
+ QString cppResult = %CONVERTTOCPP[QString](ret);
+ return cppResult;
+});
+
+%PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+// @snippet qhttpserver-route
+
+// @snippet qhttpserver-afterrequest
+auto *callable = %PYARG_1;
+
+%CPPSELF.%FUNCTION_NAME([callable](QHttpServerResponse &&response,
+ const QHttpServerRequest &request) {
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(2));
+ auto *responsePtr = &response;
+ auto *requestPtr = &request;
+ PyTuple_SET_ITEM(arglist, 0,
+ %CONVERTTOPYTHON[QHttpServerResponse *](responsePtr));
+ PyTuple_SET_ITEM(arglist, 1,
+ %CONVERTTOPYTHON[QHttpServerRequest *](requestPtr));
+ PyObject_CallObject(callable, arglist);
+ if (PyErr_Occurred())
+ PyErr_Print();
+ return std::move(response);
+});
+// @snippet qhttpserver-afterrequest
diff --git a/sources/pyside6/PySide6/glue/qtcharts.cpp b/sources/pyside6/PySide6/glue/qtcharts.cpp
new file mode 100644
index 000000000..a99dbbb8a
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtcharts.cpp
@@ -0,0 +1,16 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qchart-releaseownership
+Shiboken::Object::releaseOwnership(%PYARG_1);
+// @snippet qchart-releaseownership
+
+// @snippet qxyseries-appendnp-numpy-x-y
+const auto points = PySide::Numpy::xyDataToQPointFList(%PYARG_1, %PYARG_2);
+%CPPSELF.append(points);
+// @snippet qxyseries-appendnp-numpy-x-y
+
+// @snippet qxyseries-replacenp-numpy-x-y
+const auto points = PySide::Numpy::xyDataToQPointFList(%PYARG_1, %PYARG_2);
+%CPPSELF.replace(points);
+// @snippet qxyseries-replacenp-numpy-x-y
diff --git a/sources/pyside6/PySide6/glue/qtcore.cpp b/sources/pyside6/PySide6/glue/qtcore.cpp
new file mode 100644
index 000000000..0c206db72
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtcore.cpp
@@ -0,0 +1,2150 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet include-pyside
+#include <pysideinit.h>
+#include <limits>
+#include "glue/core_snippets_p.h"
+// @snippet include-pyside
+
+// @snippet core-snippets-p-h
+#include "glue/core_snippets_p.h"
+// @snippet core-snippets-p-h
+
+// @snippet qarg_helper
+
+// Helper for the Q_ARG/Q_RETURN_ARG functions, creating a meta type
+// and instance.
+struct QArgData
+{
+ operator bool() const { return metaType.isValid() && data != nullptr; }
+
+ QMetaType metaType;
+ void *data = nullptr;
+};
+
+QArgData qArgDataFromPyType(PyObject *t)
+{
+ QArgData result;
+ const char *typeName{};
+ if (PyType_Check(t)) {
+ auto *pyType = reinterpret_cast<PyTypeObject *>(t);
+ typeName = pyType->tp_name;
+ result.metaType = PySide::qMetaTypeFromPyType(pyType);
+ } else if (PyUnicode_Check(t)) {
+ typeName = Shiboken::String::toCString(t);
+ result.metaType = QMetaType::fromName(typeName);
+ } else {
+ PyErr_Format(PyExc_RuntimeError, "%s: Parameter should be a type or type string.",
+ __FUNCTION__);
+ return result;
+ }
+
+ if (!result.metaType.isValid()) {
+ PyErr_Format(PyExc_RuntimeError, "%s: Unable to find a QMetaType for \"%s\".",
+ __FUNCTION__, typeName);
+ return result;
+ }
+
+ result.data = result.metaType.create();
+ if (result.data == nullptr) {
+ PyErr_Format(PyExc_RuntimeError, "%s: Unable to create an instance of \"%s\" (%s).",
+ __FUNCTION__, typeName, result.metaType.name());
+ return result;
+ }
+ return result;
+}
+// @snippet qarg_helper
+
+// @snippet settings-value-helpers
+// Convert a QVariant to a desired primitive type
+static PyObject *convertToPrimitiveType(const QVariant &out, int metaTypeId)
+{
+ switch (metaTypeId) {
+ case QMetaType::QByteArray:
+ return PyBytes_FromString(out.toByteArray().constData());
+ case QMetaType::QString:
+ return PyUnicode_FromString(out.toByteArray().constData());
+ case QMetaType::Short:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::UShort:
+ case QMetaType::ULong:
+ case QMetaType::ULongLong:
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ return PyLong_FromDouble(out.toFloat());
+ case QMetaType::Double:
+ case QMetaType::Float:
+ case QMetaType::Float16:
+ return PyFloat_FromDouble(out.toFloat());
+ case QMetaType::Bool:
+ if (out.toBool()) {
+ Py_RETURN_TRUE;
+ }
+ Py_RETURN_FALSE;
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+// Helper for QSettings::value() to convert a value to the desired type
+static PyObject *settingsTypeCoercion(const QVariant &out, PyTypeObject *typeObj)
+{
+ if (typeObj == &PyList_Type) {
+ // Convert any string, etc, to a list of 1 element
+ if (auto *primitiveValue = convertToPrimitiveType(out, out.typeId())) {
+ PyObject *list = PyList_New(1);
+ PyList_SET_ITEM(list, 0, primitiveValue);
+ return list;
+ }
+
+ const QByteArray out_ba = out.toByteArray();
+ if (out_ba.isEmpty())
+ return PyList_New(0);
+
+ const QByteArrayList valuesList = out_ba.split(',');
+ const Py_ssize_t valuesSize = valuesList.size();
+ PyObject *list = PyList_New(valuesSize);
+ for (Py_ssize_t i = 0; i < valuesSize; ++i) {
+ PyObject *item = PyUnicode_FromString(valuesList.at(i).constData());
+ PyList_SET_ITEM(list, i, item);
+ }
+ return list;
+ }
+
+ if (typeObj == &PyBytes_Type)
+ return convertToPrimitiveType(out, QMetaType::QByteArray);
+ if (typeObj == &PyUnicode_Type)
+ return convertToPrimitiveType(out, QMetaType::QString);
+ if (typeObj == &PyLong_Type)
+ return convertToPrimitiveType(out, QMetaType::Int);
+ if (typeObj == &PyFloat_Type)
+ return convertToPrimitiveType(out, QMetaType::Double);
+ if (typeObj == &PyBool_Type)
+ return convertToPrimitiveType(out, QMetaType::Bool);
+
+ // TODO: PyDict_Type and PyTuple_Type
+ PyErr_SetString(PyExc_TypeError,
+ "Invalid type parameter.\n"
+ "\tUse 'list', 'bytes', 'str', 'int', 'float', 'bool', "
+ "or a Qt-derived type");
+ return nullptr;
+}
+
+static bool isEquivalentSettingsType(PyTypeObject *typeObj, int metaTypeId)
+{
+ switch (metaTypeId) {
+ case QMetaType::QVariantList:
+ case QMetaType::QStringList:
+ return typeObj == &PyList_Type;
+ case QMetaType::QByteArray:
+ return typeObj == &PyBytes_Type;
+ case QMetaType::QString:
+ return typeObj == &PyUnicode_Type;
+ case QMetaType::Short:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::UShort:
+ case QMetaType::ULong:
+ case QMetaType::ULongLong:
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ return typeObj == &PyLong_Type;
+ case QMetaType::Double:
+ case QMetaType::Float:
+ case QMetaType::Float16:
+ return typeObj == &PyFloat_Type;
+ case QMetaType::Bool:
+ return typeObj == &PyBool_Type;
+ default:
+ break;
+ }
+ return false;
+}
+// @snippet settings-value-helpers
+
+// @snippet qsettings-value
+// If we enter the kwds, means that we have a defaultValue or
+// at least a type.
+// This avoids that we are passing '0' as defaultValue.
+// defaultValue can also be passed as positional argument,
+// not only as keyword.
+// PySide-535: Allow for empty dict instead of nullptr in PyPy
+QVariant out;
+if ((kwds && PyDict_Size(kwds) > 0) || numArgs > 1) {
+ Py_BEGIN_ALLOW_THREADS
+ out = %CPPSELF.value(%1, %2);
+ Py_END_ALLOW_THREADS
+} else {
+ Py_BEGIN_ALLOW_THREADS
+ out = %CPPSELF.value(%1);
+ Py_END_ALLOW_THREADS
+}
+
+PyTypeObject *typeObj = reinterpret_cast<PyTypeObject*>(%PYARG_3);
+
+if (typeObj && !Shiboken::ObjectType::checkType(typeObj)
+ && !isEquivalentSettingsType(typeObj, out.typeId())) {
+ %PYARG_0 = settingsTypeCoercion(out, typeObj);
+} else {
+ if (out.isValid()) {
+ %PYARG_0 = %CONVERTTOPYTHON[QVariant](out);
+ } else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+ }
+}
+
+// @snippet qsettings-value
+
+// @snippet metatype-from-type
+%0 = new %TYPE(PySide::qMetaTypeFromPyType(reinterpret_cast<PyTypeObject *>(%1)));
+// @snippet metatype-from-type
+
+// @snippet metatype-from-metatype-type
+Shiboken::AutoDecRef intArg(PyObject_GetAttrString(%PYARG_1, "value"));
+%0 = new %TYPE(PyLong_AsLong(intArg));
+// @snippet metatype-from-metatype-type
+
+// @snippet conversion-pytypeobject-qmetatype
+auto *pyType = reinterpret_cast<PyTypeObject *>(%in);
+%out = PySide::qMetaTypeFromPyType(pyType);
+// @snippet conversion-pytypeobject-qmetatype
+
+// @snippet conversion-qmetatype-pytypeobject
+auto pyType = Shiboken::Conversions::getPythonTypeObject(%in.name());
+%out = pyType ? (reinterpret_cast<PyObject *>(pyType)) : Py_None;
+Py_INCREF(%out);
+return %out;
+// @snippet conversion-qmetatype-pytypeobject
+
+// @snippet qvariant-conversion
+static QVariant QVariant_convertToVariantMap(PyObject *map)
+{
+ Py_ssize_t pos = 0;
+ Shiboken::AutoDecRef keys(PyDict_Keys(map));
+ if (!QVariant_isStringList(keys))
+ return {};
+ PyObject *key;
+ PyObject *value;
+ QMap<QString,QVariant> ret;
+ while (PyDict_Next(map, &pos, &key, &value)) {
+ QString cppKey = %CONVERTTOCPP[QString](key);
+ QVariant cppValue = %CONVERTTOCPP[QVariant](value);
+ ret.insert(cppKey, cppValue);
+ }
+ return QVariant(ret);
+}
+static QVariant QVariant_convertToVariantList(PyObject *list)
+{
+ if (QVariant_isStringList(list)) {
+ QList<QString > lst = %CONVERTTOCPP[QList<QString>](list);
+ return QVariant(QStringList(lst));
+ }
+ QVariant valueList = QVariant_convertToValueList(list);
+ if (valueList.isValid())
+ return valueList;
+
+ if (PySequence_Size(list) < 0) {
+ // clear the error if < 0 which means no length at all
+ PyErr_Clear();
+ return {};
+ }
+
+ QList<QVariant> lst;
+ Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
+ const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ PyObject *pyItem = PySequence_Fast_GET_ITEM(fast.object(), i);
+ QVariant item = %CONVERTTOCPP[QVariant](pyItem);
+ lst.append(item);
+ }
+ return QVariant(lst);
+}
+
+using SpecificConverter = Shiboken::Conversions::SpecificConverter;
+
+static std::optional<SpecificConverter> converterForQtType(const char *typeNameC)
+{
+ // Fix typedef "QGenericMatrix<3,3,float>" -> QMatrix3x3". The reverse
+ // conversion happens automatically in QMetaType::fromName() in
+ // QVariant_resolveMetaType().
+ QByteArrayView typeNameV(typeNameC);
+ if (typeNameV.startsWith("QGenericMatrix<") && typeNameV.endsWith(",float>")) {
+ QByteArray typeName = typeNameV.toByteArray();
+ typeName.remove(1, 7);
+ typeName.remove(7, 1); // '<'
+ typeName.chop(7);
+ typeName.replace(',', 'x');
+ SpecificConverter matrixConverter(typeName.constData());
+ if (matrixConverter)
+ return matrixConverter;
+ }
+ SpecificConverter converter(typeNameC);
+ if (converter)
+ return converter;
+ return std::nullopt;
+}
+// @snippet qvariant-conversion
+
+// @snippet qt-qabs
+double _abs = qAbs(%1);
+%PYARG_0 = %CONVERTTOPYTHON[double](_abs);
+// @snippet qt-qabs
+
+// @snippet qt-addpostroutine
+PySide::addPostRoutine(%1);
+// @snippet qt-addpostroutine
+
+// @snippet qt-qaddpostroutine
+qAddPostRoutine(PySide::globalPostRoutineCallback);
+// @snippet qt-qaddpostroutine
+
+// @snippet qcompress-buffer
+auto *ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1));
+QByteArray compressed = %FUNCTION_NAME(ptr, %2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](compressed);
+// @snippet qcompress-buffer
+
+// @snippet quncompress-buffer
+auto *ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1));
+QByteArray uncompressed = %FUNCTION_NAME(ptr, %2);
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](uncompressed);
+// @snippet quncompress-buffer
+
+// @snippet qt-version
+QList<QByteArray> version = QByteArray(qVersion()).split('.');
+PyObject *pyQtVersion = PyTuple_New(3);
+for (int i = 0; i < 3; ++i)
+ PyTuple_SET_ITEM(pyQtVersion, i, PyLong_FromLong(version[i].toInt()));
+PyModule_AddObject(module, "__version_info__", pyQtVersion);
+PyModule_AddStringConstant(module, "__version__", qVersion());
+// @snippet qt-version
+
+// @snippet qobject-connect
+#include <qobjectconnect.h>
+// @snippet qobject-connect
+
+// @snippet qobject-connect-1
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnect(%1, %2, %CPPSELF, %3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-1
+
+// @snippet qobject-connect-2
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnect(%1, %2, %3, %4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-2
+
+// @snippet qobject-connect-3
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnect(%1, %2, %3, %4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-3
+
+// @snippet qobject-connect-4
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnectCallback(%1, %2, %PYARG_3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-4
+
+// @snippet qobject-connect-4-context
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnectCallback(%1, %2, %3, %PYARG_4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-4-context
+
+// @snippet qobject-connect-5
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnectCallback(%CPPSELF, %1, %PYARG_2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-5
+
+// @snippet qobject-connect-6
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectConnect(%CPPSELF, %1, %2, %3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-6
+
+// @snippet qobject-emit
+%RETURN_TYPE %0 = PySide::SignalManager::instance().emitSignal(%CPPSELF, %1, %PYARG_2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-emit
+
+// @snippet qobject-disconnect-1
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectDisconnectCallback(%CPPSELF, %1, %2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-disconnect-1
+
+// @snippet qobject-disconnect-2
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = PySide::qobjectDisconnectCallback(%1, %2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-disconnect-2
+
+// @snippet qfatal
+// qFatal doesn't have a stream version, so we do a
+// qWarning call followed by a qFatal() call using a
+// literal.
+Py_BEGIN_ALLOW_THREADS
+qWarning() << %1;
+qFatal("[A qFatal() call was made from Python code]");
+Py_END_ALLOW_THREADS
+// @snippet qfatal
+
+// @snippet moduleshutdown
+PySide::runCleanupFunctions();
+// @snippet moduleshutdown
+
+// @snippet qt-qenum
+%PYARG_0 = PySide::QEnum::QEnumMacro(%1, false);
+// @snippet qt-qenum
+
+// @snippet qt-qflag
+%PYARG_0 = PySide::QEnum::QEnumMacro(%1, true);
+// @snippet qt-qflag
+
+// @snippet qt-init-feature
+PySide::Feature::init();
+// @snippet qt-init-feature
+
+// @snippet qt-pysideinit
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QString_IDX], "unicode");
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QString_IDX], "str");
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QtCore_QList_QVariant_IDX], "QVariantList");
+Shiboken::Conversions::registerConverterName(SbkPySide6_QtCoreTypeConverters[SBK_QtCore_QMap_QString_QVariant_IDX], "QVariantMap");
+
+PySide::registerInternalQtConf();
+PySide::init(module);
+Py_AtExit(QtCoreModuleExit);
+// @snippet qt-pysideinit
+
+// @snippet qt-messagehandler
+// Define a global variable to handle qInstallMessageHandler callback
+static PyObject *qtmsghandler = nullptr;
+
+static void msgHandlerCallback(QtMsgType type, const QMessageLogContext &ctx, const QString &msg)
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(3));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QtMsgType](type));
+ PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMessageLogContext &](ctx));
+ QByteArray array = msg.toUtf8(); // Python handler requires UTF-8
+ const char *data = array.constData();
+ PyTuple_SET_ITEM(arglist, 2, %CONVERTTOPYTHON[const char *](data));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(qtmsghandler, arglist));
+}
+static void QtCoreModuleExit()
+{
+ PySide::SignalManager::instance().clear();
+}
+// @snippet qt-messagehandler
+
+// @snippet qt-installmessagehandler
+if (%PYARG_1 == Py_None) {
+ qInstallMessageHandler(0);
+ %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None;
+ qtmsghandler = 0;
+} else if (!PyCallable_Check(%PYARG_1)) {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+} else {
+ %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None;
+ Py_INCREF(%PYARG_1);
+ qtmsghandler = %PYARG_1;
+ qInstallMessageHandler(msgHandlerCallback);
+}
+
+if (%PYARG_0 == Py_None)
+ Py_INCREF(%PYARG_0);
+// @snippet qt-installmessagehandler
+
+// @snippet qline-hash
+namespace PySide {
+ template<> inline Py_ssize_t hash(const QLine &l)
+ {
+ return qHashMulti(0, l.x1(), l.y1(), l.x2(), l.y2());
+ }
+};
+// @snippet qline-hash
+
+// @snippet qlinef-intersect
+QPointF p;
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &p);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QPointF](p));
+// @snippet qlinef-intersect
+
+// @snippet qresource-data
+const void *d = %CPPSELF.%FUNCTION_NAME();
+if (d) {
+ %PYARG_0 = Shiboken::Buffer::newObject(d, %CPPSELF.size());
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qresource-data
+
+// @snippet qdate-topython
+if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+%PYARG_0 = PyDate_FromDate(%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day());
+// @snippet qdate-topython
+
+// @snippet qdate-getdate
+int year, month, day;
+%CPPSELF.%FUNCTION_NAME(&year, &month, &day);
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](year));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](month));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](day));
+// @snippet qdate-getdate
+
+// @snippet qdate-weeknumber
+int yearNumber;
+int week = %CPPSELF.%FUNCTION_NAME(&yearNumber);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](week));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](yearNumber));
+// @snippet qdate-weeknumber
+
+// @snippet qdatetime-1
+QDate date(%1, %2, %3);
+QTime time(%4, %5, %6, %7);
+%0 = new %TYPE(date, time, Qt::TimeSpec(%8));
+// @snippet qdatetime-1
+
+// @snippet qdatetime-2
+QDate date(%1, %2, %3);
+QTime time(%4, %5, %6);
+%0 = new %TYPE(date, time);
+// @snippet qdatetime-2
+
+// @snippet qdatetime-3
+QDate date(%1, %2, %3);
+QTime time(%4, %5, %6, %7);
+%0 = new %TYPE(date, time, %8);
+// @snippet qdatetime-3
+
+// @snippet qdatetime-topython
+QDate date = %CPPSELF.date();
+QTime time = %CPPSELF.time();
+if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+%PYARG_0 = PyDateTime_FromDateAndTime(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.msec()*1000);
+// @snippet qdatetime-topython
+
+// @snippet qtime-topython
+if (!PyDateTimeAPI)
+ PyDateTime_IMPORT;
+%PYARG_0 = PyTime_FromTime(%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()*1000);
+// @snippet qtime-topython
+
+// @snippet qbitarray-len
+return %CPPSELF.size();
+// @snippet qbitarray-len
+
+// @snippet qbitarray-getitem
+if (_i < 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+}
+bool ret = %CPPSELF.at(_i);
+return %CONVERTTOPYTHON[bool](ret);
+// @snippet qbitarray-getitem
+
+// @snippet qbitarray-setitem
+PyObject *args = Py_BuildValue("(iiO)", _i, 1, _value);
+PyObject *result = Sbk_QBitArrayFunc_setBit(self, args);
+Py_DECREF(args);
+Py_XDECREF(result);
+return !result ? -1 : 0;
+// @snippet qbitarray-setitem
+
+// @snippet default-enter
+Py_INCREF(%PYSELF);
+pyResult = %PYSELF;
+// @snippet default-enter
+
+// @snippet qsignalblocker-unblock
+%CPPSELF.unblock();
+// @snippet qsignalblocker-unblock
+
+// @snippet unlock
+%CPPSELF.unlock();
+// @snippet unlock
+
+// @snippet qabstractitemmodel-createindex
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, %PYARG_3);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qabstractitemmodel-createindex
+
+// @snippet qabstractitemmodel
+qRegisterMetaType<QList<int> >("QList<int>");
+// @snippet qabstractitemmodel
+
+// @snippet qobject-metaobject
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-metaobject
+
+// @snippet qobject-findchild-2
+QObject *child = qObjectFindChild(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %3);
+%PYARG_0 = %CONVERTTOPYTHON[QObject *](child);
+// @snippet qobject-findchild-2
+
+// @snippet qobject-findchildren
+%PYARG_0 = PyList_New(0);
+qObjectFindChildren(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %3,
+ [%PYARG_0](QObject *child) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child));
+ PyList_Append(%PYARG_0, pyChild.object());
+ });
+// @snippet qobject-findchildren
+
+// @snippet qobject-tr
+const QString result = qObjectTr(reinterpret_cast<PyTypeObject *>(%PYSELF), %1, %2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[QString](result);
+// @snippet qobject-tr
+
+// @snippet qobject-sender
+// Retrieve the sender from a dynamic property set by GlobalReceiverV2 in case of a
+// non-C++ slot (Python callback).
+auto *ret = %CPPSELF.%FUNCTION_NAME();
+if (ret == nullptr) {
+ auto senderV = %CPPSELF.property("_q_pyside_sender");
+ if (senderV.typeId() == QMetaType::QObjectStar)
+ ret = senderV.value<QObject *>();
+}
+%PYARG_0 = %CONVERTTOPYTHON[QObject*](ret);
+// @snippet qobject-sender
+
+// @snippet qbytearray-mgetitem
+if (PyIndex_Check(_key)) {
+ const Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
+ if (_i < 0 || _i >= %CPPSELF.size())
+ return PyErr_Format(PyExc_IndexError, "index out of bounds");
+ char res[2] = {%CPPSELF.at(_i), '\0'};
+ return PyBytes_FromStringAndSize(res, 1);
+}
+
+if (PySlice_Check(_key) == 0)
+ return PyErr_Format(PyExc_TypeError,
+ "list indices must be integers or slices, not %.200s",
+ Py_TYPE(_key)->tp_name);
+
+Py_ssize_t start, stop, step, slicelength;
+if (PySlice_GetIndicesEx(_key, %CPPSELF.size(), &start, &stop, &step, &slicelength) < 0)
+ return nullptr;
+
+QByteArray ba;
+if (slicelength <= 0)
+ return %CONVERTTOPYTHON[QByteArray](ba);
+
+if (step == 1) {
+ Py_ssize_t max = %CPPSELF.size();
+ start = qBound(Py_ssize_t(0), start, max);
+ stop = qBound(Py_ssize_t(0), stop, max);
+ if (start < stop)
+ ba = %CPPSELF.mid(start, stop - start);
+ return %CONVERTTOPYTHON[QByteArray](ba);
+}
+
+for (Py_ssize_t cur = start; slicelength > 0; cur += step, --slicelength)
+ ba.append(%CPPSELF.at(cur));
+
+return %CONVERTTOPYTHON[QByteArray](ba);
+// @snippet qbytearray-mgetitem
+
+// @snippet qbytearray-msetitem
+// PYSIDE-2404: Usage of the `get()` function not necessary, the type exists.
+if (PyIndex_Check(_key)) {
+ Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
+ if (_i == -1 && PyErr_Occurred())
+ return -1;
+
+ if (_i < 0)
+ _i += %CPPSELF.size();
+
+ if (_i < 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "QByteArray index out of range");
+ return -1;
+ }
+
+ // Provide more specific error message for bytes/str, bytearray, QByteArray respectively
+ if (PyBytes_Check(_value)) {
+ if (Py_SIZE(_value) != 1) {
+ PyErr_SetString(PyExc_ValueError, "bytes must be of size 1");
+ return -1;
+ }
+ } else if (PyByteArray_Check(_value)) {
+ if (Py_SIZE(_value) != 1) {
+ PyErr_SetString(PyExc_ValueError, "bytearray must be of size 1");
+ return -1;
+ }
+ } else if (Py_TYPE(_value) == reinterpret_cast<PyTypeObject *>(
+ SbkPySide6_QtCoreTypeStructs[SBK_QByteArray_IDX].type)) {
+ if (PyObject_Length(_value) != 1) {
+ PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1");
+ return -1;
+ }
+ } else {
+ PyErr_SetString(PyExc_ValueError, "a bytes, bytearray, QByteArray of size 1 is required");
+ return -1;
+ }
+
+ // Not support int or long.
+ %CPPSELF.remove(_i, 1);
+ PyObject *args = Py_BuildValue("(nO)", _i, _value);
+ PyObject *result = Sbk_QByteArrayFunc_insert(self, args);
+ Py_DECREF(args);
+ Py_XDECREF(result);
+ return result != nullptr ? 0: -1;
+}
+
+if (PySlice_Check(_key) == 0) {
+ PyErr_Format(PyExc_TypeError, "QBytearray indices must be integers or slices, not %.200s",
+ Py_TYPE(_key)->tp_name);
+ return -1;
+}
+
+Py_ssize_t start, stop, step, slicelength;
+if (PySlice_GetIndicesEx(_key, %CPPSELF.size(), &start, &stop, &step, &slicelength) < 0)
+ return -1;
+
+// The parameter candidates are: bytes/str, bytearray, QByteArray itself.
+// Not supported are iterables containing ints between 0~255
+// case 1: value is nullpre, means delete the items within the range
+// case 2: step is 1, means shrink or expand
+// case 3: step is not 1, then the number of slots have to equal the number of items in _value
+Py_ssize_t value_length = 0;
+if (_value != nullptr && _value != Py_None) {
+ if (!(PyBytes_Check(_value) || PyByteArray_Check(_value)
+ || Py_TYPE(_value) == SbkPySide6_QtCoreTypeStructs[SBK_QByteArray_IDX].type)) {
+ PyErr_Format(PyExc_TypeError, "bytes, bytearray or QByteArray is required, not %.200s",
+ Py_TYPE(_value)->tp_name);
+ return -1;
+ }
+ value_length = PyObject_Length(_value);
+}
+
+if (step != 1 && value_length != slicelength) {
+ PyErr_Format(PyExc_ValueError, "attempt to assign %s of size %d to extended slice of size %d",
+ Py_TYPE(_value)->tp_name, int(value_length), int(slicelength));
+ return -1;
+}
+
+if (step != 1) {
+ Py_ssize_t i = start;
+ for (Py_ssize_t j = 0; j < slicelength; ++j) {
+ PyObject *item = PyObject_GetItem(_value, PyLong_FromSsize_t(j));
+ QByteArray temp;
+ if (PyLong_Check(item)) {
+ int overflow;
+ const long ival = PyLong_AsLongAndOverflow(item, &overflow);
+ // Not supposed to be bigger than 255 because only bytes,
+ // bytearray, QByteArray were accepted
+ temp.append(char(ival));
+ } else {
+ temp = %CONVERTTOCPP[QByteArray](item);
+ }
+ %CPPSELF.replace(i, 1, temp);
+ i += step;
+ }
+ return 0;
+}
+
+QByteArray ba = %CONVERTTOCPP[QByteArray](_value);
+%CPPSELF.replace(start, slicelength, ba);
+return 0;
+// @snippet qbytearray-msetitem
+
+// @snippet qbytearray-bufferprotocol
+extern "C" {
+// QByteArray buffer protocol functions
+// see: http://www.python.org/dev/peps/pep-3118/
+
+static int SbkQByteArray_getbufferproc(PyObject *obj, Py_buffer *view, int flags)
+{
+ if (!view || !Shiboken::Object::isValid(obj))
+ return -1;
+
+ QByteArray * cppSelf = %CONVERTTOCPP[QByteArray *](obj);
+ //XXX /|\ omitting this space crashes shiboken!
+#ifdef Py_LIMITED_API
+ view->obj = obj;
+ view->buf = reinterpret_cast<void *>(cppSelf->data());
+ view->len = cppSelf->size();
+ view->readonly = 0;
+ view->itemsize = 1;
+ view->format = (flags & PyBUF_FORMAT) == PyBUF_FORMAT ? const_cast<char *>("B") : nullptr;
+ view->ndim = 1;
+ view->shape = (flags & PyBUF_ND) == PyBUF_ND ? &(view->len) : nullptr;
+ view->strides = (flags & PyBUF_STRIDES) == PyBUF_STRIDES ? &(view->itemsize) : nullptr;
+ view->suboffsets = nullptr;
+ view->internal = nullptr;
+
+ Py_XINCREF(obj);
+ return 0;
+#else // Py_LIMITED_API
+ const int result = PyBuffer_FillInfo(view, obj, reinterpret_cast<void *>(cppSelf->data()),
+ cppSelf->size(), 0, flags);
+ if (result == 0)
+ Py_XINCREF(obj);
+ return result;
+#endif
+}
+
+static PyBufferProcs SbkQByteArrayBufferProc = {
+ /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc,
+ /*bf_releasebuffer*/ (releasebufferproc)0,
+};
+
+}
+// @snippet qbytearray-bufferprotocol
+
+// @snippet qbytearray-operatorplus-1
+QByteArray ba = QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)) + *%CPPSELF;
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
+// @snippet qbytearray-operatorplus-1
+
+// @snippet qbytearray-operatorplus-2
+QByteArray ba = QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)) + *%CPPSELF;
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
+// @snippet qbytearray-operatorplus-2
+
+// @snippet qbytearray-operatorplus-3
+QByteArray ba = *%CPPSELF + QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
+// @snippet qbytearray-operatorplus-3
+
+// @snippet qbytearray-operatorplusequal
+*%CPPSELF += QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
+// @snippet qbytearray-operatorplusequal
+
+// @snippet qbytearray-operatorequalequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF == ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorequalequal
+
+// @snippet qbytearray-operatornotequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF != ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatornotequal
+
+// @snippet qbytearray-operatorgreater
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF > ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorgreater
+
+// @snippet qbytearray-operatorgreaterequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF >= ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorgreaterequal
+
+// @snippet qbytearray-operatorlower
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF < ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorlower
+
+// @snippet qbytearray-operatorlowerequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF <= ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorlowerequal
+
+// @snippet qbytearray-repr
+PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size());
+if (aux == nullptr) {
+ return nullptr;
+}
+QByteArray b(Py_TYPE(%PYSELF)->tp_name);
+%PYARG_0 = PyUnicode_FromFormat("%s(%R)", b.constData(), aux);
+Py_DECREF(aux);
+// @snippet qbytearray-repr
+
+// @snippet qbytearray-2
+%0 = new QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
+// @snippet qbytearray-2
+
+// @snippet qbytearray-3
+%0 = new QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
+// @snippet qbytearray-3
+
+// @snippet qbytearray-py3
+PepType_AS_BUFFER(Shiboken::SbkType<QByteArray>()) = &SbkQByteArrayBufferProc;
+// @snippet qbytearray-py3
+
+// @snippet qbytearray-data
+%PYARG_0 = PyBytes_FromStringAndSize(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size());
+// @snippet qbytearray-data
+
+// @snippet qbytearray-str
+PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size());
+if (aux == nullptr) {
+ return nullptr;
+}
+%PYARG_0 = PyObject_Repr(aux);
+Py_DECREF(aux);
+// @snippet qbytearray-str
+
+// @snippet qbytearray-len
+return %CPPSELF.size();
+// @snippet qbytearray-len
+
+// @snippet qbytearray-getitem
+if (_i < 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+} else {
+ char res[2];
+ res[0] = %CPPSELF.at(_i);
+ res[1] = 0;
+ return PyBytes_FromStringAndSize(res, 1);
+}
+// @snippet qbytearray-getitem
+
+// @snippet qbytearray-setitem
+%CPPSELF.remove(_i, 1);
+PyObject *args = Py_BuildValue("(nO)", _i, _value);
+PyObject *result = Sbk_QByteArrayFunc_insert(self, args);
+Py_DECREF(args);
+Py_XDECREF(result);
+return !result ? -1 : 0;
+// @snippet qbytearray-setitem
+
+// @snippet qfiledevice-unmap
+uchar *ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1));
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ptr);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qfiledevice-unmap
+
+// @snippet qfiledevice-map
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1, %2, %3), %2, Shiboken::Buffer::ReadWrite);
+// @snippet qfiledevice-map
+
+// @snippet qiodevice-bufferedread
+Py_ssize_t bufferLen;
+auto *data = reinterpret_cast<char*>(Shiboken::Buffer::getPointer(%PYARG_1, &bufferLen));
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(data, PyLong_AsLongLong(%PYARG_2));
+return PyLong_FromLong(%0);
+// @snippet qiodevice-bufferedread
+
+// @snippet qiodevice-readdata
+QByteArray ba(1 + qsizetype(%2), char(0));
+%CPPSELF.%FUNCTION_NAME(ba.data(), qint64(%2));
+%PYARG_0 = Shiboken::String::fromCString(ba.constData());
+// @snippet qiodevice-readdata
+
+// @snippet qcryptographichash-adddata
+%CPPSELF.%FUNCTION_NAME(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1));
+// @snippet qcryptographichash-adddata
+
+// @snippet qmetaobject-repr
+const QByteArray repr = PySide::MetaObjectBuilder::formatMetaObject(%CPPSELF).toUtf8();
+%PYARG_0 = PyUnicode_FromString(repr.constData());
+// @snippet qmetaobject-repr
+
+// @snippet qsocketdescriptor
+#ifdef WIN32
+using DescriptorType = Qt::HANDLE;
+#else
+using DescriptorType = int;
+#endif
+// @snippet qsocketdescriptor
+
+// @snippet qsocketnotifier
+PyObject *socket = %PYARG_1;
+if (socket != nullptr) {
+ // We use qintptr as PyLong, but we check for int
+ // since it is currently an alias to be Python2 compatible.
+ // Internally, ints are qlonglongs.
+ if (%CHECKTYPE[int](socket)) {
+ int cppSocket = %CONVERTTOCPP[int](socket);
+ qintptr socket = (qintptr)cppSocket;
+ %0 = new %TYPE(socket, %2, %3);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "QSocketNotifier: first argument (socket) must be an int.");
+ }
+}
+// @snippet qsocketnotifier
+
+// @snippet qtranslator-load
+Py_ssize_t size;
+auto *ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1, &size));
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast<const uchar *>(ptr), size);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qtranslator-load
+
+// @snippet qtimer-singleshot-functorclass
+struct QSingleShotTimerFunctor : public Shiboken::PyObjectHolder
+{
+public:
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()();
+};
+
+void QSingleShotTimerFunctor::operator()()
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(0));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
+ if (Shiboken::Errors::occurred())
+ Shiboken::Errors::storeErrorOrPrint();
+ release(); // single shot
+}
+// @snippet qtimer-singleshot-functorclass
+
+// @snippet qtimer-singleshot-direct-mapping
+Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+%CPPSELF.%FUNCTION_NAME(%1, %2, %3);
+// @snippet qtimer-singleshot-direct-mapping
+
+// @snippet qtimer-singleshot-functor
+auto msec = %1;
+if (msec == 0) {
+ if (PyObject_TypeCheck(%2, PySideSignalInstance_TypeF())) {
+ auto *signal = %PYARG_2;
+ auto cppCallback = [signal]()
+ {
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef ret(PyObject_CallMethod(signal, "emit", "()"));
+ Py_DECREF(signal);
+ };
+
+ Py_INCREF(signal);
+ %CPPSELF.%FUNCTION_NAME(msec, cppCallback);
+ } else {
+ %CPPSELF.%FUNCTION_NAME(msec, QSingleShotTimerFunctor(%PYARG_2));
+ }
+} else {
+ // %FUNCTION_NAME() - disable generation of c++ function call
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+ auto *timerType = Shiboken::SbkType<QTimer>();
+ auto newFunc = reinterpret_cast<newfunc>(PepType_GetSlot(timerType, Py_tp_new));
+ auto initFunc = reinterpret_cast<initproc>(PepType_GetSlot(timerType, Py_tp_init));
+ auto *pyTimer = newFunc(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
+ initFunc(pyTimer, emptyTuple, nullptr);
+
+ QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
+ timer->setSingleShot(true);
+
+ if (PyObject_TypeCheck(%2, PySideSignalInstance_TypeF())) {
+ PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%2);
+ Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance)));
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer, "connect", "OsOO",
+ pyTimer,
+ SIGNAL(timeout()),
+ PySide::Signal::getObject(signalInstance),
+ signalSignature.object())
+ );
+ } else {
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer, "connect", "OsO",
+ pyTimer,
+ SIGNAL(timeout()),
+ %PYARG_2)
+ );
+ }
+
+ timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater, Qt::DirectConnection);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
+ Py_XDECREF(pyTimer);
+ timer->start(msec);
+}
+// @snippet qtimer-singleshot-functor
+
+// @snippet qtimer-singleshot-functor-context
+auto msec = %1;
+if (msec == 0) {
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+ auto *callable = %PYARG_3;
+ auto cppCallback = [callable]()
+ {
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(0));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+ };
+
+ Py_INCREF(callable);
+ %CPPSELF.%FUNCTION_NAME(msec, %2, cppCallback);
+} else {
+ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+ auto *timerType = Shiboken::SbkType<QTimer>();
+ auto newFunc = reinterpret_cast<newfunc>(PepType_GetSlot(timerType, Py_tp_new));
+ auto initFunc = reinterpret_cast<initproc>(PepType_GetSlot(timerType, Py_tp_init));
+ auto *pyTimer = newFunc(Shiboken::SbkType<QTimer>(), emptyTuple, nullptr);
+ initFunc(pyTimer, emptyTuple, nullptr);
+
+ QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
+ timer->setSingleShot(true);
+
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer, "connect", "OsOO",
+ pyTimer,
+ SIGNAL(timeout()),
+ %PYARG_2,
+ %PYARG_3)
+ );
+
+ timer->connect(timer, &QTimer::timeout, timer, &QObject::deleteLater, Qt::DirectConnection);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(pyTimer));
+ Py_XDECREF(pyTimer);
+ timer->start(msec);
+}
+// @snippet qtimer-singleshot-functor-context
+
+// @snippet qprocess-startdetached
+qint64 pid;
+%RETURN_TYPE retval = %TYPE::%FUNCTION_NAME(%1, %2, %3, &pid);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[qint64](pid));
+// @snippet qprocess-startdetached
+
+// @snippet qcoreapplication-init
+static void QCoreApplicationConstructor(PyObject *self, PyObject *pyargv, QCoreApplicationWrapper **cptr)
+{
+ static int argc;
+ static char **argv;
+ PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
+ if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
+ *cptr = new QCoreApplicationWrapper(argc, argv);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(self));
+ PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
+ }
+}
+// @snippet qcoreapplication-init
+
+// @snippet qcoreapplication-1
+QCoreApplicationConstructor(%PYSELF, args, &%0);
+// @snippet qcoreapplication-1
+
+// @snippet qcoreapplication-2
+PyObject *empty = PyTuple_New(2);
+if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
+ QCoreApplicationConstructor(%PYSELF, empty, &%0);
+}
+// @snippet qcoreapplication-2
+
+// @snippet qcoreapplication-instance
+PyObject *pyApp = Py_None;
+if (qApp) {
+ pyApp = reinterpret_cast<PyObject *>(
+ Shiboken::BindingManager::instance().retrieveWrapper(qApp));
+ if (!pyApp)
+ pyApp = %CONVERTTOPYTHON[QCoreApplication *](qApp);
+ // this will keep app live after python exit (extra ref)
+}
+// PYSIDE-571: make sure that we return the singleton "None"
+if (Py_TYPE(pyApp) == Py_TYPE(Py_None))
+ Py_DECREF(MakeQAppWrapper(nullptr));
+%PYARG_0 = pyApp;
+Py_XINCREF(%PYARG_0);
+// @snippet qcoreapplication-instance
+
+// @snippet qdatastream-readrawdata
+QByteArray data;
+data.resize(%2);
+int result = 0;
+Py_BEGIN_ALLOW_THREADS
+result = %CPPSELF.%FUNCTION_NAME(data.data(), data.size());
+Py_END_ALLOW_THREADS
+if (result == -1) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else {
+ %PYARG_0 = PyBytes_FromStringAndSize(data.constData(), result);
+}
+// @snippet qdatastream-readrawdata
+
+// @snippet qdatastream-writerawdata-pybuffer
+int r = 0;
+Py_ssize_t bufferLen;
+auto *data = reinterpret_cast<const char*>(Shiboken::Buffer::getPointer(%PYARG_1, &bufferLen));
+Py_BEGIN_ALLOW_THREADS
+r = %CPPSELF.%FUNCTION_NAME(data, bufferLen);
+Py_END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](r);
+// @snippet qdatastream-writerawdata-pybuffer
+
+// @snippet qdatastream-writerawdata
+int r = 0;
+Py_BEGIN_ALLOW_THREADS
+r = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1));
+Py_END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](r);
+// @snippet qdatastream-writerawdata
+
+// @snippet releaseownership
+Shiboken::Object::releaseOwnership(%PYARG_0);
+// @snippet releaseownership
+
+// @snippet qanimationgroup-clear
+for (int counter = 0, count = %CPPSELF.animationCount(); counter < count; ++counter ) {
+ QAbstractAnimation *animation = %CPPSELF.animationAt(counter);
+ PyObject *obj = %CONVERTTOPYTHON[QAbstractAnimation *](animation);
+ Shiboken::Object::setParent(nullptr, obj);
+ Py_DECREF(obj);
+}
+%CPPSELF.clear();
+// @snippet qanimationgroup-clear
+
+// @snippet qeasingcurve
+PySideEasingCurveFunctor::init();
+// @snippet qeasingcurve
+
+// @snippet qeasingcurve-setcustomtype
+QEasingCurve::EasingFunction func = PySideEasingCurveFunctor::createCustomFuntion(%PYSELF, %PYARG_1);
+if (func)
+ %CPPSELF.%FUNCTION_NAME(func);
+// @snippet qeasingcurve-setcustomtype
+
+// @snippet qeasingcurve-customtype
+//%FUNCTION_NAME()
+%PYARG_0 = PySideEasingCurveFunctor::callable(%PYSELF);
+// @snippet qeasingcurve-customtype
+
+// @snippet qt-signal
+%PYARG_0 = Shiboken::String::fromFormat("2%s",QMetaObject::normalizedSignature(%1).constData());
+// @snippet qt-signal
+
+// @snippet qt-slot
+%PYARG_0 = Shiboken::String::fromFormat("1%s",QMetaObject::normalizedSignature(%1).constData());
+// @snippet qt-slot
+
+// @snippet qt-registerresourcedata
+QT_BEGIN_NAMESPACE
+extern bool
+qRegisterResourceData(int,
+ const unsigned char *,
+ const unsigned char *,
+ const unsigned char *);
+
+extern bool
+qUnregisterResourceData(int,
+ const unsigned char *,
+ const unsigned char *,
+ const unsigned char *);
+QT_END_NAMESPACE
+// @snippet qt-registerresourcedata
+
+// @snippet qt-qregisterresourcedata
+%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_2)),
+ reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_3)),
+ reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_4)));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qt-qregisterresourcedata
+
+// @snippet qt-qunregisterresourcedata
+%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_2)),
+ reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_3)),
+ reinterpret_cast<uchar *>(PyBytes_AS_STRING(%PYARG_4)));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qt-qunregisterresourcedata
+
+// @snippet use-stream-for-format-security
+// Uses the stream version for security reasons
+// see gcc man page at -Wformat-security
+Py_BEGIN_ALLOW_THREADS
+%FUNCTION_NAME() << %1;
+Py_END_ALLOW_THREADS
+// @snippet use-stream-for-format-security
+
+// @snippet qresource-registerResource
+ auto ptr = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_1));
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast<const uchar *>(ptr), %2);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qresource-registerResource
+
+// @snippet qstring-return
+%PYARG_0 = %CONVERTTOPYTHON[QString](%1);
+// @snippet qstring-return
+
+// @snippet stream-write-method
+Py_BEGIN_ALLOW_THREADS
+(*%CPPSELF) << %1;
+Py_END_ALLOW_THREADS
+// @snippet stream-write-method
+
+// @snippet stream-read-method
+%RETURN_TYPE _cpp_result;
+Py_BEGIN_ALLOW_THREADS
+(*%CPPSELF) >> _cpp_result;
+Py_END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](_cpp_result);
+// @snippet stream-read-method
+
+// @snippet return-qstring-ref
+QString &res = *%0;
+%PYARG_0 = %CONVERTTOPYTHON[QString](res);
+// @snippet return-qstring-ref
+
+// @snippet return-readData
+%RETURN_TYPE %0 = 0;
+if (PyBytes_Check(%PYARG_0)) {
+ %0 = PyBytes_GET_SIZE(%PYARG_0.object());
+ memcpy(%1, PyBytes_AS_STRING(%PYARG_0.object()), %0);
+} else if (Shiboken::String::check(%PYARG_0.object())) {
+ %0 = Shiboken::String::len(%PYARG_0.object());
+ memcpy(%1, Shiboken::String::toCString(%PYARG_0.object()), %0);
+}
+// @snippet return-readData
+
+// @snippet qiodevice-readData
+QByteArray ba(1 + qsizetype(%2), char(0));
+Py_BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(ba.data(), qint64(%2));
+Py_END_ALLOW_THREADS
+%PYARG_0 = Shiboken::String::fromCString(ba.constData());
+// @snippet qiodevice-readData
+
+// @snippet qt-module-shutdown
+{ // Avoid name clash
+ Shiboken::AutoDecRef regFunc(static_cast<PyObject *>(nullptr));
+ Shiboken::AutoDecRef atexit(Shiboken::Module::import("atexit"));
+ if (atexit.isNull()) {
+ qWarning("Module atexit not found for registering __moduleShutdown");
+ PyErr_Clear();
+ } else {
+ regFunc.reset(PyObject_GetAttrString(atexit, "register"));
+ if (regFunc.isNull()) {
+ qWarning("Function atexit.register not found for registering __moduleShutdown");
+ PyErr_Clear();
+ }
+ }
+ if (!atexit.isNull() && !regFunc.isNull()){
+ PyObject *shutDownFunc = PyObject_GetAttrString(module, "__moduleShutdown");
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTuple_SET_ITEM(args, 0, shutDownFunc);
+ Shiboken::AutoDecRef retval(PyObject_Call(regFunc, args, 0));
+ Q_ASSERT(!retval.isNull());
+ }
+}
+// @snippet qt-module-shutdown
+
+// @snippet qthread_init_pypy
+#ifdef PYPY_VERSION
+// PYSIDE-535: PyPy 7.3.8 needs this call, which is actually a no-op in Python 3.9
+// This function should be replaced by a `Py_Initialize` call, but
+// that is still undefined. So we don't rely yet on any PyPy version.
+PyEval_InitThreads();
+#endif
+// @snippet qthread_init_pypy
+
+// @snippet qthread_exec_
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+#ifndef AVOID_PROTECTED_HACK
+int cppResult = %CPPSELF.exec();
+#else
+int cppResult = static_cast<::QThreadWrapper *>(cppSelf)->QThreadWrapper::exec_protected();
+#endif
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet qthread_exec_
+
+// @snippet exec_
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+int cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet exec_
+
+// @snippet exec_arg1
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+int cppResult;
+if (numArgs == 1)
+ cppResult = %CPPSELF.exec(%1);
+else
+ cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet exec_arg1
+
+// @snippet exec_arg1_noreturn
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+if (numArgs == 1)
+ %CPPSELF.exec(%1);
+else
+ %CPPSELF.exec();
+%END_ALLOW_THREADS
+// @snippet exec_arg1_noreturn
+
+// @snippet qtextstreammanipulator-exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%CPPSELF.exec(%1);
+// @snippet qtextstreammanipulator-exec
+
+/*********************************************************************
+ * CONVERSIONS
+ ********************************************************************/
+
+// @snippet conversion-pybool
+%out = %OUTTYPE(%in == Py_True);
+// @snippet conversion-pybool
+
+// @snippet conversion-pylong-quintptr
+#if QT_POINTER_SIZE == 8
+%out = %OUTTYPE(PyLong_AsUnsignedLongLong(%in));
+#else
+%out = %OUTTYPE(PyLong_AsUnsignedLong(%in));
+#endif
+// @snippet conversion-pylong-quintptr
+
+// @snippet conversion-pyunicode
+%out = PySide::pyUnicodeToQString(%in);
+// @snippet conversion-pyunicode
+
+// @snippet conversion-pynone
+SBK_UNUSED(%in)
+%out = %OUTTYPE();
+// @snippet conversion-pynone
+
+// @snippet qfile-path-1
+auto cppArg0 = PySide::pyPathToQString(%PYARG_1);
+// @snippet qfile-path-1
+
+// @snippet qfile-path-2
+auto cppArg1 = PySide::pyPathToQString(%PYARG_2);
+// @snippet qfile-path-2
+
+// @snippet qitemselection-add
+auto res = (*%CPPSELF) + cppArg0;
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](res);
+// @snippet qitemselection-add
+
+// @snippet conversion-pystring-char
+char c = %CONVERTTOCPP[char](%in);
+%out = %OUTTYPE(static_cast<unsigned short>(c));
+// @snippet conversion-pystring-char
+
+// @snippet conversion-pyint
+int i = %CONVERTTOCPP[int](%in);
+%out = %OUTTYPE(i);
+// @snippet conversion-pyint
+
+// @snippet conversion-qlonglong
+// PYSIDE-1250: For QVariant, if the type fits into an int; use int preferably.
+qlonglong in = %CONVERTTOCPP[qlonglong](%in);
+constexpr qlonglong intMax = qint64(std::numeric_limits<int>::max());
+constexpr qlonglong intMin = qint64(std::numeric_limits<int>::min());
+%out = in >= intMin && in <= intMax ? %OUTTYPE(int(in)) : %OUTTYPE(in);
+// @snippet conversion-qlonglong
+
+// @snippet conversion-qstring
+QString in = %CONVERTTOCPP[QString](%in);
+%out = %OUTTYPE(in);
+// @snippet conversion-qstring
+
+// @snippet conversion-qbytearray
+QByteArray in = %CONVERTTOCPP[QByteArray](%in);
+%out = %OUTTYPE(in);
+// @snippet conversion-qbytearray
+
+// @snippet conversion-pyfloat
+double in = %CONVERTTOCPP[double](%in);
+%out = %OUTTYPE(in);
+// @snippet conversion-pyfloat
+
+// @snippet conversion-sbkobject
+// a class supported by QVariant?
+const QMetaType metaType = QVariant_resolveMetaType(Py_TYPE(%in));
+bool ok = false;
+if (metaType.isValid()) {
+ QVariant var(metaType);
+ auto converterO = converterForQtType(metaType.name());
+ ok = converterO.has_value();
+ if (ok) {
+ converterO.value().toCpp(pyIn, var.data());
+ %out = var;
+ } else {
+ qWarning("%s: Cannot find a converter for \"%s\".",
+ __FUNCTION__, metaType.name());
+ }
+}
+
+// If the type was not encountered, return a default PyObjectWrapper
+if (!ok)
+ %out = QVariant::fromValue(PySide::PyObjectWrapper(%in));
+// @snippet conversion-sbkobject
+
+// @snippet conversion-pydict
+QVariant ret = QVariant_convertToVariantMap(%in);
+%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in));
+// @snippet conversion-pydict
+
+// @snippet conversion-pylist
+QVariant ret = QVariant_convertToVariantList(%in);
+%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in));
+// @snippet conversion-pylist
+
+// @snippet conversion-pyobject
+// Is a shiboken type not known by Qt
+%out = QVariant::fromValue(PySide::PyObjectWrapper(%in));
+// @snippet conversion-pyobject
+
+// @snippet conversion-qjsonobject-pydict
+QVariant dict = QVariant_convertToVariantMap(%in);
+QJsonValue val = QJsonValue::fromVariant(dict);
+%out = val.toObject();
+// @snippet conversion-qjsonobject-pydict
+
+// @snippet conversion-qdate-pydate
+int day = PyDateTime_GET_DAY(%in);
+int month = PyDateTime_GET_MONTH(%in);
+int year = PyDateTime_GET_YEAR(%in);
+%out = %OUTTYPE(year, month, day);
+// @snippet conversion-qdate-pydate
+
+// @snippet conversion-qdatetime-pydatetime
+int day = PyDateTime_GET_DAY(%in);
+int month = PyDateTime_GET_MONTH(%in);
+int year = PyDateTime_GET_YEAR(%in);
+int hour = PyDateTime_DATE_GET_HOUR(%in);
+int min = PyDateTime_DATE_GET_MINUTE(%in);
+int sec = PyDateTime_DATE_GET_SECOND(%in);
+int usec = PyDateTime_DATE_GET_MICROSECOND(%in);
+%out = %OUTTYPE(QDate(year, month, day), QTime(hour, min, sec, usec/1000));
+// @snippet conversion-qdatetime-pydatetime
+
+// @snippet conversion-qtime-pytime
+int hour = PyDateTime_TIME_GET_HOUR(%in);
+int min = PyDateTime_TIME_GET_MINUTE(%in);
+int sec = PyDateTime_TIME_GET_SECOND(%in);
+int usec = PyDateTime_TIME_GET_MICROSECOND(%in);
+%out = %OUTTYPE(hour, min, sec, usec/1000);
+// @snippet conversion-qtime-pytime
+
+// @snippet conversion-qbytearray-pybytes
+%out = %OUTTYPE(PyBytes_AS_STRING(%in), PyBytes_GET_SIZE(%in));
+// @snippet conversion-qbytearray-pybytes
+
+// @snippet conversion-qbytearray-pybytearray
+%out = %OUTTYPE(PyByteArray_AsString(%in), PyByteArray_Size(%in));
+// @snippet conversion-qbytearray-pybytearray
+
+// @snippet conversion-qbytearray-pystring
+%out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in));
+// @snippet conversion-qbytearray-pystring
+
+/*********************************************************************
+ * NATIVE TO TARGET CONVERSIONS
+ ********************************************************************/
+
+// @snippet return-pybool
+return PyBool_FromLong((bool)%in);
+// @snippet return-pybool
+
+// @snippet return-pybytes
+return PyBytes_FromStringAndSize(%in.constData(), %in.size());
+// @snippet return-pybytes
+
+// @snippet return-pylong
+return PyLong_FromLong(%in);
+// @snippet return-pylong
+
+// @snippet return-pylong-quintptr
+#if QT_POINTER_SIZE == 8
+return PyLong_FromUnsignedLongLong(%in);
+#else
+return PyLong_FromUnsignedLong(%in);
+#endif
+// @snippet return-pylong-quintptr
+
+// @snippet return-qfunctionpointer-pylong
+return PyLong_FromVoidPtr(reinterpret_cast<void *>(%in));
+// @snippet return-qfunctionpointer-pylong
+
+// @snippet conversion-pylong-qfunctionpointer
+%out = reinterpret_cast<QFunctionPointer>(PyLong_AsVoidPtr(%in));
+// @snippet conversion-pylong-qfunctionpointer
+
+// @snippet return-pyunicode
+return PySide::qStringToPyUnicode(%in);
+// @snippet return-pyunicode
+
+// @snippet return-pyunicode-from-qlatin1string
+#ifdef Py_LIMITED_API
+return PySide::qStringToPyUnicode(QString::fromLatin1(%in));
+#else
+return PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, %in.constData(), %in.size());
+#endif
+// @snippet return-pyunicode-from-qlatin1string
+
+// @snippet qlatin1string-check
+static bool qLatin1StringCheck(PyObject *o)
+{
+ return PyUnicode_CheckExact(o) != 0
+ && _PepUnicode_KIND(o) == PepUnicode_1BYTE_KIND;
+}
+// @snippet qlatin1string-check
+
+// @snippet conversion-pystring-qlatin1string
+const char *data = reinterpret_cast<const char *>(_PepUnicode_DATA(%in));
+const Py_ssize_t len = PyUnicode_GetLength(%in);
+%out = QLatin1String(data, len);
+// @snippet conversion-pystring-qlatin1string
+
+// @snippet return-pyunicode-from-qanystringview
+return PySide::qStringToPyUnicode(%in.toString());
+// @snippet return-pyunicode-from-qanystringview
+
+// @snippet return-pyunicode-qchar
+auto c = wchar_t(%in.unicode());
+return PyUnicode_FromWideChar(&c, 1);
+// @snippet return-pyunicode-qchar
+
+// @snippet return-qvariant
+if (!%in.isValid())
+ Py_RETURN_NONE;
+
+switch (%in.typeId()) {
+case QMetaType::UnknownType:
+case QMetaType::Nullptr:
+ Py_RETURN_NONE;
+case QMetaType::VoidStar:
+ if (%in.constData() == nullptr)
+ Py_RETURN_NONE;
+ break;
+
+case QMetaType::QVariantList: {
+ const auto var = %in.value<QVariantList>();
+ return %CONVERTTOPYTHON[QList<QVariant>](var);
+}
+case QMetaType::QStringList: {
+ const auto var = %in.value<QStringList>();
+ return %CONVERTTOPYTHON[QList<QString>](var);
+}
+case QMetaType::QVariantMap: {
+ const auto var = %in.value<QVariantMap>();
+ return %CONVERTTOPYTHON[QMap<QString, QVariant>](var);
+}
+default:
+ break;
+}
+
+auto converterO = converterForQtType(cppInRef.typeName());
+if (converterO.has_value())
+ return converterO.value().toPython(cppInRef.data());
+
+PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s'.", %in.typeName());
+return 0;
+// @snippet return-qvariant
+
+// @snippet return-qjsonobject
+// The QVariantMap returned by QJsonObject seems to cause a segfault, so
+// using QJsonObject.toVariantMap() won't work.
+// Wrapping it in a QJsonValue first allows it to work
+QJsonValue val(%in);
+QVariant ret = val.toVariant();
+
+return %CONVERTTOPYTHON[QVariant](ret);
+// @snippet return-qjsonobject
+
+// @snippet qthread_pthread_cleanup
+#ifdef Q_OS_UNIX
+# include <pthread.h>
+static void qthread_pthread_cleanup(void *arg)
+{
+ // PYSIDE 1282: When terminating a thread using QThread::terminate()
+ // (pthread_cancel()), QThread::run() is aborted and the lock is released,
+ // but ~GilState() is still executed for some reason. Prevent it from
+ // releasing.
+ auto gil = reinterpret_cast<Shiboken::GilState *>(arg);
+ gil->abandon();
+}
+#endif // Q_OS_UNIX
+// @snippet qthread_pthread_cleanup
+
+// @snippet qthread_pthread_cleanup_install
+#ifdef Q_OS_UNIX
+pthread_cleanup_push(qthread_pthread_cleanup, &gil);
+#endif
+// @snippet qthread_pthread_cleanup_install
+
+// @snippet qthread_pthread_cleanup_uninstall
+#ifdef Q_OS_UNIX
+pthread_cleanup_pop(0);
+#endif
+// @snippet qthread_pthread_cleanup_uninstall
+
+// @snippet qlibraryinfo_build
+auto oldResult = pyResult;
+const auto version = _PepRuntimeVersion();
+pyResult = PyUnicode_FromFormat(
+#ifdef Py_LIMITED_API
+ "%U [Python limited API %d.%d.%d]",
+#else
+ "%U [Python %d.%d.%d]",
+#endif
+ oldResult, (version >> 16) & 0xFF,
+ (version >> 8) & 0xFF, version & 0xFF);
+Py_DECREF(oldResult);
+// @snippet qlibraryinfo_build
+
+// @snippet qsharedmemory_data_readonly
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size());
+// @snippet qsharedmemory_data_readonly
+
+// @snippet qsharedmemory_data_readwrite
+// FIXME: There is no way to tell whether QSharedMemory was attached read/write
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size(),
+ Shiboken::Buffer::ReadWrite);
+// @snippet qsharedmemory_data_readwrite
+
+// @snippet std-function-void-lambda
+auto *callable = %PYARG_1;
+auto cppCallback = [callable]()
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(0));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+};
+// @snippet std-function-void-lambda
+
+// @snippet qthreadpool-start
+Py_INCREF(callable);
+%CPPSELF.%FUNCTION_NAME(cppCallback, %2);
+// @snippet qthreadpool-start
+
+// @snippet qthreadpool-trystart
+Py_INCREF(callable);
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(cppCallback);
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet qthreadpool-trystart
+
+// @snippet repr-qevent
+QString result;
+QDebug(&result).nospace() << "<PySide6.QtCore.QEvent(" << %CPPSELF->type() << ")>";
+%PYARG_0 = Shiboken::String::fromCString(qPrintable(result));
+// @snippet repr-qevent
+
+// @snippet qmetaproperty_write_enum
+if (Shiboken::Enum::check(%PYARG_2))
+ cppArg1 = QVariant(int(Shiboken::Enum::getValue(%PYARG_2)));
+// @snippet qmetaproperty_write_enum
+
+// @snippet qdatastream-read-bytes
+QByteArray data;
+data.resize(%2);
+auto dataChar = data.data();
+cppSelf->readBytes(dataChar, %2);
+const char *constDataChar = dataChar;
+if (dataChar == nullptr) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else {
+ %PYARG_0 = PyBytes_FromStringAndSize(constDataChar, %2);
+}
+// @snippet qdatastream-read-bytes
+
+// @snippet qloggingcategory_to_cpp
+// PYSIDE-2404: Usage of the `get()` function not necessary, the type exists.
+ QLoggingCategory *category{nullptr};
+ Shiboken::Conversions::pythonToCppPointer(SbkPySide6_QtCoreTypeStructs[SBK_QLoggingCategory_IDX].type,
+ pyArgs[0], &(category));
+// @snippet qloggingcategory_to_cpp
+
+// Q_ARG()-equivalent
+// @snippet q_arg
+const QArgData qArgData = qArgDataFromPyType(%1);
+if (!qArgData)
+ return nullptr;
+
+switch (qArgData.metaType.id()) {
+ case QMetaType::Bool:
+ *reinterpret_cast<bool *>(qArgData.data) = %2 == Py_True;
+ break;
+ case QMetaType::Int:
+ *reinterpret_cast<int *>(qArgData.data) = int(PyLong_AsLong(%2));
+ break;
+ case QMetaType::Double:
+ *reinterpret_cast<double *>(qArgData.data) = PyFloat_AsDouble(%2);
+ break;
+ case QMetaType::QString:
+ *reinterpret_cast<QString *>(qArgData.data) = PySide::pyUnicodeToQString(%2);
+ break;
+ default: {
+ Shiboken::Conversions::SpecificConverter converter(qArgData.metaType.name());
+ const auto type = converter.conversionType();
+ // Copy for values, Pointer for objects
+ if (type == Shiboken::Conversions::SpecificConverter::InvalidConversion) {
+ PyErr_Format(PyExc_RuntimeError, "%s: Unable to find converter for \"%s\".",
+ __FUNCTION__, qArgData.metaType.name());
+ return nullptr;
+ }
+ converter.toCpp(%2, qArgData.data);
+ }
+}
+
+QtCoreHelper::QGenericArgumentHolder result(qArgData.metaType, qArgData.data);
+%PYARG_0 = %CONVERTTOPYTHON[QtCoreHelper::QGenericArgumentHolder](result);
+// @snippet q_arg
+
+// Q_RETURN_ARG()-equivalent
+// @snippet q_return_arg
+const QArgData qArgData = qArgDataFromPyType(%1);
+if (!qArgData)
+ return nullptr;
+
+QtCoreHelper::QGenericReturnArgumentHolder result(qArgData.metaType, qArgData.data);
+%PYARG_0 = %CONVERTTOPYTHON[QtCoreHelper::QGenericReturnArgumentHolder](result);
+// @snippet q_return_arg
+
+// @snippet qmetamethod-invoke-helpers
+static InvokeMetaMethodFunc
+ createInvokeMetaMethodFunc(const QMetaMethod &method, QObject *object,
+ Qt::ConnectionType type = Qt::AutoConnection)
+{
+ return [&method, object, type](QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return method.invoke(object, type, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
+}
+
+static InvokeMetaMethodFuncWithReturn
+ createInvokeMetaMethodFuncWithReturn(const QMetaMethod &method, QObject *object,
+ Qt::ConnectionType type = Qt::AutoConnection)
+{
+ return [&method, object, type](QGenericReturnArgument r,
+ QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return method.invoke(object, type, r, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
+}
+// @snippet qmetamethod-invoke-helpers
+
+// @snippet qmetamethod-invoke-conn-type-return-arg
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(*%CPPSELF, %1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13);
+// @snippet qmetamethod-invoke-conn-type-return-arg
+
+// @snippet qmetamethod-invoke-return-arg
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(*%CPPSELF, %1),
+ %2, %3, %4, %5, %6, %7, %8, %9, %10, %11, %12);
+// @snippet qmetamethod-invoke-return-arg
+
+// @snippet qmetamethod-invoke-conn-type
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(*%CPPSELF, %1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12);
+// @snippet qmetamethod-invoke-conn-type
+
+// @snippet qmetamethod-invoke
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(*%CPPSELF, %1),
+ %2, %3, %4, %5, %6, %7, %8, %9, %10, %11);
+// @snippet qmetamethod-invoke
+
+// @snippet qmetaobject-invokemethod-helpers
+static InvokeMetaMethodFunc
+ createInvokeMetaMethodFunc(QObject *object, const char *methodName,
+ Qt::ConnectionType type = Qt::AutoConnection)
+{
+ return [object, methodName, type](QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return QMetaObject::invokeMethod(object, methodName, type,
+ a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
+}
+
+static InvokeMetaMethodFuncWithReturn
+ createInvokeMetaMethodFuncWithReturn(QObject *object, const char *methodName,
+ Qt::ConnectionType type = Qt::AutoConnection)
+{
+ return [object, methodName, type](QGenericReturnArgument r,
+ QGenericArgument a0, QGenericArgument a1,
+ QGenericArgument a2, QGenericArgument a3,
+ QGenericArgument a4, QGenericArgument a5,
+ QGenericArgument a6, QGenericArgument a7,
+ QGenericArgument a8, QGenericArgument a9) -> bool
+ {
+ return QMetaObject::invokeMethod(object, methodName, type,
+ r, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ };
+}
+// @snippet qmetaobject-invokemethod-helpers
+
+// invokeMethod(QObject *,const char *, QGenericArgument a0, a1, a2 )
+// @snippet qmetaobject-invokemethod-arg
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(%1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12);
+// @snippet qmetaobject-invokemethod-arg
+
+// invokeMethod(QObject *,const char *,Qt::ConnectionType, QGenericArgument a0, a1, a2 )
+// @snippet qmetaobject-invokemethod-conn-type-arg
+%PYARG_0 = invokeMetaMethod(createInvokeMetaMethodFunc(%1, %2, %3),
+ %4, %5, %6, %7, %8, %9, %10, %11, %12, %13);
+// @snippet qmetaobject-invokemethod-conn-type-arg
+
+// invokeMethod(QObject *,const char *, Qt::ConnectionType, QGenericReturnArgument,QGenericArgument a0, a1, a2 )
+// @snippet qmetaobject-invokemethod-conn-type-return-arg
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(%1, %2, %3),
+ %4, %5, %6, %7, %8, %9, %10, %11, %12, %13, %14);
+// @snippet qmetaobject-invokemethod-conn-type-return-arg
+
+// invokeMethod(QObject *,const char *, QGenericReturnArgument,QGenericArgument a0, a1, a2 )
+// @snippet qmetaobject-invokemethod-return-arg
+%PYARG_0 = invokeMetaMethodWithReturn(createInvokeMetaMethodFuncWithReturn(%1, %2),
+ %3, %4, %5, %6, %7, %8, %9, %10, %11, %12, %13);
+// @snippet qmetaobject-invokemethod-return-arg
+
+// @snippet keycombination-from-keycombination
+cptr = new ::%TYPE(%1);
+// @snippet keycombination-from-keycombination
+
+// @snippet keycombination-from-modifier
+cptr = new ::%TYPE(%1, %2);
+// @snippet keycombination-from-modifier
+
+// @snippet qmetamethod-from-signal
+auto *signalInst = reinterpret_cast<PySideSignalInstance *>(%PYARG_1);
+const auto data = PySide::Signal::getEmitterData(signalInst);
+const auto result = data.methodIndex != -1
+ ? data.emitter->metaObject()->method(data.methodIndex)
+ : QMetaMethod{};
+%PYARG_0 = %CONVERTTOPYTHON[QMetaMethod](result);
+// @snippet qmetamethod-from-signal
+
+// @snippet qrunnable_create
+auto callable = %PYARG_1;
+auto callback = [callable]() -> void
+{
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 1 of %FUNCTION_NAME must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, nullptr));
+ Py_DECREF(callable);
+};
+Py_INCREF(callable);
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(callback);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qrunnable_create
+
+// @snippet qlocale_system
+// For darwin systems, QLocale::system() involves looking at the Info.plist of the application
+// bundle to detect the system localization. In the case of Qt for Python, the application bundle
+// is the used Python framework. To enable retreival of localized string, the property list key
+// CFBunldeAllowMixedLocalizations should be set to True inside the Info.plist file. Otherwise,
+// CFBundleDevelopmentRegion will be used to find the language preference of the user, which in the
+// case of Python is always english.
+// This is a hack until CFBunldeAllowMixedLocalizations will be set in the Python framework
+// installation in darwin systems.
+// Upstream issue in CPython: https://github.com/python/cpython/issues/108269
+#ifdef Q_OS_DARWIN
+ Shiboken::AutoDecRef locale(PyImport_ImportModule("locale"));
+ Shiboken::AutoDecRef getLocale(PyObject_GetAttrString(locale, "getlocale"));
+ Shiboken::AutoDecRef systemLocale(PyObject_CallObject(getLocale, nullptr));
+ PyObject* localeCode = PyTuple_GetItem(systemLocale, 0);
+ %RETURN_TYPE %0;
+ if (localeCode != Py_None) {
+ QString localeCodeStr = PySide::pyStringToQString(localeCode);
+ %0 = QLocale(localeCodeStr);
+ } else {
+ // The default locale is 'C' locale as mentioned in
+ // https://docs.python.org/3/library/locale.html
+ %0 = ::QLocale::c();
+ }
+#else
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
+#endif
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qlocale_system
+
+// @snippet qcoreapplication-requestpermission
+auto permission = %1;
+auto callable = %PYARG_3;
+
+// check if callable
+if (!PyCallable_Check(callable)) {
+ qWarning("Functor of %FUNCTION_NAME is not a callable");
+ return {};
+}
+
+// find the number of arguments of callable. It should either be empy or accept a QPermission
+// object
+int count = 0;
+PyObject* fc = nullptr;
+bool classMethod = false;
+Shiboken::AutoDecRef func_ob(PyObject_GetAttr(callable, Shiboken::PyMagicName::func()));
+
+if (func_ob.isNull() && PyObject_HasAttr(callable, Shiboken::PyMagicName::code())) {
+ // variable `callable` is a function
+ fc = PyObject_GetAttr(callable, Shiboken::PyMagicName::code());
+} else {
+ // variable `callable` is a class method
+ fc = PyObject_GetAttr(func_ob, Shiboken::PyMagicName::code());
+ classMethod = true;
+}
+
+if (fc) {
+ PyObject* ac = PyObject_GetAttrString(fc, "co_argcount");
+ if (ac) {
+ count = PyLong_AsLong(ac);
+ Py_DECREF(ac);
+ }
+ Py_DECREF(fc);
+}
+
+if ((classMethod && (count > 2)) || (!classMethod && (count > 1))) {
+ qWarning("Functor of %FUNCTION_NAME must either have QPermission object as argument or none."
+ "The QPermission object store the result of requestPermission()");
+ return {};
+}
+
+bool arg_qpermission = (classMethod && (count == 2)) || (!classMethod && (count == 1));
+
+auto callback = [callable, count, arg_qpermission](const QPermission &permission) -> void
+{
+ Shiboken::GilState state;
+ if (arg_qpermission) {
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist.object(), 0, %CONVERTTOPYTHON[QPermission](permission));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ } else {
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, nullptr));
+ }
+ Py_DECREF(callable);
+};
+Py_INCREF(callable);
+
+Py_BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(permission, %2, callback);
+Py_END_ALLOW_THREADS
+// @snippet qcoreapplication-requestpermission
+
+// @snippet qlockfile-getlockinfo
+qint64 pid{};
+QString hostname, appname;
+%CPPSELF.%FUNCTION_NAME(&pid, &hostname, &appname);
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[qint64](pid));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](hostname));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[QString](appname));
+// @snippet qlockfile-getlockinfo
+
+// @snippet darwin_permission_plugin
+#ifdef Q_OS_DARWIN
+#include<QtCore/qplugin.h>
+// register the static plugin and setup its metadata
+Q_IMPORT_PLUGIN(QDarwinCameraPermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinMicrophonePermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinBluetoothPermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinContactsPermissionPlugin)
+Q_IMPORT_PLUGIN(QDarwinCalendarPermissionPlugin)
+#endif
+// @snippet darwin_permission_plugin
+
+// @snippet qt-modifier
+PyObject *_inputDict = PyDict_New();
+// Note: The builtins line is no longer needed since Python 3.10. Undocumented!
+PyDict_SetItemString(_inputDict, "__builtins__", PyEval_GetBuiltins());
+PyDict_SetItemString(_inputDict, "QtCore", module);
+PyDict_SetItemString(_inputDict, "Qt", reinterpret_cast<PyObject *>(pyType));
+// Explicitly not dereferencing the result.
+PyRun_String(R"PY(if True:
+ from enum import Flag
+ from textwrap import dedent
+ from warnings import warn
+ # QtCore and Qt come as globals.
+
+ def func_or(self, other):
+ if isinstance(self, Flag) and isinstance(other, Flag):
+ # this is normal or-ing flags together
+ return Qt.KeyboardModifier(self.value | other.value)
+ return QtCore.QKeyCombination(self, other)
+
+ def func_add(self, other):
+ warn(dedent(f"""
+ The "+" operator is deprecated in Qt For Python 6.0 .
+ Please use "|" instead."""), stacklevel=2)
+ return func_or(self, other)
+
+ Qt.KeyboardModifier.__or__ = func_or
+ Qt.KeyboardModifier.__ror__ = func_or
+ Qt.Modifier.__or__ = func_or
+ Qt.Modifier.__ror__ = func_or
+ Qt.KeyboardModifier.__add__ = func_add
+ Qt.KeyboardModifier.__radd__ = func_add
+ Qt.Modifier.__add__ = func_add
+ Qt.Modifier.__radd__ = func_add
+
+)PY", Py_file_input, _inputDict, _inputDict);
+// @snippet qt-modifier
diff --git a/sources/pyside6/PySide6/glue/qtdatavisualization.cpp b/sources/pyside6/PySide6/glue/qtdatavisualization.cpp
new file mode 100644
index 000000000..3a179cb17
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtdatavisualization.cpp
@@ -0,0 +1,90 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet releaseownership
+Shiboken::Object::releaseOwnership(%PYARG_1);
+// @snippet releaseownership
+
+// @snippet qcustom3dvolume-settexturedata
+using VectorType = decltype(%1);
+%CPPSELF.setTextureData(new VectorType(%1));
+// @snippet qcustom3dvolume-settexturedata
+
+// @snippet dataproxy-addrow
+using ListType = decltype(%1);
+%RETURN_TYPE %0 = %CPPSELF.addRow(new ListType(%1));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet dataproxy-addrow
+
+// @snippet dataproxy-addrow-string
+using ListType = decltype(%1);
+%RETURN_TYPE %0 = %CPPSELF.addRow(new ListType(%1), %2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet dataproxy-addrow-string
+
+// @snippet dataproxy-insertrow
+using ListType = decltype(%2);
+%CPPSELF.insertRow(%1, new ListType(%2));
+// @snippet dataproxy-insertrow
+
+// @snippet dataproxy-insertrow-string
+using ListType = decltype(%2);
+%CPPSELF.insertRow(%1, new ListType(%2), %3);
+// @snippet dataproxy-insertrow-string
+
+// @snippet dataproxy-setrow
+using ListType = decltype(%2);
+%CPPSELF.setRow(%1, new ListType(%2));
+// @snippet dataproxy-setrow
+
+// @snippet dataproxy-setrow-string
+using ListType = decltype(%2);
+%CPPSELF.setRow(%1, new ListType(%2), %3);
+// @snippet dataproxy-setrow-string
+
+// @snippet dataproxy-resetarray
+using ListType = decltype(%1);
+%CPPSELF.resetArray(new ListType(%1));
+// @snippet dataproxy-resetarray
+
+// @snippet dataproxy-resetarray2
+using ListType = decltype(%1);
+%CPPSELF.resetArray(new ListType(%1), %2, %3);
+// @snippet dataproxy-resetarray2
+
+// @snippet scatterdataproxy-resetarray
+%CPPSELF.resetArray(new QScatterDataArray(*%1));
+// @snippet scatterdataproxy-resetarray
+
+// @snippet qsurfacedataproxy-resetarraynp
+auto *data = QtDataVisualizationHelper::surfaceDataFromNp(%1, %2, %3, %4, %5);
+// %CPPSELF.%FUNCTION_NAME
+%CPPSELF.resetArray(data);
+// @snippet qsurfacedataproxy-resetarraynp
+
+// @snippet qvalue3daxisformatter-friend
+class QFriendlyValue3DAxisFormatter : public QValue3DAxisFormatter
+{
+public:
+using QValue3DAxisFormatter::gridPositions;
+using QValue3DAxisFormatter::labelPositions;
+using QValue3DAxisFormatter::labelStrings;
+};
+
+static inline QFriendlyValue3DAxisFormatter *friendlyFormatter(QValue3DAxisFormatter *f)
+{
+ return static_cast<QFriendlyValue3DAxisFormatter *>(f);
+}
+// @snippet qvalue3daxisformatter-friend
+
+// @snippet qvalue3daxisformatter-setgridpositions
+friendlyFormatter(%CPPSELF)->gridPositions() = %1;
+// @snippet qvalue3daxisformatter-setgridpositions
+
+// @snippet qvalue3daxisformatter-setlabelpositions
+friendlyFormatter(%CPPSELF)->labelPositions() = %1;
+// @snippet qvalue3daxisformatter-setlabelpositions
+
+// @snippet qvalue3daxisformatter-setlabelstrings
+friendlyFormatter(%CPPSELF)->labelStrings() = %1;
+// @snippet qvalue3daxisformatter-setlabelstrings
diff --git a/sources/pyside6/PySide6/glue/qtdesigner.cpp b/sources/pyside6/PySide6/glue/qtdesigner.cpp
new file mode 100644
index 000000000..d26d9f857
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtdesigner.cpp
@@ -0,0 +1,7 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qtdesigner-registercustomwidget
+if (!QPyDesignerCustomWidgetCollection::_registerCustomWidgetHelper(%PYARG_1, kwds))
+ return {};
+// @snippet qtdesigner-registercustomwidget
diff --git a/sources/pyside6/PySide6/glue/qtgraphs.cpp b/sources/pyside6/PySide6/glue/qtgraphs.cpp
new file mode 100644
index 000000000..b5a5db799
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtgraphs.cpp
@@ -0,0 +1,8 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet graphs-qsurfacedataproxy-resetarraynp
+auto data = QtGraphsHelper::surfaceDataFromNp(%1, %2, %3, %4, %5);
+// %CPPSELF.%FUNCTION_NAME
+%CPPSELF.resetArray(data);
+// @snippet graphs-qsurfacedataproxy-resetarraynp
diff --git a/sources/pyside6/PySide6/glue/qtgui.cpp b/sources/pyside6/PySide6/glue/qtgui.cpp
new file mode 100644
index 000000000..5c860a2bf
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtgui.cpp
@@ -0,0 +1,947 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet gui-declarations
+QT_BEGIN_NAMESPACE
+void qt_set_sequence_auto_mnemonic(bool);
+QT_END_NAMESPACE
+// @snippet gui-declarations
+
+// @snippet qaccessible-pysidefactory
+// Helper for QAccessible::installFactory() that forwards the calls to
+// Python callables.
+class PySideAccessibleFactory
+{
+ PySideAccessibleFactory() = default;
+public:
+ ~PySideAccessibleFactory();
+
+ static PySideAccessibleFactory *instance() { return m_instance; }
+ static PySideAccessibleFactory *ensureInstance();
+
+ static void installFactory(PyObject *f);
+ static void cleanup();
+
+ static QAccessibleInterface *factory(const QString &key, QObject *o);
+
+private:
+ QAccessibleInterface *callFactories(const QString &key, QObject *o);
+
+ static PySideAccessibleFactory *m_instance;
+
+ QList<PyObject *> m_factoryFunctions;
+ QList<PyObject *> m_objects;
+};
+
+PySideAccessibleFactory *PySideAccessibleFactory::m_instance = nullptr;
+
+PySideAccessibleFactory::~PySideAccessibleFactory()
+{
+ QAccessible::removeFactory(PySideAccessibleFactory::factory);
+ if (!m_factoryFunctions.isEmpty()) {
+ Shiboken::GilState state;
+ for (auto *f : m_factoryFunctions)
+ Py_DECREF(f);
+ for (auto *o : m_objects)
+ Py_DECREF(o);
+ }
+}
+
+PySideAccessibleFactory *PySideAccessibleFactory::ensureInstance()
+{
+ if (m_instance == nullptr) {
+ m_instance = new PySideAccessibleFactory;
+ QAccessible::installFactory(PySideAccessibleFactory::factory);
+ qAddPostRoutine(PySideAccessibleFactory::cleanup);
+ }
+ return m_instance;
+}
+
+void PySideAccessibleFactory::installFactory(PyObject *f)
+{
+ if (m_instance != nullptr) {
+ Py_INCREF(f);
+ m_instance->m_factoryFunctions.append(f);
+ }
+}
+
+void PySideAccessibleFactory::cleanup()
+{
+ delete m_instance;
+ m_instance = nullptr;
+}
+
+QAccessibleInterface *PySideAccessibleFactory::factory(const QString &key, QObject *o)
+{
+ return m_instance ? m_instance->callFactories(key, o) : nullptr;
+}
+
+QAccessibleInterface *PySideAccessibleFactory::callFactories(const QString &key, QObject *o)
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(2));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](key));
+ PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QObject *](o));
+
+ for (auto *f : m_factoryFunctions) {
+ if (PyObject *pyResult = PyObject_CallObject(f, arglist)) {
+ if (pyResult != Py_None) {
+ m_objects.append(pyResult);
+ QAccessibleInterface* result = %CONVERTTOCPP[QAccessibleInterface *](pyResult);
+ return result;
+ }
+ Py_DECREF(pyResult);
+ }
+ }
+
+ return nullptr;
+}
+// @snippet qaccessible-pysidefactory
+
+// @snippet qaccessible-installfactory
+PySideAccessibleFactory::ensureInstance()->installFactory(%1);
+// @snippet qaccessible-installfactory
+
+// @snippet qaction-menu
+// %CPPSELF->menu(); // pretend it was called.
+QObject *object = %CPPSELF->menu<QObject *>();
+%PYARG_0 = %CONVERTTOPYTHON[QObject*](object);
+// @snippet qaction-menu
+
+// @snippet qopenglfunctions-glgetv-return-size
+// Return the number of return values of the glGetBoolean/Double/Integerv functions
+// cf https://registry.khronos.org/OpenGL-Refpages/gl4/html/glGet.xhtml
+static int glGetVReturnSize(GLenum pname)
+{
+ switch (pname) {
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_DEPTH_RANGE:
+ case GL_MAX_VIEWPORT_DIMS:
+#if !QT_CONFIG(opengles2)
+ case GL_POINT_SIZE_RANGE:
+ case GL_SMOOTH_LINE_WIDTH_RANGE:
+ case GL_VIEWPORT_BOUNDS_RANGE:
+#endif
+ return 2;
+ case GL_BLEND_COLOR:
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_COLOR_WRITEMASK:
+ case GL_SCISSOR_BOX:
+ case GL_VIEWPORT:
+ return 4;
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ return GL_NUM_COMPRESSED_TEXTURE_FORMATS;
+ default:
+ break;
+ }
+ return 1;
+}
+// @snippet qopenglfunctions-glgetv-return-size
+
+// @snippet qopenglextrafunctions-glgeti-v-return-size
+// Return the number of return values of the indexed
+// glGetBoolean/Double/Integeri_v functions
+// cf https://registry.khronos.org/OpenGL-Refpages/gl4/html/glGet.xhtml
+static int glGetI_VReturnSize(GLenum pname)
+{
+ return pname == GL_VIEWPORT ? 4 : 1;
+}
+// @snippet qopenglextrafunctions-glgeti-v-return-size
+
+// @snippet qopenglfunctions-glgetbooleanv
+const int size = glGetVReturnSize(%1);
+QVarLengthArray<GLboolean> result(size, GL_FALSE);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[bool](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createByteArray1(size, result.constData());
+}
+// @snippet qopenglfunctions-glgetbooleanv
+
+// @snippet qopenglfunctions-glgetdoublev
+const int size = glGetVReturnSize(%1);
+QVarLengthArray<GLdouble> result(size, 0);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[double](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createDoubleArray1(size, result.constData());
+}
+// @snippet qopenglfunctions-glgetdoublev
+
+// @snippet qopenglfunctions-glgetfloatv
+const int size = glGetVReturnSize(%1);
+QVarLengthArray<GLfloat> result(size, 0);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[float](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createFloatArray1(size, result.constData());
+}
+// @snippet qopenglfunctions-glgetfloatv
+
+// @snippet qopenglfunctions-glgetintegerv
+const int size = glGetVReturnSize(%1);
+QVarLengthArray<GLint> result(size, 0);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[int](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createIntArray1(size, result.constData());
+}
+// @snippet qopenglfunctions-glgetintegerv
+
+// @snippet qopenglextrafunctions-glgetbooleani-v
+const int size = glGetI_VReturnSize(%1);
+QVarLengthArray<GLboolean> result(size, GL_FALSE);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[bool](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createByteArray1(size, result.constData());
+}
+// @snippet qopenglextrafunctions-glgetbooleani-v
+
+// @snippet qopenglextrafunctions-glgetdoublei-v
+const int size = glGetI_VReturnSize(%1);
+QVarLengthArray<GLdouble> result(size, 0);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[double](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createDoubleArray1(size, result.constData());
+}
+// @snippet qopenglextrafunctions-glgetdoublei-v
+
+// @snippet qopenglextrafunctions-glgetfloati-v
+const int size = glGetI_VReturnSize(%1);
+QVarLengthArray<GLfloat> result(size, 0);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[float](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createFloatArray1(size, result.constData());
+}
+// @snippet qopenglextrafunctions-glgetfloati-v
+
+// @snippet qopenglextrafunctions-glgetintegeri-v
+const int size = glGetI_VReturnSize(%1);
+QVarLengthArray<GLint> result(size, 0);
+%CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, result.data());
+if (size == 1) {
+ %PYARG_0 = %CONVERTTOPYTHON[int](result[0]);
+} else {
+ %PYARG_0 = Shiboken::Numpy::createIntArray1(size, result.constData());
+}
+// @snippet qopenglextrafunctions-glgetintegeri-v
+
+// @snippet glgetshadersource
+GLsizei bufSize = 4096;
+GLsizei length = bufSize - 1;
+QByteArray buffer;
+for (; length == bufSize - 1; bufSize += 4096) {
+ buffer.resize(qsizetype(bufSize));
+ %CPPSELF->%FUNCTION_NAME(%1, bufSize, &length, buffer.data());
+ if (%CPPSELF->glGetError() != GL_NO_ERROR) {
+ buffer.clear();
+ break;
+ }
+}
+auto *data = buffer.constData();
+%PYARG_0 = %CONVERTTOPYTHON[char *](data);
+// @snippet glgetshadersource
+
+// @snippet glshadersource
+const QByteArray buffer = %2.toUtf8();
+const char *sources[] = {buffer.constData()};
+%CPPSELF->%FUNCTION_NAME(%1, 1, sources, nullptr);
+// @snippet glshadersource
+
+// @snippet glgetstring-return
+%PYARG_0 = %CONVERTTOPYTHON[const char *](%0);
+// @snippet glgetstring-return
+
+// @snippet qtransform-quadtoquad
+QTransform _result;
+if (QTransform::quadToQuad(%1, %2, _result)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qtransform-quadtoquad
+
+// @snippet qtransform-quadtosquare
+QTransform _result;
+if (QTransform::quadToSquare(%1, _result)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qtransform-quadtosquare
+
+// @snippet qtransform-squaretoquad
+QTransform _result;
+if (QTransform::squareToQuad(%1, _result)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qtransform-squaretoquad
+
+// @snippet qbitmap-fromdata
+auto *buffer = reinterpret_cast<uchar *>(Shiboken::Buffer::getPointer(%PYARG_2));
+QBitmap %0 = QBitmap::fromData(%1, buffer, %3);
+%PYARG_0 = %CONVERTTOPYTHON[QBitmap](%0);
+// @snippet qbitmap-fromdata
+
+// @snippet qtextline-cursortox
+%RETURN_TYPE %0 = %CPPSELF->::%TYPE::%FUNCTION_NAME(&%1, %2);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+// @snippet qtextline-cursortox
+
+// @snippet qkeysequence-getitem
+if (_i < 0 || _i >= %CPPSELF.count()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+}
+QKeyCombination item = (*%CPPSELF)[_i];
+return %CONVERTTOPYTHON[QKeyCombination](item);
+// @snippet qkeysequence-getitem
+
+// @snippet qkeysequence-repr
+auto ObTuple_Type = reinterpret_cast<PyObject *>(&PyTuple_Type);
+auto ObSelf_Type = reinterpret_cast<PyObject *>(Py_TYPE(%PYSELF));
+Shiboken::AutoDecRef surrogate(PyObject_CallFunctionObjArgs(ObTuple_Type, %PYSELF, nullptr));
+Shiboken::AutoDecRef argstr(PyObject_Repr(surrogate));
+Shiboken::AutoDecRef name(PyObject_GetAttrString(ObSelf_Type, "__name__"));
+return PyUnicode_Concat(name, argstr);
+// @snippet qkeysequence-repr
+
+// @snippet qpicture-data
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.data(), %CPPSELF.size());
+// @snippet qpicture-data
+
+// @snippet qtextblock-setuserdata
+const QTextDocument *doc = %CPPSELF.document();
+if (doc) {
+ Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument *](doc));
+ Shiboken::Object::setParent(pyDocument, %PYARG_1);
+}
+// @snippet qtextblock-setuserdata
+
+// @snippet qtextblock-userdata
+const QTextDocument *doc = %CPPSELF.document();
+if (doc) {
+ Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument *](doc));
+ Shiboken::Object::setParent(pyDocument, %PYARG_0);
+}
+// @snippet qtextblock-userdata
+
+// @snippet qpolygon-reduce
+const Py_ssize_t count = %CPPSELF.size();
+PyObject *points = PyList_New(count);
+for (Py_ssize_t i = 0; i < count; ++i){
+ int x, y;
+ %CPPSELF.point(i, &x, &y);
+ QPoint pt{x, y};
+ PyList_SET_ITEM(points, i, %CONVERTTOPYTHON[QPoint](pt));
+}
+// @snippet qpolygon-reduce
+
+// @snippet qpolygon-operatorlowerlower
+// %FUNCTION_NAME()
+*%CPPSELF << %1;
+%PYARG_0 = %CONVERTTOPYTHON[QPolygon *](%CPPSELF);
+// @snippet qpolygon-operatorlowerlower
+
+// @snippet qpixmap
+%0 = new %TYPE(QPixmap::fromImage(%1));
+// @snippet qpixmap
+
+// @snippet qicon-addpixmap
+const auto path = PySide::pyPathToQString(%PYARG_1);
+%CPPSELF->addPixmap(path);
+// @snippet qicon-addpixmap
+
+// @snippet qclipboard-setpixmap
+const auto path = PySide::pyPathToQString(%PYARG_1);
+%CPPSELF->setPixmap(QPixmap(path));
+// @snippet qclipboard-setpixmap
+
+// @snippet qclipboard-setimage
+const auto path = PySide::pyPathToQString(%PYARG_1);
+%CPPSELF->setImage(QImage(path));
+// @snippet qclipboard-setimage
+
+// @snippet qimage-decref-image-data
+static void imageDecrefDataHandler(void *data)
+{
+ // Avoid "Python memory allocator called without holding the GIL"
+ auto state = PyGILState_Ensure();
+ Py_DECREF(reinterpret_cast<PyObject *>(data));
+ PyGILState_Release(state);
+}
+// @snippet qimage-decref-image-data
+
+// @snippet qimage-constbits
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.sizeInBytes());
+// @snippet qimage-constbits
+
+// @snippet qimage-bits
+// byteCount() is only available on Qt4.7, so we use bytesPerLine * height
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.bytesPerLine() * %CPPSELF.height(), Shiboken::Buffer::ReadWrite);
+// @snippet qimage-bits
+
+// @snippet qimage-constscanline
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine());
+// @snippet qimage-constscanline
+
+// @snippet qimage-scanline
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine(), Shiboken::Buffer::ReadWrite);
+// @snippet qimage-scanline
+
+// @snippet qcolor-setstate
+Shiboken::AutoDecRef func(PyObject_GetAttr(%PYSELF, PyTuple_GET_ITEM(%1, 0)));
+PyObject *args = PyTuple_GET_ITEM(%1, 1);
+%PYARG_0 = PyObject_Call(func, args, nullptr);
+// @snippet qcolor-setstate
+
+// @snippet qcolor-reduce
+switch (%CPPSELF.spec()) {
+ case QColor::Rgb:
+ {
+ float r, g, b, a;
+ %CPPSELF.getRgbF(&r, &g, &b, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setRgbF", r, g, b, a);
+ break;
+ }
+ case QColor::Hsv:
+ {
+ float h, s, v, a;
+ %CPPSELF.getHsvF(&h, &s, &v, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setHsvF", h, s, v, a);
+ break;
+ }
+ case QColor::Cmyk:
+ {
+ float c, m, y, k, a;
+ %CPPSELF.getCmykF(&c, &m, &y, &k, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(fffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setCmykF", c, m, y, k, a);
+ break;
+ }
+ case QColor::Hsl:
+ {
+ float h, s, l, a;
+ %CPPSELF.getHslF(&h, &s, &l, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setHslF", h, s, l, a);
+ break;
+ }
+ default:
+ {
+ %PYARG_0 = Py_BuildValue("(N(O))", PyObject_Type(%PYSELF), Py_None);
+ }
+}
+// @snippet qcolor-reduce
+
+// @snippet qcolor-totuple
+switch (%CPPSELF.spec()) {
+ case QColor::Rgb:
+ {
+ int r, g, b, a;
+ %CPPSELF.getRgb(&r, &g, &b, &a);
+ %PYARG_0 = Py_BuildValue("iiii", r, g, b, a);
+ break;
+ }
+ case QColor::Hsv:
+ {
+ int h, s, v, a;
+ %CPPSELF.getHsv(&h, &s, &v, &a);
+ %PYARG_0 = Py_BuildValue("iiii", h, s, v, a);
+ break;
+ }
+ case QColor::Cmyk:
+ {
+ int c, m, y, k, a;
+ %CPPSELF.getCmyk(&c, &m, &y, &k, &a);
+ %PYARG_0 = Py_BuildValue("iiiii", c, m, y, k, a);
+ break;
+ }
+ case QColor::Hsl:
+ {
+ int h, s, l, a;
+ %CPPSELF.getHsl(&h, &s, &l, &a);
+ %PYARG_0 = Py_BuildValue("iiii", h, s, l, a);
+ break;
+ }
+ default:
+ {
+ %PYARG_0 = 0;
+ }
+}
+// @snippet qcolor-totuple
+
+// @snippet qcolor
+if (%1.type() == QVariant::Color)
+ %0 = new %TYPE(%1.value<QColor>());
+else
+ PyErr_SetString(PyExc_TypeError, "QVariant must be holding a QColor");
+// @snippet qcolor
+
+// @snippet qfontmetricsf-boundingrect
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 5) {
+ array = Shiboken::sequenceToIntArray(%PYARG_5, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetricsf-boundingrect
+
+// @snippet qfontmetricsf-size
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 4) {
+ array = Shiboken::sequenceToIntArray(%PYARG_4, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetricsf-size
+
+// @snippet qfontmetrics-boundingrect-1
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 8) {
+ array = Shiboken::sequenceToIntArray(%PYARG_8, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetrics-boundingrect-1
+
+// @snippet qfontmetrics-boundingrect-2
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 5) {
+ array = Shiboken::sequenceToIntArray(%PYARG_5, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetrics-boundingrect-2
+
+// @snippet qfontmetrics-size
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 4) {
+ array = Shiboken::sequenceToIntArray(%PYARG_4, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetrics-size
+
+// @snippet qpixmapcache-find
+QPixmap p;
+if (%CPPSELF.%FUNCTION_NAME(%1, &p)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QPixmap](p);
+} else {
+ %PYARG_0 = Py_None;
+ Py_INCREF(%PYARG_0);
+}
+// @snippet qpixmapcache-find
+
+// @snippet qstandarditem-setchild-1
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->child(%1, %2);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditem-setchild-1
+
+// @snippet qstandarditem-setchild-2
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->child(%1);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditem-setchild-2
+
+// @snippet qkeyevent-operatornotequal
+bool ret = !(&%CPPSELF == %1);
+%PYARG_0 = %CONVERTTOPYTHON[bool](ret);
+// @snippet qkeyevent-operatornotequal
+
+// @snippet qstandarditemmodel-setitem-1
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->item(%1, %2);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditemmodel-setitem-1
+
+// @snippet qstandarditemmodel-setitem-2
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->item(%1);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditemmodel-setitem-2
+
+// @snippet qstandarditemmodel-setverticalheaderitem
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->verticalHeaderItem(%1);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditemmodel-setverticalheaderitem
+
+// @snippet qstandarditemmodel-clear
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+SbkObject *pyRoot = bm.retrieveWrapper(%CPPSELF.invisibleRootItem());
+if (pyRoot) {
+ Shiboken::Object::destroy(pyRoot, %CPPSELF.invisibleRootItem());
+}
+
+for (int r=0, r_max = %CPPSELF.rowCount(); r < r_max; r++) {
+ QList<QStandardItem *> ri = %CPPSELF.takeRow(0);
+
+ PyObject *pyResult = %CONVERTTOPYTHON[QList<QStandardItem * >](ri);
+ Shiboken::Object::setParent(Py_None, pyResult);
+ Py_XDECREF(pyResult);
+}
+// @snippet qstandarditemmodel-clear
+
+// @snippet qclipboard-text
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+// @snippet qclipboard-text
+
+// @snippet qpainter-drawpointsnp-numpy-x-y
+const auto points = PySide::Numpy::xyDataToQPointFList(%PYARG_1, %PYARG_2);
+%CPPSELF.drawPoints(points);
+// @snippet qpainter-drawpointsnp-numpy-x-y
+
+// @snippet qpainter-drawpolygon
+%CPPSELF.%FUNCTION_NAME(%1.constData(), %1.size(), %2);
+// @snippet qpainter-drawpolygon
+
+// @snippet qpainter-enter
+Py_INCREF(%PYSELF);
+pyResult = %PYSELF;
+// @snippet qpainter-enter
+
+// @snippet qpainter-exit
+%CPPSELF.end();
+// @snippet qpainter-exit
+
+// @snippet qmatrix4x4
+// PYSIDE-795: All PySequences can be made iterable with PySequence_Fast.
+Shiboken::AutoDecRef seq(PySequence_Fast(%PYARG_1, "Can't turn into sequence"));
+if (PySequence_Size(seq) == 16) {
+ float values[16];
+ for (Py_ssize_t i = 0; i < 16; ++i) {
+ PyObject *pv = PySequence_Fast_GET_ITEM(seq.object(), i);
+ values[i] = PyFloat_AsDouble(pv);
+ }
+
+ %0 = new %TYPE(values[0], values[1], values[2], values[3],
+ values[4], values[5], values[6], values[7],
+ values[8], values[9], values[10], values[11],
+ values[12], values[13], values[14], values[15]);
+}
+// @snippet qmatrix4x4
+
+// @snippet qmatrix4x4-copydatato
+float values[16];
+%CPPSELF.%FUNCTION_NAME(values);
+%PYARG_0 = PyTuple_New(16);
+for (Py_ssize_t i = 0; i < 16; ++i) {
+ PyObject *v = PyFloat_FromDouble(values[i]);
+ PyTuple_SET_ITEM(%PYARG_0, i, v);
+}
+// @snippet qmatrix4x4-copydatato
+
+// @snippet qmatrix4x4-mgetitem
+if (PySequence_Check(_key)) {
+ Shiboken::AutoDecRef key(PySequence_Fast(_key, "Invalid matrix index."));
+ if (PySequence_Fast_GET_SIZE(key.object()) == 2) {
+ PyObject *posx = PySequence_Fast_GET_ITEM(key.object(), 0);
+ PyObject *posy = PySequence_Fast_GET_ITEM(key.object(), 1);
+ Py_ssize_t x = PyLong_AsSsize_t(posx);
+ Py_ssize_t y = PyLong_AsSsize_t(posy);
+ float ret = (*%CPPSELF)(x,y);
+ return %CONVERTTOPYTHON[float](ret);
+ }
+}
+PyErr_SetString(PyExc_IndexError, "Invalid matrix index.");
+return 0;
+// @snippet qmatrix4x4-mgetitem
+
+// @snippet qguiapplication-init
+static void QGuiApplicationConstructor(PyObject *self, PyObject *pyargv, QGuiApplicationWrapper **cptr)
+{
+ static int argc;
+ static char **argv;
+ PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
+ if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
+ *cptr = new QGuiApplicationWrapper(argc, argv, 0);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(self));
+ PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
+ }
+}
+// @snippet qguiapplication-init
+
+// @snippet qguiapplication-1
+QGuiApplicationConstructor(%PYSELF, args, &%0);
+// @snippet qguiapplication-1
+
+// @snippet qguiapplication-2
+PyObject *empty = PyTuple_New(2);
+if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
+ QGuiApplicationConstructor(%PYSELF, empty, &%0);
+}
+// @snippet qguiapplication-2
+
+// @snippet qguiapplication-setoverridecursor
+auto *cppResult = new QtGuiHelper::QOverrideCursorGuard();
+%PYARG_0 = %CONVERTTOPYTHON[QtGuiHelper::QOverrideCursorGuard*](cppResult);
+Shiboken::Object::getOwnership(%PYARG_0); // Ensure the guard is removed
+// @snippet qguiapplication-setoverridecursor
+
+// @snippet qguiapplication-nativeInterface
+bool hasNativeApp = false;
+#if QT_CONFIG(xcb)
+if (auto *x11App = %CPPSELF.nativeInterface<QNativeInterface::QX11Application>()) {
+ hasNativeApp = true;
+ %PYARG_0 = %CONVERTTOPYTHON[QNativeInterface::QX11Application*](x11App);
+}
+#endif
+if (!hasNativeApp) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qguiapplication-nativeInterface
+
+// @snippet qscreen-grabWindow
+WId id = %1;
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id, %2, %3, %4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+// @snippet qscreen-grabWindow
+
+// @snippet qscreen-nativeInterface
+bool hasNativeScreen = false;
+#ifdef Q_OS_WIN
+if (auto *winScreen = %CPPSELF.nativeInterface<QNativeInterface::QWindowsScreen>()) {
+ hasNativeScreen = true;
+ %PYARG_0 = %CONVERTTOPYTHON[QNativeInterface::QWindowsScreen*](winScreen);
+}
+#endif
+if (!hasNativeScreen) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qscreen-nativeInterface
+
+// @snippet qx11application-resource-ptr
+ auto *resource = %CPPSELF.%FUNCTION_NAME();
+%PYARG_0 = PyLong_FromVoidPtr(resource);
+// @snippet qx11application-resource-ptr
+
+// @snippet qwindow-fromWinId
+WId id = %1;
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+// @snippet qwindow-fromWinId
+
+// @snippet set-qtkey-shortcut
+%CPPSELF.%FUNCTION_NAME(QKeyCombination(%1));
+// @snippet set-qtkey-shortcut
+
+// @snippet qshortcut-1
+%0 = new %TYPE(%1, %2);
+// @snippet qshortcut-1
+
+// @snippet qshortcut-2
+Shiboken::AutoDecRef result(PyObject_CallMethod(%PYSELF, "connect", "OsO",
+ %PYSELF, SIGNAL(activated()), %PYARG_3)
+ );
+if (!result.isNull())
+ Shiboken::Object::setParent(%PYARG_2, %PYSELF);
+// @snippet qshortcut-2
+
+// @snippet qguiapplication-exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+int cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet qguiapplication-exec
+
+// @snippet qdrag-exec-arg1
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+int cppResult = %CPPSELF.exec(%1);
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet qdrag-exec-arg1
+
+// @snippet qdrag-exec-arg2
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+int cppResult;
+if (numArgs == 2)
+ cppResult = %CPPSELF.exec(%1, %2);
+else if (numArgs == 1)
+ cppResult = %CPPSELF.exec(%1);
+else
+ cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet qdrag-exec-arg2
+
+// @snippet qquaternion-getaxisandangle-vector3d-float
+QVector3D outVec{};
+float angle{};
+%CPPSELF.%FUNCTION_NAME(&outVec, &angle);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QVector3D](outVec));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[float](angle));
+// @snippet qquaternion-getaxisandangle-vector3d-float
+
+// @snippet qquaternion-geteulerangles
+float pitch{}, yaw{}, roll{};
+%CPPSELF.%FUNCTION_NAME(&pitch, &yaw, &roll);
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[float](pitch));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[float](yaw));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[float](roll));
+// @snippet qquaternion-geteulerangles
+
+// @snippet qregion-len
+return %CPPSELF.rectCount();
+// @snippet qregion-len
+
+// @snippet qregion-getitem
+if (_i < 0 || _i >= %CPPSELF.rectCount())
+ return PyErr_Format(PyExc_IndexError, "index out of bounds");
+
+const QRect cppResult = *(%CPPSELF.cbegin() + _i);
+return %CONVERTTOPYTHON[QRect](cppResult);
+// @snippet qregion-getitem
+
+// Some RHI functions take a std::initializer_list<>. Add functions
+// to convert from list.
+
+// @snippet qrhi-initializer-list
+%CPPSELF.%FUNCTION_NAME(%1.cbegin(), %1.cend());
+// @snippet qrhi-initializer-list
+
+// @snippet qrhi-commandbuffer-setvertexinput
+%CPPSELF.%FUNCTION_NAME(%1, %2.size(), %2.constData(), %3, %4, %5);
+// @snippet qrhi-commandbuffer-setvertexinput
+
+/*********************************************************************
+ * CONVERSIONS
+ ********************************************************************/
+
+// @snippet conversion-pylong
+%out = reinterpret_cast<%OUTTYPE>(PyLong_AsVoidPtr(%in));
+// @snippet conversion-pylong
+
+/*********************************************************************
+ * NATIVE TO TARGET CONVERSIONS
+ ********************************************************************/
+
+// @snippet return-pylong-voidptr
+return PyLong_FromVoidPtr(reinterpret_cast<void *>(%in));
+// @snippet return-pylong-voidptr
diff --git a/sources/pyside6/PySide6/glue/qtmultimedia.cpp b/sources/pyside6/PySide6/glue/qtmultimedia.cpp
new file mode 100644
index 000000000..ac8434b97
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtmultimedia.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qvideoframe-bits
+#include "object.h"
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1);
+%END_ALLOW_THREADS
+const auto size = %CPPSELF.mappedBytes(%1);
+%PYARG_0 = Shiboken::Buffer::newObject(%0, size, Shiboken::Buffer::ReadWrite);
+// @snippet qvideoframe-bits
+
+// @snippet qaudiobuffer-data
+unsigned char *data = %CPPSELF.%FUNCTION_NAME<unsigned char>();
+const auto size = %CPPSELF.byteCount();
+%PYARG_0 = Shiboken::Buffer::newObject(data, size, Shiboken::Buffer::ReadWrite);
+// @snippet qaudiobuffer-data
+
+// @snippet qaudiobuffer-const-data
+const unsigned char *data = %CPPSELF.%FUNCTION_NAME<unsigned char>();
+const auto size = %CPPSELF.byteCount();
+%PYARG_0 = Shiboken::Buffer::newObject(data, size);
+// @snippet qaudiobuffer-const-data
+
+// @snippet qtaudio-namespace-compatibility-alias
+Py_INCREF(pyType);
+PyModule_AddObject(module, "QtAudio", reinterpret_cast<PyObject *>(pyType));
+// @snippet qtaudio-namespace-compatibility-alias
diff --git a/sources/pyside6/PySide6/glue/qtnetwork.cpp b/sources/pyside6/PySide6/glue/qtnetwork.cpp
new file mode 100644
index 000000000..f635f4671
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtnetwork.cpp
@@ -0,0 +1,130 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qudpsocket-readdatagram
+Shiboken::AutoArrayPointer<char> data(%ARGUMENT_NAMES);
+QHostAddress ha;
+quint16 port;
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(data, %ARGUMENT_NAMES, &ha, &port);
+%END_ALLOW_THREADS
+QByteArray ba(data, retval);
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QByteArray](ba));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QHostAddress](ha));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[quint16](port));
+// @snippet qudpsocket-readdatagram
+
+// @snippet qhostinfo-lookuphost-functor
+struct QHostInfoFunctor : public Shiboken::PyObjectHolder
+{
+public:
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()(const QHostInfo &hostInfo);
+};
+
+void QHostInfoFunctor::operator()(const QHostInfo &hostInfo)
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ auto *pyHostInfo = %CONVERTTOPYTHON[QHostInfo](hostInfo);
+ PyTuple_SET_ITEM(arglist.object(), 0, pyHostInfo);
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
+ release(); // single shot
+}
+// @snippet qhostinfo-lookuphost-functor
+
+// @snippet qhostinfo-lookuphost-callable
+%CPPSELF.%FUNCTION_NAME(%1, QHostInfoFunctor(%PYARG_2));
+// @snippet qhostinfo-lookuphost-callable
+
+// @snippet qipv6address-len
+return 16;
+// @snippet qipv6address-len
+
+// @snippet qipv6address-getitem
+if (_i >= 16) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+}
+if (_i < 0)
+ _i = 16 - qAbs(_i);
+
+uint item = %CPPSELF.c[_i];
+return %CONVERTTOPYTHON[uint](item);
+// @snippet qipv6address-getitem
+
+// @snippet qipv6address-setitem
+if (_i >= 16) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return -1;
+}
+if (_i < 0)
+ _i = 16 - qAbs(_i);
+quint8 item = %CONVERTTOCPP[quint8](_value);
+%CPPSELF.c[_i] = item;
+return 0;
+// @snippet qipv6address-setitem
+
+// @snippet qrestaccessmanager-functor
+class QRestFunctor
+{
+public:
+ explicit QRestFunctor(PyObject *callable) noexcept : m_callable(callable)
+ {
+ Py_INCREF(callable);
+ }
+
+ void operator()(QRestReply &restReply);
+
+private:
+ PyObject *m_callable;
+};
+
+void QRestFunctor::operator()(QRestReply &restReply)
+{
+ Q_ASSERT(m_callable);
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ auto *restReplyPtr = &restReply;
+ auto *pyRestReply = %CONVERTTOPYTHON[QRestReply*](restReplyPtr);
+ PyTuple_SET_ITEM(arglist.object(), 0, pyRestReply);
+ Shiboken::AutoDecRef ret(PyObject_CallObject(m_callable, arglist));
+ Py_DECREF(m_callable);
+ m_callable = nullptr;
+}
+// @snippet qrestaccessmanager-functor
+
+// @snippet qrestaccessmanager-callback
+auto *networkReply = %CPPSELF.%FUNCTION_NAME(%1, %2, QRestFunctor(%PYARG_3));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](networkReply);
+// @snippet qrestaccessmanager-callback
+
+// @snippet qrestaccessmanager-data-callback
+auto *networkReply = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, QRestFunctor(%PYARG_4));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](networkReply);
+// @snippet qrestaccessmanager-data-callback
+
+// @snippet qrestaccessmanager-method-data-callback
+auto *networkReply = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, QRestFunctor(%PYARG_5));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](networkReply);
+// @snippet qrestaccessmanager-method-data-callback
+
+// @snippet qrestreply-readjson
+QJsonParseError jsonParseError;
+std::optional<QJsonDocument> documentOptional = %CPPSELF.%FUNCTION_NAME(&jsonParseError);
+
+PyObject *pyDocument{};
+if (documentOptional.has_value()) {
+ const auto &document = documentOptional.value();
+ pyDocument = %CONVERTTOPYTHON[QJsonDocument](document);
+} else {
+ pyDocument = Py_None;
+ Py_INCREF(Py_None);
+}
+
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SetItem(%PYARG_0, 0, pyDocument);
+PyTuple_SetItem(%PYARG_0, 1, %CONVERTTOPYTHON[QJsonParseError](jsonParseError));
+// @snippet qrestreply-readjson
diff --git a/sources/pyside6/PySide6/glue/qtnetworkauth.cpp b/sources/pyside6/PySide6/glue/qtnetworkauth.cpp
new file mode 100644
index 000000000..7877a8dd5
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtnetworkauth.cpp
@@ -0,0 +1,44 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qabstractoauth-lookuphost-functor
+struct QAbstractOAuthModifyFunctor : public Shiboken::PyObjectHolder
+{
+public:
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()(QAbstractOAuth::Stage stage, QMultiMap<QString, QVariant>* dictPointer);
+};
+
+void QAbstractOAuthModifyFunctor::operator()(QAbstractOAuth::Stage stage,
+ QMultiMap<QString, QVariant>* dictPointer)
+{
+ auto *callable = object();
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 1 of setModifyParametersFunction() must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ QMultiMap<QString, QVariant> dict = *dictPointer;
+ Shiboken::AutoDecRef arglist(PyTuple_New(2));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QAbstractOAuth::Stage](stage));
+ PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMultiMap<QString, QVariant>](dict));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+
+ if (!ret.isNull() && PyDict_Check(ret.object()) != 0) {
+ PyObject *key{};
+ PyObject *value{};
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(ret.object(), &pos, &key, &value)) {
+ QString cppKey = %CONVERTTOCPP[QString](key);
+ QVariant cppValue = %CONVERTTOCPP[QVariant](value);
+ dictPointer->replace(cppKey, cppValue);
+ }
+ }
+}
+// @snippet qabstractoauth-lookuphost-functor
+
+// @snippet qabstractoauth-setmodifyparametersfunction
+%CPPSELF.%FUNCTION_NAME(QAbstractOAuthModifyFunctor(%PYARG_1));
+// @snippet qabstractoauth-setmodifyparametersfunction
+
diff --git a/sources/pyside6/PySide6/glue/qtopengl.cpp b/sources/pyside6/PySide6/glue/qtopengl.cpp
new file mode 100644
index 000000000..cdfaafb3b
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtopengl.cpp
@@ -0,0 +1,89 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet qopenglshaderprogram_setuniformvalue_float
+float value = %2;
+%CPPSELF.setUniformValue(%1, value);
+// @snippet qopenglshaderprogram_setuniformvalue_float
+
+// @snippet qopenglshaderprogram_setuniformvalue_int
+int value = %2;
+%CPPSELF.setUniformValue(%1, value);
+// @snippet qopenglshaderprogram_setuniformvalue_int
+
+// @snippet qopenglversionfunctionsfactory-get
+QAbstractOpenGLFunctions *af = %CPPSELF.%FUNCTION_NAME(%1, %2);
+if (auto *f = dynamic_cast<QOpenGLFunctions_4_5_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_5_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_5_Compatibility *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_5_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_4_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_4_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_4_Compatibility *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_4_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_3_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_3_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_2_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_2_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_1_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_1_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_0_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_0_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_4_0_Compatibility *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_4_0_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_3_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_3_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_3_Compatibility *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_3_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_2_Core *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_2_Core *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_2_Compatibility *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_2_Compatibility *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_1 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_1 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_3_0 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_3_0 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_2_1 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_2_1 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_2_0 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_2_0 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_5 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_5 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_4 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_4 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_3 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_3 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_2 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_2 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_1 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_1 *](f);
+} else if (auto *f = dynamic_cast<QOpenGLFunctions_1_0 *>(af)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QOpenGLFunctions_1_0 *](f);
+} else {
+ QString message;
+ QDebug(&message) << "No OpenGL functions could be obtained for" << %1;
+ PyErr_SetString(PyExc_RuntimeError, message.toUtf8().constData());
+ %PYARG_0 = Py_None;
+}
+// @snippet qopenglversionfunctionsfactory-get
+
+// @snippet glgetvreturnsize_declaration
+int glGetVReturnSize(GLenum pname);
+// @snippet glgetvreturnsize_declaration
+
+// @snippet glgeti-vreturnsize_declaration
+int glGetI_VReturnSize(GLenum pname);
+// @snippet glgeti-vreturnsize_declaration
+
+// @snippet vao-binder-enter
+Py_INCREF(%PYSELF);
+pyResult = %PYSELF;
+// @snippet vao-binder-enter
+
+// @snippet vao-binder-exit
+%CPPSELF.release();
+// @snippet vao-binder-exit
diff --git a/sources/pyside6/PySide6/glue/qtpositioning.cpp b/sources/pyside6/PySide6/glue/qtpositioning.cpp
new file mode 100644
index 000000000..91c331c74
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtpositioning.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet darwin_location_permission_plugin
+#ifdef Q_OS_DARWIN
+#include<QtCore/qplugin.h>
+// register the static plugin and setup its metadata
+Q_IMPORT_PLUGIN(QDarwinLocationPermissionPlugin)
+#endif
+// @snippet darwin_location_permission_plugin
diff --git a/sources/pyside6/PySide6/glue/qtprintsupport.cpp b/sources/pyside6/PySide6/glue/qtprintsupport.cpp
new file mode 100644
index 000000000..39672c62a
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtprintsupport.cpp
@@ -0,0 +1,20 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet setpagesize
+bool out = %CPPSELF.setPageSize(%1);
+%PYARG_0 = %CONVERTTOPYTHON[bool](out);
+// @snippet setpagesize
+
+// @snippet exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+int cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet exec
diff --git a/sources/pyside6/PySide6/glue/qtqml.cpp b/sources/pyside6/PySide6/glue/qtqml.cpp
new file mode 100644
index 000000000..a56db8de6
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtqml.cpp
@@ -0,0 +1,90 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qmlerrror-repr
+const QByteArray message = %CPPSELF.toString().toUtf8();
+%PYARG_0 = Shiboken::String::fromCString(message.constData());
+// @snippet qmlerrror-repr
+
+// @snippet qmlattachedpropertiesobject
+auto *%0 = PySide::Qml::qmlAttachedPropertiesObject(%ARGUMENT_NAMES);
+%PYARG_0 = %CONVERTTOPYTHON[QObject*](%0);
+// @snippet qmlattachedpropertiesobject
+
+// @snippet qmlregistertype
+int %0 = PySide::Qml::qmlRegisterType(%ARGUMENT_NAMES);
+%PYARG_0 = %CONVERTTOPYTHON[int](%0);
+// @snippet qmlregistertype
+
+// @snippet qmlregistersingletontype_qobject_callback
+int %0 = PySide::Qml::qmlRegisterSingletonType(%ARGUMENT_NAMES, true, true);
+%PYARG_0 = %CONVERTTOPYTHON[int](%0);
+// @snippet qmlregistersingletontype_qobject_callback
+
+// @snippet qmlregistersingletontype_qobject_nocallback
+int %0 = PySide::Qml::qmlRegisterSingletonType(%ARGUMENT_NAMES, nullptr, true, false);
+%PYARG_0 = %CONVERTTOPYTHON[int](%0);
+// @snippet qmlregistersingletontype_qobject_nocallback
+
+// @snippet qmlregistersingletontype_qjsvalue
+int %0 = PySide::Qml::qmlRegisterSingletonType(nullptr, %ARGUMENT_NAMES, false, true);
+%PYARG_0 = %CONVERTTOPYTHON[int](%0);
+// @snippet qmlregistersingletontype_qjsvalue
+
+// @snippet qmlregistersingletoninstance
+int %0 = PySide::Qml::qmlRegisterSingletonInstance(%ARGUMENT_NAMES);
+%PYARG_0 = %CONVERTTOPYTHON[int](%0);
+// @snippet qmlregistersingletoninstance
+
+// @snippet qmlregisteruncreatabletype
+int %0 = PySide::Qml::qmlRegisterType(%ARGUMENT_NAMES, false);
+%PYARG_0 = %CONVERTTOPYTHON[int](%0);
+// @snippet qmlregisteruncreatabletype
+
+// @snippet init
+PySide::Qml::init(module);
+initQtQmlVolatileBool(module);
+// @snippet init
+
+// @snippet qjsengine-toscriptvalue
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1);
+return %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+// @snippet qjsengine-toscriptvalue
+
+// @snippet qmlelement
+%PYARG_0 = PySide::Qml::qmlElementMacro(%ARGUMENT_NAMES);
+// @snippet qmlelement
+
+// @snippet qmlanonymous
+%PYARG_0 = PySide::Qml::qmlAnonymousMacro(%ARGUMENT_NAMES);
+// @snippet qmlanonymous
+
+// @snippet qmlsingleton
+%PYARG_0 = PySide::Qml::qmlSingletonMacro(%ARGUMENT_NAMES);
+// @snippet qmlsingleton
+
+// @snippet qqmlengine-singletoninstance-qmltypeid
+QJSValue instance = %CPPSELF.singletonInstance<QJSValue>(%1);
+if (instance.isNull()) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else if (instance.isQObject()) {
+ QObject *result = instance.toQObject();
+ %PYARG_0 = %CONVERTTOPYTHON[QObject *](result);
+} else {
+ %PYARG_0 = %CONVERTTOPYTHON[QJSValue](instance);
+}
+// @snippet qqmlengine-singletoninstance-qmltypeid
+
+// @snippet qqmlengine-singletoninstance-typename
+QJSValue instance = %CPPSELF.singletonInstance<QJSValue>(%1, %2);
+if (instance.isNull()) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else if (instance.isQObject()) {
+ QObject *result = instance.toQObject();
+ %PYARG_0 = %CONVERTTOPYTHON[QObject *](result);
+} else {
+ %PYARG_0 = %CONVERTTOPYTHON[QJSValue](instance);
+}
+// @snippet qqmlengine-singletoninstance-typename
diff --git a/sources/pyside6/PySide6/glue/qtquick.cpp b/sources/pyside6/PySide6/glue/qtquick.cpp
new file mode 100644
index 000000000..060418faf
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtquick.cpp
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qtquick
+PySide::initQuickSupport(module);
+// @snippet qtquick
+
+// @snippet qsgeometry-vertexdataaspoint2d
+auto *points = %CPPSELF->vertexDataAsPoint2D();
+const Py_ssize_t vertexCount = %CPPSELF->vertexCount();
+%PYARG_0 = PyList_New(vertexCount);
+for (Py_ssize_t i = 0; i < vertexCount; ++i) {
+ QSGGeometry::Point2D p = points[i];
+ PyList_SET_ITEM(%PYARG_0, i, %CONVERTTOPYTHON[QSGGeometry::Point2D](p));
+}
+// @snippet qsgeometry-vertexdataaspoint2d
+
+// @snippet qsgeometry-setvertexdataaspoint2d
+const qsizetype vertexCount = %CPPSELF->vertexCount();
+if (vertexCount != %1.size()) {
+ PyErr_SetString(PyExc_RuntimeError, "size mismatch");
+ return {};
+}
+
+QSGGeometry::Point2D *points = %CPPSELF->vertexDataAsPoint2D();
+std::copy(%1.cbegin(), %1.cend(), points);
+// @snippet qsgeometry-setvertexdataaspoint2d
diff --git a/sources/pyside6/PySide6/glue/qtquicktest.cpp b/sources/pyside6/PySide6/glue/qtquicktest.cpp
new file mode 100644
index 000000000..f41735ddf
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtquicktest.cpp
@@ -0,0 +1,50 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet call-quick-test-main
+static int callQuickTestMain(const QString &name, QObject *setup,
+ QStringList argv, QString dir)
+{
+ if (dir.isEmpty())
+ dir = QDir::currentPath();
+ if (argv.isEmpty())
+ argv.append(name);
+
+ std::vector<QByteArray> argvB;
+ std::vector<char *> argvC;
+ const auto argc = argv.size();
+ argvB.reserve(argc);
+ argvC.reserve(argc);
+ for (const auto &arg : argv) {
+ argvB.emplace_back(arg.toUtf8());
+ argvC.push_back(argvB.back().data());
+ }
+
+ return quick_test_main_with_setup(int(argc), argvC.data(),
+ name.toUtf8().constData(),
+ dir.toUtf8().constData(), setup);
+}
+// @snippet call-quick-test-main
+
+// @snippet quick-test-main
+const int exitCode = callQuickTestMain(%1, nullptr, %2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[int](exitCode);
+// @snippet quick-test-main
+
+// @snippet quick-test-main_with_setup
+Shiboken::AutoDecRef pySetupObject(PyObject_CallObject(reinterpret_cast<PyObject *>(%2), nullptr));
+if (pySetupObject.isNull() || PyErr_Occurred() != nullptr)
+ return nullptr;
+
+/// Convenience to convert a PyObject to QObject
+QObject *setupObject = PySide::convertToQObject(pySetupObject.object(), true /* raiseError */);
+if (setupObject == nullptr)
+ return nullptr;
+
+const int exitCode = callQuickTestMain(%1, setupObject, %3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[int](exitCode);
+// @snippet quick-test-main_with_setup
diff --git a/sources/pyside6/PySide6/glue/qtserialbus.cpp b/sources/pyside6/PySide6/glue/qtserialbus.cpp
new file mode 100644
index 000000000..b5b491f49
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtserialbus.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet qcanbus-available-devices
+QString errorMessage;
+const QList<QCanBusDeviceInfo> result = %CPPSELF.%FUNCTION_NAME(%1, &errorMessage);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QList<QCanBusDeviceInfo>](result));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](errorMessage));
+// @snippet qcanbus-available-devices
+
+// @snippet qcanbus-createdevice
+PyObject *pyDevice{};
+QString errorMessage;
+if (auto *device = %CPPSELF.%FUNCTION_NAME(%1, %2, &errorMessage)) {
+ pyDevice = %CONVERTTOPYTHON[%RETURN_TYPE](device);
+ // Ownership transferences (target)
+ Shiboken::Object::getOwnership(pyDevice);
+} else {
+ pyDevice = Py_None;
+ Py_INCREF(pyDevice);
+}
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, pyDevice);
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](errorMessage));
+// @snippet qcanbus-createdevice
diff --git a/sources/pyside6/PySide6/glue/qtsql.cpp b/sources/pyside6/PySide6/glue/qtsql.cpp
new file mode 100644
index 000000000..ff0d7a7a4
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtsql.cpp
@@ -0,0 +1,60 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+
+// @snippet simple-exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+bool cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+// @snippet simple-exec
+
+
+// @snippet qsqldatabase-exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+QSqlQuery cppResult = %CPPSELF.exec(%1);
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[QSqlQuery](cppResult);
+// @snippet qsqldatabase-exec
+
+// @snippet qsqlquery-exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+bool cppResult = %CPPSELF.exec(%1);
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+// @snippet qsqlquery-exec
+
+// @snippet qsqlresult-exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+#ifndef AVOID_PROTECTED_HACK
+bool cppResult = %CPPSELF.exec();
+#else
+bool cppResult = static_cast<::QSqlResultWrapper *>(cppSelf)->QSqlResultWrapper::exec_protected();
+#endif
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+// @snippet qsqlresult-exec
diff --git a/sources/pyside6/PySide6/glue/qtstatemachine.cpp b/sources/pyside6/PySide6/glue/qtstatemachine.cpp
new file mode 100644
index 000000000..098200b14
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtstatemachine.cpp
@@ -0,0 +1,67 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet qsignaltransition
+if (PyObject_TypeCheck(%1, PySideSignalInstance_TypeF())) {
+ auto *signalInstance = reinterpret_cast<PySideSignalInstance *>(%PYARG_1);
+ PyObject *dataSource = PySide::Signal::getObject(signalInstance);
+ Shiboken::AutoDecRef obType(PyObject_Type(dataSource));
+ QObject * sender = %CONVERTTOCPP[QObject *](dataSource);
+ //XXX /|\ omitting this space crashes shiboken!
+ if (sender) {
+ const char *dataSignature = PySide::Signal::getSignature(signalInstance);
+ QByteArray signature(dataSignature); // Append SIGNAL flag (2)
+ signature.prepend('2');
+ %0 = new QSignalTransitionWrapper(sender, signature, %2);
+ }
+}
+// @snippet qsignaltransition
+
+// @snippet qstate-addtransition-1
+QByteArray signalName(%2);
+signalName.remove(0, 1);
+if (PySide::SignalManager::registerMetaMethod(%1, signalName.constData(),
+ QMetaMethod::Signal)) {
+ QSignalTransition *%0 = %CPPSELF->addTransition(%1, %2, %3);
+ %PYARG_0 = %CONVERTTOPYTHON[QSignalTransition *](%0);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qstate-addtransition-1
+
+// @snippet qstate-addtransition-2
+// Obviously the label used by the following goto is a very awkward solution,
+// since it refers to a name very tied to the generator implementation.
+// Check bug #362 for more information on this
+// http://bugs.openbossa.org/show_bug.cgi?id=362
+// PYSIDE-2256: The label was removed
+if (!PyObject_TypeCheck(%1, PySideSignalInstance_TypeF()))
+ return Shiboken::returnWrongArguments(args, fullName, errInfo);
+PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%1);
+auto sender = %CONVERTTOCPP[QObject *](PySide::Signal::getObject(signalInstance));
+QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSignature(signalInstance),%2);
+%PYARG_0 = %CONVERTTOPYTHON[QSignalTransition *](%0);
+// @snippet qstate-addtransition-2
+
+// @snippet qstatemachine-configuration
+%PYARG_0 = PySet_New(0);
+for (auto *abs_state : %CPPSELF.configuration()) {
+ Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractState *](abs_state));
+ Shiboken::Object::setParent(self, obj);
+ PySet_Add(%PYARG_0, obj);
+}
+// @snippet qstatemachine-configuration
+
+// @snippet qstatemachine-defaultanimations
+%PYARG_0 = PyList_New(0);
+for (auto *abs_anim : %CPPSELF.defaultAnimations()) {
+ Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractAnimation *](abs_anim));
+ Shiboken::Object::setParent(self, obj);
+ PyList_Append(%PYARG_0, obj);
+}
+// @snippet qstatemachine-defaultanimations
diff --git a/sources/pyside6/PySide6/glue/qttest.cpp b/sources/pyside6/PySide6/glue/qttest.cpp
new file mode 100644
index 000000000..626cc1608
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qttest.cpp
@@ -0,0 +1,24 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet qsignalspy-signal
+auto *signalInst = reinterpret_cast<PySideSignalInstance *>(%PYARG_1);
+PyObject *emitterPyObject = PySide::Signal::getObject(signalInst);
+QObject* emitter = %CONVERTTOCPP[QObject *](emitterPyObject);
+QByteArray signature = PySide::Signal::getSignature(signalInst);
+if (!signature.isEmpty())
+ signature.prepend('2'); // SIGNAL() macro
+
+if (emitter == nullptr || signature.isEmpty()) {
+ QByteArray error = QByteArrayLiteral("Wrong parameter (")
+ + (%PYARG_1)->ob_type->tp_name
+ + QByteArrayLiteral(") passed, QSignalSpy requires a signal.");
+ PyErr_SetString(PyExc_ValueError, error.constData());
+ return -1;
+}
+%0 = new QSignalSpyWrapper(emitter, signature.constData());
+// @snippet qsignalspy-signal
diff --git a/sources/pyside6/PySide6/glue/qtuitools.cpp b/sources/pyside6/PySide6/glue/qtuitools.cpp
new file mode 100644
index 000000000..1835ed096
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtuitools.cpp
@@ -0,0 +1,212 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// @snippet uitools-loadui
+/*
+ * Based on code provided by:
+ * Antonio Valentino <antonio.valentino at tiscali.it>
+ * Frédéric <frederic.mantegazza at gbiloba.org>
+ */
+
+#include <shiboken.h>
+
+#include <QtUiTools/QUiLoader>
+#include <QtWidgets/QWidget>
+#include <QtCore/QFile>
+
+static void createChildrenNameAttributes(PyObject *root, QObject *object)
+{
+ for (auto *child : object->children()) {
+ const QByteArray name = child->objectName().toLocal8Bit();
+
+ if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
+ Shiboken::AutoDecRef attrName(Py_BuildValue("s", name.constData()));
+ if (!PyObject_HasAttr(root, attrName)) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child));
+ PyObject_SetAttr(root, attrName, pyChild);
+ }
+ createChildrenNameAttributes(root, child);
+ }
+ createChildrenNameAttributes(root, child);
+ }
+}
+
+static PyObject *QUiLoadedLoadUiFromDevice(QUiLoader *self, QIODevice *dev, QWidget *parent)
+{
+ QWidget *wdg = self->load(dev, parent);
+
+ if (wdg) {
+ PyObject *pyWdg = %CONVERTTOPYTHON[QWidget *](wdg);
+ createChildrenNameAttributes(pyWdg, wdg);
+ if (parent) {
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent));
+ Shiboken::Object::setParent(pyParent, pyWdg);
+ }
+ return pyWdg;
+ }
+
+ if (!PyErr_Occurred())
+ PyErr_Format(PyExc_RuntimeError, "Unable to open/read ui device");
+ return nullptr;
+}
+
+static PyObject *QUiLoaderLoadUiFromFileName(QUiLoader *self, const QString &uiFile, QWidget *parent)
+{
+ QFile fd(uiFile);
+ return QUiLoadedLoadUiFromDevice(self, &fd, parent);
+}
+// @snippet uitools-loadui
+
+// @snippet quiloader
+Q_IMPORT_PLUGIN(PyCustomWidgets);
+// @snippet quiloader
+
+// @snippet quiloader-registercustomwidget
+registerCustomWidget(%PYARG_1);
+%CPPSELF.addPluginPath(QString{}); // force reload widgets
+// @snippet quiloader-registercustomwidget
+
+// @snippet quiloader-load-1
+// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
+%PYARG_0 = QUiLoadedLoadUiFromDevice(%CPPSELF, %1, %2);
+// @snippet quiloader-load-1
+
+// @snippet quiloader-load-2
+// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
+auto str = PySide::pyPathToQString(%1);
+%PYARG_0 = QUiLoaderLoadUiFromFileName(%CPPSELF, str, %2);
+// @snippet quiloader-load-2
+
+// @snippet loaduitype
+/*
+Arguments:
+ %PYARG_1 (uifile)
+*/
+// 1. Generate the Python code from the UI file
+PyObject *strObj = PyUnicode_AsUTF8String(%PYARG_1);
+char *arg1 = PyBytes_AsString(strObj);
+QByteArray uiFileName(arg1);
+Py_DECREF(strObj);
+
+if (uiFileName.isEmpty()) {
+ qCritical() << "Error converting the UI filename to QByteArray";
+ Py_RETURN_NONE;
+}
+
+QFile uiFile(QString::fromUtf8(uiFileName));
+
+if (!uiFile.exists()) {
+ qCritical().noquote() << "File" << uiFileName << "does not exist";
+ Py_RETURN_NONE;
+}
+
+// Use the 'pyside6-uic' wrapper instead of 'uic'
+// This approach is better than rely on 'uic' since installing
+// the wheels cover this case.
+QString uicBin(QStringLiteral("pyside6-uic"));
+QStringList uicArgs = {QString::fromUtf8(uiFileName)};
+
+QProcess uicProcess;
+uicProcess.start(uicBin, uicArgs);
+if (!uicProcess.waitForStarted()) {
+ qCritical().noquote() << "Cannot run '" << uicBin << "': "
+ << uicProcess.errorString() << " - Check if 'pyside6-uic' is in PATH";
+ Py_RETURN_NONE;
+}
+
+if (!uicProcess.waitForFinished()
+ || uicProcess.exitStatus() != QProcess::NormalExit
+ || uicProcess.exitCode() != 0) {
+ qCritical().noquote() << '\'' << uicBin << "' failed: "
+ << uicProcess.errorString() << " - Exit status " << uicProcess.exitStatus()
+ << " (" << uicProcess.exitCode() << ")\n";
+ Py_RETURN_NONE;
+}
+
+QByteArray uiFileContent = uicProcess.readAllStandardOutput();
+QByteArray errorOutput = uicProcess.readAllStandardError();
+
+if (!errorOutput.isEmpty()) {
+ qCritical().noquote() << '\'' << uicBin << "' failed: " << errorOutput;
+ Py_RETURN_NONE;
+}
+
+// 2. Obtain the 'classname' and the Qt base class.
+QByteArray className;
+QByteArray baseClassName;
+
+// Problem
+// The generated Python file doesn't have the Qt Base class information.
+
+// Solution
+// Use the XML file
+if (!uiFile.open(QIODevice::ReadOnly))
+ Py_RETURN_NONE;
+
+// This will look for the first <widget> tag, e.g.:
+// <widget class="QWidget" name="ThemeWidgetForm">
+// and then extract the information from "class", and "name",
+// to get the baseClassName and className respectively
+QXmlStreamReader reader(&uiFile);
+while (!reader.atEnd() && baseClassName.isEmpty() && className.isEmpty()) {
+ auto token = reader.readNext();
+ if (token == QXmlStreamReader::StartElement && reader.name() == u"widget") {
+ baseClassName = reader.attributes().value(QLatin1StringView("class")).toUtf8();
+ className = reader.attributes().value(QLatin1StringView("name")).toUtf8();
+ }
+}
+
+uiFile.close();
+
+if (className.isEmpty() || baseClassName.isEmpty() || reader.hasError()) {
+ qCritical() << "An error occurred when parsing the UI file while looking for the class info "
+ << reader.errorString();
+ Py_RETURN_NONE;
+}
+
+QByteArray pyClassName("Ui_"+className);
+
+PyObject *module = PyImport_ImportModule("__main__");
+PyObject *loc = PyModule_GetDict(module);
+
+// 3. exec() the code so the class exists in the context: exec(uiFileContent)
+// The context of PyRun_SimpleString is __main__.
+// 'Py_file_input' is the equivalent to using exec(), since it will execute
+// the code, without returning anything.
+Shiboken::AutoDecRef codeUi(Py_CompileString(uiFileContent.constData(), "<stdin>", Py_file_input));
+if (codeUi.isNull()) {
+ qCritical() << "Error while compiling the generated Python file";
+ Py_RETURN_NONE;
+}
+PyObject *uiObj = PyEval_EvalCode(codeUi, loc, loc);
+
+if (uiObj == nullptr) {
+ qCritical() << "Error while running exec() on the generated code";
+ Py_RETURN_NONE;
+}
+
+// 4. eval() the name of the class on a variable to return
+// 'Py_eval_input' is the equivalent to using eval(), since it will just
+// evaluate an expression.
+Shiboken::AutoDecRef codeClass(Py_CompileString(pyClassName.constData(),"<stdin>", Py_eval_input));
+if (codeClass.isNull()) {
+ qCritical() << "Error while compiling the Python class";
+ Py_RETURN_NONE;
+}
+
+Shiboken::AutoDecRef codeBaseClass(Py_CompileString(baseClassName.constData(), "<stdin>", Py_eval_input));
+if (codeBaseClass.isNull()) {
+ qCritical() << "Error while compiling the base class";
+ Py_RETURN_NONE;
+}
+
+PyObject *classObj = PyEval_EvalCode(codeClass, loc, loc);
+PyObject *baseClassObj = PyEval_EvalCode(codeBaseClass, loc, loc);
+
+%PYARG_0 = PyTuple_New(2);
+if (%PYARG_0 == nullptr) {
+ qCritical() << "Error while creating the return Tuple";
+ Py_RETURN_NONE;
+}
+PyTuple_SET_ITEM(%PYARG_0, 0, classObj);
+PyTuple_SET_ITEM(%PYARG_0, 1, baseClassObj);
+// @snippet loaduitype
diff --git a/sources/pyside6/PySide6/glue/qtwebenginecore.cpp b/sources/pyside6/PySide6/glue/qtwebenginecore.cpp
new file mode 100644
index 000000000..76a7c6d73
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtwebenginecore.cpp
@@ -0,0 +1,64 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qwebenginecookiestore-functor
+struct QWebEngineCookieFilterFunctor : public Shiboken::PyObjectHolder
+{
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ bool operator()(const QWebEngineCookieStore::FilterRequest& filterRequest) const;
+};
+
+bool QWebEngineCookieFilterFunctor::operator()(const QWebEngineCookieStore::FilterRequest &
+ filterRequest) const
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist, 0,
+ %CONVERTTOPYTHON[QWebEngineCookieStore::FilterRequest](filterRequest));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
+ return ret.object() == Py_True;
+}
+// @snippet qwebenginecookiestore-functor
+
+// @snippet qwebenginecookiestore-setcookiefilter
+%CPPSELF.%FUNCTION_NAME(QWebEngineCookieFilterFunctor(%PYARG_1));
+// @snippet qwebenginecookiestore-setcookiefilter
+
+// @snippet qwebengineprofile-functor
+struct QWebEngineNotificationFunctor : public Shiboken::PyObjectHolder
+{
+ using Shiboken::PyObjectHolder::PyObjectHolder;
+
+ void operator()(std::unique_ptr<QWebEngineNotification> webEngineNotification);
+};
+
+void QWebEngineNotificationFunctor::operator()
+ (std::unique_ptr<QWebEngineNotification> webEngineNotification)
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ auto *notification = webEngineNotification.release();
+ PyTuple_SET_ITEM(arglist.object(), 0,
+ %CONVERTTOPYTHON[QWebEngineNotification*](notification));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(object(), arglist));
+};
+// @snippet qwebengineprofile-functor
+
+// @snippet qwebengineprofile-setnotificationpresenter
+%CPPSELF.%FUNCTION_NAME(QWebEngineNotificationFunctor(%PYARG_1));
+// @snippet qwebengineprofile-setnotificationpresenter
+
+// @snippet qwebenginepage-javascriptprompt-virtual-redirect
+std::pair<bool, QString> resultPair = javaScriptPromptPyOverride(gil, pyOverride.object(), securityOrigin, msg, defaultValue);
+result->assign(resultPair.second);
+return resultPair.first;
+// @snippet qwebenginepage-javascriptprompt-virtual-redirect
+
+// @snippet qwebenginepage-javascriptprompt-return
+QString str;
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, &str);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](str));
+// @snippet qwebenginepage-javascriptprompt-return
diff --git a/sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp b/sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp
new file mode 100644
index 000000000..af15130a4
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtwebenginewidgets.cpp
@@ -0,0 +1,121 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qwebenginepage-findtext
+auto callable = %PYARG_3;
+auto callback = [callable](const QWebEngineFindTextResult &result)
+{
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 3 of %FUNCTION_NAME must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QWebEngineFindTextResult](result));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+
+};
+Py_INCREF(callable);
+%CPPSELF.%FUNCTION_NAME(%1, %2, callback);
+// @snippet qwebenginepage-findtext
+
+// @snippet qwebenginepage-print
+auto printer = %PYARG_1;
+auto callable = %PYARG_2;
+auto callback = [printer, callable](bool succeeded)
+{
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 2 of %FUNCTION_NAME must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[bool](succeeded));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+ Py_DECREF(printer);
+
+};
+Py_INCREF(printer); // Add a reference to the printer until asynchronous printing has finished
+Py_INCREF(callable);
+%CPPSELF.%FUNCTION_NAME(%1, callback);
+// @snippet qwebenginepage-print
+
+// @snippet qwebenginepage-convertto
+auto callable = %PYARG_1;
+auto callback = [callable](const QString &text)
+{
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 1 of %FUNCTION_NAME must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](text));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+};
+
+Py_INCREF(callable);
+%CPPSELF.%FUNCTION_NAME(callback);
+// @snippet qwebenginepage-convertto
+
+// @snippet qwebenginepage-runjavascript
+auto callable = %PYARG_3;
+auto callback = [callable](const QVariant &result)
+{
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 3 of %FUNCTION_NAME must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ switch (result.type()) {
+ case QVariant::Bool: {
+ const bool value = result.toBool();
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](value));
+ }
+ break;
+ case QVariant::Int:
+ case QVariant::UInt:
+ case QVariant::LongLong:
+ case QVariant::ULongLong:
+ case QVariant::Double: {
+ const double number = result.toDouble();
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[double](number));
+ }
+ break;
+ default: {
+ const QString value = result.toString();
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](value));
+ }
+ break;
+ }
+ // PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[bool](found));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+};
+
+Py_INCREF(callable);
+%CPPSELF.%FUNCTION_NAME(%1, %2, callback);
+// @snippet qwebenginepage-runjavascript
+
+// @snippet qwebenginepage-printtopdf
+auto callable = %PYARG_1;
+auto callback = [callable](const QByteArray &pdf)
+{
+ if (!PyCallable_Check(callable)) {
+ qWarning("Argument 1 of %FUNCTION_NAME must be a callable.");
+ return;
+ }
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(1));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QByteArray](pdf));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist));
+ Py_DECREF(callable);
+};
+
+Py_INCREF(callable);
+%CPPSELF.%FUNCTION_NAME(callback, %2);
+// @snippet qwebenginepage-printtopdf
diff --git a/sources/pyside6/PySide6/glue/qtwidgets.cpp b/sources/pyside6/PySide6/glue/qtwidgets.cpp
new file mode 100644
index 000000000..f886106cf
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtwidgets.cpp
@@ -0,0 +1,818 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet qtreewidgetitemiterator-next
+if (**%CPPSELF) {
+ QTreeWidgetItemIterator *%0 = new QTreeWidgetItemIterator((*%CPPSELF)++);
+ %PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItemIterator *](%0);
+}
+// @snippet qtreewidgetitemiterator-next
+
+// @snippet qtreewidgetitemiterator-value
+QTreeWidgetItem *%0 = %CPPSELF.operator *();
+%PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItem *](%0);
+Shiboken::Object::releaseOwnership(%PYARG_0);
+// @snippet qtreewidgetitemiterator-value
+
+// @snippet qgraphicsitem
+PyObject *userTypeConstant = PyLong_FromLong(QGraphicsItem::UserType);
+tpDict.reset(PepType_GetDict(Sbk_QGraphicsItem_TypeF()));
+PyDict_SetItemString(tpDict.object(), "UserType", userTypeConstant);
+// @snippet qgraphicsitem
+
+// @snippet qgraphicsitem-scene-return-parenting
+if (%0) {
+ QObject *parent = %0->parent();
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QObject *](parent));
+ Shiboken::Object::setParent(pyParent, %PYARG_0);
+}
+// @snippet qgraphicsitem-scene-return-parenting
+
+// @snippet qgraphicsitem-isblockedbymodalpanel
+QGraphicsItem *item_ = nullptr;
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&item_);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QGraphicsItem *](item_));
+// @snippet qgraphicsitem-isblockedbymodalpanel
+
+// @snippet qitemeditorfactory-registereditor
+Shiboken::Object::releaseOwnership(%PYARG_2);
+// @snippet qitemeditorfactory-registereditor
+
+// @snippet qitemeditorfactory-setdefaultfactory
+//this function is static we need keep ref to default value, to be able to call python virtual functions
+static PyObject *_defaultValue = nullptr;
+%CPPSELF.%FUNCTION_NAME(%1);
+Py_INCREF(%PYARG_1);
+if (_defaultValue)
+ Py_DECREF(_defaultValue);
+
+_defaultValue = %PYARG_1;
+// @snippet qitemeditorfactory-setdefaultfactory
+
+// @snippet qformlayout-fix-args
+int _row;
+QFormLayout::ItemRole _role;
+%CPPSELF->%FUNCTION_NAME(%ARGUMENT_NAMES, &_row, &_role);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](_row));
+// On the C++ side, *rolePtr is not set if row == -1, in which case on
+// the Python side this gets converted to a random value outside the
+// enum range. Fix this by setting _role to a default value here.
+if (_row == -1)
+ _role = QFormLayout::LabelRole;
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role));
+// @snippet qformlayout-fix-args
+
+// @snippet qfiledialog-return
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &%5, %6);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](%5));
+// @snippet qfiledialog-return
+
+// @snippet qwidget-addaction-glue
+static PyObject *connectAction(QAction *action, PyObject *callback)
+{
+ PyObject *pyAct = %CONVERTTOPYTHON[QAction *](action);
+ Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct, "connect", "OsO",
+ pyAct,
+ SIGNAL(triggered()), callback));
+ if (result.isNull()) {
+ Py_DECREF(pyAct);
+ return nullptr;
+ }
+ return pyAct;
+}
+
+static inline PyObject *addActionWithPyObject(QWidget *self, const QString &text,
+ PyObject *callback)
+{
+ QAction *act = self->addAction(text);
+ return connectAction(act, callback);
+}
+
+static inline PyObject *addActionWithPyObject(QWidget *self, const QIcon &icon, const QString &text,
+ PyObject *callback)
+{
+ auto *act = self->addAction(icon, text);
+ return connectAction(act, callback);
+}
+
+static inline PyObject *addActionWithPyObject(QWidget *self, const QString &text,
+ const QKeySequence &shortcut,
+ PyObject *callback)
+{
+ QAction *act = self->addAction(text, shortcut);
+ return connectAction(act, callback);
+}
+
+static inline PyObject *addActionWithPyObject(QWidget *self, const QIcon &icon,
+ const QString &text,
+ const QKeySequence &shortcut,
+ PyObject *callback)
+{
+ QAction *act = self->addAction(icon, text, shortcut);
+ return connectAction(act, callback);
+}
+// @snippet qwidget-addaction-glue
+
+// FIXME PYSIDE7: Remove in favor of widgets methods
+// @snippet qmenu-glue
+inline PyObject *addMenuActionWithPyObject(QMenu *self, const QIcon &icon,
+ const QString &text, PyObject *callback,
+ const QKeySequence &shortcut)
+{
+ QAction *act = self->addAction(text);
+
+ if (!icon.isNull())
+ act->setIcon(icon);
+
+ if (!shortcut.isEmpty())
+ act->setShortcut(shortcut);
+
+ self->addAction(act);
+
+ PyObject *pyAct = %CONVERTTOPYTHON[QAction *](act);
+ Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct, "connect", "OsO",
+ pyAct,
+ SIGNAL(triggered()), callback));
+ if (result.isNull()) {
+ Py_DECREF(pyAct);
+ return nullptr;
+ }
+
+ return pyAct;
+}
+// @snippet qmenu-glue
+
+// addAction(QString,PyObject*,QKeySequence) FIXME PYSIDE7 deprecated
+// @snippet qmenu-addaction-1
+%PYARG_0 = addMenuActionWithPyObject(%CPPSELF, QIcon(), %1, %2, %3);
+// @snippet qmenu-addaction-1
+
+// addAction(QIcon,QString,PyObject*,QKeySequence) FIXME PYSIDE7 deprecated
+// @snippet qmenu-addaction-2
+%PYARG_0 = addMenuActionWithPyObject(%CPPSELF, %1, %2, %3, %4);
+// @snippet qmenu-addaction-2
+
+// @snippet qmenu-addaction-3
+%CPPSELF.addAction(%1);
+// @snippet qmenu-addaction-3
+
+// addAction(QString,PyObject*)
+// @snippet qwidget-addaction-2
+%PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2);
+// @snippet qwidget-addaction-2
+
+// addAction(QString,QKeySequence,PyObject*) or addAction(QIcon,QString,PyObject*)
+// @snippet qwidget-addaction-3
+%PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2, %3);
+// @snippet qwidget-addaction-3
+
+// addAction(QIcon,QString,QKeySequence,PyObject*)
+// @snippet qwidget-addaction-4
+%PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2, %3, %4);
+// @snippet qwidget-addaction-4
+
+// @snippet qmenu-clear
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+const auto &actions = %CPPSELF.actions();
+for (auto *act : actions) {
+ if (auto wrapper = bm.retrieveWrapper(act)) {
+ auto pyObj = reinterpret_cast<PyObject *>(wrapper);
+ Py_INCREF(pyObj);
+ Shiboken::Object::setParent(nullptr, pyObj);
+ Shiboken::Object::invalidate(pyObj);
+ Py_DECREF(pyObj);
+ }
+}
+// @snippet qmenu-clear
+
+// @snippet qmenubar-clear
+const auto &actions = %CPPSELF.actions();
+for (auto *act : actions) {
+ Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction *](act));
+ Shiboken::Object::setParent(nullptr, pyAct);
+ Shiboken::Object::invalidate(pyAct);
+}
+// @snippet qmenubar-clear
+
+// @snippet qtoolbox-removeitem
+QWidget *_widget = %CPPSELF.widget(%1);
+if (_widget) {
+ Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget *](_widget));
+ Shiboken::Object::setParent(0, pyWidget);
+}
+// @snippet qtoolbox-removeitem
+
+// @snippet qlayout-help-functions
+#ifndef _QLAYOUT_HELP_FUNCTIONS_
+#define _QLAYOUT_HELP_FUNCTIONS_ // Guard for jumbo builds
+
+static const char msgInvalidParameterAdd[] =
+ "Invalid parameter None passed to addLayoutOwnership().";
+static const char msgInvalidParameterRemoval[] =
+ "Invalid parameter None passed to removeLayoutOwnership().";
+
+void addLayoutOwnership(QLayout *layout, QLayoutItem *item);
+void removeLayoutOwnership(QLayout *layout, QWidget *widget);
+
+inline void addLayoutOwnership(QLayout *layout, QWidget *widget)
+{
+ if (layout == nullptr || widget == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd);
+ return;
+ }
+
+ //transfer ownership to parent widget
+ QWidget *lw = layout->parentWidget();
+ QWidget *pw = widget->parentWidget();
+
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](widget));
+
+ //Transfer parent to layout widget
+ if (pw && lw && pw != lw)
+ Shiboken::Object::setParent(nullptr, pyChild);
+
+ if (!lw && !pw) {
+ //keep the reference while the layout is orphan
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](layout));
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(pyParent.object()),
+ retrieveObjectName(pyParent).constData(),
+ pyChild, true);
+ } else {
+ if (!lw)
+ lw = pw;
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](lw));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ }
+}
+
+inline void addLayoutOwnership(QLayout *layout, QLayout *other)
+{
+ if (layout == nullptr || other == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd);
+ return;
+ }
+
+ //transfer all children widgets from other to layout parent widget
+ QWidget *parent = layout->parentWidget();
+ if (!parent) {
+ //keep the reference while the layout is orphan
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout *](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout *](other));
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(pyParent.object()),
+ retrieveObjectName(pyParent).constData(),
+ pyChild, true);
+ return;
+ }
+
+ for (int i = 0, i_max = other->count(); i < i_max; ++i) {
+ QLayoutItem *item = other->itemAt(i);
+ if (PyErr_Occurred() || !item)
+ return;
+ addLayoutOwnership(layout, item);
+ }
+
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout *](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout *](other));
+ Shiboken::Object::setParent(pyParent, pyChild);
+}
+
+inline void addLayoutOwnership(QLayout *layout, QLayoutItem *item)
+{
+
+ if (layout == nullptr || item == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterAdd);
+ return;
+ }
+
+ if (QWidget *w = item->widget()) {
+ addLayoutOwnership(layout, w);
+ } else {
+ if (QLayout *l = item->layout())
+ addLayoutOwnership(layout, l);
+ }
+
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout *](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem *](item));
+ Shiboken::Object::setParent(pyParent, pyChild);
+}
+
+static void removeWidgetFromLayout(QLayout *layout, QWidget *widget)
+{
+ if (layout == nullptr || widget == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval);
+ return;
+ }
+
+ if (QWidget *parent = widget->parentWidget()) {
+ //give the ownership to parent
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](widget));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ } else {
+ //remove reference on layout
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](widget));
+ Shiboken::Object::removeReference(reinterpret_cast<SbkObject *>(pyParent.object()),
+ retrieveObjectName(pyParent).constData(),
+ pyChild);
+ }
+}
+
+inline void removeLayoutOwnership(QLayout *layout, QLayoutItem *item)
+{
+ if (layout == nullptr || item == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval);
+ return;
+ }
+
+ if (QWidget *w = item->widget()) {
+ removeWidgetFromLayout(layout, w);
+ } else {
+ QLayout *l = item->layout();
+ if (l && item != l)
+ removeLayoutOwnership(layout, l);
+ }
+
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem *](item));
+ Shiboken::Object::invalidate(pyChild);
+ Shiboken::Object::setParent(0, pyChild);
+}
+
+inline void removeLayoutOwnership(QLayout *layout, QWidget *widget)
+{
+ if (layout == nullptr || widget == nullptr) {
+ PyErr_SetString(PyExc_RuntimeError, msgInvalidParameterRemoval);
+ return;
+ }
+
+ for (int i = 0, i_max = layout->count(); i < i_max; ++i) {
+ QLayoutItem *item = layout->itemAt(i);
+ if (PyErr_Occurred() || !item)
+ return;
+ if (item->widget() == widget)
+ removeLayoutOwnership(layout, item);
+ }
+}
+#endif // _QLAYOUT_HELP_FUNCTIONS_
+// @snippet qlayout-help-functions
+
+// @snippet qlayout-setalignment
+%CPPSELF.setAlignment(%1);
+// @snippet qlayout-setalignment
+
+// @snippet addownership-item-at
+if (%0 != nullptr)
+ addLayoutOwnership(%CPPSELF, %0);
+// @snippet addownership-item-at
+
+// @snippet addownership-1
+addLayoutOwnership(%CPPSELF, %1);
+// @snippet addownership-1
+
+// @snippet addownership-2
+addLayoutOwnership(%CPPSELF, %2);
+// @snippet addownership-2
+
+// @snippet removeownership-1
+removeLayoutOwnership(%CPPSELF, %1);
+// @snippet removeownership-1
+
+// @snippet qgridlayout-getitemposition
+int a, b, c, d;
+%CPPSELF.%FUNCTION_NAME(%1, &a, &b, &c, &d);
+%PYARG_0 = PyTuple_New(4);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](a));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](b));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](c));
+PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](d));
+// @snippet qgridlayout-getitemposition
+
+// @snippet qgraphicsscene-destroyitemgroup
+QGraphicsItem *parentItem = %1->parentItem();
+Shiboken::AutoDecRef parent(%CONVERTTOPYTHON[QGraphicsItem *](parentItem));
+const auto &childItems = %1->childItems();
+for (auto *item : childItems)
+ Shiboken::Object::setParent(parent, %CONVERTTOPYTHON[QGraphicsItem *](item));
+%CPPSELF.%FUNCTION_NAME(%1);
+// the arg was destroyed by Qt.
+Shiboken::Object::invalidate(%PYARG_1);
+// @snippet qgraphicsscene-destroyitemgroup
+
+// @snippet qgraphicsscene-addwidget
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(%PYARG_0), "setWidget(QWidget*)1", %PYARG_1);
+// @snippet qgraphicsscene-addwidget
+
+// @snippet qgraphicsscene-clear
+const QList<QGraphicsItem *> items = %CPPSELF.items();
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+for (auto *item : items) {
+ SbkObject *obj = bm.retrieveWrapper(item);
+ if (obj) {
+ if (Py_REFCNT(reinterpret_cast<PyObject *>(obj)) > 1) // If the refcnt is 1 the object will vannish anyway.
+ Shiboken::Object::invalidate(obj);
+ Shiboken::Object::removeParent(obj);
+ }
+}
+%CPPSELF.%FUNCTION_NAME();
+// @snippet qgraphicsscene-clear
+
+// @snippet qtreewidget-clear
+QTreeWidgetItem *rootItem = %CPPSELF.invisibleRootItem();
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+
+// PYSIDE-1251:
+// Since some objects can be created with a parent and without
+// being saved on a local variable (refcount = 1), they will be
+// deleted when setting the parent to nullptr, so we change the loop
+// to do this from the last child to the first, to avoid the case
+// when the child(1) points to the original child(2) in case the
+// first one was removed.
+for (int i = rootItem->childCount() - 1; i >= 0; --i) {
+ QTreeWidgetItem *item = rootItem->child(i);
+ if (SbkObject *wrapper = bm.retrieveWrapper(item))
+ Shiboken::Object::setParent(nullptr, reinterpret_cast<PyObject *>(wrapper));
+}
+// @snippet qtreewidget-clear
+
+// @snippet qtreewidgetitem
+// Only call the parent function if this return some value
+// the parent can be the TreeWidget
+if (%0)
+ Shiboken::Object::setParent(%PYARG_0, %PYSELF);
+// @snippet qtreewidgetitem
+
+// @snippet qlistwidget-clear
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+for (int i = 0, count = %CPPSELF.count(); i < count; ++i) {
+ QListWidgetItem *item = %CPPSELF.item(i);
+ if (auto wrapper = bm.retrieveWrapper(item)) {
+ auto pyObj = reinterpret_cast<PyObject *>(wrapper);
+ Py_INCREF(pyObj);
+ Shiboken::Object::setParent(nullptr, pyObj);
+ Shiboken::Object::invalidate(pyObj);
+ Py_DECREF(pyObj);
+ }
+}
+%CPPSELF.%FUNCTION_NAME();
+// @snippet qlistwidget-clear
+
+// @snippet qwidget-retrieveobjectname
+#ifndef _RETRIEVEOBJECTNAME_
+#define _RETRIEVEOBJECTNAME_ // Guard for jumbo builds
+static QByteArray retrieveObjectName(PyObject *obj)
+{
+ Shiboken::AutoDecRef objName(PyObject_Str(obj));
+ return Shiboken::String::toCString(objName);
+}
+#endif
+// @snippet qwidget-retrieveobjectname
+
+// @snippet qwidget-glue
+
+// Transfer objects ownership from layout to widget
+static inline void qwidgetReparentLayout(QWidget *parent, QLayout *layout)
+{
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent));
+
+ for (int i=0, i_count = layout->count(); i < i_count; i++) {
+ QLayoutItem *item = layout->itemAt(i);
+ if (PyErr_Occurred() || !item)
+ return;
+
+ if (QWidget *w = item->widget()) {
+ QWidget *pw = w->parentWidget();
+ if (pw != parent) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](w));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ }
+ } else {
+ if (QLayout *l = item->layout())
+ qwidgetReparentLayout(parent, l);
+ }
+ }
+
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout *](layout));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ //remove previous references
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(pyChild.object()),
+ retrieveObjectName(pyChild).constData(),
+ Py_None);
+}
+
+static inline void qwidgetSetLayout(QWidget *self, QLayout *layout)
+{
+ if (!layout || self->layout())
+ return;
+
+ QObject *oldParent = layout->parent();
+ if (oldParent && oldParent != self) {
+ if (oldParent->isWidgetType()) {
+ // remove old parent policy
+ Shiboken::AutoDecRef pyLayout(%CONVERTTOPYTHON[QLayout *](layout));
+ Shiboken::Object::setParent(Py_None, pyLayout);
+ } else {
+ PyErr_Format(PyExc_RuntimeError, "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
+ qPrintable(layout->objectName()), self->metaObject()->className(), qPrintable(self->objectName()));
+ return;
+ }
+ }
+
+ if (oldParent != self) {
+ qwidgetReparentLayout(self, layout);
+ if (PyErr_Occurred())
+ return;
+
+ self->setLayout(layout);
+ }
+}
+// @snippet qwidget-glue
+
+// @snippet qwidget-setstyle
+Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(%PYSELF), "__style__", %PYARG_1);
+// @snippet qwidget-setstyle
+
+// @snippet qwidget-style
+QStyle *myStyle = %CPPSELF->style();
+if (myStyle && qApp) {
+ bool keepReference = true;
+ %PYARG_0 = %CONVERTTOPYTHON[QStyle *](myStyle);
+ QStyle *appStyle = qApp->style();
+ if (appStyle == myStyle) {
+ Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication *](qApp));
+ // Do not set parentship when qApp is embedded
+ if (Shiboken::Object::wasCreatedByPython(reinterpret_cast<SbkObject *>(pyApp.object()))) {
+ Shiboken::Object::setParent(pyApp, %PYARG_0);
+ Shiboken::Object::releaseOwnership(%PYARG_0);
+ keepReference = false;
+ }
+ }
+ if (keepReference)
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject *>(%PYSELF), "__style__", %PYARG_0);
+}
+// @snippet qwidget-style
+
+// @snippet qapplication-init
+static void QApplicationConstructor(PyObject *self, PyObject *pyargv, QApplicationWrapper **cptr)
+{
+ static int argc;
+ static char **argv;
+ PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
+ if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
+ *cptr = new QApplicationWrapper(argc, argv, 0);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject *>(self));
+ PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
+ }
+}
+// @snippet qapplication-init
+
+// @snippet qapplication-setStyle
+if (qApp) {
+ Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication *](qApp));
+ Shiboken::Object::setParent(pyApp, %PYARG_1);
+ Shiboken::Object::releaseOwnership(%PYARG_1);
+}
+// @snippet qapplication-setStyle
+
+// @snippet qwidget-setlayout
+qwidgetSetLayout(%CPPSELF, %1);
+// %FUNCTION_NAME() - disable generation of function call.
+// @snippet qwidget-setlayout
+
+// @snippet qtabwidget-removetab
+QWidget *tab = %CPPSELF.widget(%1);
+if (tab) {
+ Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget *](tab));
+ %CPPSELF.%FUNCTION_NAME(%1);
+}
+// @snippet qtabwidget-removetab
+
+// @snippet qtabwidget-clear
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+for (int i = 0, count = %CPPSELF.count(); i < count; ++i) {
+ QWidget *widget = %CPPSELF.widget(i);
+ if (bm.hasWrapper(widget)) {
+ Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget *](widget));
+ Shiboken::Object::releaseOwnership(pyWidget);
+ }
+}
+%CPPSELF.%FUNCTION_NAME();
+// @snippet qtabwidget-clear
+
+// @snippet qlineedit-addaction
+%CPPSELF.addAction(%1);
+// @snippet qlineedit-addaction
+
+// addAction(QIcon,QString,const QObject*,const char*,Qt::ConnectionType)
+// @snippet qwidget-addaction-1
+QAction *action = %CPPSELF.addAction(%1, %2);
+%PYARG_0 = %CONVERTTOPYTHON[QAction *](action);
+Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0,
+ "connect", "OsO",
+ %PYARG_0, SIGNAL(triggered()), %PYARG_3)
+);
+// @snippet qwidget-addaction-1
+
+// addAction(QString,const QObject*,const char*,Qt::ConnectionType)
+// @snippet qwidget-addaction-2
+QAction *action = %CPPSELF.addAction(%1);
+%PYARG_0 = %CONVERTTOPYTHON[QAction *](action);
+Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0,
+ "connect", "OsO",
+ %PYARG_0, SIGNAL(triggered()), %PYARG_2)
+);
+// @snippet qwidget-addaction-2
+
+// @snippet qtoolbar-clear
+QList<PyObject *> lst;
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+const auto &toolButtonChildren = %CPPSELF.findChildren<QToolButton *>();
+for (auto *child : toolButtonChildren) {
+ if (bm.hasWrapper(child)) {
+ PyObject *pyChild = %CONVERTTOPYTHON[QToolButton *](child);
+ Shiboken::Object::setParent(nullptr, pyChild);
+ lst << pyChild;
+ }
+}
+
+//Remove actions
+const auto &actions = %CPPSELF.actions();
+for (auto *act : actions) {
+ Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction *](act));
+ Shiboken::Object::setParent(nullptr, pyAct);
+ Shiboken::Object::invalidate(pyAct);
+}
+
+%CPPSELF.clear();
+for (auto *obj : std::as_const(lst)) {
+ Shiboken::Object::invalidate(reinterpret_cast<SbkObject *>(obj));
+ Py_XDECREF(obj);
+}
+// @snippet qtoolbar-clear
+
+// @snippet qapplication-1
+QApplicationConstructor(%PYSELF, args, &%0);
+// @snippet qapplication-1
+
+// @snippet qapplication-2
+PyObject *empty = PyTuple_New(2);
+if (!PyTuple_SetItem(empty, 0, PyList_New(0)))
+ QApplicationConstructor(%PYSELF, empty, &%0);
+// @snippet qapplication-2
+
+// @snippet qgraphicsproxywidget-setwidget
+QWidget *_old = %CPPSELF.widget();
+if (_old)
+ Shiboken::Object::setParent(nullptr, %CONVERTTOPYTHON[QWidget *](_old));
+%CPPSELF.%FUNCTION_NAME(%1);
+Shiboken::Object::setParent(%PYSELF, %PYARG_1);
+// @snippet qgraphicsproxywidget-setwidget
+
+// @snippet qapplication-exec
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+int cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[int](cppResult);
+// @snippet qapplication-exec
+
+// @snippet qmenu-exec-1
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+QAction *cppResult = %CPPSELF.exec();
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[QAction*](cppResult);
+// @snippet qmenu-exec-1
+
+// @snippet qmenu-exec-2
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+QAction *cppResult = %CPPSELF.exec(%1, %2);
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[QAction*](cppResult);
+// @snippet qmenu-exec-2
+
+// @snippet qmenu-exec-3
+if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'exec_' will be removed in the future. "
+ "Use 'exec' instead.",
+ 1)) {
+ return nullptr;
+}
+%BEGIN_ALLOW_THREADS
+QAction *cppResult = %CPPSELF.exec(%1, %2, %3, %4);
+%END_ALLOW_THREADS
+%PYARG_0 = %CONVERTTOPYTHON[QAction*](cppResult);
+// @snippet qmenu-exec-3
+
+// @snippet qstyleoption-typename
+const char *styleOptionType(const QStyleOption *o)
+{
+ switch (o->type) {
+ case QStyleOption::SO_Default:
+ break;
+ case QStyleOption::SO_FocusRect:
+ return "QStyleOptionFocusRect";
+ case QStyleOption::SO_Button:
+ return "QStyleOptionButton";
+ case QStyleOption::SO_Tab:
+ return "QStyleOptionTab";
+ case QStyleOption::SO_MenuItem:
+ return "QStyleOptionMenuItem";
+ case QStyleOption::SO_Frame:
+ return "QStyleOptionFrame";
+ case QStyleOption::SO_ProgressBar:
+ return "QStyleOptionProgressBar";
+ case QStyleOption::SO_ToolBox:
+ return "QStyleOptionToolBox";
+ case QStyleOption::SO_Header:
+ return "QStyleOptionHeader";
+ case QStyleOption::SO_DockWidget:
+ return "QStyleOptionDockWidget";
+ case QStyleOption::SO_ViewItem:
+ return "QStyleOptionViewItem";
+ case QStyleOption::SO_TabWidgetFrame:
+ return "QStyleOptionTabWidgetFrame";
+ case QStyleOption::SO_TabBarBase:
+ return "QStyleOptionTabBarBase";
+ case QStyleOption::SO_RubberBand:
+ return "QStyleOptionRubberBand";
+ case QStyleOption::SO_ToolBar:
+ return "QStyleOptionToolBar";
+ case QStyleOption::SO_GraphicsItem:
+ return "QStyleOptionGraphicsItem";
+ case QStyleOption::SO_Slider:
+ return "QStyleOptionSlider";
+ case QStyleOption::SO_SpinBox:
+ return "QStyleOptionSpinBox";
+ case QStyleOption::SO_ToolButton:
+ return "QStyleOptionToolButton";
+ case QStyleOption::SO_ComboBox:
+ return "QStyleOptionComboBox";
+ case QStyleOption::SO_TitleBar:
+ return "QStyleOptionTitleBar";
+ case QStyleOption::SO_GroupBox:
+ return "QStyleOptionGroupBox";
+ case QStyleOption::SO_SizeGrip:
+ return "QStyleOptionSizeGrip";
+ default:
+ break;
+ }
+ return "QStyleOption";
+}
+// @snippet qstyleoption-typename
+
+// @snippet qwizardpage-registerfield
+auto *signalInst = reinterpret_cast<PySideSignalInstance *>(%PYARG_4);
+const auto data = PySide::Signal::getEmitterData(signalInst);
+if (data.methodIndex == -1)
+ return PyErr_Format(PyExc_RuntimeError, "QWizardPage::registerField(): Unable to retrieve signal emitter.");
+const auto method = data.emitter->metaObject()->method(data.methodIndex);
+const QByteArray signature = QByteArrayLiteral("2") + method.methodSignature();
+%BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(%1, %2, %3, signature.constData());
+%END_ALLOW_THREADS
+// @snippet qwizardpage-registerfield
+
+// The constructor heuristics generate setting a parent-child relationship
+// when creating a QDialog with parent. This causes the dialog to leak
+// when it synchronous exec() is used instead of asynchronous show().
+// In that case, remove the parent-child relationship.
+// @snippet qdialog-exec-remove-parent-relation
+Shiboken::Object::removeParent(reinterpret_cast<SbkObject *>(%PYSELF));
+// @snippet qdialog-exec-remove-parent-relation
+
+/*********************************************************************
+ * CONVERSIONS
+ ********************************************************************/
+
+/*********************************************************************
+ * NATIVE TO TARGET CONVERSIONS
+ ********************************************************************/
diff --git a/sources/pyside6/PySide6/glue/qtxml.cpp b/sources/pyside6/PySide6/glue/qtxml.cpp
new file mode 100644
index 000000000..120579927
--- /dev/null
+++ b/sources/pyside6/PySide6/glue/qtxml.cpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet qdomdocument-setcontent
+QString _errorMsg_;
+int _errorLine_ = 0;
+int _errorColumn_ = 0;
+%BEGIN_ALLOW_THREADS
+bool _ret_ = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &_errorMsg_, &_errorLine_,
+ &_errorColumn_);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(4);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](_ret_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](_errorMsg_));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](_errorLine_));
+PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](_errorColumn_));
+// @snippet qdomdocument-setcontent
diff --git a/sources/pyside6/PySide6/licensecomment.txt b/sources/pyside6/PySide6/licensecomment.txt
new file mode 100644
index 000000000..d82c85d88
--- /dev/null
+++ b/sources/pyside6/PySide6/licensecomment.txt
@@ -0,0 +1,2 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
diff --git a/sources/pyside6/PySide6/py.typed.in b/sources/pyside6/PySide6/py.typed.in
new file mode 100644
index 000000000..0e76a07dc
--- /dev/null
+++ b/sources/pyside6/PySide6/py.typed.in
@@ -0,0 +1 @@
+# this is a marker file for mypy
diff --git a/sources/pyside6/PySide6/pysideqtesttouch.h b/sources/pyside6/PySide6/pysideqtesttouch.h
new file mode 100644
index 000000000..4b4a4a9b5
--- /dev/null
+++ b/sources/pyside6/PySide6/pysideqtesttouch.h
@@ -0,0 +1,179 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQTESTTOUCH_H
+#define PYSIDEQTESTTOUCH_H
+
+#include <QtTest/qttestglobal.h>
+#include <QtTest/qtestassert.h>
+#include <QtTest/qtestsystem.h>
+#include <QtTest/qtestspontaneevent.h>
+#include <QtTest/qtesttouch.h>
+
+#include <QtCore/qmap.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qwindow.h>
+#ifdef QT_WIDGETS_LIB
+#include <QtWidgets/qwidget.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace QTest
+{
+
+ class PySideQTouchEventSequence
+ {
+ public:
+ ~PySideQTouchEventSequence()
+ {
+ if (commitWhenDestroyed)
+ commit();
+ }
+ PySideQTouchEventSequence *press(int touchId, const QPoint &pt, QWindow *window = nullptr)
+ {
+ auto it = m_points.find(touchId);
+ if (it == m_points.end()) {
+ QEventPoint point(touchId, QEventPoint::Pressed, pt, mapToScreen(window, pt));
+ m_points.insert(touchId, point);
+ }
+ return this;
+ }
+ PySideQTouchEventSequence *move(int touchId, const QPoint &pt, QWindow *window = nullptr)
+ {
+ QEventPoint point(touchId, QEventPoint::Updated, pt, mapToScreen(window, pt));
+ m_points[touchId] = point;
+ return this;
+ }
+ PySideQTouchEventSequence *release(int touchId, const QPoint &pt, QWindow *window = nullptr)
+ {
+ auto it = m_points.find(touchId);
+ if (it == m_points.end()) {
+ QEventPoint point(touchId, QEventPoint::Released, pt, mapToScreen(window, pt));
+ m_points.insert(touchId, point);
+ }
+ return this;
+ }
+ PySideQTouchEventSequence *stationary(int touchId)
+ {
+ auto it = m_points.find(touchId);
+ if (it == m_points.end()) {
+ auto previous_it = m_previousPoints.find(touchId);
+ const QEventPoint point = previous_it != m_previousPoints.end()
+ ? previous_it.value()
+ : QEventPoint(touchId, QEventPoint::Stationary, QPointF(), QPointF());
+ m_points.insert(touchId, point);
+ }
+ return this;
+ }
+
+#ifdef QT_WIDGETS_LIB
+ PySideQTouchEventSequence *press(int touchId, const QPoint &pt, QWidget *widget = nullptr)
+ {
+ auto it = m_points.find(touchId);
+ if (it == m_points.end()) {
+ QEventPoint point(touchId, QEventPoint::Pressed, pt, mapToScreen(widget, pt));
+ m_points.insert(touchId, point);
+ }
+ return this;
+ }
+
+ PySideQTouchEventSequence *move(int touchId, const QPoint &pt, QWidget *widget = nullptr)
+ {
+ QEventPoint point(touchId, QEventPoint::Updated, pt, mapToScreen(widget, pt));
+ m_points[touchId] = point;
+ return this;
+ }
+
+ PySideQTouchEventSequence *release(int touchId, const QPoint &pt, QWidget *widget = nullptr)
+ {
+ auto it = m_points.find(touchId);
+ if (it == m_points.end()) {
+ QEventPoint point(touchId, QEventPoint::Released, pt, mapToScreen(widget, pt));
+ m_points.insert(touchId, point);
+ }
+ return this;
+ }
+#endif
+
+ void commit(bool processEvents = true)
+ {
+ if (!m_points.isEmpty()) {
+ if (targetWindow) {
+ qt_handleTouchEvent(targetWindow, device, m_points.values());
+ }
+#ifdef QT_WIDGETS_LIB
+ else if (targetWidget) {
+ qt_handleTouchEvent(targetWidget->windowHandle(), device, m_points.values());
+ }
+#endif
+ }
+ if (processEvents)
+ QCoreApplication::processEvents();
+ m_previousPoints = m_points;
+ m_points.clear();
+ }
+
+private:
+#ifdef QT_WIDGETS_LIB
+ PySideQTouchEventSequence(QWidget *widget, QPointingDevice *aDevice, bool autoCommit)
+ : targetWidget(widget), device(aDevice), commitWhenDestroyed(autoCommit)
+ {
+ }
+#endif
+ PySideQTouchEventSequence(QWindow *window, QPointingDevice *aDevice, bool autoCommit)
+ : targetWindow(window), device(aDevice), commitWhenDestroyed(autoCommit)
+ {
+ }
+
+#ifdef QT_WIDGETS_LIB
+ QPointF mapToScreen(const QWidget *widget, const QPointF &pt)
+ {
+ if (widget)
+ return widget->mapToGlobal(pt);
+ return targetWidget ? targetWidget->mapToGlobal(pt) : pt;
+ }
+#endif
+ QPointF mapToScreen(const QWindow *window, const QPointF &pt)
+ {
+ if(window)
+ return window->mapToGlobal(pt);
+ return targetWindow ? targetWindow->mapToGlobal(pt) : pt;
+ }
+
+ QMap<int, QEventPoint> m_previousPoints;
+ QMap<int, QEventPoint> m_points;
+#ifdef QT_WIDGETS_LIB
+ QWidget *targetWidget = nullptr;
+#endif
+ QWindow *targetWindow = nullptr;
+ QPointingDevice *device = nullptr;
+ bool commitWhenDestroyed = false;
+#ifdef QT_WIDGETS_LIB
+ friend PySideQTouchEventSequence *generateTouchEvent(QWidget *, QPointingDevice *, bool);
+#endif
+ friend PySideQTouchEventSequence *generateTouchEvent(QWindow *, QPointingDevice *, bool);
+ };
+
+#ifdef QT_WIDGETS_LIB
+ inline
+ PySideQTouchEventSequence *generateTouchEvent(QWidget *widget,
+ QPointingDevice *device,
+ bool autoCommit = true)
+ {
+ return new PySideQTouchEventSequence(widget, device, autoCommit);
+ }
+#endif
+ inline
+ PySideQTouchEventSequence *generateTouchEvent(QWindow *window,
+ QPointingDevice *device,
+ bool autoCommit = true)
+ {
+ return new PySideQTouchEventSequence(window, device, autoCommit);
+ }
+
+}
+
+QT_END_NAMESPACE
+
+#endif // PYSIDEQTESTTOUCH_H
diff --git a/sources/pyside6/PySide6/pysidewtypes.h b/sources/pyside6/PySide6/pysidewtypes.h
new file mode 100644
index 000000000..f853949ac
--- /dev/null
+++ b/sources/pyside6/PySide6/pysidewtypes.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef __PYSIDEWTYPES__
+#define __PYSIDEWTYPES__
+
+using HWND = struct HWND__ *;
+using UINT = unsigned;
+using LONG = long;
+using DWORD = unsigned long;
+using WPARAM = UINT;
+using LPARAM = LONG;
+
+struct POINT
+{
+ LONG x;
+ LONG y;
+};
+
+struct MSG
+{
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ DWORD time;
+ POINT pt;
+};
+
+#endif
diff --git a/sources/pyside6/PySide6/qiopipe.h b/sources/pyside6/PySide6/qiopipe.h
new file mode 100644
index 000000000..6a325f184
--- /dev/null
+++ b/sources/pyside6/PySide6/qiopipe.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QIOPIPE_H
+#define QIOPIPE_H
+
+#include <QtCore/qiodevicebase.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+
+namespace QtCoreHelper
+{
+
+class QIOPipePrivate;
+class QIOPipe : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QIOPipe)
+
+public:
+ QIOPipe(QObject *parent = nullptr);
+
+ bool open(QIODeviceBase::OpenMode mode);
+
+ QIODevice *end1() const;
+ QIODevice *end2() const;
+};
+
+} // namespace QtCoreHelper
+
+QT_END_NAMESPACE
+
+#endif // QIOPIPE_H
diff --git a/sources/pyside6/PySide6/qpydesignerextensions.h b/sources/pyside6/PySide6/qpydesignerextensions.h
new file mode 100644
index 000000000..871fa8284
--- /dev/null
+++ b/sources/pyside6/PySide6/qpydesignerextensions.h
@@ -0,0 +1,84 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPYDESIGNEREXTENSIONS_H
+#define QPYDESIGNEREXTENSIONS_H
+
+#include <QtDesigner/QDesignerContainerExtension>
+#include <QtDesigner/QDesignerMemberSheetExtension>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtUiPlugin/QDesignerCustomWidgetCollectionInterface>
+#include <QtUiPlugin/QDesignerCustomWidgetInterface>
+
+// Not automatically found since "find_package(Qt6 COMPONENTS Designer)" is not used
+
+#ifdef Q_MOC_RUN
+Q_DECLARE_INTERFACE(QDesignerContainerExtension, "org.qt-project.Qt.Designer.Container")
+Q_DECLARE_INTERFACE(QDesignerMemberSheetExtension, "org.qt-project.Qt.Designer.MemberSheet")
+Q_DECLARE_EXTENSION_INTERFACE(QDesignerPropertySheetExtension, "org.qt-project.Qt.Designer.PropertySheet")
+Q_DECLARE_INTERFACE(QDesignerTaskMenuExtension, "org.qt-project.Qt.Designer.TaskMenu")
+Q_DECLARE_INTERFACE(QDesignerCustomWidgetCollectionInterface, "org.qt-project.Qt.QDesignerCustomWidgetCollectionInterface")
+#endif
+
+struct _object; // PyObject
+
+QT_BEGIN_NAMESPACE
+
+// Extension implementations need to inherit QObject which cannot be done in Python.
+// Provide a base class (cf QPyTextObject).
+
+class QPyDesignerContainerExtension : public QObject, public QDesignerContainerExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerContainerExtension)
+public:
+ explicit QPyDesignerContainerExtension(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+class QPyDesignerMemberSheetExtension : public QObject, public QDesignerMemberSheetExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerMemberSheetExtension)
+public:
+ explicit QPyDesignerMemberSheetExtension(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+class QPyDesignerPropertySheetExtension : public QObject, public QDesignerPropertySheetExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerPropertySheetExtension)
+public:
+ explicit QPyDesignerPropertySheetExtension(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+class QPyDesignerTaskMenuExtension : public QObject, public QDesignerTaskMenuExtension
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerTaskMenuExtension)
+public:
+ explicit QPyDesignerTaskMenuExtension(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+class QPyDesignerCustomWidgetCollection : public QDesignerCustomWidgetCollectionInterface
+{
+public:
+ ~QPyDesignerCustomWidgetCollection();
+
+ static QPyDesignerCustomWidgetCollection *instance();
+
+ QList<QDesignerCustomWidgetInterface *> customWidgets() const override;
+
+ static void addCustomWidget(QDesignerCustomWidgetInterface *c);
+
+ static bool _registerCustomWidgetHelper(_object *typeArg, _object *kwds);
+
+private:
+ QPyDesignerCustomWidgetCollection();
+
+ QList<QDesignerCustomWidgetInterface *> m_customWidgets;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPYDESIGNEREXTENSIONS_H
diff --git a/sources/pyside6/PySide6/qpyqmlparserstatus.h b/sources/pyside6/PySide6/qpyqmlparserstatus.h
new file mode 100644
index 000000000..24dcdda75
--- /dev/null
+++ b/sources/pyside6/PySide6/qpyqmlparserstatus.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPYQMLPARSERSTATUS_H
+#define QPYQMLPARSERSTATUS_H
+
+#include <QtCore/QObject>
+#include <QtQml/QQmlParserStatus>
+
+#ifdef Q_MOC_RUN
+Q_DECLARE_INTERFACE(QQmlParserStatus, "org.qt-project.Qt.QQmlParserStatus")
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// Inherit from QObject such that QQmlParserStatus can be found at
+// a fixed offset (RegisterType::parserStatusCast).
+class QPyQmlParserStatus : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+public:
+ explicit QPyQmlParserStatus(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+QT_END_NAMESPACE
+
+#endif // QPYQMLPARSERSTATUS_H
diff --git a/sources/pyside6/PySide6/qpyqmlpropertyvaluesource.h b/sources/pyside6/PySide6/qpyqmlpropertyvaluesource.h
new file mode 100644
index 000000000..0b6a0b95c
--- /dev/null
+++ b/sources/pyside6/PySide6/qpyqmlpropertyvaluesource.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPYQMLPROPERTYVALUESOURCE_H
+#define QPYQMLPROPERTYVALUESOURCE_H
+
+#include <QtQml/QQmlPropertyValueSource>
+
+#ifdef Q_MOC_RUN
+Q_DECLARE_INTERFACE(QQmlPropertyValueSource, "org.qt-project.Qt.QQmlPropertyValueSource")
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// Inherit from QObject such that QQmlPropertyValueSource can be found at
+// a fixed offset (RegisterType::valueSourceCast).
+class QPyQmlPropertyValueSource : public QObject, public QQmlPropertyValueSource
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlPropertyValueSource)
+public:
+ explicit QPyQmlPropertyValueSource(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+QT_END_NAMESPACE
+
+#endif // QPYQMLPROPERTYVALUESOURCE_H
diff --git a/sources/pyside6/PySide6/qpytextobject.cpp b/sources/pyside6/PySide6/qpytextobject.cpp
new file mode 100644
index 000000000..501db2af9
--- /dev/null
+++ b/sources/pyside6/PySide6/qpytextobject.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qpytextobject.h"
+
+/*!
+ \class QPyTextObject
+ \brief Workaround to make possible use QTextObjectInterface on PySide.
+ \ingroup richtext-processing
+ Due to the technical details of how to bind C++ classes to Python, you need to use this class when you need to implement
+ your own QTextObjectInterface rather than create a class inheriting from QObject and QTextObjectInterface.
+
+ \sa QTextObjectInterface
+*/
diff --git a/sources/pyside6/PySide6/qpytextobject.h b/sources/pyside6/PySide6/qpytextobject.h
new file mode 100644
index 000000000..45bb0bd52
--- /dev/null
+++ b/sources/pyside6/PySide6/qpytextobject.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPYTEXTOBJECT
+#define QPYTEXTOBJECT
+
+#include <QtCore/QObject>
+#include <QtGui/QTextObjectInterface>
+
+// Qt5: no idea why this definition is not found automatically! It should come
+// from <QTextObjectInterface> which resolves to qabstracttextdocumentlayout.h
+#ifdef Q_MOC_RUN
+Q_DECLARE_INTERFACE(QTextObjectInterface, "org.qt-project.Qt.QTextObjectInterface")
+#endif
+
+QT_BEGIN_NAMESPACE
+class QPyTextObject : public QObject, public QTextObjectInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QTextObjectInterface)
+public:
+ QPyTextObject(QObject *parent = nullptr) : QObject(parent) {}
+};
+QT_END_NAMESPACE
+
+#endif
+
+
diff --git a/sources/pyside6/PySide6/qt.conf.in b/sources/pyside6/PySide6/qt.conf.in
new file mode 100644
index 000000000..ff5b0a30e
--- /dev/null
+++ b/sources/pyside6/PySide6/qt.conf.in
@@ -0,0 +1,2 @@
+[Paths]
+Prefix = @QT_CONF_PREFIX@
diff --git a/sources/pyside6/PySide6/qtcorehelper.h b/sources/pyside6/PySide6/qtcorehelper.h
new file mode 100644
index 000000000..589d0b295
--- /dev/null
+++ b/sources/pyside6/PySide6/qtcorehelper.h
@@ -0,0 +1,122 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTCOREHELPER_H
+#define QTCOREHELPER_H
+
+#include <QtCore/qmutex.h>
+#include <QtCore/qobjectdefs.h>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtCoreHelper {
+
+ using MutexLocker = QT_PREPEND_NAMESPACE(QMutexLocker<QMutex>);
+ using RecursiveMutexLocker = QT_PREPEND_NAMESPACE(QMutexLocker<QRecursiveMutex>);
+
+ // ::QMutexLocker is a template with the QMutex class as parameter which can
+ // only be represented by different type names in Python. Provide a common API.
+ class QMutexLocker
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QMutexLocker)
+
+ explicit QMutexLocker(QMutex *m)
+ : m_mutexLocker(new MutexLocker(m))
+ {
+ }
+
+ explicit QMutexLocker(QRecursiveMutex *m)
+ : m_recursiveMutexLocker(new RecursiveMutexLocker(m))
+ {
+ }
+
+ void unlock()
+ {
+ if (m_mutexLocker)
+ m_mutexLocker->unlock();
+ else
+ m_recursiveMutexLocker->unlock();
+ }
+
+ void relock()
+ {
+ if (m_mutexLocker)
+ m_mutexLocker->relock();
+ else
+ m_recursiveMutexLocker->relock();
+ }
+
+ QMutex *mutex() const
+ {
+ return m_mutexLocker ? m_mutexLocker->mutex() : nullptr;
+ }
+
+ QRecursiveMutex *recursiveMutex() const
+ {
+ return m_recursiveMutexLocker ? m_recursiveMutexLocker->mutex() : nullptr;
+ }
+
+ ~QMutexLocker()
+ {
+ delete m_mutexLocker;
+ delete m_recursiveMutexLocker;
+ }
+
+ private:
+ MutexLocker *m_mutexLocker = nullptr;
+ RecursiveMutexLocker *m_recursiveMutexLocker = nullptr;
+ };
+
+ class QGenericArgumentData;
+
+ // Return value of function Q_ARG() to be passed to QMetaObject::invokeMethod.
+ // Frees the data if it is an allocated, primitive type.
+ class QGenericArgumentHolder {
+ public:
+ QGenericArgumentHolder();
+ explicit QGenericArgumentHolder(const QMetaType &type, const void *aData);
+ QGenericArgumentHolder(const QGenericArgumentHolder &);
+ QGenericArgumentHolder(QGenericArgumentHolder &&);
+ QGenericArgumentHolder &operator=(const QGenericArgumentHolder &);
+ QGenericArgumentHolder &operator=(QGenericArgumentHolder &&);
+ ~QGenericArgumentHolder();
+
+ QGenericArgument toGenericArgument() const;
+
+ QMetaType metaType() const;
+ const void *data() const;
+
+ private:
+ std::shared_ptr<QGenericArgumentData> d;
+ };
+
+ class QGenericReturnArgumentData;
+
+ // Return value of function Q_RETURN_ARG() to be passed to QMetaObject::invokeMethod.
+ // Frees the data if it is an allocated, primitive type.
+ class QGenericReturnArgumentHolder {
+ public:
+ explicit QGenericReturnArgumentHolder(const QMetaType &type, void *aData);
+ QGenericReturnArgumentHolder(const QGenericReturnArgumentHolder &);
+ QGenericReturnArgumentHolder(QGenericReturnArgumentHolder &&);
+ QGenericReturnArgumentHolder &operator=(const QGenericReturnArgumentHolder &);
+ QGenericReturnArgumentHolder &operator=(QGenericReturnArgumentHolder &&);
+ ~QGenericReturnArgumentHolder();
+
+ QGenericReturnArgument toGenericReturnArgument() const;
+
+ QMetaType metaType() const;
+ const void *data() const;
+
+ private:
+ std::shared_ptr<QGenericReturnArgumentData> d;
+ };
+
+} // namespace QtCoreHelper
+
+QT_END_NAMESPACE
+
+#endif // QTCOREHELPER_H
diff --git a/sources/pyside6/PySide6/qtdatavisualization_helper.h b/sources/pyside6/PySide6/qtdatavisualization_helper.h
new file mode 100644
index 000000000..8fee4492d
--- /dev/null
+++ b/sources/pyside6/PySide6/qtdatavisualization_helper.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTDATAVISUALIZATION_HELPER_H
+#define QTDATAVISUALIZATION_HELPER_H
+
+#include <sbkpython.h>
+
+#include <QtDataVisualization/qsurfacedataproxy.h>
+#include <QtCore/qlist.h>
+
+namespace QtDataVisualizationHelper {
+
+QSurfaceDataArray *surfaceDataFromNp(double x, double deltaX, double z, double deltaZ,
+ PyObject *data);
+
+} // namespace QtDataVisualizationHelper
+
+#endif // QTDATAVISUALIZATION_HELPER_H
diff --git a/sources/pyside6/PySide6/qtdbushelper.h b/sources/pyside6/PySide6/qtdbushelper.h
new file mode 100644
index 000000000..7389ad815
--- /dev/null
+++ b/sources/pyside6/PySide6/qtdbushelper.h
@@ -0,0 +1,62 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTDBUSHELPER_H
+#define QTDBUSHELPER_H
+
+#include <QtDBus/qdbusmessage.h>
+#include <QtDBus/qdbuspendingcall.h>
+#include <QtDBus/qdbusreply.h>
+
+QT_BEGIN_NAMESPACE
+namespace QtDBusHelper {
+
+// A Python-bindings friendly, non-template QDBusReply
+
+class QDBusReply {
+public:
+ QDBusReply();
+
+ // Enable constructing QDBusReply from a QDBusMessage which is returned by
+ // call().
+ explicit QDBusReply(const QDBusMessage &reply) :
+ m_error(reply),
+ m_data(reply.arguments().value(0, {}))
+ {
+ }
+
+ // Enable constructing QDBusReply from an original Qt QDBusReply for
+ // the functions we declare (QDBusConnectionInterface::registeredServiceNames())
+ template <class T>
+ explicit QDBusReply(const ::QDBusReply<T> &qr) :
+ m_error(qr.error()),
+ m_data(QVariant(qr.value()))
+ {
+ }
+
+ explicit QDBusReply(const ::QDBusReply<void> &qr) :
+ m_error(qr.error())
+ {
+ }
+
+ bool isValid() const { return !m_error.isValid(); }
+
+ QVariant value() const
+ {
+ return m_data;
+ }
+
+ const QDBusError &error() const { return m_error; }
+
+private:
+ QDBusError m_error;
+ QVariant m_data;
+};
+
+inline QDBusReply::QDBusReply() = default;
+
+} // namespace QtDBusHelper
+
+QT_END_NAMESPACE
+
+#endif // QTDBUSHELPER_H
diff --git a/sources/pyside6/PySide6/qtgraphs_helper.h b/sources/pyside6/PySide6/qtgraphs_helper.h
new file mode 100644
index 000000000..e488fc7d3
--- /dev/null
+++ b/sources/pyside6/PySide6/qtgraphs_helper.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTGRAPHS_HELPER_H
+#define QTGRAPHS_HELPER_H
+
+#include <sbkpython.h>
+
+#include <QtGraphs/qsurfacedataproxy.h>
+#include <QtCore/qlist.h>
+
+namespace QtGraphsHelper {
+
+QSurfaceDataArray surfaceDataFromNp(double x, double deltaX, double z, double deltaZ,
+ PyObject *data);
+
+} // namespace QtGraphsHelper
+
+#endif // QTGRAPHS_HELPER_H
diff --git a/sources/pyside6/PySide6/qtguihelper.h b/sources/pyside6/PySide6/qtguihelper.h
new file mode 100644
index 000000000..e537cfefa
--- /dev/null
+++ b/sources/pyside6/PySide6/qtguihelper.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTGUIHELPER_H
+#define QTGUIHELPER_H
+
+#include <QtGui/QGuiApplication>
+
+QT_BEGIN_NAMESPACE
+namespace QtGuiHelper {
+
+ class QOverrideCursorGuard
+ {
+ public:
+ Q_DISABLE_COPY_MOVE(QOverrideCursorGuard)
+
+ QOverrideCursorGuard() = default;
+ ~QOverrideCursorGuard() = default;
+
+ void restoreOverrideCursor()
+ {
+ if (m_guard) {
+ QGuiApplication::restoreOverrideCursor();
+ m_guard = false;
+ }
+ }
+
+ private:
+ bool m_guard = true;
+ };
+
+} // namespace QtGuiHelper
+QT_END_NAMESPACE
+
+#endif // QTGUIHELPER_H
diff --git a/sources/pyside6/PySide6/support/__init__.py b/sources/pyside6/PySide6/support/__init__.py
new file mode 100644
index 000000000..5127df0f4
--- /dev/null
+++ b/sources/pyside6/PySide6/support/__init__.py
@@ -0,0 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+from shiboken6.Shiboken import VoidPtr
+
+#eof
diff --git a/sources/pyside6/PySide6/support/deprecated.py b/sources/pyside6/PySide6/support/deprecated.py
new file mode 100644
index 000000000..263dd3ed7
--- /dev/null
+++ b/sources/pyside6/PySide6/support/deprecated.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+deprecated.py
+
+This module contains deprecated things that are removed from the interface.
+They are implemented in Python again, together with a deprecation warning.
+
+Functions that are to be called for
+ PySide6.<module> must be named
+ fix_for_<module> .
+
+Note that this fixing code is run after all initializations, but before the
+import is finished. But that is no problem since the module is passed in.
+"""
+
+# eof
diff --git a/sources/pyside6/PySide6/support/generate_pyi.py b/sources/pyside6/PySide6/support/generate_pyi.py
new file mode 100644
index 000000000..92808e2a5
--- /dev/null
+++ b/sources/pyside6/PySide6/support/generate_pyi.py
@@ -0,0 +1,93 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+generate_pyi.py
+
+This script generates the .pyi files for all PySide modules.
+"""
+
+import argparse
+import inspect # noqa: F401
+import logging
+import os
+import sys
+import typing # noqa: F401
+
+from pathlib import Path
+from types import SimpleNamespace # noqa: F401
+
+# Can we use forward references?
+USE_PEP563 = sys.version_info[:2] >= (3, 7)
+
+
+def generate_all_pyi(outpath, options):
+ ps = os.pathsep
+ if options.sys_path:
+ # make sure to propagate the paths from sys_path to subprocesses
+ normpath = lambda x: os.fspath(Path(x).resolve()) # noqa: E731
+ sys_path = [normpath(_) for _ in options.sys_path]
+ sys.path[0:0] = sys_path
+ pypath = ps.join(sys_path)
+ os.environ["PYTHONPATH"] = pypath
+
+ # now we can import
+ global PySide6, inspect, typing, HintingEnumerator, build_brace_pattern
+ import PySide6
+ from PySide6.support.signature.lib.enum_sig import HintingEnumerator
+ from PySide6.support.signature.lib.tool import build_brace_pattern
+ from PySide6.support.signature.lib.pyi_generator import generate_pyi
+
+ # propagate USE_PEP563 to the mapping module.
+ # Perhaps this can be automated?
+ PySide6.support.signature.mapping.USE_PEP563 = USE_PEP563
+
+ outpath = Path(outpath) if outpath and os.fspath(outpath) else Path(PySide6.__file__).parent
+ name_list = PySide6.__all__ if options.modules == ["all"] else options.modules
+ errors = ", ".join(set(name_list) - set(PySide6.__all__))
+ if errors:
+ raise ImportError(f"The module(s) '{errors}' do not exist")
+ for mod_name in name_list:
+ import_name = "PySide6." + mod_name
+ if hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: We cannot use __feature__ yet in PyPy
+ generate_pyi(import_name, outpath, options)
+ else:
+ from PySide6.support import feature
+ feature_id = feature.get_select_id(options.feature)
+ with feature.force_selection(feature_id, import_name):
+ generate_pyi(import_name, outpath, options)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="This script generates the .pyi file for all PySide modules.")
+ parser.add_argument("modules", nargs="+",
+ help="'all' or the names of modules to build (QtCore QtGui etc.)")
+ parser.add_argument("--quiet", action="store_true", help="Run quietly")
+ parser.add_argument("--outpath",
+ help="the output directory (default = binary location)")
+ parser.add_argument("--sys-path", nargs="+",
+ help="a list of strings prepended to sys.path")
+ parser.add_argument("--feature", nargs="+", choices=["snake_case", "true_property"], default=[],
+ help="""a list of feature names. """
+ """Example: `--feature snake_case true_property`. """
+ """Currently not available for PyPy.""")
+ options = parser.parse_args()
+
+ qtest_env = os.environ.get("QTEST_ENVIRONMENT", "")
+ log_level = logging.DEBUG if qtest_env else logging.INFO
+ if options.quiet:
+ log_level = logging.WARNING
+ logging.basicConfig(level=log_level)
+ logger = logging.getLogger("generate_pyi")
+
+ outpath = options.outpath
+ if outpath and not Path(outpath).exists():
+ os.makedirs(outpath)
+ logger.info(f"+++ Created path {outpath}")
+ options._pyside_call = True
+ options.logger = logger
+ options.is_ci = qtest_env == "ci"
+ generate_all_pyi(outpath, options=options)
+# eof
diff --git a/sources/pyside6/PySide6/templates/common.xml b/sources/pyside6/PySide6/templates/common.xml
new file mode 100644
index 000000000..44ed931e7
--- /dev/null
+++ b/sources/pyside6/PySide6/templates/common.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem>
+ <template name="const_char_pybuffer">
+ PyObject *%out = Shiboken::Buffer::newObject(%in, size);
+ </template>
+
+ <template name="pybuffer_const_char">
+ Py_ssize_t bufferLen;
+ char *%out = reinterpret_cast&lt;char*&gt;(Shiboken::Buffer::getPointer(%PYARG_1, &amp;bufferLen));
+ </template>
+
+ <template name="uint_remove">
+ uint %out = bufferLen;
+ </template>
+
+ <template name="pybytes_const_uchar">
+ const uchar *%out = reinterpret_cast&lt;const uchar*>(PyBytes_AS_STRING(%PYARG_1));
+ </template>
+
+ <template name="pybytes_uint">
+ uint %out = static_cast&lt;uint>(PyBytes_Size(%PYARG_1));
+ </template>
+</typesystem>
diff --git a/sources/pyside6/PySide6/templates/core_common.xml b/sources/pyside6/PySide6/templates/core_common.xml
new file mode 100644
index 000000000..07bafc6ff
--- /dev/null
+++ b/sources/pyside6/PySide6/templates/core_common.xml
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem>
+
+ <template name="tuple_ok_retval">
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](ok_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ </template>
+
+ <template name="bool*_fix,arg">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;ok_, %2);
+ <insert-template name="tuple_ok_retval"/>
+ </template>
+
+ <template name="bool*_fix,arg,arg,arg,arg">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;ok_, %2, %3, %4, %5);
+ <insert-template name="tuple_ok_retval"/>
+ </template>
+
+ <!-- Templates to fix bool* parameters -->
+ <template name="tuple_retval_ok">
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[bool](ok_));
+ </template>
+
+ <template name="fix_bool*">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;ok_);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_args,bool*">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;ok_);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_args,arg,bool*">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, &amp;ok_);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_arg,bool*,arg">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, &amp;ok_, %3);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_bool*,arg">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;ok_, %2);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_bool*,arg,arg">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;ok_, %2, %3);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_bool*,arg,arg,arg">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;ok_, %2, %3, %4);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_bool*,arg,arg,arg,arg">
+ bool ok_;
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;ok_, %2, %3, %4, %5);
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <!-- QInputDialog: these should allow threads -->
+ <template name="fix_arg,arg,arg,arg,arg,arg,arg,bool*,arg">
+ bool ok_;
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &amp;ok_, %9);
+ Py_END_ALLOW_THREADS
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_arg,arg,arg,arg,arg,arg,arg,bool*,arg,arg">
+ bool ok_;
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, &amp;ok_, %9, %10);
+ Py_END_ALLOW_THREADS
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_arg,arg,arg,arg,arg,arg,bool*,arg">
+ bool ok_;
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, &amp;ok_, %8);
+ Py_END_ALLOW_THREADS
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_arg,arg,arg,arg,arg,bool*,arg">
+ bool ok_;
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, &amp;ok_, %7);
+ Py_END_ALLOW_THREADS
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+
+ <template name="fix_arg,arg,arg,arg,bool*,arg,arg">
+ bool ok_;
+ %RETURN_TYPE retval_;
+ Py_BEGIN_ALLOW_THREADS
+ retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &amp;ok_, %6, %7);
+ Py_END_ALLOW_THREADS
+ <insert-template name="tuple_retval_ok"/>
+ </template>
+ <!-- End of QInputDialog templates -->
+
+ <template name="fix_char*">
+ char val_{};
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;val_);
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[char](val_));
+ </template>
+
+ <template name="tuple_abcd_same_type">
+ %PYARG_0 = PyTuple_New(4);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[$TYPE](c));
+ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[$TYPE](d));
+ </template>
+
+ <template name="fix_number*,number*,number*,number*">
+ $TYPE a, b, c, d;
+ %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d);
+ <insert-template name="tuple_abcd_same_type"/>
+ </template>
+
+ <template name="fix_number*,number*,number*,number*,args">
+ $TYPE a, b, c, d;
+ %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d, %ARGUMENT_NAMES);
+ <insert-template name="tuple_abcd_same_type"/>
+ </template>
+
+ <template name="fix_native_return_number*,number*,number*,number*">
+ PyObject* _obj = %PYARG_0.object();
+ if (!PySequence_Check(_obj)
+ || PySequence_Fast_GET_SIZE(_obj) != 4
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 0))
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 1))
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 2))
+ || !PyNumber_Check(PySequence_Fast_GET_ITEM(_obj, 3))) {
+ PyErr_SetString(PyExc_TypeError, "Sequence of 4 numbers expected");
+ } else {
+ *%1 = %CONVERTTOCPP[$TYPE](PySequence_Fast_GET_ITEM(_obj, 0));
+ *%2 = %CONVERTTOCPP[$TYPE](PySequence_Fast_GET_ITEM(_obj, 1));
+ *%3 = %CONVERTTOCPP[$TYPE](PySequence_Fast_GET_ITEM(_obj, 2));
+ *%4 = %CONVERTTOCPP[$TYPE](PySequence_Fast_GET_ITEM(_obj, 3));
+ }
+ </template>
+
+ <template name="fix_number*,number*,number*,number*,number*">
+ $TYPE a, b, c, d, e;
+ %CPPSELF.%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d, &amp;e);
+ %PYARG_0 = PyTuple_New(5);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[$TYPE](c));
+ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[$TYPE](d));
+ PyTuple_SET_ITEM(%PYARG_0, 4, %CONVERTTOPYTHON[$TYPE](e));
+ </template>
+
+ <template name="fix_args,number*,number*">
+ $TYPE a, b;
+ %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;a, &amp;b);
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
+ </template>
+
+ <template name="fix_arg,int*,int*">
+ %RETURN_TYPE _ret;
+ int a, b;
+ _ret = %CPPSELF.%FUNCTION_NAME(%1, &amp;a, &amp;b);
+ %PYARG_0 = PyTuple_New(3);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](_ret));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](a));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](b));
+ </template>
+
+ <template name="return_tuple_QValidator_QString_int">
+ %RETURN_TYPE retval_ = %RETURN_TYPE(%CPPSELF.%FUNCTION_NAME(%1, %2));
+ %PYARG_0 = PyTuple_New(3);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[%ARG2_TYPE](%2));
+ </template>
+
+ <template name="repr_code">
+ QString format = QString::asprintf("%s(%REPR_FORMAT)",
+ Py_TYPE(%PYSELF)->tp_name, %REPR_ARGS);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(format));
+ </template>
+
+ <template name="repr_qdebug">
+ QString result;
+ QDebug(&amp;result).nospace() &lt;&lt; "&lt;PySide6.MODULE." &lt;&lt; %CPPSELF &lt;&lt; '>';
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(result));
+ </template>
+
+ <template name="repr_qdebug_gui">
+ <insert-template name="repr_qdebug">
+ <replace from="MODULE" to="QtGui"/>
+ </insert-template>
+ </template>
+
+ <template name="return_internal_pointer">
+ %PYARG_0 = reinterpret_cast&lt;PyObject*>(%CPPSELF.%FUNCTION_NAME());
+ if (!%PYARG_0)
+ %PYARG_0 = Py_None;
+ Py_INCREF(%PYARG_0);
+ </template>
+
+ <!-- Helpers for modifying "bool nativeEventFilter(QByteArray, void*, long *result)"
+ to return a tuple of bool,long -->
+ <template name="return_native_eventfilter_conversion_variables">
+ qintptr resultVar{0};
+ qintptr *%out = &amp;resultVar;
+ </template>
+ <template name="return_native_eventfilter_conversion">
+ %RETURN_TYPE %out = false;
+ if (PySequence_Check(%PYARG_0) &amp;&amp; (PySequence_Size(%PYARG_0) == 2)) {
+ Shiboken::AutoDecRef pyItem(PySequence_GetItem(%PYARG_0, 0));
+ %out = %CONVERTTOCPP[bool](pyItem);
+ if (result) {
+ Shiboken::AutoDecRef pyResultItem(PySequence_GetItem(pyResult, 1));
+ *result = %CONVERTTOCPP[long](pyResultItem);
+ }
+ }
+ </template>
+
+ <template name="return_native_eventfilter">
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[long](*result_out));
+ </template>
+
+ <!-- templates for __reduce__ -->
+ <template name="reduce_code">
+ %PYARG_0 = Py_BuildValue("(N(%REDUCE_FORMAT))", PyObject_Type(%PYSELF), %REDUCE_ARGS);
+ </template>
+
+ <!-- Replace '#' for the argument number you want. -->
+ <template name="return_argument">
+ Py_INCREF(%PYARG_#);
+ %PYARG_0 = %PYARG_#;
+ </template>
+
+ <!-- Iterator -->
+ <template name="__iter__">
+ Py_INCREF(%PYSELF);
+ %PYARG_0 = %PYSELF;
+ </template>
+
+ <template name="to_tuple">
+ %PYARG_0 = Py_BuildValue("%TT_FORMAT", %TT_ARGS);
+ </template>
+
+ <template name="checkPyCapsuleOrPyCObject_func">
+ static bool checkPyCapsuleOrPyCObject(PyObject* pyObj)
+ {
+ return PyCapsule_CheckExact(pyObj);
+ }
+ </template>
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/templates/datavisualization_common.xml b/sources/pyside6/PySide6/templates/datavisualization_common.xml
new file mode 100644
index 000000000..6d5861322
--- /dev/null
+++ b/sources/pyside6/PySide6/templates/datavisualization_common.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem>
+ <template name="cppqlistofptrtoqlists_to_py_conversion">
+ const Py_ssize_t rowCount = %in.size();
+ PyObject* %out = PyList_New(rowCount);
+ for (Py_ssize_t r = 0; r &lt; rowCount; ++r) {
+ const QList&lt;%INTYPE_0&gt; *row = %in.at(r);
+ const Py_ssize_t columnCount = row->size();
+ PyObject *pyRow = PyList_New(columnCount);
+ for (Py_ssize_t c = 0; c &lt; columnCount; ++c) {
+ const %INTYPE_0 &amp;cppItem = row->at(c);
+ PyList_SET_ITEM(pyRow, c, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
+ }
+ PyList_SET_ITEM(%out, r, pyRow);
+ }
+ return %out;
+ </template>
+
+ <template name="py_to_cppqlistofptrtoqlists_conversion">
+ const Py_ssize_t rowCount = PySequence_Size(%in);
+ %OUTTYPE &amp;result = %out;
+ result.reserve(rowCount);
+ for (Py_ssize_t r = 0; r &lt; rowCount; ++r) {
+ Shiboken::AutoDecRef rowItem(PySequence_GetItem(%in, r));
+ const Py_ssize_t columnCount = PySequence_Size(rowItem);
+ auto *row = new QList&lt;%OUTTYPE_0&gt;;
+ row->reserve(columnCount);
+ for (Py_ssize_t c = 0; c &lt; columnCount; ++c) {
+ Shiboken::AutoDecRef pyItem(PySequence_GetItem(rowItem, c));
+ %OUTTYPE_0 v = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
+ row->append(v);
+ }
+ result.append(row);
+ }
+ </template>
+</typesystem>
diff --git a/sources/pyside6/PySide6/templates/gui_common.xml b/sources/pyside6/PySide6/templates/gui_common.xml
new file mode 100644
index 000000000..6a7404507
--- /dev/null
+++ b/sources/pyside6/PySide6/templates/gui_common.xml
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem>
+ <template name="QFontCharFix">
+ int size = Shiboken::String::len(%PYARG_1);
+ if (size == 1) {
+ const char *str = Shiboken::String::toCString(%PYARG_1);
+ const QChar ch(static_cast&lt;unsigned short&gt;(str[0]));
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ch);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "String must have only one character");
+ }
+ </template>
+
+ <template name="load_xpm">
+ Shiboken::AutoDecRef strList(PySequence_Fast(%PYARG_1, "Invalid sequence."));
+ Py_ssize_t lineCount = PySequence_Fast_GET_SIZE(strList.object());
+ for (Py_ssize_t line = 0; line &lt; lineCount; ++line) {
+ if (!Shiboken::String::check(PySequence_Fast_GET_ITEM(strList.object(), line))) {
+ PyErr_SetString(PyExc_TypeError, "The argument must be a sequence of strings.");
+ break;
+ }
+ }
+ // PySIDE-1735: Enums are now implemented in Python, so we need to avoid asserts.
+ if (PyErr_Occurred())
+ break;
+
+ auto xpm = new const char*[lineCount];
+ for (Py_ssize_t line = 0; line &lt; lineCount; ++line)
+ xpm[line] = Shiboken::String::toCString(PySequence_Fast_GET_ITEM(strList.object(), line));
+
+ %0 = new %TYPE(xpm);
+
+ delete [] xpm;
+ </template>
+
+ <template name="qmatrix_map">
+ %ARG1_TYPE a, b;
+ %CPPSELF.%FUNCTION_NAME(%1, %2, &amp;a, &amp;b);
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%ARG1_TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](b));
+ </template>
+
+ <template name="qimage_buffer_constructor">
+ Py_INCREF(%PYARG_1);
+ auto ptr = reinterpret_cast&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_1));
+ %0 = new %TYPE(ptr, %ARGS, imageDecrefDataHandler, %PYARG_1);
+ </template>
+
+ <template name="qcolor_repr">
+ switch(%CPPSELF.spec()) {
+ case QColor::Rgb:
+ {
+ float r, g, b, a;
+ %CPPSELF.getRgbF(&amp;r, &amp;g, &amp;b, &amp;a);
+ QString repr = QString::asprintf("PySide6.QtGui.QColor.fromRgbF(%.6f, %.6f, %.6f, %.6f)", r, g, b, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ case QColor::Hsv:
+ {
+ float h, s, v, a;
+ %CPPSELF.getHsvF(&amp;h, &amp;s, &amp;v, &amp;a);
+ QString repr = QString::asprintf("PySide6.QtGui.QColor.fromHsvF(%.6f, %.6f, %.6f, %.6f)", h, s, v, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ case QColor::Cmyk:
+ {
+ float c, m, y, k, a;
+ %CPPSELF.getCmykF(&amp;c, &amp;m, &amp;y, &amp;k, &amp;a);
+ QString repr = QString::asprintf("PySide6.QtGui.QColor.fromCmykF(%.6f, %.6f, %.6f, %.6f, %.6f)", c, m, y, k, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ case QColor::Hsl:
+ {
+ float h, s, l, a;
+ %CPPSELF.getHslF(&amp;h, &amp;s, &amp;l, &amp;a);
+ QString repr = QString::asprintf("PySide6.QtGui.QColor.fromHslF(%.6f, %.6f, %.6f, %.6f)", h, s, l, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ default:
+ {
+ %PYARG_0 = Shiboken::String::fromCString("PySide6.QtGui.QColor()");
+ }
+ }
+ </template>
+
+ <template name="validator_conversionrule">
+ QValidator::State %out;
+
+ if (PySequence_Check(%PYARG_0)) {
+ Shiboken::AutoDecRef seq(PySequence_Fast(%PYARG_0, 0));
+ const Py_ssize_t size = PySequence_Fast_GET_SIZE(seq.object());
+
+ if (size > 1) {
+ if (%ISCONVERTIBLE[QString](PySequence_Fast_GET_ITEM(seq.object(), 1)))
+ %1 = %CONVERTTOCPP[QString](PySequence_Fast_GET_ITEM(seq.object(), 1));
+ else
+ qWarning("%TYPE::%FUNCTION_NAME: Second tuple element is not convertible to unicode.");
+ }
+
+ if (size > 2) {
+ if (%ISCONVERTIBLE[int](PySequence_Fast_GET_ITEM(seq.object(), 2)))
+ %2 = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(seq.object(), 2));
+ else
+ qWarning("%TYPE::%FUNCTION_NAME: Second tuple element is not convertible to int.");
+ }
+ %PYARG_0.reset(PySequence_Fast_GET_ITEM(seq.object(), 0));
+ Py_INCREF(%PYARG_0); // we need to incref, because "%PYARG_0 = ..." will decref the tuple and the tuple will be decrefed again at the end of this scope.
+ }
+
+ // check retrun value
+ if (%ISCONVERTIBLE[QValidator::State](%PYARG_0)) {
+ %out = %CONVERTTOCPP[QValidator::State](%PYARG_0);
+ } else {
+ PyErr_Format(PyExc_TypeError, "Invalid return value in function %s, expected %s, got %s.",
+ "QValidator.validate",
+ "PySide6.QtGui.QValidator.State, (PySide6.QtGui.QValidator.State,), (PySide6.QtGui.QValidator.State, unicode) or (PySide6.QtGui.QValidator.State, unicode, int)",
+ Py_TYPE(pyResult)->tp_name);
+ return QValidator::State();
+ }
+ </template>
+
+ <template name="qpainter_drawlist">
+ %CPPSELF.%FUNCTION_NAME(%1.constData(), %1.size());
+ </template>
+
+ <template name="inplace_add">
+ *%CPPSELF += %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="inplace_sub">
+ *%CPPSELF -= %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="inplace_mult">
+ *%CPPSELF *= %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="inplace_div">
+ *%CPPSELF /= %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="return_QString_native">
+ if (%ISCONVERTIBLE[QString](%PYARG_0))
+ %1 = %CONVERTTOCPP[QString](%PYARG_0);
+ else
+ qWarning("%TYPE::%FUNCTION_NAME: Argument is not convertible to unicode.");
+ </template>
+
+ <template name="repr_code_matrix">
+ QByteArray format(Py_TYPE(%PYSELF)->tp_name);
+ format += QByteArrayLiteral("((");
+
+ QList&lt; %MATRIX_TYPE &gt; cppArgs;
+ %MATRIX_TYPE data[%MATRIX_SIZE];
+ %CPPSELF.copyDataTo(data);
+ int matrixSize = %MATRIX_SIZE;
+ for(int size=0; size &lt; matrixSize; size++) {
+ if (size > 0)
+ format += ", ";
+ format += QByteArray::number(data[size]);
+ }
+ format += "))";
+
+ %PYARG_0 = Shiboken::String::fromStringAndSize(format, format.size());
+ </template>
+
+ <template name="reduce_code_matrix">
+ QList&lt; %MATRIX_TYPE &gt; cppArgs;
+ %MATRIX_TYPE data[%MATRIX_SIZE];
+ %CPPSELF.copyDataTo(data);
+ int matrixSize = %MATRIX_SIZE;
+ for(int size=0; size &lt; matrixSize; size++)
+ cppArgs.append(data[size]);
+
+ PyObject *type = PyObject_Type(%PYSELF);
+ PyObject *args = Py_BuildValue("(N)",
+ %CONVERTTOPYTHON[QList&lt;%MATRIX_TYPE&gt; ](cppArgs));
+ %PYARG_0 = Py_BuildValue("(NN)", type, args);
+ </template>
+
+ <template name="matrix_data_function">
+ const float* data = %CPPSELF.constData();
+ PyObject *pyData = PyTuple_New(%MATRIX_SIZE);
+ if (data) {
+ for(int i=0; i &lt; %MATRIX_SIZE; i++)
+ PyTuple_SET_ITEM(pyData, i, %CONVERTTOPYTHON[float](data[i]));
+ }
+ return pyData;
+ </template>
+
+ <template name="matrix_constructor">
+ // PYSIDE-795: All PySequences can be made iterable with PySequence_Fast.
+ Shiboken::AutoDecRef seq(PySequence_Fast(%PYARG_1, "Can't turn into sequence"));
+ if (PySequence_Size(seq) == %SIZE) {
+ Shiboken::AutoDecRef fast(PySequence_Fast(seq,
+ "Failed to parse sequence on %TYPE constructor."));
+ float values[%SIZE];
+ for(int i=0; i &lt; %SIZE; i++) {
+ PyObject *pv = PySequence_Fast_GET_ITEM(fast.object(), i);
+ values[i] = %CONVERTTOCPP[float](pv);
+ }
+ %0 = new %TYPE(values);
+ }
+ </template>
+
+ <template name="fix_args,QRectF*">
+ QRectF rect_;
+ %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;rect_);
+ %PYARG_0 = %CONVERTTOPYTHON[QRectF](rect_);
+ </template>
+
+ <template name="fix_args,QRect*">
+ QRect rect_;
+ %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;rect_);
+ %PYARG_0 = %CONVERTTOPYTHON[QRect](rect_);
+ </template>
+
+ <template name="__next__">
+ if (!%CPPSELF.atEnd()) {
+ %PYARG_0 = %CONVERTTOPYTHON[%CPPSELF_TYPE](*%CPPSELF);
+ ++(*%CPPSELF);
+ }
+ </template>
+
+ <template name="__iter_parent__">
+ %CPPSELF_TYPE _tmp = %CPPSELF.begin();
+ %PYARG_0 = %CONVERTTOPYTHON[%CPPSELF_TYPE](_tmp);
+ </template>
+
+ <template name="const_char_pybuffer">
+ PyObject *%out = Shiboken::Buffer::newObject(%in, size);
+ </template>
+
+ <template name="pybuffer_const_char">
+ Py_ssize_t bufferLen;
+ char *%out = reinterpret_cast&lt;char*&gt;(Shiboken::Buffer::getPointer(%PYARG_1, &amp;bufferLen));
+ </template>
+
+ <template name="uint_remove">
+ uint %out = bufferLen;
+ </template>
+
+ <template name="pybytes_const_uchar">
+ const uchar *%out = reinterpret_cast&lt;const uchar*>(PyBytes_AS_STRING(%PYARG_1));
+ </template>
+
+ <template name="pybytes_uint">
+ uint %out = static_cast&lt;uint>(PyBytes_Size(%PYARG_1));
+ </template>
+
+
+</typesystem>
diff --git a/sources/pyside6/PySide6/templates/opengl_common.xml b/sources/pyside6/PySide6/templates/opengl_common.xml
new file mode 100644
index 000000000..566ebe6ee
--- /dev/null
+++ b/sources/pyside6/PySide6/templates/opengl_common.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem>
+ <template name="callArrayFunction">
+ Py_ssize_t _size = PySequence_Size(%PYARG_2);
+ if (_size) {
+ $ATTR_TYPE *_list = new $ATTR_TYPE[_size];
+ if (_size) {
+ Shiboken::AutoDecRef fast(PySequence_Fast(%PYARG_2,
+ "Failed to parse sequence with type %VECTOR_TYPE."));
+ for(Py_ssize_t i=0; i &lt; _size; i++) {
+ PyObject* pv = PySequence_Fast_GET_ITEM(fast.object(), i);
+ _list[i] = %CONVERTTOCPP[$ATTR_TYPE](pv);
+ }
+ }
+ %CPPSELF.%FUNCTION_NAME(%1, _list, $ARG0);
+ delete[] _list;
+ } else {
+ %CPPSELF.%FUNCTION_NAME(%1, reinterpret_cast&lt;$ATTR_TYPE*&gt;(nullptr), $ARG1);
+ }
+ </template>
+ <template name="glGetString_return_QString">
+ const GLubyte *us = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES);
+ const QString s = QString::fromLocal8Bit(reinterpret_cast&lt;const char *&gt;(us));
+ %PYARG_0 = %CONVERTTOPYTHON[QString](s);
+ </template>
+</typesystem>
diff --git a/sources/pyside6/PySide6/templates/widgets_common.xml b/sources/pyside6/PySide6/templates/widgets_common.xml
new file mode 100644
index 000000000..b0dee43cd
--- /dev/null
+++ b/sources/pyside6/PySide6/templates/widgets_common.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
+<typesystem>
+
+ <template name="replace_child">
+ $CHILD_TYPE* oldChild = %CPPSELF.$FUNCTION_GET_OLD();
+ if (oldChild &amp;&amp; (oldChild != $CPPARG)) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[$CHILD_TYPE*](oldChild));
+ Shiboken::Object::setParent(nullptr, pyChild);
+ Shiboken::Object::releaseOwnership(pyChild);
+ }
+ Shiboken::Object::setParent(%PYSELF, $PYARG);
+ </template>
+
+ <template name="qgraphicsitem_pysequence">
+ const Py_ssize_t numItems = PySequence_Size(%PYARG_1);
+ Shiboken::AutoArrayPointer&lt;QGraphicsItem*&gt; %out(numItems);
+ for (Py_ssize_t i = 0; i &lt; numItems; ++i) {
+ %out[i] = %CONVERTTOCPP[QGraphicsItem*](PySequence_Fast_GET_ITEM(%PYARG_1, i));
+ }
+ </template>
+
+ <template name="qgraphicsitem_pyobject">
+ Shiboken::AutoDecRef object(PyList_New(0));
+ for (int i=0, max=numItems; i &lt; max; i++) {
+ PyList_Append(object, %CONVERTTOPYTHON[QGraphicsItem*](%in[i]));
+ }
+ PyObject *%out = object.object();
+ </template>
+
+ <template name="qstyleoptiongraphicsitem_pyobject">
+ Shiboken::AutoDecRef option_object(PyList_New(0));
+ for (int i=0, max=numItems; i &lt; max; i++) {
+ const QStyleOptionGraphicsItem* item = &amp;%in[i];
+ PyList_Append(option_object, %CONVERTTOPYTHON[QStyleOptionGraphicsItem](item));
+ }
+ PyObject* %out = option_object.object();
+ </template>
+
+ <template name="pysequence_qstyleoptiongraphicsitem">
+ const Py_ssize_t numOptions = PySequence_Size(%PYARG_2);
+ Shiboken::AutoArrayPointer&lt;QStyleOptionGraphicsItem&gt; %out(numOptions);
+ for (Py_ssize_t i=0; i &lt; numOptions; ++i) {
+ %out[i] = %CONVERTTOCPP[QStyleOptionGraphicsItem](PySequence_Fast_GET_ITEM(%PYARG_1, i));
+ }
+ </template>
+
+ <template name="pysequencesize_int">
+ int %out = PySequence_Size(%PYARG_1);
+ </template>
+
+</typesystem>
diff --git a/sources/pyside6/cmake/Macros/PySideModules.cmake b/sources/pyside6/cmake/Macros/PySideModules.cmake
new file mode 100644
index 000000000..33b844f95
--- /dev/null
+++ b/sources/pyside6/cmake/Macros/PySideModules.cmake
@@ -0,0 +1,386 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(CMakeParseArguments)
+
+# A version of cmake_parse_arguments that makes sure all arguments are processed and errors out
+# with a message about ${type} having received unknown arguments.
+macro(pyside_parse_all_arguments prefix type flags options multiopts)
+ cmake_parse_arguments(${prefix} "${flags}" "${options}" "${multiopts}" ${ARGN})
+ if(DEFINED ${prefix}_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${prefix}_UNPARSED_ARGUMENTS}).")
+ endif()
+endmacro()
+
+macro(make_path varname)
+ # accepts any number of path variables
+ string(REPLACE ";" "${PATH_SEP}" ${varname} "${ARGN}")
+endmacro()
+
+macro(unmake_path varname)
+ string(REPLACE "${PATH_SEP}" ";" ${varname} "${ARGN}")
+endmacro()
+
+# Check for presence of QtOpenGL and modify module variables
+# accordingly
+macro(check_qt_opengl module include_var deps_var dropped_entries_var)
+ if (Qt${QT_MAJOR_VERSION}OpenGL_FOUND)
+ message(STATUS "Qt${QT_MAJOR_VERSION}${module}: Building with OpenGL")
+ list(APPEND ${include_var} ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS}
+ ${QtOpenGL_GEN_DIR})
+ list(APPEND ${deps_var} QtOpenGL)
+ else()
+ message(STATUS "Qt${QT_MAJOR_VERSION}${module}: Dropping OpenGL")
+ # This is a dummy entry creating a conditional typesystem keyword
+ list(APPEND ${dropped_entries_var} "QtOpenGL")
+ endif()
+endmacro()
+
+# set size optimization flags for pyside6
+macro(append_size_optimization_flags _module_name)
+ if(NOT QFP_NO_OVERRIDE_OPTIMIZATION_FLAGS)
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+ target_compile_options(${_module_name} PRIVATE /Gy /Gw /EHsc)
+ target_link_options(${_module_name} PRIVATE LINKER:/OPT:REF)
+ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|CLANG")
+ target_compile_options(${_module_name} PRIVATE -ffunction-sections -fdata-sections -fno-exceptions)
+ target_link_options(${_module_name} PRIVATE LINKER:--gc-sections)
+ endif()
+ endif()
+endmacro()
+
+# Sample usage
+# create_pyside_module(NAME QtGui
+# INCLUDE_DIRS QtGui_include_dirs
+# LIBRARIES QtGui_libraries
+# DEPS QtGui_deps
+# TYPESYSTEM_PATH QtGui_SOURCE_DIR
+# SOURCES QtGui_SRC
+# STATIC_SOURCES QtGui_static_sources
+# TYPESYSTEM_NAME ${QtGui_BINARY_DIR}/typesystem_gui.xml
+# DROPPED_ENTRIES QtGui_DROPPED_ENTRIES
+# GLUE_SOURCES QtGui_glue_sources)
+macro(create_pyside_module)
+ pyside_parse_all_arguments(
+ "module" # Prefix
+ "create_pyside_module" # Macro name
+ "" # Flags
+ "NAME;TYPESYSTEM_PATH;TYPESYSTEM_NAME" # Single value
+ "INCLUDE_DIRS;LIBRARIES;DEPS;SOURCES;STATIC_SOURCES;DROPPED_ENTRIES;GLUE_SOURCES;ADDITIONAL_INCLUDE_DIRS" # Multival
+ ${ARGN} # Number of arguments given when the macros is called
+ )
+
+ if ("${module_NAME}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs a NAME value.")
+ endif()
+ if ("${module_INCLUDE_DIRS}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs at least one INCLUDE_DIRS value.")
+ endif()
+ if ("${module_TYPESYSTEM_PATH}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs a TYPESYSTEM_PATH value.")
+ endif()
+ if ("${module_SOURCES}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs at least one SOURCES value.")
+ endif()
+
+ string(TOLOWER ${module_NAME} _module)
+ string(REGEX REPLACE ^qt "" _module ${_module})
+
+ if(${module_GLUE_SOURCES})
+ set (module_GLUE_SOURCES "${${module_GLUE_SOURCES}}")
+ else()
+ set (module_GLUE_SOURCES "")
+ endif()
+
+ if (NOT EXISTS ${module_TYPESYSTEM_NAME})
+ set(typesystem_path ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_${_module}.xml)
+ else()
+ set(typesystem_path ${module_TYPESYSTEM_NAME})
+ endif()
+
+ # Create typesystem XML dependencies list, so that whenever they change, shiboken is invoked
+ # automatically.
+ # First add the main file.
+ set(total_type_system_files ${typesystem_path})
+
+ get_filename_component(typesystem_root "${CMAKE_CURRENT_SOURCE_DIR}" DIRECTORY)
+
+ set(deps ${module_NAME} ${${module_DEPS}})
+ foreach(dep ${deps})
+ set(glob_expression "${typesystem_root}/${dep}/*.xml")
+ file(GLOB type_system_files ${glob_expression})
+ set(total_type_system_files ${total_type_system_files} ${type_system_files})
+ endforeach(dep)
+
+ # Remove any possible duplicates.
+ list(REMOVE_DUPLICATES total_type_system_files)
+
+ # Contains include directories to pass to shiboken's preprocessor (mkspec / global)
+ get_target_property(qt_platform_includes Qt${QT_MAJOR_VERSION}::Platform
+ INTERFACE_INCLUDE_DIRECTORIES)
+ # Add QtCore since include conventions are sometimes violated for its classes
+ get_target_property(qt_core_includes Qt${QT_MAJOR_VERSION}::Core
+ INTERFACE_INCLUDE_DIRECTORIES)
+ set(shiboken_include_dir_list ${pyside6_SOURCE_DIR} ${qt_platform_includes}
+ ${qt_core_includes})
+ if(module_ADDITIONAL_INCLUDE_DIRS)
+ list(APPEND shiboken_include_dir_list ${${module_ADDITIONAL_INCLUDE_DIRS}})
+ endif()
+
+ # Transform the path separators into something shiboken understands.
+ make_path(shiboken_include_dirs ${shiboken_include_dir_list})
+
+ set(force_process_system_include_paths_list "")
+ # When building against system Qt (as it happens with yocto / Boot2Qt), the Qt headers are
+ # considered system headers by clang_Location_isInSystemHeader, and thus shiboken will not
+ # process them.
+ #
+ # We do want to process them.
+ #
+ # Tell shiboken to consider them as special typesystem system include paths, which ensures
+ # the types are processed and extracted.
+ #
+ # This option is opt-in because it might cause problems if there are other system headers
+ # installed in the same location as the Qt ones, resulting in processing more non-Qt system
+ # types that might not be supported by shiboken.
+ if(PYSIDE_TREAT_QT_INCLUDE_DIRS_AS_NON_SYSTEM)
+ list(APPEND force_process_system_include_paths_list
+ ${qt_platform_includes}
+ ${qt_core_includes})
+ endif()
+
+ # Allow passing extra non system inlcude dirs.
+ if(SHIBOKEN_FORCE_PROCESS_SYSTEM_INCLUDE_PATHS)
+ list(APPEND force_process_system_include_paths_list
+ ${SHIBOKEN_FORCE_PROCESS_SYSTEM_INCLUDE_PATHS})
+ endif()
+
+ # Transform the path separators into something shiboken understands.
+ make_path(force_process_system_include_paths ${force_process_system_include_paths_list})
+
+ if(force_process_system_include_paths)
+ set(force_process_system_include_paths
+ "--force-process-system-include-paths=${force_process_system_include_paths}")
+ endif()
+
+ get_filename_component(pyside_binary_dir ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+
+ # Install module glue files.
+ string(TOLOWER ${module_NAME} lower_module_name)
+ set(${module_NAME}_glue "${CMAKE_CURRENT_SOURCE_DIR}/../glue/${lower_module_name}.cpp")
+ set(${module_name}_glue_dependency "")
+ if(EXISTS ${${module_NAME}_glue})
+ install(FILES ${${module_NAME}_glue} DESTINATION share/PySide6${pyside6_SUFFIX}/glue)
+ set(${module_NAME}_glue_dependency ${${module_NAME}_glue})
+ endif()
+
+ # Install standalone glue files into typesystems subfolder, so that the resolved relative
+ # paths remain correct.
+ if (module_GLUE_SOURCES)
+ install(FILES ${module_GLUE_SOURCES} DESTINATION share/PySide6${pyside6_SUFFIX}/typesystems/glue)
+ endif()
+
+ shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
+ set(shiboken_command
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ ${GENERATOR_EXTRA_FLAGS}
+ "--include-paths=${shiboken_include_dirs}"
+ "${force_process_system_include_paths}"
+ "--typesystem-paths=${pyside_binary_dir}${PATH_SEP}${pyside6_SOURCE_DIR}${PATH_SEP}${${module_TYPESYSTEM_PATH}}"
+ --output-directory=${CMAKE_CURRENT_BINARY_DIR}
+ --license-file=${CMAKE_CURRENT_SOURCE_DIR}/../licensecomment.txt
+ --lean-headers
+ --api-version=${SUPPORTED_QT_VERSION})
+
+ # check if building for Android with a macOS host
+ # This is not needed for Linux because OpenGLES2 development binaries in
+ # linux can be installed by installing 'libgles2-mesa-dev' package which
+ # comes as a default requirement for building PySide6. As such for
+ # cross-compiling in linux, we use the clang compiler from the installed
+ # libclang itself.
+ if(CMAKE_ANDROID_ARCH_LLVM_TRIPLE AND CMAKE_HOST_APPLE)
+ message(STATUS "Building for Android with arch ${CMAKE_ANDROID_ARCH_LLVM_TRIPLE}")
+ list(APPEND shiboken_command "--clang-option=--target=${CMAKE_ANDROID_ARCH_LLVM_TRIPLE}")
+
+ # CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX does not contain the ANDROID_PLATFORM i.e. it ends with
+ # the form 'aarch64-linux-android-'. Remove the last '-' and add the corresponding clang
+ # based on ANDROID_PLATFORM making it 'aarch64-linux-android26-clang++'
+
+ # Get the length of the string
+ string(LENGTH "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}" _length)
+
+ # Subtract 1 from the length to get the characters till '-'
+ math(EXPR _last_index "${_length} - 1")
+
+ # Get the substring from the start to the character before the last one
+ string(SUBSTRING "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}" 0 "${_last_index}"
+ SHIBOKEN_ANDROID_COMPILER_PREFIX)
+
+ # use the compiler from the Android NDK
+ list(APPEND shiboken_command
+ "--compiler-path=${SHIBOKEN_ANDROID_COMPILER_PREFIX}${CMAKE_ANDROID_API}-clang++")
+ endif()
+
+ if(CMAKE_HOST_APPLE)
+ set(shiboken_framework_include_dir_list ${QT_FRAMEWORK_INCLUDE_DIR})
+ make_path(shiboken_framework_include_dirs ${shiboken_framework_include_dir_list})
+ list(APPEND shiboken_command "--framework-include-paths=${shiboken_framework_include_dirs}")
+ endif()
+
+ if(${module_DROPPED_ENTRIES})
+ list(JOIN ${module_DROPPED_ENTRIES} "\;" dropped_entries)
+ list(APPEND shiboken_command "\"--drop-type-entries=${dropped_entries}\"")
+ endif()
+
+ list(APPEND shiboken_command "${pyside6_BINARY_DIR}/${module_NAME}_global.h"
+ ${typesystem_path})
+
+ add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${${module_SOURCES}}
+ COMMAND ${shiboken_command}
+ DEPENDS ${total_type_system_files}
+ ${module_GLUE_SOURCES}
+ ${${module_NAME}_glue_dependency}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for ${module_NAME}...")
+
+ include_directories(${module_NAME} ${${module_INCLUDE_DIRS}} ${pyside6_SOURCE_DIR})
+ add_library(${module_NAME} MODULE ${${module_SOURCES}}
+ ${${module_STATIC_SOURCES}})
+
+ append_size_optimization_flags(${module_NAME})
+
+ target_compile_definitions(${module_NAME} PRIVATE -DQT_LEAN_HEADERS=1)
+
+ set_target_properties(${module_NAME} PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "${module_NAME}${SHIBOKEN_PYTHON_EXTENSION_SUFFIX}"
+ LIBRARY_OUTPUT_DIRECTORY ${pyside6_BINARY_DIR})
+ if(WIN32)
+ set_target_properties(${module_NAME} PROPERTIES SUFFIX ".pyd")
+ # Sanitize windows.h as pulled by gl.h to prevent clashes with QAbstract3dAxis::min(), etc.
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX")
+ endif()
+
+ target_link_libraries(${module_NAME} ${${module_LIBRARIES}})
+ target_link_libraries(${module_NAME} Shiboken6::libshiboken)
+ if(${module_DEPS})
+ add_dependencies(${module_NAME} ${${module_DEPS}})
+ endif()
+ create_generator_target(${module_NAME})
+
+ # build type hinting stubs
+
+ # Need to set the LD_ env vars before invoking the script, because it might use build-time
+ # libraries instead of install time libraries.
+ if (WIN32)
+ set(ld_prefix_var_name "PATH")
+ elseif(APPLE)
+ set(ld_prefix_var_name "DYLD_LIBRARY_PATH")
+ else()
+ set(ld_prefix_var_name "LD_LIBRARY_PATH")
+ endif()
+
+ set(ld_prefix_list "")
+ list(APPEND ld_prefix_list "${pysidebindings_BINARY_DIR}/libpyside")
+ list(APPEND ld_prefix_list "${pysidebindings_BINARY_DIR}/libpysideqml")
+ list(APPEND ld_prefix_list "${SHIBOKEN_SHARED_LIBRARY_DIR}")
+ if(WIN32)
+ list(APPEND ld_prefix_list "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_BINS}")
+ endif()
+
+ list(JOIN ld_prefix_list "${PATH_SEP}" ld_prefix_values_string)
+ set(ld_prefix "${ld_prefix_var_name}=${ld_prefix_values_string}")
+
+ # Append any existing ld_prefix values, so existing PATH, LD_LIBRARY_PATH, etc.
+ # On Windows it is needed because pyside modules import Qt,
+ # and the Qt modules are found from PATH.
+ # On Linux and macOS, existing values might be set to find system libraries correctly.
+ # For example on openSUSE when compiling with icc, libimf.so from Intel has to be found.
+ if(WIN32)
+ # Get the value of PATH with CMake separators.
+ file(TO_CMAKE_PATH "$ENV{${ld_prefix_var_name}}" path_value)
+
+ # Replace the CMake list separators with "\;"s, to avoid the PATH values being
+ # interpreted as CMake list elements, we actually want to pass the whole string separated
+ # by ";" to the command line.
+ if(path_value)
+ make_path(path_value "${path_value}")
+ string(APPEND ld_prefix "${PATH_SEP}${path_value}")
+ endif()
+ else()
+ # Handles both macOS and Linux.
+ set(env_value "$ENV{${ld_prefix_var_name}}")
+ if(env_value)
+ string(APPEND ld_prefix ":${env_value}")
+ endif()
+ endif()
+
+ qfp_strip_library("${module_NAME}")
+
+ # Add target to generate pyi file, which depends on the module target.
+ # Don't generate the files when cross-building because the target python can not be executed
+ # on the host machine (usually, unless you use some userspace qemu based mechanism).
+ # TODO: Can we do something better here to still get pyi files?
+ if(NOT (PYSIDE_IS_CROSS_BUILD OR DISABLE_PYI))
+ set(generate_pyi_options ${module_NAME} --sys-path
+ "${pysidebindings_BINARY_DIR}"
+ "${SHIBOKEN_PYTHON_MODULE_DIR}/..") # use the layer above shiboken6
+ if (QUIET_BUILD)
+ list(APPEND generate_pyi_options "--quiet")
+ endif()
+
+ add_custom_target("${module_NAME}_pyi" ALL
+ COMMAND
+ ${CMAKE_COMMAND} -E env ${ld_prefix}
+ "${SHIBOKEN_PYTHON_INTERPRETER}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../support/generate_pyi.py"
+ ${generate_pyi_options})
+ add_dependencies("${module_NAME}_pyi" ${module_NAME})
+
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/../${module_NAME}.pyi"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/PySide6")
+ endif()
+
+
+ # install
+ install(TARGETS ${module_NAME} LIBRARY DESTINATION "${PYTHON_SITE_PACKAGES}/PySide6")
+
+
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PySide6/${module_NAME}/pyside6_${lower_module_name}_python.h
+ DESTINATION include/PySide6${pyside6_SUFFIX}/${module_NAME}/)
+ file(GLOB typesystem_files ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_*.xml ${typesystem_path})
+
+# Copy typesystem files and remove module names from the <load-typesystem> element
+# so that it works in a flat directory:
+# <load-typesystem name="QtWidgets/typesystem_widgets.xml" ... ->
+# <load-typesystem name="typesystem_widgets.xml"
+ foreach(typesystem_file ${typesystem_files})
+ get_filename_component(typesystem_file_name "${typesystem_file}" NAME)
+ file(READ "${typesystem_file}" typesystemXml)
+ string(REGEX REPLACE "<load-typesystem name=\"[^/\"]+/" "<load-typesystem name=\"" typesystemXml "${typesystemXml}")
+ set (typesystem_target_file "${CMAKE_CURRENT_BINARY_DIR}/PySide6/typesystems/${typesystem_file_name}")
+ file(WRITE "${typesystem_target_file}" "${typesystemXml}")
+ install(FILES "${typesystem_target_file}" DESTINATION share/PySide6${pyside6_SUFFIX}/typesystems)
+ endforeach()
+endmacro()
+
+# Only add subdirectory if the associated Qt module is found.
+# As a side effect, this macro now also defines the variable ${name}_GEN_DIR
+# and must be called for every subproject.
+macro(HAS_QT_MODULE var name)
+ if (NOT DISABLE_${name} AND ${var})
+ # we keep the PySide name here because this is compiled into shiboken
+ set(${name}_GEN_DIR ${CMAKE_CURRENT_BINARY_DIR}/${name}/PySide6/${name}
+ CACHE INTERNAL "dir with generated source" FORCE)
+ add_subdirectory(${name})
+ else()
+ # Used on documentation to skip modules
+ set("if_${name}" "<!--" PARENT_SCOPE)
+ set("end_${name}" "-->" PARENT_SCOPE)
+ endif()
+endmacro()
+
diff --git a/sources/pyside6/cmake/Macros/icecc.cmake b/sources/pyside6/cmake/Macros/icecc.cmake
new file mode 100644
index 000000000..fa8d3b7cf
--- /dev/null
+++ b/sources/pyside6/cmake/Macros/icecc.cmake
@@ -0,0 +1,14 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include (CMakeForceCompiler)
+option(ENABLE_ICECC "Enable icecc checking, for distributed compilation")
+if (ENABLE_ICECC)
+ find_program(ICECC icecc)
+ if (ICECC)
+ message(STATUS "icecc found! Distributed compilation for all!! huhuhu.")
+ cmake_force_cxx_compiler(${ICECC} icecc)
+ else(ICECC)
+ message(FATAL_ERROR "icecc NOT found! re-run cmake without -DENABLE_ICECC")
+ endif(ICECC)
+endif(ENABLE_ICECC)
diff --git a/sources/pyside6/cmake/PySideHelpers.cmake b/sources/pyside6/cmake/PySideHelpers.cmake
new file mode 100644
index 000000000..01c438107
--- /dev/null
+++ b/sources/pyside6/cmake/PySideHelpers.cmake
@@ -0,0 +1,275 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+function(pyside_internal_detect_if_cross_building)
+ if(CMAKE_CROSSCOMPILING OR QFP_SHIBOKEN_HOST_PATH)
+ set(is_cross_build TRUE)
+ else()
+ set(is_cross_build FALSE)
+ endif()
+ set(PYSIDE_IS_CROSS_BUILD "${is_cross_build}" PARENT_SCOPE)
+ message(STATUS "PYSIDE_IS_CROSS_BUILD: ${PYSIDE_IS_CROSS_BUILD}")
+endfunction()
+
+function(pyside_internal_set_up_extra_dependency_paths)
+ set(extra_root_path_vars
+ QFP_QT_TARGET_PATH
+ QFP_PYTHON_TARGET_PATH
+ QFP_SHIBOKEN_TARGET_PATH
+ )
+ foreach(root_path IN LISTS extra_root_path_vars)
+ set(new_root_path_value "${${root_path}}")
+ if(new_root_path_value)
+ set(new_prefix_path "${CMAKE_PREFIX_PATH}")
+ list(PREPEND new_prefix_path "${new_root_path_value}/lib/cmake")
+ set(CMAKE_PREFIX_PATH "${new_prefix_path}")
+ set(CMAKE_PREFIX_PATH "${new_prefix_path}" PARENT_SCOPE)
+
+ # Need to adjust the prefix and root paths so that find_package(Qt) and other 3rd
+ # party packages are found successfully when they are located outside of the
+ # default sysroot (whatever that maybe for the target platform).
+ if(PYSIDE_IS_CROSS_BUILD)
+ set(new_root_path "${CMAKE_FIND_ROOT_PATH}")
+ list(PREPEND new_root_path "${new_root_path_value}")
+ set(CMAKE_FIND_ROOT_PATH "${new_root_path}")
+ set(CMAKE_FIND_ROOT_PATH "${new_root_path}" PARENT_SCOPE)
+ endif()
+ endif()
+ endforeach()
+endfunction()
+
+function(pyside_internal_find_host_shiboken_tools)
+ set(find_package_extra_args)
+ if(QFP_SHIBOKEN_HOST_PATH)
+ list(APPEND find_package_extra_args PATHS "${QFP_SHIBOKEN_HOST_PATH}/lib/cmake")
+ list(PREPEND CMAKE_FIND_ROOT_PATH "${QFP_SHIBOKEN_HOST_PATH}")
+ endif()
+
+ # When doing a regular build, immediately mark the package as required.
+ if(NOT PYSIDE_IS_CROSS_BUILD)
+ list(APPEND "REQUIRED")
+ endif()
+
+ find_package(
+ Shiboken6Tools 6 CONFIG
+ ${find_package_extra_args}
+ )
+
+ # When cross building, we show a more helpful error message that
+ # QFP_SHIBOKEN_HOST_PATH should be provided instead of CMAKE_PREFIX_PATH (specifically
+ # for the host tools package).
+ if(PYSIDE_IS_CROSS_BUILD)
+ if(NOT Shiboken6Tools_DIR)
+ message(FATAL_ERROR
+ "Shiboken6Tools package was not found. "
+ "Please set QFP_SHIBOKEN_HOST_PATH to the location where the Shiboken6Tools "
+ "CMake package is installed.")
+ endif()
+ endif()
+endfunction()
+
+macro(collect_essential_modules)
+ # Collect all essential modules.
+ # note: the order of this list is relevant for dependencies.
+ # For instance: Qt5Printsupport must come before Qt5WebKitWidgets.
+ set(ALL_ESSENTIAL_MODULES
+ Core
+ Gui
+ Widgets
+ PrintSupport
+ Sql
+ Network
+ Test
+ Concurrent)
+endmacro()
+
+macro(collect_optional_modules)
+ # Collect all optional modules.
+ set(ALL_OPTIONAL_MODULES
+ DBus
+ Designer
+ Xml
+ Help Multimedia
+ MultimediaWidgets
+ OpenGL
+ OpenGLWidgets
+ Pdf
+ PdfWidgets
+ Positioning
+ Location
+ NetworkAuth
+ Nfc
+ Qml
+ Quick
+ Quick3D
+ QuickControls2
+ QuickTest
+ QuickWidgets
+ RemoteObjects
+ Scxml
+ Sensors
+ SerialPort
+ SerialBus
+ StateMachine
+ TextToSpeech
+ Charts
+ SpatialAudio
+ Svg
+ SvgWidgets
+ DataVisualization
+ Graphs
+ Bluetooth)
+ find_package(Qt${QT_MAJOR_VERSION}UiTools)
+ if(Qt${QT_MAJOR_VERSION}UiTools_FOUND)
+ list(APPEND ALL_OPTIONAL_MODULES UiTools)
+ else()
+ set(DISABLE_QtUiTools 1)
+ endif()
+ if(WIN32)
+ list(APPEND ALL_OPTIONAL_MODULES AxContainer)
+ endif()
+ list(APPEND ALL_OPTIONAL_MODULES WebChannel WebEngineCore WebEngineWidgets
+ WebEngineQuick WebSockets HttpServer)
+ list(APPEND ALL_OPTIONAL_MODULES 3DCore 3DRender 3DInput 3DLogic 3DAnimation 3DExtras)
+endmacro()
+
+macro(check_os)
+ set(ENABLE_UNIX "1")
+ set(ENABLE_MAC "0")
+ set(ENABLE_WIN "0")
+
+ # check if Android, if so, set ENABLE_UNIX=1
+ # this is needed to avoid including the wrapper specific to macOS when building for Android
+ # from a macOS host
+ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
+ if(CMAKE_HOST_APPLE)
+ set(ENABLE_MAC "1")
+ elseif(CMAKE_HOST_WIN32)
+ set(ENABLE_WIN "1")
+ set(ENABLE_UNIX "0")
+ elseif(NOT CMAKE_HOST_UNIX)
+ message(FATAL_ERROR "OS not supported")
+ endif()
+ endif()
+endmacro()
+
+macro(use_protected_as_public_hack)
+ # 2017-04-24 The protected hack can unfortunately not be disabled, because
+ # Clang does produce linker errors when we disable the hack.
+ # But the ugly workaround in Python is replaced by a shiboken change.
+ if(WIN32 OR DEFINED AVOID_PROTECTED_HACK)
+ message(STATUS "PySide6 will be generated avoiding the protected hack!")
+ set(GENERATOR_EXTRA_FLAGS ${GENERATOR_EXTRA_FLAGS} --avoid-protected-hack)
+ add_definitions(-DAVOID_PROTECTED_HACK)
+ else()
+ message(STATUS "PySide will be generated using the protected hack!")
+ endif()
+endmacro()
+
+macro(remove_skipped_modules)
+ # Removing from the MODULES list the items that were defined with
+ # -DSKIP_MODULES on command line
+ if(SKIP_MODULES)
+ foreach(s ${SKIP_MODULES})
+ list(REMOVE_ITEM MODULES ${s})
+ endforeach()
+ endif()
+
+ foreach(m ${MODULES})
+ collect_module_if_found(${m})
+ list(FIND all_module_shortnames ${m} is_module_collected)
+ # If the module was collected, remove it from disabled modules list.
+ if (NOT is_module_collected EQUAL -1)
+ list(REMOVE_ITEM DISABLED_MODULES ${m})
+ endif()
+ endforeach()
+endmacro()
+
+macro(collect_module_if_found shortname)
+ set(name "Qt${QT_MAJOR_VERSION}${shortname}")
+ set(_qt_module_name "${name}")
+ if ("${shortname}" STREQUAL "OpenGLFunctions")
+ set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui")
+ endif()
+ # Determine essential/optional/missing
+ set(module_state "missing")
+ list(FIND ALL_ESSENTIAL_MODULES "${shortname}" essentialIndex)
+ if(${essentialIndex} EQUAL -1)
+ list(FIND ALL_OPTIONAL_MODULES "${shortname}" optionalIndex)
+ if(NOT ${optionalIndex} EQUAL -1)
+ set(module_state "optional")
+ endif()
+ else()
+ set(module_state "essential")
+ endif()
+
+ # Silence warnings when optional packages are not found when doing a quiet build.
+ set(quiet_argument "")
+ if (QUIET_BUILD AND "${module_state}" STREQUAL "optional")
+ set(quiet_argument "QUIET")
+ endif()
+
+ find_package(${_qt_module_name} ${quiet_argument})
+ # If package is found, _name_found will be equal to 1
+ set(_name_found "${_qt_module_name}_FOUND")
+ # _name_dir will keep the path to the directory where the CMake rules were found
+ # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Core or /usr/lib64/cmake/Qt5Core
+ set(_name_dir "${_qt_module_name}_DIR")
+ # Qt5Core will set the base path to check if all the modules are on the same
+ # directory, to avoid CMake looking in another path.
+ # This will be saved in a global variable at the beginning of the modules
+ # collection process.
+ string(FIND "${name}" "Qt${QT_MAJOR_VERSION}Core" qtcore_found)
+ if(("${qtcore_found}" GREATER "0") OR ("${qtcore_found}" EQUAL "0"))
+ get_filename_component(_core_abs_dir "${${_name_dir}}/../" ABSOLUTE)
+ # Setting the absolute path where the Qt5Core was found
+ # e.g: ~/qt5.9-install/qtbase/lib/cmake or /usr/lib64/cmake
+ message(STATUS "CORE_ABS_DIR:" ${_core_abs_dir})
+ endif()
+
+ # Getting the absolute path for each module where the CMake was found, to
+ # compare it with CORE_ABS_DIR and check if they are in the same source directory
+ # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Script or /usr/lib64/cmake/Qt5Script
+ get_filename_component(_module_dir "${${_name_dir}}" ABSOLUTE)
+ string(FIND "${_module_dir}" "${_core_abs_dir}" found_basepath)
+
+ # If the module was found, and also the module path is the same as the
+ # Qt5Core base path, we will generate the list with the modules to be installed
+ set(looked_in_message ". Looked in: ${${_name_dir}}")
+ if("${${_name_found}}" AND (("${found_basepath}" GREATER "0") OR ("${found_basepath}" EQUAL "0")))
+ message(STATUS "${module_state} module ${name} found (${ARGN})${looked_in_message}")
+ # record the shortnames for the tests
+ list(APPEND all_module_shortnames ${shortname})
+ # Build Qt 5 compatibility variables
+ if(${QT_MAJOR_VERSION} GREATER_EQUAL 6 AND NOT "${shortname}" STREQUAL "OpenGLFunctions")
+ get_target_property(Qt6${shortname}_INCLUDE_DIRS Qt6::${shortname}
+ INTERFACE_INCLUDE_DIRECTORIES)
+ get_target_property(Qt6${shortname}_PRIVATE_INCLUDE_DIRS
+ Qt6::${shortname}Private
+ INTERFACE_INCLUDE_DIRECTORIES)
+ set(Qt6${shortname}_LIBRARIES Qt::${shortname})
+ endif()
+ else()
+ if("${module_state}" STREQUAL "optional")
+ message(STATUS "optional module ${name} skipped${looked_in_message}")
+ elseif("${module_state}" STREQUAL "essential")
+ message(STATUS "skipped module ${name} is essential!\n"
+ " We do not guarantee that all tests are working.${looked_in_message}")
+ else()
+ message(FATAL_ERROR "module ${name} MISSING${looked_in_message}")
+ endif()
+ endif()
+endmacro()
+
+# resets the RELEASE CXX flags for size based optimization
+macro(override_release_flags_for_size_optimization)
+ if(NOT QFP_NO_OVERRIDE_OPTIMIZATION_FLAGS)
+ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+ set(CMAKE_CXX_FLAGS_RELEASE "/O1 /DNDEBUG")
+ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG")
+ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set(CMAKE_CXX_FLAGS_RELEASE "-Oz -DNDEBUG")
+ endif()
+ endif()
+endmacro()
diff --git a/sources/pyside6/cmake/PySideSetup.cmake b/sources/pyside6/cmake/PySideSetup.cmake
new file mode 100644
index 000000000..038dc1642
--- /dev/null
+++ b/sources/pyside6/cmake/PySideSetup.cmake
@@ -0,0 +1,243 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Don't ignore targets that do not exist, inside add_dependencies calls.
+cmake_policy(SET CMP0046 NEW)
+
+set(QT_MAJOR_VERSION 6)
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../shiboken6/cmake")
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Macros")
+
+# TODO: Don't directly include, ShibokenHelpers but rather pick it up from the installed Shiboken
+# package. Needs to support top-level build as well (Shiboken is not yet installed in that case).
+include(ShibokenHelpers)
+include(PySideHelpers)
+
+#does nothing if QFP_NO_OVERRIDE_OPTIMIZATION_FLAGS (no-size-optimization) flag is not set
+override_release_flags_for_size_optimization()
+
+# Don't display "up-to-date / install" messages when installing, to reduce visual clutter.
+if(QUIET_BUILD)
+ set(CMAKE_INSTALL_MESSAGE NEVER)
+endif()
+
+# Override message not to display info messages when doing a quiet build.
+if(QUIET_BUILD AND is_pyside6_superproject_build)
+ function(message)
+ list(GET ARGV 0 MessageType)
+ if(MessageType STREQUAL FATAL_ERROR OR
+ MessageType STREQUAL SEND_ERROR OR
+ MessageType STREQUAL WARNING OR
+ MessageType STREQUAL AUTHOR_WARNING)
+ list(REMOVE_AT ARGV 0)
+ _message(${MessageType} "${ARGV}")
+ endif()
+ endfunction()
+endif()
+
+
+pyside_internal_detect_if_cross_building()
+pyside_internal_set_up_extra_dependency_paths()
+pyside_internal_find_host_shiboken_tools()
+find_package(Shiboken6 6 CONFIG REQUIRED)
+
+if(is_pyside6_superproject_build)
+ shiboken_find_required_python()
+endif()
+
+set(BINDING_API_MAJOR_VERSION "${pyside_MAJOR_VERSION}")
+set(BINDING_API_MINOR_VERSION "${pyside_MINOR_VERSION}")
+set(BINDING_API_MICRO_VERSION "${pyside_MICRO_VERSION}")
+set(BINDING_API_PRE_RELEASE_VERSION_TYPE "${pyside_PRE_RELEASE_VERSION_TYPE}")
+set(BINDING_API_PRE_RELEASE_VERSION "${pyside_PRE_RELEASE_VERSION}")
+
+# Detect if the Python interpreter is actually PyPy
+execute_process(
+ COMMAND ${Python_EXECUTABLE} -c "if True:
+ pypy_version = ''
+ import sys
+ if hasattr(sys, 'pypy_version_info'):
+ pypy_version = '.'.join(map(str, sys.pypy_version_info[:3]))
+ print(pypy_version)
+ "
+ OUTPUT_VARIABLE PYPY_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if(WIN32)
+ set(PATH_SEP "\;")
+else()
+ set(PATH_SEP ":")
+endif()
+
+if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "${SHIBOKEN_BUILD_TYPE}" CACHE STRING "Build Type")
+endif()
+
+if(CMAKE_BUILD_TYPE STREQUAL "Release")
+ add_definitions("-DNDEBUG")
+endif()
+
+if(SHIBOKEN_PYTHON_LIMITED_API)
+ message(STATUS "******************************************************")
+ message(STATUS "** PySide6 Limited API enabled.")
+ message(STATUS "******************************************************")
+endif()
+
+# Need to ensure host Tools packages are found instead of target ones when cross-compiling.
+if(QFP_QT_HOST_PATH)
+ get_filename_component(__qt_host_path_absolute "${QFP_QT_HOST_PATH}" ABSOLUTE)
+ if(EXISTS "${__qt_host_path_absolute}")
+ set(QT_HOST_PATH "${__qt_host_path_absolute}")
+
+ set(__qt_candidate_host_path_cmake_dir "${QT_HOST_PATH}/lib/cmake")
+ if(EXISTS "${__qt_candidate_host_path_cmake_dir}")
+ set(QT_HOST_PATH_CMAKE_DIR "${__qt_candidate_host_path_cmake_dir}")
+ endif()
+ endif()
+endif()
+find_package(Qt6 REQUIRED COMPONENTS Core)
+
+add_definitions(${Qt${QT_MAJOR_VERSION}Core_DEFINITIONS})
+
+option(BUILD_TESTS "Build tests." TRUE)
+option(ENABLE_VERSION_SUFFIX "Used to use current version in suffix to generated files. This is used to allow multiples versions installed simultaneous." FALSE)
+set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
+set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
+if(CMAKE_HOST_APPLE)
+ set(ALTERNATIVE_QT_INCLUDE_DIR "" CACHE PATH "Deprecated. CMake now finds the proper include dir itself.")
+ set(OSX_USE_LIBCPP "OFF" CACHE BOOL "Explicitly link the libc++ standard library (useful for macOS deployment targets lower than 10.9.")
+ if(OSX_USE_LIBCPP)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+ endif()
+endif()
+
+# Force usage of the C++17 standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+# Obtain QT_INCLUDE_DIR from INTERFACE_INCLUDE_DIRECTORIES which returns a list
+# ../install-qt-6/include/QtCore;../install-qt-6/include
+set(QT_INCLUDE_DIR "")
+get_target_property(QT_INCLUDE_DIR_LIST Qt6::Core INTERFACE_INCLUDE_DIRECTORIES)
+foreach(_Q ${QT_INCLUDE_DIR_LIST})
+ if(NOT "${_Q}" MATCHES "QtCore$")
+ set(QT_INCLUDE_DIR "${_Q}")
+ endif()
+endforeach()
+if(QT_INCLUDE_DIR STREQUAL "")
+ message(FATAL_ERROR "Unable to obtain the Qt include directory")
+endif()
+
+# On macOS, check if Qt is a framework build. This affects how include paths should be handled.
+get_target_property(QtCore_is_framework Qt${QT_MAJOR_VERSION}::Core FRAMEWORK)
+
+if(QtCore_is_framework)
+ # Get the path to the framework dir.
+ set(QT_FRAMEWORK_INCLUDE_DIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBS}")
+ message(STATUS "*** QT_FRAMEWORK_INCLUDE_DIR is ${QT_FRAMEWORK_INCLUDE_DIR}")
+ set(QT_INCLUDE_DIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_HEADERS}")
+endif()
+
+set_cmake_cxx_flags()
+
+message(STATUS "*** computed QT_INCLUDE_DIR as ${QT_INCLUDE_DIR}")
+
+set(BINDING_NAME PySide6)
+
+set(BINDING_API_VERSION "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}" CACHE STRING "PySide6 version" FORCE)
+set(PYSIDE_SO_VERSION ${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION})
+if(BINDING_API_PRE_RELEASE_VERSION_TYPE STREQUAL "")
+ set(BINDING_API_VERSION_FULL "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}"
+ CACHE STRING "PySide6 version [full]" FORCE)
+else()
+ set(BINDING_API_VERSION_FULL "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}~${BINDING_API_PRE_RELEASE_VERSION_TYPE}${BINDING_API_PRE_RELEASE_VERSION}"
+ CACHE STRING "PySide6 version [full]" FORCE)
+endif()
+
+compute_config_py_values(BINDING_API_VERSION)
+
+include(PySideModules)
+
+# Set default values for pyside6_global.h
+set (Qt${QT_MAJOR_VERSION}Test_FOUND "0")
+set (Qt${QT_MAJOR_VERSION}Widgets_FOUND "0")
+
+collect_essential_modules()
+collect_optional_modules()
+
+# Modules to be built unless specified by -DMODULES on command line
+if(NOT MODULES)
+ set(MODULES "${ALL_ESSENTIAL_MODULES};${ALL_OPTIONAL_MODULES}")
+endif()
+
+# This will contain the set of modules for which bindings are not built.
+set(DISABLED_MODULES "${ALL_ESSENTIAL_MODULES};${ALL_OPTIONAL_MODULES}")
+
+remove_skipped_modules()
+
+# Mark all non-collected modules as disabled. This is used for disabling tests
+# that depend on the disabled modules.
+foreach(m ${DISABLED_MODULES})
+ set(DISABLE_Qt${m} 1)
+endforeach()
+
+# Whether to add libpysideqml
+find_package(Qt6 COMPONENTS Qml)
+
+string(REGEX MATCHALL "[0-9]+" qt_version_helper "${Qt${QT_MAJOR_VERSION}Core_VERSION}")
+
+list(GET qt_version_helper 0 QT_VERSION_MAJOR)
+list(GET qt_version_helper 1 QT_VERSION_MINOR)
+list(GET qt_version_helper 2 QT_VERSION_PATCH)
+unset(qt_version_helper)
+
+set(PYSIDE_QT_VERSION "${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}" CACHE STRING "Qt version used to compile PySide" FORCE)
+if(ENABLE_VERSION_SUFFIX)
+ set(pyside_SUFFIX "-${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}")
+endif()
+
+# no more supported: include(${QT_USE_FILE})
+
+# Configure OS support
+check_os()
+
+# Define supported Qt Version
+set(SUPPORTED_QT_VERSION "${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}")
+
+
+# uninstall target
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+
+# When opening super project, prevent redefinition of uninstall target.
+if(NOT TARGET uninstall)
+ add_custom_target(uninstall "${CMAKE_COMMAND}"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+endif()
+
+if(NOT PYTHON_SITE_PACKAGES)
+ shiboken_internal_set_python_site_packages()
+endif()
+
+shiboken_get_debug_level(debug_level)
+
+set(GENERATOR_EXTRA_FLAGS
+ ${SHIBOKEN_GENERATOR_EXTRA_FLAGS}
+ ${debug_level}
+ --generator-set=shiboken
+ --enable-parent-ctor-heuristic
+ --enable-pyside-extensions
+ --enable-return-value-heuristic
+ --use-isnull-as-nb-bool)
+use_protected_as_public_hack()
+
+# Build with Address sanitizer enabled if requested. This may break things, so use at your own risk.
+if(SANITIZE_ADDRESS AND NOT MSVC)
+ setup_sanitize_address()
+endif()
+
+find_package(Qt6 COMPONENTS Designer)
+
diff --git a/sources/pyside6/cmake_uninstall.cmake b/sources/pyside6/cmake_uninstall.cmake
new file mode 100644
index 000000000..4031b4e1a
--- /dev/null
+++ b/sources/pyside6/cmake_uninstall.cmake
@@ -0,0 +1,24 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+STRING(REGEX REPLACE "\n" ";" files "${files}")
+FOREACH(file ${files})
+ MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
+ IF(EXISTS "$ENV{DESTDIR}${file}")
+ EXEC_PROGRAM(
+ "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ IF(NOT "${rm_retval}" STREQUAL 0)
+ MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
+ ENDIF(NOT "${rm_retval}" STREQUAL 0)
+ ELSE(EXISTS "$ENV{DESTDIR}${file}")
+ MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
+ ENDIF(EXISTS "$ENV{DESTDIR}${file}")
+ENDFOREACH(file)
diff --git a/sources/pyside6/doc/CMakeLists.txt b/sources/pyside6/doc/CMakeLists.txt
new file mode 100644
index 000000000..83583756f
--- /dev/null
+++ b/sources/pyside6/doc/CMakeLists.txt
@@ -0,0 +1,294 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+cmake_policy(VERSION 3.18)
+
+project(doc)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../shiboken6/cmake")
+include(FindDocTools)
+
+# When the doc project is built as part of the pyside project, we show informational message
+# and return early if requirements are not met.
+if(NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
+ if(QT_SRC_DIR AND SPHINX_BUILD AND DOT_EXEC AND BUILD_DOCS)
+ # All requirements met, proceed.
+ else()
+ set(reasons "")
+ if(NOT QT_SRC_DIR)
+ list(APPEND reasons " QT_SRC_DIR variable not set\n")
+ endif()
+ if(NOT SPHINX_BUILD)
+ list(APPEND reasons " sphinx-build command not found\n")
+ endif()
+ if(NOT DOT_EXEC)
+ list(APPEND reasons " graphviz not found\n")
+ endif()
+ if(NOT BUILD_DOCS)
+ list(APPEND reasons " BUILD_DOCS was set to FALSE (default)\n")
+ endif()
+ message(STATUS "apidoc generation targets disabled due to the following reasons:\n"
+ ${reasons})
+ return()
+ endif()
+else()
+ # We are building the docs as a standalone project, likely via setup.py build_base_docs
+ # command. Perform stricter sanity checks.
+ if(NOT SPHINX_BUILD)
+ message(FATAL_ERROR "sphinx-build command not found. Please set the SPHINX_BUILD variable.")
+ endif()
+endif()
+
+# Generate html by default.
+if(NOT DOC_OUTPUT_FORMAT)
+ set(DOC_OUTPUT_FORMAT "html")
+endif()
+
+if (WIN32)
+ set(PATH_SEP "\;")
+else()
+ set(PATH_SEP ":")
+endif()
+
+set(DOC_DATA_DIR "${CMAKE_CURRENT_BINARY_DIR}/qdoc-output")
+# Directory for sphinx-generated files to build the HTML website. If changed,
+# update "build_scripts/main.py" in "PysideBaseDocs" class at line:
+# self.sphinx_src = self.out_dir / "base".
+set(DOC_BASE_DIR "base")
+
+set(ENV_INHERITANCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/inheritance.json")
+
+get_filename_component(ROOT ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+set(TS_ROOT "${ROOT}/PySide6")
+
+file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/pyside.qdocconf ${CMAKE_CURRENT_LIST_DIR}/pyside.qdocconf.in)
+
+# We need to find the interpreter when running this only
+# for the 'build_base_docs' case, and not a full doc build
+if (NOT FULLDOCSBUILD)
+ find_package(Python COMPONENTS Interpreter)
+endif()
+
+if (QT_SRC_DIR)
+ file(REAL_PATH ${QT_SRC_DIR}/.. QT_ROOT_PATH)
+else()
+ set(QT_ROOT_PATH "")
+endif()
+
+if(PYSIDE_IS_CROSS_BUILD)
+ set(python_executable "${QFP_PYTHON_HOST_PATH}")
+else()
+ set(python_executable "${Python_EXECUTABLE}")
+endif()
+
+set(TOOLS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../tools")
+
+if (FULLDOCSBUILD)
+ # Fetch and transform the snippets from Qt
+ set(SNIPPETS_TOOL "${TOOLS_DIR}/snippets_translate/main.py")
+ set(SNIPPETS_TARGET ${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/codesnippets)
+
+ # Note QT_SRC_DIR points to 'qtbase',
+ # so we use the general SRC directory to copy all the other snippets
+ add_custom_target("snippets_translate" DEPENDS "${SNIPPETS_TARGET}")
+ add_custom_command(OUTPUT "${SNIPPETS_TARGET}"
+ COMMAND ${python_executable} ${SNIPPETS_TOOL}
+ --qt ${QT_ROOT_PATH} --target ${SNIPPETS_TARGET} -w
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ COMMENT "Fetching and converting snippets...")
+endif()
+
+# Generate example gallery
+set(EXAMPLE_TOOL_TARGET "${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/examples")
+set(EXAMPLE_TOOL_OPTIONS --target "${EXAMPLE_TOOL_TARGET}" --qt-src-dir "${QT_SRC_DIR}")
+if (QUIET_BUILD)
+ list(APPEND EXAMPLE_TOOL_OPTIONS "-q")
+endif()
+set(EXAMPLE_TOOL_DIR "${TOOLS_DIR}/example_gallery/main.py")
+
+add_custom_target("example_gallery" DEPENDS "${EXAMPLE_TOOL_TARGET}")
+add_custom_command(OUTPUT "${EXAMPLE_TOOL_TARGET}"
+ COMMAND ${python_executable} ${EXAMPLE_TOOL_DIR} ${EXAMPLE_TOOL_OPTIONS}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ COMMENT "Generating example gallery...")
+
+set(SHIBOKEN_INTERSPHINX_FILE "${ROOT}/pyside6/shiboken6/objects.inv")
+set(HAS_WEBENGINE_WIDGETS 0)
+set(SKIP_SPHINX_WARNINGS 1)
+if (FULLDOCSBUILD)
+ set(SKIP_SPHINX_WARNINGS 0)
+ set(SHIBOKEN_INTERSPHINX_FILE "${CMAKE_BINARY_DIR}/doc/html/shiboken6/doc/html/objects.inv")
+ # For Qt modules that are part of the documentation build:
+ # - Configure the module docconf file
+ # - Write shiboken header consisting of pyside6_global.h and module includes
+ # - Build include path for qdoc for shiboken
+
+ # The last element of the include list is the mkspec directory containing qplatformdefs.h
+ list(GET Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS -1 mkspecInclude)
+ set(config_docconf "${CMAKE_CURRENT_LIST_DIR}/pyside-config.qdocconf")
+ configure_file("pyside-config.qdocconf.in" "${config_docconf}" @ONLY)
+
+ set(global_header "${pyside6_BINARY_DIR}/qdoc.h")
+ file(READ "${pyside6_BINARY_DIR}/pyside6_global.h" docHeaderContents)
+ file(WRITE ${global_header} "${docHeaderContents}")
+
+ set(global_typesystem "${CMAKE_CURRENT_BINARY_DIR}/typesystem_doc.xml")
+ file(READ "typesystem_doc.xml.in" typeSystemDocXmlContents)
+ file(WRITE ${global_typesystem} "${typeSystemDocXmlContents}")
+
+ execute_process(
+ COMMAND ${Python_EXECUTABLE} "${TOOLS_DIR}/doc_modules.py"
+ -t "${global_typesystem}" -g "${global_header}" -d "${config_docconf}"
+ "${QT_INCLUDE_DIR}" "${SUPPORTED_QT_VERSION}"
+ OUTPUT_VARIABLE ALL_DOC_MODULES
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ separate_arguments (ALL_DOC_MODULES UNIX_COMMAND "${ALL_DOC_MODULES}")
+
+ foreach(moduleIn ${ALL_DOC_MODULES})
+ string(TOLOWER "${moduleIn}" lowerModuleIn)
+ set(docConf "${CMAKE_CURRENT_LIST_DIR}/qtmodules/pyside-qt${lowerModuleIn}.qdocconf.in")
+ if(EXISTS "${docConf}")
+ string(REGEX REPLACE "(^.*)\.in" "\\1" OUTFILE ${docConf})
+ get_filename_component(BASENAME ${OUTFILE} NAME)
+ configure_file(${docConf} "${CMAKE_CURRENT_LIST_DIR}/qtmodules/${BASENAME}" @ONLY)
+ file(APPEND "pyside.qdocconf.in" "\@CMAKE_CURRENT_LIST_DIR\@/qtmodules/${BASENAME}\n")
+ endif()
+ endforeach()
+
+ # There is no binding for the qtdoc repository, but it has some relevant documents.
+ set(qtdoc_doc_conf "qtmodules/pyside-qtdoc.qdocconf")
+ configure_file("${qtdoc_doc_conf}.in" "${CMAKE_CURRENT_LIST_DIR}/${qtdoc_doc_conf}" @ONLY)
+ file(APPEND "pyside.qdocconf.in" "\@CMAKE_CURRENT_LIST_DIR\@/${qtdoc_doc_conf}\n")
+
+ configure_file("pyside.qdocconf.in" "pyside.qdocconf" @ONLY)
+ configure_file("qdoc_spawner.py.in" "qdoc_spawner.py" @ONLY)
+
+
+ set(QDOC_TYPESYSTEM_PATH "${pyside6_SOURCE_DIR}${PATH_SEP}${pyside6_BINARY_DIR}")
+
+ if(NOT qdoc_binary)
+ message(FATAL_ERROR
+ "No qdoc binary was found which full documentation generation requires. "
+ "Please either add qdoc to PATH or specify the QDOC_EXECUTABLE variable."
+ )
+ endif()
+
+ add_custom_target(qdoc DEPENDS "${DOC_DATA_DIR}/webxml/qtcore-index.webxml")
+
+ add_custom_command(OUTPUT "${DOC_DATA_DIR}/webxml/qtcore-index.webxml"
+ Use dummy Qt version information, QDoc needs it but has no effect on WebXML output
+ COMMAND ${CMAKE_COMMAND} -E env ${python_executable} qdoc_spawner.py
+ --qt=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}
+ --doc-data-dir=${DOC_DATA_DIR}
+ --qdoc-binary=${qdoc_binary}
+ --build-dir=${CMAKE_CURRENT_LIST_DIR}/src
+ --qt-install-docs=${QT_SRC_DIR}/doc
+ --parallel="auto"
+ --verbose
+ COMMENT "Running qdoc against Qt source code...")
+endif()
+
+# Avoid using 'auto' for '-j' option as it could lead to
+# crash on some systems due to out-of-memory situation. Instead
+# use a no. less than 8.
+add_custom_target(apidoc
+ COMMAND ${CMAKE_COMMAND} -E env INHERITANCE_FILE=${ENV_INHERITANCE_FILE}
+ ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b ${DOC_OUTPUT_FORMAT}
+ -j 6 ${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR} html
+ COMMENT "Generating PySide htmls..."
+ )
+
+# create a custom commands to copy the shiboken docs
+# and generate offline help based on the output format.
+if(DOC_OUTPUT_FORMAT STREQUAL "html")
+ add_custom_command(TARGET apidoc POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken6
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken6/doc/html
+ ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken6
+ COMMENT "Copying Shiboken docs..."
+ DEPENDS "${DOC_DATA_DIR}/webxml/qtcore-index.webxml"
+ VERBATIM)
+else()
+ if(qhelpgenerator_binary)
+ message(STATUS "qhelpgenerator - found")
+ # Python script that will be called to update the QHP
+ set(PATCH_QHP_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/../../shiboken6/doc/scripts/patch_qhp.py")
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/PySide.qhp QHP_FILE)
+ add_custom_command(TARGET apidoc POST_BUILD
+ COMMAND ${python_executable} ${PATCH_QHP_SCRIPT} -p -v pyside6 ${QHP_FILE}
+ COMMAND "${qhelpgenerator_binary}" ${QHP_FILE}
+ COMMENT "Generating QCH from a QHP file..."
+ DEPENDS "${DOC_DATA_DIR}/webxml/qtcore-index.webxml"
+ VERBATIM
+ )
+ else()
+ message(WARNING "qhelpgenerator - not found! qch generation disabled")
+ endif()
+endif()
+
+# create conf.py based on conf.py.in
+configure_file("conf.py.in" "${DOC_BASE_DIR}/conf.py" @ONLY)
+
+set(CODE_SNIPPET_ROOT "${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/codesnippets")
+
+if (FULLDOCSBUILD)
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/PySide6/QtCore/index.rst"
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --generator-set=qtdoc
+ ${global_header}
+ --enable-pyside-extensions
+ --include-paths="${QT_INCLUDE_DIR}${PATH_SEP}${pyside6_SOURCE_DIR}${PATH_SEP}${TS_ROOT}"
+ --api-version=${SUPPORTED_QT_VERSION}
+ --typesystem-paths="${QDOC_TYPESYSTEM_PATH}"
+ --library-source-dir=${QT_SRC_DIR}
+ --documentation-data-dir=${DOC_DATA_DIR}/webxml
+ --output-directory=${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}
+ --documentation-code-snippets-dir=${CODE_SNIPPET_ROOT}
+ --snippets-path-rewrite=${QT_ROOT_PATH}:${CODE_SNIPPET_ROOT}
+ --documentation-extra-sections-dir=${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/extras
+ --additional-documentation=${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/additionaldocs.lst
+ --inheritance-file=${ENV_INHERITANCE_FILE}
+ ${global_typesystem}
+ WORKING_DIRECTORY ${${module}_SOURCE_DIR}
+ COMMENT "Running generator to generate documentation...")
+endif()
+
+add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/extras"
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}
+ COMMENT "Copying docs...")
+
+add_custom_target("doc_copy"
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/extras")
+
+add_custom_target("docrsts"
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/PySide6/QtCore/index.rst")
+
+set(LIBEXEC_PATH "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBEXECS}")
+add_custom_target("licensedocrsts"
+ COMMAND ${python_executable}
+ ${CMAKE_CURRENT_LIST_DIR}/qtattributionsscannertorst.py
+ -l "${LIBEXEC_PATH}"
+ ${CMAKE_CURRENT_LIST_DIR}/../../..
+ ${CMAKE_CURRENT_BINARY_DIR}/${DOC_BASE_DIR}/licenses.rst
+ COMMENT "Creating 3rdparty license documentation..."
+)
+
+add_dependencies(docrsts example_gallery)
+
+if (FULLDOCSBUILD)
+ add_dependencies(apidoc docrsts licensedocrsts)
+ add_dependencies(licensedocrsts docrsts)
+ add_dependencies(docrsts doc_copy qdoc snippets_translate)
+endif()
+
+#install files
+add_custom_target(apidocinstall
+ COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/share/doc/PySide6-${BINDING_API_VERSION} && cp -rv ${CMAKE_CURRENT_BINARY_DIR}/html/* ${CMAKE_INSTALL_PREFIX}/share/doc/PySide-${BINDING_API_VERSION}
+)
+
+add_dependencies(apidocinstall apidoc)
diff --git a/sources/pyside6/doc/PySide6/QtAsyncio/index.rst b/sources/pyside6/doc/PySide6/QtAsyncio/index.rst
new file mode 100644
index 000000000..326f6efcc
--- /dev/null
+++ b/sources/pyside6/doc/PySide6/QtAsyncio/index.rst
@@ -0,0 +1,150 @@
+.. module:: PySide6.QtAsyncio
+
+PySide6.QtAsyncio
+*****************
+
+.. note:: This module is currently in technical preview.
+
+The Qt Asyncio module is a pure Python module that allows programs to be
+written that use Qt's API in conjunction with `asyncio
+<https://docs.python.org/3/library/asyncio.html>`_. asyncio is a popular
+Python library for asynchronous programming. It is used in particular
+for programs that need to handle many I/O operations from many sources,
+such as web servers. More generally, it allows developers to work with
+`couroutines <https://docs.python.org/3/library/asyncio-task.html#coroutine>`_.
+Coroutines can be imagined as "asynchronous functions". In contrast to
+Qt's signals and slot mechanism, this allows for asynchronous programs
+that are closer in program flow to synchronous programs, as programs no
+longer have to be imagined as a series of callbacks. Instead, coroutines
+transparently resume and yield at designated spots.
+
+Consider the following simple coroutine defined with the ``async``
+keyword in front of its definition:
+
+::
+
+ async def do_something():
+ result = await do_something_asynchronously()
+ print(result)
+
+``do_something_asynchronously()`` is a coroutine itself, e.g., an
+I/O-heavy operation that would normally block the execution flow in a
+synchronous program. Instead, the ``await`` keyword is used to wait for
+the result, at which point ``do_something()`` yields and the program
+flow transparently switches to the next asynchronous task. When the
+result becomes available, the program flow is able to switch back to the
+``do_something()`` coroutine, which then resumes and prints the result.
+
+The asyncio API
+^^^^^^^^^^^^^^^
+
+asyncio and Qt are both based on an event loop. asyncio provides an API
+to replace its default event loop with a custom implementation.
+**QtAsyncio** provides such an implementation that uses Qt's event loop,
+allowing Qt and asyncio to be used together.
+
+We consider that this API consists of two levels:
+
+1. Fundamental infrastructure for event loops and asynchronous
+ operations, including `futures
+ <https://docs.python.org/3/library/asyncio-future.html#asyncio.Future>`_,
+ `tasks <https://docs.python.org/3/library/asyncio-task.html#asyncio.Task>`_,
+ `handles <https://docs.python.org/3/library/asyncio-eventloop.html#callback-handles>`_,
+ executors, and event loop management functions (see below).
+2. A user-facing API for use in applications, including transports and
+ protocols, network connections, servers, sockets, signals,
+ subprocesses.
+
+**QtAsyncio** currently covers the first level. This includes the
+following functions, for which the API is identical with QtAsyncio as
+with asyncio:
+
+* `run_until_complete() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_until_complete>`_
+* `run_forever() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_forever>`_
+* `stop() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.stop>`_
+* `is_running() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.is_running>`_
+* `is_closed() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.is_closed>`_
+* `close() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.close>`_
+* `shutdown_asyncgens() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.shutdown_asyncgens>`_
+* `shutdown_default_executor() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.shutdown_default_executor>`_
+* `call_soon() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.call_soon>`_
+* `call_soon_threadsafe() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.call_soon_threadsafe>`_
+* `call_later() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.call_later>`_
+* `call_at() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.call_at>`_
+* `time() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.time>`_
+* `create_future() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.create_future>`_
+* `create_task() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.create_task>`_
+* `set_task_factory() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.set_task_factory>`_
+* `get_task_factory() <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.get_task_factory>`_
+
+Also included is the ability to
+`run synchronous code in an executor <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor>`_
+(``ThreadPoolExecutor``).
+
+Get started with QtAsyncio
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To write a program with **QtAsyncio**, first import the module, e.g.:
+
+::
+
+ import PySide6.QtAsyncio as QtAsyncio
+
+**QtAsyncio** provides a function ``run()`` that can be used to run a
+specific coroutine until it is complete, or to start the Qt & asyncio
+event loop plainly. The former case makes sense if the program flow
+starts with said coroutine, the latter case makes sense if a coroutine
+is enqueued later in the program flow, e.g., after pressing a button in
+the UI.
+
+::
+
+ QtAsyncio.run()
+
+(see the `asyncio "minimal" example <https://doc.qt.io/qtforpython-6/examples/example_async_minimal.html>`_
+for an instance of this usage) or
+
+::
+
+ QtAsyncio.run(my_coroutine())
+
+(see the `asyncio "Eratosthenes" example <https://doc.qt.io/qtforpython-6/examples/example_async_eratosthenes.html>`_)
+or
+
+::
+
+ QtAsyncio.run(my_coroutine(), keep_running=False)
+
+to run the coroutine and then stop the event loop upon its completion.
+This latter case behaves identically to ``asyncio.run(my_coroutine())``.
+
+An additional optional argument ``quit_qapp`` can be passed to ``run()``
+to configure whether the QCoreApplication at the core of QtAsyncio
+should be shut down when asyncio finishes. A special case where one
+would want to disable this is test suites that want to reuse a single
+QCoreApplication instance across all unit tests, which would fail if
+this instance is shut down every time. The default is ``True``.
+
+Note that this argument is orthogonal to the ``keep_running`` argument.
+``keep_running`` determines if **asyncio** should keep running after the
+coroutine has finished, while ``quit_qapp`` determines if the
+QCoreApplication should be shut down after asyncio has finished. It is
+possible for asyncio to finish while the QCoreApplication is kept alive.
+
+An argument ``handle_sigint`` determines whether QtAsyncio should handle
+SIGINT (Ctrl+C) and shut down the event loop when it is received. The
+default is ``False``. Set this to ``True`` if you want QtAsyncio to take
+care of handling SIGINT instead of your program.
+
+Coroutines explained
+^^^^^^^^^^^^^^^^^^^^
+
+Coroutines are functions that can be paused (yield) and resumed. Behind
+this simple concept lies a complex mechanism that is abstracted by the
+asynchronous framework. This talk presents a diagram that attempts to
+illustrate the flow of a coroutine from the moment it's provided to the
+async framework until it's completed.
+
+.. image:: https://img.youtube.com/vi/XuqdTvisqkQ/mqdefault.jpg
+ :alt: Asynchronous programming with asyncio and Qt
+ :target: https://www.youtube.com/watch?v=XuqdTvisqkQ
diff --git a/sources/pyside6/doc/_static/css/qt_font.css b/sources/pyside6/doc/_static/css/qt_font.css
new file mode 100644
index 000000000..ce39943ef
--- /dev/null
+++ b/sources/pyside6/doc/_static/css/qt_font.css
@@ -0,0 +1,15 @@
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ font-weight: 400;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium Web"),
+ local("TitilliumWeb-Regular"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
diff --git a/sources/pyside6/doc/_static/css/qt_style.css b/sources/pyside6/doc/_static/css/qt_style.css
new file mode 100644
index 000000000..08c4646c6
--- /dev/null
+++ b/sources/pyside6/doc/_static/css/qt_style.css
@@ -0,0 +1,100 @@
+.text-center {
+ text-align: center !important;
+}
+
+.text-center img {
+ padding-top: 10px;
+ height: 70px !important;
+}
+
+.cover-img img {
+ object-fit: cover;
+ height: 50%;
+}
+
+/* Tables */
+.section .docutils.container td {
+ float:left;
+}
+
+table.docutils {
+ margin-right: auto;
+ margin-bottom: 10px;
+ border: none;
+ width: initial;
+ font-size: 0.8em;
+}
+
+table.docutils.colwidths-given td {
+ float: none;
+}
+
+table.docutils th,
+table.docutils td {
+ padding-left:0;
+ border: none;
+}
+
+table.docutils td ul {
+ margin:0
+}
+
+table.docutils td ul > li {
+ margin: 0 0 0.5em;
+}
+
+.hide {
+ display: none;
+}
+
+.fixed .container {
+ max-width:1280px;
+ margin:0 auto;
+ padding:0 3.9%; /* 0? */
+ position:relative;
+ overflow:visible
+}
+
+/* We cannot put a :download:`....` command inside
+ * a sphinx-design button, so we add some properties from the button
+ * to the download class to mimic it */
+code.download {
+ text-align: center;
+ color: var(--color-brand-primary);
+ display: block;
+ border-color: transparent;
+ background-color: transparent;
+ border: 1px solid var(--color-brand-primary) !important;
+ border-radius: 0.25rem;
+ font-size: 1rem;
+ font-weight: 400;
+ vertical-align: middle;
+ padding: .375rem .75rem;
+ user-select: none;
+ line-height: 1.5;
+ transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
+}
+
+code.download:hover {
+ color: white;
+ background-color: var(--color-brand-primary);
+ border-color: var(--color-brand-primary);
+ text-decoration: none;
+ padding: .375rem .75rem;
+}
+
+dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple):first-child > dt {
+ font-size: +2.25rem;
+ font-weight: 700;
+ color: #ff00dd;
+}
+
+.theme-toggle svg{
+ width: +1.25rem;
+ height: +2.25rem;
+}
+
+.sd-card-title code span {
+ font-size: +1rem;
+ color: var(--color-brand-primary);
+}
diff --git a/sources/pyside6/doc/_static/qtforpython.ico b/sources/pyside6/doc/_static/qtforpython.ico
new file mode 100644
index 000000000..2f4d9e9de
--- /dev/null
+++ b/sources/pyside6/doc/_static/qtforpython.ico
Binary files differ
diff --git a/sources/pyside6/doc/_static/qtforpython.png b/sources/pyside6/doc/_static/qtforpython.png
new file mode 100644
index 000000000..33e971022
--- /dev/null
+++ b/sources/pyside6/doc/_static/qtforpython.png
Binary files differ
diff --git a/sources/pyside6/doc/_tags/android.rst b/sources/pyside6/doc/_tags/android.rst
new file mode 100644
index 000000000..08a30fc0f
--- /dev/null
+++ b/sources/pyside6/doc/_tags/android.rst
@@ -0,0 +1,21 @@
+My tags: Android
+################
+
+.. toctree::
+ :maxdepth: 1
+ :caption: With this tag
+
+ ../examples/example_bluetooth_heartrate_game.rst
+ ../examples/example_bluetooth_lowenergyscanner.rst
+ ../examples/example_location_mapviewer.rst
+ ../examples/example_multimedia_audiooutput.rst
+ ../examples/example_multimedia_audiosource.rst
+ ../examples/example_multimedia_camera.rst
+ ../examples/example_qml_editingmodel.rst
+ ../examples/example_qml_usingmodel.rst
+ ../examples/example_quick_models_objectlistmodel.rst
+ ../examples/example_quick_models_stringlistmodel.rst
+ ../examples/example_quick_painteditem.rst
+ ../examples/example_quickcontrols_contactslist.rst
+ ../examples/example_quickcontrols_gallery.rst
+ ../examples/example_widgets_widgets_digitalclock.rst
diff --git a/sources/pyside6/doc/_tags/tagsindex.rst b/sources/pyside6/doc/_tags/tagsindex.rst
new file mode 100644
index 000000000..be29337ec
--- /dev/null
+++ b/sources/pyside6/doc/_tags/tagsindex.rst
@@ -0,0 +1,12 @@
+:orphan:
+
+.. _tagoverview:
+
+Tags overview
+#############
+
+.. toctree::
+ :caption: Tags
+ :maxdepth: 1
+
+ Android (14) <android.rst>
diff --git a/sources/pyside6/doc/_templates/layout.html b/sources/pyside6/doc/_templates/layout.html
new file mode 100644
index 000000000..8f16e1cdf
--- /dev/null
+++ b/sources/pyside6/doc/_templates/layout.html
@@ -0,0 +1,53 @@
+{% extends "!layout.html" %}
+
+{%- block sidebar1 %}{{ sidebar() }}{%- endblock %}
+{%- block sidebar2 %}{%- endblock %}
+
+{% block sidebarlogo %}
+<div class="logo">
+ <a href="http://www.pyside.org">
+ <img alt="PySide" src="{{ pathto('_static/pysidelogo.png', 1) }}"/>
+ </a>
+</div>
+{% endblock %}
+
+{%- block header %}
+<div id="container">
+ <div class="header">
+ <div class="header_container">
+ <div class="related">
+ <ul>
+ {%- block rootrellink %}
+ <li><a href="{{ pathto( 'index' ) }}">{{ shorttitle|e }}</a></li>
+ {%- endblock %}
+ {%- for parent in parents %}
+ <li>{{ reldelim1 }} <a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a></li>
+ {%- endfor %}
+ {%- block relbaritems %} {% endblock %}
+ </ul>
+ </div>
+ </div>
+ </div>
+{%- endblock -%}
+
+{%- block document %}
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body" role="main">
+ {% block body %} {% endblock %}
+ </div>
+ </div>
+ </div>
+{% endblock %}
+
+{%- block footer %}
+ <div class="footer">
+ <a href="https://www.qt.io/"><img src="{{ pathto('_static/logo_qt.png', 1) }}" alt="Qt" border="0" /></a>
+ <a href="http://www.python.org"><img src="{{ pathto('_static/logo_python.jpg', 1) }}" alt="Python" border="0" /></a>
+ <p>{{ copyright }}</p>
+ </div>
+</div>
+{%- endblock %}
+
+{%- block relbar1 %}{%- endblock %}
+{%- block relbar2 %}{%- endblock %}
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/domainindex.html b/sources/pyside6/doc/_themes/pysidedocs_qthelp/domainindex.html
new file mode 100644
index 000000000..c136cdd1c
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/domainindex.html
@@ -0,0 +1,57 @@
+{#
+ basic/domainindex.html
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Template for domain indices (module index, ...).
+
+ :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+#}
+{% extends "layout.html" %}
+{% set title = indextitle %}
+{% block extrahead %}
+{{ super() }}
+{% if not embedded and collapse_index %}
+ <script type="text/javascript">
+ DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
+ </script>
+{% endif %}
+{% endblock %}
+{% block body %}
+<div class="section">
+ {%- set curr_group = 0 %}
+
+ <h1>{{ indextitle }}</h1>
+
+ <div class="modindex-jumpbox">
+ {%- for (letter, entries) in content %}
+ <a href="#cap-{{ letter }}"><strong>{{ letter }}</strong></a>
+ {%- if not loop.last %} | {% endif %}
+ {%- endfor %}
+ </div>
+
+ <table class="indextable modindextable" cellspacing="0" cellpadding="2">
+ {%- for letter, entries in content %}
+ <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
+ <tr class="cap"><td></td><td><a name="cap-{{ letter }}">
+ <strong>{{ letter }}</strong></a></td><td></td></tr>
+ {%- for (name, grouptype, page, anchor, extra, qualifier, description)
+ in entries %}
+ {%- if grouptype == 1 %}{% set curr_group = curr_group + 1 %}{% endif %}
+ <tr{% if grouptype == 2 %} class="cg-{{ curr_group }}"{% endif %}>
+ <td>{% if grouptype == 1 -%}
+ <img src="{{ pathto('_static/minus.png', 1) }}" id="toggle-{{ curr_group }}"
+ class="toggler" style="display: none" alt="-" />
+ {%- endif %}</td>
+ <td>{% if grouptype == 2 %}&nbsp;&nbsp;&nbsp;{% endif %}
+ {% if page %}<a href="{{ pathto(page) }}#{{ anchor }}">{% endif -%}
+ <tt class="xref">{{ name|e }}</tt>
+ {%- if page %}</a>{% endif %}
+ {%- if extra %} <em>({{ extra|e }})</em>{% endif -%}
+ </td><td>{% if qualifier %}<strong>{{ qualifier|e }}:</strong>{% endif %}
+ <em>{{ description|e }}</em></td></tr>
+ {%- endfor %}
+ {%- endfor %}
+ </table>
+</div>
+{% endblock %}
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/fakebar.png b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/fakebar.png
new file mode 100644
index 000000000..b45830e00
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/fakebar.png
Binary files differ
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg
new file mode 100644
index 000000000..cd474efba
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg
Binary files differ
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_qt.png b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_qt.png
new file mode 100644
index 000000000..3bc03b7c7
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/logo_qt.png
Binary files differ
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/minus.png b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/minus.png
new file mode 100644
index 000000000..da1c5620d
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/minus.png
Binary files differ
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/plus.png b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/plus.png
new file mode 100644
index 000000000..b3cb37425
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/plus.png
Binary files differ
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pyside.css b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pyside.css
new file mode 100644
index 000000000..94134cacf
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pyside.css
@@ -0,0 +1,1943 @@
+@import url('cookie-confirm.css') screen;
+
+/* -- admonitions -- */
+
+div.admonition {
+ margin: 1.5em 0 1.5em;
+ padding: 0;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.admonition code {
+ font-family: inherit;
+}
+
+p.admonition-title + p {
+ padding-left: 1em;
+}
+
+div.admonition a:after {
+ content: ', ';
+}
+
+div.admonition a:last-child:after {
+ content: '';
+}
+
+.body {
+ width: 100%
+}
+.bodywrapper .admonition p.admonition-title {
+ margin-bottom:5px
+}
+
+.bodywrapper .admonition p {
+ margin:0
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+div.warning, div.seealso, div.note {
+ padding: 6px 0px 6px 10px;
+ border: none;
+}
+
+div.warning {
+ background-color: #ffe4e4;
+}
+
+div.seealso {
+ background-color: #fff2d6;
+}
+
+div.note {
+ background-color: #f3f3f4;
+}
+
+table.docutils {
+ margin-right: auto;
+ margin-bottom: 10px;
+ border: none;
+ width: initial;
+}
+
+table.docutils.colwidths-given td {
+ float: none;
+}
+
+table.docutils th,
+table.docutils td {
+ padding-left:0;
+ border: none;
+}
+
+table.docutils td ul {
+ margin:0
+}
+
+table.docutils td ul > li {
+ margin: 0 0 0.5em;
+}
+h2 em {
+ float: right;
+ font-size: 10px;
+ position: relative;
+ top: -20px;
+}
+
+.document {
+ padding-bottom: 20px;
+}
+
+.documentwrapper {
+ margin-left: 20px;
+}
+
+.body blockquote {
+ border: none;
+ padding-left: 0;
+ margin-bottom: 1.5em;
+}
+
+.sphinxsidebar {
+ float: left;
+ width: 186px;
+ padding: 25px;
+ text-align: left;
+ background-color: #fff;
+}
+
+.sphinxsidebar ul {
+ padding: 0px;
+ margin: 0px;
+ list-style-position: inside;
+}
+
+.sphinxsidebar > ul {
+ padding: 0px;
+ margin: 0px;
+}
+
+.sphinxsidebar ul li li {
+ margin-left: 10px;
+ padding: 0px;
+ font-size: 0.95em;
+}
+
+.sphinxsidebar ul a,
+.sphinxsidebar p.topless a {
+ word-break: break-word;
+}
+
+.sphinxsidebar h3, .sphinxsidebar h3 a {
+ color: #333;
+}
+
+.sphinxsidebar p.topless {
+ margin: 1em 0 1em;
+}
+
+.pysidetoc ul {
+ list-style: none;
+ padding: 0px;
+ margin: 0px;
+}
+
+.pysidetoc em {
+ font-style: normal;
+}
+
+.pysidetoc strong {
+ display: block;
+ padding: 5px;
+ margin: 0 10px 10px 0;
+ border: none;
+ background-color: #e2e2e2;
+}
+
+.section .docutils.container td {
+ float:left;
+}
+
+.hide {
+ display: none;
+}
+
+/* copy-notice */
+.document + p {
+ margin-left: 255px;
+ width: 70%;
+ font-size: 0.75em;
+ margin: 0 35px 15px 280px;
+}
+
+#searchbox {
+ border-top: 1px solid #989898;
+ padding-top: 10px;
+ margin-left: -10px;
+ margin-right: -10px;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#search_button {
+ border: 1px solid #3A393A;
+ background-color: #3A393A;
+ color: white;
+ cursor: pointer;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+
+}
+
+form {
+ margin: 0px;
+ padding: 0px;
+}
+
+#searchbox h3 {
+ padding: 10px 0 0 0;
+ margin-bottom: 5px;
+}
+
+/* search field */
+form #q {
+ width: 136px;
+ /* height: 22px; */
+ /* border: none; */
+ margin: 0px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+ margin-top: 2px;
+ padding: 4px;
+ line-height: 22px;
+}
+
+#search-results h2 {
+ display: none;
+}
+
+#search-results h2 {
+ display: none;
+}
+
+#search-results ul.search {
+ margin: 0px;
+ padding: 0px;
+}
+
+ul.search div.context {
+ padding-left: 40px;
+}
+
+#installation td {
+ text-align: center;
+ font-weight: bold;
+}
+
+em {
+ color: inherit;
+ font-style:italic;
+}
+
+/******** REL bar *********/
+
+.related {
+ display: inline;
+}
+
+.related h3 {
+ display: none;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.contentstable {
+ width: 100%;
+}
+
+.contentstable td {
+ padding-left: 30px;
+ vertical-align: top;
+}
+
+p.biglink a {
+ font-size: 20px;
+}
+
+dt:target, .highlight {
+ background-color: #fbe54e;
+}
+
+p.highlight-link {
+ margin-top: 10px;
+ font-size: 0.8em;
+}
+
+#synopsis table, table.field-list {
+ margin: 1em 0 1em 0;
+}
+
+table.field-list tr {
+ text-align: left;
+}
+
+tt.descname {
+ font-size: 120%;
+ font-weight: bold;
+}
+
+#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul {
+ margin: 0;
+ padding: 6px;
+ border: 1px solid #ddd;
+ border-radius: 0;
+ background-color: #e2e2e2;
+}
+
+#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p {
+ margin: 0;
+ padding: 0;
+}
+
+#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li {
+ list-style: none;
+ margin: 5px;
+ padding: 0;
+ font-size: 90%;
+}
+
+#synopsis span.pre {
+ color: #009491;
+ font-weight: bolder;
+}
+
+#detailed-description .class dt,
+#detailed-description .method dt,
+#detailed-description .staticmethod dt,
+#detailed-description .attribute dt {
+ margin: 0px;
+ margin-bottom: 10px;
+ padding: 10px;
+ font-weight: bold;
+ background-color: #e2e2e2;
+ border: none;
+ border-radius: 0;
+}
+
+#detailed-description dd > blockquote,
+#detailed-description dd > .field-list {
+ font-family: monospace;
+ font-size: small;
+ border-left: 10px solid #e2e2e2;
+ padding-left: 10px;
+ margin-bottom: 1.5em;
+}
+
+#detailed-description dd > blockquote blockquote {
+ border: none;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd,
+#detailed-description .method .field-odd,
+#detailed-description .staticmethod .field-odd,
+#detailed-description .attribute .field-odd {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+
+}
+
+#detailed-description .class .field-even,
+#detailed-description .method .field-even,
+#detailed-description .staticmethod .field-even,
+#detailed-description .attribute .field-even {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+}
+
+#detailed-description .class .field-odd li,
+#detailed-description .method .field-odd li,
+#detailed-description .staticmethod .field-odd li,
+#detailed-description .attribute .field-odd li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+}
+
+#detailed-description .class .field-even li,
+#detailed-description .method .field-even li,
+#detailed-description .staticmethod .field-even li,
+#detailed-description .attribute .field-even li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd p,
+#detailed-description .method .field-odd p,
+#detailed-description .staticmethod .field-odd p,
+#detailed-description .attribute .field-odd p{
+ margin: 0;
+ margin-left: 20px;
+
+}
+
+#detailed-description .class .field-even p,
+#detailed-description .method .field-even p,
+#detailed-description .staticmethod .field-even p,
+#detailed-description .attribute .field-even p{
+ margin: 0;
+ margin-left: 20px;
+}
+
+#detailed-description .class .field-odd p:last-child,
+#detailed-description .method .field-odd p:last-child,
+#detailed-description .staticmethod .field-odd p:last-child,
+#detailed-description .attribute .field-odd p:last-child {
+ margin-bottom: 10px;
+
+}
+
+#detailed-description .class .field-even p:last-child,
+#detailed-description .method .field-even p:last-child,
+#detailed-description .staticmethod .field-even p:last-child,
+#detailed-description .attribute .field-even p:last-child{
+ margin-bottom: 10px;
+}
+
+.document dl.attribute,
+.document dl.class,
+.document dl.method,
+.document dl.staticmethod {
+ margin-top: 2em;
+}
+
+.document dl.attribute dd,
+.document dl.class dd,
+.document dl.method dd,
+.document dl.staticmethod dd {
+ padding-left: 1em;
+}
+
+#detailed-description .attribute td:nth-child(1) {
+ font-family: monospace;
+}
+
+/* Qt theme */
+#navbar {
+ position:fixed;
+ top:0;
+ left:0;
+ z-index:100;
+ background:#fff;
+ width:100%
+}
+#navbar .container, .fixed .container {
+ max-width:1280px;
+ margin:0 auto;
+ padding:0 3.9%; /* 0? */
+ position:relative;
+ overflow:visible
+}
+#navbar .navbar-header {
+ position:relative
+}
+#menuextras li a:hover span {
+ color: #2cde85;
+}
+/* new header */
+#mm-wrap, #mm-wrap #mm-helper,
+#mm-wrap #mm-helper li.mm-item,
+#mm-wrap #mm-helper a.mm-link {
+ -moz-transition: none;
+ -o-transition: none;
+ -webkit-transition: none;
+ transition: none;
+ -webkit-border-radius: 0 0 0 0;
+ -moz-border-radius: 0 0 0 0;
+ -ms-border-radius: 0 0 0 0;
+ -o-border-radius: 0 0 0 0;
+ border-radius: 0 0 0 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ -ms-box-shadow: none;
+ -o-box-shadow: none;
+ box-shadow: none;
+ background: none;
+ border: 0;
+ bottom: auto;
+ box-sizing: border-box;
+ clip: auto;
+ color: #090e21;
+ display: block;
+ float: none;
+ font-family: inherit;
+ font-size: 14px;
+ height: auto;
+ left: auto;
+ line-height: 1.7;
+ list-style-type: none;
+ margin: 0;
+ min-height: 0;
+ opacity: 1;
+ outline: none;
+ overflow: visible;
+ padding: 0;
+ position: relative;
+ right: auto;
+ text-align: left;
+ text-decoration: none;
+ text-transform: none;
+ top: auto;
+ vertical-align: baseline;
+ visibility: inherit;
+ width: auto;
+}
+#mm-wrap #mm-helper {
+ visibility:visible;
+ text-align:right;
+ padding:0 0px 0 0px
+}
+#navbar #mm-wrap #mm-helper li.mm-item {
+ border-right:solid #f3f3f4 1px;
+ padding-right:30px;
+ padding-left:30px
+}
+#navbar #mm-wrap #mm-helper li.mm-item > a:hover {
+ opacity: .5
+}
+#mm-wrap #mm-helper > li.mm-item {
+ margin:0 0 0 0;
+ display:inline-block;
+ height:auto;
+ vertical-align:middle
+}
+#navbar #mm-wrap #mm-helper li.mm-item:nth-child(3) {
+ border-right:0
+}
+#mm-wrap #mm-helper a.mm-link {
+ cursor: pointer
+}
+@media (max-width: 1279px) {
+ #navbar {
+ padding:0;
+ position:relative;
+ }
+ #navbar .container {
+ max-width:100%
+ }
+ .container {
+ padding:0 2%
+ }
+}
+#navbar .navbar-oneQt {
+ display:inline;
+ float:left;
+ width:31px;
+ color:#2cde85
+}
+#navbar .navbar-oneQt:before {
+ content:attr(data-icon);
+ position:absolute;
+ top:14px;
+ left:0;
+ color:#2cde85;
+ font-family:'Qt Icons';
+ line-height:1;
+ font-size:40px;
+ transition:all 0.3s ease-in-out;
+}
+#mm-wrap {
+ clear:both;
+ background:rgba(255, 255, 255, 0.1);
+ -webkit-border-radius:0px 0px 0px 0px;
+ -moz-border-radius:0px 0px 0px 0px;
+ -ms-border-radius:0px 0px 0px 0px;
+ -o-border-radius:0px 0px 0px 0px;
+ border-radius:0px 0px 0px 0px
+}
+#mm-wrap #mm-helper li.mm-item:last-child a {
+ background:transparent url("icon_avatar.png") 50% 50% no-repeat !important;
+ background-size:24px !important;
+ width:24px !important;
+ height:24px !important;
+}
+#navbar #mm-wrap #mm-helper li.mm-item > a {
+ opacity:1;
+ -webkit-transition:all 0.3s ease-in-out;
+ -moz-transition:all 0.3s ease-in-out;
+ -ms-transition:all 0.3s ease-in-out;
+ -o-transition:all 0.3s ease-in-out;
+ transition:all 0.3s ease-in-out;
+}
+#mm-wrap #mm-helper > li.mm-item > a.mm-link {
+ border-top:0px solid #fff;
+ border-left:0px solid #fff;
+ border-right:0px solid #fff;
+ border-bottom:0px solid #fff;
+ outline:none;
+ text-decoration:none;
+ padding:0 0 0 0;
+ line-height:70px;
+ font-weight:normal;
+ height:70px;
+ vertical-align:baseline;
+ text-align:left;
+ width:auto;
+ display:block;
+ color:#090e21;
+ text-transform:none;
+ text-decoration:none;
+ background:rgba(0, 0, 0, 0);
+ -webkit-border-radius:0px 0px 0px 0px;
+ -moz-border-radius:0px 0px 0px 0px;
+ -ms-border-radius:0px 0px 0px 0px;
+ -o-border-radius:0px 0px 0px 0px;
+ border-radius:0px 0px 0px 0px;
+ font-family:inherit;
+ font-size:14px;
+}
+/* end new header */
+@media (min-width: 1320px) {
+ .body .flowListDiv dl.flowList {
+ -webkit-column-count:3;
+ -moz-column-count:3;
+ column-count:3
+ }
+}
+@media (min-width: 1120px) {
+ #navbar.fixed {
+ -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
+ -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
+ box-shadow:0px 0px 8px rgba(0,0,0,0.23)
+ }
+ #navbar.fixed #mm-wrap #mm-helper > li.mm-item > a.mm-link {
+ height:50px;
+ line-height:50px
+ }
+ #navbar.fixed .navbar-oneQt:before {
+ font-size:35px;
+ top:7px
+ }
+
+ .flowListDiv dl.flowList {
+ -webkit-column-count:2;
+ -moz-column-count:2;
+ column-count:2
+ }
+}
+@media (max-width: 1120px) {
+ #navbar {
+ padding:0;
+ position:relative
+ }
+ #navbar .navbar-oneQt:before {
+ left:10px
+ }
+ #navbar .container {
+ max-width:100%;
+ padding:0
+ }
+ #footerbar .container {
+ padding:0
+ }
+ body .main {
+ margin-top:0px
+ }
+ #footerbar .footer-main .footer-nav {
+ padding:3.9% 0 3.9% 3%;
+ border-bottom:1px solid #413d3b;
+ float:none;
+ display:block;
+ width:auto
+ }
+ #footerbar .footer-main .theqtcompany {
+ clear:both;
+ float:left;
+ margin:30px 0 8px 3%
+ }
+ #footerbar .footer-main .footer-social {
+ float:left;
+ padding:50px 0px 0px 3%
+ }
+ #footerbar #menu-footer-submenu {
+ clear:both;
+ float:none;
+ display:block;
+ padding:0px 0px 3.9% 3%
+ }
+ ul#menu-footer-submenu {
+ margin-left: 0
+ }
+}
+.cookies_yum {
+ background-color:#cecfd5;
+ display:none;
+ width:100%
+}
+.cookies_yum img {
+ width:25px;
+ top:6px;
+ display:inline-block;
+ position:absolute;
+ left:13px
+}
+.cookies_yum div {
+ margin:0 auto;
+ max-width:1280px;
+ min-height:30px;
+ padding:6px 0px 6px 0px;
+ position:relative
+}
+.cookies_yum p {
+ color:#09102b;
+ margin:0px;
+ font-size:0.79em;
+ display:inline-block;
+ line-height:1.2;
+ padding:0 30px 0 50px
+}
+.cookies_yum p a {
+ white-space:nowrap
+}
+.cookies_yum a:hover {
+ color:#46a2da
+}
+.cookies_yum .close {
+ width:15px;
+ height:15px;
+ background-image:url("cookiebar-x.png");
+ background-size:15px 30px;
+ background-position:top left;
+ cursor:pointer;
+ top:13px;
+ right:13px;
+ position:absolute;
+ transition:none
+}
+.cookies_yum .close:hover {
+ background-position:bottom left
+}
+#sidebar-toggle,#toc-toggle {
+ width:24px;
+ height:14px;
+ background-size:24px 28px;
+ cursor:pointer;
+ background-image:url("list_expand.png");
+ float:right
+}
+#sidebar-toggle.collapsed,
+#toc-toggle.collapsed {
+ background-position:bottom left
+}
+#sidebar-content > h2 {
+ display:none
+}
+#footerbar {
+ background:#222840;
+ color:#fff;
+ font-size: 0.9em;
+}
+#footerbar.fixed {
+ bottom:0;
+ left:0;
+ width:100%
+}
+#footerbar .footer-nav {
+ display:inline;
+ float:left
+}
+#footerbar .footer-main .footer-nav li {
+ float:left;
+ margin-right:1em
+}
+#footerbar .footer-main .footer-nav li a {
+ display:block;
+ padding:30px 0 10px 0;
+ line-height:20px;
+ height:20px;
+ color:#fff;
+ font-weight: 600;
+}
+#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a {
+ color:#eee
+}
+#footerbar .footer-main .footer-nav .sub-menu {
+ margin-left:0;
+ margin-bottom:0
+}
+#footerbar .footer-main .footer-nav .sub-menu li {
+ float:none;
+ width: 100%;
+}
+#footerbar .footer-main .footer-nav .sub-menu ul {
+ padding:1px 1em;
+ font-size:0.786em;
+ line-height:8px;
+ float:none;
+ color:#5d5b59;
+ margin-bottom:0
+}
+#footerbar .footer-main .footer-nav .sub-menu li a {
+ padding:2px 0;
+ font-size:1em;
+ float:none;
+ color:#cecfd5;
+ font-weight: 400;
+}
+#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a {
+ color:#eee
+}
+#footerbar .theqtcompany {
+ background:url("theqtcompany.png") no-repeat;
+ background-size:100%;
+ width:215px;
+ height:68px;
+ display:inline;
+ float:right;
+ margin:29px 0 28px 30px
+}
+#footerbar .footer-social {
+ display:inline;
+ float:right;
+ width:164px
+}
+#footerbar .footer-main .footer-social>div {
+ margin-left:0.1em;
+ margin-bottom:10px
+}
+#footerbar .disclaimer {
+ font-size:0.786em;
+ line-height:2.73;
+ color:#868584;
+ padding-top:20px;
+ padding-bottom:0.5%
+}
+#footerbar .disclaimer a {
+ color:#bdbebf
+}
+#footerbar .disclaimer a:hover {
+ color:#d6d6d6
+}
+#footerbar .disclaimer ul li {
+ float:left;
+ vertical-align:middle;
+ margin-left:1.18em
+}
+#footerbar .disclaimer ul li:first-child {
+ margin-left:0
+}
+#footerbar .disclaimer ul.lang-selector a {
+ color:#506a34;
+ color:rgba(128,195,66,0.3)
+}
+#footerbar .disclaimer ul.lang-selector a:hover {
+ color:#80c342;
+ color:rgba(128,195,66,0.7)
+}
+#menu-footer-menu, #menu-footer-menu ul {
+ margin-left:0;
+ margin-bottom:0
+}
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ font-weight: 400;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium Web"), local("TitilliumWeb-Regular"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+/* titillium-web-italic - latin_latin-ext */
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: italic;
+ font-weight: 400;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium WebItalic"), local("TitilliumWeb-Italic"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+/* titillium-web-600 - latin_latin-ext */
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ font-weight: 600;
+ src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot");
+ /* IE9 Compat Modes */
+ src: local("Titillium WebSemiBold"), local("TitilliumWeb-SemiBold"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.svg#TitilliumWeb") format("svg");
+ /* Legacy iOS */
+}
+@font-face {
+ font-family:monospace;
+ font-style:normal;
+ font-weight:400;
+ src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff")
+}
+@font-face {
+ font-family:'Qt Icons';
+ src:url("../style/icomoon.eot?-tgjuoj");
+ src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg");
+ font-weight:normal;
+ font-style:normal
+}
+@font-face {
+ font-family:'social-icons';
+ src:url("../style/social-icons.eot?54625607");
+ src:url("../style/social-icons.eot?54625607#iefix") format("embedded-opentype"),
+ url("../style/social-icons.woff?54625607") format("woff");
+ font-weight:normal;
+ font-style:normal
+}
+.clearfix:before,.clearfix:after {
+ content:" ";
+ display:table
+}
+.clearfix:after {
+ clear:both
+}
+.clearfix {
+ *zoom:1
+}
+.clearfix .right {
+ float:right
+}
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+ margin:0;
+ padding:0;
+ border:0;
+ font-size:100%;
+ line-height: 1.4;
+}
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
+ vertical-align:baseline
+}
+h1,h2,h3,h4,h5,h6 {
+ font-weight:300
+}
+.body h2,.body h3,.body h4,.body h5,.body h6 {
+ margin:1.5em 0 0.75em
+}
+.body h1 {
+ margin-bottom:0.75em;
+ font-size:2.25em;
+}
+.body h3.fn,.body h3.flags {
+ color:#26282a;
+ font-size:1.46em;
+ padding:15px 0 15px 0;
+ border-bottom:2px #eee solid;
+ word-wrap:break-word
+}
+.body .fngroup {
+ border-bottom:2px #eee solid;
+ padding-bottom:15px;
+ margin-bottom:1.5em
+}
+.body .fngroup h3.fngroupitem {
+ margin:0;
+ padding-bottom:0;
+ border:none
+}
+.body h3.fn .name,
+.body h3 span.type,
+.qmlname span.name {
+ font-weight: 400
+}
+.qmlname {
+ font-size:1.46em
+}
+.qmlproto table {
+ border:none;
+ border-bottom:2px #eee solid
+}
+.qmlproto table p {
+ max-width:100%
+}
+.qmlproto table tr {
+ background-color:#fff
+}
+.qmlname td, .qmlname th {
+ border:none;
+ text-align:left;
+ padding:5px 0 0 0
+}
+.qmlreadonly,.qmldefault {
+ padding:0 5px 0 5px;
+ font-size:0.75em;
+ background-color:#eee;
+ float:right
+}
+.qmlreadonly {
+ color:#414141
+}
+.qmldefault {
+ color:#D14141
+}
+.rightAlign {
+ padding:3px 5px 3px 10px;
+ text-align:right
+}
+.centerAlign.functionIndex {
+ text-align:center;
+ font-size:150%;
+ margin-bottom: 1em
+}
+article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section {
+ display:block
+}
+body {
+ line-height:1.25em;
+ font-family: Arial, Helvitica;
+ font-weight:400;
+ transition-duration:1s;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-size: 16px;
+ background-color:#f3f3f4;
+ color:#404244;
+}
+ol,ul {
+ list-style-type: square;
+ #color: #17a81a;
+}
+.body ol,.body ul {
+ margin-top:0.75em;
+ margin-left:20px
+}
+.bodywrapper ol>li {
+ list-style-type:decimal;
+ margin-left:15px
+}
+.bodywrapper ol.a >li {
+ list-style-type:lower-alpha;
+}
+.bodywrapper ol.A >li {
+ list-style-type:upper-alpha;
+}
+.bodywrapper ol.i >li {
+ list-style-type:lower-roman;
+}
+.bodywrapper ol.I >li {
+ list-style-type:upper-roman;
+}
+.body li p {
+ margin-top:1em
+}
+blockquote,q {
+ quotes:none;
+ border-left:10px solid #ddd;
+ padding-left:10px
+}
+blockquote:before,blockquote:after,q:before,q:after {
+ content:'';
+ content:none;
+ width:100%
+}
+table {
+ border-collapse:collapse;
+ border-spacing:0;
+ margin-bottom:5px;
+ width:100%
+}
+a {
+ color:#17a81a;
+ text-decoration:none;
+ transition-duration:0.3s
+}
+a:hover {
+ color:#17a81a
+}
+.main,#footerbar>div {
+ max-width:1280px;
+ width:95%;
+ margin:0 auto
+}
+.main {
+ margin-top:80px
+}
+@media (max-width: 1120px) {
+ .main,.navbar-header,#footerbar>div {
+ width: 100%;
+ margin: 0;
+ }
+ .main .main-rounded {
+ padding: 0 15px;
+ }
+}
+.main_index {
+ background-color:#fff
+}
+.sectionlist {
+ margin-bottom:2em
+}
+[class*="col-"] {
+ letter-spacing:normal
+}
+.landing,.main_index .row {
+ letter-spacing:-0.31em
+}
+.main_index .row>div {
+ letter-spacing:normal
+}
+.col-1,.body {
+ display:inline-block;
+ background-color:#fff;
+ padding: 25px 35px 20px 30px;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+}
+.col-1 h2 {
+ font-size:1.8em;
+ font-weight:300;
+ line-height:1.1;
+ margin-bottom:0.83em;
+ margin-top:1em
+}
+.icons1of3 img {
+ display:inline-block;
+ float:left;
+ margin-right:0.75em;
+ margin-top:-5px;
+ width:2.75em
+}
+div.multi-column {
+ position:relative
+}
+div.multi-column div {
+ display:-moz-inline-box;
+ display:inline-block;
+ vertical-align:top;
+ margin-top:1em;
+ margin-right:2em;
+ width:16em
+}
+.sidebar {
+ display:block;
+ position:relative;
+ position:sticky;
+ float:left;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ width:20%;
+ padding-right:20px
+}
+.sidebar li {
+ text-overflow:ellipsis;
+ overflow:hidden
+}
+.toc,.sectionlist {
+ padding:25px;
+ background-color:#fff;
+ margin-bottom:1.25em
+}
+.sidebar .sectionlist p {
+ margin-bottom:0
+}
+.sectionlist.promo {
+ padding:0;
+ background-color:#f3f3f4
+}
+.sidebar-content:empty {
+ display:none;
+ visibility:hidden
+}
+.col-2 h2,.toc h3,.sidebar-content h2,
+.sidebar-content h3,.sectionlist h2,
+.sphinxsidebar {
+ position: fixed;
+ overflow: scroll;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
+.sphinxsidebar h3 {
+ font-weight: bold;
+ margin-bottom:1em;
+}
+.toc h3 a {
+ color:#404244
+}
+.title {
+ font-size:2.25em;
+ font-weight:300;
+ letter-spacing:-1px;
+ line-height:1.15em;
+ margin-bottom:0.5em;
+ word-wrap:break-word
+}
+.navigationbar,col-1 h2 {
+ font-size:0.85em
+}
+.navigationbar h1 {
+ font-size:2.5em;
+ margin-bottom:0.85em;
+ margin-top:0.85em
+}
+.navigationbar li {
+ display:inline-block;
+ margin-right:5px;
+ position:relative;
+ padding-right:10px;
+ color:#585a5c
+}
+.navigationbar ul:last-of-type li a {
+ color:#404244
+}
+.sectionlist li, .sphinxsidebar li {
+ padding-bottom: 10px;
+ line-height: 1.75em;
+}
+.col-1 ul {
+ margin-bottom:1.56em
+}
+.bodywrapper li {
+ margin-top:0.5em;
+ line-height:1.25em
+}
+.bodywrapper li.level2 {
+ margin-left:10px;
+ margin-top:0.4em;
+ font-size:0.9375em;
+}
+.bodywrapper p,
+.bodywrapper dd {
+ line-height:1.25em;
+ margin:1em 0 1em;
+ color:#404244
+}
+.bodywrapper b {
+ font-weight:600
+}
+.body ul,.body ol {
+ /* margin-bottom:1.5em */
+}
+.bodywrapper ul ul {
+ margin-top:0.5em
+}
+.bodywrapper .naviNextPrevious {
+ margin-top:25px;
+ max-width:100%
+}
+.naviNextPrevious.headerNavi,
+p.naviNextPrevious + p {
+ display:none
+}
+.nextPage {
+ float:right
+}
+.prevPage:before {
+ content:"< "
+}
+.nextPage:after {
+ content:" >"
+}
+.navigationbar li a {
+ color:#404244
+}
+.navigationbar li:after {
+ color:#404244;
+ content:"›";
+ display:inline-block;
+ font-size:1.5em;
+ line-height:1;
+ position:absolute;
+ right:-2px;
+ top:-4px
+}
+.sub-navigation {
+ margin-top:10px
+}
+.navigationbar li:last-child:after,.sub-navigation li:after {
+ content:none
+}
+.navigationbar {
+ margin-bottom:10px;
+ line-height:1em
+}
+#buildversion {
+ margin-bottom:10px;
+ font-style:italic;
+ font-size:small;
+ float:right
+}
+.copy-notice {
+ width:75%;
+ font-size:0.75em;
+ margin:20px 35px 0 10px;
+ line-height:1.75em;
+ float:right;
+ color:#585a5c
+}
+.copy-notice.index {
+ margin-top:10px;
+ float:none
+}
+li a.active {
+ color:#585a5c
+}
+.flowList {
+ padding:25px
+}
+.flowListDiv dl {
+ -webkit-column-count:1;
+ -moz-column-count:1;
+ column-count:1
+}
+.flowList dd {
+ display:inline-block;
+ margin-left:10px;
+ width:90%;
+ line-height:1.15em;
+ overflow-x:hidden;
+ text-overflow:ellipsis
+}
+.alphaChar {
+ font-size:2em;
+ position:absolute
+}
+.flowList.odd {
+ background-color:#f9f9f9
+}
+.body ul>li,.doc-column ul>li {
+ list-style-image:url("list_arrow.png");
+ margin-left:15px;
+ color:#404244;
+ margin-top:0.65em;
+ line-height:1em
+}
+.bodywrapper table p {
+ margin:0px;
+ padding:0px
+}
+.bodywrapper table p {
+ margin:0px;
+ padding:0px;
+ min-height:1.25em
+}
+.bodywrapper .qmldoc {
+ margin-top:0.75em
+}
+.body h2 {
+ margin-top: 1.5em;
+ font-size:1.75em
+}
+.body h3 {
+ font-size:1.35em
+}
+.body h4 {
+ font-size:1.15em
+}
+.body p img {
+ margin-top:0.75em;
+ max-width:100%
+}
+.body .border img {
+ box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
+}
+.body .border .player {
+ box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
+}
+.body p.figCaption {
+ transform:translateY(-30px);
+ color:#606366;
+ font-size:95%;
+ margin-left:3px;
+ font-style:italic
+}
+.body table {
+ width:initial;
+ vertical-align:initial
+}
+table .odd {
+ background-color:#f9f9f9
+}
+table thead {
+ text-align:left;
+ padding-left:20px
+}
+table,table td,table th {
+ border:1px solid #eee
+}
+table td,table th {
+ padding:5px 20px;
+ line-height:1.3
+}
+.body .fixed table td {
+ min-width:50%;
+ width:50%
+}
+table.alignedsummary,table.propsummary {
+ width:initial
+}
+table.valuelist td.tblval {
+ font-size:0.75em
+}
+div.main_index .row {
+ border-bottom:10px solid #f3f3f4
+}
+div.main_index .row {
+ position:relative
+}
+div.main_index .row>div {
+ display:inline-block;
+ width:50%;
+ vertical-align:top;
+ padding:2em 3em;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box
+}
+div.main_index h2 {
+ font-size:2.1875em;
+ margin-bottom:1em
+}
+#search_bar {
+ width:40%;
+ float:right
+}
+div.main_index .row:after {
+ content:"";
+ position:absolute;
+ top:0;
+ right:50%;
+ height:100%;
+ width:10px;
+ background-color:#f3f3f4
+}
+div.table {
+ overflow-x:auto
+}
+.body tr > td > pre {
+ font-size:0.75em
+}
+p.qt_commercial {
+ border:3px solid #5caa15;
+ margin:0 auto;
+ padding:15px;
+ width:28%;
+ text-align:center;
+ clear:both
+}
+h1.qt_commercial {
+ padding:20px;
+ background-color:#5caa15;
+ display:inline;
+ float:right;
+ font-size:1.25em;
+ line-height:1.25em;
+ height:1.25em;
+ color:#fff
+}
+div.qt_commercial {
+ border-top:5px solid #5caa15;
+ margin-bottom:50px
+}
+div.pre {
+ position:relative;
+ height:auto
+}
+pre, .LegaleseLeft {
+ background-color:#222840;
+ color:#fff;
+ display:block;
+ font-family:monospace;
+ line-height:1.5;
+ overflow-x:auto;
+ margin-bottom:25px;
+ padding:25px;
+ margin-top:0.75em;
+ font-size: .8em;
+}
+.bodywrapper .LegaleseLeft p {
+ color:#fff;
+ white-space: pre-wrap
+}
+pre .str,code .str {
+ color:#aaaaaa
+}
+pre .kwd,code .kwd {
+ color:#ffff55
+}
+pre .com,code .com {
+ color:#55ffff
+}
+pre .typ,code .typ {
+ color:#4f9d08
+}
+pre a .typ,code a .typ {
+ color:#21be2b
+}
+pre .lit,code .lit {
+ color:#ff55ff
+}
+pre .pun,code .pun {
+ color:#fff
+}
+pre .pln,code .pln {
+ color:#fff
+}
+@media print {
+ pre {
+ background-color:#eee !important
+ }
+ pre .str,code .str {
+ color:#060
+ }
+ pre .kwd,code .kwd{
+ color:#006;
+ font-weight:bold
+ }
+ pre .com,code .com {
+ color:#600
+ }
+ pre .typ,code .typ {
+ color:#404;
+ font-weight:bold
+ }
+ pre .lit,code .lit {
+ color:#044
+ }
+ pre .pun,code .pun {
+ color:#440
+ }
+ pre .pln,code .pln {
+ color:#000
+ }
+}
+pre.wrap {
+ white-space:pre-wrap
+}
+pre span.wrap {
+ display:none;
+ background:url("wrap.png") no-repeat;
+ right:0;
+ top:2px;
+ position:absolute;
+ width:20px;
+ height:14px;
+ margin:4px;
+ opacity:0.65
+}
+
+span.pre {
+ color: #09102d;
+}
+
+span.wrap:hover {
+ opacity:1
+}
+span.wrap:active {
+ opacity:0.75
+}
+.copy_text {
+ background-color:#46a2da;
+ color:#fff;
+ border:2px solid #46a2da;
+ padding:10px 16px;
+ margin-left:-10px;
+ margin-top:-50px;
+ position:absolute;
+ opacity:0;
+ cursor:pointer;
+ float:right
+}
+.copy_text:hover {
+ background-color:#fff;
+ color:#46a2da
+}
+code,.codelike {
+ font-family:monospace;
+}
+#detailed-description .function dt > code,
+#detailed-description .function dt > em {
+ font-weight:bold
+}
+h3.fn code {
+ font-size:0.75em;
+ float:right;
+ background-color:#eee;
+ padding:3px;
+ margin: 3px 0 0 20px
+}
+pre:hover>.copy_text {
+ display:inline-block;
+ opacity:1;
+ transition:0.5s ease
+}
+#main_title_bar {
+ background:url("pyside-logo.png") no-repeat;
+ background-size:100%;
+ width:366px;
+ height:86px;
+ margin:15px 0 15px 0
+}
+#main_title_bar h1 {
+ visibility:hidden
+}
+#main_title_bar .search_bar {
+ letter-spacing:normal;
+ width:50%;
+ display:inline-block;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ vertical-align:middle
+}
+#main_title_bar h1 {
+ letter-spacing:normal;
+ display:inline-block;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ vertical-align:middle
+}
+#main_title_bar .search_bar * {
+ letter-spacing:normal;
+ padding:0;
+ margin:0;
+ border:none
+}
+#sidebar-toggle,#toc-toggle {
+ display:none
+}
+@media (max-width: 980px) {
+ body {
+ font-size:calc-em(14px)
+ }
+ #main_title_bar>h1,#main_title_bar .search_bar {
+ width:100%
+ }
+ #main_title_bar .search_bar {
+ margin-bottom:15px
+ }
+ .main {
+ margin-top:0px
+ }
+ .main_index .row {
+ border:none !important
+ }
+ .title {
+ font-size:1.5em;
+ font-weight:400;
+ word-wrap:break-word
+ }
+ .col-1,.body,.naviNextPrevious,.sidebar {
+ padding:10px
+ }
+ .sidebar {
+ position:relative;
+ padding-top:0
+ }
+ .search .sidebar {
+ display:none;
+ visibility:hidden
+ }
+ .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 {
+ text-align:center;
+ margin-bottom:5px
+ }
+ div.main_index .row:after {
+ content:none
+ }
+ div.main_index .row>div {
+ display:block !important;
+ width:100%;
+ padding:15px;
+ margin:0
+ }
+ .body,.sidebar,.col-1 {
+ width:100%
+ }
+ .sidebar-content,.col-2,.toc {
+ background-color:#fff;
+ margin-bottom:1em;
+ padding:20px
+ }
+ #sidebar-toggle,#toc-toggle {
+ display:block
+ }
+ #sidebar-toggle.collapsed + h2 {
+ display:block
+ }
+ .bodywrapper p {
+ margin-bottom:1em;
+ max-width:100%
+ }
+ table td,table th {
+ padding:5px 5px
+ }
+ .sectionlist {
+ padding:0
+ }
+ .sidebar > .sectionlist {
+ padding:20px
+ }
+ .sectionlist.promo {
+ max-width:46%;
+ margin:0 auto 1em auto;
+ float:left;
+ padding:0 2%
+ }
+ .sidebar .sidebar-content {
+ clear:both
+ }
+ .copy-notice {
+ float:none;
+ width:initial
+ }
+}
+[id]:target > *:first-child,
+dt[id]:target {
+ -webkit-animation:highlighter 3s;
+ animation:highlighter 3s
+}
+@-webkit-keyframes highlighter {
+ 25% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+ 75% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+}
+@keyframes highlighter {
+ 25% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+ 75% {
+ background-color:#d1e8f6;
+ color:#444
+ }
+}
+@-webkit-keyframes copypaste {
+ 25% {
+ opacity:1
+ }
+ 100% {
+ border-radius:10px;
+ margin-top:-50px;
+ opacity:1
+ }
+}
+@keyframes copypaste {
+ 25% {
+ opacity:1
+ }
+ 100% {
+ border-radius:10px;
+ margin-top:-50px;
+ opacity:1
+ }
+}
+#footer {
+ clear:both
+}
+.footer-social i {
+ font-family: "social-icons";
+ font-style: normal;
+ font-size:150%;
+ margin: .55em;
+ color: #cecfd5
+}
+.footer-social i:hover {
+ color: #eee
+}
+.footer-social .icon-twitter:before {
+ content: '\f099'
+}
+.footer-social .icon-facebook:before {
+ content: '\f09a'
+}
+.footer-social .icon-youtube:before {
+ content: '\f16a'
+}
+.menuextraslanguages {
+ display:none;
+ visibility:hidden
+}
+
+input:focus {
+ border-color: #46a2da;
+ box-shadow: 0 0 5px #46a2da;
+ color: #000;
+}
+
+.animation {
+ width: 100%;
+ border-style: none;
+ border-width: 0
+}
+
+.player {
+ width: auto;
+ position: relative;
+ display: table;
+ margin-bottom:1.5em;
+}
+
+.playcontrol {
+ display: none;
+ background: url("play_icon.svg") no-repeat center,
+ linear-gradient(
+ rgba(0,0,0,0.15), rgba(0,0,0,0.15)
+ );
+ background-size: 25%;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ left: 0%;
+ right: 0%;
+ top: 0%;
+ bottom: 0%;
+ margin: auto
+}
+
+/* expand/collapse code sections */
+pre input {
+ display:none;
+ visibility:hidden
+}
+pre label {
+ display:block;
+ margin:-3px 3px 0 -16px;
+ text-align:center;
+ color:#21be2b;
+ float:left;
+}
+pre label:hover {
+ color:#fff
+}
+pre label::before {
+ font-weight:600;
+ font-size:16px;
+ content:"+";
+ display:inline-block;
+ width:16px;
+ height:16px
+}
+#ec_expand {
+ height:16px;
+ overflow:hidden;
+ transition:height 0.35s;
+}
+#ec_expand::before {
+ content:"...*/";
+ color:#aaa;
+ background-color:#3a4055;
+ z-index:99 !important;
+ right:25px;
+ position:absolute
+}
+#ec_toggle:checked ~ #ec_expand {
+ height:initial
+}
+#ec_toggle:checked ~ #ec_expand::before {
+ content:""
+}
+#ec_toggle:checked ~ label::before {
+ content:"-"
+}
+
+/* permalinks */
+h1:hover > .headerlink,
+h2:hover > .plink,
+h2:hover > .headerlink,
+h3:hover > .plink,
+h3:hover > .headerlink,
+h4:hover > .plink,
+h4:hover > .headerlink,
+h5:hover > .plink,
+h5:hover > .headerlink {
+ opacity:1
+}
+a.plink, a.headerlink {
+ opacity: 0;
+ padding-left: 8px;
+ font-size: 0.8em;
+ font-weight: 600;
+ transition: opacity 180ms ease-in-out
+}
+a.plink::before {
+ content:'\00B6'
+}
+
+table.special {
+ border: 3px;
+ padding: 0px;
+ border-collapse: separate;
+ border-spacing: 20px;
+ line-height: 1.5em;
+}
+
+.special p {
+ text-align: center;
+ color: #3a4055;
+}
+
+.special a {
+ display: block;
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special a:hover {
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special strong {
+ color: #17a81a;
+ font-size: 110%;
+ font-weight: normal;
+}
+
+table.special th,
+table.special td {
+ border: 1px solid #888;
+ padding-top: 14px;
+ padding-bottom: 14px;
+ padding-left: 6px;
+ padding-right: 5px;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+}
+
+.special td:hover {
+ padding-top: 2px;
+ padding-bottom: 2px;
+ border-bottom: 4px solid #2cde85;
+}
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png
new file mode 100644
index 000000000..3a2f2bd17
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png
Binary files differ
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png
new file mode 100644
index 000000000..4036733a7
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png
Binary files differ
diff --git a/sources/pyside6/doc/_themes/pysidedocs_qthelp/theme.conf b/sources/pyside6/doc/_themes/pysidedocs_qthelp/theme.conf
new file mode 100644
index 000000000..4384b459c
--- /dev/null
+++ b/sources/pyside6/doc/_themes/pysidedocs_qthelp/theme.conf
@@ -0,0 +1,7 @@
+[theme]
+inherit = default
+stylesheet = pyside.css
+pygments_style = none
+
+[options]
+nosidebar = true
diff --git a/sources/pyside6/doc/additionaldocs.lst b/sources/pyside6/doc/additionaldocs.lst
new file mode 100644
index 000000000..81da58370
--- /dev/null
+++ b/sources/pyside6/doc/additionaldocs.lst
@@ -0,0 +1,624 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+# see README.md
+# A line enclosed in [] denotes a (relative) target directory
+
+[overviews]
+animation-overview.webxml
+animation.webxml
+application-windows.webxml
+audiooverview.webxml
+bindableproperties.webxml
+bluetooth-examples.webxml
+cameraoverview.webxml
+compatmap.webxml
+concurrent-changes-qt6.webxml
+containers.webxml
+coordsys.webxml
+creating-a-sensor-plugin.webxml
+custom-types.webxml
+database.webxml
+datastreamformat.webxml
+dbus-changes-qt6.webxml
+determining-the-default-sensor-for-a-type.webxml
+dialogs.webxml
+dnd.webxml
+dynamic-sensor-backend-registration.webxml
+echoclient.webxml
+echoserver.webxml
+events.webxml
+eventsandfilters.webxml
+examples-dbus.webxml
+examples-designer.webxml
+examples-desktop.webxml
+examples-dialogs.webxml
+examples-graphicsview.webxml
+examples-itemviews.webxml
+examples-mainwindow.webxml
+examples-network.webxml
+examples-painting.webxml
+examples-qthelp.webxml
+examples-qtnetworkauth.webxml
+examples-qtscxml.webxml
+examples-qtuitools.webxml
+examples-richtext.webxml
+examples-widgets-opengl.webxml
+examples-widgets.webxml
+focus.webxml
+gallery.webxml
+genericbackend.webxml
+gestures-overview.webxml
+graphicsview.webxml
+gui-changes-qt6.webxml
+helpsystem.webxml
+implicit-sharing.webxml
+io-functions.webxml
+io.webxml
+java-style-iterators.webxml
+json.webxml
+layout.webxml
+mainwindow.webxml
+metaobjects.webxml
+model-view-programming.webxml
+modelview.webxml
+multimedia-examples.webxml
+multimediaoverview.webxml
+network-changes-qt6.webxml
+network.webxml
+nfc-android.webxml
+nfc-examples.webxml
+object.webxml
+objecttrees.webxml
+opengl-changes-qt6.webxml
+painting-3d.webxml
+painting.webxml
+paintsystem-devices.webxml
+paintsystem-drawing.webxml
+paintsystem-images.webxml
+paintsystem.webxml
+plugins.webxml
+position-plugin-geoclue2.webxml
+position-plugin-gypsy.webxml
+position-plugin-nmea.webxml
+positioning-cpp-qml.webxml
+printing.webxml
+printsupport-changes-qt6.webxml
+properties.webxml
+qabstracteventdispatcher-timerinfo.webxml
+qabstracttextdocumentlayout-paintcontext.webxml
+qabstracttextdocumentlayout-selection.webxml
+qaccessible-state.webxml
+qadoptshareddatatag.webxml
+qcborerror.webxml
+qcborparsererror.webxml
+qcborstreamreader-stringresult.webxml
+qdbusdeclaringsignals.webxml
+qdbusdeclaringslots.webxml
+qdbustypesystem.webxml
+qdbusviewer.webxml
+qdbusxml2cpp.webxml
+qdrawutil-h.webxml
+qdtlsclientverifier-generatorparameters.webxml
+qformlayout-takerowresult.webxml
+qglobalstatic.webxml
+qhashseed.webxml
+qhelplink.webxml
+qiconengine-scaledpixmapargument.webxml
+qiterator.webxml
+qjsonparseerror.webxml
+qmediatimerange-interval.webxml
+qml-advtutorial.webxml
+qml-changes-qt6.webxml
+qml-dynamicview-tutorial.webxml
+qml-tutorial.webxml
+qml-tutorial1.webxml
+qml-tutorial2.webxml
+qml-tutorial3.webxml
+qmldiskcache.webxml
+qmlreference.webxml
+qndeffilter-record.webxml
+qoutputrange.webxml
+qpageranges-range.webxml
+qprocess-createprocessarguments.webxml
+qqmlcontext-propertypair.webxml
+qquickitem-itemchangedata.webxml
+qscxmlc.webxml
+qsggeometry-attribute.webxml
+qsggeometry-coloredpoint2d.webxml
+qsggeometry-point2d.webxml
+qsggeometry-texturedpoint2d.webxml
+qsgmaterialshader-graphicspipelinestate.webxml
+qsgmaterialtype.webxml
+qstaticplugin.webxml
+qt3d-basicshapes-cpp-example.webxml
+qt3d-changes-qt6.webxml
+qt3d-cpp.webxml
+qt3d-examples.webxml
+qt3d-multiviewport-example.webxml
+qt3d-overview.webxml
+qt3d-pbr-materials-example.webxml
+qt3d-qml.webxml
+qt3d-simple-qml-example.webxml
+qt3d-simplecustommaterial-example.webxml
+qt3d-wireframe-example.webxml
+qt3drender-framegraph.webxml
+qt3drender-geometry.webxml
+qt3drender-porting-to-rhi.webxml
+qt3drender-protips.webxml
+qtalgorithms.webxml
+qtbluetooth-btchat-example.webxml
+qtbluetooth-changes-qt6.webxml
+qtbluetooth-le-overview.webxml
+qtbluetooth-lowenergyscanner-example.webxml
+qtbluetooth-overview.webxml
+qtcborcommon.webxml
+qtcharts-barmodelmapper-example.webxml
+qtcharts-boxplotchart-example.webxml
+qtcharts-candlestickchart-example.webxml
+qtcharts-changes-qt6.webxml
+qtcharts-customchart-example.webxml
+qtcharts-datetimeaxis-example.webxml
+qtcharts-examples.webxml
+qtcharts-horizontalbarchart-example.webxml
+qtcharts-horizontalpercentbarchart-example.webxml
+qtcharts-horizontalstackedbarchart-example.webxml
+qtcharts-legendmarkers-example.webxml
+qtcharts-multiaxis-example.webxml
+qtcharts-openglseries-example.webxml
+qtcharts-overview.webxml
+qtcharts-pointsselectionandmarkers-example.webxml
+qtcharts-polarchart-example.webxml
+qtcharts-qmlaxes-example.webxml
+qtcharts-qmlcustomizations-example.webxml
+qtcharts-qmlcustomlegend-example.webxml
+qtcharts-qmlf1legends-example.webxml
+qtcharts-qmloscilloscope-example.webxml
+qtcharts-qmlweather-example.webxml
+qtcharts-scatterchart-example.webxml
+qtcharts-selectedbar-example.webxml
+qtcharts-splinechart-example.webxml
+qtcharts-stackedbarchart-example.webxml
+qtcharts-zoomlinechart-example.webxml
+qtconcurrent-imagescaling-example.webxml
+qtconcurrent-wordcount-example.webxml
+qtconcurrentfilter.webxml
+qtconcurrentmap.webxml
+qtconcurrentrun.webxml
+qtconcurrenttask.webxml
+qtcore-changes-qt6.webxml
+qtcore-ipc-localfortuneclient-example.webxml
+qtcore-ipc-localfortuneserver-example.webxml
+qtcore-platform-androidnotifier-example.webxml
+qtcore-serialization-savegame-example.webxml
+qtcore-threads-queuedcustomtype-example.webxml
+qtcore-threads-semaphores-example.webxml
+qtcore-threads-waitconditions-example.webxml
+qtcore-tools-contiguouscache-example.webxml
+qtdbus-chat-example.webxml
+qtdbus-cmake-qt-add-dbus-adaptor.webxml
+qtdbus-cmake-qt-add-dbus-interface.webxml
+qtdbus-cmake-qt-add-dbus-interfaces.webxml
+qtdbus-cmake-qt-generate-dbus-interface.webxml
+qtdbus-complexpingpong-example.webxml
+qtdbus-remotecontrolledcar-example.webxml
+qtdesigner-calculatorbuilder-example.webxml
+qtdesigner-calculatorform-example.webxml
+qtdesigner-components.webxml
+qtdesigner-containerextension-example.webxml
+qtdesigner-customwidgetplugin-example.webxml
+qtdesigner-manual.webxml
+qtest-overview.webxml
+qtest-tutorial.webxml
+qtextedit-extraselection.webxml
+qtextlayout-formatrange.webxml
+qtextoption-tab.webxml
+qtglobal.webxml
+qtgui-rasterwindow-example.webxml
+qthelp-contextsensitivehelp-example.webxml
+qthelp-framework.webxml
+qthelpproject.webxml
+qtilerules.webxml
+qtimezone-offsetdata.webxml
+qtjavascript.webxml
+qtmath.webxml
+qtmultimedia-apple.webxml
+qtmultimedia-changes-qt6.webxml
+qtnetwork-broadcastreceiver-example.webxml
+qtnetwork-broadcastsender-example.webxml
+qtnetwork-http-example.webxml
+qtnetwork-multicastreceiver-example.webxml
+qtnetwork-multicastsender-example.webxml
+qtnetwork-network-chat-example.webxml
+qtnetwork-programming.webxml
+qtnetwork-securesocketclient-example.webxml
+qtnetwork-secureudpclient-example.webxml
+qtnetwork-secureudpserver-example.webxml
+qtnetwork-torrent-example.webxml
+qtnfc-annotatedurl-example.webxml
+qtnfc-changes-qt6.webxml
+qtnfc-ndefeditor-example.webxml
+qtnfc-overview.webxml
+qtopengl-2dpainting-example.webxml
+qtopengl-cube-example.webxml
+qtopengl-hellogles3-example.webxml
+qtopengl-openglwindow-example.webxml
+qtplugin.webxml
+qtpositioning-android.webxml
+qtpositioning-changes-qt6.webxml
+qtpositioning-examples.webxml
+qtpositioning-ios.webxml
+qtpositioning-logfilepositionsource-example.webxml
+qtpositioning-plugins.webxml
+qtpositioning-satelliteinfo-example.webxml
+qtpositioning-weatherinfo-example.webxml
+qtqml-documents-definetypes.webxml
+qtqml-documents-networktransparency.webxml
+qtqml-documents-scope.webxml
+qtqml-documents-structure.webxml
+qtqml-documents-topic.webxml
+qtqml-dynamicscene-example.webxml
+qtqml-javascript-dynamicobjectcreation.webxml
+qtqml-javascript-expressions.webxml
+qtqml-javascript-finetuning.webxml
+qtqml-javascript-functionlist.webxml
+qtqml-javascript-hostenvironment.webxml
+qtqml-javascript-imports.webxml
+qtqml-javascript-qmlglobalobject.webxml
+qtqml-javascript-resources.webxml
+qtqml-javascript-topic.webxml
+qtqml-qml-i18n-example.webxml
+qtqml-syntax-basics.webxml
+qtqml-syntax-directoryimports.webxml
+qtqml-syntax-imports.webxml
+qtqml-syntax-objectattributes.webxml
+qtqml-syntax-propertybinding.webxml
+qtqml-tutorials-extending-qml-example.webxml
+qtqml-typesystem-basictypes.webxml
+qtqml-typesystem-objecttypes.webxml
+qtqml-typesystem-topic.webxml
+qtquick-animation-example.webxml
+qtquick-bestpractices.webxml
+qtquick-canvas-example.webxml
+qtquick-codesamples.webxml
+qtquick-convenience-topic.webxml
+qtquick-cppextensionpoints.webxml
+qtquick-customitems-dialcontrol-example.webxml
+qtquick-customitems-flipable-example.webxml
+qtquick-customitems-painteditem-example.webxml
+qtquick-draganddrop-example.webxml
+qtquick-effects-particles.webxml
+qtquick-effects-sprites.webxml
+qtquick-effects-topic.webxml
+qtquick-effects-transformations.webxml
+qtquick-imageelements-example.webxml
+qtquick-imageprovider-example.webxml
+qtquick-imageresponseprovider-example.webxml
+qtquick-input-focus.webxml
+qtquick-input-mouseevents.webxml
+qtquick-input-textinput.webxml
+qtquick-input-topic.webxml
+qtquick-keyinteraction-example.webxml
+qtquick-layouts-example.webxml
+qtquick-localstorage-example.webxml
+qtquick-models-abstractitemmodel-example.webxml
+qtquick-modelviewsdata-cppmodels.webxml
+qtquick-modelviewsdata-modelview.webxml
+qtquick-modelviewsdata-topic.webxml
+qtquick-mousearea-example.webxml
+qtquick-particles-affectors-example.webxml
+qtquick-particles-emitters-example.webxml
+qtquick-particles-imageparticle-example.webxml
+qtquick-particles-performance.webxml
+qtquick-particles-system-example.webxml
+qtquick-positioners-example.webxml
+qtquick-positioning-anchors.webxml
+qtquick-positioning-layouts.webxml
+qtquick-positioning-righttoleft.webxml
+qtquick-positioning-topic.webxml
+qtquick-quick-accessibility-example.webxml
+qtquick-quickwidgets-quickwidget-example.webxml
+qtquick-scenegraph-custommaterial-example.webxml
+qtquick-scenegraph-d3d11underqml-example.webxml
+qtquick-scenegraph-graph-example.webxml
+qtquick-scenegraph-materials.webxml
+qtquick-scenegraph-metaltextureimport-example.webxml
+qtquick-scenegraph-metalunderqml-example.webxml
+qtquick-scenegraph-nodes.webxml
+qtquick-scenegraph-twotextureproviders-example.webxml
+qtquick-scenegraph-vulkantextureimport-example.webxml
+qtquick-scenegraph-vulkanunderqml-example.webxml
+qtquick-shadereffects-example.webxml
+qtquick-shapes-example.webxml
+qtquick-statesanimations-animations.webxml
+qtquick-statesanimations-behaviors.webxml
+qtquick-statesanimations-states.webxml
+qtquick-statesanimations-topic.webxml
+qtquick-tableview-gameoflife-example.webxml
+qtquick-tableview-pixelator-example.webxml
+qtquick-text-example.webxml
+qtquick-tool-qmllint.webxml
+qtquick-tools-and-utilities.webxml
+qtquick-tutorials-dynamicview-dynamicview1-example.webxml
+qtquick-tutorials-dynamicview-dynamicview2-example.webxml
+qtquick-tutorials-dynamicview-dynamicview3-example.webxml
+qtquick-tutorials-dynamicview-dynamicview4-example.webxml
+qtquick-tutorials-samegame-samegame1-example.webxml
+qtquick-tutorials-samegame-samegame2-example.webxml
+qtquick-tutorials-samegame-samegame3-example.webxml
+qtquick-tutorials-samegame-samegame4-example.webxml
+qtquick-views-example.webxml
+qtquick-visualcanvas-adaptations-openvg.webxml
+qtquick-visualcanvas-adaptations-software.webxml
+qtquick-visualcanvas-adaptations.webxml
+qtquick-visualcanvas-coordinates.webxml
+qtquick-visualcanvas-scenegraph-renderer.webxml
+qtquick-visualcanvas-scenegraph.webxml
+qtquick-visualcanvas-topic.webxml
+qtquick-visualcanvas-visualparent.webxml
+qtquick-visualtypes-topic.webxml
+qtquickcontrols-changes-qt6.webxml
+qtquickcontrols-chattutorial-example.webxml
+qtquickcontrols-contactlist-example.webxml
+qtquickcontrols-eventcalendar-example.webxml
+qtquickcontrols-flatstyle-example.webxml
+qtquickcontrols-imagine-automotive-example.webxml
+qtquickcontrols-texteditor-example.webxml
+qtquickcontrols-wearable-example.webxml
+qtquickcontrols-basic.webxml
+qtquickcontrols-buttons.webxml
+qtquickcontrols-configuration.webxml
+qtquickcontrols-containers.webxml
+qtquickcontrols-customize.webxml
+qtquickcontrols-delegates.webxml
+qtquickcontrols-deployment.webxml
+qtquickcontrols-environment.webxml
+qtquickcontrols-examples.webxml
+qtquickcontrols-fileselectors.webxml
+qtquickcontrols-focus.webxml
+qtquickcontrols-fusion.webxml
+qtquickcontrols-gettingstarted.webxml
+qtquickcontrols-guidelines.webxml
+qtquickcontrols-icons.webxml
+qtquickcontrols-imagine.webxml
+qtquickcontrols-indicators.webxml
+qtquickcontrols-input.webxml
+qtquickcontrols-macos.webxml
+qtquickcontrols-material.webxml
+qtquickcontrols-menus.webxml
+qtquickcontrols-navigation.webxml
+qtquickcontrols-popups.webxml
+qtquickcontrols-separators.webxml
+qtquickcontrols-styles.webxml
+qtquickcontrols-universal.webxml
+qtquickcontrols-windows.webxml
+qtquicklayouts-overview.webxml
+qtremoteobjects-cmake-qt-add-repc-merged.webxml
+qtremoteobjects-cmake-qt-add-repc-replicas.webxml
+qtremoteobjects-cmake-qt-add-repc-sources.webxml
+qtremoteobjects-cmake-qt-rep-from-headers.webxml
+qtremoteobjects-compatibility.webxml
+qtremoteobjects-custom-transport.webxml
+qtremoteobjects-external-schemas.webxml
+qtremoteobjects-gettingstarted.webxml
+qtremoteobjects-interaction.webxml
+qtremoteobjects-node.webxml
+qtremoteobjects-registry.webxml
+qtremoteobjects-repc.webxml
+qtremoteobjects-replica.webxml
+qtremoteobjects-source.webxml
+qtremoteobjects-ssl-example.webxml
+qtremoteobjects-troubleshooting.webxml
+qtremoteobjects-websockets-example.webxml
+qtscxml-changes-qt6.webxml
+qtscxml-cmake-qt-add-statecharts.webxml
+qtscxml-ftpclient-example.webxml
+qtscxml-instantiating-state-machines.webxml
+qtscxml-overview.webxml
+qtscxml-scxml-compliance.webxml
+qtscxml-sudoku-example.webxml
+qtscxml-trafficlight-qml-dynamic-example.webxml
+qtscxml-trafficlight-qml-simple-example.webxml
+qtscxml-trafficlight-qml-static-example.webxml
+qtscxml-trafficlight-widgets-dynamic-example.webxml
+qtscxml-trafficlight-widgets-static-example.webxml
+qtsensors-changes-qt6.webxml
+qtsensors-cpp.webxml
+qtsensors-examples.webxml
+qtsensors-sensorsshowcase-example.webxml
+qtserialport-blockingreceiver-example.webxml
+qtserialport-blockingsender-example.webxml
+qtserialport-changes-qt6.webxml
+qtserialport-examples.webxml
+qtserialport-terminal-example.webxml
+qtsql-cachedtable-example.webxml
+qtsql-changes-qt6.webxml
+qtsql-drilldown-example.webxml
+qtsql-masterdetail-example.webxml
+qtsql-querymodel-example.webxml
+qtsql-sqlbrowser-example.webxml
+qtsql-sqlwidgetmapper-example.webxml
+qtsql-tablemodel-example.webxml
+qtsvg-changes-qt6.webxml
+qttest-best-practices-qdoc.webxml
+qttestlib-tutorial1-example.webxml
+qttestlib-tutorial2-example.webxml
+qttestlib-tutorial3-example.webxml
+qttestlib-tutorial4-example.webxml
+qttestlib-tutorial5-example.webxml
+qttestlib-tutorial6.webxml
+qtuitools-textfinder-example.webxml
+qtwebchannel-changes-qt6.webxml
+qtwebchannel-chatclient-html-example.webxml
+qtwebchannel-chatclient-qml-example.webxml
+qtwebchannel-chatserver-cpp-example.webxml
+qtwebchannel-examples.webxml
+qtwebchannel-javascript.webxml
+qtwebengine-changes-qt6.webxml
+qtwebengine-features.webxml
+qtwebengine-overview.webxml
+qtwebengine-platform-notes.webxml
+qtwebengine-webenginequick-lifecycle-example.webxml
+qtwebengine-webenginewidgets-contentmanipulation-example.webxml
+qtwebengine-webenginewidgets-cookiebrowser-example.webxml
+qtwebengine-webenginewidgets-html2pdf-example.webxml
+qtwebengine-webenginewidgets-maps-example.webxml
+qtwebengine-webenginewidgets-printme-example.webxml
+qtwebengine-webenginewidgets-spellchecker-example.webxml
+qtwebengine-webenginewidgets-videoplayer-example.webxml
+qtwebenginewidgets-qtwebkitportingguide.webxml
+qtwebsockets-changes-qt6.webxml
+qtwebsockets-echoclient-example.webxml
+qtwebsockets-echoserver-example.webxml
+qtwebsockets-examples.webxml
+qtwebsockets-qmlwebsocketclient-example.webxml
+qtwebsockets-qmlwebsocketserver-example.webxml
+qtwebsockets-simplechat-example.webxml
+qtwebsockets-sslechoclient-example.webxml
+qtwebsockets-sslechoserver-example.webxml
+qtwebsockets-testing.webxml
+qtwidgets-gestures-imagegestures-example.webxml
+qtwidgets-graphicsview-basicgraphicslayouts-example.webxml
+qtwidgets-graphicsview-chip-example.webxml
+qtwidgets-graphicsview-simpleanchorlayout-example.webxml
+qtwidgets-itemviews-coloreditorfactory-example.webxml
+qtwidgets-itemviews-combowidgetmapper-example.webxml
+qtwidgets-itemviews-customsortfiltermodel-example.webxml
+qtwidgets-itemviews-frozencolumn-example.webxml
+qtwidgets-itemviews-simpletreemodel-example.webxml
+qtwidgets-mainwindows-menus-example.webxml
+qtwidgets-painting-affine-example.webxml
+qtwidgets-painting-composition-example.webxml
+qtwidgets-painting-deform-example.webxml
+qtwidgets-painting-gradients-example.webxml
+qtwidgets-painting-imagecomposition-example.webxml
+qtwidgets-painting-painterpaths-example.webxml
+qtwidgets-painting-pathstroke-example.webxml
+qtwidgets-painting-transformations-example.webxml
+qtwidgets-tools-completer-example.webxml
+qtwidgets-tools-customcompleter-example.webxml
+qtwidgets-tools-echoplugin-example.webxml
+qtwidgets-tools-settingseditor-example.webxml
+qtwidgets-tools-styleplugin-example.webxml
+qtwidgets-tools-treemodelcompleter-example.webxml
+qtwidgets-tools-undoframework-example.webxml
+qtwidgets-touch-knobs-example.webxml
+qtwidgets-tutorials-notepad-example.webxml
+qtwidgets-tutorials-widgets-childwidget-example.webxml
+qtwidgets-tutorials-widgets-nestedlayouts-example.webxml
+qtwidgets-tutorials-widgets-toplevel-example.webxml
+qtwidgets-tutorials-widgets-windowlayout-example.webxml
+qtwidgets-widgets-analogclock-example.webxml
+qtwidgets-widgets-calculator-example.webxml
+qtwidgets-widgets-calendarwidget-example.webxml
+qtwidgets-widgets-groupbox-example.webxml
+qtwidgets-widgets-lineedits-example.webxml
+qtwidgets-widgets-scribble-example.webxml
+qtwidgets-widgets-shapedclock-example.webxml
+qtwidgets-widgets-sliders-example.webxml
+qtwidgets-widgets-spinboxes-example.webxml
+qtwidgets-widgets-tablet-example.webxml
+qtwidgets-widgets-windowflags-example.webxml
+quick-changes-qt6.webxml
+qwebenginecookiestore-filterrequest.webxml
+qwidget-styling.webxml
+remoteobjects-changes-qt6.webxml
+remoteobjects-example-dynamic-replica.webxml
+remoteobjects-example-registry.webxml
+remoteobjects-example-static-source.webxml
+resources.webxml
+richtext-advanced-processing.webxml
+richtext-common-tasks.webxml
+richtext-cursor.webxml
+richtext-html-subset.webxml
+richtext-layouts.webxml
+richtext-processing.webxml
+richtext-structure.webxml
+richtext.webxml
+senorfwbackend.webxml
+sensors-backend-topics.webxml
+shared.webxml
+signalsandslots.webxml
+sql-connecting.webxml
+sql-driver.webxml
+sql-forms.webxml
+sql-model.webxml
+sql-presenting.webxml
+sql-programming.webxml
+sql-sqlstatements.webxml
+sql-types.webxml
+ssl.webxml
+standard-dialogs.webxml
+style-reference.webxml
+stylesheet-customizing.webxml
+stylesheet-designer.webxml
+stylesheet-examples.webxml
+stylesheet-reference.webxml
+stylesheet-syntax.webxml
+stylesheet.webxml
+svgrendering.webxml
+testlib-changes-qt6.webxml
+timers.webxml
+usingadaptors.webxml
+videooverview.webxml
+webengine-examples.webxml
+webengine-widgetexamples.webxml
+websockets-overview.webxml
+widget-classes.webxml
+widgets-changes-qt6.webxml
+widgets-tutorial.webxml
+xml-changes-qt6.webxml
+xml-dom-tml.webxml
+xml-namespaces.webxml
+xml-processing.webxml
+xml-streaming.webxml
+xml-tools.webxml
+# qtdoc repository
+accessible.webxml
+appicon.webxml
+create-your-first-applications.webxml
+deployment.webxml
+desktop-integration.webxml
+exceptionsafety.webxml
+explore-qt.webxml
+get-and-install-qt.webxml
+gettingstarted.webxml
+highdpi.webxml
+install-qt-design-studio.webxml
+ipc.webxml
+known-issues.webxml
+overviews-main.webxml
+plugins-howto.webxml
+qml-codingconventions.webxml
+qml-glossary.webxml
+qmlapplications.webxml
+qmlfirststeps.webxml
+qt-intro.webxml
+qtquick-debugging.webxml
+qtquick-performance.webxml
+qtquick-qml-runtime.webxml
+qtquick-usecase-animations.webxml
+qtquick-usecase-integratingjs.webxml
+qtquick-usecase-layouts.webxml
+qtquick-usecase-styling.webxml
+qtquick-usecase-text.webxml
+qtquick-usecase-userinput.webxml
+qtquick-usecase-visual.webxml
+qundo.webxml
+rcc.webxml
+restoring-geometry.webxml
+scalability.webxml
+session.webxml
+sharedlibrary.webxml
+solutions-for-application-development.webxml
+solutions-for-ui-design.webxml
+thread-basics.webxml
+threads.webxml
+tools-for-qt-quick-uis.webxml
+tools-for-qt-widget-based-uis.webxml
+topics-app-development.webxml
+topics-data-io.webxml
+topics-ui.webxml
+uic.webxml
+unicode.webxml
+wayland-and-qt.webxml
diff --git a/sources/pyside6/doc/api.rst b/sources/pyside6/doc/api.rst
new file mode 100644
index 000000000..7bbe2ce1c
--- /dev/null
+++ b/sources/pyside6/doc/api.rst
@@ -0,0 +1,59 @@
+.. _pyside-api:
+
+Modules API
+===========
+
+Basic modules
+-------------
+
+These are the main modules that help you build a Widget-based UI.
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: :mod:`QtCore <PySide6.QtCore>`
+
+ Provides core non-GUI functionality, like signal and slots, properties,
+ base classes of item models, serialization, and more.
+
+ .. grid-item-card:: :mod:`QtGui <PySide6.QtGui>`
+
+ Extends QtCore with GUI functionality: Events, windows and screens,
+ OpenGL and raster-based 2D painting, as well as images.
+
+ .. grid-item-card:: :mod:`QtWidgets <PySide6.QtWidgets>`
+
+ Provides ready to use Widgets for your application, including graphical
+ elements for your UI.
+
+QML and Qt Quick
+----------------
+
+Use these modules to interact with the `QML Language <https://doc.qt.io/qt-5.qmlapplications>`_,
+from Python.
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: :mod:`QtQml <PySide6.QtQml>`
+
+ The base Python API to interact with the module.
+
+ .. grid-item-card:: :mod:`QtQuick <PySide6.QtQuick>`
+
+ Provides classes to embed Qt Quick in Qt applications.
+
+ .. grid-item-card:: :mod:`QtQuickWidgets <PySide6.QtQuickWidgets>`
+
+ Provides the QQuickWidget class to embed Qt Quick in widget-based
+ applications.
+
+All the modules
+---------------
+
+There are many other modules currently supported by |pymodname|, here you can find a complete list
+of them.
+
+.. toctree::
+
+ modules.rst
diff --git a/sources/pyside6/doc/commercial/index.rst b/sources/pyside6/doc/commercial/index.rst
new file mode 100644
index 000000000..e74419d6a
--- /dev/null
+++ b/sources/pyside6/doc/commercial/index.rst
@@ -0,0 +1,250 @@
+.. _commercial-page:
+
+Commercial Use
+==============
+
+|project| follows the same licensing that Qt has, which means that there are two
+distributions, the Community Edition (LGPLv3/GPLv3) and a Commercial Edition. For
+more information, check the `Qt Licensing`_ page.
+
+As a brief description, you can get the commercial |project| packages by having
+any of the following licenses:
+
+#. Qt for Application Development Professional (ADP)
+#. Qt for Application Development Enterprise (ADE)
+#. Qt for Device Creation Professional (DCP)
+#. Qt for Device Creation Enterprise (DCE)
+
+The only difference is that the ADP license **does not** include the extra
+``Qt OPC UA``, ``Qt MQTT`` and ``Qt CoAP`` modules, which are distributed in
+a special Python wheel.
+
+|project| follows the same approach as Qt, meaning that commercial
+users will have access to both our commercial packages for any
+given version, or the special commercial LTS releases.
+
+Commercial users **should not** install the Community Edition distribution via ``pip
+install pyside6`` to avoid licensing problems, and should refer to the
+packages that can be acquired from the `Qt Account`_, the Qt Installer, or
+via the `qtpip` tool.
+
+Installation
+------------
+
+We understand that the installation of the commercial wheels will depend
+on your use cases. For this, we currently offer three
+ways to install a commercial Qt for Python release: a command line tool,
+using the Maintenance Tool, or downloading packages by hand.
+
+qtpip - a commercial wheel installer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+`qtpip`_ is a wrapper around `pip`_ (the package installer for Python) that provides an
+integration with the detection of commercial licenses.
+
+To set up the tool, we recommend creating a virtual environment for your
+project, and then installing the tool like any other module:
+
+.. code-block:: bash
+
+ # Create and activate a virtual environment first
+ # then install 'qtpip'
+ pip install qtpip
+
+ # Now install pyside6 (or any of the Qt for Python packages)
+ qtpip install pyside6
+
+Besides the ``install`` command, you can also ``uninstall`` (like in pip) but
+you can also perform a `fulluninstall`` to fully remove all the Qt for Python
+packages. You can find more information running ``qtpip -h``::
+
+ $ qtpip -h
+ Usage: qtpip [options] install <package> fulluninstall <PySide6/shiboken6/all>
+ Qt wrapper around pip.
+ These arguments override pip's. For more, refer to pip --help
+
+ Options:
+ -f, --force Force installation if OSS wheels were already
+ installed.
+ --no-input Disable prompting for input.
+ --no-cache-dir Disable the cache.
+ --disable-pip-version-check Don't periodically check PyPI to determine
+ whether a new version of pip is available for
+ download.
+ --no-color Suppress colored output.
+ --user Install to the Python user install directory for
+ your platform.
+ --force-reinstall Reinstall all packages even if they are already
+ up-to-date.
+ -h, --help Displays help on commandline options.
+ --help-all Displays help, including generic Qt options.
+ -v, --version Displays version information.
+
+ Arguments:
+ install Installs a package, this can be any of PySide6,
+ PySide6-Essentials, PySide6-Addons, shiboken6 or
+ shiboken6-generator for the respective commercial
+ wheel, or any other wheel from PyPi.
+ fulluninstall Fully uninstalls all packages related to
+ PySide6, shiboken6, or both.
+
+.. note:: The release cycle of ``qtpip`` will be independent from the Qt for
+ Python one.
+
+
+Maintenance Tool
+^^^^^^^^^^^^^^^^
+
+As a commercial user, you are able to download the commercial set of wheels
+from the `Qt Maintenance Tool`_. The same versions that are available for
+Qt/C++ are available for the Python bindings.
+
+The wheels will be downloaded, but not installed, mainly because they should
+be installed into a virtual environment rather than the default interpreter.
+A ``requirements.txt`` file will be provided alongside the wheels, in order to
+simplify the installation step::
+
+ pip install -r /path/to/Qt/QtForPython/6.6.0/requirements.txt
+
+Complementary to the wheels, you will be able to download the sources
+as well.
+
+.. note:: Wheels installed this way will be detectable by `*Qt Creator*`_, which
+ will offer you to install them for your current Python interpreter.
+
+Using account.qt.io
+^^^^^^^^^^^^^^^^^^^
+
+Head to your `Qt Account`_ page, and select the **Download** option on the side
+menu. You will find an option to select |project| from the **Products**
+section:
+
+.. image:: products.png
+ :alt: Products screenshot
+ :align: center
+
+There are two options that will list a different set of packages:
+
+* **Qt for Python Commercial wheels** which are the non-LTS releases under
+ commercial licensing, and include commercial only features and tools.
+ Additionally, here is where you can find the *Qt for automation (M2M
+ Protocols)* packages.
+
+* **Qt for Python (Commercial LTS)** where you will find the 5.15.x LTS and 6.2.x
+ LTS releases.
+
+Once you select any of those, you will be able to select the version of the
+packages you want to download for the **Qt for Python Commercial wheels** packages:
+
+.. image:: versions_commercial.png
+ :alt: Commercial versions screenshot
+ :align: center
+
+and the **Qt for Python (Commercial LTS)** packages:
+
+.. image:: versions_lts.png
+ :alt: LTS versions screenshot
+ :align: center
+
+For any of the versions, you can download many packages depending on your
+Operating System (macOS, Windows, or Linux). To learn more about what the
+packages contain, please check the :ref:`package_details` page.
+
+Once you download the packages, you are encouraged to create a Python virtual
+environment to install them - check the ref:`quick-start` page for how to do
+it.
+With your activated environment on a terminal, run the following command (for
+macOS/Linux)::
+
+ pip install *.whl
+
+to install them all, and leave ``pip`` to resolve the dependencies among the
+packages, or for Windows do it by hand selecting the proper combination::
+
+ pip install shiboken6-... PySide6_Essentials-... PySide6-Addons... ...
+
+Alternatively for Windows, you can specify the following command which includes
+the version, and assumes that you are running it on the same directory where
+the wheels are::
+
+ pip install --no-index --find-links=. PySide6==6.4.0.commercial
+
+.. note:: As described in the :ref:`package_details` page, the dependency
+ of the packages requires you to first install the ``shiboken6``
+ package, and then ``shiboken6-generator`` in case you are interested
+ on binding generation; or ``PySide6_Essentials`` in case you want
+ to use the essential modules. After the Essentials, you can optionally
+ install the ``PySide6_Addons`` and ``PySide6_M2M`` depending on your
+ needs.
+
+Qt Creator Integration
+----------------------
+
+*Qt Creator* offers the option to create new |project| projects from the main
+wizard.
+
+To execute the projects, make sure that the proper *Python Interpreter* is
+selected, so *Qt Creator* can use the commercial modules you just installed.
+Go to *Edit -> Preferences* where you can find the *Python* option
+that will show the following:
+
+.. image:: qtcreator_python.png
+ :alt: Qt Creator Python options
+ :align: center
+
+you can add, remove and modify environments. To include a new one, make sure to
+select the main Python executable from your environment. This can be found on
+``path_to_your_env/bin/python`` (macOS and Linux), or
+``path_to_your_env\python.exe`` (Windows).
+
+As an alternative, you can launch *Qt Creator* from within the virtual
+environment, detecting your installation automatically.
+
+Migrating from other versions
+-----------------------------
+
+In case you have a virtual environment with the Open Source distribution, you
+need to first uninstall those packages with the ``pip uninstall <package>``
+command.
+
+To check if packages are installed, run ``pip list`` and look for
+``shiboken`` or ``PySide`` packages.
+
+We always recommend creating a new virtual environment, so in doubt it is
+better to just remove the old ones if you have previous installations. The
+nature of virtual environments is volatile by design.
+
+
+Python Workflow
+---------------
+
+The Qt framework is a C++ framework that we expose to Python with the help of
+Shiboken (binding generator), which allows us to create the PySide Python module.
+
+|project| tries to find a middle ground between how C++ and Python projects
+work, so there are many decisions that need to be made, one of them being that
+the distributing of the packages needs to follow the same Python workflow,
+which means creating Python packages (wheels) and distributing them in a way
+people can use the ``pip`` tool to install them.
+
+PyPi is the main platform to distribute Open Source packages, but when
+commercial packages are required the situation is different. Among all the
+alternatives we had, we initially decided to provide the packages (wheels) on
+the `Qt Account`_ platform, so people can download and install on demand, but
+we are investigating simple ways to improve this process.
+
+There have also been discussions regarding including |project| in the *Qt
+Maintenance Tool* but this creates a new level of complexity. The reasoning is
+that the tool would require people to select or create a Python virtual
+environment on a separate location for this to be installed. Additionally,
+the Python workflow considers virtual environments as very volatile. This means
+they get removed and created often, so reinstalling or updating the |project|
+packages will likely happen.
+
+.. _`Qt Licensing`: https://www.qt.io/licensing/
+.. _`Qt Account`: https://account.qt.io
+.. _`Qt Maintenance Tool`: https://doc.qt.io/qt-6/qt-online-installation.html
+.. _`Qt Creator`: https://www.qt.io/product/development-tools
+.. _`qtpip`: https://pypi.org/project/qtpip/
+.. _`pip`: https://pypi.org/project/pip/
+
diff --git a/sources/pyside6/doc/commercial/products.png b/sources/pyside6/doc/commercial/products.png
new file mode 100644
index 000000000..d78a29e47
--- /dev/null
+++ b/sources/pyside6/doc/commercial/products.png
Binary files differ
diff --git a/sources/pyside6/doc/commercial/qtcreator_python.png b/sources/pyside6/doc/commercial/qtcreator_python.png
new file mode 100644
index 000000000..067497657
--- /dev/null
+++ b/sources/pyside6/doc/commercial/qtcreator_python.png
Binary files differ
diff --git a/sources/pyside6/doc/commercial/versions_commercial.png b/sources/pyside6/doc/commercial/versions_commercial.png
new file mode 100644
index 000000000..00b4b875a
--- /dev/null
+++ b/sources/pyside6/doc/commercial/versions_commercial.png
Binary files differ
diff --git a/sources/pyside6/doc/commercial/versions_lts.png b/sources/pyside6/doc/commercial/versions_lts.png
new file mode 100644
index 000000000..36adaadca
--- /dev/null
+++ b/sources/pyside6/doc/commercial/versions_lts.png
Binary files differ
diff --git a/sources/pyside6/doc/conf.py.in b/sources/pyside6/doc/conf.py.in
new file mode 100644
index 000000000..e195d227f
--- /dev/null
+++ b/sources/pyside6/doc/conf.py.in
@@ -0,0 +1,244 @@
+# -*- coding: utf-8 -*-
+#
+# PySide documentation build configuration file, created by
+# sphinx-quickstart on Wed Apr 22 15:04:20 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use Path(path).resolve() to make it absolute, like shown here.
+sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@')
+sys.path.append('@pyside_BINARY_DIR@')
+if @HAS_WEBENGINE_WIDGETS@:
+ sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@/../../../examples/webenginewidgets/tabbedbrowser')
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig',
+ 'sphinx.ext.coverage', 'sphinx.ext.intersphinx', 'sphinx.ext.todo',
+ 'sphinx.ext.graphviz', 'inheritance_diagram', 'pysideinclude',
+ 'sphinx.ext.viewcode',
+ 'sphinx_design', 'sphinx_copybutton', 'myst_parser', 'sphinx_tags',
+ 'sphinx_toolbox.decorators']
+
+myst_enable_extensions = [
+ "amsmath",
+ "colon_fence",
+ "deflist",
+ "dollarmath",
+ "fieldlist",
+ "html_admonition",
+ "html_image",
+ "replacements",
+ "smartquotes",
+ "strikethrough",
+ "substitution",
+ "tasklist",
+]
+myst_heading_anchors = 6
+
+output_format='@DOC_OUTPUT_FORMAT@'
+
+def setup(app):
+ app.add_config_value('output_format','qthelp','env')
+
+rst_epilog = """
+.. |project| replace:: Qt for Python
+.. |pymodname| replace:: PySide6
+"""
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_templates']
+
+# The suffix of source filenames.
+source_suffix = {
+ '.rst': 'restructuredtext',
+ '.md': 'markdown',
+}
+
+# The encoding of source files.
+source_encoding = 'utf-8'
+
+graphviz_output_format = 'svg' # Enable URLs in inheritance diagrams
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'PySide'
+copyright = u'2024 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 (https://www.gnu.org/licenses/fdl.html) as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.'
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '@BINDING_API_VERSION@'
+# The full version, including alpha/beta/rc tags.
+release = '@BINDING_API_VERSION_FULL@'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_patterns = ['_build',
+ 'extras',
+ '**README.md']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+pygments_dark_style = "monokai"
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'furo'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+html_theme_options = {
+ # FIXME: This option is currently enable because on the 'requirements-doc.txt'
+ # We are using a fork of the theme, to include this new option.
+ # This needs to be removed once the functionality is either upstreamed,
+ # or a similar option is provided.
+ "collapse_navbar": True,
+ "dark_css_variables": {
+ "color-brand-primary": "#2cde85",
+ "color-brand-content": "#2cde85",
+ "color-admonition-title--important": "#2cde85",
+ "color-admonition-title-background--important": "#474b53",
+ "font-stack": "'Titillium Web', sans-serif",
+ },
+ "light_css_variables": {
+ "color-brand-primary": "#27138b",
+ "color-brand-content": "#27138b",
+ "color-admonition-title--important": "#27138b",
+ "font-stack": "'Titillium Web', sans-serif",
+ },
+}
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes']
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+html_title = 'Qt for Python'
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+html_logo = "@CMAKE_CURRENT_SOURCE_DIR@/_static/qtforpython.png"
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = "_static/qtforpython.ico"
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_static']
+
+html_css_files = [
+ 'css/qt_font.css',
+ 'css/qt_style.css',
+]
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = { '' : ''}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = { 'index' : 'index.html'}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+html_use_index = False
+
+# If true, the index is split into individual pages for each letter.
+html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+html_show_sourcelink = False
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+#htmlhelp_basename = 'PySideDoc'
+
+# Link to the shiboken6 sphinx project to enable linking
+# between the two projects.
+intersphinx_mapping = {'shiboken6': ('shiboken6','@SHIBOKEN_INTERSPHINX_FILE@')}
+
+add_module_names = False
+
+# Skip some warnings when building the documentation with
+# 'build_base_docs' due to the lack of qdoc generated files, in charge
+# of sphinx modules (autodoc) and references.
+if @SKIP_SPHINX_WARNINGS@:
+ suppress_warnings = ["autodoc", "autodoc.import_object", "ref.ref"]
+
+# -- Options for qthelp output ---------------------------------------------------
+qthelp_theme = 'pysidedocs_qthelp'
+
+# for example tagging based on supported platforms
+tags_create_tags = True
+tags_create_badges = True
+tags_badge_colors = {
+ "Android": "info",
+}
diff --git a/sources/pyside6/doc/considerations.rst b/sources/pyside6/doc/considerations.rst
new file mode 100644
index 000000000..dda1d8b0d
--- /dev/null
+++ b/sources/pyside6/doc/considerations.rst
@@ -0,0 +1,441 @@
+.. _pysideapi2:
+
+Considerations
+==============
+
+API Changes
+-----------
+
+One of the goals of |pymodname| is to be API compatible with PyQt,
+with certain exceptions.
+
+The latest considerations and known issues will be also reported
+in the :ref:`developer-notes`.
+
+__hash__() function return value
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The hash value returned for the classes :class:`PySide6.QtCore.QDate`,
+:class:`PySide6.QtCore.QDateTime`, :class:`PySide6.QtCore.QTime`, :class:`PySide6.QtCore.QUrl`
+will be based on their string representations, thus objects with the same value will produce the
+same hash.
+
+
+QString
+~~~~~~~
+
+Methods and functions that change the contents of a QString argument were modified to receive an
+immutable Python Unicode (or str) and return another Python Unicode/str as the modified string.
+
+The following methods had their return types modified this way:
+
+**Classes:** QAbstractSpinBox, QDateTimeEdit, QDoubleSpinBox, QSpinBox, QValidator
+
+* ``fixup(string): string``
+* ``validate(string, int): [QValidator.State, string, int]``
+
+**Classes:** QDoubleValidator, QIntValidator, QRegExpValidator
+
+* ``validate(string, int): [QValidator.State, string, int]``
+
+**Class:** QClipboard
+
+* ``text(string, QClipboard.Mode mode=QClipboard.Clipboard): [string, string]``
+
+**Class:** QFileDialog
+
+Instead of ``getOpenFileNameAndFilter()``, ``getOpenFileNamesAndFilter()`` and
+``getSaveFileNameAndFilter()`` like PyQt does, PySide has modified the original methods to return
+a tuple.
+
+* ``getOpenFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [string, filter]``
+* ``getOpenFileNames(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [list(string), filter]``
+* ``getSaveFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [string, filter]``
+
+**Class:** QWebPage
+
+* ``javaScriptPrompt(QWebFrame, string, string): [bool, string]``
+
+**Classes:** QFontMetrics and QFontMetricsF
+
+They had two new methods added. Both take a string of one character and convert to a QChar
+(to call the C++ counterpart):
+
+* ``widthChar(string)``
+* ``boundingRectChar(string)``
+
+
+QTextStream
+~~~~~~~~~~~
+
+Inside this class some renames were applied to avoid clashes with native Python functions.
+They are: ``bin_()``, ``hex_()`` and ``oct_()``.
+The only modification was the addition of the '_' character.
+
+
+QVariant
+~~~~~~~~
+
+As ``QVariant`` was removed, any function expecting it can receive any Python object (``None`` is
+an invalid ``QVariant``).
+The same rule is valid when returning something: the returned ``QVariant`` will be converted to
+its original Python object type.
+
+When a method expects a ``QVariant::Type`` the programmer can use a string (the type name) or the
+type itself.
+
+
+qApp "macro"
+~~~~~~~~~~~~
+
+The C++ API of QtWidgets provides a macro called ``qApp`` that roughly expands to
+``QtWidgets::QApplication->instance()``.
+
+In PySide, we tried to create a macro-like experience.
+For that, the ``qApp`` variable was implemented as a normal variable
+that lives in the builtins.
+After importing ``PySide6``, you can immediately use ``qApp``.
+
+As a useful shortcut for the action "create an application if it was not created", we recommend::
+
+ qApp or QtWidgets.QApplication()
+
+or if you want to check if there is one, simply use the truth value::
+
+ if qApp:
+ # do something if an application was created
+ pass
+
+Comparing to ``None`` is also possible, but slightly over-specified.
+
+
+Testing support
++++++++++++++++
+
+For testing purposes, you can also get rid of the application by calling::
+
+ qApp.shutdown()
+
+As for 5.14.2, this is currently an experimental feature that is not fully tested.
+
+
+Embedding status
+++++++++++++++++
+
+In embedded mode, application objects that are pre-created in C++ don't have a Python wrapper.
+The ``qApp`` variable is created together with a wrapped application.
+Therefore, ``qApp`` does not exist in that embedded mode.
+Please note that you always can use ``QtWidgets.QApplication.instance()`` instead.
+
+
+Abandoned Alternative
++++++++++++++++++++++
+
+We also tried an alternative implementation with a ``qApp()`` function that was more *pythonic*
+and problem free, but many people liked the ``qApp`` macro better for its brevity, so here it is.
+
+
+Rich Comparison
+~~~~~~~~~~~~~~~
+
+There was a long-standing bug in the ``tp_richcompare`` implementation of PySide classes.
+
+* When a class did not implement it, the default implementation of ``object`` is used.
+ This implements ``==`` and ``!=`` like the ``is`` operator.
+
+* When a class implements only a single function like ``<``, then the default implementation
+ was disabled, and expressions like ``obj in sequence`` failed with ``NotImplemented``.
+
+This oversight was fixed in version 5.15.1 .
+
+
+Features
+--------
+
+In |project|, we begin for the first time to support a more pythonic user interface.
+With a special import statement, you can switch on features which replace certain aspects of
+the Python interpreter. This is done by an import statement right after the PySide6 import.
+
+snake_case
+~~~~~~~~~~
+
+With the statement:
+
+.. code-block:: python
+
+ from __feature__ import snake_case
+
+all methods in the current module are switched from ``camelCase`` to ``snake_case``.
+A single upper case letter is replaced by an underscore and the lower case letter.
+
+true_property
+~~~~~~~~~~~~~
+
+With the statement:
+
+.. code-block:: python
+
+ from __feature__ import true_property
+
+all getter and setter functions which are marked as a property in the Qt6 docs
+are replaced by Python property objects. Properties are also listed as such
+in the according QMetaObject of a class.
+
+Example for both features
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some |project| snippet might read:
+
+.. code-block:: python
+
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+With the above features selected, this reads:
+
+.. code-block:: python
+
+ self.table.horizontal_header().section_resize_mode = QHeaderView.Stretch
+
+Additionally, properties can also be declared directly in Shiboken for
+non Qt-libraries, see :ref:`property-declare`.
+
+More about features
+~~~~~~~~~~~~~~~~~~~
+
+Detailed info about features can be found here: :ref:`feature-why`
+
+Tools
+~~~~~
+
+|project| ships some Qt tools:
+
+* ``pyside6-rcc``: Qt Resource Compiler. This is a command line tool
+ that compiles ``.qrc`` files containing binary data, for example images,
+ into executable Python code (see :ref:`using_qrc_files`).
+* ``pyside6-uic``: Qt User Interface Compiler. This is a command line tool
+ that compiles ``.ui`` files containing designs of Qt Widget-based forms
+ into executable Python code (see :ref:`using_ui_files`).
+* ``pyside6-assistant``: Qt Help Viewer. This is a graphical tool that can
+ be used to view Qt documentation from Qt Compressed Help files (``.qhc``).
+ Currently, only the binary without documentation sets is shipped to reduce the
+ wheel size. For building the documentation, see :ref:`building_documentation`.
+* ``pyside6-designer``: Qt User Interface Designer. This is a graphical tool
+ to create designs of Qt Widget-based forms and use custom widgets
+ (see :ref:`using_ui_files`, :ref:`designer_custom_widgets`).
+
+
+.. _NewEnumSystem:
+
+The New Python Enums
+--------------------
+
+The Motivation to use new Enums
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For a long time, there were just the Shiboken enums, which were modelled as exact as possible
+after the existing enums in Qt. These enums are small classes which also inherit from
+int.
+
+Meanwhile, Python enums have been developed over the years. They have become a natural
+part of modern Python. The implementation is perfectly modelled after the needs of Python
+users. It is therefore just consequent to stop having two different enum implementations
+in the same application and instead to use the new Python implementation everywhere.
+
+
+Existing Work
+~~~~~~~~~~~~~
+
+The new enums beginning with PySide 6.3, replace the Shiboken enums
+with Python variants, which harmonize the builtin enums with the already existing
+``QEnum`` "macro" shown in the :ref:`QEnum` section.
+
+
+Enums behavior in PySide
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+In ``PySide 6.3`` there was a double implementation of old and new enums, where the
+default was old enums.
+The new approach to enum is the default in ``PySide 6.4`` and becomes mandatory
+in ``PySide 6.6``. There exists the environment variable ``PYSIDE6_OPTION_PYTHON_ENUM``
+with the default value of "1". There can also variations be selected by specifying
+different flags, but the value of "0" (switching off) is no longer supported.
+
+The still available options for switching some enum features off can be found in the
+:ref:`enum-features` section.
+
+
+The Differences between old and new Enums
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Python enums and Shiboken enums are more or less compatible with each other.
+Tiny differences are in restrictions:
+
+* Python enums cannot inherit from each other, whereas Shiboken enums can
+* Python enums don't allow undefined values, Shiboken enums do
+* Python enums always need exactly one argument, Shiboken enums have a default zero value
+* Python enums rarely inherit from int, Shiboken enums always do
+
+More visible are the differences between flags, as shown in the following:
+
+The Shiboken flag constructor example has been in PySide prior to 6.3:
+
+::
+
+ flags = Qt.Alignment()
+ enum = Qt.AlignmentFlag
+
+with enum shortcuts like
+
+::
+
+ Qt.AlignLeft = Qt.AlignmentFlag.AlignLeft
+ Qt.AlignTop = Qt.AlignmentFlag.AlignTop
+
+In PySide 6.3, these shortcuts and flags no longer exist (officially).
+Instead, Python has an enum.Flags class which is a subclass of the enum.Enum class.
+But don't be too scared, here comes the good news...
+
+
+Doing a Smooth Transition from the Old Enums
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Changing all the enum code to suddenly use the new syntax is cumbersome and error-prone,
+because such necessary changes are not easy to find.
+Therefore a ``forgiveness mode`` was developed:
+
+The ``forgiveness mode`` allows you to continue using the old constructs but translates them
+silently into the new ones. If you for example write
+
+::
+
+ flags = Qt.Alignment()
+ enum = Qt.AlignLeft
+
+ item.setForeground(QColor(Qt.green))
+
+ flags_type = QPainter.RenderHints
+ flags = QPainter.RenderHints()
+
+ chart_view.setRenderHint(QPainter.Antialiasing)
+
+you get in reality a construct that mimics the following code which is the
+recommended way of writing Flags and Enums:
+
+::
+
+ flags = Qt.AlignmentFlag(0)
+ enum = Qt.AlignmentFlag.AlignLeft
+
+ item.setForeground(QColor(Qt.GlobalColor.green))
+
+ flags_type = QPainter.RenderHint
+ flags = QPainter.RenderHint(0)
+
+ chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
+
+This has the effect that you can initially ignore the difference between old and new enums,
+as long as the new enums are properties of classes. (This does not work on global enums
+which don't have a class, see ``Limitations`` below.)
+
+
+Forgiveness Mode and Type Hints
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When you inspect for instance ``QtCore.pyi``, you will only find the new enums, although
+the old ones are still allowed. Also, line completion will only work with the new constructs
+and never propose the old ones.
+
+The reason to implement ``forgiveness mode`` this way was
+
+* to make the transition as smooth as possible, but
+* to encourage people to use the new enums whenever new code is written.
+
+So you can continue to write:
+
+::
+
+ self.text.setAlignment(Qt.AlignCenter)
+
+but this construct is used and recommended for the future:
+
+::
+
+ self.text.setAlignment(Qt.AlignmentFlag.AlignCenter)
+
+
+Limitations
+~~~~~~~~~~~
+
+The forgiveness mode works very well whenever the enum class is embedded in a normal
+PySide class. But there are a few global enums, where especially the ``QtMsgType``
+is a problem:
+
+::
+
+ t = QtMsgType.QtDebugMsg
+
+cannot be written in the shortcut form
+
+::
+
+ t = QtDebugMsg
+
+because there is no surrounding PySide class that provides the forgiving mode
+implementation. Typically, the needed changes are easily found because they often occur
+in an import statement.
+
+Permission API
+--------------
+
+The cross-platform permission APIs were introduced to Qt in version 6.5 which are currently relevant
+to platforms macOS, iOS, Android and WebAssembly. With this API, your Qt application can check and
+request permission for certain features like Camera, Microphone, Location, Bluetooth, Contacts,
+Calendar. More about permission API can be read in this `Blog post`_.
+
+When a PySide6 application that uses the permission API is run in interpreted mode, i.e.,
+``python <main_file>.py``, the code implementing the permission API *will not work*. The only way
+to make your PySide6 application using permission API work is to bundle the application. For Android,
+this means using the `pyside6-android-deploy`_ tool and for macOS, this means using the
+`pyside6-deploy`_ tool.
+
+When running in interpreted mode, you can skip over the permission check/request using the following
+*if* condition
+
+::
+
+ is_deployed = "__compiled__" in globals()
+ if not is_deployed and sys.platform == "darwin":
+ # code implementing permission check and request
+
+This can also be seen in the PySide6 `Camera example`_. * __compiled__ * is a Nuitka attribute to
+check if the application is run as a standalone application or run in interpreted mode with Python.
+
+Android
+~~~~~~~~
+
+For Android, `pyside6-android-deploy`_ takes care of identifying the necessary permissions needed by
+the application and adding those permissions to the *AndroidManifest.xml* using the
+*<uses-permission>* element.
+
+macOS
+~~~~~
+
+Since the Android platform does not automatically come bundled with a Python interpreter, it is
+evident that to make a PySide6 application run on Android you have to package the PySide6
+application. This is not the case for desktop platforms like macOS where a Python interpreter and
+its packages can be installed and run quite easily.
+
+The problem for macOS is that for the permission API to work you need a macOS bundle with an
+*Info.plist* file that lists all the permissions required using the *usage description* string for
+each permission used. When Python is run in interpreted mode, i.e., when you run Python, the Qt
+permission API fetches the *Info.plist* from the Python interpreter by default which does not
+contain the *usage description* strings for the permissions required. You can certainly modify the
+*Info.plist* of the Python framework installation to make the Qt permission API work when running
+a PySide6 application from the terminal. However, this is not recommended. Therefore, the only
+viable solution is to bundle the PySide6 application as a macOS application bundle using
+`pyside6-deploy`_. This macOS application bundle will have its own Info.plist file.
+
+.. _`Blog post`: https://www.qt.io/blog/permission-apis-in-qt-6.5
+.. _`Camera Example`: https://doc.qt.io/qtforpython-6/examples/example_multimedia_camera.html#camera-example
+.. _`pyside6-android-deploy`: https://doc.qt.io/qtforpython-6/gettingstarted/package_details.html#deployment
+.. _`pyside6-deploy`: https://doc.qt.io/qtforpython-6/gettingstarted/package_details.html#deployment
diff --git a/sources/pyside6/doc/contents.rst b/sources/pyside6/doc/contents.rst
new file mode 100644
index 000000000..4b6c7ffa9
--- /dev/null
+++ b/sources/pyside6/doc/contents.rst
@@ -0,0 +1,28 @@
+.. items for the main front page grid
+
+.. toctree::
+ :maxdepth: 2
+
+ quickstart.rst
+ commercial/index.rst
+ gettingstarted/index.rst
+ api.rst
+ tools/index.rst
+ tutorials/index.rst
+ examples/index.rst
+ videos.rst
+ deployment/index.rst
+ considerations.rst
+ developer/index.rst
+
+..
+ Intersphinx references in toctrees is not supported
+ https://github.com/sphinx-doc/sphinx/issues/1836
+..
+ shiboken6/index.rst
+
+Module Index
+============
+
+* :ref:`modindex`
+
diff --git a/sources/pyside6/doc/deployment/deployment-briefcase.rst b/sources/pyside6/doc/deployment/deployment-briefcase.rst
new file mode 100644
index 000000000..e85e618a7
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-briefcase.rst
@@ -0,0 +1,211 @@
+|project| & Briefcase
+#######################
+
+`Briefcase <https://briefcase.readthedocs.io>`_ is a packaging tool that lets
+you create a standalone package for a Python application. It supports the
+following installer formats:
+
+* ``.app`` application bundle for macOS
+* MSI installer for Windows
+* AppImage for Linux
+
+For more details, see the `official documentation
+<https://briefcase.readthedocs.io/en/latest/index.html>`_.
+
+Status of Qt 6 Support
+======================
+
+As of March 2021, Qt 6 is not supported yet.
+
+Preparation
+===========
+
+Install ``Briefcase`` using the following **pip** command::
+
+ pip install briefcase
+
+You also need : docker on linux, `WixToolset`_ on windows,
+
+If you're using a virtual environment, remember to activate it before installing ``Briefcase``.
+
+After installation, the ``briefcase`` binary is located in your virtual environment's ``bin/``
+directory, or where your Python executable is located.
+
+You can either create a brand new project using the briefcase assistant or setup your own.
+
+.. _`WixToolset`: https://wixtoolset.org/
+
+Use Briefcase Assistant
+=======================
+
+Run the following command and answer the questions to get started::
+
+ briefcase new
+
+Ensure that |pymodname| is chosen as the **GUI toolkit choice**.
+Your |pymodname| application is now configured. You can jump to `Build the package`_.
+
+
+Set up your project
+===================
+
+Create a pyproject.toml
+-----------------------
+
+At the root level of your project, create a ``pyproject.toml`` file::
+
+ [tool.briefcase]
+ project_name = "MyPySideApp"
+ bundle = "com.example"
+ version = "0.0.1"
+ url = "https://somwhere/on/the/net"
+ license = "GNU General Public License v3 (GPLv3)"
+ author = 'MyName Firstname'
+ author_email = "cool@mailexample.com"
+
+ [tool.briefcase.app.mypysideapp]
+ formal_name = "A Cool App"
+ description = "The coolest app ever"
+ icon = "src/mypysideapp/resources/appicon" # Briecase will choose the right extension depending the os (png,ico,...)
+ sources = ['src/mypysideapp']
+ requires = ['pyside6==6.0.0',
+ 'pony>=0.7.11,<0.8',
+ 'dickens==1.0.1',
+ 'Pillow==7.1.2',
+ 'mako==1.1.2',
+ 'beautifulsoup4']
+
+
+ [tool.briefcase.app.mypysideapp.macOS]
+ requires = []
+
+ [tool.briefcase.app.mypysideapp.linux]
+ requires = []
+ system_requires = []
+
+ [tool.briefcase.app.mypysideapp.windows]
+ requires = []
+
+
+Write some code
+---------------
+
+Let's say your project tree is like this::
+
+ pyproject.toml
+ setup.cfg
+ pytest.ini
+ src/
+
+ mypysideapp/
+ resources/
+ appicon.png
+ appicon.ico
+ __init__.py
+ __main__.py
+ app.py
+
+
+Content of ``__main__.py``::
+
+ import sys
+ from PySide6.QtWidgets import QApplication
+ from mypysideapp.app import MyWidget
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec())
+
+
+Content of ``app.py``::
+
+ import random
+ from PySide6.QtWidgets import (QLabel, QPushButton,
+ QVBoxLayout, QWidget)
+ from PySide6.QtCore import Slot, Qt
+
+ class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ # Connecting the signal
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+
+Build the package
+=================
+
+Initialize the package
+----------------------
+
+Just run::
+
+ briefcase create
+
+Run the following command to initialize the building the packages for Windows, Linux, and macOS.
+It creates a subdirectory each for the different platforms.
+This step takes longer as it adds the packages listed in ``requires`` sections in the
+``pyproject.toml`` file.
+
+Build the application
+---------------------
+::
+
+ briefcase build
+
+You'll get::
+
+ macOS/A Cool App/A Cool App.app
+ or
+ linux/A Cool App-x86_64-0.0.1.AppImage
+ or
+ windows\A Cool App
+
+
+Run the application
+-------------------
+::
+
+ briefcase run
+
+.. note:: You can run your project in ``dev`` mode (your source code not packaged) with
+ ``briefcase dev``
+
+
+Build the installer (only Windows and macOS)
+--------------------------------------------
+
+macOS::
+
+ briefcase package --no-sign
+
+It's possible to sign, see the
+`documentation <https://briefcase.readthedocs.io/en/latest/how-to/code-signing/index.html>`_.
+You get ``macOS/A Cool App-0.0.1.dmg``
+
+Windows::
+
+ briefcase package
+
+You get ``windows\A_Cool_App-0.0.1.msi``
diff --git a/sources/pyside6/doc/deployment/deployment-cxfreeze.rst b/sources/pyside6/doc/deployment/deployment-cxfreeze.rst
new file mode 100644
index 000000000..46cbb142e
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-cxfreeze.rst
@@ -0,0 +1,131 @@
+=====================
+|project| & cx_Freeze
+=====================
+
+`cx_Freeze <https://marcelotduarte.github.io/cx_Freeze//>`_ lets you
+freeze your Python application into executables. The supported
+platforms are Linux, macOS, Windows, FreeBSD, among others.
+
+You can read the `official documentation <https://cx-freeze.readthedocs.io/en/latest/index.html>`_
+to clarify any further question, and remember to contribute to
+the project by `filing issues
+<https://github.com/marcelotduarte/cx_Freeze/issues>`_
+if you find any, or contributing to `their development <https://github.com/marcelotduarte/cx_Freeze>`_.
+
+Preparation
+===========
+
+Installing ``cx_Freeze`` can be done using **pip**::
+
+ pip install cx_freeze
+
+If you are using a virtual environment, remember to activate it before
+installing ``cx_Freeze`` into it.
+
+After the installation, you will have the ``cxfreeze`` binary to deploy
+your application.
+
+Freezing an application
+=======================
+
+There are three options to work with ``cx_Freeze``:
+
+1. Using the ``cxfreeze`` script.
+2. Creating ``setup.py`` script to build the project.
+3. Using the module classes directly (for advanced purposes).
+
+The following sections cover the first two use cases.
+
+Creating an example
+-------------------
+
+Now, consider the following simple script, named ``hello.py``::
+
+ import sys
+ import random
+ from PySide6.QtWidgets import (QApplication, QLabel, QPushButton,
+ QVBoxLayout, QWidget)
+ from PySide6.QtCore import Slot, Qt
+
+ class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ # Connecting the signal
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec())
+
+
+Using ``cxfreeze`` executable
+-----------------------------
+
+Now that we have an application, try freezing it with the following
+command::
+
+ cxfreeze hello.py
+
+This command creates a ``dist/`` directory containing the executable.
+and a ``lib/`` directory containing all the shared libraries.
+
+To launch the application, go to the ``dist/`` directory and execute
+the file::
+
+ cd dist/
+ ./main
+
+
+Using a ``setuptools`` script
+-----------------------------
+
+For this process, you need an additional script called ``setup.py``::
+
+ import sys
+ from cx_Freeze import setup, Executable
+
+ setup(name = "MyApp",
+ version = "0.1",
+ description = "My GUI App",
+ executables = [Executable("hello.py")])
+
+Now, build the project using it::
+
+ python setup.py build
+
+This step creates a ``build/`` directory with the following structure::
+
+ build
+ └── exe.linux-x86_64-3.7
+ └── lib
+ └── main
+
+The first directory inside ``build/`` depends on the platform
+you are using, in this case a ``x86_64`` Linux using Python 3.7.
+The structure is the same as previously described, and you can simply
+enter the directory and execute the file::
+
+ cd build/exe.linux-x86_64-3.7
+ ./main
diff --git a/sources/pyside6/doc/deployment/deployment-fbs.rst b/sources/pyside6/doc/deployment/deployment-fbs.rst
new file mode 100644
index 000000000..459a225bf
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-fbs.rst
@@ -0,0 +1,97 @@
+|project| & fbs
+####################
+
+`fbs`_ provides a powerful environment for packaging, creating installers, and signing your
+application. It also lets you manage updates to your application. Since `fbs`_ is based on
+PyInstaller, it supports Linux, macOS, and Windows.
+
+For more details, see the `fbs tutorial`_ and the `fbs manual`_.
+
+.. _fbs: https://build-system.fman.io/
+.. _fbs tutorial: https://github.com/mherrmann/fbs-tutorial
+.. _fbs manual: https://build-system.fman.io/manual/
+
+Preparation
+===========
+
+Installing `fbs`_ (>= 0.7.6) is done via **pip**::
+
+ pip install fbs
+
+If you're using a virtual environment, remember to activate it before installing `fbs`_.
+
+After the installation, you can use the `fbs`_ executable.
+
+Starting a new project
+======================
+
+`fbs`_ provides useful features for you to create a base project structure with the following
+command::
+
+ fbs startproject
+
+This command prompts you to answer a few questions to configure the details of your project, like:
+
+* Application name
+* Author name
+* Qt bindings (PySide6)
+* Bundle indentified (for macOS)
+
+Afterwards, you have a ``src/`` directory that contains the following structure::
+
+ └── src
+ ├── build
+ │ └── settings
+ └── main
+ ├── icons
+ │ ├── base
+ │ ├── linux
+ │ └── mac
+ └── python
+
+Inside the ``settings`` directory, there are a few JSON files that can be edited to include more
+information about your project.
+
+The ``main`` file is in the ``python`` directory, and its default content is::
+
+ from fbs_runtime.application_context import ApplicationContext
+ from PySide6.QtWidgets import QMainWindow
+
+ import sys
+
+ if __name__ == '__main__':
+ appctxt = ApplicationContext() # 1. Instantiate ApplicationContext
+ window = QMainWindow()
+ window.resize(250, 150)
+ window.show()
+ exit_code = appctxt.app.exec() # 2. Invoke appctxt.app.exec()
+ sys.exit(exit_code)
+
+This example shows an empty ``QMainWindow``. You can run it using the following command::
+
+ fbs run
+
+Freezing the application
+========================
+
+Once you've verified that the application is working properly, you can continue with the freezing
+process using the following command::
+
+ fbs freeze
+
+After the process completes, you see a message stating the location of your executable. For
+example::
+
+ Done. You can now run `target/MyApp/MyApp`. If that doesn't work, see
+ https://build-system.fman.io/troubleshooting
+
+
+Now, you can try to run the application. The result is the same window as the one you saw with the
+``fbs run`` command::
+
+ cd target/MyApp/
+ ./MyApp
+
+.. note:: This is the case for Linux. For other platforms like macOS, you need to enter the
+ directory: ``target/MyApp.app/Contents/macOS``. For Windows, you need to find the ``MyApp.exe``
+ executable.
diff --git a/sources/pyside6/doc/deployment/deployment-nuitka.rst b/sources/pyside6/doc/deployment/deployment-nuitka.rst
new file mode 100644
index 000000000..8b0afa56c
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-nuitka.rst
@@ -0,0 +1,132 @@
+|project| & Nuitka
+##################
+
+`Nuitka <https://nuitka.net/>`_ lets you compile your python application into a
+stand-alone executable. Besides being a Python compiler which provides a fair
+acceleration, it has the side-effect of acting as an installer as well.
+Nuitka supports Linux, macOS and Windows.
+
+For more details, see the `official documentation <https://nuitka.net/pages/overview.html>`_.
+
+Preparation
+===========
+
+Install ``Nuitka`` via **pip** with the following command::
+
+ pip install nuitka
+
+After installation, the ``nuitka3`` binary is located in your virtual environment's ``bin/``
+directory, or where your Python executable is located.
+Alternatively, you can also run::
+
+ python3 -m nuitka
+
+to achieve the same effect.
+
+Freeze an application
+=====================
+
+``Nuitka`` has many options that you can use. To list them all, run ``nuitka3 -h``.
+
+To simply compile a project, you can run::
+
+ nuitka3 <programname>
+
+There are two main features:
+
+* the option to place it in a directory containing the libraries
+ (``--standalone``)
+* the option to package the whole project (including shared libraries) into one executable file
+ (``--onefile``)
+
+If you use these options, you need to specify ``--plugin-enable=pyside6``.
+
+Run an example
+--------------
+
+Now, consider the following script, named ``hello.py``::
+
+ import sys
+ import random
+ from PySide6.QtWidgets import (QApplication, QLabel, QPushButton,
+ QVBoxLayout, QWidget)
+ from PySide6.QtCore import Slot, Qt
+
+ class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ # Connecting the signal
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec())
+
+You don't have to copy this script. You find it as ``examples/installer_test/hello.py``.
+
+The command line to proceed looks like this::
+
+ nuitka3 examples/installer_test/hello.py
+
+This process creates an executable ``hello.bin`` and a directory hello.build that you
+don't need. You can execute the binary directly.
+
+In order to create a bundle which can be copied onto a machine without any pre-existing
+installation, run::
+
+ nuitka3 --standalone --plugin-enable=pyside6 examples/installer_test/hello.py
+
+This creates an application ``hello.dist/hello`` that contains everything needed to run.
+
+To run the application, go to ``hello.dist/`` and run the program::
+
+ cd hello.dist
+ ./hello
+
+Use the ``--onefile`` option if you prefer to have everything bundled into one executable, without
+the shared libraries next to it. First you need to install::
+
+ pip install zstandard
+
+for data compression. Then you can run::
+
+ nuitka3 --onefile --plugin-enable=pyside6 examples/installer_test/hello.py
+
+This process takes a bit longer, but in the end you have one executable ``hello.bin``::
+
+ ./hello.bin
+
+
+Some Caveats
+============
+
+
+Nuitka issue on macOS
+---------------------
+
+Nuitka currently has a problem with the macOS bundle files on current macOS versions.
+That has the effect that ``--standalone`` and ``--onefile`` create a crashing application.
+Older versions which don't have the recent macOS API changes from 2020 will work.
+We are currently trying to fix that problem.
diff --git a/sources/pyside6/doc/deployment/deployment-py2exe.rst b/sources/pyside6/doc/deployment/deployment-py2exe.rst
new file mode 100644
index 000000000..6ca09a826
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-py2exe.rst
@@ -0,0 +1,16 @@
+|project| & py2exe
+##################
+
+Deploying an application using py2exe requires writing a small ``setup.py`` file.
+It is explained in the `Tutorial <http://www.py2exe.org/index.cgi/Tutorial>`_.
+
+py2exe is not generally aware of Qt. It merely copies the dependent libraries
+of the application to the ``dist`` directory, so, the plugins, QML imports
+and translations of Qt are missing.
+
+The latter need to be copied manually after running py2exe.
+This can be achieved by running the ``windeployqt`` tool
+from the Qt SDK on the Qt libraries present in the ``dist`` directory,
+for example::
+
+ windeployqt dist\\Qt6Widgets.dll
diff --git a/sources/pyside6/doc/deployment/deployment-pyinstaller.rst b/sources/pyside6/doc/deployment/deployment-pyinstaller.rst
new file mode 100644
index 000000000..feb257162
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-pyinstaller.rst
@@ -0,0 +1,164 @@
+|project| & PyInstaller
+#######################
+
+`PyInstaller <https://www.pyinstaller.org/>`_ lets you freeze your python application into a
+stand-alone executable. This installer supports Linux, macOS, Windows, and more; and is also
+compatible with 3rd-party Python modules, such as |pymodname|.
+
+For more details, see the `official documentation <https://www.pyinstaller.org>`_.
+
+Status of Qt 6 Support
+======================
+
+As of March 2021, Qt 6 is not supported yet. PyInstaller is unable to properly
+deploy Qt; the Qt plugins are not copied. With that, using ``--onefile`` is not
+possible.
+
+It is possible to use PyInstaller for the non ``--onefile`` case though by
+manually copying the Qt plugins, QML imports and translations into
+the dist directory after running PyInstaller.
+
+On Windows, this can be achieved by running the ``windeployqt`` tool
+from the Qt SDK on the Qt libraries present in the ``dist`` directory, for
+example:
+
+ windeployqt dist\\app\\Qt6Widgets.dll
+
+
+Preparation
+===========
+
+Install the ``PyInstaller`` via **pip** with the following command::
+
+ pip install pyinstaller
+
+If you're using a virtual environment, remember to activate it before installing ``PyInstaller``.
+
+After installation, the ``pyinstaller`` binary is located in your virtual environment's ``bin/``
+directory, or where your Python executable is located. If that directory isn't in your ``PATH``,
+include the whole path when you run ``pyinstaller``.
+
+.. warning:: If you already have a PySide6 or Shiboken6 version installed in your
+ system path, PyInstaller uses them instead of your virtual environment version.
+
+Freeze an application
+=======================
+
+``PyInstaller`` has many options that you can use. To list them all, run ``pyinstaller -h``.
+
+There are two main features:
+
+ * the option to package the whole project (including shared libraries) into one executable file
+ (``--onefile``)
+ * the option to place it in a directory containing the libraries
+
+Additionally, on Windows when the command is running, you can open a console with the ``-c`` option
+(or ``--console`` or ``--nowindowed`` equivalent).
+
+Otherwise, you can specify to not open such a console window on macOS and Windows with the ``-w``
+option (or ``--windowed`` or ``--noconsole`` equivalent).
+
+Create an example
+-----------------
+
+Now, consider the following script, named ``hello.py``::
+
+ import sys
+ import random
+ from PySide6.QtWidgets import (QApplication, QLabel, QPushButton,
+ QVBoxLayout, QWidget)
+ from PySide6.QtCore import Slot, Qt
+
+ class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ # Connecting the signal
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec())
+
+
+Since it has a UI, you use the ``--windowed`` option.
+
+The command line to proceed looks like this::
+
+ pyinstaller --name="MyApplication" --windowed hello.py
+
+This process creates two directories: ``dist/`` and ``build/``. The application executable and the
+required shared libraries are placed in ``dist/MyApplication``.
+
+To run the application, go to ``dist/MyApplication`` and run the program::
+
+ cd dist/MyApplication/
+ ./MyApplication
+
+.. note:: The directory inside ``dist/`` and the executable have the same name.
+
+Use the ``--onefile`` option if you prefer to have everything bundled into one executable, without
+the shared libraries next to it::
+
+ pyinstaller --name="MyApplication" --windowed --onefile hello.py
+
+This process takes a bit longer, but in the end you have one executable in the
+``dist/`` directory::
+
+ cd dist/
+ ./MyApplication
+
+
+Some Caveats
+============
+
+
+PyInstaller Issue
+-----------------
+
+As mentioned before, if available, ``PyInstaller`` picks a system installation of |pymodname| or
+Shiboken6 instead of your ``virtualenv`` version without notice. This is negligible if those
+two versions are the same.
+
+If you're working with different versions, this can result in frustrating debugging sessions
+when you think you are testing the latest version, but ``PyInstaller`` is working with an older
+version.
+
+
+Safety Instructions
+-------------------
+
+- When using ``PyInstaller`` with ``virtualenv``, make sure that there is no system
+ installation of PySide6 or shiboken6.
+
+- Before compiling, use ``pip -uninstall pyside6 pyside6_essentials pyside6_addons shiboken6 -y``
+ multiple times, until none of the programs are found anymore.
+
+- Pip is usually a good tool. But to be 100 % sure, you should directly remove
+ the PySide6 and shiboken6 folders from ``site-packages``.
+
+- Be sure to use the right version of pip. The safest way to really run the right
+ pip, is to use the Python that you mean: Instead of the pip command, better use::
+
+ <path/to/your/>python -m pip
diff --git a/sources/pyside6/doc/deployment/deployment-pyside6-android-deploy.rst b/sources/pyside6/doc/deployment/deployment-pyside6-android-deploy.rst
new file mode 100644
index 000000000..53944f6ea
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-pyside6-android-deploy.rst
@@ -0,0 +1,211 @@
+.. _pyside6-android-deploy:
+
+pyside6-android-deploy: the Android deployment tool for Qt for Python
+#####################################################################
+
+``pyside6-android-deploy`` is an easy-to-use tool for deploying PySide6 applications to different
+Android architectures, namely *arm64-v8a, x86_64, x86 and armeabi-v7a*. This tool works similarly to
+the ``pyside6-deploy`` tool and uses the same configuration file ``pysidedeploy.spec`` as
+``pyside6-deploy`` to configure the deployment process. Using the deployment configuration
+options either from the command line or from ``pysidedeploy.spec``, ``pyside6-android-deploy``
+configures the deployment to be initiated and invokes `buildozer`_, a tool used for packaging Python
+applications to Android.
+
+The final output is a `.apk` or a `.aab` file created within the project's source directory. The
+`mode` option specified under the :ref:`buildozer <buildozer_key>` key in ``pysidedeploy.spec``
+determines whether a `.apk` or a `.aab` is created.
+
+.. warning:: Currently, users are required to cross-compile Qt for Python to generate the wheels
+ required for a specific Android target architecture. This requirement will disappear when
+ there are official Qt for Python Android wheels (*in progress*). Because of this
+ requirement ``pyside6-android-deploy`` will be considered in **Technical Preview**.
+ Instructions on cross-compiling Qt for Python for Android can be found
+ :ref:`here <cross_compile_android>`.
+
+.. note:: ``pyside6-android-deploy`` only works on a Linux host at the moment. This constraint
+ is also because Qt for Python cross-compilation for Android currently only works on Linux
+ systems.
+
+How to use it?
+==============
+
+Like ``pyside6-deploy``, there are :ref:`two different ways <how_pysidedeploy>` with which
+you can deploy your PySide6 application using ``pyside6-android-deploy``. The only difference is
+that for ``pyside6-android-deploy`` to work, the main Python entry point file should be named
+``main.py``.
+
+.. _pysideandroiddeploy:
+
+pysidedeploy.spec
+=================
+
+Like ``pyside6-deploy``, you can use the ``pysidedeploy.spec`` file to control the various
+parameters of the deployment process. The file has multiple sections, with each section containing
+multiple keys (parameters being controlled) assigned to a value. The advantages of such a file are
+mentioned :ref:`here <pysidedeployspec_advantages>`. The benefit of using the same
+``pysidedeploy.spec`` for both ``pyside6-deploy`` and ``pyside6-android-deploy`` is that you can
+have one single file to control deployment to all platforms.
+
+The relevant parameters for ``pyside6-android-deploy`` are:
+
+**app**
+ * ``title``: The name of the application.
+ * ``project_dir``: Project directory. The general assumption made is that the project directory
+ is the parent directory of the main Python entry point file.
+ * ``input_file``: Path to the main Python entry point file. For ``pyside6-android-deploy`` this
+ file should be named `main.py`.
+ * ``project_file``: If it exists, this points to the path to the `Qt Creator Python Project File
+ .pyproject <https://doc.qt.io/qtforpython-6/faq/typesoffiles.html
+ #qt-creator-python-project-file-pyproject>`_ file. Such a file in the project directory ensures
+ that deployment does not consider unnecessary files when bundling the executable.
+ * ``exec_directory``: The directory where the final executable is generated.
+
+**python**
+ * ``python_path``: Path to the Python executable. It is recommended to run
+ ``pyside6-android-deploy`` from a virtual environment as certain Python packages will be
+ installed onto the Python environment. However, note to keep the created virtual environment
+ outside the project directory so that ``pyside6-android-deploy`` does not try to package it
+ as well.
+ * ``android_packages``: The Python packages installed into the Python environment for deployment
+ to work. By default, the Python packages `buildozer`_ and `cpython`_ are installed.
+
+.. _qt_key:
+
+**qt**
+ * ``modules``: Comma-separated list of all the Qt modules used by the application. Just like the
+ other configuration options in ``pysidedeploy.spec``, this option is also computed automatically
+ by ``pyside6-android-deploy``. However, if you want to explicitly include certain Qt modules,
+ the module names can be appended to this list without the `Qt` prefix.
+ e.g. Network instead of QtNetwork
+ * ``plugins``: This field is *not relevant* for ``pyside6-android-deploy`` and is only specific to
+ ``pyside6-deploy``. The plugins relevant for ``pyside6-android-deploy`` are specified through
+ the ``plugins`` option under the :ref:`android <android_key>` key.
+
+.. _android_key:
+
+**android**
+ * ``wheel_pyside``: Specifies the path to the PySide6 Android wheel for a specific target
+ architecture.
+ * ``wheel_pyside``: Specifies the path to the Shiboken6 Android wheel for a specific target
+ architecture.
+ * ``plugins``: Comma-separated list of all the Qt plugins used by the application. Just like the
+ other configuration options in ``pysidedeploy.spec``, this option is also computed automatically
+ by ``pyside6-android-deploy``. However, if you want to to explicitly include certain Qt plugins,
+ the plugin names can be appended to this list. To see all the plugins bundled with PySide6, see
+ the `plugins` folder in the ``site-packages`` on your Python where PySide6 is installed. The
+ plugin name corresponds to their folder name. This field can be confused with the ``plugins``
+ option under :ref:`qt <qt_key>` key. In the future, they will be merged into one single option.
+
+.. _buildozer_key:
+
+**buildozer**
+ * ``mode``: Specifies one of the two modes - `release` and `debug`, to run `buildozer`_. The
+ `release` mode creates an *aab* while the `debug` mode creates an apk. The default mode is
+ `debug`.
+ * ``recipe_dir``: Specifies the path to the directory containing `python-for-android`_ recipes.
+ This option is automatically computed by ``pyside6-android-deploy`` during deployment. Without
+ the :ref:`--keep-deployment-files <keep_deployment_files>` option of ``pyside6-android-deploy``,
+ the `recipe_dir` will point to a temporary directory that is deleted after the final Android
+ application package is created.
+ * ``jars_dir``: Specifies the path to the Qt Android `.jar` files that are relevant for
+ creating the Android application package. This option is automatically computed by
+ ``pyside6-android-deploy`` during deployment. Just like ``recipe_dir``, this field is also
+ *not relevant* unless used with the :ref:`--keep-deployment-files <keep_deployment_files>`
+ option of ``pyside6-android-deploy``.
+ * ``ndk_path``: Specifies the path to the Android NDK used for packaging the application.
+ * ``sdk_path``: Specifies the path to the Android SDK used for packaging the application.
+ * ``local_libs``: Specifies non-Qt plugins or other libraries compatible with the Android target
+ to be loaded by the Android runtime on startup.
+ * ``sdk_path``: Specifies the path to the Android SDK used for packaging the application.
+ * ``arch``: Specifies the target architecture's instruction set. This option take one of the four
+ values - *aarch64, armv7a, i686, x86_64*.
+
+Command Line Options
+====================
+
+Here are all the command line options of ``pyside6-android-deploy``:
+
+* **-c/--config-file**: This option is used to specify the path to ``pysidedeploy.spec`` explicitly.
+
+* **--init**: Used to only create the ``pysidedeploy.spec`` file.
+ Usage::
+
+ pyside6-android-deploy --init
+
+* **-v/--verbose**: Runs ``pyside6-android-deploy`` in verbose mode.
+
+* **--dry-run**: Displays the commands being run to produce the Android application package.
+
+.. _keep_deployment_files:
+
+* **--keep-deployment-files**: When this option is added, it retains the build folders created by
+ `buildozer`_ during the deployment process. This includes the folder storing the
+ `python-for-android`_ recipes, relevant `.jar` files and even the Android Gradle project for the
+ application.
+
+* **-f/--force**: When this option is used, it assumes ``yes`` to all prompts and runs
+ ``pyside6-android-deploy`` non-interactively. ``pyside6-android-deploy`` prompts the user to
+ create a Python virtual environment, if not already in one. With this option, the current Python
+ environment is used irrespective of whether the current Python environment is a virtual
+ environment or not.
+
+* **--name**: Application name.
+
+* **--wheel-pyside**: Path to the PySide6 Android wheel for a specific target architecture.
+
+* **--wheel-shiboken**: Path to the Shiboken6 Android wheel for a specific target architecture.
+
+* **--ndk-path**: Path to the Android NDK used for packaging the application.
+
+* **--sdk-path**: Path to the Android SDK used for packaging the application.
+
+* **--extra-ignore-dirs**: Comma-separated directory names inside the project directory. These
+ directories will be skipped when searching for Python files relevant to the project.
+
+* **--extra-modules**: Comma-separated list of Qt modules to be added to the application,
+ in case they are not found automatically. The module name can either be specified
+ by omitting the prefix of Qt or including it eg: both Network and QtNetwork works.
+
+.. _cross_compile_android:
+
+Cross-compile Qt for Python wheels for Android
+==============================================
+
+The cross-compilation of Qt for Python wheel for a specific Android target architecture needs to be
+done only once per Qt version, irrespective of the number of applications you are deploying.
+Currently, cross-compiling Qt for Python wheels only works with a Linux host. Follow these steps
+to cross-compile Qt for Python Android wheels.
+
+#. `Download <qt_download>`_ and install Qt version for which you would like to create Qt for Python
+ wheels.
+
+#. Cloning the Qt for Python repository::
+
+ git clone https://code.qt.io/pyside/pyside-setup
+
+#. Check out the version that you want to build, for example 6.7. The version checked out has
+ to correspond to the Qt version downloaded in Step 1::
+
+ cd pyside-setup && git checkout 6.7
+
+#. Installing the dependencies::
+
+ pip install -r requirements.txt
+ pip install -r tools/cross_compile_android/requirements.txt
+
+#. Run the cross-compilation Python script.::
+
+ python tools/cross_compile_android/main.py --plat-name=aarch64 --qt-install-path=/opt/Qt/6.7.0
+ --auto-accept-license --skip-update
+
+ *--qt-install-path* refers to the path where Qt 6.7.0 is installed. *--auto-accept-license* and
+ *--skip-update* are required for downloading and installing Android NDK and SDK if not already
+ specified through command line options or if they don't already exist in the
+ ``pyside6-android-deploy`` cache. Use --help to see all the other available options::
+
+ python tools/cross_compile_android/main.py --help
+
+.. _`buildozer`: https://buildozer.readthedocs.io/en/latest/
+.. _`python-for-android`: https://python-for-android.readthedocs.io/en/latest/
+.. _`qt_download`: https://www.qt.io/download
+.. _`cpython`: https://pypi.org/project/Cython/
diff --git a/sources/pyside6/doc/deployment/deployment-pyside6-deploy.rst b/sources/pyside6/doc/deployment/deployment-pyside6-deploy.rst
new file mode 100644
index 000000000..980fe2dd1
--- /dev/null
+++ b/sources/pyside6/doc/deployment/deployment-pyside6-deploy.rst
@@ -0,0 +1,217 @@
+.. _pyside6-deploy:
+
+pyside6-deploy: the deployment tool for Qt for Python
+#####################################################
+
+``pyside6-deploy`` is an easy to use tool for deploying PySide6 applications to different
+platforms. It is a wrapper around `Nuitka <https://nuitka.net/>`_, a Python compiler that
+compiles your Python code to C code, and links with libpython to produce the final executable.
+
+The final executable produced has a ``.exe`` suffix on Windows, ``.bin`` on Linux and ``.app`` on
+macOS.
+
+.. note:: Although using a virtual environment for Python is recommended for ``pyside6-deploy``, do
+ not add the virtual environment to the application directory you are trying to deploy.
+ ``pyside6-deploy`` will try to package this venv folder and will eventually fail.
+
+.. _how_pysidedeploy:
+
+How to use it?
+==============
+
+There are 2 different ways with which you can deploy your PySide6 application using
+``pyside6-deploy``:
+
+Approach 1: Using the main python entry point file
+--------------------------------------------------
+
+In this approach, you point ``pyside6-deploy`` to the file containing the main Python entry point
+file of the project i.e. the file containing ``if __name__ == "__main__":``.
+The command looks like this::
+
+ pyside6-deploy /path/to/main_file.py
+
+On running the command, ``pyside6-deploy`` installs all the dependencies required for deployment
+into the Python environment.
+
+If your main Python entry point file is named ``main.py``, then you don't have to point it to the
+filename. You can run ``pyside6-deploy`` without any options, and it will work.
+
+.. note:: If your project contains a ``pysidedeploy.spec`` file, which is generated on the first
+ run of ``pyside6-deploy`` on the project directory, then for any subsequent runs of
+ ``pyside6-deploy`` you can run ``pyside6-deploy`` without specifying the main Python entry
+ point file. It would take the path to the main file from the ``pysidedeploy.spec`` file.
+ To know more about what deployment parameters are controlled by ``pysidedeploy.spec`` file,
+ read `pysidedeploy`_.
+
+.. _approach_two:
+
+Approach 2: Using pysidedeploy.spec config file
+------------------------------------------------
+
+When you run ``pyside6-deploy`` for the first time, it creates a file called ``pysidedeploy.spec``
+in the project directory. This file controls various :ref:`parameters <pysidedeploy>` that influence
+the deployment process. Any subsequent runs of ``pyside6-deploy`` on the project directory, would
+not require additional parameters like the main Python entry point file. You can also point
+``pyside6-deploy`` to the path of the ``pysidedeploy.spec`` file (in case it is not in the same
+directory), to take the parameters from that file. This can be done with the following command::
+
+ pyside6-deploy -c /path/to/pysidedeploy.spec
+
+.. _pysidedeploy:
+
+pysidedeploy.spec
+=================
+
+As mentioned in the `Approach 2 <approach_two>`_ above, you can use this file to control the various
+parameters of the deployment process. The file has multiple sections, with each section containing
+multiple keys (parameters being controlled) assigned to a value. The advantages of such a file are
+two folds:
+
+.. _pysidedeployspec_advantages:
+
+#. Using the command line, you can control the deployment parameters without specifying them each
+ time. It is saved permanently in a file, and any subsequent runs much later in time
+ would enable the user to be aware of their last deployment parameters.
+
+#. Since these parameters are saved into a file, they can be checked into version control. This
+ gives the user more control of the deployment process. For example, when you decide to exclude
+ more QML plugins, or want to include more Nuitka options into your executable.
+
+This file is also used by the ``pyside6-android-deploy`` tool as a configuration file. The advantage
+here is that you can have one single file to control deployment to all platforms.
+
+The relevant parameters for ``pyside6-deploy`` are:
+
+**app**
+ * ``title``: The name of the application
+ * ``project_dir``: Project directory. The general assumption made is that the project directory
+ is the parent directory of the main Python entry point file
+ * ``input_file``: Path to the main Python entry point file
+ * ``project_file``: If it exists, this points to the path to the `Qt Creator Python Project File
+ .pyproject <https://doc.qt.io/qtforpython-6/faq/typesoffiles.html
+ #qt-creator-python-project-file-pyproject>`_ file. Such a file makes sure that the deployment
+ process never considers unnecessary files when bundling the executable.
+ * ``exec_directory``: The directory where the final executable is generated.
+ * ``icon``: The icon used for the application. For Windows, the icon image should be of ``.ico``
+ format, for macOS it should be of ``.icns`` format, and for linux all standard image formats
+ are accepted.
+
+**python**
+ * ``python_path``: Path to the Python executable. It is recommended to run the deployment
+ process inside a virtual environment as certain python packages will be installed onto the
+ Python environment.
+ * ``packages``: The Python packages installed into the Python environment for deployment to
+ work. By default, the Python packages `nuitka <https://pypi.org/project/Nuitka/>`__,
+ `ordered_set <https://pypi.org/project/ordered-set/>`_ and `zstandard
+ <https://pypi.org/project/zstandard/>`_ are installed. If the deployment platform is
+ Linux-based, then `patchelf <https://pypi.org/project/patchelf/>`_ is also installed
+
+**qt**
+ * ``qml_files``: Comma-separated paths to all the QML files bundled with the executable
+ * ``excluded_qml_plugins``: The problem with using Nuitka for QML deployment is that all the QML
+ plugins are also bundled with the executable. When the plugins are bundled, the binaries of
+ the plugin's Qt module are also packaged. For example, size heavy module like QtWebEngine
+ also gets added to your executable, even when you do not use it in your code. The
+ ``excluded_qml_plugins`` parameter helps you to explicitly specify which all QML plugins are
+ excluded. ``pyside6-deploy`` automatically checks the QML files against the various QML
+ plugins and excludes the following Qt modules if they don't exist::
+
+ QtQuick, QtQuick3D, QtCharts, QtWebEngine, QtTest, QtSensors
+
+ The reason why only the presence of the above 6 Qt modules is searched for is because they
+ have the most size heavy binaries among all the Qt modules. With this, you can drastically
+ reduce the size of your executables.
+ * ``modules``: Comma-separated list of all the Qt modules used by the application. Just like the
+ other configuration options in `pysidedeploy.spec`, this option is also computed automatically
+ by ``pyside6-deploy``. However, if the user wants to explicitly include certain Qt modules, the
+ module names can be appended to this list without the `Qt` prefix.
+ e.g. Network instead of QtNetwork
+ * ``plugins``: Comma-separated list of all the Qt plugins used by the application. Just like the
+ other configuration options in `pysidedeploy.spec`, this option is also computed automatically
+ by ``pyside6-deploy``. However, if the user wants to explicitly include certain Qt plugins,
+ the plugin names can be appended to this list. To see all the plugins bundled with PySide6,
+ see the `plugins` folder in the `site-packages` on your Python where PySide6 is installed. The
+ plugin name correspond to their folder name.
+
+**nuitka**
+ * ``macos.permissions``: Only relevant for macOS. This option lists the permissions used by the
+ macOS application, as found in the ``Info.plist`` file of the macOS application bundle, using
+ the so-called UsageDescription strings. The permissions are normally automatically found by
+ ``pyside6-deploy``. However the user can also explicitly specify them using the format
+ `<UsageDescriptionKey>:<Short Description>`. For example, the Camera permission is specified
+ as::
+
+ NSCameraUsageDescription:CameraAccess
+
+ * ``extra_args``: Any extra Nuitka arguments specified. It is specified as space-separated
+ command line arguments i.e. just like how you would specify it when you use Nuitka through
+ the command line. By default, it contains the following arguments::
+
+ --quiet --noinclude-qt-translations=True
+
+Command Line Options
+====================
+
+The most important command line options are the path to the main Python entry point file and the
+``pysidedeploy.spec`` file. If neither of these files exists or their command line options are
+given, then ``pyside6-deploy`` assumes that your current working directory does not contain a
+PySide6 project.
+
+Here are all the command line options of ``pyside6-deploy``:
+
+* **main entry point file**: This option does not have a name or a flag and is not restricted by it.
+ This enables ``pyside6-deploy`` to be used like::
+
+ pyside6-deploy /path/to/main_file.py
+
+* **-c/--config-file**: This option is used to specify the path to ``pysidedeploy.spec`` explicitly
+
+* **--init**: Used to only create the ``pysidedeploy.spec`` file
+ Usage::
+
+ pyside6-deploy /path/to/main --init
+
+
+* **-v/--verbose**: Runs ``pyside6-deploy`` in verbose mode.
+
+* **--dry-run**: Displays the final Nuitka command being run.
+
+* **--keep-deployment-files**: When this option is added, it retains the build folders created by
+ Nuitka during the deployment process.
+
+* **-f/--force**: When this option is used, it forces through all the input prompts.
+ ``pyside6-deploy`` prompts the user to create a Python virtual environment, if not already in one.
+ With this option, the current Python environment is used irrespective of whether the current
+ Python environment is a virtual environment or not.
+
+* **--name**: Application name.
+
+* **--extra-ignore-dirs**: Comma-separated directory names inside the project directory. These
+ directories will be skipped when searching for Python files relevant to the project.
+
+* **--extra-modules**: Comma-separated list of Qt modules to be added to the application,
+ in case they are not found automatically. The module name can either be specified
+ by omitting the prefix of Qt or including it eg: both Network and QtNetwork works.
+
+Considerations
+===============
+
+For deployment to work efficiently by bundling only the necessary plugins, the following utilities
+are required to be installed on the system:
+
+.. list-table::
+ :header-rows: 1
+
+ * - OS
+ - Dependencies
+ - Installation
+ * - Windows
+ - dumpbin
+ - Shipped with MSVC. Run `vcvarsall.bat` to add it to PATH
+ * - Linux
+ - readelf
+ - Available by default
+ * - macOS
+ - dyld_info
+ - Available by default from macOS 12 and upwards
diff --git a/sources/pyside6/doc/deployment/index.rst b/sources/pyside6/doc/deployment/index.rst
new file mode 100644
index 000000000..36e677566
--- /dev/null
+++ b/sources/pyside6/doc/deployment/index.rst
@@ -0,0 +1,155 @@
+.. _deployment-guides:
+
+Deployment
+==========
+
+Deploying or freezing an application is an important part of a Python project,
+this means to bundle all required resources so that the application finds everything it needs to
+be able to run on a client's machine.
+However, because most large projects aren't based on a single Python file, distributing these
+applications can be a challenge.
+
+Here are a few distribution options that you can use:
+ 1. Send a normal ZIP file with the application's content.
+ 2. Build a proper `Python package (wheel) <https://packaging.python.org/>`_.
+ 3. Freeze the application into a single binary file or directory.
+ 4. Provide native installer (msi, dmg)
+
+If you are considering Option 3, then starting with 6.4, we ship a new tool called `pyside6-deploy`
+that deploys your PySide6 application to all desktop platforms - Windows, Linux, and macOS. To know
+more about how to use the tool see :ref:`pyside6-deploy`. For Android deployment, see
+:ref:`pyside6-android-deploy`. Additionally, you can also use other popular deployment tools shown
+below:
+
+* `fbs`_
+* `PyInstaller`_
+* `cx_Freeze`_
+* `py2exe`_
+* `py2app`_
+* `briefcase`_
+
+.. _fbs: https://build-system.fman.io/
+.. _PyInstaller: https://www.pyinstaller.org/
+.. _cx_Freeze: https://marcelotduarte.github.io/cx_Freeze/
+.. _py2exe: http://www.py2exe.org/
+.. _py2app: https://py2app.readthedocs.io/en/latest/
+.. _briefcase: https://briefcase.readthedocs.io
+
+Although you can deploy PySide6 application using these tools, it is recommended to use
+`pyside6-deploy` as it is easier to use and also to get the most optimized executable. Since
+|project| is a cross-platform framework, we focus on solutions for the three major platforms that
+Qt supports: Windows, Linux, and macOS.
+
+The following table summarizes the platform support for those packaging tools:
+
+.. raw:: html
+
+ <table class="docutils align-default">
+ <thead>
+ <tr>
+ <th class="head">Name</th>
+ <th class="head">License</th>
+ <th class="head">Qt 6</th>
+ <th class="head">Qt 5</th>
+ <th class="head">Linux</th>
+ <th class="head">macOS</th>
+ <th class="head">Windows</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p>fbs</p></td>
+ <td><p>GPL</p></td>
+ <td></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>PyInstaller</p></td>
+ <td><p>GPL</p></td>
+ <td><p style="color: green;">partial</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>cx_Freeze</p></td>
+ <td><p>MIT</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>py2exe</p></td>
+ <td><p>MIT</p></td>
+ <td><p style="color: green;">partial</p></td>
+ <td><p style="color: green;">partial</p></td>
+ <td><p style="color: red;">no</p></td>
+ <td><p style="color: red;">no</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>py2app</p></td>
+ <td><p>MIT</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: red;">no</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: red;">no</p></td>
+ </tr>
+ <tr>
+ <td><p>briefcase</p></td>
+ <td><p>BSD3</p></td>
+ <td><p style="color: green;">partial</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>Nuitka</p></td>
+ <td><p>MIT</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ </tbody>
+ </table>
+
+Notice that only *fbs*, *cx_Freeze*, *briefcase*, and *PyInstaller* meet our cross-platform requirement.
+
+Since these are command-line tools, you'll need special hooks or scripts to handle resources
+such as images, icons, and meta-information, before adding them to your package. Additionally,
+these tools don't offer a mechanism to update your application packages.
+
+To create update packages, use the `PyUpdater <https://www.pyupdater.org/>`_, which is a tool
+built around PyInstaller.
+
+The `fbs`_ tool offers a nice UI for the user to install the
+application step-by-step.
+
+.. note::
+
+ Deployment is supported only from Qt for Python 5.12.2 and later.
+
+Here's a set of tutorials on how to use these tools:
+
+.. toctree::
+ :name: mastertoc
+ :maxdepth: 2
+
+ deployment-pyside6-deploy.rst
+ deployment-pyside6-android-deploy.rst
+ deployment-fbs.rst
+ deployment-pyinstaller.rst
+ deployment-cxfreeze.rst
+ deployment-briefcase.rst
+ deployment-py2exe.rst
+ deployment-nuitka.rst
diff --git a/sources/pyside6/doc/developer/adapt_qt.rst b/sources/pyside6/doc/developer/adapt_qt.rst
new file mode 100644
index 000000000..aec81fb0f
--- /dev/null
+++ b/sources/pyside6/doc/developer/adapt_qt.rst
@@ -0,0 +1,54 @@
+.. _developer-adapt-qt:
+
+Adapt to new Qt versions
+========================
+
+Adapting to source changes
+--------------------------
+
+The dev branch of PySide is switched to a new Qt minor version
+after its API review is finished and the API is stable.
+
+Until that happens, a patch should be continuously developed
+to adapt to this version.
+
+The `new classes page <https://doc-snapshots.qt.io/qt6-6.7/newclasses67.html>`_
+is a good source of information for new API.
+
+New classes and should be added to the type system file (using
+a ``since`` attribute) and ``CMakeList.txt`` file of the respective module.
+
+Should the class not be available on all platforms, the respective
+``QT_CONFIG`` macro needs to be specified in the type system file and
+feature checks need to be added to ``CMakeList.txt`` (see for example
+``QPermission``).
+
+The process consists of running a build and evaluating the log file.
+The script
+`shiboken2tasks.py <https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/scripts/shiboken2tasks.py>`_
+from the *Qt Creator* repository can be used to convert the shiboken warnings
+into a `task file <https://doc.qt.io/qtcreator/creator-task-lists.html>`_
+for display in the build issues pane of *Qt Creator*.
+
+Warnings about new enumerations will be shown there; they should be added
+to type system file using a ``since`` attribute.
+
+Warnings about not finding a function signature for modification
+also need to be handled; mostly this is a sign of a function parameter
+being changed from ``int`` to ``qsizetype`` or similar.
+
+If the build succeeds, a test run should be done.
+
+The Qt source code should be checked for new overloads
+(indicated by ``QT6_DECL_NEW_OVERLOAD_TAIL`` starting from 6.7).
+The resolution needs to be decided for each individual case,
+mostly by removing old functions and using ``<declare-function>``
+to declare new API.
+
+Bumping the version
+-------------------
+
+To instruct ``COIN`` to use the next version of Qt, adapt the files
+``coin/dependencies.yaml`` and/or ``product_dependencies.yaml`` accordingly.
+Next, the wheel names should be changed by adapting
+``sources/shiboken6/.cmake.conf`` and ``sources/pyside6/.cmake.conf``.
diff --git a/sources/pyside6/doc/developer/add_module.rst b/sources/pyside6/doc/developer/add_module.rst
new file mode 100644
index 000000000..2eb962207
--- /dev/null
+++ b/sources/pyside6/doc/developer/add_module.rst
@@ -0,0 +1,61 @@
+.. _developer-add-module:
+
+Add a new module
+================
+
+New modules can be added for many reasons, the most important
+one is when Qt enables or includes a new one for a new release.
+
+Adding the bindings, and documentation are the essentials
+to include new modules, but adding tests and examples is ideal.
+
+Add bindings
+------------
+
+- Find the correct name (look at the include path of Qt).
+- Add the module to the ``coin/dependencies.yaml`` file.
+- Add it to ``sources/pyside6/cmake/PySideHelpers.cmake``.
+- Add it to ``build_scripts/wheel_files.py`` (plugins, translations).
+- Copy an existing module to ``sources/pyside6/PySide6/<name>``.
+- Adapt the ``typesystem.xml`` and ``CMakeList.txt`` (using for example
+ *Qt Creator*'s case-preserving replace function).
+- Make sure the dependencies are correct.
+- Find the exported public classes, add them to the ``typesystem.xml`` file,
+ checking whether they are ``value-type`` or ``object-type``. Add their enums
+ and flags.
+- Add the wrapper files to ``CMakeList.txt``.
+- Create a test dir under ``sources/pyside6/tests`` with an empty
+ ``CMakeList.txt``.
+- Try to build with the module added to the ``--module-subset`` option of
+ ``setup.py``.
+- Watch out for shiboken warnings in the log.
+- Be aware that ``ninja`` mixes stdout and stderr, so, the first warning is
+ typically hidden behind a progress message.
+- A convenient way of doing this is using
+ ``qt-creator/scripts/shiboken2tasks.py`` from the
+ `*Qt Creator* repository <https://code.qt.io/cgit/qt-creator/qt-creator.git>`_
+ converting them to a ``.tasks`` file which can be loaded into *Qt Creator*'s
+ issue pane.
+- Link errors may manifest when ``generate_pyi`` imports the module trying
+ to create signatures. They indicate a missing source file entry
+ or a bug in the module itself.
+
+.. note:: For the build to succeed, the module must follow the Qt convention
+ of using ``#include <QtModule/header.h>`` since module include paths
+ are not passed in PySide.
+
+Distribution
+------------
+
+- Determine to which wheel the module belongs according to
+ `Qt Modules <https://doc.qt.io/qt-6/qtmodules.html>`_.
+- Add the module to ``build_scripts/wheel_files.py`` for use by
+ ``create_wheels.py``.
+- Add the module to one of the ``README.pyside6_*.md`` files.
+
+Add documentation
+-----------------
+
+- Add entry to ``sources/pyside6/doc/modules.rst``.
+- Add a .qdocconf.in file in ``sources/pyside6/doc/qtmodules``.
+- Add module description ``.rst`` file in ``sources/pyside6/doc/extras``.
diff --git a/sources/pyside6/doc/developer/add_port_example.rst b/sources/pyside6/doc/developer/add_port_example.rst
new file mode 100644
index 000000000..b99641f45
--- /dev/null
+++ b/sources/pyside6/doc/developer/add_port_example.rst
@@ -0,0 +1,67 @@
+.. _developer-add-port-example:
+
+Add a new example or port one
+=============================
+
+Adding examples is a good exercise for people wanting to become familiar with
+the modules and its functionality.
+
+You can either design an example from scratch or inspired in another
+application, or simply you can port an existing Qt example that does not have
+a Python counterpart.
+
+Example code should be free of `flake8 <https://pypi.org/project/flake8/>`_
+warnings; this is enforced by a bot. A configuration file is provided
+at the root of the repository. Offending lines can be excluded by a
+``noqa`` directive if there is a good reason to do so.
+
+Keep in mind we do allow 100 columns for line length.
+
+Additionally, please use `isort <https://pypi.org/project/isort/>`_ to keep the
+imports ordered and consistent with other examples.
+
+For example:
+
+.. code-block:: bash
+
+ $ flake8 --config pyside-setup/.flake8 your_file.py
+ $ isort your_file.py
+
+
+
+Add a new example
+-----------------
+
+- Check if the topic your example covers is not in an existing example already.
+- Create a new directory inside the ``examples/<module>`` you think
+ is more relevant.
+- Inside, place the code of the example, and also a ``.pyproject``
+ file listing the files the example needs.
+- If you want the example to be automatically displayed on the
+ example gallery, include a ``doc`` directory that contains a ``rst``
+ file and a screenshot. Check other examples for formatting questions.
+- When writing the ``rst`` file, you can include code snippets using
+ the ``literalinclude`` directive specifying the relative path
+ as listed in the ``.pyproject`` file. The `example_gallery` tool will
+ expand this (see the `pointconfiguration` example).
+- For the code displayed in the tabs, you can create ``rstinc`` files
+ in the ``doc`` directory containing some description explaining them
+ (see the `samplebinding` example).
+
+Port a Qt example
+-----------------
+
+- Quickly check the C++ example, fix outdated code.
+- Port the sources using ``tools/tools/qtcpp2py.py`` (front-end for
+ ``snippets-translate``).
+- Note that our examples need to have unique names due to the doc build.
+- Verify that all slots are decorated using ``@Slot``.
+- Add a ``.pyproject`` file (verify later on that docs build).
+- Add a ``doc`` directory and descriptive ``.rst`` file,
+ and a screenshot if suitable (use ``optipng`` to reduce file size).
+- Add the ``"""Port of the ... example from Qt 6"""`` doc string.
+- Try to port variable and function names to snake case convention.
+- Remove C++ documentation from ``sources/pyside6/doc/additionaldocs.lst``.
+
+.. note:: Example screenshots in ``.png`` should be optimized by
+ running ``optipng -o 7 -strip all``. Alternatively, the ``.webp`` format can be used.
diff --git a/sources/pyside6/doc/developer/add_tool.rst b/sources/pyside6/doc/developer/add_tool.rst
new file mode 100644
index 000000000..732e6b915
--- /dev/null
+++ b/sources/pyside6/doc/developer/add_tool.rst
@@ -0,0 +1,51 @@
+.. _developer-add-tool:
+
+Add a new tool or a Qt tool wrapper
+===================================
+
+Tooling is essential to |project|, for that reason you can find many ad-hoc
+tools in the repository, which include wrappers of Qt tools or newly developed
+tools to solve issues, or improve some project workflows.
+
+Add a new tool
+--------------
+
+Tools not available to end users
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This depicts the tools that are not shipped with Qt for Python wheels and are used to aid
+Qt for Python development
+
+- Place your tool in the ``tools`` directory.
+- If your project has more than one file, create a directory.
+- Create a ``.pyproject`` file including all the relevant files
+ for your tool.
+
+Tools available to end users
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Place your tool in the ``sources/pyside-tools`` directory.
+- If your project has more than one file, create a directory.
+- Create a ``.pyproject`` file including all the relevant files
+ for your tool.
+- Add the relevant files in ``sources/pyside-tools/CMakeLists.txt``.
+- Add the tool in ``sources/pyside-tools/pyside_tool.py``.
+- Add the tool in ``build_scripts/__init__.py`` to create the setuptools entry points
+ i.e. this enable using the tool from the console as "pyside6-<tool_name>"
+- Add an entry to ``sources/pyside6/doc/gettingstarted/package_details.rst``.
+- Include the necessary Qt binaries explicitly on ``build_scripts/wheel_files.py``
+- Build with ``--standalone``, verify it is working.
+
+
+Add a Qt tool wrapper
+---------------------
+
+- Add the relevant files in ``sources/pyside-tools/CMakeLists.txt``.
+- Add the tool in ``sources/pyside-tools/pyside_tool.py``.
+- Add the tool in ``build_scripts/__init__.py`` to create the setuptools entry points
+ i.e. this enable using the tool from the console as "pyside6-<tool_name>"
+- Add an entry to ``sources/pyside6/doc/tools/index.rst`` and the detailed
+ documentation to ``sources/pyside6/doc/tools/<tool_name>.rst``.
+- Include the necessary Qt binaries explicitly on ``build_scripts/wheel_files.py``
+- Add the necessary files to ``build_scripts/wheel_files.py``.
+- Build with ``--standalone``, verify it is working. Also, check if the wheel bundles the tool.
diff --git a/sources/pyside6/doc/developer/documentation.rst b/sources/pyside6/doc/developer/documentation.rst
new file mode 100644
index 000000000..517bd46f1
--- /dev/null
+++ b/sources/pyside6/doc/developer/documentation.rst
@@ -0,0 +1,73 @@
+.. _developer-documentation:
+
+Fixing Documentation issues
+===========================
+
+Fixing texts
+------------
+
+Shiboken's ``<inject-documentation>`` element can be used to add texts.
+It's ``"replace"`` mode is currently not implemented, though.
+
+Fixing snippets
+---------------
+
+Snippets can replaced by placing a Python equivalent under ``sources/pyside6/doc/snippets``.
+The directory structure matches that of Qt. To replace a snippet with the id `0` in
+``qtbase/examples/foo/snippet.cpp``, place a file ``qtbase/examples/foo/snippet_0.cpp.py``
+under that directory (one snippet per file with the snippet id appended to the base name).
+
+More complicated mappings can be added to ``tools/snippets_translate/override.py``.
+
+# Recreating the module descriptions after a Qt major version change
+
+The source tree contains .rst files containing the module description in
+doc/extras (named for example "QtCore.rst"). They are extracted/adapted from
+the C++ module descriptions. If there is no module description file, shiboken
+will extract the module description from the webxml files generated by qdoc.
+This ends up in the build directory under doc/rst/PySide6/&lt;module&gt;/index.rst.
+It can be used as a starting point for a module description file. C++
+specific information like build instructions should be removed.
+
+The descriptions may link to tutorials which can be added to additionaldocs.lst
+for webxml extraction.
+
+Maintaining additionaldocs.lst
+------------------------------
+
+The file is a list of additional documentation files. These are basically Qt
+tutorials referenced by the documentation. They will receive some Python
+adaption by shiboken/sphinx.
+
+The list can be created by the below script and some hand-editing. It will find
+almost all documents. Quite a number of them might be unreferenced, but there
+is no good way of filtering for this.
+Pages of examples that exist in Python should be removed.
+
+.. code-block:: bash
+
+ for F in *.webxml
+ do
+ echo "$F" | egrep '(-index)|(-module)|(-qmlmodule)\.webxml$' > /dev/null
+ if [ $? -ne 0 ]
+ then
+ if fgrep '<para>' "$F" > /dev/null # Exclude reference only
+ then
+ egrep "(<class )|(<namespace )" $F > /dev/null || echo $F
+ fi
+ fi
+ done
+
+Inheritance graphs
+------------------
+
+``inheritance_diagram.pyproject`` lists the script involved in inheritance
+graph generation, ``inheritance_diagram.py`` being the main one used by sphinx.
+The others have main-test drivers for checking.
+
+There are 2 scripts used for determining the inheritance:
+* ``json_inheritance.py`` (env var ``INHERITANCE_FILE``) reads a
+ inheritance.json file containing the class hierarchy generated by
+ shiboken's doc generator.
+
+* ``import_inheritance.py`` actually tries to import the class (legacy)
diff --git a/sources/pyside6/doc/developer/enumfeatures_doc.rst b/sources/pyside6/doc/developer/enumfeatures_doc.rst
new file mode 100644
index 000000000..91b7b6346
--- /dev/null
+++ b/sources/pyside6/doc/developer/enumfeatures_doc.rst
@@ -0,0 +1,160 @@
+.. _enum-features:
+
+The Set of Enum Features
+========================
+
+The development of the new Python enums took the form of a series of patches.
+While we put a lot of effort into supporting the old Enums (without promoting
+them), it is still possible that someone has a case where they cannot use
+the Python enums as they are now. To avoid people setting the environment
+flag to disable this completely, we implemented a way to select each
+combination of enum functions step by step with a specific set of flags.
+
+
+The Possible Enum Flags
+-----------------------
+
+This is the table of all flags used to control the creation of Python enums.
+
+====================== ===== ======================================================
+Flag Name Value
+====================== ===== ======================================================
+ENOPT_OLD_ENUM 0x00 (False) No longer possible since PySide 6.6
+ENOPT_NEW_ENUM 0x01 (True) The default for PySide 6.4, full implementation
+ENOPT_INHERIT_INT 0x02 Turn all Enum into IntEnum and Flag into IntFlag
+ENOPT_GLOBAL_SHORTCUT 0x04 Re-add shortcuts for global enums
+ENOPT_SCOPED_SHORTCUT 0x08 Re-add shortcuts for scoped enums
+ENOPT_NO_FAKESHORTCUT 0x10 Don't fake rename (forgiveness mode)
+ENOPT_NO_FAKERENAMES 0x20 Don't fake shortcuts (forgiveness mode)
+ENOPT_NO_ZERODEFAULT 0x40 Don't use zero default (forgiveness mode)
+ENOPT_NO_MISSING 0x80 Don't allow missing values in Enum
+====================== ===== ======================================================
+
+Such a set of flags can be defined either by the environment variable
+``PYSIDE6_OPTION_PYTHON_ENUM`` or set by the Python variable
+``sys.pyside6_option_python_enum`` before PySide6 is imported.
+The environment variable also supports arbitrary integer expressions
+by using ``ast.literal_eval``.
+
+
+ENOPT_OLD_ENUM (0x00)
+~~~~~~~~~~~~~~~~~~~~~
+
+This option completely disables the new enum implementation.
+Even though this is a valid option, we want to avoid it if possible.
+The goal is to eventually remove the old implementation. To make this
+possible, we have made the individual features of the enum implementation
+accessible as flags. This way, if users report problems, we may be able
+to provide a temporary solution before extending enum support accordingly.
+
+
+ENOPT_NEW_ENUM (0x01)
+~~~~~~~~~~~~~~~~~~~~~
+
+In a perfect world, no one would choose anything other than this default
+setting. Unfortunately, reality is not always like that. That is why
+there are the following flags.
+
+
+The most likely flags needed
+----------------------------
+
+If there are errors, they are likely to be the following: Either implicit
+assumptions are there that require IntEnum, or global enums are used that
+unfortunately cannot be replaced with tricks.
+
+
+ENOPT_INHERIT_INT (0x02)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When this flag is set, all ``enum.Enum/enum.Flag`` classes are converted to
+``enum.IntEnum/enum.IntFlag``. This solves the most likely compatibility
+problem when switching to Python enums. The old Shiboken enums always
+inherit from int, but most Python enums do not.
+
+It was a decision of Python developers not to let enums inherit from int by
+default, since no order should be implied. In most cases, inheritance from
+int can be avoided, either by using the value property or better by
+uplifting: instead of using ``AnEnum.AnInstance.value`` in a function that
+expects an int argument, you can also convert the integer to an enumeration
+instance after the call by ``AnEnum(int_arg)`` and use that in comparisons.
+
+However, there are cases where this is not possible, and explicit support in
+PySide is simply not available. In those cases, you can use this flag as a
+workaround until we have implemented alternatives.
+
+
+ENOPT_GLOBAL_SHORTCUT (0x04)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the beginning of the Python enum implementation, we continued to support
+the shortcut behavior of Shiboken enums: the enum constants were mirrored
+into the enclosing scope.
+This was later emulated in the course of forgiveness mode. For enum classes
+in a PySide class this works fine, but for enum classes directly on the module
+level there is no good way to implement forgiveness.
+
+It is unlikely that errors are hidden for global enums, because they should
+already produce an error during import. But for cases without access to
+the source code, you can help yourself with this flag.
+
+A flag value of 0x6 is likely to solve the majority of problems.
+
+
+Flags for completeness
+----------------------
+
+The following flags complement the description of Python Enums.
+They essentially serve the better understanding of the
+implementation and make it fully transparent and customizable.
+
+
+ENOPT_SCOPED_SHORTCUT (0x08)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For completeness, we also supported mirroring scoped enums, although this
+has since been replaced by forgiveness mode. If you want to try this,
+please also use the ENOPT_NO_FAKESHORTCUT flag (0x10), otherwise the
+effect of this flag will remain invisible.
+
+
+ENOPT_NO_FAKERENAMES (0x10)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Forgiveness mode emulates renaming ``Enum.Flag`` classes back to Shiboken
+QFlags structures, which have slightly different names.
+So when such a defunct name is used, the system replaces it internally
+with the new ``enum.Flag`` structure. Unless special boundary problems
+are provoked, this replacement should work.
+
+To see the effect of this renaming, you can turn it off with this flag.
+
+
+ENOPT_NO_ZERODEFAULT (0x40)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As part of the forgiveness mode, Python enums can be created by a
+parameterless call, although Python enums actually force a parameter
+when called.
+
+The effect can be examined if this flag is set to disable it.
+
+
+ENOPT_NO_MISSING (0x80)
+~~~~~~~~~~~~~~~~~~~~~~~
+
+There are a few cases where Shiboken enums use missing values. In
+``enum.Flag`` structures, this is allowed anyway because we have set the
+``FlagBoundary.KEEP`` flag (see ``enum.py``).
+
+Normal ``enum.Enum`` structures don't have this provision, but the
+``enum`` module allows to pass a ``_missing_`` function for customization.
+
+Our way of dealing with this situation is to create a new fake
+``enum.Enum`` class with the same name and a nameless instance, and
+pretend with an attribute setting that it has the same type.
+The additional instances created in this way are recorded in a class dict
+``_sbk_missing_`` in order to preserve their identity.
+
+You will see the effect of not defining a ``_missing_`` function if you
+set this flag.
diff --git a/sources/pyside6/doc/developer/extras.rst b/sources/pyside6/doc/developer/extras.rst
new file mode 100644
index 000000000..9788b539d
--- /dev/null
+++ b/sources/pyside6/doc/developer/extras.rst
@@ -0,0 +1,55 @@
+Test a wheel
+============
+
+There is a tool that you can use to test a set of wheels called 'testwheel' but
+it's currently in a different repository (``qt/qtqa``):
+
+- Use ``scripts/packagetesting/testwheel.py`` from the
+ `qtqa repository <https://code.qt.io/cgit/qt/qtqa.git>`_.
+
+To test the wheels:
+
+- Create a virtual environment and activate it.
+- Install the dependencies listed on the ``requirements.txt`` file.
+- Install all the wheels: ``shiboken6``, ``shiboken6-generator``,
+ and ``PySide6-Essentials``.
+- Run the ``testwheel`` tool.
+- Install ``PySide6-Addons`` wheels.
+- Run again the ``testwheel`` tool.
+- In case you have access to commercial wheels, don't forget the
+ ``PySide6-M2M`` as well, and re-run the ``testwheel`` tool.
+
+Build on the command line
+=========================
+
+- Consider using ``build_scripts/qp5_tool.py``.
+
+Build with address sanitizer (Linux)
+====================================
+
+ASAN needs to be told to not exit on memory leaks and its library
+needs to be pre-loaded. Assuming the library is found
+at ``/usr/lib/gcc/x86_64-linux-gnu/11``:
+
+.. code-block:: bash
+
+ export ASAN_OPTIONS=detect_leaks=0
+ export LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so
+ python setup.py build [...] --sanitize-address
+
+De-Virtualize the Python Files
+==============================
+
+The Python files in the Shiboken module are completely virtual, i.E.
+they are nowhere existent in the file system for security reasons.
+
+For debugging purposes or to change something, it might be desirable
+to move these files into the normal file system, again.
+
+- Setting the environment variable "SBK_EMBED" once to false unpacks these
+ files when PySide6 or shiboken6 are imported. The files are written
+ into "side-packages/shiboken6/files.dir" and are used from then on.
+
+- Setting the variable to true removes "files.dir".
+
+- Without the "SBK_EMBED" variable, the embedding status remains sticky.
diff --git a/sources/pyside6/doc/developer/feature-motivation.rst b/sources/pyside6/doc/developer/feature-motivation.rst
new file mode 100644
index 000000000..1509ea724
--- /dev/null
+++ b/sources/pyside6/doc/developer/feature-motivation.rst
@@ -0,0 +1,303 @@
+.. _feature-why:
+
+Why do we have a __feature__?
+=============================
+
+
+History
+-------
+
+In PySide user story PYSIDE-1019, we tested certain ways to
+make PySide more pythonic. The first idea was to support some
+way to allow for ``snake_case`` function names.
+
+This feature is possible with relatively low compatibility
+problems, because having the same function with different names
+would be not so nice, but a possible low-effort solution.
+
+When going to ``true_property``, things become different. When we
+support properties as first class objects instead of getter
+and setter functions, we get a conflict, because a function
+cannot act as a property (no braces) and be a function at the
+same time.
+
+This consideration led us to the idea:
+Features must be selectable per-module.
+
+
+Why are features selectable per-module?
+---------------------------------------
+
+Suppose you have some pre-existing code. Maybe you use some downloaded
+code or you generated an interface file. When you now decide to
+use a feature, you don't want all this existing stuff to become
+incorrect. By using the statement
+
+.. code-block:: python
+
+ from __feature__ import ...
+
+you declare that this module uses some feature. Other modules will not
+be influenced by this decision and can stay unchanged.
+
+
+Why dunder, and why not __future__?
+-----------------------------------
+
+Especially in Python 2, but in a few cases also in Python 3, there is
+the future statement
+
+.. code-block:: python
+
+ from __future__ import ...
+
+That is a statement that can only appear at the beginning of a module,
+and it switches how the Python parser works.
+
+Our first idea was to mimick this behavior for PySide, although we are
+a bit cheating: The feature statement is not a syntactical construct,
+and we cannot easily forbid that it is in the middle of a module.
+
+We then realized that the intention of Python's ``__future__`` import and
+PySide's ``__feature__`` import are different: While Python implies by
+``__future__`` some improvement, we do not want to associate with
+``__feature__``. We simply think that some users who come from Python may
+like our features, while others are used to the C++ convention and
+consider something that deviates from the Qt documentation as drawback.
+
+The intention to use the ``from __feature__ import ...`` notation was the hope that
+people see the similarity to Python's ``__future__`` statement and put that import
+at the beginning of a module to make it very visible that this module
+has some special global differences.
+
+
+The snake_case feature
+======================
+
+By using the statement
+
+.. code-block:: python
+
+ from __feature__ import snake_case
+
+all methods of all classes used in this module are changing their name.
+
+The algorithm to change names is this:
+
+* if the name has less than 3 chars, or
+* if two upper chars are adjacent, or
+* if the name starts with ``gl`` (which marks OpenGL),
+* the name is returned unchanged. Otherwise
+* a single upper char ``C`` is replaced by ``_c``
+
+
+The true_property feature
+=========================
+
+By using the statement
+
+.. code-block:: python
+
+ from __feature__ import true_property
+
+all methods of all classes used in this module which are declared in the Qt
+documentation as property become real properties in Python.
+
+This feature is incompatible with the past and cannot coexist; it is
+the reason why the feature idea was developed at all.
+
+
+Normal Properties
+-----------------
+
+Normal properties have the same name as before:
+
+.. code-block:: python
+
+ QtWidgets.QLabel().color()
+
+becomes as property
+
+.. code-block:: python
+
+ QtWidgets.QLabel().color
+
+When there is also a setter method,
+
+.. code-block:: python
+
+ QtWidgets.QLabel().setColor(value)
+
+becomes as property
+
+.. code-block:: python
+
+ QtWidgets.QLabel().color = value
+
+Normal properties swallow the getter and setter functions and replace
+them by the property object.
+
+
+Special Properties
+------------------
+
+Special properties are those with non-standard names.
+
+.. code-block:: python
+
+ QtWidgets.QLabel().size()
+
+becomes as property
+
+.. code-block:: python
+
+ QtWidgets.QLabel().size
+
+But here we have no setSize function, but
+
+.. code-block:: python
+
+ QtWidgets.QLabel().resize(value)
+
+which becomes as property
+
+.. code-block:: python
+
+ QtWidgets.QLabel().size = value
+
+In that case, the setter does not become swallowed, because so many
+people are used to the ``resize`` function.
+
+
+Class properties
+----------------
+
+It should be mentioned that we not only support regular properties
+as they are known from Python. There is also the concept of class
+properties which always call their getter and setter:
+
+A regular property like the aforementioned ``QtWidgets.QLabel`` has
+this visibility:
+
+.. code-block:: python
+
+ >>> QtWidgets.QLabel.size
+ <property object at 0x113a23540>
+ >>> QtWidgets.QLabel().size
+ PySide6.QtCore.QSize(640, 480)
+
+A class property instead is also evaluated without requiring an instance:
+
+.. code-block:: python
+
+ >>> QtWidgets.QApplication.windowIcon
+ <PySide6.QtGui.QIcon(null) at 0x113a211c0>
+
+You can only inspect it if you go directly to the right class dict:
+
+.. code-block:: python
+
+ >>> QtGui.QGuiApplication.__dict__["windowIcon"]
+ <PySide6.PyClassProperty object at 0x114fc5270>
+
+
+About Property Completeness
+---------------------------
+
+There are many properties where the Python programmer agrees that these
+functions should be properties, but a few are not properties, like
+
+.. code-block:: python
+
+ >>> QtWidgets.QMainWindow.centralWidget
+ <method 'centralWidget' of 'PySide6.QtWidgets.QMainWindow' objects>
+
+We are currently discussing if we should correct these rare cases, as they
+are probably only omissions. Having to memorize the missing properties
+seems to be quite cumbersome, and instead of looking all properties up in
+the Qt documentation, it would be easier to add all properties that
+should be properties and are obviously missing.
+
+
+Name Clashes and Solution
+-------------------------
+
+There are some rare cases where a property already exists as a function,
+either with multiple signatures or having parameters.
+This is not very nice in C++ as well, but for Python this is forbidden.
+Example:
+
+.. code-block:: python
+
+ >>> from PySide6 import *
+ >>> from PySide6.support.signature import get_signature
+ >>> import pprint
+ >>> pprint.pprint(get_signature(QtCore.QTimer.singleShot))
+ [<Signature (arg__1: int, arg__2: Callable) -> None>,
+ <Signature (msec: int, receiver: PySide6.QtCore.QObject, member: bytes) -> None>,
+ <Signature (msec: int, timerType: PySide6.QtCore.Qt.TimerType,
+ receiver: PySide6.QtCore.QObject, member: bytes) -> None>]
+
+When creating this property, we respect the existing function and use a slightly
+different name for the property by appending an underscore.
+
+.. code-block:: python
+
+ >>> from __feature__ import true_property
+ >>> QtCore.QTimer.singleShot_
+ <property object at 0x118e5f8b0>
+
+We hope that these clashes can be removed in future Qt versions.
+
+
+The __feature__ import
+======================
+
+The implementation of ``from __feature__ import ...`` is built by a slight
+modification of the ``__import__`` builtin. We made that explicit by assigning
+variables in the builtin module. This modification takes place at |project|
+import time:
+
+* The original function in ``__import__`` is kept in ``__orig_import__``.
+* The new function is in ``__feature_import__`` and assigned to ``__import__``.
+
+This function calls the Python function ``PySide6.support.__feature__.feature_import``
+first, and falls back to ``__orig_import__`` if feature import is not applicable.
+
+
+Overriding __import__
+---------------------
+
+This is not recommended. Import modifications should be done using import hooks,
+see the Python documentation on `Import-Hooks`_.
+
+If you would like to modify ``__import__`` anyway without destroying the features,
+please override just the ``__orig_import__`` function.
+
+
+IDEs and Modifying Python stub files
+------------------------------------
+
+|project| comes with pre-generated ``.pyi`` stub files in the same location as
+the binary module. For instance, in the site-packages directory, you can find
+a ``QtCore.pyi`` file next to ``QtCore.abi3.so`` or ``QtCore.pyd`` on Windows.
+
+When using ``__feature__`` often with common IDEs, you may want to provide
+a feature-aware version of ``.pyi`` files to get a correct display. The simplest
+way to change them all in-place is the command:
+
+.. code-block:: bash
+
+ pyside6-genpyi all --feature snake_case true_property
+
+
+Using __feature__ with UIC files
+--------------------------------
+
+Features can be freely used together with generated UIC files. The UIC files
+are _not_ converted, intentionally. Mixing them with feature selections in other
+Python modules should always work, because switching will happen as needed, selected
+by the currently active module. (Please report to us if this fails for an example)
+
+
+.. _`Import-Hooks`: https://docs.python.org/3/reference/import.html#import-hooks
diff --git a/sources/pyside6/doc/developer/index.rst b/sources/pyside6/doc/developer/index.rst
new file mode 100644
index 000000000..92c84259d
--- /dev/null
+++ b/sources/pyside6/doc/developer/index.rst
@@ -0,0 +1,35 @@
+.. _developer-notes:
+
+Developer Notes
+===============
+
+Developing |project| requires people to understand different processes
+and steps that need to be taken into account when dealing with topics
+related to modules, bindings, examples, and more.
+
+Development Topics
+------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ add_module.rst
+ add_port_example.rst
+ add_tool.rst
+ documentation.rst
+ adapt_qt.rst
+ extras.rst
+
+Implementation details
+----------------------
+
+Complementary, here you can find the reasoning and motivation for the
+many features and implementation details that the project has:
+
+.. toctree::
+ :maxdepth: 2
+
+ enumfeatures_doc.rst
+ limited_api.rst
+ signature_doc.rst
+ feature-motivation.rst
diff --git a/sources/pyside6/doc/developer/limited_api.rst b/sources/pyside6/doc/developer/limited_api.rst
new file mode 100644
index 000000000..44d3faad2
--- /dev/null
+++ b/sources/pyside6/doc/developer/limited_api.rst
@@ -0,0 +1,703 @@
+The Transition To The Limited Python API (PEP384)
+=================================================
+
+
+Foreword
+--------
+
+Python supports a limited API that restricts access to certain structures.
+Besides eliminating whole modules and all functions and macros which names
+start with an
+underscore, the most drastic restriction is the removal of normal type object
+declarations.
+
+For details about the eliminated modules and functions, please see the
+`PEP 384`_ page for reference.
+
+
+.. _`PEP 384`: https://www.python.org/dev/peps/pep-0384/
+
+
+
+Changed Modules
+---------------
+
+All changed module's include files are listed with the changed functions here.
+As a general rule, it was tried to keep the changes to a minimum diff.
+Macros which are not available were changed to functions with the same name
+if possible. Completely removed names ``Py{name}`` were re-implemented as ``Pep{name}``.
+
+
+memoryobject.h
+~~~~~~~~~~~~~~
+
+The buffer protocol was completely removed. We redefined all the structures
+and methods, because PySide uses that. This is an exception to the limited API
+that we have to check ourselves. The code is extracted in bufferprocs_py37.h .
+This is related to the following:
+
+
+abstract.h
+~~~~~~~~~~
+
+This belongs to the buffer protocol like memoryobject.h .
+As replacement for ``Py_buffer`` we defined ``Pep_buffer`` and several other
+internal macros.
+
+The version is checked by hand, and the version number must be updated only
+if the implementation does not change. Otherwise, we need to write version
+dependent code paths.
+
+It is questionable if it is worthwhile to continue using the buffer protocol
+or if we should try to get rid of ``Pep_buffer``, completely.
+
+
+pydebug.h
+~~~~~~~~~
+
+We have no direct access to ``Py_VerboseFlag`` because debugging is not
+supported. We redefined it as macro ``Py_VerboseFlag`` which calls ``Pep_VerboseFlag``.
+
+
+unicodeobject.h
+~~~~~~~~~~~~~~~
+
+The macro ``PyUnicode_GET_SIZE`` was removed and replaced by ``PepUnicode_GetLength``
+which evaluates to ``PyUnicode_GetSize`` for Python 2 and ``PyUnicode_GetLength`` for Python 3.
+Since Python 3.3, ``PyUnicode_GetSize`` would have the bad side effect of requiring the GIL!
+
+Function ``_PyUnicode_AsString`` is unavailable and was replaced by a macro
+that calls ``_PepUnicode_AsString``. The implementation was a bit involved,
+and it would be better to change the code and replace this function.
+
+
+bytesobject.h
+~~~~~~~~~~~~~
+
+The macros ``PyBytes_AS_STRING`` and ``PyBytes_GET_SIZE`` were redefined to call
+the according functions.
+
+
+floatobject.h
+~~~~~~~~~~~~~
+
+``PyFloat_AS_DOUBLE`` now calls ``PyFloat_AsDouble``.
+
+
+tupleobject.h
+~~~~~~~~~~~~~
+
+``PyTuple_GET_ITEM``, ``PyTuple_SET_ITEM`` and ``PyTuple_GET_SIZE`` were redefined as
+function calls.
+
+
+listobject.h
+~~~~~~~~~~~~
+
+``PyList_GET_ITEM``, ``PyList_SET_ITEM`` and ``PyList_GET_SIZE`` were redefined as
+function calls.
+
+
+dictobject.h
+~~~~~~~~~~~~
+
+``PyDict_GetItem`` also exists in a ``PyDict_GetItemWithError`` version that does
+not suppress errors. This suppression has the side effect of touching global
+structures. This function exists in Python 2 only since Python 2.7.12 and has
+a different name. We simply implemented the function.
+Needed to avoid the GIL when accessing dictionaries.
+
+
+methodobject.h
+~~~~~~~~~~~~~~
+
+``PyCFunction_GET_FUNCTION``, ``PyCFunction_GET_SELF`` and ``PyCFunction_GET_FLAGS``
+were redefined as function calls.
+
+Direct access to the methoddef structure is not available, and we defined
+``PepCFunction_GET_NAMESTR`` as accessor for name strings.
+
+
+pythonrun.h
+~~~~~~~~~~~
+
+The simple function ``PyRun_String`` is not available. It was re-implemented
+in a simplified version for the signature module.
+
+
+funcobject.h
+~~~~~~~~~~~~
+
+The definitions of funcobject.h are completely missing, although there
+are extra ``#ifdef`` conditional defines inside, too. This suggests that the exclusion
+was unintended.
+
+We therefore redefined ``PyFunctionObject`` as an opaque type.
+
+The missing macro ``PyFunction_Check`` was defined, and the macro
+``PyFunction_GET_CODE`` calls the according function.
+
+There is no equivalent for function name access, therefore we introduced
+``PepFunction_GetName`` either as a function or as a macro.
+
+*TODO: We should fix funcobject.h*
+
+
+classobject.h
+~~~~~~~~~~~~~
+
+Classobject is also completely not imported, instead of defining an opaque type.
+
+We defined the missing functions ``PyMethod_New``, ``PyMethod_Function`` and
+``PyMethod_Self`` and also redefined ``PyMethod_GET_SELF`` and
+``PyMethod_GET_FUNCTION`` as calls to these functions.
+
+*TODO: We should fix classobject.h*
+
+
+code.h
+~~~~~~
+
+The whole code.c code is gone, although it may make sense to
+define some minimum accessibility. This will be clarified on
+`Python-Dev`_. We needed access to code objects and defined the missing
+PepCode_GET_FLAGS and PepCode_GET_ARGCOUNT either as function or macro.
+We further added the missing flags, although few are used:
+
+``CO_OPTIMIZED`` ``CO_NEWLOCALS`` ``CO_VARARGS`` ``CO_VARKEYWORDS`` ``CO_NESTED``
+``CO_GENERATOR``
+
+*TODO: We should maybe fix code.h*
+
+.. _`Python-Dev`: https://mail.python.org/mailman/listinfo/python-dev
+
+datetime.h
+~~~~~~~~~~
+
+The DateTime module is explicitly not included in the limited API.
+We defined all the needed functions but called them via Python instead
+of direct call macros. This has a slight performance impact.
+
+The performance could be easily improved by providing an interface
+that fetches all attributes at once, instead of going through the object
+protocol every time.
+
+The re-defined macros and methods are::
+
+ PyDateTime_GET_YEAR
+ PyDateTime_GET_MONTH
+ PyDateTime_GET_DAY
+ PyDateTime_DATE_GET_HOUR
+ PyDateTime_DATE_GET_MINUTE
+ PyDateTime_DATE_GET_SECOND
+ PyDateTime_DATE_GET_MICROSECOND
+ PyDateTime_DATE_GET_FOLD
+ PyDateTime_TIME_GET_HOUR
+ PyDateTime_TIME_GET_MINUTE
+ PyDateTime_TIME_GET_SECOND
+ PyDateTime_TIME_GET_MICROSECOND
+ PyDateTime_TIME_GET_FOLD
+
+ PyDate_Check
+ PyDateTime_Check
+ PyTime_Check
+
+ PyDate_FromDate
+ PyDateTime_FromDateAndTime
+ PyTime_FromTime
+
+*XXX: We should maybe provide an optimized interface to datetime*
+
+
+object.h
+~~~~~~~~
+
+The file object.h contains the ``PyTypeObject`` structure, which is supposed
+to be completely opaque. All access to types should be done through
+``PyType_GetSlot`` calls. Due to bugs and deficiencies in the limited API
+implementation, it was not possible to do that. Instead, we have defined
+a simplified structure for ``PyTypeObject`` that has only the fields that
+are used in PySide.
+
+We will explain later why and how this was done. Here is the reduced
+structure::
+
+ typedef struct _typeobject {
+ PyVarObject ob_base;
+ const char *tp_name;
+ Py_ssize_t tp_basicsize;
+ void *X03; // Py_ssize_t tp_itemsize;
+ void *X04; // destructor tp_dealloc;
+ void *X05; // printfunc tp_print;
+ void *X06; // getattrfunc tp_getattr;
+ void *X07; // setattrfunc tp_setattr;
+ void *X08; // PyAsyncMethods *tp_as_async;
+ void *X09; // reprfunc tp_repr;
+ void *X10; // PyNumberMethods *tp_as_number;
+ void *X11; // PySequenceMethods *tp_as_sequence;
+ void *X12; // PyMappingMethods *tp_as_mapping;
+ void *X13; // hashfunc tp_hash;
+ ternaryfunc tp_call;
+ reprfunc tp_str;
+ void *X16; // getattrofunc tp_getattro;
+ void *X17; // setattrofunc tp_setattro;
+ void *X18; // PyBufferProcs *tp_as_buffer;
+ void *X19; // unsigned long tp_flags;
+ void *X20; // const char *tp_doc;
+ traverseproc tp_traverse;
+ inquiry tp_clear;
+ void *X23; // richcmpfunc tp_richcompare;
+ Py_ssize_t tp_weaklistoffset;
+ void *X25; // getiterfunc tp_iter;
+ void *X26; // iternextfunc tp_iternext;
+ struct PyMethodDef *tp_methods;
+ void *X28; // struct PyMemberDef *tp_members;
+ void *X29; // struct PyGetSetDef *tp_getset;
+ struct _typeobject *tp_base;
+ PyObject *tp_dict;
+ descrgetfunc tp_descr_get;
+ void *X33; // descrsetfunc tp_descr_set;
+ Py_ssize_t tp_dictoffset;
+ initproc tp_init;
+ allocfunc tp_alloc;
+ newfunc tp_new;
+ freefunc tp_free;
+ inquiry tp_is_gc; /* For PyObject_IS_GC */
+ PyObject *tp_bases;
+ PyObject *tp_mro; /* method resolution order */
+ } PyTypeObject;
+
+Function ``PyIndex_Check`` had to be defined in an unwanted way due to
+a Python issue. See file pep384_issue33738.cpp .
+
+There are extension structures which have been isolated as special macros that
+dynamically compute the right offsets of the extended type structures:
+
+* ``PepType_SOTP`` for ``SbkObjectTypePrivate``
+* ``PepType_SETP`` for ``SbkEnumTypePrivate``
+* ``PepType_PFTP`` for ``PySideQFlagsTypePrivate``
+
+How these extension structures are used can best be seen by searching
+``PepType_{four}`` in the source.
+
+Due to the new heaptype interface, the names of certain types contain
+now the module name in the ``tp_name`` field. To have a compatible way
+to access simple type names as C string, ``PepType_GetNameStr`` has been
+written that skips over dotted name parts.
+
+Finally, the function ``_PyObject_Dump`` was excluded from the limited API.
+This is a useful debugging aid that we always want to have available,
+so it is added back, again. Anyway, we did not reimplement it, and so
+Windows is not supported.
+Therefore, a forgotten debugging call of this functions will break COIN. :-)
+
+
+Using The New Type API
+----------------------
+
+After converting everything but the object.h file, we were a little
+bit shocked: it suddenly was clear that we would have no more
+access to type objects, and even more scary that all types which we
+use have to be heap types, only!
+
+For PySide with its intense use of heap type extensions in various
+flavors, the situation looked quite unsolvable. In the end, it was
+nicely solved, but it took almost 3.5 months to get that right.
+
+Before we see how this is done, we will explain the differences
+between the APIs and their consequences.
+
+
+The Interface
+~~~~~~~~~~~~~
+
+The old type API of Python knows static types and heap types.
+Static types are written down as a declaration of a ``PyTypeObject``
+structure with all its fields filled in. Here is for example
+the definition of the Python type ``object`` (Python 3.6)::
+
+ PyTypeObject PyBaseObject_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "object", /* tp_name */
+ sizeof(PyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ object_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ object_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)_Py_HashPointer, /* tp_hash */
+ 0, /* tp_call */
+ object_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ PyDoc_STR("object()\n--\n\nThe most base type"), /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ object_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ object_methods, /* tp_methods */
+ 0, /* tp_members */
+ object_getsets, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ object_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ object_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+ };
+
+We can write the same structure in form of a ``PyType_Spec`` structure,
+and there is even an incomplete tool *abitype.py* that does this conversion
+for us. With a few corrections, the result looks like this::
+
+ static PyType_Slot PyBaseObject_Type_slots[] = {
+ {Py_tp_dealloc, (void *)object_dealloc},
+ {Py_tp_repr, (void *)object_repr},
+ {Py_tp_hash, (void *)_Py_HashPointer},
+ {Py_tp_str, (void *)object_str},
+ {Py_tp_getattro, (void *)PyObject_GenericGetAttr},
+ {Py_tp_setattro, (void *)PyObject_GenericSetAttr},
+ {Py_tp_richcompare, (void *)object_richcompare},
+ {Py_tp_methods, (void *)object_methods},
+ {Py_tp_getset, (void *)object_getsets},
+ {Py_tp_init, (void *)object_init},
+ {Py_tp_alloc, (void *)PyType_GenericAlloc},
+ {Py_tp_new, (void *)object_new},
+ {Py_tp_free, (void *)PyObject_Del},
+ {0, 0},
+ };
+ static PyType_Spec PyBaseObject_Type_spec = {
+ "object",
+ sizeof(PyObject),
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ PyBaseObject_Type_slots,
+ };
+
+This new structure is almost compatible with the old one, but there
+are some subtle differences.
+
+* The new types are generated in one step
+
+This seems to be no problem, but it was very much, due to the way the
+types were built in PySide. Types were assembled piece by piece, and
+finally the ``PyType_Ready`` function was called.
+
+With the new API, ``PyType_Ready`` is called already at the end of
+``PyType_FromSpec``, and that meant that the logic of type creation became
+completely turned upside down.
+
+* The new types are always heaptypes
+
+With the new type creation functions, it is no longer possible to
+create "normal" types. Instead, they all have to be allocated on the
+heap and garbage collected. The user should normally not recognize this.
+But type creation is more constrained, and you cannot create a subtype
+if the ``Py_TPFLAGS_BASETYPE`` is not set. This constraint was already
+violated by PySide and needed a quite profound fix.
+
+* The new types always need a module
+
+While this is not a problem per se, the above new type spec will not create
+a usable new type, but complain with::
+
+ DeprecationWarning: builtin type object has no __module__ attribute
+
+But there are more problems:
+
+* The new types have unexpected defaults
+
+When fields are empty, you would usually assume that they stay empty.
+There are just a few corrections that ``PyType_Ready`` will do to a type.
+
+But there is the following clause in ``PyType_FromSpec`` that can give you
+many headaches::
+
+ if (type->tp_dealloc == NULL) {
+ /* It's a heap type, so needs the heap types' dealloc.
+ subtype_dealloc will call the base type's tp_dealloc, if
+ necessary. */
+ type->tp_dealloc = subtype_dealloc;
+ }
+
+In fact, before the move to the new API, the ``PyType_Ready`` function
+filled empty ``tp_dealloc`` fields with ``object_dealloc``. And the code
+that has been written with that in mind now becomes pretty wrong if suddenly
+``subtype_dealloc`` is used.
+
+The way out was to explicitly provide an ``object_dealloc`` function.
+This would then again impose a problem, because ``object_dealloc`` is not
+public. Writing our own version is easy, but it again needs access to
+type objects. But fortunately, we have broken this rule, already...
+
+
+* The new types are only partially allocated
+
+The structures used in ``PyType_FromSpec`` are almost all allocated,
+only the name field is static. This is no problem for types which are
+statically created once. But if you want to parameterize things and
+create multiple types with a single slots and spec definition, the name
+field that is used for tp_name must be allocated dynamically.
+This is misleading, since all the slots already are copies.
+
+* The new types don't support special offsets
+
+The special fields ``tp_weaklistoffset`` and ``tp_dictoffset`` are not supported
+by ``PyType_FromSpec``. Unfortunately the documentation does not tell you
+if you are allowed to set these fields manually after creating the type or not.
+We finally did it and it worked, but we are not sure about correctness.
+
+See basewrapper.cpp function ``SbkObject_TypeF()`` as the only reference to
+these fields in PySide. This single reference is absolutely necessary and
+very important, since all derived types invisibly inherit these two fields.
+
+
+Future Versions Of The Limited API
+----------------------------------
+
+As we have seen, the current version of the limited API does a bit of
+cheating, because it uses parts of the data structure that should be
+an opaque type. At the moment, this works fine because the data is
+still way more compatible as it could be.
+
+But what if this is changed in the future?
+
+We know that the data structures are stable until Python 3.8 comes out.
+Until then, the small bugs and omissions will hopefully all be solved.
+Then it will be possible to replace the current small tricks by calls
+to ``PyType_GetSlot`` in the way things should be.
+
+At the very moment when the current assumptions about the data structure
+are no longer true, we will rewrite the direct attribute access with
+calls to ``PyType_GetSlot``. After that, no more changes will be necessary.
+
+
+Appendix A: The Transition To Simpler Types
+-------------------------------------------
+
+After all code had been converted to the limited API, there was a
+remaining problem with the ``PyHeapTypeObject``.
+
+Why a problem? Well, all the type structures in shiboken use
+special extra fields at the end of the heap type object. This
+currently enforces extra knowledge at compile time about how large the
+heap type object is. In a clean implementation, we would only use
+the ``PyTypeObject`` itself and access the fields *behind* the type
+by a pointer that is computed at runtime.
+
+
+Restricted PyTypeObject
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Before we are going into details, let us motivate the existence of
+the restricted ``PyTypeObject``:
+
+Originally, we wanted to use ``PyTypeObject`` as an opaque type and
+restrict ourselves to only use the access function ``PyType_GetSlot``.
+This function allows access to all fields which are supported by
+the limited API.
+
+But this is a restriction, because we get no access to ``tp_dict``,
+which we need to support the signature extension. But we can work
+around that.
+
+The real restriction is that ``PyType_GetSlot`` only works for heap
+types. This makes the function quite useless, because we have
+no access to ``PyType_Type``, which is the most important type ``type``
+in Python. We need that for instance to compute the size of
+``PyHeapTypeObject`` dynamically.
+
+With much effort, it is possible to clone ``PyType_Type`` as a heap
+type. But due to a bug in the Pep 384 support, we need
+access to the ``nb_index`` field of a normal type. Cloning does not
+help because ``PyNumberMethods`` fields are *not* inherited.
+
+After we realized this dead end, we changed concept and did not
+use ``PyType_GetSlot`` at all (except in function ``copyNumberMethods``),
+but created a restricted ``PyTypeObject`` with only those fields
+defined that are needed in PySide.
+
+Is this breakage of the limited API? I don't think so. A special
+function runs on program startup that checks the correct position
+of the fields of ``PyTypeObject``, although a change in those fields is
+more than unlikely.
+The really crucial thing is to no longer use ``PyHeapTypeObject``
+explicitly because that *does* change its layout over time.
+
+
+Diversification
+~~~~~~~~~~~~~~~
+
+There were multiple ``Sbk{something}`` structures which all used a "d" field
+for their private data. This made it not easy to find the right
+fields when switching between objects and types::
+
+ struct LIBSHIBOKEN_API SbkObject
+ {
+ PyObject_HEAD
+ PyObject *ob_dict;
+ PyObject *weakreflist;
+ SbkObjectPrivate *d;
+ };
+
+ struct LIBSHIBOKEN_API SbkObjectType
+ {
+ PyHeapTypeObject super;
+ SbkObjectTypePrivate *d;
+ };
+
+The first step was to rename the SbkObjectTypePrivate part from "d" to
+"sotp". It was chosen to be short but easy to remember as abbreviation
+of "SbkObjectTypePrivate", leading to::
+
+ struct LIBSHIBOKEN_API SbkObjectType
+ {
+ PyHeapTypeObject super;
+ SbkObjectTypePrivate *sotp;
+ };
+
+After renaming, it was easier to do the following transformations.
+
+
+Abstraction
+~~~~~~~~~~~
+
+After renaming the type extension pointers to ``sotp``, I replaced
+them by function-like macros which did the special access *behind*
+the types, instead of those explicit fields. For instance, the
+expression::
+
+ type->sotp->converter
+
+became::
+
+ PepType_SOTP(type)->converter
+
+The macro expansion can be seen here::
+
+ #define PepHeapType_SIZE \
+ (reinterpret_cast<PyTypeObject *>(&PyType_Type)->tp_basicsize)
+
+ #define _genericTypeExtender(etype) \
+ (reinterpret_cast<char *>(etype) + PepHeapType_SIZE)
+
+ #define PepType_SOTP(etype) \
+ (*reinterpret_cast<SbkObjectTypePrivate **>(_genericTypeExtender(etype)))
+
+This looks complicated, but in the end there is only a single new
+indirection via ``PyType_Type``, which happens at runtime. This is the
+key to fulfil what Pep 384 wants to achieve: *No more version-dependent fields*.
+
+
+Simplification
+~~~~~~~~~~~~~~
+
+After all type extension fields were replaced by macro calls, we
+could remove the following version dependent re-definition of ``PyHeapTypeObject``
+::
+
+ typedef struct _pyheaptypeobject {
+ union {
+ PyTypeObject ht_type;
+ void *opaque[PY_HEAPTYPE_SIZE];
+ };
+ } PyHeapTypeObject;
+
+, and the version dependent structure::
+
+ struct LIBSHIBOKEN_API SbkObjectType
+ {
+ PyHeapTypeObject super;
+ SbkObjectTypePrivate *sotp;
+ };
+
+could be removed. SbkObjectType remains as a (deprecated)
+type alias to PyTypeObject.
+
+
+Appendix B: Verification Of PyTypeObject
+----------------------------------------
+
+We have introduced a limited PyTypeObject in the same place
+as the original PyTypeObject, and now we need to prove that
+we are allowed to do so.
+
+When using the limited API as intended, then types are completely
+opaque, and access is only through ``PyType_FromSpec`` and (from
+version 3.5 upwards) through ``PyType_GetSlot``.
+
+Python then uses all the slot definitions in the type description
+and produces a regular heap type object.
+
+
+Unused Information
+~~~~~~~~~~~~~~~~~~
+
+We know many things about types that are not explicitly said,
+but they are inherently clear:
+
+(a) The basic structure of a type is always the same, regardless
+ if it is a static type or a heap type.
+
+(b) types are evolving very slowly, and a field is never replaced
+ by another field with different semantics.
+
+Inherent rule (a) gives us the following information: If we calculate
+the offsets of the basic fields, then this info is also usable for non-heap
+types.
+
+The validation checks if rule (b) is still valid.
+
+
+How it Works
+~~~~~~~~~~~~
+
+The basic idea of the validation is to produce a new type using
+``PyType_FromSpec`` and to see where in the type structure these fields
+show up. So we build a ``PyType_Slot`` structure with all the fields we
+are using and make sure that these values are all unique in the
+type.
+
+Most fields are not interrogated by ``PyType_FromSpec``, and so we
+simply used some numeric value. Some fields are interpreted, like
+``tp_members``. This field must really be a ``PyMemberDef``. And there are
+``tp_base`` and ``tp_bases`` which have to be type objects and lists
+thereof. It was easiest to not produce these fields from scratch
+but use them from the ``type`` object ``PyType_Type``.
+
+Then one would think to write a function that searches the known
+values in the opaque type structure.
+
+But we can do better and use optimistically the observation (b):
+We simply use the restricted ``PyTypeObject`` structure and assume that
+every field lands exactly where we are awaiting it.
+
+And that is the whole proof: If we find all the disjoint values at
+the places where we expect them, then verification is done.
+
+
+About ``tp_dict``
+~~~~~~~~~~~~~~~~~
+
+One word about the ``tp_dict`` field: This field is a bit special in
+the proof, since it does not appear in the spec and cannot easily
+be checked by ``type.__dict__`` because that creates a *dictproxy*
+object. So how do we prove that is really the right dict?
+
+We have to create that ``PyMethodDef`` structure anyway, and instead of
+leaving it empty, we insert a dummy function. Then we ask the
+``tp_dict`` field if it has the awaited object in it, and that's it!
+
+#EOT
diff --git a/sources/pyside6/doc/developer/signature_doc.rst b/sources/pyside6/doc/developer/signature_doc.rst
new file mode 100644
index 000000000..a6c703dab
--- /dev/null
+++ b/sources/pyside6/doc/developer/signature_doc.rst
@@ -0,0 +1,361 @@
+.. _signature-extension:
+
+The signature C extension
+=========================
+
+This module is a C extension for CPython 3.5 and up, and CPython 2.7.
+Its purpose is to provide support for the ``__signature__`` attribute
+of builtin PyCFunction objects.
+
+
+Short Introduction to the Topic
+-------------------------------
+
+Beginning with CPython 3.5, Python functions began to grow a ``__signature__``
+attribute for normal Python functions. This is totally optional and just
+a nice-to-have feature in Python.
+
+PySide, on the other hand, could use ``__signature__`` very much, because the
+typing info for the 15000+ PySide functions is really missing, and it
+would be nice to have this info directly available.
+
+
+The Idea to Support Signatures
+------------------------------
+
+We want to have an additional ``__signature__`` attribute in all PySide
+methods, without changing lots of generated code.
+Therefore, we did not change any of the existing data structures,
+but supported the new attribute by a global dictionary.
+
+When the ``__signature__`` property is requested, a method is called that
+does a lookup in the global dict. This is a flexible approach with little impact
+to the rest of the project. It has very limited overhead compared to direct
+attribute access, but for the need of a signature access from time to time,
+this is an adequate compromise.
+
+
+How this Code Works
+~~~~~~~~~~~~~~~~~~~
+
+Signatures are supported for regular Python functions, only. Creating signatures
+for ``PyCFunction`` objects would require quite some extra effort in Python.
+
+Fortunately, we found this special *stealth* technique, that saves us most of the
+needed effort:
+
+The basic idea is to create a dummy Python function with **varnames**, **defaults**
+and **annotations** properties, and then to use the inspect
+module to create a signature object. This object is returned as the computed
+result of the ``__signature__`` attribute of the real ``PyCFunction`` object.
+
+There is one thing that really changes Python a bit:
+
+* We added the ``__signature__`` attribute to every function.
+
+That is a little change to Python that does not harm, but it saves us
+tons of code, that was needed in the early versions of the module.
+
+The internal work is done in two steps:
+
+* All functions of a class get the *signature text* when the module is imported.
+ This is only a very small overhead added to the startup time. It is a single
+ string for each whole class.
+* The actual signature object is created later, when the attribute is really
+ requested. Signatures are cached and only created on first access.
+
+Example:
+
+The ``PyCFunction`` ``QtWidgets.QApplication.palette`` is interrogated for its
+signature. That means ``pyside_sm_get___signature__()`` is called.
+It calls ``GetSignature_Function`` which returns the signature if it is found.
+
+
+Why this Code is Fast
+~~~~~~~~~~~~~~~~~~~~~
+
+It costs a little time (maybe 6 seconds) to run through every single signature
+object, since these are more than 25000 Python objects. But all the signature
+objects will be rarely accessed but in special applications.
+The normal case are only a few accesses, and these are working pretty fast.
+
+The key to make this signature module fast is to avoid computation as much as
+possible. When no signature objects are used, then almost no time is lost in
+initialization. Only the above mentioned strings and some support modules are
+additionally loaded on ``import PySide6``.
+When it comes to signature usage, then late initialization is used and cached.
+This technique is also known as *full laziness* in haskell.
+
+There are actually two locations where late initialization occurs:
+
+* ``dict`` can be no dict but a tuple. That is the initial argument tuple that
+ was saved by ``PySide_BuildSignatureArgs`` at module load time.
+ If so, then ``pyside_type_init`` in parser.py will be called,
+ which parses the string and creates the dict.
+* ``props`` can be empty. Then ``create_signature`` in loader.py
+ is called, which uses a dummy function to produce a signature instance
+ with the inspect module.
+
+The initialization that is always done is just two dictionary writes
+per class, and we have about 1000 classes.
+To measure the additional overhead, we have simulated what happens
+when ``from PySide6 import *`` is performed.
+It turned out that the overhead is below 0.5 ms.
+
+
+The Signature Package Structure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The C++ code involved with the signature module is completely in the file
+shiboken6/libshiboken/signature.cpp . All other functionality is implemented in
+the ``signature`` Python package. It has the following structure::
+
+ sources/shiboken6/shibokenmodule/files.dir/shibokensupport
+ ├── __init__.py
+ ├── feature.py
+ ├── fix-complaints.py
+ ├── shibokensupport.pyproject
+ └── signature
+ ├── PSF-3.7.0.txt
+ ├── __init__.py
+ ├── errorhandler.py
+ ├── importhandler.py
+ ├── layout.py
+ ├── lib
+ │   ├── __init__.py
+ │   ├── enum_sig.py
+ │   ├── pyi_generator.py
+ │   └── tool.py
+ ├── loader.py
+ ├── mapping.py
+ ├── parser.py
+ └── qt_attribution.json
+
+Really important are the **parser**, **mapping**, **errorhandler**, **enum_sig**,
+**layout** and **loader** modules. The rest is needed to create Python 2 compatibility
+or be compatible with embedding and installers.
+
+
+**loader.py**
+ This module assembles and imports the ``inspect`` module, and then exports the
+ ``create_signature`` function. This function takes a fake function and some
+ attributes and builds a ``__signature__`` object with the inspect module.
+
+
+**parser.py**
+ This module takes a class signatures string from C++ and parses it into the
+ needed properties for the ``create_signature`` function. Its entry point is the
+ ``pyside_type_init`` function, which is called from the C module via ``loader.py``.
+
+
+**mapping.py**
+ The purpose of the mapping module is maintaining a list of replacement strings
+ that map from the *signature text* in C to the property strings that Python
+ needs. A lot of mappings are resolved by rather complex expressions in ``parser.py``,
+ but a few hundred cases are better to spell explicitly, here.
+
+**errorhandler.py**
+ Since ``Qt For Python 5.12``, we no longer use the builtin type error messages from C++.
+ Instead, we get much better results with the signature module. At the same time,
+ this enforced supporting shiboken as well, and the signature module was no longer
+ optional.
+
+**enum_sig.py**
+ The diverse applications of the signature module all needed to iterate over modules,
+ classes and functions. In order to centralize this enumeration, the process has
+ been factored out as a context manager. The user has only to supply functions
+ that do the actual formatting.
+
+ See for example the .pyi generator ``pyside6/PySide6/support/generate_pyi.py``.
+
+**layout.py**
+ As more applications used the signature module, different formatting of signatures
+ was needed. To support that, we created the function ``create_signature``, which
+ has a parameter to choose from some predefined layouts.
+
+
+**typing27.py**
+ Python 2 has no typing module at all. This is a backport of the minimum that is needed.
+
+
+**backport_inspect.py**
+ Python 2 has an inspect module, but lacks the signature functions, completely.
+ This module adds the missing functionality, which is merged at runtime into
+ the inspect module.
+
+
+Multiple Arities
+~~~~~~~~~~~~~~~~
+
+One aspect that was ignored so far was *multiple arities*: How to handle it when
+a function has more than one signature?
+
+I did not find any note on how multiple signatures should be treated in Python,
+but this simple rules seem to work well:
+
+* If there is a list, then it is a multi-signature.
+* Otherwise, it is a simple signature.
+
+
+Impacts of The Signature Module
+-------------------------------
+
+The signature module has a number of impacts to other PySide modules, which were
+created as a consequence of its existence, and there will be a few more in the
+future:
+
+
+existence_test.py
+~~~~~~~~~~~~~~~~~
+
+The file ``pyside6/tests/registry/existence_test.py`` was written using the
+signatures from the signatures module. The idea is that there are some 15000
+functions with a certain signature.
+
+These functions should not get lost by some bad check-in. Therefore, a list
+of all existing signatures is kept as a module that assembles a
+dictionary. The function existence is checked, and also the exact arity.
+
+This module exists for every PySide release and every platform. The initial
+module is generated once and saved as ``exists_{plat}_{version}.py``.
+
+An error is normally only reported as a warning, but:
+
+
+Interaction With The Coin Module
+++++++++++++++++++++++++++++++++
+
+When this test program is run in COIN, then the warnings are turned into
+errors. The reason is that only in COIN, we have a stable configuration
+of PySide modules that can reliably be compared.
+
+These modules have the name ``exists_{platf}_{version}_ci.py``, and as a big
+exception for generated code, these files are *intentionally* checked in.
+
+
+What Happens When a List is Missing?
+++++++++++++++++++++++++++++++++++++
+
+When a new version of PySide gets created, then the existence test files
+initially do not exist.
+
+When a COIN test is run, then it will complain about the error and create
+the missing module on standard output.
+But since COIN tests are run multiple times, the output that was generated
+by the first test will still exist at the subsequent runs.
+(If COIN was properly implemented, we could not take that advantage and
+would need to implement that as an extra exception.)
+
+As a result, a missing module will be reported as a test which partially
+succeeded (called "FLAKY"). To avoid further flaky tests and to activate as a real test,
+we can now capture the error output of COIN and check the generated module
+in.
+
+
+Explicitly Enforcing Recreation
++++++++++++++++++++++++++++++++
+
+The former way to regenerate the registry files was to remove the files
+and check that in. This has the desired effect, but creates huge deltas.
+As a more efficient way, we have prepared a comment in the first line
+that contains the word "recreate".
+By uncommenting this line, a NameError is triggered, which has the same
+effect.
+
+
+init_platform.py
+++++++++++++++++
+
+For generating the ``exists_{platf}_{version}`` modules, the module
+``pyside6/tests/registry/init_platform.py`` was written. It can be used
+standalone from the commandline, to check the compatibility of some
+changes, directly.
+
+
+scrape_testresults.py
+~~~~~~~~~~~~~~~~~~~~~
+
+To simplify and automate the process of extracting the ``exists_{platf}_{version}_ci.py``
+files, the script ``pyside6/tests/registry/scrape_testresults.py`` has been written.
+
+This script scans the whole testresults website for PySide, that is::
+
+ https://testresults.qt.io/coin/api/results/pyside/pyside-setup/
+
+On the first scan, the script runs less than 30 minutes. After that, a cache
+is generated and the scan works *much* faster. The test results are placed
+into the folder ``pyside6/tests/registry/testresults/embedded/`` with a
+unique name that allows for easy sorting. Example::
+
+ testresults/embedded/2018_09_10_10_40_34-test_1536891759-exists_linux_5_11_2_ci.py
+
+These files are created only once. If they already exist, they are not touched, again.
+The file `pyside6/tests/registry/known_urls.json`` holds all scanned URLs after
+a successful scan. The ``testresults/embedded`` folder can be kept for reference
+or can be removed. Important is only the json file.
+
+The result of a scan is then directly placed into the ``pyside6/tests/registry/``
+folder. It should be reviewed and then eventually checked in.
+
+
+generate_pyi.py
+~~~~~~~~~~~~~~~
+
+``pyside6/PySide6/support/generate_pyi.py`` is still under development.
+This module generates so-called hinting stubs for integration of PySide
+with diverse *Python IDEs*.
+
+Although this module creates the stubs as an add-on, the
+impact on the quality of the signature module is considerable:
+
+The module must create syntactically correct ``.pyi`` files which contain
+not only signatures but also constants and enums of all PySide modules.
+This serves as an extra challenge that has a very positive effect on
+the completeness and correctness of signatures.
+
+The module has a ``--feature`` option to generate modified .pyi files.
+A shortcut for this command is ``pyside6-genpyi``.
+
+A useful command to change all .pyi files to use all features is
+
+.. code-block:: bash
+
+ pyside6-genpyi all --feature snake_case true_property
+
+
+pyi_generator.py
+~~~~~~~~~~~~~~~~
+
+``shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py``
+has been extracted from ``generate_pyi.py``. It allows the generation of ``.pyi``
+files from arbitrary extension modules created with shiboken.
+
+A shortcut for this command is ``shiboken6-genpyi``.
+
+
+Current Extensions
+~~~~~~~~~~~~~~~~~~
+
+Before the signature module was written, there already existed the concept of
+signatures, but in a more C++ - centric way. From that time, there existed
+the error messages, which are created when a function gets wrong argument types.
+
+These error messages were replaced by text generated on demand by
+the signature module, in order to be more consistent and correct.
+This was implemented in ``Qt For Python 5.12.0``.
+
+Additionally, the ``__doc__`` attribute of PySide methods was not set.
+It was easy to get a nice ``help()`` feature by creating signatures
+as default content for docstrings.
+This was implemented in ``Qt For Python 5.12.1``.
+
+
+Literature
+----------
+
+* `PEP 362 – Function Signature Object <https://www.python.org/dev/peps/pep-0362/>`__
+* `PEP 484 – Type Hints <https://www.python.org/dev/peps/pep-0484/>`__
+* `PEP 3107 – Function Annotations <https://www.python.org/dev/peps/pep-3107/>`__
+
+
+*Personal Remark: This module is dedicated to our lovebird "Püppi", who died on 2017-09-15.*
diff --git a/sources/pyside6/doc/example_no_image.png b/sources/pyside6/doc/example_no_image.png
new file mode 100644
index 000000000..626714074
--- /dev/null
+++ b/sources/pyside6/doc/example_no_image.png
Binary files differ
diff --git a/sources/pyside6/doc/extras/QtBluetooth.rst b/sources/pyside6/doc/extras/QtBluetooth.rst
new file mode 100644
index 000000000..965896752
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtBluetooth.rst
@@ -0,0 +1,102 @@
+Qt Bluetooth enables connectivity between Bluetooth enabled devices.
+
+The Bluetooth API provides connectivity between Bluetooth enabled devices.
+
+Currently, the API is supported on the following platforms:
+
+ +-------------------------------------+-------+---+-----------------+-----------------------------------------+--------------+
+ |API Feature |Android|iOS|Linux (BlueZ 5.x)|:ref:`macOS<Qt-WebEngine-Platform-Notes>`|Qt for Windows|
+ +-------------------------------------+-------+---+-----------------+-----------------------------------------+--------------+
+ |Classic Bluetooth |x | |x |x |x |
+ +-------------------------------------+-------+---+-----------------+-----------------------------------------+--------------+
+ |Bluetooth LE Central |x |x |x |x |x |
+ +-------------------------------------+-------+---+-----------------+-----------------------------------------+--------------+
+ |Bluetooth LE Peripheral |x |x |x |x | |
+ +-------------------------------------+-------+---+-----------------+-----------------------------------------+--------------+
+ |Bluetooth LE Advertisement & Scanning| | | | | |
+ +-------------------------------------+-------+---+-----------------+-----------------------------------------+--------------+
+
+Qt 5.14 adds a native Win32 port supporting Classic Bluetooth on Windows 7 or
+newer, and Bluetooth LE on Windows 8 or newer. It must be enabled at build time
+by configuration option -native-win32-bluetooth. The UWP backend is used by
+default if this option is not set and the Win32 target platform supports the
+required UWP APIs (minimal requirement is Windows 10 version 1507, with
+slightly improved service discovery since Windows 10 version 1607).
+
+Overview
+^^^^^^^^
+
+Bluetooth is a short-range (less than 100 meters) wireless technology. It has a
+reasonably high data transfer rate of 2.1 Mbit/s, which makes it ideal for
+transferring data between devices. Bluetooth connectivity is based on basic
+device management, such as scanning for devices, gathering information about
+them, and exchanging data between them.
+
+Qt Bluetooth supports Bluetooth Low Energy development for client/central role
+use cases. Further details can be found in the :ref:`Bluetooth Low Energy
+Overview<Bluetooth-Low-Energy-Overview>` section.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtBluetooth
+
+macOS Specific
+^^^^^^^^^^^^^^
+
+The Bluetooth API on macOS requires a certain type of event dispatcher that in
+Qt causes a dependency to
+:class:`QGuiApplication<PySide6.QtGui.QGuiApplication>` . However, you can set
+the environment variable ``QT_EVENT_DISPATCHER_CORE_FOUNDATION=1`` to
+circumvent this issue.
+
+Applications that don't use Classic Bluetooth will find a subset of
+`QtBluetooth`_ is available,
+as CoreBluetooth (Bluetooth LE) do not require either of
+:class:`QApplication<PySide6.QtWidgets.QApplication>` or
+:class:`QGuiApplication<PySide6.QtGui.QGuiApplication>` .
+
+Guides
+^^^^^^
+
+ * :ref:`Classic Bluetooth Overview<Qt-Bluetooth-Overview>`
+ * :ref:`Bluetooth Low Energy Overview<Bluetooth-Low-Energy-Overview>`
+
+
+Logging Categories
+^^^^^^^^^^^^^^^^^^
+
+The `QtBluetooth`_ module
+exports the following :class:`logging categories<~.Configuring Categories>` :
+
+ +--------------------+-------------------------------------------------------------+
+ |Logging Category |Description |
+ +--------------------+-------------------------------------------------------------+
+ |qt.bluetooth |Enables logging of cross platform code path in `QtBluetooth`_|
+ +--------------------+-------------------------------------------------------------+
+ |qt.bluetooth.android|Enables logging of the Android implementation |
+ +--------------------+-------------------------------------------------------------+
+ |qt.bluetooth.bluez |Enables logging of the BLuez/Linux implementation |
+ +--------------------+-------------------------------------------------------------+
+ |qt.bluetooth.ios |Enables logging of the iOS implementation |
+ +--------------------+-------------------------------------------------------------+
+ |qt.bluetooth.osx |Enables logging of the macOS implementation |
+ +--------------------+-------------------------------------------------------------+
+ |qt.bluetooth.windows|Enables logging of the Qt for Windows implementation |
+ +--------------------+-------------------------------------------------------------+
+
+Logging categories can be used to enable additional warning and debug output
+for `QtBluetooth`_ . More detailed information about logging can be found in
+:class:`QLoggingCategory<~.QLoggingCategory>` . A quick way to enable all
+`QtBluetooth`_ logging is to add the following line to the ``main()``
+function::
+
+ QLoggingCategory.setFilterRules("qt.bluetooth* = true")
+
+
+.. _QtBluetooth: https://doc.qt.io/qt-6/qtbluetooth-module.html
diff --git a/sources/pyside6/doc/extras/QtCharts.rst b/sources/pyside6/doc/extras/QtCharts.rst
new file mode 100644
index 000000000..8f2d768bf
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCharts.rst
@@ -0,0 +1,21 @@
+The Qt Charts module provides a set of easy-to-use chart components. It uses
+the Qt Graphics View Framework to integrate charts with modern user interfaces.
+Qt Charts can be used as QWidgets,
+:class:`QGraphicsWidget<PySide6.QtWidgets.QGraphicsWidget>` , or QML types.
+Users can easily create impressive charts by selecting one of the themes.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+ ::
+
+ from PySide6 import QtCharts
+
+The module also provides `QML types <https://doc.qt.io/qt-6/qtcharts-qmlmodule.html>`_ .
+
+.. note:: An instance of QApplication is required for the QML types as the
+ module depends on Qt's \l{Graphics View Framework} for rendering.
+ QGuiApplication is not sufficient.
diff --git a/sources/pyside6/doc/extras/QtConcurrent.rst b/sources/pyside6/doc/extras/QtConcurrent.rst
new file mode 100644
index 000000000..33c5b3bfb
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtConcurrent.rst
@@ -0,0 +1,37 @@
+The Qt Concurrent module contains functionality to support concurrent execution
+of program code.
+
+The Qt Concurrent module provides high-level APIs that make it possible to
+write multi-threaded programs without using low-level threading primitives such
+as mutexes, read-write locks, wait conditions, or semaphores. Programs written
+with Qt Concurrent automatically adjust the number of threads used according to
+the number of processor cores available. This means that applications written
+today will continue to scale when deployed on multi-core systems in the future.
+
+Qt Concurrent includes functional programming style APIs for parallel list
+processing, including a MapReduce and FilterReduce implementation for
+shared-memory (non-distributed) systems, and classes for managing asynchronous
+computations in GUI applications:
+
+ * :class:`QFuture<PySide6.QtCore.QFuture>` represents the result of an
+ asynchronous computation.
+ * :class:`QFutureIterator<~.QFutureIterator>` allows iterating through results
+ available via :class:`QFuture<PySide6.QtCore.QFuture>` .
+ * :class:`QFutureWatcher<PySide6.QtCore.QFutureWatcher>` allows monitoring a
+ :class:`QFuture<PySide6.QtCore.QFuture>` using signals-and-slots.
+ * :class:`QFutureSynchronizer<~.QFutureSynchronizer>` is a convenience class
+ that automatically synchronizes several QFutures.
+ * :class:`QPromise<~.QPromise>` provides a way to report progress and results
+ of the asynchronous computation to :class:`QFuture<PySide6.QtCore.QFuture>` .
+ Allows suspending or canceling the task when requested by
+ :class:`QFuture<PySide6.QtCore.QFuture>` .
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtConcurrent
diff --git a/sources/pyside6/doc/extras/QtCore.ClassInfo.rst b/sources/pyside6/doc/extras/QtCore.ClassInfo.rst
new file mode 100644
index 000000000..75445e1fc
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCore.ClassInfo.rst
@@ -0,0 +1,34 @@
+.. currentmodule:: PySide6.QtCore
+.. py:decorator:: ClassInfo
+
+This decorator is used to associate extra information to the class, which is available
+using ``QObject.metaObject()``. This information is used by the
+*Qt D-Bus* and *Qt Qml* modules.
+
+The extra information takes the form of a dictionary with key and value in a literal string.
+
+The recommended usage is to provide the key/value using python keyword syntax, where the
+keyword becomes the key, and the provided string becomes the value.
+
+If the key needs to contain special characters (spaces, commas, '::', start with a number, etc),
+it is also possible to pass a python dictionary with arbitrary strings for both the key and
+value and enabling special characters in the key.
+
+.. note:: This decorator is a implementation of the Q_CLASSINFO macro.
+
+
+Example
+-------
+
+.. code-block:: python
+
+ # Recommended syntax
+ @ClassInfo(Author='PySide Team', URL='http://www.pyside.org')
+ class MyObject(QObject):
+ ...
+
+
+ # Provided to support keys not supported by Python's keyword syntax
+ @ClassInfo({'Some key text $': 'This syntax supports special characters in keys'})
+ class MyObject(QObject):
+ ...
diff --git a/sources/pyside6/doc/extras/QtCore.Property.rst b/sources/pyside6/doc/extras/QtCore.Property.rst
new file mode 100644
index 000000000..9ed7de427
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCore.Property.rst
@@ -0,0 +1,129 @@
+.. currentmodule:: PySide6.QtCore
+.. py:class:: Property
+
+Detailed Description
+--------------------
+
+The Property function lets you declare properties that
+behave both as Qt and Python properties, and have their
+getters and setters defined as Python functions.
+
+They are equivalent to the ``Q_PROPERTY`` macro in the `Qt Docs`_.
+
+Here is an example that illustrates how to use this
+function:
+
+.. code-block:: python
+ :linenos:
+
+ from PySide6.QtCore import QObject, Property
+
+ class MyObject(QObject):
+ def __init__(self, startval=42):
+ QObject.__init__(self)
+ self.ppval = startval
+
+ def readPP(self):
+ return self.ppval
+
+ def setPP(self, val):
+ self.ppval = val
+
+ pp = Property(int, readPP, setPP)
+
+ obj = MyObject()
+ obj.pp = 47
+ print(obj.pp)
+
+The full options for ``QtCore.Property`` can be found with ``QtCore.Property.__doc__``:
+
+.. code-block:: python
+
+ Property(self, type: type,
+ fget: Optional[Callable] = None,
+ fset: Optional[Callable] = None,
+ freset: Optional[Callable] = None,
+ fdel: Optional[Callable] = None,
+ doc: str = '',
+ notify: Optional[Callable] = None,
+ designable: bool = True,
+ scriptable: bool = True,
+ stored: bool = True, user: bool = False,
+ constant: bool = False,
+ final: bool = False) -> PySide6.QtCore.Property
+
+Normally, only ``type``, ``fget``and ``fset`` are used.
+
+
+Properties compared with Python properties
+------------------------------------------
+
+``Python`` has property objects very similar to ``QtCore.Property``.
+Despite the fact that the latter has an extra ``freset`` function, the usage
+of properties is almost the same. The main difference is that ``QtCore.Property``
+requires a ``type`` parameter.
+
+In the above example, the following lines would be equivalent properties:
+
+.. code-block:: python
+
+ pp = QtCore.Property(int, readPP, setPP) # PySide version
+ pp = property(readPP, setPP) # Python version
+
+As you know from the `Python Docs`_, ``Python`` allows to break the property
+creation into multiple steps, using the decorator syntax. We can do this in
+``PySide`` as well:
+
+.. code-block:: python
+ :linenos:
+
+ from PySide6.QtCore import QObject, Property
+
+ class MyObject(QObject):
+ def __init__(self, startval=42):
+ QObject.__init__(self)
+ self.ppval = startval
+
+ @Property(int)
+ def pp(self):
+ return self.ppval
+
+ @pp.setter
+ def pp(self, val):
+ self.ppval = val
+
+ obj = MyObject()
+ obj.pp = 47
+ print(obj.pp)
+
+Please be careful here: The two ``Python`` functions have the same name, intentionally.
+This is needed to let ``Python`` know that these functions belong to the same property.
+
+
+Properties in QML expressions
+-----------------------------
+
+If you are using properties of your objects in QML expressions,
+QML requires that the property changes are notified. Here is an
+example illustrating how to do this:
+
+.. code-block:: python
+ :linenos:
+
+ from PySide6.QtCore import QObject, Signal, Property
+
+ class Person(QObject):
+
+ name_changed = Signal()
+
+ def __init__(self, name):
+ QObject.__init__(self)
+ self._person_name = name
+
+ def _name(self):
+ return self._person_name
+
+ name = Property(str, _name, notify=name_changed)
+
+.. _`Python Docs`: https://docs.python.org/3/library/functions.html?highlight=property#property
+.. _`Qt Docs`: https://doc.qt.io/qt-6/properties.html
diff --git a/sources/pyside6/doc/extras/QtCore.QEnum.rst b/sources/pyside6/doc/extras/QtCore.QEnum.rst
new file mode 100644
index 000000000..7ea35d8af
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCore.QEnum.rst
@@ -0,0 +1,27 @@
+.. currentmodule:: PySide6.QtCore
+.. py:decorator:: QEnum
+
+This class decorator is equivalent to the `Q_ENUM` macro from Qt. The decorator
+is used to register a Python Enum derived class to the meta-object system,
+which is available via `QObject.staticMetaObject`. The enumerator must be in a
+QObject derived class to be registered.
+
+Example
+-------
+
+::
+
+ from enum import Enum, auto
+
+ from PySide6.QtCore import QEnum, QObject
+
+ class Demo(QObject):
+
+ @QEnum
+ class Orientation(Enum):
+ North, East, South, West = range(4)
+
+See :deco:`QFlag` for registering Python Flag derived classes.
+
+Meanwhile all enums and flags have been converted to Python Enums
+(default since ``PySide 6.4``), see the :ref:`NewEnumSystem` section.
diff --git a/sources/pyside6/doc/extras/QtCore.QFlag.rst b/sources/pyside6/doc/extras/QtCore.QFlag.rst
new file mode 100644
index 000000000..dd4f02800
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCore.QFlag.rst
@@ -0,0 +1,74 @@
+.. currentmodule:: PySide6.QtCore
+.. py:decorator:: QFlag
+
+QFlag handles a variation of the Python Enum, the Flag class.
+
+Please do not confuse that with the Qt QFlags concept. Python does
+not use that concept, it has its own class hierarchy, instead.
+For more details, see the `Python enum documentation <https://docs.python.org/3/library/enum.html>`_.
+
+Example
+-------
+
+::
+
+ from enum import Flag, auto
+
+ from PySide6.QtCore import QFlag, QObject
+
+ class Demo(QObject):
+
+ @QFlag
+ class Color(Flag):
+ RED = auto()
+ BLUE = auto()
+ GREEN = auto()
+ WHITE = RED | BLUE | GREEN
+
+
+Details about Qt Flags:
+-----------------------
+
+There are some small differences between Qt flags and Python flags.
+In Qt, we have for instance these declarations:
+
+::
+
+ enum QtGui::RenderHint { Antialiasing, TextAntialiasing, SmoothPixmapTransform,
+ HighQualityAntialiasing, NonCosmeticDefaultPen }
+ flags QtGui::RenderHints
+
+The equivalent Python notation would look like this:
+
+::
+
+ @QFlag
+ class RenderHints(enum.Flag)
+ Antialiasing = auto()
+ TextAntialiasing = auto()
+ SmoothPixmapTransform = auto()
+ HighQualityAntialiasing = auto()
+ NonCosmeticDefaultPen = auto()
+
+
+As another example, the Qt::AlignmentFlag flag has 'AlignmentFlag' as the enum
+name, but 'Alignment' as the type name. Non flag enums have the same type and
+enum names.
+
+::
+
+ enum Qt::AlignmentFlag
+ flags Qt::Alignment
+
+The Python way to specify this would be
+
+::
+
+ @QFlag
+ class Alignment(enum.Flag):
+ ...
+
+See :deco:`QEnum` for registering Python Enum derived classes.
+
+Meanwhile all enums and flags have been converted to Python Enums
+(default since ``PySide 6.4``), see the :ref:`NewEnumSystem` section.
diff --git a/sources/pyside6/doc/extras/QtCore.Signal.rst b/sources/pyside6/doc/extras/QtCore.Signal.rst
new file mode 100644
index 000000000..c83a76a83
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCore.Signal.rst
@@ -0,0 +1,58 @@
+.. currentmodule:: PySide6.QtCore
+.. py:class:: Signal
+
+Synopsis
+--------
+
+Functions
+^^^^^^^^^
+
++-----------------------------------------------------+
+|def :meth:`connect<Signal.connect>` (receiver) |
++-----------------------------------------------------+
+|def :meth:`disconnect<Signal.disconnect>` (receiver) |
++-----------------------------------------------------+
+|def :meth:`emit<Signal.disconnect>` (\*args) |
++-----------------------------------------------------+
+
+Detailed Description
+--------------------
+
+The :class:`~.Signal` class provides a way to declare and connect Qt
+signals in a pythonic way.
+
+.. class:: PySide6.QtCore.Signal([type1 [, type2...]] [, name="" [, arguments=[]]])
+
+ :param name: str
+ :param arguments: list
+
+``Signal`` takes a list of Python types of the arguments.
+
+ It is possible to use the same signal name with different types by
+ passing a list of tuples representing the signatures, but this is a legacy
+ technique recommended against in new code (see
+ :ref:`overloading-signals-and-slots`).
+
+The optional named argument ``name`` defines the signal name. If nothing is
+passed, the new signal will have the same name as the variable that it is
+being assigned to.
+
+The optional named argument ``arguments`` receives a list of strings
+denoting the argument names. This is useful for QML applications which
+may refer to the emitted values by name.
+
+.. method:: Signal.connect(receiver[, type=Qt.AutoConnection])
+
+ Create a connection between this signal and a `receiver`, the `receiver`
+ can be a Python callable, a :class:`Slot` or a :class:`Signal`.
+
+.. method:: Signal.disconnect(receiver)
+
+ Disconnect this signal from a `receiver`, the `receiver` can be a Python
+ callable, a :class:`Slot` or a :class:`Signal`.
+
+.. method:: Signal.emit(*args)
+
+ `args` is the arguments to pass to any connected slots, if any.
+
+.. seealso:: :ref:`signals-and-slots`
diff --git a/sources/pyside6/doc/extras/QtCore.Slot.rst b/sources/pyside6/doc/extras/QtCore.Slot.rst
new file mode 100644
index 000000000..98a1d465b
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCore.Slot.rst
@@ -0,0 +1,42 @@
+.. currentmodule:: PySide6.QtCore
+.. py:decorator:: Slot([type1 [, type2...]] [, name="" [, result=None, [tag=""]]])
+
+ :param name: str
+ :param result: type
+ :param tag: str
+
+``Slot`` takes a list of Python types of the arguments.
+
+The optional named argument ``name`` defines the slot name. If nothing is
+passed, the slot name will be the decorated function name.
+
+The optional named argument ``result`` specifies the return type.
+
+The optional named argument ``tag`` specifies a value to be returned
+by ``QMetaMethod.tag()``.
+
+This implementation is functionally compatible with the PyQt one.
+
+======= =========== ======
+Module PyQt PySide
+======= =========== ======
+QtCore pyqtSignal Signal
+QtCore pyqtSlot Slot
+======= =========== ======
+
+.. seealso:: :ref:`signals-and-slots`
+
+Q_INVOKABLE
+-----------
+
+There is no equivalent of the Q_INVOKABLE macro of Qt
+since PySide6 slots can actually have return values.
+If you need to create a invokable method that returns some value,
+declare it as a slot, e.g.:
+
+::
+
+ class Foo(QObject):
+ @Slot(float, result=int)
+ def getFloatReturnInt(self, f):
+ return int(f)
diff --git a/sources/pyside6/doc/extras/QtCore.rst b/sources/pyside6/doc/extras/QtCore.rst
new file mode 100644
index 000000000..ac72bc487
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtCore.rst
@@ -0,0 +1,61 @@
+The Qt Core module is part of Qt's essential modules.
+
+The Qt Core module adds these features to C++:
+
+ * a very powerful mechanism for seamless object communication called signals and slots
+ * queryable and designable object properties
+ * hierarchical and queryable object trees
+
+The following pages provide more information about Qt's core features:
+
+ * :ref:`The Meta-Object System<The-Meta-Object-System>`
+ * :ref:`The Property System<The-Property-System>`
+ * :ref:`Object Model<Object-Model>`
+ * :ref:`Object Trees & Ownership<Object-Trees---Ownership>`
+ * :ref:`Signals & Slots<Signals---Slots>`
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtCore
+
+Threading and Concurrent Programming
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Qt provides thread support in the form of platform-independent
+threading classes, a thread-safe way of posting events, and
+signal-slot connections across threads. Multithreaded programming is
+also a useful paradigm for performing time-consuming operations
+without freezing the user interface of an application.
+
+The Thread Support in Qt page contains information on implementing
+threads in applications. Additional concurrent classes are provided by
+the :ref:`Qt Concurrent<Qt-Concurrent>` module.
+
+Input/Output and Resources
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Qt provides a resource system for organizing application files and
+assets, a set of containers, and classes for receiving input and
+printing output.
+
+ * :ref:`Serializing Qt Data Types<Serializing-Qt-Data-Types>`
+
+In addition, Qt Core provides a platform-independent mechanism for
+storing binary files in the application's executable.
+
+ * :ref:`The Qt Resource System<using_qrc_files>`
+
+Additional Frameworks
+^^^^^^^^^^^^^^^^^^^^^
+
+Qt Core also provides some of Qt's key frameworks.
+
+ * :ref:`The Animation Framework<The-Animation-Framework>`
+ * `JSON Support in Qt <https://doc.qt.io/qt-6/json.html>`_
+ * :ref:`The Event System<The-Event-System>`
diff --git a/sources/pyside6/doc/extras/QtDBus.rst b/sources/pyside6/doc/extras/QtDBus.rst
new file mode 100644
index 000000000..3b9cd775a
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtDBus.rst
@@ -0,0 +1,193 @@
+An introduction to Inter-Process Communication and Remote Procedure
+Calling with D-Bus.
+
+Introduction
+^^^^^^^^^^^^
+
+D-Bus is an Inter-Process Communication (IPC) and Remote Procedure
+Calling (RPC) mechanism originally developed for Linux to replace
+existing and competing IPC solutions with one unified protocol. It has
+also been designed to allow communication between system-level
+processes (such as printer and hardware driver services) and normal
+user processes.
+
+It uses a fast, binary message-passing protocol, which is suitable for
+same-machine communication due to its low latency and low overhead.
+Its specification is currently defined by the ``freedesktop.org``
+project, and is available to all parties.
+
+Communication in general happens through a central server application,
+called the "bus" (hence the name), but direct
+application-to-application communication is also possible. When
+communicating on a bus, applications can query which other
+applications and services are available, as well as activate one on
+demand.
+
+The Buses
+^^^^^^^^^
+
+D-Bus buses are used when many-to-many communication is desired. In
+order to achieve that, a central server is launched before any
+applications can connect to the bus: this server is responsible for
+keeping track of the applications that are connected and for properly
+routing messages from their source to their destination.
+
+In addition, D-Bus defines two well-known buses, called the system bus
+and the session bus. These buses are special in the sense that they
+have well-defined semantics: some services are defined to be found in
+one or both of these buses.
+
+For example, an application wishing to query the list of hardware
+devices attached to the computer will probably communicate to a
+service available on the system bus, while the service providing
+opening of the user's web browser will probably be found on the
+session bus.
+
+On the system bus, one can also expect to find restrictions on what
+services each application is allowed to offer. Therefore, one can be
+reasonably certain that, if a certain service is present, it is being
+offered by a trusted application.
+
+Messages
+^^^^^^^^
+
+On the low level, applications communicate over D-Bus by sending
+messages to one another. Messages are used to relay the remote
+procedure calls as well as the replies and errors associated with
+them. When used over a bus, messages have a destination, which means
+they are routed only to the interested parties, avoiding congestion
+due to "swarming" or broadcasting.
+
+A special kind of message called a "signal message" (a concept based
+on Qt's :ref:`Signals and Slots<Signals---Slots>` mechanism), however,
+does not have a pre-defined destination. Since its purpose is to be
+used in a one-to-many context, signal messages are designed to work
+over an "opt-in" mechanism.
+
+The Qt D-Bus module fully encapsulates the low-level concept of
+messages into a simpler, object-oriented approach familiar to Qt
+developers. In most cases, the developer need not worry about sending
+or receiving messages.
+
+Service Names
+^^^^^^^^^^^^^
+
+When communicating over a bus, applications obtain what is called a
+"service name": it is how that application chooses to be known by
+other applications on the same bus. The service names are brokered by
+the D-Bus bus daemon and are used to route messages from one
+application to another. An analogous concept to service names are IP
+addresses and hostnames: a computer normally has one IP address and
+may have one or more hostnames associated with it, according to the
+services that it provides to the network.
+
+On the other hand, if a bus is not used, service names are also not
+used. If we compare this to a computer network again, this would
+equate to a point-to-point network: since the peer is known, there is
+no need to use hostnames to find it or its IP address.
+
+The format of a D-Bus service name is in fact very similar to a host
+name: it is a dot-separated sequence of letters and digits. The common
+practice is even to name one's service name according to the domain
+name of the organization that defined that service.
+
+For example, the D-Bus service is defined by ``freedesktop.org`` and
+can be found on the bus under the service name:
+
+ ::
+
+ org.freedesktop.DBus
+
+Object Paths
+^^^^^^^^^^^^
+
+Like network hosts, applications provide specific services to other
+applications by exporting objects. Those objects are hierarchically
+organized, much like the parent-child relationship that classes
+derived from :class:`QObject<PySide6.QtCore.QObject>` possess. One
+difference, however, is that there is the concept of "root object",
+which all objects have as the ultimate parent.
+
+If we continue our analogy with Web services, object paths equate to
+the path part of a URL.
+
+Like them, object paths in D-Bus are formed resembling path names on
+the filesystem: they are slash-separated labels, each consisting of
+letters, digits and the underscore character ("\_"). They must always
+start with a slash and must not end with one.
+
+Interfaces
+^^^^^^^^^^
+
+Interfaces are similar to C++ abstract classes and Java's
+``interface`` keyword and declare the "contract" that is established
+between caller and callee. That is, they establish the names of the
+methods, signals, and properties that are available as well as the
+behavior that is expected from either side when communication is
+established.
+
+Qt uses a very similar mechanism in its Plugin system: Base classes in
+C++ are associated with a unique identifier by way of the
+:meth:`Q\_DECLARE\_INTERFACE()<~QtDBus.Q_DECLARE_INTERFACE>` macro.
+
+D-Bus interface names are, in fact, named in a manner similar to what
+is suggested by the Qt Plugin System: an identifier usually
+constructed from the domain name of the entity that defined that
+interface.
+
+Cheat Sheet
+^^^^^^^^^^^
+
+To facilitate remembering of the naming formats and their purposes,
+the following table can be used:
+
+ +-------------+------------------+---------------------------------------+
+ |D-Bus Concept|Analogy |Name format |
+ +-------------+------------------+---------------------------------------+
+ |Service name |Network hostnames |Dot-separated ("looks like a hostname")|
+ +-------------+------------------+---------------------------------------+
+ |Object path |URL path component|Slash-separated ("looks like a path") |
+ +-------------+------------------+---------------------------------------+
+ |Interface |Plugin identifier |Dot-separated |
+ +-------------+------------------+---------------------------------------+
+
+Debugging
+^^^^^^^^^
+
+When developing applications that use D-Bus, it is sometimes useful to
+be able to see information about the messages that are sent and
+received across the bus by each application.
+
+This feature can be enabled on a per-application basis by setting the
+``QDBUS_DEBUG`` environment variable before running each application.
+For example, we can enable debugging only for the car in the
+:ref:`D-Bus Remote Controlled Car
+Example<D-Bus-Remote-Controlled-Car-Example>` by running the
+controller and the car in the following way:
+
+ ::
+
+ QDBUS_DEBUG=1 python examples/dbus/pingpong/pong.py
+
+Information about the messages will be written to the console the
+application was launched from.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtDBus
+
+Further Reading
+^^^^^^^^^^^^^^^
+
+The following documents contain information about Qt's D-Bus integration features, and provide details about the mechanisms used to send and receive type information over the bus:
+
+ * `Using Qt D-Bus Adaptors <https://doc.qt.io/qt-6/usingadaptors.html>`_
+ * `The Qt D-Bus Type System <https://doc.qt.io/qt-6/qdbustypesystem.html>`_
+ * `Qt D-Bus XML compiler (qdbusxml2cpp) <https://doc.qt.io/qt-6/qdbusxml2cpp.html>`_
+ * `D-Bus Viewer <https://doc.qt.io/qt-6/qdbusviewer.html>`_
diff --git a/sources/pyside6/doc/extras/QtDataVisualization.rst b/sources/pyside6/doc/extras/QtDataVisualization.rst
new file mode 100644
index 000000000..66e2d9523
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtDataVisualization.rst
@@ -0,0 +1,30 @@
+Provides functionality for 3D visualization.
+
+The Qt Data Visualization module enables you to visualize data in 3D as bar,
+scatter, and surface graphs. It's especially useful for visualizing depth maps
+and large quantities of rapidly changing data, such as data received from
+multiple sensors. The look and feel of graphs can be customized by using themes
+or by adding custom items and labels.
+
+Qt Data Visualization is built on Qt 6 and OpenGL to take advantage of hardware
+acceleration and Qt Quick 2.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtDataVisualization
+
+The module also provides `QML types <https://doc.qt.io/qt-6/qtdatavisualization-qmlmodule.html>`_ .
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+ * :ref:`Overview<Qt-Data-Visualization-Overview>`
+ * :ref:`Data Handling<Qt-Data-Visualization-Data-Handling>`
+ * :ref:`Interacting with Data<Qt-Data-Visualization-Interacting-with-Data>`
+ * :ref:`Known Issues<Qt-Data-Visualization-Known-Issues>`
diff --git a/sources/pyside6/doc/extras/QtDesigner.QPyDesignerContainerExtension.rst b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerContainerExtension.rst
new file mode 100644
index 000000000..a3e5ef511
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerContainerExtension.rst
@@ -0,0 +1,9 @@
+.. currentmodule:: PySide6.QtDesigner
+.. py:class:: QPyDesignerContainerExtension
+
+QPyDesignerContainerExtension is the base class for implementing
+`QDesignerContainerExtension class`_
+for a *Qt Widgets Designer* custom widget plugin in Python.
+It provides the required inheritance from **QObject**.
+
+.. _QDesignerContainerExtension class: https://doc.qt.io/qt-6/qdesignercontainerextension.html
diff --git a/sources/pyside6/doc/extras/QtDesigner.QPyDesignerCustomWidgetCollection.rst b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerCustomWidgetCollection.rst
new file mode 100644
index 000000000..615ca4eec
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerCustomWidgetCollection.rst
@@ -0,0 +1,52 @@
+.. currentmodule:: PySide6.QtDesigner
+.. py:class:: QPyDesignerCustomWidgetCollection
+
+Synopsis
+--------
+
+Functions
+^^^^^^^^^
+
++------------------------------------------------------------------------------------------------+
+|def :meth:`registerCustomWidget<QPyDesignerCustomWidgetCollection.registerCustomWidget>` (type) |
++------------------------------------------------------------------------------------------------+
+|def :meth:`addCustomWidget<QPyDesignerCustomWidgetCollection.addCustomWidget>` (custom_widget) |
++------------------------------------------------------------------------------------------------+
+
+Detailed Description
+--------------------
+
+The :class:`~.QPyDesignerCustomWidgetCollection` implements
+`QDesignerCustomWidgetCollectionInterface <https://doc.qt.io/qt-6/qdesignercustomwidgetcollectioninterface.html>`_
+and provides static helper functions for registering custom widgets by
+type or by implementing
+`QDesignerCustomWidgetInterface`_ .
+
+The usage is explained in :ref:`designer_custom_widgets`.
+
+.. py:staticmethod:: QPyDesignerCustomWidgetCollection.registerCustomWidget(type[, xml=""[, tool_tip=""[, icon=""[, group=""[container=False]]]]])
+
+ Registers an instance of a Python-implemented QWidget by type with
+ *Qt Widgets Designer*.
+
+ The optional keyword arguments correspond to the getters of
+ `QDesignerCustomWidgetInterface`_ :
+
+ :param str xml: A snippet of XML code in ``.ui`` format that specifies how the widget is created and sets initial property values.
+ :param str tool_tip: Tool tip to be shown in the widget box.
+ :param str icon: Path to an icon file be shown in the widget box.
+ :param str group: Category for grouping widgets in the widget box.
+ :param str module: Module name for generating the import code by `uic <https://doc.qt.io/qt-6/uic.html>`_ .
+ :param bool container: Indicates whether the widget is a container like `QGroupBox`, that is, child widgets can be placed on it.
+
+ .. seealso:: :meth:`registerCustomWidget()<PySide6.QtUiTools.QUiLoader.registerCustomWidget>`
+
+.. py:staticmethod:: QPyDesignerCustomWidgetCollection.addCustomWidget(custom_widget)
+
+ Adds a custom widget (implementation of
+ `QDesignerCustomWidgetInterface`_)
+ with *Qt Widgets Designer*.
+
+ :param QDesignerCustomWidgetInterface custom_widget: Custom widget instance
+
+.. _QDesignerCustomWidgetInterface: https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html
diff --git a/sources/pyside6/doc/extras/QtDesigner.QPyDesignerMemberSheetExtension.rst b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerMemberSheetExtension.rst
new file mode 100644
index 000000000..ef2356221
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerMemberSheetExtension.rst
@@ -0,0 +1,9 @@
+.. currentmodule:: PySide6.QtDesigner
+.. py:class:: QPyDesignerMemberSheetExtension
+
+QPyDesignerMemberSheetExtension is the base class for implementing
+`QDesignerMemberSheetExtension class`_
+for a *Qt Widgets Designer* custom widget plugin in Python.
+It provides the required inheritance from **QObject**.
+
+.. _QDesignerMemberSheetExtension class: https://doc.qt.io/qt-6/qdesignermembersheetextension.html
diff --git a/sources/pyside6/doc/extras/QtDesigner.QPyDesignerTaskMenuExtension.rst b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerTaskMenuExtension.rst
new file mode 100644
index 000000000..e5e13122d
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtDesigner.QPyDesignerTaskMenuExtension.rst
@@ -0,0 +1,9 @@
+.. currentmodule:: PySide6.QtDesigner
+.. py:class:: QPyDesignerTaskMenuExtension
+
+QPyDesignerTaskMenuExtension is the base class for implementing
+`QDesignerTaskMenuExtension class`_
+for a *Qt Widgets Designer* custom widget plugin in Python.
+It provides the required inheritance from **QObject**.
+
+.. _QDesignerTaskMenuExtension class: https://doc.qt.io/qt-6/qdesignertaskmenuextension.html
diff --git a/sources/pyside6/doc/extras/QtDesigner.rst b/sources/pyside6/doc/extras/QtDesigner.rst
new file mode 100644
index 000000000..844f25b7b
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtDesigner.rst
@@ -0,0 +1,18 @@
+Provides classes to create your own custom widget plugins for
+*Qt Widgets Designer* and classes to access *Qt Widgets Designer*
+components.
+
+In addition, the :class:`QFormBuilder<PySide6.QtDesigner.QFormBuilder>` class
+provides the possibility of constructing user interfaces from UI files at
+run-time.
+
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtDesigner
diff --git a/sources/pyside6/doc/extras/QtGui.rst b/sources/pyside6/doc/extras/QtGui.rst
new file mode 100644
index 000000000..8341ff453
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtGui.rst
@@ -0,0 +1,142 @@
+The Qt GUI module provides classes for windowing system integration,
+event handling, OpenGL and OpenGL ES integration, 2D graphics, basic
+imaging, fonts, and text. These classes are used internally by Qt's
+user interface technologies and can also be used directly, for
+instance to write applications using low-level OpenGL ES graphics
+APIs.
+
+For application developers writing user interfaces, Qt provides higher
+level APIs, like Qt Quick, that are much more suitable than the
+enablers found in the Qt GUI module.
+
+Application Windows
+^^^^^^^^^^^^^^^^^^^
+
+The most important classes in the Qt GUI module are
+:class:`QGuiApplication<PySide6.QtGui.QGuiApplication>` and
+:class:`QWindow<PySide6.QtGui.QWindow>` . A Qt application that wants
+to show content on screen will need to make use of these.
+:class:`QGuiApplication<PySide6.QtGui.QGuiApplication>` contains the
+main event loop, where all events from the window system and other
+sources are processed and dispatched. It also handles the
+application's initialization and finalization.
+
+The :class:`QWindow<PySide6.QtGui.QWindow>` class represents a window
+in the underlying windowing system. It provides a number of virtual
+functions to handle events ( :class:`QEvent<PySide6.QtCore.QEvent>` )
+from the windowing system, such as touch-input, exposure, focus, key
+strokes, and geometry changes.
+
+2D Graphics
+^^^^^^^^^^^
+
+The Qt GUI module contains classes for 2D graphics, imaging, fonts,
+and advanced typography.
+
+A :class:`QWindow<PySide6.QtGui.QWindow>` created with the surface
+type :attr:`RasterSurface<QSurface.SurfaceType>` can be used in
+combination with :class:`QBackingStore<PySide6.QtGui.QBackingStore>`
+and :class:`QPainter<PySide6.QtGui.QPainter>` , Qt's highly optimized
+2D vector graphics API. :class:`QPainter<PySide6.QtGui.QPainter>`
+supports drawing lines, polygons, vector paths, images, and text. For
+more information, see :ref:`Paint System<Paint-System>` and
+:ref:`Raster Window Example<Raster-Window-Example>` .
+
+Qt can load and save images using the
+:class:`QImage<PySide6.QtGui.QImage>` and
+:class:`QPixmap<PySide6.QtGui.QPixmap>` classes. By default, Qt
+supports the most common image formats including JPEG and PNG among
+others. Users can add support for additional formats via the
+:class:`QImageIOPlugin<~.QImageIOPlugin>` class. For more information,
+see :ref:`Reading and Writing Image
+Files<Reading-and-Writing-Image-Files>` .
+
+Typography in Qt is done with
+:class:`QTextDocument<PySide6.QtGui.QTextDocument>` , which uses the
+:class:`QPainter<PySide6.QtGui.QPainter>` API in combination with Qt's
+font classes, primarily :class:`QFont<PySide6.QtGui.QFont>` .
+Applications that prefer more low-level APIs to text and font handling
+can use classes like :class:`QRawFont<PySide6.QtGui.QRawFont>` and
+:class:`QGlyphRun<PySide6.QtGui.QGlyphRun>` .
+
+OpenGL and OpenGL ES Integration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:class:`QWindow<PySide6.QtGui.QWindow>` supports rendering using
+OpenGL and OpenGL ES, depending on what the platform supports. OpenGL
+rendering is enabled by setting the
+:class:`QWindow<PySide6.QtGui.QWindow>` 's surface type to
+:attr:`OpenGLSurface<QSurface.SurfaceType>` , choosing the format
+attributes with :class:`QSurfaceFormat<PySide6.QtGui.QSurfaceFormat>`
+, and then creating a
+:class:`QOpenGLContext<PySide6.QtGui.QOpenGLContext>` to manage the
+native OpenGL context. In addition, Qt has
+:class:`QOpenGLPaintDevice<PySide6.QtOpenGL.QOpenGLPaintDevice>` ,
+which enables the use of OpenGL accelerated
+:class:`QPainter<PySide6.QtGui.QPainter>` rendering, as well as
+convenience classes that simplify the writing of OpenGL code and hides
+the complexities of extension handling and the differences between
+OpenGL ES 2 and desktop OpenGL. The convenience classes include
+:class:`QOpenGLFunctions<PySide6.QtGui.QOpenGLFunctions>` that lets an
+application use all the OpenGL ES 2 functions on desktop OpenGL
+without having to manually resolve the OpenGL function pointers. This
+enables cross-platform development of applications targeting mobile or
+embedded devices, and provides classes that wrap native OpenGL
+functionality in a simpler Qt API.
+
+For more information, see the :ref:`OpenGL Window Example<OpenGL-Window-Example>` .
+
+The Qt GUI module also contains a few math classes to aid with the
+most common mathematical operations related to 3D graphics. These
+classes include :class:`QMatrix4x4<PySide6.QtGui.QMatrix4x4>` ,
+:class:`QVector4D<PySide6.QtGui.QVector4D>` , and
+:class:`QQuaternion<PySide6.QtGui.QQuaternion>` .
+
+A :class:`QWindow<PySide6.QtGui.QWindow>` created with the
+:attr:`OpenGLSurface<QSurface.SurfaceType>` can be used in combination
+with :class:`QPainter<PySide6.QtGui.QPainter>` and
+:class:`QOpenGLPaintDevice<PySide6.QtOpenGL.QOpenGLPaintDevice>` to
+have OpenGL hardware-accelerated 2D graphics by sacrificing some of
+the visual quality.
+
+Vulkan Integration
+^^^^^^^^^^^^^^^^^^
+
+Qt GUI has support for the `Vulkan <https://www.khronos.org/vulkan/>`_
+API. Qt applications require the presence of the `LunarG Vulkan SDK
+<https://www.lunarg.com/vulkan-sdk/>`_ .
+
+On Windows, the SDK sets the environment variable ``VULKAN_SDK``\,
+which will be detected by the ``configure`` script.
+
+On Android, Vulkan headers were added in API level 24 of the NDK.
+
+Relevant classes:
+
+* QVulkanDeviceFunctions
+ * :class:`QVulkanExtension<~.QVulkanExtension>`
+ * QVulkanFunctions
+ * :class:`QVulkanInfoVector<~.QVulkanInfoVector>`
+ * :class:`QVulkanInstance<~.QVulkanInstance>`
+ * :class:`QVulkanWindow<~.QVulkanWindow>`
+ * :class:`QVulkanWindowRenderer<~.QVulkanWindowRenderer>`
+
+For more information, see the
+:ref:`Hello Vulkan Widget Example<Hello-Vulkan-Widget-Example>` and the
+:ref:`Hello Vulkan Window Example<Hello-Vulkan-Window-Example>` .
+
+Drag and Drop
+^^^^^^^^^^^^^
+
+Qt GUI includes support for drag and drop. The
+:ref:`Drag and Drop<Drag-and-Drop>` overview has more information.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtGui
diff --git a/sources/pyside6/doc/extras/QtHelp.rst b/sources/pyside6/doc/extras/QtHelp.rst
new file mode 100644
index 000000000..f6013486e
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtHelp.rst
@@ -0,0 +1,19 @@
+The QtHelp module provides classes for integrating online documentation
+in applications.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtHelp
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+The classes and tools supplied with Qt to enable developers to include online
+help and documentation in their applications are described in more detail in
+:ref:`The Qt Help Framework<The-Qt-Help-Framework>` .
diff --git a/sources/pyside6/doc/extras/QtMultimedia.rst b/sources/pyside6/doc/extras/QtMultimedia.rst
new file mode 100644
index 000000000..527c2427b
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtMultimedia.rst
@@ -0,0 +1,116 @@
+ .. image:: images/noun_Media_166644.svg
+
+The Qt Multimedia module provides APIs for playing back and recording audiovisual content
+
+Qt Multimedia is an add-on module that provides a rich set of QML types and C++
+classes to handle multimedia content. It contains an easy to use API for
+playing back audio and video files and rendering those on screen, as well as a
+comprehensive API for recording audio and video from the systems cameras and
+microphones.
+
+The functionality of this module is divided into the following submodules:
+
+
+ +---------------------------------------------------+-----------------------------------------------+
+ |:ref:`Qt Multimedia<Multimedia-Overview>` |Provides API for multimedia-specific use cases.|
+ +---------------------------------------------------+-----------------------------------------------+
+ |:ref:`Qt Multimedia Widgets<Qt-Multimedia-Widgets>`|Provides the widget-based multimedia API. |
+ +---------------------------------------------------+-----------------------------------------------+
+
+Getting started
+^^^^^^^^^^^^^^^
+
+If you are porting from Qt 5 to Qt 6 see :ref:`Changes to Qt Multimedia<Changes-to-Qt-Multimedia>` .
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtMultimedia
+
+The module also provides QML `types <https://doc.qt.io/qt-6/qtmultimedia-qmlmodule.html>`_ .
+
+Overviews and Important Topics
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * :ref:`Changes in Qt 6<Changes-to-Qt-Multimedia>`
+ * :ref:`Multimedia Overview<Multimedia-Overview>`
+ * :ref:`Audio Overview<Audio-Overview>`
+ * :ref:`Video Overview<Video-Overview>`
+ * :ref:`Camera Overview<Camera-Overview>`
+ * :ref:`Supported Media Formats<Video-Overview>`
+
+QML Types
+^^^^^^^^^
+
+The following table outlines some important QML types.
+
+ +------------------+---------------------------------------------------------------------+
+ |Type |Description |
+ +------------------+---------------------------------------------------------------------+
+ |`MediaPlayer`_ |Add audio/video playback functionality to a scene. |
+ +------------------+---------------------------------------------------------------------+
+ |`CaptureSession`_ |Create a session for capturing audio/video. |
+ +------------------+---------------------------------------------------------------------+
+ |`Camera`_ |Access a camera connected to the system. |
+ +------------------+---------------------------------------------------------------------+
+ |`AudioInput`_ |Access an audio input (microphone) connected to the system. |
+ +------------------+---------------------------------------------------------------------+
+ |`AudioOutput`_ |Access an audio output (speaker, headphone) connected to the system. |
+ +------------------+---------------------------------------------------------------------+
+ |`VideoOutput`_ |Display video content. |
+ +------------------+---------------------------------------------------------------------+
+ |`MediaRecorder`_ |Record audio/video from the `CaptureSession`_ . |
+ +------------------+---------------------------------------------------------------------+
+ |`ImageCapture`_ |Capture still images from the Camera. |
+ +------------------+---------------------------------------------------------------------+
+ |`Video`_ |Add Video playback functionality to a scene. Uses `MediaPlayer`_ and |
+ | |`VideoOutput`_ types to provide video playback functionality. |
+ +------------------+---------------------------------------------------------------------+
+
+.. _MediaPlayer: https://doc.qt.io/qt-6/qml-qtmultimedia-mediaplayer.html
+.. _CaptureSession: https://doc.qt.io/qt-6/qml-qtmultimedia-capturesession.html
+.. _Camera: https://doc.qt.io/qt-6/qml-qtmultimedia-camera.html
+.. _AudioInput: https://doc.qt.io/qt-6/qml-qtmultimedia-audioinput.html
+.. _AudioOutput: https://doc.qt.io/qt-6/qml-qtmultimedia-audiooutput.html
+.. _VideoOutput: https://doc.qt.io/qt-6/qml-qtmultimedia-videooutput.html
+.. _MediaRecorder: https://doc.qt.io/qt-6/qml-qtmultimedia-mediarecorder.html
+.. _ImageCapture: https://doc.qt.io/qt-6/qml-qtmultimedia-imagecapture.html
+.. _Video: https://doc.qt.io/qt-6/qml-qtmultimedia-video.html
+
+C++ Classes
+^^^^^^^^^^^
+
+The following table outlines some important C++ Classes
+
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |Class |Description |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QMediaPlayer<PySide6.QtMultimedia.QMediaPlayer>` |Playback media from a source. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QVideoWidget<PySide6.QtMultimediaWidgets.QVideoWidget>` |Display video from a media player or a capture session. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QMediaCaptureSession<PySide6.QtMultimedia.QMediaCaptureSession>`|Capture audio and video. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QCamera<PySide6.QtMultimedia.QCamera>` |Access a camera connected to the system |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QAudioInput<PySide6.QtMultimedia.QAudioInput>` |Access an audio input (microphone) connected to the system. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QAudioOutput<PySide6.QtMultimedia.QAudioOutput>` |Access an audio output (speaker, headphone) connected to the system.|
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QImageCapture<PySide6.QtMultimedia.QImageCapture>` |Capture still images with a camera. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QMediaRecorder<PySide6.QtMultimedia.QMediaRecorder>` |Record media content from a capture session. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QVideoSink<PySide6.QtMultimedia.QVideoSink>` |Access and render individual video frames. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+ |:class:`QAudioSink<PySide6.QtMultimedia.QAudioSink>` |Sends raw audio data to an audio output device. |
+ +------------------------------------------------------------------------+--------------------------------------------------------------------+
+
+For playback :class:`QMediaPlayer<PySide6.QtMultimedia.QMediaPlayer>` ,
+:class:`QAudioOutput<PySide6.QtMultimedia.QAudioOutput>` and QVideoOutput
+contain all the required functionality. The other classes are used for
+capturing audio and video content, where the
+:class:`QMediaCaptureSession<PySide6.QtMultimedia.QMediaCaptureSession>` is the
+central class managing the whole capture/recording process.
diff --git a/sources/pyside6/doc/extras/QtMultimediaWidgets.rst b/sources/pyside6/doc/extras/QtMultimediaWidgets.rst
new file mode 100644
index 000000000..510114907
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtMultimediaWidgets.rst
@@ -0,0 +1,15 @@
+An add-on module which provides multimedia-related widgets.
+
+Qt Multimedia Widgets provides additional multimedia-related widgets and
+controls. The classes expand the capabilities of the
+:ref:`Qt Multimedia<Qt-Multimedia>` and :ref:`Qt Widgets<Qt-Widgets>` modules.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtMultimediaWidgets
diff --git a/sources/pyside6/doc/extras/QtNetwork.rst b/sources/pyside6/doc/extras/QtNetwork.rst
new file mode 100644
index 000000000..18d8b3db2
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtNetwork.rst
@@ -0,0 +1,30 @@
+Provides networking capabilities
+
+The Qt Network module provides a set of APIs for programming applications that
+use TCP/IP. Operations such as requests, cookies, and sending data over HTTP
+are handled by various Python classes.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtNetwork
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+These articles contain information about Qt Network setup and about applications with networking capabilities.
+
+
+ * :ref:`Network Programming with Qt<Network-Programming-with-Qt>` - Programming applications
+ with networking capabilities
+ * :ref:`Secure Sockets Layer (SSL) Classes<Secure-Sockets-Layer--SSL--Classes>` - Classes
+ for secure communication over network sockets
+
+Also note shipping OpenSSL might cause
+`Import and Export Restrictions <https://doc.qt.io/qt-6/ssl.html#import-and-export-restrictions>`_
+to apply.
diff --git a/sources/pyside6/doc/extras/QtNetworkAuth.rst b/sources/pyside6/doc/extras/QtNetworkAuth.rst
new file mode 100644
index 000000000..1947d5ba4
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtNetworkAuth.rst
@@ -0,0 +1,37 @@
+Provides network authorization capabilities (OAuth).
+
+Qt Network Authorization provides a set of APIs that enable Qt applications to
+obtain limited access to online accounts and HTTP services without exposing
+users' passwords.
+
+Currently, the supported authorization protocol is `OAuth <https://oauth.net>`_
+, versions 1 and 2.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtNetworkAuth
+
+Overview
+^^^^^^^^
+
+The goal of this module is to provide a way to handle different authentication
+methods present on the Internet.
+
+There are several authentication systems, including:
+
+ * `OAuth 1 <https://datatracker.ietf.org/doc/html/rfc5849>`_
+ * `OAuth 2 <https://datatracker.ietf.org/doc/html/rfc6749>`_
+ * `OpenID <http://openid.net>`_
+ * `OpenID Connect <http://openid.net/connect/>`_
+
+These systems allow the application developers to create applications which use
+external authentication servers provided by an *Authorization Server*\. Users
+of these services need not worry about passing their credentials to suspicious
+applications. Instead, the credentials are entered in a known and trusted web
+interface.
diff --git a/sources/pyside6/doc/extras/QtNfc.rst b/sources/pyside6/doc/extras/QtNfc.rst
new file mode 100644
index 000000000..9cd0181f0
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtNfc.rst
@@ -0,0 +1,31 @@
+Enables connectivity between NFC enabled devices.
+
+The NFC API provides connectivity between NFC enabled devices.
+
+Overview
+^^^^^^^^
+
+NFC is an extremely short-range (less than 20 centimeters) wireless technology
+and has a maximum transfer rate of 424 kbit/s. NFC is ideal for transferring
+small packets of data when two devices are touched together.
+
+The NFC API provides APIs for interacting with NFC Forum Tags and NFC Forum
+Devices, including target detection and loss, registering NDEF message
+handlers, reading and writing NDEF messages on NFC Forum Tags and sending tag
+specific commands.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtNfc
+
+Guides
+^^^^^^
+
+ * `Qt NFC Overview <https://doc.qt.io/qt-6/qtnfc-overview.html>`_
+ * `Qt NFC on Android <https://doc.qt.io/qt-6/nfc-android.html>`_
diff --git a/sources/pyside6/doc/extras/QtOpenGL.rst b/sources/pyside6/doc/extras/QtOpenGL.rst
new file mode 100644
index 000000000..aa699a7d7
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtOpenGL.rst
@@ -0,0 +1,26 @@
+OpenGL is a standard API for rendering 3D graphics. OpenGL only deals
+with 3D rendering and provides little or no support for GUI
+programming issues. The user interface for an OpenGL application must
+be created with another toolkit, such as XCB on the X platform,
+Microsoft Foundation Classes (MFC) under Windows, or Qt on both
+platforms.
+
+.. note:: OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other countries.
+
+The Qt OpenGL module makes it easy to use OpenGL in Qt applications.
+To include the definitions of the module's classes, use the following
+directive:
+
+::
+
+ import PySide6.QtOpenGL
+
+The Qt OpenGL module is implemented as a platform-independent wrapper
+around the platform-dependent GLX (version 1.3 or later), WGL, or AGL
+C APIs. Applications using the Qt OpenGL module can take advantage of
+the whole Qt API for non-OpenGL-specific GUI functionality.
+
+The QtOpenGL module is available on Windows, X11 and Mac OS X. Qt for
+Embedded Linux and OpenGL supports OpenGL ES (OpenGL for Embedded
+Systems).
+
diff --git a/sources/pyside6/doc/extras/QtOpenGLWidgets.rst b/sources/pyside6/doc/extras/QtOpenGLWidgets.rst
new file mode 100644
index 000000000..d40b89d71
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtOpenGLWidgets.rst
@@ -0,0 +1,8 @@
+The Qt OpenGL provides the OpenGL widget class that can be used just like any
+other Qt widget, except that it opens an OpenGL display buffer where you can
+use the OpenGL API to render the contents. To include the definitions of
+the module's classes, use the following directive:
+
+::
+
+ import PySide6.QtOpenGLWidgets
diff --git a/sources/pyside6/doc/extras/QtPositioning.rst b/sources/pyside6/doc/extras/QtPositioning.rst
new file mode 100644
index 000000000..800e369fa
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtPositioning.rst
@@ -0,0 +1,40 @@
+The Qt Positioning API provides positioning information via QML and Python interfaces.
+
+Currently the API is supported on Android, iOS, macOS, Linux, and Windows (with
+GPS receivers exposed as a serial port providing NMEA sentences or using
+``Windows.Devices.Geolocation``\).
+
+Overview
+^^^^^^^^
+
+The Qt Positioning API gives developers the ability to determine a position by
+using a variety of possible sources, including satellite, or wifi, or text
+file, and so on. That information can then be used to for example determine a
+position on a map. In addition satellite information can be retrieved and area
+based monitoring can be performed.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtPositioning
+
+The module also provides `QML types <https://doc.qt.io/qt-6/qtpositioning-qmlmodule.html>`_ .
+
+To load the Qt Positioning module, add the following statement to your .qml files
+
+ ::
+
+ import QtPositioning
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+ * :ref:`Positioning introduction for C++<Positioning--C--->`
+ * :ref:`Positioning introduction for QML<Positioning--QML->`
+ * :ref:`Qt Positioning Plugins<Qt-Positioning-Plugins>`
+ * :ref:`Interfaces between C++ and QML Code in Qt Positioning<Interfaces-between-C---and-QML-Code-in-Qt-Positioning>`
diff --git a/sources/pyside6/doc/extras/QtPrintSupport.rst b/sources/pyside6/doc/extras/QtPrintSupport.rst
new file mode 100644
index 000000000..146ef6a9f
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtPrintSupport.rst
@@ -0,0 +1,15 @@
+The Qt Print Support module provides extensive cross-platform support for
+printing. Using the printing systems on each platform, Qt applications can
+print to attached printers and across networks to remote printers. The printing
+system also supports PDF file generation, providing the foundation for basic
+report generation facilities.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtPrintSupport
diff --git a/sources/pyside6/doc/extras/QtQml.ListProperty.rst b/sources/pyside6/doc/extras/QtQml.ListProperty.rst
new file mode 100644
index 000000000..eaa580c68
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.ListProperty.rst
@@ -0,0 +1,24 @@
+.. currentmodule:: PySide6.QtQml
+.. py:class:: ListProperty
+
+ The ``ListProperty`` class allows applications to expose list-like properties of
+ :class:`~PySide6.QtCore.QObject`-derived classes to QML.
+ The usage is shown in the :ref:`qml-object-and-list-property-types-example`
+ and the :ref:`qml-chapter5-listproperties` example.
+
+ .. py:method:: __init__(type, append, count=None, at=None, clear=None, removeLast=None, doc="", notify=None, designable=True, scriptable=True, stored=True, user=False, constant=False, final=False)
+
+ :param type type: Element type
+ :param callable append: A function to append an item
+ :param callable count: A function returning the list count
+ :param callable at: A function returning the item at an index
+ :param callable clear: A function to clear the list
+ :param removeLast: A function to remove the last item
+ :param str doc: Doc string
+ :param Signal notify: A signal emitted when a change occurs
+ :param bool designable: Not used in QML
+ :param bool scriptable: Not used in QML
+ :param bool stored: Whether the property is stored
+ :param bool user: Not used in QML
+ :param bool constant: Whether the property is constant
+ :param bool final: Whether the property is final
diff --git a/sources/pyside6/doc/extras/QtQml.QPyQmlParserStatus.rst b/sources/pyside6/doc/extras/QtQml.QPyQmlParserStatus.rst
new file mode 100644
index 000000000..10dde6b9a
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QPyQmlParserStatus.rst
@@ -0,0 +1,9 @@
+.. currentmodule:: PySide6.QtQml
+.. py:class:: QPyQmlParserStatus
+
+QPyQmlParserStatus is the base class for implementing
+`QQmlParserStatus class`_ .
+
+It provides the required inheritance from **QObject**.
+
+.. _QQmlParserStatus class: https://doc.qt.io/qt-6/qqmlparserstatus.html
diff --git a/sources/pyside6/doc/extras/QtQml.QPyQmlPropertyValueSource.rst b/sources/pyside6/doc/extras/QtQml.QPyQmlPropertyValueSource.rst
new file mode 100644
index 000000000..bf7f8e98f
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QPyQmlPropertyValueSource.rst
@@ -0,0 +1,9 @@
+.. currentmodule:: PySide6.QtQml
+.. py:class:: QPyQmlPropertyValueSource
+
+QPyQmlPropertyValueSource is the base class for implementing
+`QQmlPropertyValueSource class`_ .
+
+It provides the required inheritance from **QObject**.
+
+.. _QQmlPropertyValueSource class: https://doc.qt.io/qt-6/qqmlpropertyvaluesource.html
diff --git a/sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst b/sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst
new file mode 100644
index 000000000..44aa0ea21
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlAnonymous.rst
@@ -0,0 +1,17 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlAnonymous
+
+Declares the enclosing type to be available, but anonymous in QML. The type
+cannot be created or used to declare properties in QML, but when passed from
+C++, it is recognized. In QML, you can use properties of this type if they
+are declared in C++.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+ @QmlAnonymous
+ class ClassForQml(QObject):
+ # ...
diff --git a/sources/pyside6/doc/extras/QtQml.QmlAttached.rst b/sources/pyside6/doc/extras/QtQml.QmlAttached.rst
new file mode 100644
index 000000000..4331b03f9
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlAttached.rst
@@ -0,0 +1,35 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlAttached
+
+This decorator declares that the enclosing type attaches the type passed as
+an attached property to other types. This takes effect if the type is exposed
+to QML using a ``QmlElement()`` or ``@QmlNamedElement()`` decorator.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+ @QmlAnonymous
+ class LayoutAttached(QObject):
+ @Property(QMargins)
+ def margins(self):
+ ...
+
+ @QmlElement()
+ @QmlAttached(LayoutAttached)
+ class Layout(QObject):
+ ...
+
+Afterwards the class may be used in QML:
+
+.. code-block:: javascript
+
+ import com.library.name 1.0
+
+ Layout {
+ Widget {
+ Layout.margins: [2, 2, 2, 2]
+ }
+ }
diff --git a/sources/pyside6/doc/extras/QtQml.QmlElement.rst b/sources/pyside6/doc/extras/QtQml.QmlElement.rst
new file mode 100644
index 000000000..66397b2d9
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlElement.rst
@@ -0,0 +1,25 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlElement
+
+This decorator registers a class it is attached to for use in QML, using
+global variables to specify the import name and version.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+ @QmlElement
+ class ClassForQml(QObject):
+ # ...
+
+Afterwards the class may be used in QML:
+
+.. code-block:: python
+
+ import com.library.name 1.0
+
+ ClassForQml {
+ // ...
+ }
diff --git a/sources/pyside6/doc/extras/QtQml.QmlExtended.rst b/sources/pyside6/doc/extras/QtQml.QmlExtended.rst
new file mode 100644
index 000000000..af113a9c8
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlExtended.rst
@@ -0,0 +1,32 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlExtended
+
+Declares that the enclosing type uses the type passed as an extension to
+provide further properties, methods, and enumerations in QML. This takes effect
+if the type is exposed to QML using a ``QmlElement()`` or ``QmlNamedElement()``
+decorator.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+ class LineEditExtension(QObject):
+ pass
+
+ @QmlNamedElement("QLineEdit")
+ @QmlExtended(LineEditExtension)
+ @QmlForeign(QLineEdit)
+ class LineEditForeign(QObject):
+ ...
+
+Afterwards the class may be used in QML:
+
+.. code-block:: javascript
+
+ import com.library.name 1.0
+
+ QLineEdit {
+ left_margin: 10
+ }
diff --git a/sources/pyside6/doc/extras/QtQml.QmlForeign.rst b/sources/pyside6/doc/extras/QtQml.QmlForeign.rst
new file mode 100644
index 000000000..90b821e9b
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlForeign.rst
@@ -0,0 +1,28 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlForeign
+
+This decorator can be used to change the type that is created by QML.
+
+This is useful for registering types that cannot be amended by adding the
+QmlElement decorator, for example because they belong to 3rdparty libraries.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+ @QmlNamedElement("QWidget")
+ @QmlForeign(QWidget)
+ class ForeignWidgetHelperClass(QObject):
+ ...
+
+Afterwards the class may be used in QML:
+
+.. code-block:: javascript
+
+ import com.library.name 1.0
+
+ QWidget {
+ // ...
+ }
diff --git a/sources/pyside6/doc/extras/QtQml.QmlNamedElement.rst b/sources/pyside6/doc/extras/QtQml.QmlNamedElement.rst
new file mode 100644
index 000000000..79eb9d7ad
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlNamedElement.rst
@@ -0,0 +1,26 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlNamedElement
+
+This decorator registers a class it is attached to for use in QML under
+a name different from the class name, using global variables to specify
+the import name and version.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+ @QmlNamedElement("ClassForQml")
+ class ClassWithSomeName(QObject):
+ ...
+
+Afterwards the class may be used in QML:
+
+.. code-block:: javascript
+
+ import com.library.name 1.0
+
+ ClassForQml {
+ // ...
+ }
diff --git a/sources/pyside6/doc/extras/QtQml.QmlSingleton.rst b/sources/pyside6/doc/extras/QtQml.QmlSingleton.rst
new file mode 100644
index 000000000..402c18d55
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlSingleton.rst
@@ -0,0 +1,33 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlSingleton
+
+Declares the decorated type to be a singleton in QML. This only takes effect if
+the type is a QObject and is available in QML (by having a QmlElement decorator).
+The QQmlEngine will try to create a singleton instance using the type's default
+constructor.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+ @QmlElement
+ @QmlSingleton
+ class ClassForQml(QObject):
+ ...
+
+It is also possible to use a static ``create()`` method which receives
+the engine as a parameter:
+
+.. code-block:: python
+
+ @QmlElement
+ @QmlSingleton
+ class ClassForQml(QObject):
+
+ @staticmethod
+ def create(engine):
+ ...
+
+.. note:: The order of the decorators matters; ``QmlSingleton`` needs to be preceded by ``QmlElement``.
diff --git a/sources/pyside6/doc/extras/QtQml.QmlUncreatable.rst b/sources/pyside6/doc/extras/QtQml.QmlUncreatable.rst
new file mode 100644
index 000000000..b7a28801f
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.QmlUncreatable.rst
@@ -0,0 +1,26 @@
+.. currentmodule:: PySide6.QtQml
+.. py:decorator:: QmlUncreatable
+
+Declares that the decorated type shall not be creatable from QML. This takes
+effect if the type is available in QML, by a preceding ``QmlElement``
+decorator. The reason will be emitted as error message if an attempt to create
+the type from QML is detected.
+
+Some QML types are implicitly uncreatable, in particular types exposed with
+``QmlAnonymous``.
+
+Passing None or no argument will cause a standard message to be used instead.
+
+.. code-block:: python
+
+ QML_IMPORT_NAME = "com.library.name"
+ QML_IMPORT_MAJOR_VERSION = 1
+ QML_IMPORT_MINOR_VERSION = 0 # Optional
+
+
+ @QmlElement
+ @QmlUncreatable("BaseClassForQml is an abstract base class")
+ class BaseClassForQml(QObject):
+ ...
+
+.. note:: The order of the decorators matters; ``QmlUncreatable`` needs to be preceded by ``QmlElement``.
diff --git a/sources/pyside6/doc/extras/QtQml.rst b/sources/pyside6/doc/extras/QtQml.rst
new file mode 100644
index 000000000..66f736f02
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQml.rst
@@ -0,0 +1,75 @@
+The Qt QML module defines and implements the QML language
+
+The Qt QML module provides a framework for developing applications and
+libraries with the QML language. It defines and implements the language and
+engine infrastructure, and provides an API to enable application developers to
+extend the QML language with custom types and integrate QML code with
+JavaScript and C++. The Qt QML module provides both a `QML API
+<https://doc.qt.io/qt-6/qtqml-qmlmodule.html>`_ and a `C++ API
+<https://doc.qt.io/qt-6/qtqml-module.html>`_ .
+
+Note that while the Qt QML module provides the language and infrastructure for
+QML applications, the :ref:`Qt Quick<Qt-Quick>` module provides many visual
+components, model-view support, an animation framework, and much more for
+building user interfaces.
+
+For those new to QML and Qt Quick, please see QML Applications for an
+introduction to writing QML applications.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtQml
+
+The module also provides `QML types <https://doc.qt.io/qt-6/qtqml-qmlmodule.html>`_ .
+
+QML and QML Types
+^^^^^^^^^^^^^^^^^
+
+The Qt QML module contains the QML framework and important QML types used in
+applications. The constructs of QML are described in the
+:ref:`The QML Reference<The-QML-Reference>` .
+
+In addition to the :ref:`QML Basic Types<QML-Basic-Types>` , the module comes
+with the following QML object types:
+
+ * `Component <https://doc.qt.io/qt-6/qml-qtqml-component.html>`_
+ * `QtObject <https://doc.qt.io/qt-6/qml-qtqml-qtobject.html>`_
+ * `Binding <https://doc.qt.io/qt-6/qml-qtqml-binding.html>`_
+ * `Connections <https://doc.qt.io/qt-6/qml-qtqml-connections.html>`_
+ * `Timer <https://doc.qt.io/qt-6/qml-qtqml-timer.html>`_
+
+The `Qt <https://doc.qt.io/qt-6/qml-qtqml-qt.html>`_ global object provides
+useful enums and functions for various QML types.
+
+Lists and Models
+^^^^^^^^^^^^^^^^
+
+New in Qt 5.1, the model types are moved to a submodule, ``QtQml.Models``\. The
+Qt QML Models page has more information.
+
+ * DelegateModel
+ * DelegateModelGroup
+ * ListElement
+ * ListModel
+ * ObjectModel
+
+JavaScript Environment for QML Applications
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+JavaScript expressions allow QML code to contain application logic. Qt QML
+provides the framework for running JavaScript expressions in QML and from C++.
+
+These sections are from :ref:`The QML Reference<The-QML-Reference>` .
+
+ * `Integrating QML and JavaScript <https://doc.qt.io/qt-6/qtqml-javascript-topic.html>`_
+ * `Using JavaScript Expressions with QML <https://doc.qt.io/qt-6/qtqml-javascript-expressions.html>`_
+ * `Dynamic QML Object Creation from JavaScript <https://doc.qt.io/qt-6/qtqml-javascript-dynamicobjectcreation.html>`_
+ * `Defining JavaScript Resources In QML <https://doc.qt.io/qt-6/qtqml-javascript-resources.html>`_
+ * `Importing JavaScript Resources In QML <https://doc.qt.io/qt-6/qtqml-javascript-imports.html>`_
+ * `JavaScript Host Environment <https://doc.qt.io/qt-6/qtqml-javascript-hostenvironment.html>`_
diff --git a/sources/pyside6/doc/extras/QtQuickControls2.rst b/sources/pyside6/doc/extras/QtQuickControls2.rst
new file mode 100644
index 000000000..dba542045
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQuickControls2.rst
@@ -0,0 +1,45 @@
+Provides a set of UI controls for Qt Quick.
+
+Qt Quick Controls provides a set of controls that can be used to build complete
+interfaces in Qt Quick. The module was introduced in Qt 5.7.
+
+ .. image:: images/qtquickcontrols2-styles.png
+
+Qt Quick Controls comes with a selection customizable styles. See
+:ref:`Styling Qt Quick Controls<Styling-Qt-Quick-Controls>` for more details.
+
+ .. _QtQuickControls2_using-the-module:
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtQuickControls2
+
+Versions
+^^^^^^^^
+
+Qt Quick Controls 2.0 was introduced in Qt 5.7. Subsequent minor Qt releases
+increment the import version of the Qt Quick Controls modules by one, until Qt
+5.12, where the import versions match Qt's minor version.
+
+In Qt 6, both the major and minor versions match, and version numbers may be
+omitted from imports in QML. If the version is omitted, the latest version will
+be used.
+
+Topics
+^^^^^^
+
+ * `Getting Started <https://doc.qt.io/qt-6/qtquickcontrols2-gettingstarted.html>`_
+ * `Guidelines <https://doc.qt.io/qt-6/qtquickcontrols2-guidelines.html>`_
+ * `Styling <https://doc.qt.io/qt-6/qtquickcontrols2-styles.html>`_
+ * `Icons <https://doc.qt.io/qt-6/qtquickcontrols2-icons.html>`_
+ * `Customization <https://doc.qt.io/qt-6/qtquickcontrols2-customize.html>`_
+ * `Using File Selectors <https://doc.qt.io/qt-6/qtquickcontrols2-fileselectors.html>`_
+ * `Deployment <https://doc.qt.io/qt-6/qtquickcontrols2-deployment.html>`_
+ * `Configuration File <https://doc.qt.io/qt-6/qtquickcontrols2-configuration.html>`_
+ * `Environment Variables <https://doc.qt.io/qt-6/qtquickcontrols2-environment.html>`_
diff --git a/sources/pyside6/doc/extras/QtQuickTest.rst b/sources/pyside6/doc/extras/QtQuickTest.rst
new file mode 100644
index 000000000..52f13590b
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtQuickTest.rst
@@ -0,0 +1,58 @@
+ Qt Quick Test is a unit test framework for QML applications. Test cases are
+ written as JavaScript functions within a QML TestCase type:
+
+.. code-block:: JavaScript
+
+ import QtQuick
+ import QtTest
+
+ TestCase {
+ name: "MathTests"
+
+ function test_math() {
+ compare(2 + 2, 4, "2 + 2 = 4")
+ }
+
+ function test_fail() {
+ compare(2 + 2, 5, "2 + 2 = 5")
+ }
+ }
+
+Functions whose names start with ``test_`` are treated as test cases to be
+executed.
+
+QML API
+^^^^^^^
+
+The `QML types <https://doc.qt.io/qt-6/qttest-qmlmodule.html>`_
+in Qt Quick Test are available through the ``QtTest`` import.
+To use the types, add the following import statement to your ``.qml`` file:
+
+.. code-block:: JavaScript
+
+ import QtTest
+
+Running Tests
+^^^^^^^^^^^^^
+
+Test cases are launched by a harness that consists of the following code:
+
+.. code-block:: Python
+
+ import sys
+ from PySide6.QtQuickTest import QUICK_TEST_MAIN
+
+ QUICK_TEST_MAIN("example", sys.argv)
+
+Where "example" is the identifier to use to uniquely identify this set of
+tests.
+
+Test execution can be controlled by a number of command line options (pass
+``-h`` for help).
+
+Executing Code Before QML Tests
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To execute code before any of the QML tests are run, the
+:py:func:`QUICK_TEST_MAIN_WITH_SETUP` function can be used. This can be useful
+for setting context properties on the QML engine, amongst other things.
diff --git a/sources/pyside6/doc/extras/QtRemoteObjects.rst b/sources/pyside6/doc/extras/QtRemoteObjects.rst
new file mode 100644
index 000000000..7a8eb76a3
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtRemoteObjects.rst
@@ -0,0 +1,101 @@
+Provides APIs for inter-process communication.
+
+Remote Object Concepts
+^^^^^^^^^^^^^^^^^^^^^^
+
+Qt Remote Objects (QtRO) is an Inter-Process Communication (IPC) module
+developed for Qt. This module extends Qt's existing functionalities to enable
+information exchange between processes or computers, easily.
+
+One of Qt's key features, to enable this information exchange, is the
+distinction between an object's API (defined by its properties, signals, and
+slots) and the implementation of that API. QtRO's purpose is to meet that
+expected API, even if the true :class:`QObject<PySide6.QtCore.QObject>` is in a
+different process. A slot called on a copy of an object (the
+:ref:`Replica<Qt-Remote-Objects-Replica>` in QtRO) is forwarded to the true
+object (the :ref:`Source<Qt-Remote-Objects-Source>` in QtRO) for handling.
+Every Replica receives updates to the Source, either property changes or
+emitted signals.
+
+A :ref:`Replica<Qt-Remote-Objects-Replica>` is a light-weight proxy for the
+:ref:`Source<Qt-Remote-Objects-Source>` object, but a Replica supports the same
+connections and behavior of QObjects, which makes it usable in the same way as
+any other :class:`QObject<PySide6.QtCore.QObject>` that Qt provides. Behind the
+scenes, QtRO handles everything that's necessary for the Replica to look like
+its Source.
+
+Note that Remote Objects behave differently from traditional Remote Procedure
+Call (RPC) implementations, for example:
+
+ * In RPC, the client makes a request and waits for the response.
+ * In RPC, the server doesn't push anything to the client unless it's in response to a request.
+ * Often, the design of RPC is such that different clients are independent of each other:
+ for instance, two clients can ask a mapping service for directions and get
+ different results.
+
+While it is possible to implement this RPC-style behavior in QtRO, as Sources
+without properties, and slots that have return values, QtRO hides the fact that
+the processing is really remote. You let a node give you the Replica instead of
+creating it yourself, possibly use the status signals (
+:meth:`isReplicaValid()<PySide6.QtRemoteObjects.QRemoteObjectReplica.isReplicaValid>`
+), but then interact with the object like you would with any other
+:class:`QObject<PySide6.QtCore.QObject>` -based type.
+
+Use Case: GPS
+^^^^^^^^^^^^^
+
+Consider a sensor such as a Global Positioning System (GPS) receiver. In QtRO terms:
+
+ * The :ref:`Source<Qt-Remote-Objects-Source>` would be the process that directly
+ interacts with the GPS hardware and derives your current location.
+ * The location would be exposed as :class:`QObject<PySide6.QtCore.QObject>` properties;
+ the periodic updates to the location would update these properties and emit property
+ changed signals.
+ * :ref:`Replicas<Qt-Remote-Objects-Replica>` would be created in other processes
+ and would always know your current location, but wouldn't need any of the logic
+ to compute the location from the sensor data.
+ * Connecting to the location changed signal on the Replica would work as
+ expected: the signal emitted from the Source would trigger the signal
+ emission on every Replica.
+
+Use Case: Printer Access
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Consider a service that provides access to a printer. In QtRO terms:
+
+ * The :ref:`Source<Qt-Remote-Objects-Source>` would be the process
+ controlling the printer directly.
+ * The ink levels and printer status would be monitored by
+ :class:`QObject<PySide6.QtCore.QObject>` properties. Updates to these
+ properties would emit property changed signals.
+ * The key feature -- being able to print something -- needs to be passed
+ back to the printer. Incidentally, this aligns with the Qt slot mechanism,
+ which QtRO uses as the way for :ref:`Replicas<Qt-Remote-Objects-Replica>`
+ to make calls on the Source. In effect, properties and signals go from Source
+ to Replicas; slots go from Replica to Source.
+ * When a print request is accepted, the printer status would change,
+ triggering a change in the status property. This would then be reported
+ to all Replicas.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtRemoteObjects
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+ * `Getting Started with Qt Remote Objects <https://doc.qt.io/qt-6/qtremoteobjects-gettingstarted.html>`_
+ * `Nodes <https://doc.qt.io/qt-6/qtremoteobjects-node.html>`_
+ * `Sources <https://doc.qt.io/qt-6/qtremoteobjects-source.html>`_
+ * `Replicas <https://doc.qt.io/qt-6/qtremoteobjects-replica.html>`_
+ * `Registry <https://doc.qt.io/qt-6/qtremoteobjects-registry.html>`_
+ * `Compiler <https://doc.qt.io/qt-6/qtremoteobjects-repc.html>`_
+ * `Remote Object Interaction <https://doc.qt.io/qt-6/qtremoteobjects-interaction.html>`__
+ * `Troubleshooting <https://doc.qt.io/qt-6/qtremoteobjects-troubleshooting.html>`_
+ * `Protocol Versioning <https://doc.qt.io/qt-6/qtremoteobjects-compatibility.html>`_
diff --git a/sources/pyside6/doc/extras/QtScxml.rst b/sources/pyside6/doc/extras/QtScxml.rst
new file mode 100644
index 000000000..e757bfd58
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtScxml.rst
@@ -0,0 +1,25 @@
+Provides functionality to create state machines from SCXML files.
+
+The Qt SCXML module provides functionality to create state machines from
+`SCXML <http://www.w3.org/TR/scxml/>`_ files. This includes both dynamically
+creating state machines (loading the SCXML file and instantiating states and
+transitions) and generating a C++ file that has a class implementing the state
+machine. It also contains functionality to support data models and executable
+content.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtScxml
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+ * `Qt SCXML Overview <https://doc.qt.io/qt-6/qtscxml-overview.html>`_
+ * `Instantiating State Machines <https://doc.qt.io/qt-6/qtscxml-instantiating-state-machines.html>`_
+ * `SCXML Compliance <https://doc.qt.io/qt-6/qtscxml-scxml-compliance.html>`_
diff --git a/sources/pyside6/doc/extras/QtSensors.rst b/sources/pyside6/doc/extras/QtSensors.rst
new file mode 100644
index 000000000..03a4d5477
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtSensors.rst
@@ -0,0 +1,19 @@
+
+The Qt Sensors API provides access to sensor hardware via QML and Python
+interfaces.
+
+Currently the API is supported on Android, iOS, and Windows (MSVC).
+
+Information for Application Writers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Applications can access Qt Sensors using QML or Python.
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtSensors
+
+The module also provides `QML types <https://doc.qt.io/qt-6/qtsensors-qmlmodule.html>`_ .
diff --git a/sources/pyside6/doc/extras/QtSerialBus.rst b/sources/pyside6/doc/extras/QtSerialBus.rst
new file mode 100644
index 000000000..a6493a2ae
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtSerialBus.rst
@@ -0,0 +1,46 @@
+The Qt Serial Bus API provides classes and functions to access the various
+industrial serial buses and protocols, such as CAN, ModBus, and others.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtSerialBus
+
+Supported Buses and Protocols
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ * Qt CAN Bus
+ * Qt Modbus
+
+Logging Categories
+^^^^^^^^^^^^^^^^^^
+
+The QtSerialBus module exports the following logging categories:
+
+.. list-table::
+ :header-rows: 1
+
+ * - Logging Category
+ - Description
+ * - qt.canbus
+ - Enables standard logging inside the Qt CAN Bus classes
+ * - qt.canbus.plugins
+ - Enables low level logging inside the Qt CAN Bus plugin classes. To set logging for a specific plugin, use ``qt.canbus.plugins.pluginname``, e.g. ``qt.canbus.plugins.socketcan``. ``qt.canbus.plugins*`` affects all plugins.
+ * - qt.modbus
+ - Enables standard logging inside the Qt Modbus classes
+ * - qt.modbus.lowlevel
+ - Enables low level logging including individual packet content inside the Qt Modbus classes
+
+Logging categories can be used to enable additional warning and debug output
+for QtSerialBus.
+
+A quick way to enable all Qt Modbus logging is to add the following line:
+
+.. code-block:: python
+
+ QLoggingCategory.setFilterRules("qt.modbus* = true")
diff --git a/sources/pyside6/doc/extras/QtSerialPort.rst b/sources/pyside6/doc/extras/QtSerialPort.rst
new file mode 100644
index 000000000..1b20039c3
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtSerialPort.rst
@@ -0,0 +1,18 @@
+Provides an API to make serial programming simple and portable.
+
+Qt Serial Port provides the basic functionality, which includes configuring,
+I/O operations, getting and setting the control signals of the RS-232 pinouts.
+
+The following items are not supported by this module:
+
+ * Terminal features, such as echo, control CR/LF, and so on.
+ * Text mode.
+ * Configuring timeouts and delays while reading or writing.
+ * Pinout signal change notification.
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtSerialPort
diff --git a/sources/pyside6/doc/extras/QtSql.rst b/sources/pyside6/doc/extras/QtSql.rst
new file mode 100644
index 000000000..f3374edc8
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtSql.rst
@@ -0,0 +1,21 @@
+Provides a driver layer, SQL API layer, and a user interface layer for SQL databases
+
+The Qt SQL module provides support for SQL databases. Qt SQL's APIs are divided
+into different layers:
+
+ * Driver layer
+ * SQL API layer
+ * User interface layer
+
+The :ref:`SQL Programming<SQL-Programming>` guide contains information about
+development using Qt SQL.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtSql
diff --git a/sources/pyside6/doc/extras/QtSvg.rst b/sources/pyside6/doc/extras/QtSvg.rst
new file mode 100644
index 000000000..d652841a6
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtSvg.rst
@@ -0,0 +1,21 @@
+Qt SVG provides functionality for handling SVG images.
+
+Scalable Vector Graphics (SVG) is an XML-based language for describing
+two-dimensional vector graphics. Qt provides classes for rendering and
+displaying SVG drawings in widgets and on other paint devices.
+
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtSvg
+
+Articles
+^^^^^^^^
+
+ * :ref:`Rendering SVG Files<Rendering-SVG-Files>` contains information about how to render SVG files
diff --git a/sources/pyside6/doc/extras/QtTest.rst b/sources/pyside6/doc/extras/QtTest.rst
new file mode 100644
index 000000000..cebd5a053
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtTest.rst
@@ -0,0 +1,7 @@
+To include the definitions of the module's classes, use the following directive:
+
+::
+
+ import PySide6.QtTest
+
+.. note:: Not all macros in the C++ version of QtTest were exposed in PySide. This module is useful only for GUI testing and benchmarking; for ordinary unit testing you should use the ``pytest`` Python module.
diff --git a/sources/pyside6/doc/extras/QtUiTools.rst b/sources/pyside6/doc/extras/QtUiTools.rst
new file mode 100644
index 000000000..e83aa0357
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtUiTools.rst
@@ -0,0 +1,17 @@
+*Qt Widgets Designer* forms are processed at run-time to produce
+dynamically-generated user interfaces. In order to generate a form at
+run-time, a resource file containing a UI file is needed.
+
+A form loader object, provided by the ``QUiLoader`` class, is used to
+construct the user interface. This user interface can be retrieved
+from any ``QIODevice``; for example, a ``QFile`` object can be used to obtain
+a form stored in a project's resources. The
+:meth:`PySide6.QtUiTools.QUiLoader.load` function takes the user
+interface description contained in the file and constructs the form
+widget.
+
+To include the definitions of the module's classes, use the following directive:
+
+::
+
+ import PySide.QtUiTools
diff --git a/sources/pyside6/doc/extras/QtWebChannel.rst b/sources/pyside6/doc/extras/QtWebChannel.rst
new file mode 100644
index 000000000..5207a3486
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtWebChannel.rst
@@ -0,0 +1,30 @@
+Bridges the gap between Qt applications and HTML/JavaScript.
+
+Qt WebChannel enables peer-to-peer communication between a server (QML/Python
+application) and a client (HTML/JavaScript or QML application). It is supported
+out of the box by :ref:`Qt WebEngine<Qt-WebEngine>` . In addition it can work
+on all browsers that support :ref:`WebSockets<Qt-WebSockets>` , enabling Qt
+WebChannel clients to run in any JavaScript environment (including QML). This
+requires the implementation of a custom transport based on Qt WebSockets.
+
+The module provides a JavaScript library for seamless integration of Python and
+QML applications with HTML/JavaScript and QML clients. The clients must use the
+JavaScript library to access the serialized QObjects published by the host
+applications.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtWebChannel
+
+API Reference
+^^^^^^^^^^^^^
+
+ * `JavaScript API <https://doc.qt.io/qt-6/qtwebchannel-javascript.html>`_
+
+The module also provides `QML types <https://doc.qt.io/qt-6/qtwebchannel-qmlmodule.html>`_ .
diff --git a/sources/pyside6/doc/extras/QtWebEngineCore.rst b/sources/pyside6/doc/extras/QtWebEngineCore.rst
new file mode 100644
index 000000000..ff8dd5c23
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtWebEngineCore.rst
@@ -0,0 +1,19 @@
+Provides common API shared by Qt WebEngine and Qt WebEngine Widgets.
+
+Qt WebEngine Core provides API shared by :ref:`Qt WebEngine<Qt-WebEngine>`
+and :ref:`Qt WebEngine Widgets<Qt-WebEngine-Widgets>` .
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtWebEngineCore
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+ * `Qt WebEngine Overview <https://doc.qt.io/qt-6/qtwebengine-overview.html>`_
diff --git a/sources/pyside6/doc/extras/QtWebEngineWidgets.rst b/sources/pyside6/doc/extras/QtWebEngineWidgets.rst
new file mode 100644
index 000000000..8d3f6e126
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtWebEngineWidgets.rst
@@ -0,0 +1,18 @@
+Provides a web browser engine as well as C++ classes to render web content and
+interact with it.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtWebEngineWidgets
+
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+ * `Qt WebEngine Overview <https://doc.qt.io/qt-6/qtwebengine-overview.html>`_
diff --git a/sources/pyside6/doc/extras/QtWebSockets.rst b/sources/pyside6/doc/extras/QtWebSockets.rst
new file mode 100644
index 000000000..f15264699
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtWebSockets.rst
@@ -0,0 +1,29 @@
+Provides an implementation of the WebSocket protocol.
+
+WebSocket is a web-based protocol designed to enable two-way communication
+between a client application and a remote host. It enables the two entities to
+send data back and forth if the initial handshake succeeds. WebSocket is the
+solution for applications that struggle to get real-time data feeds with less
+network latency and minimum data exchange.
+
+The Qt WebSockets module provides C++ and QML interfaces that enable Qt
+applications to act as a server that can process WebSocket requests, or a
+client that can consume data received from the server, or both.
+
+Getting Started
+^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtWebSockets
+
+The module also provides `QML types <https://doc.qt.io/qt-6/qtwebsockets-qmlmodule.html>`_ .
+
+Articles and Guides
+^^^^^^^^^^^^^^^^^^^
+
+ * `Overview <https://doc.qt.io/qt-6/websockets-overview.html>`_
+ * `Testing Qt WebSockets <https://doc.qt.io/qt-6/qtwebsockets-testing.html>`_
diff --git a/sources/pyside6/doc/extras/QtWidgets.rst b/sources/pyside6/doc/extras/QtWidgets.rst
new file mode 100644
index 000000000..784421aac
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtWidgets.rst
@@ -0,0 +1,86 @@
+A module which provides a set of C++ technologies for building user
+interfaces
+
+The QtWidgets module provides a set of UI elements to create classic
+desktop-style user interfaces.
+
+Widgets
+^^^^^^^
+
+Widgets are the primary elements for creating user interfaces in Qt. They can
+display data and status information, receive user input, and provide a
+container for other widgets that should be grouped together. A widget that is
+not embedded in a parent widget is called a window.
+
+ .. image:: images/parent-child-widgets.png
+
+The :class:`QWidget<PySide6.QtWidgets.QWidget>` class provides the
+basic capability to render to the screen, and to handle user input
+events. All UI elements that Qt provides are either subclasses of
+:class:`QWidget<PySide6.QtWidgets.QWidget>` , or are used in
+connection with a :class:`QWidget<PySide6.QtWidgets.QWidget>`
+subclass. Creating custom widgets is done by subclassing
+:class:`QWidget<PySide6.QtWidgets.QWidget>` or a suitable subclass and
+reimplementing the virtual event handlers.
+
+ * :ref:`Window and Dialog Widgets<Window-and-Dialog-Widgets>`
+ * :ref:`Application Main Window<Application-Main-Window>`
+ * :ref:`Dialog Windows<Dialog-Windows>`
+ * :ref:`Keyboard Focus in Widgets<Keyboard-Focus-in-Widgets>`
+
+Styles
+^^^^^^
+
+:ref:`Styles<Styles-and-Style-Aware-Widgets>` draw on behalf of
+widgets and encapsulate the look and feel of a GUI. Qt's built-in
+widgets use the :class:`QStyle<PySide6.QtWidgets.QStyle>` class to
+perform nearly all of their drawing, ensuring that they look exactly
+like the equivalent native widgets.
+
+:ref:`Qt Style Sheets<Qt-Style-Sheets>` are a powerful mechanism that
+allows you to customize the appearance of widgets, in addition to what
+is already possible by subclassing
+:class:`QStyle<PySide6.QtWidgets.QStyle>` .
+
+Layouts
+^^^^^^^
+
+:ref:`Layouts<Layout-Management>` are an elegant and flexible way to
+automatically arrange child widgets within their container. Each
+widget reports its size requirements to the layout through the
+:meth:`sizeHint<PySide6.QtWidgets.QWidget.sizeHint>` and
+:meth:`sizePolicy<PySide6.QtWidgets.QWidget.sizePolicy>` properties,
+and the layout distributes the available space accordingly.
+
+:ref:`Qt Widgets Designer<using_ui_files>` is a powerful tool for interactively
+creating and arranging widgets in layouts.
+
+Model/View Classes
+^^^^^^^^^^^^^^^^^^
+
+The :ref:`model/view<Model-View-Programming>` architecture provides
+classes that manage the way data is presented to the user. Data-driven
+applications which use lists and tables are structured to separate the
+data and view using models, views, and delegates.
+
+ .. image:: images/windows-treeview.png
+
+Graphics View
+^^^^^^^^^^^^^
+
+The :ref:`Graphics View Framework<Graphics-View-Framework>` is for
+managing and interacting with a large number of custom-made 2D
+graphical items, and a view widget for visualizing the items, with
+support for zooming and rotation.
+
+ .. image:: images/graphicsview-items.png
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtWidgets
diff --git a/sources/pyside6/doc/extras/QtXml.rst b/sources/pyside6/doc/extras/QtXml.rst
new file mode 100644
index 000000000..33d821baa
--- /dev/null
+++ b/sources/pyside6/doc/extras/QtXml.rst
@@ -0,0 +1,13 @@
+The Qt XML module provides implementations of the SAX and DOM standards for XML.
+
+.. note:: Qt XML will no longer receive additional features. For reading or writing XML documents iteratively (SAX), use the :class:`QXmlStreamReader<PySide6.QtCore.QXmlStreamReader>` and :class:`QXmlStreamWriter<PySide6.QtCore.QXmlStreamWriter>` classes. The classes are both easier to use and more compliant with the XML standard.
+
+Using the Module
+^^^^^^^^^^^^^^^^
+
+To include the definitions of modules classes, use the following
+directive:
+
+::
+
+ import PySide6.QtXml
diff --git a/sources/pyside6/doc/faq.rst b/sources/pyside6/doc/faq.rst
new file mode 100644
index 000000000..4171df947
--- /dev/null
+++ b/sources/pyside6/doc/faq.rst
@@ -0,0 +1,38 @@
+.. _faq:
+
+:orphan:
+
+Frequently Asked Questions
+==========================
+
+**When did The Qt Company adopt PySide?**
+ In April 2016 `The Qt Company <https://qt.io>`_ decided to properly support the port. For more
+ information, see `<https://groups.google.com/forum/#!topic/pyside-dev/pqwzngAGLWE>`_.
+
+**Why use PySide6 and not PySide, or PySide2?**
+ The PySide Python module was developed for Qt 4 and PySide2 adapts
+ the same for Qt 5. From Qt 6 onwards, the module name changes to PySide6,
+ indicating the Qt version it supports.
+
+**Where I can find information about the old PySide project?**
+ The project's old wiki page is available on PySide, but the project is now deprecated and not
+ supported.
+
+**There are three wheels (pyside6, shiboken6, and shiboken6_generator), what's the difference?**
+
+ Before the official release, everything was in one big wheel, so it made sense to split these
+ into separate wheels, each for the major projects currently in development:
+
+ * **pyside6**: contains all the PySide6 modules to use the Qt framework; also depends on the
+ shiboken6 module.
+ * **shiboken6**: contains the shiboken6 module with helper functions for PySide6.
+ * **shiboken6_generator**: contains the generator binary that can work with a C++ project and a
+ typesystem to generate Python bindings.
+ If you want to generate bindings for a Qt/C++ project, there won't be any linking to the Qt
+ shared libraries; you need to do this by hand. We recommend building PySide6 from scratch
+ to have everything properly linked.
+
+**Why is the shiboken6_generator not installed automatically?**
+ It's not necessary to install the shiboken6_generator to use PySide6. The package is a result of
+ the wheel splitting process. To use the generator, it's recommended to build it from scratch to
+ have the proper Qt linking.
diff --git a/sources/pyside6/doc/faq/distribution.rst b/sources/pyside6/doc/faq/distribution.rst
new file mode 100644
index 000000000..fea588153
--- /dev/null
+++ b/sources/pyside6/doc/faq/distribution.rst
@@ -0,0 +1,69 @@
+.. _distribution:
+
+Distributing Your Application to Other Systems/Platforms
+========================================================
+
+After developing a couple of applications, you might want to distribute them to
+other users. In case you do not have much experience with Python packages, you
+might have even asked: *How do I create a Python executable?*.
+
+If you come from compiled programming languages, deployment is something
+almost trivial, but for Python is a bit difficult.
+
+The deployment process for Python applications is called, "freezing", which is
+distributing your virtual environment content to other users.
+
+.. important:: As Python does not support WebAssembly and mobile platforms,
+ such as Android and iOS, you cannot deploy applications to these platforms
+ directly, and you require advanced processes to do so.
+
+.. note:: For embedded systems, you currently need to build |project| for your
+ target platform, and deploy the installation alongside your application.
+
+Reproducible deployment
+-----------------------
+
+A common approach is to only provide a ``requirements.txt`` file, where you
+state your dependencies. Users would need to install them from there
+to run your Application.
+
+For example, imagine I have a project with two dependencies, ``module_a`` and
+``module_b``, which I use in my ``main.py`` file. So my structure is:
+
+.. code-block:: python
+
+ # Content of the main.py file
+ from module_a import something
+ import module_b
+
+ # ...
+
+So the ``requirements.txt`` for my application would look like this::
+
+ module_a
+ module_b
+
+Later, when a user want to execute your ``main.py``, the dependencies
+must be installed using :command:`pip install -r requirements.txt`
+in a new virtual environment.
+
+.. important:: You can notice that this approach includes sharing your code
+ so it fails if you want to hide the code of your application.
+
+Freezing Your Application
+-------------------------
+
+This is the most common approach for users to distribute their applications
+and even though the code is still available for the end user, it is a bit more
+difficult to retrieve it.
+
+You can find a series of tutorials based on the most popular tools that
+allow Python users to freeze and distribute applications in our
+:ref:`deployment-guides` section.
+
+Compiling Python
+----------------
+
+Even though Python does not natively support to be compiled, there are
+complementary tools that let you to achieve this.
+You can check the `Nuitka <https://nuitka.net/>`_ project to learn more.
diff --git a/sources/pyside6/doc/faq/hello_linux.png b/sources/pyside6/doc/faq/hello_linux.png
new file mode 100644
index 000000000..f335a234d
--- /dev/null
+++ b/sources/pyside6/doc/faq/hello_linux.png
Binary files differ
diff --git a/sources/pyside6/doc/faq/hello_macOS.png b/sources/pyside6/doc/faq/hello_macOS.png
new file mode 100644
index 000000000..863149399
--- /dev/null
+++ b/sources/pyside6/doc/faq/hello_macOS.png
Binary files differ
diff --git a/sources/pyside6/doc/faq/hello_win10.jpg b/sources/pyside6/doc/faq/hello_win10.jpg
new file mode 100644
index 000000000..78dcf8ab5
--- /dev/null
+++ b/sources/pyside6/doc/faq/hello_win10.jpg
Binary files differ
diff --git a/sources/pyside6/doc/faq/tiobe.png b/sources/pyside6/doc/faq/tiobe.png
new file mode 100644
index 000000000..87647d1c2
--- /dev/null
+++ b/sources/pyside6/doc/faq/tiobe.png
Binary files differ
diff --git a/sources/pyside6/doc/faq/typesoffiles.rst b/sources/pyside6/doc/faq/typesoffiles.rst
new file mode 100644
index 000000000..3155b24fc
--- /dev/null
+++ b/sources/pyside6/doc/faq/typesoffiles.rst
@@ -0,0 +1,152 @@
+.. _typesoffiles:
+
+File Types
+==========
+
+There are many different file types that you will encounter while
+developing |project| applications, ui, qrc, qml, pyproject, etc.
+Here you can find a simple explanation for
+each of them.
+
+Python Files ``.py``
+--------------------
+
+Python files are the main format you will be dealing with, while developing
+|project| projects.
+
+It is important to note that you can write applications **only** with Python
+files, without the need of ``.ui``, ``.qrc``, or ``.qml`` files, however
+using other formats will facilitate some processes, and enable new
+functionality to your applications.
+
+.. code-block:: python
+
+ class MyWidget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+
+ self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+ # ...
+
+User Interface Definition File ``.ui``
+--------------------------------------
+
+When using *Qt Widgets Designer*, you can create user interfaces using
+Qt Widgets with the WYSIWYG form editor, this interface is represented
+as a widget tree using XML. Here is an extract of the beginning of a
+``.ui`` file:
+
+.. code-block:: xml
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+
+The `pyside6-uic` tool generates Python code from these `.ui` files,
+which you can import from your main files, so it is not necessary
+for you to include the `.ui` files in your deployed application.
+
+For more details, see :ref:`using_ui_files`.
+
+Resource Collection Files ``.qrc``
+----------------------------------
+
+List of binary files that will be used alongside your application.
+As an XML-based file, its structure look like this:
+
+.. code-block:: xml
+
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+ <file>images/quit.png</file>
+ <file>font/myfont.ttf</file>
+ </qresource>
+ </RCC>
+
+
+The `pyside6-rcc` tool generates Python code from these `.qrc` files,
+so you are not required to include the listed files in your deployed
+application.
+
+For more details, see :ref:`using_qrc_files`.
+
+Qt Modeling Language File ``.qml``
+----------------------------------
+
+Graphical QML applications are not related to Qt Widgets applications, and
+that is why the usual setup of QML project is a Python file that loads
+the QML file, and optionally, elements defined in Python that are exposed
+to QML to be used.
+
+You can write ``.qml`` files by hand, but also you can use tools like the
+*QML Designer* that is embedded in *Qt Creator*. Additionally, there are commercial
+tools like *Qt Design Studio* that allow you to load designs from other design
+applications.
+
+Here you can find an example of how a ``.qml`` file looks like.
+The code will display a lightgray rectangle, with the "Hello World!"
+message on it.
+
+.. code-block:: javascript
+
+ import QtQuick 2.0
+
+ Rectangle {
+ id: page
+ width: 320;
+ height: 480
+ color: "lightgray"
+
+ Text {
+ id: helloText
+ text: "Hello world!"
+ y: 30
+ anchors.horizontalCenter: page.horizontalCenter
+ font.pointSize: 24;
+ font.bold: true
+ }
+ }
+
+Qt Creator Python Project File ``.pyproject``
+---------------------------------------------
+
+For *Qt Creator* to load and handle Python based projects, a special file is
+needed, because C++ based projects could be handle from ``.qmake`` or
+``CMakeLists.txt`` file, which are not used with Python-based projects.
+
+Old versions of *Qt Creator*, provided a simple format with the ``.pyqtc``
+extension, which were plain-text files with one-file-per-line::
+
+ library/server.py
+ library/client.py
+ logger.py
+ ...
+
+There were limitations to this format, and further options that might be
+added that would not be supported, which was the motivation to create a
+``.pyproject`` file, which is a JSON-based file where more options could
+be added. Here is an example of such file:
+
+.. code-block:: javascript
+
+ {
+ "files": ["library/server.py", "library/client.py", "logger.py", ...]
+ }
diff --git a/sources/pyside6/doc/faq/whatisqt.rst b/sources/pyside6/doc/faq/whatisqt.rst
new file mode 100644
index 000000000..3b42a9403
--- /dev/null
+++ b/sources/pyside6/doc/faq/whatisqt.rst
@@ -0,0 +1,112 @@
+.. _whatisqt:
+
+Qt, QML, Widgets...What Is The Difference?
+==========================================
+
+If you are new to Qt, there might be a chance that you are a bit confused about
+all the concepts you have read so far. This section aims to provide a summary
+of all the key components that are relevant to develop Qt applications.
+
+Keep in mind that Qt was designed and written in C++ as a C++ framework, you
+will find many references, examples, and concepts that make sense in C++
+based applications, that might not be relevant in your Python applications,
+but keep in mind that |project| aims to expose the Qt framework to Python
+with many adaptations. You don't need to know C++ to use |project|, and you
+can find all the possible combinations between these languages later on.
+
+Qt
+--
+
+The Qt Project is an open collaboration that coordinates the development of the
+Qt Framework. You might find situations where "Qt" refers to the project, or
+to the framework.
+
+As a framework, Qt has many components, which are distributed by components
+and modules, for example, `qtbase <https://code.qt.io/cgit/qt/qtbase.git/>`_
+is the base component that holds many modules, like: ``QtCore``, ``QtGui``,
+``QtWidgets``, ``QtNetwork``, etc.
+All those modules contains many classes that you can directly use, like the
+case of the `Classes of QtCore <https://doc.qt.io/qt-6/qtcore-module.html>`_
+from which you can find classes like ``QFile``, ``QTime``, ``QByteArray``, etc.
+
+You can create applications without a User Interface, while using this classes
+to create command line applications, handle files, network connections,
+regular expressions, encoding of text, etc.
+
+On the other hand, you can create Graphical applications with classes
+from the ``QtWidgets`` module, this is also referred as **Widgets**.
+
+There are many other Qt modules like ``QtMultimedia``, ``QtCharts``, ``Qt3D``,
+among others. These modules has a specific functionality, and among this
+modules, there is one called ``QtDeclarative``, in which you can find the
+implementation of the ``QML`` declarative language. This language is similar
+to CSS and JSON, and it was created to design UI applications declaratively,
+allowing JavaScript to take care of some imperative sections, and enabling
+other components to extend and connect the code with C++.
+
+Let us check the functionality of these different approaches separately.
+
+Widgets
+-------
+
+As we mentioned before, ``QtWidgets`` is the module that provide predefined
+Widgets that you can add into your graphical application, like Buttons, Labels,
+Boxes, Menus, etc.
+
+Widget based applications will look like a native application, because the goal
+is not to affect the user experience compared to other included applications.
+
+.. image:: hello_macOS.png
+ :width: 20%
+.. image:: hello_win10.jpg
+ :width: 20%
+.. image:: hello_linux.png
+ :width: 20%
+
+.. note:: You can adapt these applications to use your self-made style, but
+ you need to be aware that the goal of Widgets is to respect the system
+ style, be careful when changing colors. Check this
+ :ref:`simple tutorial <widgetstyling>` on how to do so.
+
+QML
+---
+
+QML offers an alternative approach to create User Interfaces, compared to
+Widgets, and it was originally motivated from mobile applications development.
+Together with the ``Qt Quick`` module, it provides access to interact with
+mobile device using actions like taps, drag and drop, animations, states,
+transitions, drawer menus, etc.
+
+The elements that you can find in QML/Quick applications are focused on
+providing a more dynamic application infrastructure which different properties
+based in certain behaviors.
+
+Even though QML has the motivation to provide interfaces with mobile devices,
+you can use it for Desktop applications, too.
+
+Additionally, you can augment your application with standard JavaScript, which
+in combination with C++ can become an attractive infrastructure.
+
+Python And C++
+--------------
+
+For |project| applications you **do not need to know C++**, but it is possible
+to mix both languages in a couple of different use cases:
+
+1. If you have a Qt/C++ application, you can re-write it so it is a Qt/Python
+ application. This means that Python aims to be a full replacement for the
+ user level C++ code of Qt applications.
+2. For custom Qt widgets written in C++, you can generate your own Python
+ bindings so people can use it directly from Python.
+3. If you have a C++ based library that you use with your Qt/C++ applications
+ that is in charge of a specific task, like a performant process, you can
+ generate bindings for it, so people could be able to use it from Python.
+4. For a Qt/C++ application, you can extend it with Python, by exposing the
+ main QApplication singleton as a python binding to a Python interpreter.
+ This can be understand as a "Python Plugin System" for your Qt/C++
+ application, for example.
+
+For the the steps **2., 3., and 4.** you need the help of Shiboken, the
+binding generation tool that is used to generate |project|.
+You can find more information in the
+`documentation page <https://doc.qt.io/qtforpython/shiboken6/index.html>`_.
diff --git a/sources/pyside6/doc/faq/whatisshiboken.rst b/sources/pyside6/doc/faq/whatisshiboken.rst
new file mode 100644
index 000000000..bf6d19ab3
--- /dev/null
+++ b/sources/pyside6/doc/faq/whatisshiboken.rst
@@ -0,0 +1,40 @@
+.. _whatisshiboken:
+
+Binding Generation: What Is Shiboken?
+=====================================
+
+When you install ``PySide6`` you might have notice that also ``Shiboken6``
+is installed as a dependency::
+
+ $ pip install pyside6
+ Collecting pyside6
+ Downloading PySide6-6.0.0-6.0.0-cp36.cp37.cp38.cp39-abi3-manylinux1_x86_64.whl (170.5 MB)
+ |████████████████████████████████| 170.5 MB 42 kB/s
+ Collecting shiboken6==6.0.0
+ Downloading shiboken6-6.0.0-6.0.0-cp36.cp37.cp38.cp39-abi3-manylinux1_x86_64.whl (964 kB)
+ |████████████████████████████████| 964 kB 29.3 MB/s
+ Installing collected packages: shiboken6, pyside6
+ Successfully installed pyside6-6.0.0 shiboken6-6.0.0
+
+That installed package is also called **Shiboken Module**, and it contains
+some utilities for PySide to properly work.
+You can find more information about it on its
+`documentation page (module) <https://doc.qt.io/qtforpython/shiboken6/shibokenmodule.html>`_
+
+There is a third package that does not get installed when you install PySide,
+because it is not required, and it is called **Shiboken Generator**.
+
+Most of the times you see mentions to use "Shiboken" or to do something
+related to "binding generation", it is about this third package, and **not**
+the dependency of the PySide package.
+
+Do I Need Shiboken Generator?
+-----------------------------
+
+If your goal is to just write Qt applications in Python,
+you do not need to worry about a Shiboken generator installation,
+but on the other hand, if you want to work with your own bindings
+or extend Qt/C++ applications with Python, you **need** it.
+
+You can find all the information related to Shiboken on its
+`documentation page (generator) <https://doc.qt.io/qtforpython/shiboken6/>`_.
diff --git a/sources/pyside6/doc/faq/whichide.rst b/sources/pyside6/doc/faq/whichide.rst
new file mode 100644
index 000000000..3afa79b7f
--- /dev/null
+++ b/sources/pyside6/doc/faq/whichide.rst
@@ -0,0 +1,56 @@
+.. _whichide:
+
+Which IDEs Are Compatible?
+==========================
+
+|project|, as any other Python module, can be used in any Python-compatible
+IDE, but not all of them will provide extra functionality like *Qt Creator* does.
+
+Besides writing files, there are some external steps you might want to perform
+in order to help the development of your applications:
+
+From a terminal:
+
+* Generating a Python file from a ``.ui`` file:
+ :command:`pyside6-uic -i form.ui -o ui_form.py`
+* Generating a Python file from a ``.qrc`` file:
+ :command:`pyside6-rcc -i resources.qrc -o rc_resources.py`
+* Opening *Qt Widgets Designer* with the command :command:`pyside6-designer`
+ to edit/create ``.ui`` files.
+
+External add-ons/plugins from your favorite IDE might include configuration
+steps to run these commands, or open external tools like Designer and
+QtCreator.
+
+QtCreator
+---------
+
+You can create new projects based on some basic templates that are currently
+available in QtCreator. After selecting one, you will pass through some steps
+where you can specify the details of the template, like the project name,
+base Qt class to use for your interface, among others.
+
+Here you can see an animation of the creation of a project:
+
+.. image:: https://qt-wiki-uploads.s3.amazonaws.com/images/7/7c/Qtcreator.gif
+ :alt: Qt Creator Animation
+
+Visual Studio Code
+------------------
+
+Besides editing the code of your application, you can use external plugins to
+enable more functionality, like this unofficial
+`plugin <https://marketplace.visualstudio.com/items?itemName=seanwu.vscode-qt-for-python>`_
+that you can install from VS Code while writing the following on the Quick Open Menu (``Ctrl+P``):
+:command:`ext install seanwu.vscode-qt-for-python`.
+
+PyCharm
+-------
+
+You can configure PyCharm to enable external tools, in |project| terms,
+*Qt Widgets Designer*, and *Qt Creator*. Go to
+``File > Settings > tools > PyCharm External Tools``, and include the following
+information to add them to your project.
+Later, you will be able to right click a ``.ui`` file, and select
+``Qt Widgets Designer``, ``pyside6-uic``, or any tool that you configured this
+way.
diff --git a/sources/pyside6/doc/faq/whyqtforpython.rst b/sources/pyside6/doc/faq/whyqtforpython.rst
new file mode 100644
index 000000000..0f0ab9aaf
--- /dev/null
+++ b/sources/pyside6/doc/faq/whyqtforpython.rst
@@ -0,0 +1,203 @@
+.. _whyqtforpython:
+
+Why Qt for Python?
+==================
+
+.. image:: tiobe.png
+ :width: 0
+
+.. raw:: html
+
+ <div style="float: right; padding-left: 20px; max-width: 30%;
+ background-color: #e9eff5; padding-top: 5px;">
+ <img src="../_images/tiobe.png"
+ style="width: 90%;"
+ alt="TIOBE index for Python" />
+ <p style="font-size: 80%;">
+ Screenshot from
+ <a href="https://www.tiobe.com/tiobe-index/python/">tiobe.com/tiobe-index/python</a>,
+ on 2021.09.06
+ </p>
+ </div>
+
+To answer this question we need to take a step back, and talk a bit about
+languages.
+
+Python has been around for almost the same amount of years that Qt has,
+and similarly it has been growing, and transforming to become the most used,
+loved, and demanded language for many programming areas.
+
+Currently (2021), it's rare to be aware of Machine Learning and Artificial
+Intelligence, without having heard of Python. Similarly, when we hear about
+Data Science/Analysis/Engineering we know that it is most probably related
+to Python.
+
+One can validate this statements by public surveys that have been showing
+the evolution and preference of the Python language, like the StackOverflow
+Surveys of the lasts years:
+
++----------------------+-----------+-----------+-----------+
+| | 2019_ | 2020_ | 2021_ |
++======================+===========+===========+===========+
+| Most Loved Language | 2nd place | 3rd place | 6th place |
++----------------------+-----------+-----------+-----------+
+| Most Wanted Language | 1st place | 1st place | 1st place |
++----------------------+-----------+-----------+-----------+
+
+and the `TIOBE index`_ (image on the right).
+
+It's natural to think that this sources might not be enough to judge the
+language in general terms, but it certainly highlights a trend among
+developers around the world.
+
+Lowering the Qt Barrier
+-----------------------
+
+Veteran C++ developers will have no problem with setting up a Qt
+application from scratch, or even manage to understand a different
+code base written with Qt. In addition, many teams are multidisciplinary,
+and other project/company developers might not be fluent in C++.
+
+Python has been luring people into programming, and for the same reason
+it's not uncommon that even people with a different background are able
+to write code, meaning that different teams are enabled to speak
+"the same language".
+
+Creating Qt applications in Python requires only a few lines of code,
+and not much configuration is required to execute it. As an /unfair/
+example, let's check the code of a simple hello world application:
+
+.. tab-set::
+
+ .. tab-item:: C++ Header
+
+ .. code-block:: cpp
+
+ #ifndef MAINWINDOW_H
+ #define MAINWINDOW_H
+
+ #include <QMainWindow>
+ #include <QPushButton>
+
+ class MainWindow : public QMainWindow
+ {
+ Q_OBJECT
+ public:
+ MainWindow(QWidget *parent = nullptr);
+ private slots:
+ void handleButton();
+ private:
+ QPushButton *m_button;
+ };
+
+ #endif // MAINWINDOW_H
+
+ .. tab-item:: C++ Implementation
+
+ .. code-block:: cpp
+
+ #include "mainwindow.h"
+
+ MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ {
+ m_button = new QPushButton("My Button", this);
+ connect(m_button, SIGNAL(clicked()), this,
+ SLOT(handleButton()));
+ }
+
+ void MainWindow::handleButton()
+ {
+ m_button->setText("Ready");
+ }
+
+ .. tab-item:: C++ Main
+
+ .. code-block:: cpp
+
+ #include <QApplication>
+ #include "mainwindow.h"
+
+ int main(int argc, char *argv[])
+ {
+ QApplication app(argc, argv);
+ MainWindow mainWindow;
+ mainWindow.show();
+ return app.exec(d);
+ }
+
+.. tab-set::
+
+ .. tab-item:: Python
+
+ .. code-block:: python
+
+ import sys
+ from pyside6.QtWidgets import (QApplication, QMainWindow,
+ QPushButton)
+
+ class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ QMainWindow.__init__(self, parent)
+ self.button = QPushButton("My Button", self)
+ self.button.clicked.connect(self.handleButton)
+
+ def handleButton(self):
+ self.button.setText("Ready")
+
+ if __name__ == "__main__":
+ app = QApplication([])
+ mainWindow = MainWindow()
+ mainWindow.show()
+ sys.exit(app.exec())
+
+It's fair to say that most of the boilerplate code is provided by many
+good IDEs, like QtCreator, but using external tools certainly requires
+some practice to use them and get familiarized.
+
+Unity Makes Strength
+--------------------
+
+In our mission to enable more developers to enter the Qt World, it's
+important to note that this doesn't imply C++ developers are forgotten.
+
+Together with the bindings, Qt for Python provides our binding generator,
+Shiboken (Check :ref:`whatisshiboken`), whose functionality has
+extensibly been shown by talks on events such as those from our
+:ref:`video-gallery` section.
+
+Generating bindings between two languages it nothing new, but it has
+always been a non-trivial task, mainly for being as-compatible-as-possible
+when using external modules/libraries in your project.
+
+Shiboken's main use case is to extend Qt/C++ project's
+functionality, making them **scriptable**.
+
+What does it mean for an application to be scriptable?
+
+* enables a interpreted language to interact directly with the Qt/C++
+ application,
+* provide the option to modify and create components/elements of the
+ application from Python,
+* possibility to create a plugins/add-ons system for the application.
+* complement a process with external Python functionality.
+
+Check out this `Shiboken Webinar`_ for a hands-on example.
+
+Shiboken excels at Qt-dependent binding generation, meaning that
+any Qt/C++ project can be easily exposed to Python.
+In addition, Shiboken has proven its support for C++ projects (without Qt),
+as shown on event talks and `blog posts`.
+
+Adding Python support to well known solutions/projects is a pattern we keep
+seeing in the industry, on a broad range of devices.
+This is why we are working every day to improve the Qt for Python offering.
+
+We believe both Qt and Python will benefit from this interaction.
+
+.. _2019: https://insights.stackoverflow.com/survey/2019
+.. _2020: https://insights.stackoverflow.com/survey/2020
+.. _2021: https://insights.stackoverflow.com/survey/2021
+.. _`TIOBE index`: https://www.tiobe.com/tiobe-index/
+.. _`blog posts`: https://www.qt.io/blog/tag/qt-for-python
+.. _`Shiboken Webinar`: https://www.youtube.com/watch?v=wOMlDutOWXI
diff --git a/sources/pyside6/doc/gettingstarted/index.rst b/sources/pyside6/doc/gettingstarted/index.rst
new file mode 100644
index 000000000..51d8bea26
--- /dev/null
+++ b/sources/pyside6/doc/gettingstarted/index.rst
@@ -0,0 +1,572 @@
+Getting Started
+===============
+
+.. important:: This page is focused on building |project| **from source**.
+ If you just want to install |pymodname|, you need to run: :command:`pip install pyside6`.
+
+ For more details, refer to our :ref:`quick-start` guide. Additionally, you can check the
+ :ref:`FAQ <faq>` related to the project.
+
+.. _Quick Start: quickstart.html
+
+General Requirements
+--------------------
+
+The following prerequisites must be installed before you build |project|.
+On **Linux** you might get them with your operating system package manager, on **macOS**
+you might get them with ``brew``, and on **Windows** you can download the installer from each
+website.
+
+* **Python**: 3.9+ `[official Python website] <https://www.python.org/downloads/>`_
+* **Qt:** 6.8+ `[online installer] <https://download.qt.io/official_releases/online_installers/>`_
+* **CMake:** 3.18+ `[official CMake website] <https://cmake.org/download/>`_
+* **Git:** 2.0+. `[official Git website] <https://git-scm.com/downloads>`_
+* **libclang:** The libclang library, recommended: version 16+ for 6.8+.
+ Prebuilt versions for each OS can be `downloaded here`_.
+* Check the `Supported Platforms of Qt`_
+
+.. _downloaded here: https://download.qt.io/development_releases/prebuilt/libclang/
+.. _`Supported Platforms of Qt` : https://doc.qt.io/qt-6/supported-platforms.html
+
+Guides per platform
+-------------------
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+ linux.rst
+ macOS.rst
+ windows.rst
+ package_details.rst
+ porting_from2.rst
+
+You can refer to the following pages for platform specific instructions:
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card::
+ :img-top: ../images/windows.svg
+ :class-item: text-center
+
+ +++
+ .. button-ref:: windows
+ :color: primary
+ :outline:
+ :expand:
+
+ Windows
+
+ .. grid-item-card::
+ :img-top: ../images/macos.svg
+ :class-item: text-center
+
+ +++
+ .. button-ref:: macOS
+ :color: primary
+ :outline:
+ :expand:
+
+ macOS
+
+ .. grid-item-card::
+ :img-top: ../images/linux.svg
+ :class-item: text-center
+
+ +++
+ .. button-ref:: linux
+ :color: primary
+ :outline:
+ :expand:
+
+ Linux
+
+.. important:: |project| does not yet support WebAssembly and the mobile operating systems (Android or iOS).
+ Most Linux-based embedded OS provide PySide with their official
+ package manager (for example, `Raspbian`_ and `ArchlinuxARM`_).
+
+.. _Raspbian: https://www.raspbian.org/
+.. _ArchlinuxARM: https://archlinuxarm.org/
+
+A normal building command will look like this::
+
+ python setup.py install --qtpaths=/path/to/qtpaths \
+ --ignore-git \
+ --debug \
+ --build-tests \
+ --parallel=8 \
+ --verbose-build \
+ --module-subset=Core,Gui,Widgets
+
+Which will build and install the project with **debug** symbols, including the **tests**,
+using **ninja** (instead of make), and considering only the **module subset** of
+:mod:`QtCore <PySide6.QtCore>`, :mod:`QtGui <PySide6.QtGui>`, and
+:mod:`QtWidgets <PySide6.QtWidgets>`.
+
+`CMake Unity Build Mode`_ is used by default for speed-up.
+
+Other important options to consider are:
+ * ``--cmake``, to specify the path to the cmake binary,
+ * ``--reuse-build``, to rebuild only the modified files,
+ * ``--openssl=/path/to/openssl/bin``, to use a different path for OpenSSL,
+ * ``--standalone``, to copy over the Qt libraries into the final package to make it work on other
+ machines,
+ * ``--build-docs``, to enable the documentation build.
+ * ``--doc-build-online``, to build documentation using the online template (by
+ default it uses the offline)
+
+Testing the installation
+------------------------
+
+Once the installation finishes, you will be able to execute any of our examples::
+
+ python examples/widgets/widgets/tetrix.py
+
+Running Tests
+-------------
+
+Using the ``--build-tests`` option will enable us to run all the auto tests inside the project::
+
+ python testrunner.py test > testlog.txt
+
+.. note:: On Windows, don't forget to have qtpaths in your path
+ (:command:`set PATH=C:\\\Path\\\to\\\Qt\\\6.4.0\\\msvc2019_64\\\bin;%PATH%`)
+
+You can also run a specific test (for example ``qpainter_test``) by running::
+
+ ctest -R qpainter_test --verbose
+
+.. _cross_compilation:
+
+Cross Compilation
+-----------------
+
+Starting from 6.3, it is possible to cross-compile Shiboken (module), and
+PySide. This functionality is still in Technical Preview, which means it could
+change in the future releases.
+
+.. important:: The only supported configuration is using a host Linux
+ machine to cross-compile to a Linux target platform.
+
+Cross compiling software is a valid use case that many projects rely on,
+however, it is a complicated process that might fail due to many reasons.
+
+Before starting with the process, it is important to understand the details of
+the build system, and the goal of cross compilation.
+
+In the build process, a ``Host`` is the computer you are currently using to
+compile, and a ``Target`` is your embedded device that you are compiling for.
+
+Qt for Python is being built using setuptools, and relies on a ``setup.py`` file
+that is called recursively to build Shiboken (module),
+Shiboken (generator), and PySide. As the generator is creating
+the wrappers for the bindings, it's not cross compiled
+for the target.
+Only the Shiboken (module) and PySide are cross compiled.
+
+The building process requires a Qt installation, and a Python interpreter
+on both the host, and the target. The used Qt versions on both platforms
+should have the same minor version. That is, Qt 6.3 (host)
+cannot be used with a Qt 6.2 (target), or the other way around.
+
+.. note:: It is recommended to use the same version of Qt on both host and target to avoid possible
+ unconventional errors.
+
+Prerequisites
+~~~~~~~~~~~~~
+
+First and foremost, you need to have access to the target device because you
+need to copy several system files (sysroot). We recommend a Linux OS that has
+the latest Qt versions, like `Manjaro ARM`_ or `Archlinux ARM`_.
+
+* (target) Install Qt 6.3+ on the system using the package manager.
+* (host) Install Qt 6.3+ on the system using the package manager or Qt
+ Installer.
+* (target, host) Install the library and development packages that provide
+ C++ headers, linkers, libraries, and compilers.
+* (target, host) Install Python interpreter v3.7 or later
+* (target, host) Install CMake 3.17+
+
+After installing these prerequisites, copy the ``target`` sysroot to your
+``host`` computer. This process is tricky, because copying system files from
+another computer might cause problems with the symbolic links. Here you
+have two options to achieve that.
+
+Option A: Copying the files
+***************************
+
+Create a directory to copy the sysroot of your target device,
+for example ``rpi-sysroot``, and perform the copy on your host computer:
+
+.. code-block:: bash
+
+ rsync -vR --progress -rl --delete-after --safe-links \
+ USERNAME@TARGET_IP:/{lib,usr,opt/vc/lib} rpi-sysroot/
+
+Ensure to replace ``USERNAME`` and ``TARGET_IP`` with your system appropriate
+values.
+
+Option B: Packaging the file system
+***********************************
+
+Create a package for your sysroot in your target:
+
+.. code-block:: bash
+
+ tar cfJ ~/sysroot.tar.xz /lib /usr /opt/vc/lib
+
+Copy the package from the target to your host:
+
+.. code-block:: bash
+
+ rsync -vR --progress USERNAME@TARGET_IP:sysroot.tar.xz .
+
+Once you have the tar file, unpack it inside a ``rpi-sysroot`` directory.
+
+Fix Symlinks
+************
+
+It is recommended to run the following script to fix
+most of the issues you would find with symbolic links:
+
+.. code-block:: python
+
+ import sys
+ from pathlib import Path
+ import os
+
+ # Take a sysroot directory and turn all the absolute symlinks and turn them into
+ # relative ones such that the sysroot is usable within another system.
+
+ if len(sys.argv) != 2:
+ print(f"Usage is {sys.argv[0]} <sysroot-directory>")
+ sys.exit(-1)
+
+ topdir = Path(sys.argv[1]).absolute()
+
+ def handlelink(filep, subdir):
+ link = filep.readlink()
+ if str(link)[0] != "/":
+ return
+ if link.startswith(topdir):
+ return
+ relpath = os.path.relpath((topdir / link).resolve(), subdir)
+ os.unlink(filep)
+ os.symlink(relpath, filep)
+
+ for f in topdir.glob("**/*"):
+ if f.is_file() and f.is_symlink():
+ handlelink(f, f.parent)
+
+Setting up the toolchain
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+To perform the cross compilation, you need a special set of compilers,
+libraries, and headers, which runs on the host architecture, but generates
+(binaries/executables) for a target architecture.
+For example, from x86_64 to aarch64.
+
+It is recommended to use the official 10.2 `ARM Developer cross compilers`_,
+which you can find on their official website. For this tutorial, we choose
+``aarch64`` target architecture and we will assume that you downloaded the
+`gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz`_ file,
+and unpacked it.
+
+With those compilers, now you need a CMake toolchain file. This is
+a configuration file to set the compilers and sysroot information, together
+with extra options like compilation flags, and other details. You can use the
+following file as an example, but keep in mind they might vary:
+
+.. code-block:: cmake
+
+ # toolchain-aarch64.cmake
+ cmake_minimum_required(VERSION 3.18)
+ include_guard(GLOBAL)
+
+ set(CMAKE_SYSTEM_NAME Linux)
+ set(CMAKE_SYSTEM_PROCESSOR aarch64)
+
+ set(TARGET_SYSROOT /path/to/your/target/sysroot)
+ set(CROSS_COMPILER /path/to/your/crosscompiling/compilers/)
+
+ set(CMAKE_SYSROOT ${TARGET_SYSROOT})
+
+ set(ENV{PKG_CONFIG_PATH} "")
+ set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig)
+ set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
+
+ set(CMAKE_C_COMPILER ${CROSS_COMPILER}/aarch64-none-linux-gnu-gcc)
+ set(CMAKE_CXX_COMPILER ${CROSS_COMPILER}/aarch64-none-linux-gnu-g++)
+
+ set(QT_COMPILER_FLAGS "-march=armv8-a")
+ set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
+ set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
+
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+ include(CMakeInitializeConfigs)
+
+ function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
+ if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")
+ set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")
+
+ foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
+ if (DEFINED QT_COMPILER_FLAGS_${config})
+ set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")
+ endif()
+ endforeach()
+ endif()
+
+ if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")
+ foreach (config SHARED MODULE EXE)
+ set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")
+ endforeach()
+ endif()
+
+ _cmake_initialize_per_config_variable(${ARGV})
+ endfunction()
+
+You need to adjust the paths in these two lines::
+
+ set(TARGET_SYSROOT /path/to/your/target/sysroot)
+ set(CROSS_COMPILER /path/to/your/crosscompiling/compilers/)
+
+and replace them with the sysroot directory (the one we called ``rpi-sysroot``),
+and the compilers (the ``gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin`` directory).
+
+
+Cross compiling PySide
+~~~~~~~~~~~~~~~~~~~~~~
+
+After you have installed the prerequisites and copied the necessary files, you
+should have the following:
+
+* The compilers to cross compile (``gcc-argm-10.2-...``),
+* The target sysroot (``rpi-sysroot``),
+* The toolchain cmake file (``toolchain-aarch64.cmake``),
+* The ``pyside-setup`` repository,
+
+An example of the ``setup.py`` invocation might look like the following:
+
+.. code-block:: bash
+
+ python setup.py bdist_wheel \
+ --parallel=8 --ignore-git --reuse-build --standalone --limited-api=yes \
+ --cmake-toolchain-file=/opt/toolchain-aarch64.cmake \
+ --qt-host-path=/opt/Qt/6.3.0/gcc_64 \
+ --plat-name=linux_aarch64
+
+Depending on the target platform, you could use ``linux_armv7``,
+``linux_aarch64``, etc.
+
+For embedded platforms, which typically do not have Qt and its tools fully
+built, the option ``--no-qt-tools`` can be used to prevent the bundling of the
+tools.
+
+If the process succeeds, you will find the target wheels in your ``dist/``
+directory, for example:
+
+.. code-block:: bash
+
+ PySide6-6.3.0-6.3.0-cp36-abi3-manylinux2014_aarch64.whl
+ shiboken6-6.3.0-6.3.0-cp36-abi3-manylinux2014_aarch64.whl
+
+
+Troubleshooting
+***************
+
+* If the auto-detection mechanism fails to find the Python or Qt installations
+ you have in your target device, you can use two additional options::
+
+ --python-target-path=...
+
+ and::
+
+ --qt-target-path=...
+
+* In case the automatic build of the host Shiboken (generator) fails,
+ you can specify the custom path using::
+
+ --shiboken-host-path=...
+
+.. _`Manjaro ARM`: https://manjaro.org/download/#ARM
+.. _`Archlinux ARM`: https://archlinuxarm.org
+.. _`ARM Developer Cross Compilers`: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
+.. _`gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz`: https://developer.arm.com/-/media/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz
+
+.. _building_documentation:
+
+Building the documentation
+--------------------------
+
+Starting from 6.3, the documentation is not being built by default.
+When using the second option described in this section, make sure to use the
+``--build-docs`` option.
+
+Install the specific documentation requirements in your Python virtual
+environment::
+
+ pip install -r requirements-doc.txt
+
+You can find the ``requirements-doc.txt`` file in the root of the repository.
+
+Starting from 5.15, there are two options to build the documentation:
+
+1. Building the base documentation (no API)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The process of parsing Qt headers to generate the PySide API documentation can take several
+minutes, this means that modifying a specific section of the documentation we currently have, might
+become a hard task. You may only care about the base documentation, which comprises all the
+documentation except for the API documentation.
+
+To generate this, execute the following command::
+
+ python setup.py build_base_docs
+
+This will generate an ``html/`` directory with the following structure::
+
+ html
+ └── pyside6
+ ├── index.html
+ ├── ...
+ └── shiboken6
+ ├── index.html
+ └── ...
+
+so you can open the main page ``html/pyside6/index.html`` on your browser to check the generated
+files.
+
+This is useful when updating the general sections of the documentation, adding tutorials,
+modifying the build instructions, and more.
+
+.. note:: In case you are interested in only generating the Example Gallery,
+ you would need to run ``python tools/example_gallery/main.py`` to
+ generate the examples ``documentation`` for the gallery. This will
+ also be used internally by the ``build_base_docs`` target
+
+
+2. Building the documentation (Base + API)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The documentation is being generated using **qdoc** to get the API information, and also **sphinx**
+for the local Python related notes.
+
+The system requires the ``libxml2`` and ``libxslt`` libraries.
+
+After installing ``graphviz`` (included in the ``requirements-doc.txt`` file),
+the ``dot`` command needs to be in PATH, otherwise,
+the process will fail. Installing ``graphviz`` system-wide is also an option.
+
+Since the process relies on a Qt installation, you need to specify where the
+``qtbase`` directory of a Qt source tree is located by passing it to
+the command line option ``--qt-src-dir``.
+
+Once the common ``setup.py`` build process finishes (remember to use
+``--build-docs`` to enable the documentation build, and ``--doc-build-online``
+to get the HTML files), you can go to the generated
+``build/<your_env_name>/build/pyside6`` directory, and run::
+
+ ninja apidoc
+
+You can add ``-j X``, to perform the build process in parallel with
+X processes.
+
+.. note:: The :command:`apidoc` make target builds offline documentation in ``QCH``
+ (Qt Compressed Help) format by default. You can switch to building for the
+ online use with the ``--doc-build-online`` configure option.
+
+The target executes several steps:
+
+#. The ``qdoc`` tool is run over the Qt source code to produce documentation in WebXML format.
+#. ``shiboken6`` is run to extract the functions for which bindings exist from WebXML and convert it into RST.
+#. ``sphinx`` is run to produce the documentation in HTML format.
+
+Re-running the command will not execute step 1 unless the file
+``qdoc-output/webxml/qtcore-index.webxml`` is removed from the build tree.
+Similarly, step 2 will not be executed unless the file ``base/PySide6/QtCore/index.rst``
+is removed.
+
+Finally, you will get a ``html`` directory containing all the generated documentation. The offline
+help files, ``PySide.qch`` and ``Shiboken.qch``, can be moved to any directory of your choice. You
+can find ``Shiboken.qch`` in the build directory, ``build/<your_env_name>/build/shiboken6/doc/html``.
+
+If you want to temporarily change a ``.rst`` file to examine the impact on
+formatting, you can re-run ``sphinx`` in the ``doc`` directory::
+
+ sphinx-build base html
+
+Viewing offline documentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The offline documentation (QCH) can be viewed using the *Qt Creator* IDE or
+*Qt Assistant*, which is a standalone application for viewing QCH files.
+
+To view the QCH using *Qt Creator*, following the instructions outlined in
+`Using Qt Creator Help Mode <https://doc.qt.io/qtcreator/creator-help.html>`_.
+If you chose to use *Qt Assistant* instead, use the following command to register
+the QCH file before launching *Qt Assistant*::
+
+ assistant -register PySide.qch
+
+Troubleshooting documentation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The documentation uses intersphinx to link from the PySide to the
+Shiboken documentation. This can fail if
+
+* the default ``QCH`` format is used; in which case the required ``objects.inv``
+ files are not generated. Use ``--doc-build-online``.
+* base and full doc builds are mixed, resulting in wrong values for the
+ intersphinx location in the CMake files. Re-run ``cmake`` to fix this.
+
+Using the internal tools
+------------------------
+
+A set of tools can be found under the ``tools/`` directory inside the ``pyside-setup`` repository.
+
+* ``checklibs.py``: Script to analyze dynamic library dependencies of Mach-O binaries.
+ To use this utility, just run::
+
+ python checklibs.py /path/to/some.app/Contents/MacOS/Some
+
+ This script was fetched from this repository_.
+
+* ``create_changelog.py``: Script used to create the CHANGELOG that you can find in the ``dist/``
+ directory. Usage::
+
+ python create_changelog.py -r 6.0.1 -v v6.0.0..6.0 -t bug-fix
+
+* ``debug_windows.py``: This script can be used to find out why PySide modules
+ fail to load with various DLL errors like Missing DLL or Missing symbol in DLL.
+
+ You can think of it as a Windows version of :command:`ldd` / ``LD_DEBUG``.
+
+ Underneath, it uses the :command:`cdb.exe` command line debugger and the :command:`gflags.exe`
+ tool, which are installed with the latest Windows Kit.
+
+ The aim is to help developers debug issues that they may encounter using the PySide imports on
+ Windows. The user should then provide the generated log file.
+
+ Incidentally it can also be used for any Windows executables, not just Python.
+ To use it just run::
+
+ python debug_windows.py
+
+* ``missing_bindings.py``: This script is used to compare the state of PySide and PyQt
+ regarding available modules and classses. This content is displayed in our `wiki page`_,
+ and can be used as follows::
+
+ python missing_bindings.py --qt-version 6.0.1 -w all
+
+.. note:: The script relies on BeautifulSoup to parse the content and generate a list of the
+ missing bindings.
+
+.. _repository: https://github.com/liyanage/macosx-shell-scripts/
+.. _`wiki page`: https://wiki.qt.io/Qt_for_Python_Missing_Bindings
+.. _BeautifulSoup: https://www.crummy.com/software/BeautifulSoup/
+.. _`CMake Unity Build Mode` : https://cmake.org/cmake/help/latest/prop_tgt/UNITY_BUILD.html
diff --git a/sources/pyside6/doc/gettingstarted/linux.rst b/sources/pyside6/doc/gettingstarted/linux.rst
new file mode 100644
index 000000000..eb1b5869d
--- /dev/null
+++ b/sources/pyside6/doc/gettingstarted/linux.rst
@@ -0,0 +1,119 @@
+Getting Started on Linux
+==========================
+
+Requirements
+------------
+
+* GCC
+* ``sphinx`` package for the documentation (optional).
+* Depending on your linux distribution, the following dependencies might also be required:
+
+ * ``libgl-dev``, ``python-dev``, and ``python-setuptools``.
+* Check the platform dependencies of `Qt for Linux/X11`_.
+
+Building from source
+--------------------
+
+Creating a virtual environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``venv`` module allows you to create a local, user-writeable copy of a python environment into
+which arbitrary modules can be installed and which can be removed after use::
+
+ python -m venv testenv
+ source testenv/bin/activate
+
+will create and use a new virtual environment, which is indicated by the command prompt changing.
+
+Setting up CLANG
+~~~~~~~~~~~~~~~~
+
+If you don't have libclang already in your system, you can download from the Qt servers::
+
+ wget https://download.qt.io/development_releases/prebuilt/libclang/libclang-release_18.1.5-based-linux-Rhel8.6-gcc10.3-x86_64.7z
+
+Extract the files, and leave it on any desired path, and set the environment
+variable required::
+
+ 7z x libclang-release_18.1.5-based-linux-Rhel8.6-gcc10.3-x86_64.7z
+ export LLVM_INSTALL_DIR=$PWD/libclang
+
+Getting the source
+~~~~~~~~~~~~~~~~~~
+
+Cloning the official repository can be done by::
+
+ git clone https://code.qt.io/pyside/pyside-setup
+
+Checking out the version that we want to build, for example 6.8::
+
+ cd pyside-setup && git checkout 6.8
+
+Install the general dependencies::
+
+ pip install -r requirements.txt
+
+For building the documentation::
+
+ pip install -r requirements-doc.txt
+
+.. note:: Keep in mind you need to use the same version as your Qt installation.
+ Additionally, :command:`git checkout -b 6.8 --track origin/6.8` could be a better option
+ in case you want to work on it.
+
+Building and Installing (setuptools)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``setuptools`` approach uses the ``setup.py`` file to execute the build,
+install, and packaging steps.
+
+Check your Qt installation path, to specifically use that version of qtpaths to build PySide.
+for example, :command:`/opt/Qt/6.8.0/gcc_64/bin/qtpaths`.
+
+Build can take a few minutes, so it is recommended to use more than one CPU core::
+
+ python setup.py build --qtpaths=/opt/Qt/6.8.0/gcc_64/bin/qtpaths --build-tests --ignore-git --parallel=8
+
+To install on the current directory, just run::
+
+ python setup.py install --qtpaths=/opt/Qt/6.8.0/gcc_64/bin/qtpaths --build-tests --ignore-git --parallel=8
+
+Building and Installing (cmake)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``setuptools`` approach includes internal ``CMake`` calls when
+building and installing the project, but a CMake-only approach is only
+recommended for packaging the project for distribution builds.
+
+Assumming that Qt is in PATH, for example, the configure step can be done with::
+
+ cmake -B /path/to/the/build/directory \
+ -S /path/to/the/pyside-setup \
+ -DCMAKE_INSTALL_PREFIX=/where/to/install \
+ -DPython_EXECUTABLE=/path/to/interpreter
+
+.. note:: You can add `-DFORCE_LIMITED_API=yes` in case you want to have a
+ build which will be compatible with Python 3.7+.
+
+and then for building::
+
+ cmake --build /path/to/the/build/directory --parallel X
+
+where `X` is the amount of processes you want to use.
+Finally, the install step can be done with::
+
+ cmake --install /path/to/the/build/directory
+
+.. note:: You can build only pyside6 or only shiboken6 by using
+ the diferent source directories with the option `-S`.
+
+
+Test installation
+~~~~~~~~~~~~~~~~~
+
+You can execute one of the examples to verify the process is properly working.
+Remember to properly set the environment variables for Qt and PySide::
+
+ python examples/widgets/widgets/tetrix.py
+
+.. _`Qt for Linux/X11`: https://doc.qt.io/qt-6/linux.html
diff --git a/sources/pyside6/doc/gettingstarted/macOS.rst b/sources/pyside6/doc/gettingstarted/macOS.rst
new file mode 100644
index 000000000..accffbe92
--- /dev/null
+++ b/sources/pyside6/doc/gettingstarted/macOS.rst
@@ -0,0 +1,89 @@
+Getting Started on macOS
+========================
+
+Requirements
+------------
+
+* `XCode`_ 8.2 (macOS 10.11), 8.3.3 (macOS 10.12), 9 (macOS 10.13), 10.1 (macOS 10.14)
+* ``sphinx`` package for the documentation (optional).
+* Depending on your OS, the following dependencies might also be required:
+
+ * ``libgl-dev``, ``python-dev``, and ``python-setuptools``.
+
+* Check the platform dependencies of `Qt for macOS`_.
+
+.. _XCode: https://developer.apple.com/xcode/
+.. _`Qt for macOS`: https://doc.qt.io/qt-6/macos.html
+
+Building from source
+--------------------
+
+Creating a virtual environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``venv`` module allows you to create a local, user-writeable copy of a python environment into
+which arbitrary modules can be installed and which can be removed after use::
+
+ python -m venv testenv # your interpreter could be called 'python3'
+ source testenv/bin/activate
+
+will create and use a new virtual environment, which is indicated by the command prompt changing.
+
+Setting up CLANG
+~~~~~~~~~~~~~~~~
+
+If you don't have libclang already in your system, you can download from the Qt servers::
+
+ wget https://download.qt.io/development_releases/prebuilt/libclang/libclang-release_18.1.5-based-macos-universal.7z
+
+Extract the files, and leave it on any desired path, and set the environment
+variable required::
+
+ 7z x libclang-release_18.1.5-based-macos-universal.7z
+ export LLVM_INSTALL_DIR=$PWD/libclang
+
+Getting PySide
+~~~~~~~~~~~~~~
+
+Cloning the official repository can be done by::
+
+ git clone https://code.qt.io/pyside/pyside-setup
+
+Checking out the version that we want to build, for example, 6.8::
+
+ cd pyside-setup && git checkout 6.8
+
+Install the general dependencies::
+
+ pip install -r requirements.txt
+
+For building the documentation::
+
+ pip install -r requirements-doc.txt
+
+.. note:: Keep in mind you need to use the same version as your Qt installation
+
+Building PySide
+~~~~~~~~~~~~~~~
+
+Check your Qt installation path, to specifically use that version of qtpaths to build PySide.
+for example, ``/opt/Qt/6.8.0/gcc_64/bin/qtpaths``.
+
+Build can take a few minutes, so it is recommended to use more than one CPU core::
+
+ python setup.py build --qtpaths=/opt/Qt/6.8.0/gcc_64/bin/qtpaths --build-tests --ignore-git --parallel=8
+
+Installing PySide
+~~~~~~~~~~~~~~~~~
+
+To install on the current directory, just run::
+
+ python setup.py install --qtpaths=/opt/Qt/6.8.0/gcc_64/bin/qtpaths --build-tests --ignore-git --parallel=8
+
+Test installation
+~~~~~~~~~~~~~~~~~
+
+You can execute one of the examples to verify the process is properly working.
+Remember to properly set the environment variables for Qt and PySide::
+
+ python examples/widgets/widgets/tetrix.py
diff --git a/sources/pyside6/doc/gettingstarted/package_details.rst b/sources/pyside6/doc/gettingstarted/package_details.rst
new file mode 100644
index 000000000..113edb686
--- /dev/null
+++ b/sources/pyside6/doc/gettingstarted/package_details.rst
@@ -0,0 +1,75 @@
+.. _package_details:
+
+Package Details
+===============
+
+Having a large project as the Qt Framework available from one simple
+installation line::
+
+ pip install pyside6
+
+is really beneficial,
+but it might be confusing to newcomers.
+
+Besides your IDE, you don't need to install anything else to develop your
+Qt application, because the same command installs many tools
+that will help you design UIs, use QML types, generate
+files automatically, translate applications, etc.
+
+Package Dependencies
+--------------------
+
+.. image:: packages.png
+ :width: 400
+ :alt: Packages structure and dependency
+
+Starting from 6.3.0, the ``pyside6`` package (wheel) is almost empty,
+and only includes references to other packages that are required
+to properly use all the modules.
+This packages are:
+
+* ``pyside6-essentials``, `essential Qt modules <https://pypi.org/project/PySide6-Essentials/>`_,
+* ``pyside6-addons``, `additional Qt modules <https://pypi.org/project/PySide6-Addons/>`_,
+* ``shiboken6``, a utility Python module.
+
+You can verify this by running ``pip list`` to check the installed
+packages in your Python (virtual) environment::
+
+ (env) % pip list
+ Package Version
+ ------------------ -------
+ pip 22.0.4
+ PySide6 6.3.0
+ PySide6-Addons 6.3.0
+ PySide6-Essentials 6.3.0
+ setuptools 58.1.0
+ shiboken6 6.3.0
+
+Both ``pyside6-essentials`` and ``pyside6-addons`` contain Qt binaries
+(``.so``, ``.dll``, or ``.dylib``) that are used by the Python wrappers
+that enable you to use the Qt modules from Python.
+For example, in the ``QtCore`` module, you will find
+on Linux:
+
+* ``PySide6/QtCore.abi3.so``, and
+* ``PySide6/Qt/lib/libQt6Core.so.6``
+
+inside the ``site-packages`` directory of your (virtual) environment.
+The first is the *importable* module which depends on the second file
+which is the original QtCore library.
+
+.. note:: The package ``shiboken6-generator`` is not a dependency,
+ and it's not available on PyPi. The reason, is that it depends on
+ ``libclang``, which is a large library that we don't package, and
+ requires a special configuration for you to use. Check the `Shiboken
+ Documentation`_ for more details.
+
+..
+ Adding the full URL because it's a different sphinx project.
+.. _`Shiboken Documentation`: https://doc.qt.io/qtforpython/shiboken6/gettingstarted.html
+
+Tools Included
+--------------
+
+PySide6 comes bundled with a set of tools that assist in making the development experience with
+PySide6 more efficient. The list of tools can be found :ref:`here <package_tools>`.
diff --git a/sources/pyside6/doc/gettingstarted/packages.png b/sources/pyside6/doc/gettingstarted/packages.png
new file mode 100644
index 000000000..57e7ca47d
--- /dev/null
+++ b/sources/pyside6/doc/gettingstarted/packages.png
Binary files differ
diff --git a/sources/pyside6/doc/gettingstarted/porting_from2.rst b/sources/pyside6/doc/gettingstarted/porting_from2.rst
new file mode 100644
index 000000000..6699f54e0
--- /dev/null
+++ b/sources/pyside6/doc/gettingstarted/porting_from2.rst
@@ -0,0 +1,94 @@
+Porting Applications from PySide2 to PySide6
+============================================
+
+Module Availability
+-------------------
+
+Qt for Python 6.2.0 provides all modules planned for inclusion in Qt 6.
+
+Module-Level Changes
+--------------------
+
+* The modules *QtMacExtras*, *Qt Quick Controls 1*, *QtWinExtras*,
+ *QtXmlPatterns* and *QtX11Extras* have been removed.
+* ``QStateMachine`` and related classes have been extracted to a new
+ *QtStateMachine* module.
+* The modules *QtWebKit* and *QtWebKitWidgets* have been replaced by the new
+ *QtWebEngineCore*, *QtWebEngineQuick* and *QtWebEngineWidgets* modules.
+* ``QXmlReader`` and related classes (*SAX API*) have been removed.
+* The content of the *QtOpenGL* module has been replaced. The class
+ ``QGLWidget`` and related classes (``QGLContext``, ``QGLFunctions``,
+ ``QGLShaderProgram``) have been removed. Parts of the *Open GL*
+ functionality from *QtGui* have been extracted into this module, for example
+ ``QOpenGLBuffer`` and ``QOpenGLShaderProgram``.
+ There is a new module *QtOpenGLWidgets* which contains the class
+ ``QOpenGLWidget``, a replacement for ``QGLWidget``.
+
+As *Open GL* is phasing out,
+`QRhi <https://doc.qt.io/qt-6/topics-graphics.html>`_ should be considered
+for graphics applications.
+
+Imports
+-------
+
+The first thing to do when porting applications is to replace the
+import statements:
+
+.. code-block:: python
+
+ from PySide2.QtWidgets import QApplication
+ from PySide2 import QtCore
+
+needs to be changed to:
+
+.. code-block:: python
+
+ from PySide6.QtWidgets import QApplication
+ from PySide6 import QtCore
+
+
+Some classes are in a different module now, for example
+``QAction`` and ``QShortcut`` have been moved from ``QtWidgets`` to ``QtGui``.
+
+For *Qt Charts* and *Qt Data Visualization*, the additional namespaces have been
+removed. It is now possible to use:
+
+.. code-block:: python
+
+ from PySide6.QtCharts import QChartView
+
+directly.
+
+
+Class/Function Deprecations
+---------------------------
+
+Then, the code base needs to be checked for usage of deprecated API and adapted
+accordingly. For example:
+
+* The High DPI scaling attributes ``Qt.AA_EnableHighDpiScaling``,
+ ``Qt.AA_DisableHighDpiScaling`` and ``Qt.AA_UseHighDpiPixmaps`` are
+ deprecated. High DPI is by default enabled in Qt 6 and cannot be turned off.
+* ``QDesktopWidget`` has been removed. ``QScreen`` should be used instead,
+ which can be retrieved using ``QWidget.screen()``,
+ ``QGuiApplication.primaryScreen()`` or ``QGuiApplication.screens()``.
+* ``QFontMetrics.width()`` has been renamed to ``horizontalAdvance()``.
+* ``QMouseEvent.pos()`` and ``QMouseEvent.globalPos()`` returning a ``QPoint``
+ as well as ``QMouseEvent.x()`` and ``QMouseEvent.y()`` returning ``int``
+ are now deprecated. ``QMouseEvent.position()`` and
+ ``QMouseEvent.globalPosition()`` returning a ``QPointF`` should be used
+ instead.
+* ``Qt.MidButton`` has been renamed to ``Qt.MiddleButton``.
+* ``QOpenGLVersionFunctionsFactory.get()`` instead of
+ ``QOpenGLContext.versionFunctions()`` should be used to obtain
+ *Open GL* functions.
+* ``QRegExp`` has been replaced by ``QRegularExpression``.
+* ``QWidget.mapToGlobal()`` and ``QWidget.mapFromGlobal()`` now also accept
+ and return ``QPointF``.
+* Functions named ``exec_`` (classes ``QCoreApplication``, ``QDialog``,
+ ``QEventLoop``) have been renamed to ``exec`` which became possible
+ in Python 3.
+
+More information can be found in the
+`Porting to Qt 6 <https://doc.qt.io/qt-6/portingguide.html>`_ Guide
+and the `Qt 6.2 Documentation <https://doc.qt.io/qt-6/index.html>`_ .
diff --git a/sources/pyside6/doc/gettingstarted/windows.rst b/sources/pyside6/doc/gettingstarted/windows.rst
new file mode 100644
index 000000000..4451bb1fd
--- /dev/null
+++ b/sources/pyside6/doc/gettingstarted/windows.rst
@@ -0,0 +1,114 @@
+Getting Started on Windows
+==========================
+
+The Qt library has to be built with the same version of MSVC as Python and PySide, this can be
+selected when using the online installer.
+
+Requirements
+------------
+
+* `MSVC2022`_ for Python 3 on Windows,
+* `OpenSSL`_ (optional for SSL support, Qt must have been configured using the same SSL library).
+* ``sphinx`` package for the documentation (optional).
+* Check the platform dependencies of `Qt for Windows`_.
+
+.. note:: The Python provided by the Microsoft Store is not compatible with PySide. Please
+ use https://www.python.org/downloads/ to get a Python Interpreter.
+
+.. _MSVC2022: https://visualstudio.microsoft.com/downloads/
+.. _OpenSSL: https://sourceforge.net/projects/openssl/
+.. _`Qt for Windows`: https://doc.qt.io/qt-6/windows.html
+
+Building from source on Windows 10
+----------------------------------
+
+Creating a virtual environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``venv`` module allows you to create a local, user-writeable copy of a python environment into
+which arbitrary modules can be installed and which can be removed after use::
+
+ python -m venv testenv
+ call testenv\Scripts\activate
+
+will create and use a new virtual environment, which is indicated by the command prompt changing.
+
+Setting up CLANG
+~~~~~~~~~~~~~~~~
+
+libclang can be downloaded from the
+`Qt servers <https://download.qt.io/development_releases/prebuilt/libclang>`_.
+for example, ``libclang-release_18.1.5-based-windows-vs2019_64.7z``.
+
+Note that from version 12 onwards, the prebuilt Windows binaries from
+`LLVM <https://www.llvm.org>`_ no longer contain CMake configuration files; so
+they can no longer be used.
+
+Extract the files, and leave it on any desired path, for example, ``c:``,
+and set the environment variable required::
+
+ set LLVM_INSTALL_DIR=c:\libclang
+ set PATH=C:\libclang\bin;%PATH%
+
+Getting PySide
+~~~~~~~~~~~~~~
+
+Cloning the official repository can be done by::
+
+ git clone https://code.qt.io/pyside/pyside-setup
+
+Checking out the version that we want to build, for example, 6.8::
+
+ cd pyside-setup && git checkout 6.8
+
+Install the general dependencies::
+
+ pip install -r requirements.txt
+
+For building the documentation::
+
+ pip install -r requirements-doc.txt
+
+.. note:: Keep in mind you need to use the same version as your Qt installation
+
+Building PySide
+~~~~~~~~~~~~~~~
+
+Check your Qt installation path, to specifically use that version of qtpaths to build PySide.
+for example, ``C:\Qt\6.8.0\msvc2019_64\bin\qtpaths.exe``.
+
+Build can take a few minutes, so it is recommended to use more than one CPU core::
+
+ python setup.py build --qtpaths=c:\path\to\qtpaths.exe --openssl=c:\path\to\openssl\bin --build-tests --ignore-git --parallel=8
+
+.. _creating_windows_debug_builds:
+
+Creating Debug Builds
+~~~~~~~~~~~~~~~~~~~~~
+
+* Choose *Custom Installation* when installing Python and tick the options for
+ debug binaries and libraries
+
+* Use ``venv`` to create a virtual environment and pass the debug binary::
+
+ python_d.exe -m venv testenv_d
+
+* Use ``python_d.exe`` to invoke ``setup.py``
+
+.. note:: Make sure you add the ``--debug`` option to the ``python setup.py install`` to produce a debug build
+
+
+Installing PySide
+~~~~~~~~~~~~~~~~~
+
+To install on the current directory, just run::
+
+ python setup.py install --qtpaths=c:\path\to\qtpaths.exe --openssl=c:\path\to\openssl\bin --build-tests --ignore-git --parallel=8
+
+Test installation
+~~~~~~~~~~~~~~~~~
+
+You can execute one of the examples to verify the process is properly working.
+Remember to properly set the environment variables for Qt and PySide::
+
+ python examples/widgets/widgets/tetrix.py
diff --git a/sources/pyside6/doc/images/Commercial.svg b/sources/pyside6/doc/images/Commercial.svg
new file mode 100644
index 000000000..f37cce629
--- /dev/null
+++ b/sources/pyside6/doc/images/Commercial.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 26.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 75 75" style="enable-background:new 0 0 75 75;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:url(#handshake_00000120533523703459691090000008987813838278108073_);}
+</style>
+<g id="Icons">
+ <g id="Icon_Partner_75">
+ <g id="Icons_00000013163458512384628070000011202706081841226428_">
+ <g id="Icon_Partner_75_00000024708088633722110760000017651124705385698191_">
+
+ <linearGradient id="handshake_00000144337817784615937160000016289583607924598409_" gradientUnits="userSpaceOnUse" x1="-263.8588" y1="427.9277" x2="-265.086" y2="429.2586" gradientTransform="matrix(75 -2.450961e-05 -2.450747e-05 -74.9934 19864.2129 32166.1777)">
+ <stop offset="0" style="stop-color:#6FFE80"/>
+ <stop offset="0.3726" style="stop-color:#43CE58"/>
+ <stop offset="1" style="stop-color:#425FCF"/>
+ </linearGradient>
+
+ <path id="handshake" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#handshake_00000144337817784615937160000016289583607924598409_);" d="
+ M59.3,50c1.9,1.9,1.9,5.1,0,7.1c-0.6,0.6-1.4,1.1-2.2,1.3l0.5,0.5c1.9,1.9,1.9,5.1,0,7.1c-1.5,1.5-3.8,1.9-5.7,1
+ c-0.2,1-0.7,1.9-1.4,2.6c-1.5,1.5-3.9,1.9-5.7,1c-0.2,1-0.7,1.9-1.4,2.6c-1,1-2.3,1.5-3.5,1.5c-1.3,0-2.6-0.5-3.5-1.5L15,51.7
+ c-3.8-3.8-4.6-8.5-5.3-12.3c-0.5-2.7-0.9-5.1-2.2-6.5c-0.5-0.5-0.5-1.3,0-1.8c0.5-0.5,1.3-0.5,1.8,0c1.9,1.9,2.4,4.8,2.9,7.8
+ c0.6,3.6,1.3,7.7,4.6,10.9L38,71.2c1,1,2.6,1,3.5,0c0.5-0.5,0.7-1.1,0.7-1.8c0-0.7-0.3-1.3-0.7-1.8L30.1,56.2
+ c-0.5-0.5-0.5-1.3,0-1.8c0.5-0.5,1.3-0.5,1.8,0l11.5,11.5h0l1.8,1.8c0.9,0.9,2.6,0.9,3.5,0c1-1,1-2.6,0-3.5L34.5,50
+ c-0.5-0.5-0.5-1.3,0-1.8c0.5-0.5,1.3-0.5,1.8,0l15.9,15.9c1,1,2.6,1,3.5,0c1-1,1-2.6,0-3.5L38.9,43.8c-0.5-0.5-0.5-1.3,0-1.8
+ c0.5-0.5,1.3-0.5,1.8,0L54,55.3c1,1,2.6,1,3.5,0c1-1,1-2.6,0-3.5L44.2,38.5c-0.5-0.5-0.5-1.3,0-1.8c0.5-0.5,1.3-0.5,1.8,0
+ L59.3,50L59.3,50z M66.3,26.2c-2,2-2.7,5.3-3.4,8.5c-0.6,2.8-1.2,5.8-2.7,7.3l-1.8,1.8c-0.5,0.5-0.5,1.3,0,1.8
+ c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4l1.8-1.8c2-2,2.7-5.3,3.4-8.5c0.6-2.8,1.2-5.8,2.7-7.3c0.5-0.5,0.5-1.3,0-1.8
+ S66.8,25.7,66.3,26.2L66.3,26.2z M19.6,34.1c0,0.7,0.3,1.3,0.7,1.8l0.9,0.9c1.2,1.2,2.7,1.8,4.4,1.8s3.2-0.6,4.4-1.8l6.2-6.2
+ c2.5,2.1,5.5,3.2,8.8,3.2h0c3.7,0,7.1-1.4,9.7-4c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0c-2.1,2.1-5,3.3-8,3.3h0
+ c-3,0-5.8-1.2-8-3.3c-0.5-0.5-1.3-0.5-1.8,0L28.3,35c-1.4,1.4-3.9,1.4-5.3,0l-0.9-0.9l15-15c1.4-1.4,2.7-1.4,4.4-1.4
+ c1.8,0,4.1,0,6.2-2.1l3.5-3.5c0.5-0.5,0.5-1.3,0-1.8c-0.5-0.5-1.3-0.5-1.8,0L46,13.7c-1.4,1.4-2.7,1.4-4.4,1.4
+ c-1.8,0-4.1,0-6.2,2.1l-15,15C19.9,32.8,19.6,33.4,19.6,34.1L19.6,34.1z M23,17.3l3.5,3.5c0.2,0.2,0.6,0.4,0.9,0.4
+ c0.3,0,0.6-0.1,0.9-0.4c0.5-0.5,0.5-1.3,0-1.8l-3.5-3.5c-0.5-0.5-1.3-0.5-1.8,0C22.5,16,22.5,16.8,23,17.3L23,17.3z M21.6,11.4
+ l-7.5-7.5c-0.5-0.5-1.3-0.5-1.8,0s-0.5,1.3,0,1.8l6.6,6.6L2.1,29.1c-0.5,0.5-0.5,1.3,0,1.8c0.2,0.2,0.6,0.4,0.9,0.4
+ s0.6-0.1,0.9-0.4l17.7-17.7C22.1,12.6,22.1,11.9,21.6,11.4L21.6,11.4z M72.9,24.8L55.3,7.3l4.1-4.1c0.5-0.5,0.5-1.3,0-1.8
+ s-1.3-0.5-1.8,0l-5,5c-0.5,0.5-0.5,1.3,0,1.8l18.4,18.4c0.2,0.2,0.6,0.4,0.9,0.4c0.3,0,0.6-0.1,0.9-0.4
+ C73.4,26.1,73.4,25.3,72.9,24.8L72.9,24.8z M30.4,71.9c-0.7,0.4-1.9,0.4-3-0.7c-1.1-1.1-1.1-2.3-0.7-2.9
+ c0.3-0.5,0.2-1.2-0.3-1.6c-0.5-0.4-1.2-0.4-1.7,0.1c-1,1-2.6,1-3.5,0c-1-1-1-2.6,0-3.5c0.2-0.2,0.4-0.6,0.4-0.9
+ s-0.1-0.6-0.4-0.9c-0.5-0.5-1.3-0.5-1.8,0l-0.9,0.9c-1,1-2.6,1-3.5,0c-1-1-1-2.6,0-3.5l0.9-0.9c0.4-0.4,0.5-1.1,0.1-1.6
+ c-0.4-0.5-1.1-0.6-1.6-0.3c-0.7,0.4-1.9,0.3-2.9-0.7c-1.1-1.1-1.1-2.3-0.7-2.8c0.4-0.6,0.2-1.3-0.3-1.7
+ c-0.6-0.4-1.3-0.2-1.7,0.3c-1,1.5-1,4,1,6c0.8,0.8,1.7,1.3,2.5,1.5c-0.3,0.6-0.4,1.3-0.4,2c0,1.3,0.5,2.6,1.5,3.5
+ c1.3,1.3,3.1,1.7,4.7,1.3c0.1,1.1,0.6,2.2,1.4,3.1c1.2,1.2,3,1.7,4.6,1.4c0.2,1,0.7,2.1,1.6,3.1c1.2,1.2,2.5,1.6,3.7,1.6
+ c0.8,0,1.5-0.2,2.1-0.5c0.6-0.3,0.8-1.1,0.5-1.7C31.8,71.8,31,71.5,30.4,71.9L30.4,71.9z"/>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/sources/pyside6/doc/images/Deployment.svg b/sources/pyside6/doc/images/Deployment.svg
new file mode 100644
index 000000000..cd5a63d2a
--- /dev/null
+++ b/sources/pyside6/doc/images/Deployment.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="38px" height="38px" viewBox="0 0 38 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>robot</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-832.000000, -3701.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="Deliver" transform="translate(62.000000, 1032.000000)">
+ <g id="Product" transform="translate(776.000000, 967.000000)">
+ <g id="Auto" transform="translate(37.420728, 172.000000)">
+ <path d="M32.973961,22.1666667 L32.973961,27.2333333 C32.973961,28.9794333 31.5766823,30.4 29.8592069,30.4 L8.67887904,30.4 C6.96140363,30.4 5.56412494,28.9794333 5.56412494,27.2333333 L5.56412494,22.1666667 C5.56412494,21.8170667 5.84258395,21.5333333 6.18707576,21.5333333 C6.53156756,21.5333333 6.81002658,21.8170667 6.81002658,22.1666667 L6.81002658,27.2333333 C6.81002658,28.2808667 7.64851838,29.1333333 8.67887904,29.1333333 L29.8592069,29.1333333 C30.8895676,29.1333333 31.7280594,28.2808667 31.7280594,27.2333333 L31.7280594,22.1666667 C31.7280594,21.8170667 32.0065184,21.5333333 32.3510102,21.5333333 C32.695502,21.5333333 32.973961,21.8170667 32.973961,22.1666667 L32.973961,22.1666667 Z M37.9575676,19.6333333 C37.9575676,20.6808667 37.1190758,21.5333333 36.0887151,21.5333333 C35.2776331,21.5333333 34.5930102,21.0026 34.3351085,20.2666667 L32.3510102,20.2666667 C32.0065184,20.2666667 31.7280594,19.9829333 31.7280594,19.6333333 L31.7280594,13.3 C31.7280594,12.2524667 30.8895676,11.4 29.8592069,11.4 L16.1542889,11.4 C15.8097971,11.4 15.5313381,11.1162667 15.5313381,10.7666667 C15.5313381,10.4170667 15.8097971,10.1333333 16.1542889,10.1333333 L29.8592069,10.1333333 C31.5766823,10.1333333 32.973961,11.5539 32.973961,13.3 L32.973961,19 L34.3351085,19 C34.5930102,18.2640667 35.2776331,17.7333333 36.0887151,17.7333333 C37.1190758,17.7333333 37.9575676,18.5858 37.9575676,19.6333333 L37.9575676,19.6333333 Z M36.7116659,19.6333333 C36.7116659,19.2843667 36.432584,19 36.0887151,19 C35.7448462,19 35.4657643,19.2843667 35.4657643,19.6333333 C35.4657643,19.9823 35.7448462,20.2666667 36.0887151,20.2666667 C36.432584,20.2666667 36.7116659,19.9823 36.7116659,19.6333333 L36.7116659,19.6333333 Z M12.416584,19 C11.3862233,19 10.5477315,18.1475333 10.5477315,17.1 C10.5477315,16.0524667 11.3862233,15.2 12.416584,15.2 C13.4469446,15.2 14.2854364,16.0524667 14.2854364,17.1 C14.2854364,18.1475333 13.4469446,19 12.416584,19 L12.416584,19 Z M13.0395348,17.1 C13.0395348,16.7510333 12.7604528,16.4666667 12.416584,16.4666667 C12.0727151,16.4666667 11.7936331,16.7510333 11.7936331,17.1 C11.7936331,17.4489667 12.0727151,17.7333333 12.416584,17.7333333 C12.7604528,17.7333333 13.0395348,17.4489667 13.0395348,17.1 L13.0395348,17.1 Z M26.121502,19 C25.0911413,19 24.2526495,18.1475333 24.2526495,17.1 C24.2526495,16.0524667 25.0911413,15.2 26.121502,15.2 C27.1518626,15.2 27.9903544,16.0524667 27.9903544,17.1 C27.9903544,18.1475333 27.1518626,19 26.121502,19 L26.121502,19 Z M26.121502,17.7333333 C26.4653708,17.7333333 26.7444528,17.4489667 26.7444528,17.1 C26.7444528,16.7510333 26.4653708,16.4666667 26.121502,16.4666667 C25.7776331,16.4666667 25.4985512,16.7510333 25.4985512,17.1 C25.4985512,17.4489667 25.7776331,17.7333333 26.121502,17.7333333 L26.121502,17.7333333 Z M24.8756003,31.6666667 L13.6624856,31.6666667 C13.3179938,31.6666667 13.0395348,31.9504 13.0395348,32.3 C13.0395348,32.6496 13.3179938,32.9333333 13.6624856,32.9333333 L24.8756003,32.9333333 C25.2200921,32.9333333 25.4985512,32.6496 25.4985512,32.3 C25.4985512,31.9504 25.2200921,31.6666667 24.8756003,31.6666667 L24.8756003,31.6666667 Z M23.6296987,34.2 L14.9083872,34.2 C14.5638954,34.2 14.2854364,34.4837333 14.2854364,34.8333333 C14.2854364,35.1829333 14.5638954,35.4666667 14.9083872,35.4666667 L23.6296987,35.4666667 C23.9741905,35.4666667 24.2526495,35.1829333 24.2526495,34.8333333 C24.2526495,34.4837333 23.9741905,34.2 23.6296987,34.2 L23.6296987,34.2 Z M23.6296987,36.7333333 L14.9083872,36.7333333 C14.5638954,36.7333333 14.2854364,37.0170667 14.2854364,37.3666667 C14.2854364,37.7162667 14.5638954,38 14.9083872,38 L23.6296987,38 C23.9741905,38 24.2526495,37.7162667 24.2526495,37.3666667 C24.2526495,37.0170667 23.9741905,36.7333333 23.6296987,36.7333333 L23.6296987,36.7333333 Z M24.8756003,22.8 C25.2200921,22.8 25.4985512,23.0837333 25.4985512,23.4333333 L25.4985512,25.9666667 C25.4985512,26.3162667 25.2200921,26.6 24.8756003,26.6 L13.6624856,26.6 C13.3179938,26.6 13.0395348,26.3162667 13.0395348,25.9666667 L13.0395348,23.4333333 C13.0395348,23.0837333 13.3179938,22.8 13.6624856,22.8 L24.8756003,22.8 L24.8756003,22.8 Z M18.0231413,25.3333333 L20.5149446,25.3333333 L20.5149446,24.0666667 L18.0231413,24.0666667 L18.0231413,25.3333333 Z M14.2854364,25.3333333 L16.7772397,25.3333333 L16.7772397,24.0666667 L14.2854364,24.0666667 L14.2854364,25.3333333 Z M21.7608462,25.3333333 L24.2526495,25.3333333 L24.2526495,24.0666667 L21.7608462,24.0666667 L21.7608462,25.3333333 Z M4.20235444,20.2666667 C3.94382985,21.0026 3.2592069,21.5333333 2.44812494,21.5333333 C1.41776428,21.5333333 0.579272478,20.6808667 0.579272478,19.6333333 C0.579272478,18.5858 1.41776428,17.7333333 2.44812494,17.7333333 C3.2592069,17.7333333 3.94382985,18.2640667 4.20235444,19 L5.56287904,19 L5.56412494,13.3 C5.56412494,11.5539 6.96140363,10.1333333 8.67887904,10.1333333 L13.0812725,10.1333333 C13.442584,7.41443333 16.0789118,5.39473333 18.6460921,5.10593333 L18.6460921,3.68283333 C17.9228462,3.42063333 17.4001905,2.7246 17.4001905,1.9 C17.4001905,0.852466667 18.2386823,0 19.269043,0 C20.2994036,0 21.1378954,0.852466667 21.1378954,1.9 C21.1378954,2.7246 20.6152397,3.42063333 19.8919938,3.68346667 L19.8919938,5.10783333 C21.7222233,5.3048 23.5057315,6.34093333 24.5610102,7.87106667 C24.7591085,8.15733333 24.690584,8.5519 24.4090102,8.7533 C24.1268135,8.95406667 23.7387151,8.88376667 23.5412397,8.59813333 C22.6061905,7.24343333 20.889961,6.33333333 19.269043,6.33333333 C16.9647479,6.33333333 14.2854364,8.27006667 14.2854364,10.7666667 C14.2854364,11.1162667 14.0069774,11.4 13.6624856,11.4 L8.67887904,11.4 C7.64851838,11.4 6.81002658,12.2524667 6.81002658,13.3 L6.81002658,19.6333333 C6.81002658,19.9829333 6.53156756,20.2666667 6.18707576,20.2666667 L4.20235444,20.2666667 L4.20235444,20.2666667 Z M18.6460921,1.9 C18.6460921,2.24896667 18.9251741,2.53333333 19.269043,2.53333333 C19.6129118,2.53333333 19.8919938,2.24896667 19.8919938,1.9 C19.8919938,1.55103333 19.6129118,1.26666667 19.269043,1.26666667 C18.9251741,1.26666667 18.6460921,1.55103333 18.6460921,1.9 L18.6460921,1.9 Z M3.07107576,19.6333333 C3.07107576,19.2843667 2.79199379,19 2.44812494,19 C2.10425608,19 1.82517412,19.2843667 1.82517412,19.6333333 C1.82517412,19.9823 2.10425608,20.2666667 2.44812494,20.2666667 C2.79199379,20.2666667 3.07107576,19.9823 3.07107576,19.6333333 L3.07107576,19.6333333 Z" id="robot"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/Desktop.svg b/sources/pyside6/doc/images/Desktop.svg
new file mode 100644
index 000000000..408786a61
--- /dev/null
+++ b/sources/pyside6/doc/images/Desktop.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="38px" height="38px" viewBox="0 0 38 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>imac copy</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-150.000000, -3059.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="Deliver" transform="translate(62.000000, 1032.000000)">
+ <g id="Solution" transform="translate(0.907344, 0.000000)">
+ <g id="Auto" transform="translate(130.982155, 497.000000)">
+ <path d="M38.110501,3.16666667 L38.110501,25.9666667 C38.110501,27.5943333 36.571501,29.1333333 34.9438344,29.1333333 L3.2771677,29.1333333 C1.64950103,29.1333333 0.11050103,27.5943333 0.11050103,25.9666667 L0.11050103,22.1666667 C0.11050103,21.8170667 0.394234363,21.5333333 0.743834363,21.5333333 L34.9438344,21.5333333 C35.2934344,21.5333333 35.5771677,21.8170667 35.5771677,22.1666667 C35.5771677,22.5162667 35.2934344,22.8 34.9438344,22.8 L1.3771677,22.8 L1.3771677,25.9666667 C1.3771677,26.8900667 2.3537677,27.8666667 3.2771677,27.8666667 L34.9438344,27.8666667 C35.8672344,27.8666667 36.8438344,26.8900667 36.8438344,25.9666667 L36.8438344,3.16666667 C36.8438344,2.24326667 35.8672344,1.26666667 34.9438344,1.26666667 L3.2771677,1.26666667 C2.3537677,1.26666667 1.3771677,2.24326667 1.3771677,3.16666667 L1.3771677,19.6333333 C1.3771677,19.9829333 1.09343436,20.2666667 0.743834363,20.2666667 C0.394234363,20.2666667 0.11050103,19.9829333 0.11050103,19.6333333 L0.11050103,3.16666667 C0.11050103,1.539 1.64950103,0 3.2771677,0 L34.9438344,0 C36.571501,0 38.110501,1.539 38.110501,3.16666667 L38.110501,3.16666667 Z M17.8438344,25.3333333 C17.8438344,26.0319 18.4119344,26.6 19.110501,26.6 C19.8090677,26.6 20.3771677,26.0319 20.3771677,25.3333333 C20.3771677,24.6347667 19.8090677,24.0666667 19.110501,24.0666667 C18.4119344,24.0666667 17.8438344,24.6347667 17.8438344,25.3333333 L17.8438344,25.3333333 Z M16.5961677,19.6333333 C16.5961677,19.2837333 16.3130677,19 15.9628344,19 L15.956501,19 C15.606901,19 15.3263344,19.2837333 15.3263344,19.6333333 C15.3263344,19.9829333 15.6132344,20.2666667 15.9628344,20.2666667 C16.3130677,20.2666667 16.5961677,19.9829333 16.5961677,19.6333333 L16.5961677,19.6333333 Z M19.129501,19.6333333 C19.129501,19.2837333 18.846401,19 18.4961677,19 L18.4898344,19 C18.1402344,19 17.8596677,19.2837333 17.8596677,19.6333333 C17.8596677,19.9829333 18.1465677,20.2666667 18.4961677,20.2666667 C18.846401,20.2666667 19.129501,19.9829333 19.129501,19.6333333 L19.129501,19.6333333 Z M21.6628344,19.6333333 C21.6628344,19.2837333 21.3797344,19 21.029501,19 L21.0231677,19 C20.6735677,19 20.393001,19.2837333 20.393001,19.6333333 C20.393001,19.9829333 20.679901,20.2666667 21.029501,20.2666667 C21.3797344,20.2666667 21.6628344,19.9829333 21.6628344,19.6333333 L21.6628344,19.6333333 Z M14.0628344,19.6333333 C14.0628344,19.2837333 13.7797344,19 13.429501,19 L13.4231677,19 C13.0735677,19 12.793001,19.2837333 12.793001,19.6333333 C12.793001,19.9829333 13.079901,20.2666667 13.429501,20.2666667 C13.7797344,20.2666667 14.0628344,19.9829333 14.0628344,19.6333333 L14.0628344,19.6333333 Z M11.529501,19.6333333 C11.529501,19.2837333 11.246401,19 10.8961677,19 L10.8898344,19 C10.5402344,19 10.2596677,19.2837333 10.2596677,19.6333333 C10.2596677,19.9829333 10.5465677,20.2666667 10.8961677,20.2666667 C11.246401,20.2666667 11.529501,19.9829333 11.529501,19.6333333 L11.529501,19.6333333 Z M27.9961677,19.6333333 C27.9961677,19.2837333 27.7130677,19 27.3628344,19 L27.356501,19 C27.006901,19 26.7263344,19.2837333 26.7263344,19.6333333 C26.7263344,19.9829333 27.0132344,20.2666667 27.3628344,20.2666667 C27.7130677,20.2666667 27.9961677,19.9829333 27.9961677,19.6333333 L27.9961677,19.6333333 Z M25.4628344,19.6333333 C25.4628344,19.2837333 25.1797344,19 24.829501,19 L24.8231677,19 C24.4735677,19 24.193001,19.2837333 24.193001,19.6333333 C24.193001,19.9829333 24.479901,20.2666667 24.829501,20.2666667 C25.1797344,20.2666667 25.4628344,19.9829333 25.4628344,19.6333333 L25.4628344,19.6333333 Z M26.0771677,36.7333333 L25.4438344,36.7333333 L25.4438344,36.1 C25.4438344,35.7504 25.160101,35.4666667 24.810501,35.4666667 C24.460901,35.4666667 24.1771677,35.7504 24.1771677,36.1 L24.1771677,36.7333333 L22.910501,36.7333333 L22.910501,36.1 C22.910501,35.7504 22.6267677,35.4666667 22.2771677,35.4666667 C21.9275677,35.4666667 21.6438344,35.7504 21.6438344,36.1 L21.6438344,36.7333333 L20.3771677,36.7333333 L20.3771677,36.1 C20.3771677,35.7504 20.0934344,35.4666667 19.7438344,35.4666667 C19.3942344,35.4666667 19.110501,35.7504 19.110501,36.1 L19.110501,36.7333333 L17.8438344,36.7333333 L17.8438344,36.1 C17.8438344,35.7504 17.560101,35.4666667 17.210501,35.4666667 C16.860901,35.4666667 16.5771677,35.7504 16.5771677,36.1 L16.5771677,36.7333333 L15.310501,36.7333333 L15.310501,36.1 C15.310501,35.7504 15.0267677,35.4666667 14.6771677,35.4666667 C14.3275677,35.4666667 14.0438344,35.7504 14.0438344,36.1 L14.0438344,36.7333333 L12.7771677,36.7333333 L12.7771677,36.1 C12.7771677,35.7504 12.4934344,35.4666667 12.1438344,35.4666667 C11.7942344,35.4666667 11.510501,35.7504 11.510501,36.1 L11.510501,36.7333333 L10.2438344,36.7333333 L10.2438344,36.1 C10.2438344,35.7504 9.96010103,35.4666667 9.61050103,35.4666667 C9.26090103,35.4666667 8.9771677,35.7504 8.9771677,36.1 L8.9771677,36.7333333 L7.71050103,36.7333333 L7.71050103,36.1 C7.71050103,35.7504 7.4267677,35.4666667 7.0771677,35.4666667 C6.7275677,35.4666667 6.44383436,35.7504 6.44383436,36.1 L6.44383436,36.7333333 L5.1771677,36.7333333 L5.1771677,36.1 C5.1771677,35.7504 4.89343436,35.4666667 4.54383436,35.4666667 C4.19423436,35.4666667 3.91050103,35.7504 3.91050103,36.1 L3.91050103,36.7333333 L3.2771677,36.7333333 C2.9275677,36.7333333 2.64383436,37.0170667 2.64383436,37.3666667 C2.64383436,37.7162667 2.9275677,38 3.2771677,38 L26.0771677,38 C26.4267677,38 26.710501,37.7162667 26.710501,37.3666667 C26.710501,37.0170667 26.4267677,36.7333333 26.0771677,36.7333333 L26.0771677,36.7333333 Z M16.5771677,33.5666667 L16.5771677,31.0333333 C16.5771677,30.6837333 16.2934344,30.4 15.9438344,30.4 C15.5942344,30.4 15.310501,30.6837333 15.310501,31.0333333 L15.310501,33.5666667 C15.310501,33.9162667 15.5942344,34.2 15.9438344,34.2 C16.2934344,34.2 16.5771677,33.9162667 16.5771677,33.5666667 L16.5771677,33.5666667 Z M22.2771677,34.2 C22.6267677,34.2 22.910501,33.9162667 22.910501,33.5666667 L22.910501,31.0333333 C22.910501,30.6837333 22.6267677,30.4 22.2771677,30.4 C21.9275677,30.4 21.6438344,30.6837333 21.6438344,31.0333333 L21.6438344,33.5666667 C21.6438344,33.9162667 21.9275677,34.2 22.2771677,34.2 L22.2771677,34.2 Z M35.5771677,36.7333333 L35.5771677,37.3666667 C35.5771677,37.7162667 35.2934344,38 34.9438344,38 L29.8771677,38 C29.5275677,38 29.2438344,37.7162667 29.2438344,37.3666667 L29.2438344,36.7333333 C29.2438344,35.3362 30.3800344,34.2 31.7771677,34.2 L33.0438344,34.2 C34.4409677,34.2 35.5771677,35.3362 35.5771677,36.7333333 L35.5771677,36.7333333 Z M34.310501,36.7333333 C34.310501,36.0347667 33.742401,35.4666667 33.0438344,35.4666667 L31.7771677,35.4666667 C31.078601,35.4666667 30.510501,36.0347667 30.510501,36.7333333 L34.310501,36.7333333 L34.310501,36.7333333 Z" id="imac-copy"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/Dev.svg b/sources/pyside6/doc/images/Dev.svg
new file mode 100644
index 000000000..53e332718
--- /dev/null
+++ b/sources/pyside6/doc/images/Dev.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="37px" height="37px" viewBox="0 0 37 37" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>book-write</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-266.000000, -5715.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="Support" transform="translate(277.000000, 4042.000000)">
+ <g id="1" transform="translate(0.774880, 117.000000)">
+ <path d="M65.2327264,56.0069148 C65.5646029,56.0069148 65.8328647,55.7380528 65.8328647,55.4067765 L65.8328647,33.8017978 C65.8328647,33.4705215 65.5646029,33.2016596 65.2327264,33.2016596 C64.9008499,33.2016596 64.6325881,33.4705215 64.6325881,33.8017978 L64.6325881,55.4067765 C64.6325881,55.7380528 64.9008499,56.0069148 65.2327264,56.0069148 L65.2327264,56.0069148 Z M67.0331413,59.0076063 L67.0331413,58.407468 L65.2327264,58.407468 C64.9008499,58.407468 64.6325881,58.138606 64.6325881,57.8073297 C64.6325881,57.4760533 64.9008499,57.2071914 65.2327264,57.2071914 L67.0331413,57.2071914 L67.0331413,32.001383 L65.2327264,32.001383 C64.9008499,32.001383 64.6325881,31.732521 64.6325881,31.4012447 C64.6325881,31.0699683 64.9008499,30.8011064 65.2327264,30.8011064 L66.6622558,30.8011064 L65.2327264,27.9420475 L63.4323115,31.5428773 L63.4323115,59.0076063 C63.4323115,60.000235 64.2400976,60.8080212 65.2327264,60.8080212 C66.2253551,60.8080212 67.0331413,60.000235 67.0331413,59.0076063 L67.0331413,59.0076063 Z M68.2454206,31.4012447 C68.2454206,31.4420541 68.2412197,31.4822633 68.2334179,31.5212723 L68.2334179,59.0076063 C68.2334179,60.6621876 66.8873077,62.0082978 65.2327264,62.0082978 C63.5781451,62.0082978 62.2320349,60.6621876 62.2320349,59.0076063 L62.2320349,31.4012447 C62.2320349,31.3082232 62.2536399,31.2158019 62.2950494,31.1329828 L64.6956026,26.3318765 C64.8996496,25.9249827 65.5658031,25.9249827 65.7698502,26.3318765 L68.1217921,31.0363606 C68.19921,31.137784 68.2454206,31.263813 68.2454206,31.4012447 L68.2454206,31.4012447 Z M50.8294073,44.0041489 L44.8280243,44.0041489 C44.4961478,44.0041489 44.227886,44.2730108 44.227886,44.6042872 C44.227886,44.9355635 44.4961478,45.2044255 44.8280243,45.2044255 L50.8294073,45.2044255 C51.1612838,45.2044255 51.4295456,44.9355635 51.4295456,44.6042872 C51.4295456,44.2730108 51.1612838,44.0041489 50.8294073,44.0041489 L50.8294073,44.0041489 Z M44.8280243,42.8038723 L48.4288541,42.8038723 C48.7607306,42.8038723 49.0289924,42.5350103 49.0289924,42.203734 C49.0289924,41.8724577 48.7607306,41.6035957 48.4288541,41.6035957 L44.8280243,41.6035957 C44.4961478,41.6035957 44.227886,41.8724577 44.227886,42.203734 C44.227886,42.5350103 44.4961478,42.8038723 44.8280243,42.8038723 L44.8280243,42.8038723 Z M41.8273328,47.6049787 L53.8300988,47.6049787 L53.8300988,39.2030425 L41.8273328,39.2030425 L41.8273328,47.6049787 Z M40.6270563,48.205117 L40.6270563,38.6029042 C40.6270563,38.2716279 40.8953181,38.0027659 41.2271946,38.0027659 L54.4302371,38.0027659 C54.7621135,38.0027659 55.0303754,38.2716279 55.0303754,38.6029042 L55.0303754,48.205117 C55.0303754,48.5363933 54.7621135,48.8052552 54.4302371,48.8052552 L41.2271946,48.8052552 C40.8953181,48.8052552 40.6270563,48.5363933 40.6270563,48.205117 L40.6270563,48.205117 Z M33.4253967,31.4534567 L33.4253967,59.0076063 C33.4253967,59.9666273 34.2667906,60.8080212 35.2258116,60.8080212 L58.0310668,60.8080212 C58.9900878,60.8080212 59.8314817,59.9666273 59.8314817,59.0076063 L59.8314817,32.001383 L35.2258116,32.001383 C34.7318978,32.001383 34.0273354,31.8591502 33.4253967,31.4534567 L33.4253967,31.4534567 Z M60.43162,27.2002766 L34.6256733,27.2002766 C33.9637208,27.2002766 33.4253967,27.7386006 33.4253967,28.4005532 L33.4253967,29.0006915 C33.4253967,30.6948819 34.928143,30.7975055 35.2294124,30.8011064 L60.43162,30.8011064 C60.7634965,30.8011064 61.0317583,31.0699683 61.0317583,31.4012447 L61.0317583,59.0076063 C61.0317583,60.6339811 59.6574416,62.0082978 58.0310668,62.0082978 L35.2258116,62.0082978 C33.5994368,62.0082978 32.2251201,60.6339811 32.2251201,59.0076063 L32.2251201,28.4005532 C32.2251201,27.0766481 33.3017682,26 34.6256733,26 L60.43162,26 C60.7634965,26 61.0317583,26.268862 61.0317583,26.6001383 C61.0317583,26.9314146 60.7634965,27.2002766 60.43162,27.2002766 L60.43162,27.2002766 Z M35.2258116,59.6077446 C35.5576881,59.6077446 35.8259499,59.3388826 35.8259499,59.0076063 L35.8259499,33.8017978 C35.8259499,33.4705215 35.5576881,33.2016596 35.2258116,33.2016596 C34.8939351,33.2016596 34.6256733,33.4705215 34.6256733,33.8017978 L34.6256733,59.0076063 C34.6256733,59.3388826 34.8939351,59.6077446 35.2258116,59.6077446 L35.2258116,59.6077446 Z M59.2313434,28.4005532 C59.5632199,28.4005532 59.8314817,28.6694151 59.8314817,29.0006915 C59.8314817,29.3319678 59.5632199,29.6008298 59.2313434,29.6008298 L35.2258116,29.6008298 C34.8939351,29.6008298 34.6256733,29.3319678 34.6256733,29.0006915 C34.6256733,28.6694151 34.8939351,28.4005532 35.2258116,28.4005532 L59.2313434,28.4005532 Z" id="book-write"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/Development.svg b/sources/pyside6/doc/images/Development.svg
new file mode 100644
index 000000000..2149ee8a0
--- /dev/null
+++ b/sources/pyside6/doc/images/Development.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="41px" height="38px" viewBox="0 0 41 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>globe-share</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-831.000000, -3529.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="Deliver" transform="translate(62.000000, 1032.000000)">
+ <g id="Product" transform="translate(776.000000, 967.000000)">
+ <g id="Auto" transform="translate(36.420728, 0.000000)">
+ <path d="M10.8786296,24.4285714 L14.7525939,24.4285714 C15.675451,27.47875 17.4736653,29.6847857 18.8301296,31.0052857 C15.2113082,30.29075 12.2371296,27.7725714 10.8786296,24.4285714 L10.8786296,24.4285714 Z M18.8301296,9.709 C17.4736653,11.0295 15.675451,13.2355357 14.7525939,16.2857143 L10.8786296,16.2857143 C12.2371296,12.9417143 15.2113082,10.4235357 18.8301296,9.709 L18.8301296,9.709 Z M30.994201,16.2857143 L27.1202368,16.2857143 C26.1973796,13.2355357 24.3984868,11.0295 23.0420225,9.709 C26.6615225,10.4235357 29.6350225,12.9417143 30.994201,16.2857143 L30.994201,16.2857143 Z M23.0420225,31.0052857 C24.3984868,29.6847857 26.1973796,27.47875 27.1202368,24.4285714 L30.994201,24.4285714 C29.635701,27.7725714 26.6615225,30.29075 23.0420225,31.0052857 L23.0420225,31.0052857 Z M20.2578439,24.4285714 L20.2578439,30.4678571 C19.076451,29.3991071 17.2063082,27.3471071 16.2006653,24.4285714 L20.2578439,24.4285714 Z M20.2578439,10.2464286 L20.2578439,16.2857143 L16.2006653,16.2857143 C17.2063082,13.3671786 19.076451,11.3151786 20.2578439,10.2464286 L20.2578439,10.2464286 Z M21.6149868,16.2857143 L21.6149868,10.2464286 C22.7963796,11.3151786 24.6665225,13.3671786 25.6714868,16.2857143 L21.6149868,16.2857143 Z M21.6149868,30.4678571 L21.6149868,24.4285714 L25.6714868,24.4285714 C24.6665225,27.3471071 22.7963796,29.3991071 21.6149868,30.4678571 L21.6149868,30.4678571 Z M26.3649868,20.3571429 C26.3649868,21.32275 26.2475939,22.2245714 26.058951,23.0714286 L21.6149868,23.0714286 L21.6149868,17.6428571 L26.058951,17.6428571 C26.2475939,18.4897143 26.3649868,19.3915357 26.3649868,20.3571429 L26.3649868,20.3571429 Z M31.7935582,20.3571429 C31.7935582,21.2956071 31.6605582,22.2021786 31.435951,23.0714286 L27.460201,23.0714286 C27.626451,22.2218571 27.7221296,21.3173214 27.7221296,20.3571429 C27.7221296,19.3969643 27.626451,18.4924286 27.460201,17.6428571 L31.435951,17.6428571 C31.6605582,18.5121071 31.7935582,19.4186786 31.7935582,20.3571429 L31.7935582,20.3571429 Z M15.5078439,20.3571429 C15.5078439,19.3915357 15.6252368,18.4897143 15.8138796,17.6428571 L20.2578439,17.6428571 L20.2578439,23.0714286 L15.8138796,23.0714286 C15.6252368,22.2245714 15.5078439,21.32275 15.5078439,20.3571429 L15.5078439,20.3571429 Z M10.0792725,20.3571429 C10.0792725,19.4186786 10.2115939,18.5121071 10.436201,17.6428571 L14.4126296,17.6428571 C14.245701,18.4924286 14.150701,19.3969643 14.150701,20.3571429 C14.150701,21.3173214 14.245701,22.2218571 14.4126296,23.0714286 L10.436201,23.0714286 C10.2115939,22.2021786 10.0792725,21.2956071 10.0792725,20.3571429 L10.0792725,20.3571429 Z M20.9377725,32.5714286 C26.3982368,32.57075 31.0308439,28.9682143 32.5895225,24.016 C32.590201,24.0139643 32.5908796,24.0126071 32.5915582,24.01125 C32.9539153,22.857 33.150701,21.6294643 33.150701,20.3571429 C33.150701,19.0848214 32.9539153,17.8572857 32.5915582,16.7030357 C32.5908796,16.7016786 32.590201,16.7003214 32.5895225,16.6982857 C31.0308439,11.7460714 26.3968796,8.14285714 20.9364153,8.14285714 C15.4752725,8.14285714 10.8413082,11.7460714 9.28262962,16.6989643 L9.28195105,16.7023571 C8.91891533,17.8566071 8.72212962,19.0841429 8.72212962,20.3571429 C8.72212962,21.6301429 8.91891533,22.8576786 9.28195105,24.0119286 L9.28262962,24.0153214 C10.8413082,28.9675357 15.4745939,32.57075 20.9343796,32.5714286 L20.9350582,32.5714286 L20.9357368,32.5714286 L20.9357368,32.5714286 L20.9364153,32.5714286 L20.9370939,32.5714286 L20.9377725,32.5714286 Z M31.7935582,36.6428571 C31.0450939,36.6428571 30.4364153,36.0341786 30.4364153,35.2857143 C30.4364153,34.53725 31.0450939,33.9285714 31.7935582,33.9285714 C32.5413439,33.9285714 33.150701,34.53725 33.150701,35.2857143 C33.150701,36.0341786 32.5413439,36.6428571 31.7935582,36.6428571 L31.7935582,36.6428571 Z M31.7935582,32.5714286 C31.4142368,32.5714286 31.0539153,32.6508214 30.7261653,32.7912857 L29.597701,31.4551786 C29.3561296,31.1688214 28.927951,31.1315 28.6415939,31.3744286 C28.3545582,31.616 28.3192725,32.0441786 28.5601653,32.3305357 L29.6574153,33.6306786 C29.3004868,34.0900714 29.0792725,34.6600714 29.0792725,35.2857143 C29.0792725,36.7826429 30.2966296,38 31.7935582,38 C33.2904868,38 34.5078439,36.7826429 34.5078439,35.2857143 C34.5078439,33.7887857 33.2904868,32.5714286 31.7935582,32.5714286 L31.7935582,32.5714286 Z M10.0792725,36.6428571 C9.33080819,36.6428571 8.72212962,36.0341786 8.72212962,35.2857143 C8.72212962,34.53725 9.33080819,33.9285714 10.0792725,33.9285714 C10.8277368,33.9285714 11.4364153,34.53725 11.4364153,35.2857143 C11.4364153,36.0341786 10.8277368,36.6428571 10.0792725,36.6428571 L10.0792725,36.6428571 Z M12.3022725,31.3846071 L11.096451,32.7729643 C10.7815939,32.6453929 10.4395939,32.5714286 10.0792725,32.5714286 C8.58234391,32.5714286 7.36498676,33.7887857 7.36498676,35.2857143 C7.36498676,36.7826429 8.58234391,38 10.0792725,38 C11.5755225,38 12.7935582,36.7826429 12.7935582,35.2857143 C12.7935582,34.64175 12.5587725,34.0575 12.1828439,33.592 L13.3269153,32.2742143 C13.5725582,31.99125 13.542701,31.5623929 13.2590582,31.31675 C12.9760939,31.0711071 12.5472368,31.1009643 12.3022725,31.3846071 L12.3022725,31.3846071 Z M38.5792725,16.2857143 C37.8308082,16.2857143 37.2221296,15.6770357 37.2221296,14.9285714 C37.2221296,14.1801071 37.8308082,13.5714286 38.5792725,13.5714286 C39.3270582,13.5714286 39.9364153,14.1801071 39.9364153,14.9285714 C39.9364153,15.6770357 39.3270582,16.2857143 38.5792725,16.2857143 L38.5792725,16.2857143 Z M38.5792725,12.2142857 C37.0823439,12.2142857 35.8649868,13.4316429 35.8649868,14.9285714 C35.8649868,15.0133929 35.881951,15.0941429 35.8900939,15.1776071 L34.5885939,15.6804286 C34.238451,15.8161429 34.0647368,16.2090357 34.200451,16.5585 C34.3042725,16.8272143 34.5607725,16.9927857 34.8328796,16.9927857 C34.9143082,16.9927857 34.9970939,16.9778571 35.0778439,16.9466429 L36.3399868,16.4580714 C36.8292368,17.1726071 37.6496296,17.6428571 38.5792725,17.6428571 C40.076201,17.6428571 41.2935582,16.4255 41.2935582,14.9285714 C41.2935582,13.4316429 40.076201,12.2142857 38.5792725,12.2142857 L38.5792725,12.2142857 Z M3.29355819,16.2857143 C2.54509391,16.2857143 1.93641533,15.6770357 1.93641533,14.9285714 C1.93641533,14.1801071 2.54509391,13.5714286 3.29355819,13.5714286 C4.04202248,13.5714286 4.65070105,14.1801071 4.65070105,14.9285714 C4.65070105,15.6770357 4.04202248,16.2857143 3.29355819,16.2857143 L3.29355819,16.2857143 Z M7.71173676,16.5781786 C7.84745105,16.2287143 7.67441533,15.8358214 7.32495105,15.7001071 L5.98273676,15.1782857 C5.99020105,15.0948214 6.00784391,15.0140714 6.00784391,14.9285714 C6.00784391,13.4316429 4.78980819,12.2142857 3.29355819,12.2142857 C1.79662962,12.2142857 0.579272478,13.4316429 0.579272478,14.9285714 C0.579272478,16.4255 1.79662962,17.6428571 3.29355819,17.6428571 C4.22184391,17.6428571 5.04223676,17.1732857 5.53216533,16.4594286 L6.83366533,16.9649643 C6.91441533,16.9961786 6.99720105,17.0111071 7.07930819,17.0111071 C7.35073676,17.0111071 7.60723676,16.8468929 7.71173676,16.5781786 L7.71173676,16.5781786 Z M20.9364153,1.35714286 C21.684201,1.35714286 22.2935582,1.96582143 22.2935582,2.71428571 C22.2935582,3.46275 21.684201,4.07142857 20.9364153,4.07142857 C20.187951,4.07142857 19.5792725,3.46275 19.5792725,2.71428571 C19.5792725,1.96582143 20.187951,1.35714286 20.9364153,1.35714286 L20.9364153,1.35714286 Z M20.2578439,5.33221429 L20.2578439,6.44642857 C20.2578439,6.821 20.5618439,7.125 20.9364153,7.125 C21.3109868,7.125 21.6149868,6.821 21.6149868,6.44642857 L21.6149868,5.33221429 C22.7821296,5.02889286 23.650701,3.97507143 23.650701,2.71428571 C23.650701,1.21735714 22.4333439,0 20.9364153,0 C19.4394868,0 18.2221296,1.21735714 18.2221296,2.71428571 C18.2221296,3.97507143 19.090701,5.02889286 20.2578439,5.33221429 L20.2578439,5.33221429 Z" id="globe-share"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg>
+
diff --git a/sources/pyside6/doc/images/Examples.svg b/sources/pyside6/doc/images/Examples.svg
new file mode 100644
index 000000000..a506e7798
--- /dev/null
+++ b/sources/pyside6/doc/images/Examples.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 75 75" style="enable-background:new 0 0 75 75;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:url(#SVGID_1_);}
+ .st1{fill:none;}
+</style>
+<g id="icon">
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="87.5133" y1="87.5133" x2="-26.0279" y2="-26.0279">
+ <stop offset="0" style="stop-color:#6FFE80"/>
+ <stop offset="0.3726" style="stop-color:#43CE58"/>
+ <stop offset="1" style="stop-color:#425FCF"/>
+ </linearGradient>
+ <path class="st0" d="M75,6.2v62.5c0,3.4-2.8,6.2-6.2,6.2H6.2C2.8,75,0,72.2,0,68.8v-50c0-0.7,0.6-1.2,1.2-1.2s1.2,0.6,1.2,1.2v50
+ c0,2.1,1.7,3.8,3.8,3.8h62.5c2.1,0,3.8-1.7,3.8-3.8V6.2c0-2.1-1.7-3.8-3.8-3.8H6.2c-2.1,0-3.8,1.7-3.8,3.8v6.2h66.2
+ c0.7,0,1.2,0.6,1.2,1.2S69.4,15,68.8,15H1.2C0.6,15,0,14.4,0,13.8V6.2C0,2.8,2.8,0,6.2,0h62.5C72.2,0,75,2.8,75,6.2L75,6.2z
+ M7.5,7.5C7.5,8.9,8.6,10,10,10s2.5-1.1,2.5-2.5S11.4,5,10,5S7.5,6.1,7.5,7.5L7.5,7.5z M15,7.5c0,1.4,1.1,2.5,2.5,2.5
+ S20,8.9,20,7.5S18.9,5,17.5,5S15,6.1,15,7.5L15,7.5z M22.5,7.5c0,1.4,1.1,2.5,2.5,2.5s2.5-1.1,2.5-2.5S26.4,5,25,5
+ S22.5,6.1,22.5,7.5L22.5,7.5z M63.8,53.7H51.2V41.2c0-0.7-0.6-1.2-1.2-1.2c-8.3,0-15,6.7-15,15s6.7,15,15,15s15-6.7,15-15
+ C65,54.3,64.4,53.7,63.8,53.7z M50,67.5c-6.9,0-12.5-5.6-12.5-12.5c0-6.5,4.9-11.8,11.2-12.4v13.7h13.7
+ C61.8,62.6,56.5,67.5,50,67.5z M55,35c-0.7,0-1.2,0.6-1.2,1.2v15h15c0.7,0,1.2-0.6,1.2-1.2C70,41.7,63.3,35,55,35z M56.2,48.7V37.6
+ c5.9,0.6,10.6,5.3,11.2,11.2H56.2z M38.7,24.9l-6.3,16.7c-0.2,0.5-0.6,0.8-1.1,0.8c-0.5,0-1-0.3-1.2-0.8l-2.5-5.9l-7.6,19.6
+ c-0.2,0.5-0.7,0.8-1.2,0.8c0,0,0,0-0.1,0c-0.5,0-1-0.4-1.1-0.9L9.9,26.8l-2.4,7.3c-0.2,0.7-0.9,1-1.6,0.8c-0.7-0.2-1-0.9-0.8-1.6
+ l3.8-11.2c0.2-0.5,0.7-0.9,1.2-0.9c0.6,0,1,0.4,1.2,0.9L19,51L26.3,32c0.2-0.5,0.6-0.8,1.1-0.8c0,0,0,0,0,0c0.5,0,1,0.3,1.1,0.8
+ l2.5,5.9l6.4-17.1c0.2-0.5,0.7-0.8,1.2-0.8c0.5,0,1,0.3,1.2,0.8l2.9,8.5l4.9-7.5c0.2-0.4,0.7-0.6,1.1-0.6c0.4,0,0.8,0.3,1.1,0.6
+ l3.9,6.9l2.7-4.4c0.2-0.4,0.6-0.6,1.1-0.6c0,0,0,0,0,0c0.4,0,0.8,0.2,1.1,0.6l2.5,4c0.4,0.6,0.2,1.4-0.4,1.7
+ c-0.6,0.4-1.4,0.2-1.7-0.4l-1.4-2.3l-2.7,4.5c-0.2,0.4-0.6,0.6-1.1,0.6c-0.4,0-0.9-0.2-1.1-0.6l-4-7l-5.1,7.9
+ c-0.3,0.4-0.7,0.6-1.2,0.6c-0.5-0.1-0.9-0.4-1-0.8L38.7,24.9z"/>
+</g>
+<g id="_x37_5px_frame">
+ <rect x="0" y="0" class="st1" width="75" height="75"/>
+</g>
+</svg>
diff --git a/sources/pyside6/doc/images/Support.svg b/sources/pyside6/doc/images/Support.svg
new file mode 100644
index 000000000..98b93d95c
--- /dev/null
+++ b/sources/pyside6/doc/images/Support.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="38px" height="38px" viewBox="0 0 38 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>website-fix</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-794.000000, -5715.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="Support" transform="translate(277.000000, 4042.000000)">
+ <g id="1" transform="translate(560.490048, 136.000000)">
+ <path d="M19.509952,37.4 C20.2085186,37.4 20.7766186,36.8319 20.7766186,36.1333333 C20.7766186,35.4347667 20.2085186,34.8666667 19.509952,34.8666667 C18.8113853,34.8666667 18.2432853,35.4347667 18.2432853,36.1333333 C18.2432853,36.8319 18.8113853,37.4 19.509952,37.4 L19.509952,37.4 Z M19.509952,38.6666667 C18.1128186,38.6666667 16.9766186,37.5304667 16.9766186,36.1333333 C16.9766186,34.7362 18.1128186,33.6 19.509952,33.6 C20.9070853,33.6 22.0432853,34.7362 22.0432853,36.1333333 C22.0432853,37.5304667 20.9070853,38.6666667 19.509952,38.6666667 L19.509952,38.6666667 Z M19.509952,41.2 C22.3035853,41.2 24.5766186,38.9269667 24.5766186,36.1333333 C24.5766186,33.3397 22.3035853,31.0666667 19.509952,31.0666667 C16.7163186,31.0666667 14.4432853,33.3397 14.4432853,36.1333333 C14.4432853,38.9269667 16.7163186,41.2 19.509952,41.2 L19.509952,41.2 Z M19.509952,42.4666667 C16.017752,42.4666667 13.1766186,39.6255333 13.1766186,36.1333333 C13.1766186,32.6411333 16.017752,29.8 19.509952,29.8 C23.002152,29.8 25.8432853,32.6411333 25.8432853,36.1333333 C25.8432853,39.6255333 23.002152,42.4666667 19.509952,42.4666667 L19.509952,42.4666667 Z M35.3432853,7 L3.67661862,7 C1.93051862,7 0.509951956,8.42056667 0.509951956,10.1666667 L0.509951956,13.9666667 C0.509951956,14.3162667 0.793685289,14.6 1.14328529,14.6 L35.3432853,14.6 C35.6928853,14.6 35.9766186,14.3162667 35.9766186,13.9666667 C35.9766186,13.6170667 35.6928853,13.3333333 35.3432853,13.3333333 L1.77661862,13.3333333 L1.77661862,10.1666667 C1.77661862,9.11913333 2.62908529,8.26666667 3.67661862,8.26666667 L35.3432853,8.26666667 C36.3908186,8.26666667 37.2432853,9.11913333 37.2432853,10.1666667 L37.2432853,41.8333333 C37.2432853,42.9163333 36.4262853,43.7333333 35.3432853,43.7333333 L30.5932853,43.7333333 L29.1796853,41.8479 C29.766152,41.0594 30.184152,40.1296667 30.4248186,39.3715667 C31.303252,39.1828333 32.1158186,39.0086667 32.304552,38.9700333 C33.0183186,38.8231 33.4439186,38.236 33.4439186,37.3993667 C33.4432853,36.9243667 33.4432853,35.3283667 33.4439186,34.8654 C33.442652,34.0357333 33.018952,33.4492667 32.310252,33.2966333 L30.429252,32.8938333 C30.203152,32.1306667 29.8985186,31.396 29.521052,30.6999667 C30.0080853,29.9469333 30.457752,29.2521667 30.5635186,29.0919333 C30.9637853,28.4833 30.8497853,27.7676333 30.258252,27.1761 L28.466552,25.3844 C27.8788186,24.7979333 27.165052,24.6826667 26.5545186,25.0766 L24.9414186,26.1209667 C24.2453853,25.7435 23.5100853,25.4388667 22.7469186,25.2134 C22.5588186,24.3375 22.3859186,23.5274667 22.346652,23.3387333 C22.200352,22.6256 21.6126186,22.2 20.7766186,22.2 L18.2432853,22.2 C17.4129853,22.2 16.8265186,22.6237 16.6738853,23.3336667 L16.2710853,25.2140333 C15.5079186,25.4401333 14.7726186,25.7441333 14.0765853,26.1222333 C13.3241853,25.6358333 12.6294186,25.1861667 12.468552,25.0797667 C11.8611853,24.6807667 11.1448853,24.7941333 10.553352,25.3856667 L8.76165196,27.1767333 C8.17518529,27.7632 8.05991862,28.4776 8.45385196,29.0881333 L9.49821862,30.7012333 C9.12011862,31.3966333 8.81611862,32.1325667 8.59001862,32.8957333 C7.71411862,33.0838333 6.90345196,33.2573667 6.71471862,33.2966333 C6.00221862,33.4442 5.57661862,34.0313 5.57661862,34.8673 L5.57661862,37.4 C5.57661862,38.2296667 6.00031862,38.8161333 6.71028529,38.9694 L8.59508529,39.3728333 C8.93328529,40.4444333 9.53051862,41.5439 10.1727186,42.2570333 C10.4064186,42.5173333 10.8066853,42.5376 11.0669853,42.3039 C11.3272853,42.0702 11.3481853,41.6699333 11.113852,41.4096333 C10.4406186,40.6610333 9.92445196,39.4963333 9.71165196,38.6742667 C9.65148529,38.4424667 9.46528529,38.2638667 9.23095196,38.2138333 L6.97628529,37.7306 C6.93005196,37.7204667 6.84328529,37.7021 6.84328529,37.4 L6.84328529,34.8666667 C6.84328529,34.5633 6.93638529,34.5436667 6.97058529,34.5367 C7.18655196,34.4923667 8.21635196,34.2719667 9.23095196,34.0534667 C9.46528529,34.0034333 9.65148529,33.8248333 9.71101862,33.5930333 C9.94725196,32.6791333 10.308252,31.8070333 10.7838853,31.0008 C10.9054853,30.7943333 10.9004186,30.5372 10.769952,30.3358 L9.51785196,28.4003333 C9.49188529,28.3604333 9.44375196,28.2857 9.65718529,28.0722667 L11.4488853,26.2805667 C11.6623186,26.0671333 11.7421186,26.1184333 11.7725186,26.1380667 C11.9561853,26.2590333 12.8403186,26.8309333 13.711152,27.3939667 C13.912552,27.5238 14.170952,27.5301333 14.3767853,27.4079 C15.1830186,26.9322667 16.0551186,26.5712667 16.9683853,26.3350333 C17.2008186,26.2748667 17.3787853,26.0886667 17.429452,25.8543333 L17.9126853,23.5990333 C17.9228186,23.5528 17.9411853,23.4666667 18.2432853,23.4666667 L20.7766186,23.4666667 C21.0799853,23.4666667 21.0989853,23.5591333 21.1065853,23.5939667 C21.1502853,23.8099333 21.3713186,24.8397333 21.5891853,25.8543333 C21.6392186,26.0886667 21.8178186,26.2748667 22.0496186,26.3344 C22.9635186,26.5706333 23.8356186,26.9316333 24.641852,27.4066333 C24.8483186,27.5288667 25.1060853,27.5231667 25.3074853,27.3927 L27.2416853,26.1406 C27.2815853,26.1152667 27.3575853,26.0658667 27.5710186,26.2799333 L29.363352,28.0716333 C29.5774186,28.2863333 29.524852,28.3655 29.5052186,28.3959 C29.384252,28.5795667 28.812352,29.4637 28.2486853,30.3345333 C28.118852,30.5359333 28.113152,30.7930667 28.2353853,31.0001667 C28.7110186,31.8057667 29.0720186,32.6778667 29.308252,33.5911333 C29.3684186,33.8235667 29.5539853,34.0015333 29.7883186,34.0522 L32.0436186,34.5354333 C32.089852,34.5455667 32.1766186,34.5639333 32.177252,34.8654 C32.1766186,35.3271 32.1766186,36.9256333 32.177252,37.4 C32.177252,37.7027333 32.084152,37.7223667 32.0486853,37.7293333 C31.833352,37.7736667 30.803552,37.9947 29.788952,38.2125667 C29.5546186,38.2626 29.3684186,38.4412 29.3088853,38.673 C29.0523853,39.6635333 28.500752,40.7389333 27.9028853,41.4128 C27.7033853,41.6382667 27.689452,41.9726667 27.869952,42.2133333 L29.769952,44.7466667 C29.889652,44.9062667 30.0771186,45 30.2766186,45 L35.3432853,45 C37.119152,45 38.509952,43.6092 38.509952,41.8333333 L38.509952,10.1666667 C38.509952,8.42056667 37.0893853,7 35.3432853,7 L35.3432853,7 Z M23.9432853,18.4 C24.2928853,18.4 24.5766186,18.1162667 24.5766186,17.7666667 C24.5766186,17.4170667 24.2928853,17.1333333 23.9432853,17.1333333 L21.409952,17.1333333 C21.060352,17.1333333 20.7766186,17.4170667 20.7766186,17.7666667 C20.7766186,18.1162667 21.060352,18.4 21.409952,18.4 L23.9432853,18.4 Z M34.0766186,18.4 C34.4262186,18.4 34.709952,18.1162667 34.709952,17.7666667 C34.709952,17.4170667 34.4262186,17.1333333 34.0766186,17.1333333 L31.5432853,17.1333333 C31.1936853,17.1333333 30.909952,17.4170667 30.909952,17.7666667 C30.909952,18.1162667 31.1936853,18.4 31.5432853,18.4 L34.0766186,18.4 Z M29.009952,18.4 C29.359552,18.4 29.6432853,18.1162667 29.6432853,17.7666667 C29.6432853,17.4170667 29.359552,17.1333333 29.009952,17.1333333 L26.4766186,17.1333333 C26.1270186,17.1333333 25.8432853,17.4170667 25.8432853,17.7666667 C25.8432853,18.1162667 26.1270186,18.4 26.4766186,18.4 L29.009952,18.4 Z M10.009952,18.4 C10.359552,18.4 10.6432853,18.1162667 10.6432853,17.7666667 C10.6432853,17.4170667 10.359552,17.1333333 10.009952,17.1333333 L4.94328529,17.1333333 C4.59368529,17.1333333 4.30995196,17.4170667 4.30995196,17.7666667 C4.30995196,18.1162667 4.59368529,18.4 4.94328529,18.4 L10.009952,18.4 Z M11.909952,10.8 C11.909952,11.4985667 12.478052,12.0666667 13.1766186,12.0666667 C13.8751853,12.0666667 14.4432853,11.4985667 14.4432853,10.8 C14.4432853,10.1014333 13.8751853,9.53333333 13.1766186,9.53333333 C12.478052,9.53333333 11.909952,10.1014333 11.909952,10.8 L11.909952,10.8 Z M8.10995196,10.8 C8.10995196,11.4985667 8.67805196,12.0666667 9.37661862,12.0666667 C10.0751853,12.0666667 10.6432853,11.4985667 10.6432853,10.8 C10.6432853,10.1014333 10.0751853,9.53333333 9.37661862,9.53333333 C8.67805196,9.53333333 8.10995196,10.1014333 8.10995196,10.8 L8.10995196,10.8 Z M4.30995196,10.8 C4.30995196,11.4985667 4.87805196,12.0666667 5.57661862,12.0666667 C6.27518529,12.0666667 6.84328529,11.4985667 6.84328529,10.8 C6.84328529,10.1014333 6.27518529,9.53333333 5.57661862,9.53333333 C4.87805196,9.53333333 4.30995196,10.1014333 4.30995196,10.8 L4.30995196,10.8 Z M27.7432853,44.3666667 C27.7432853,44.7162667 27.459552,45 27.109952,45 L3.67661862,45 C1.90075196,45 0.509951956,43.6092 0.509951956,41.8333333 L0.509951956,16.5 C0.509951956,16.1504 0.793685289,15.8666667 1.14328529,15.8666667 C1.49288529,15.8666667 1.77661862,16.1504 1.77661862,16.5 L1.77661862,41.8333333 C1.77661862,42.9163333 2.59361862,43.7333333 3.67661862,43.7333333 L27.109952,43.7333333 C27.459552,43.7333333 27.7432853,44.0170667 27.7432853,44.3666667 L27.7432853,44.3666667 Z" id="website-fix"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/Tooling.svg b/sources/pyside6/doc/images/Tooling.svg
new file mode 100644
index 000000000..98116957e
--- /dev/null
+++ b/sources/pyside6/doc/images/Tooling.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="49px" height="48px" viewBox="0 0 49 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>web-development</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-1084.000000, -1756.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="WhatQtis" transform="translate(194.000000, 0.000000)">
+ <g id="Block3_Hover" transform="translate(726.316067, 114.000000)">
+ <path d="M214.4,115.2 C215.2816,115.2 216,115.9176 216,116.8 C216,117.6824 215.2816,118.4 214.4,118.4 C213.5176,118.4 212.8,117.6824 212.8,116.8 C212.8,115.9176 213.5176,115.2 214.4,115.2 L214.4,115.2 Z M217.6,116.8 C217.6,117.6824 218.3176,118.4 219.2,118.4 C220.0816,118.4 220.8,117.6824 220.8,116.8 C220.8,115.9176 220.0816,115.2 219.2,115.2 C218.3176,115.2 217.6,115.9176 217.6,116.8 L217.6,116.8 Z M222.4,116.8 C222.4,117.6824 223.1176,118.4 224,118.4 C224.8816,118.4 225.6,117.6824 225.6,116.8 C225.6,115.9176 224.8816,115.2 224,115.2 C223.1176,115.2 222.4,115.9176 222.4,116.8 L222.4,116.8 Z M215.2,128 L216.8,128 C217.2424,128 217.6,127.6416 217.6,127.2 C217.6,126.7584 217.2424,126.4 216.8,126.4 L215.2,126.4 C214.7576,126.4 214.4,126.7584 214.4,127.2 C214.4,127.6416 214.7576,128 215.2,128 L215.2,128 Z M215.2,131.2 L216.8,131.2 C217.2424,131.2 217.6,130.8416 217.6,130.4 C217.6,129.9584 217.2424,129.6 216.8,129.6 L215.2,129.6 C214.7576,129.6 214.4,129.9584 214.4,130.4 C214.4,130.8416 214.7576,131.2 215.2,131.2 L215.2,131.2 Z M215.2,134.4 L216.8,134.4 C217.2424,134.4 217.6,134.0416 217.6,133.6 C217.6,133.1584 217.2424,132.8 216.8,132.8 L215.2,132.8 C214.7576,132.8 214.4,133.1584 214.4,133.6 C214.4,134.0416 214.7576,134.4 215.2,134.4 L215.2,134.4 Z M215.2,137.6 L216.8,137.6 C217.2424,137.6 217.6,137.2416 217.6,136.8 C217.6,136.3584 217.2424,136 216.8,136 L215.2,136 C214.7576,136 214.4,136.3584 214.4,136.8 C214.4,137.2416 214.7576,137.6 215.2,137.6 L215.2,137.6 Z M215.2,140.8 L216.8,140.8 C217.2424,140.8 217.6,140.4416 217.6,140 C217.6,139.5584 217.2424,139.2 216.8,139.2 L215.2,139.2 C214.7576,139.2 214.4,139.5584 214.4,140 C214.4,140.4416 214.7576,140.8 215.2,140.8 L215.2,140.8 Z M215.2,144 L216.8,144 C217.2424,144 217.6,143.6416 217.6,143.2 C217.6,142.7584 217.2424,142.4 216.8,142.4 L215.2,142.4 C214.7576,142.4 214.4,142.7584 214.4,143.2 C214.4,143.6416 214.7576,144 215.2,144 L215.2,144 Z M215.2,147.2 L216.8,147.2 C217.2424,147.2 217.6,146.8416 217.6,146.4 C217.6,145.9584 217.2424,145.6 216.8,145.6 L215.2,145.6 C214.7576,145.6 214.4,145.9584 214.4,146.4 C214.4,146.8416 214.7576,147.2 215.2,147.2 L215.2,147.2 Z M215.2,150.4 L216.8,150.4 C217.2424,150.4 217.6,150.0416 217.6,149.6 C217.6,149.1584 217.2424,148.8 216.8,148.8 L215.2,148.8 C214.7576,148.8 214.4,149.1584 214.4,149.6 C214.4,150.0416 214.7576,150.4 215.2,150.4 L215.2,150.4 Z M215.2,153.6 L216.8,153.6 C217.2424,153.6 217.6,153.2416 217.6,152.8 C217.6,152.3584 217.2424,152 216.8,152 L215.2,152 C214.7576,152 214.4,152.3584 214.4,152.8 C214.4,153.2416 214.7576,153.6 215.2,153.6 L215.2,153.6 Z M242.4,128 C242.8424,128 243.2,127.6416 243.2,127.2 C243.2,126.7584 242.8424,126.4 242.4,126.4 L239.2,126.4 C238.7576,126.4 238.4,126.7584 238.4,127.2 C238.4,127.6416 238.7576,128 239.2,128 L242.4,128 L242.4,128 Z M235.2,130.4 C235.2,130.8416 235.5576,131.2 236,131.2 L244,131.2 C244.4424,131.2 244.8,130.8416 244.8,130.4 C244.8,129.9584 244.4424,129.6 244,129.6 L236,129.6 C235.5576,129.6 235.2,129.9584 235.2,130.4 L235.2,130.4 Z M220,131.2 L232.8,131.2 C233.2424,131.2 233.6,130.8416 233.6,130.4 C233.6,129.9584 233.2424,129.6 232.8,129.6 L220,129.6 C219.5576,129.6 219.2,129.9584 219.2,130.4 C219.2,130.8416 219.5576,131.2 220,131.2 L220,131.2 Z M220,128 L228,128 C228.4424,128 228.8,127.6416 228.8,127.2 C228.8,126.7584 228.4424,126.4 228,126.4 L220,126.4 C219.5576,126.4 219.2,126.7584 219.2,127.2 C219.2,127.6416 219.5576,128 220,128 L220,128 Z M236,126.4 L231.2,126.4 C230.7576,126.4 230.4,126.7584 230.4,127.2 C230.4,127.6416 230.7576,128 231.2,128 L236,128 C236.4424,128 236.8,127.6416 236.8,127.2 C236.8,126.7584 236.4424,126.4 236,126.4 L236,126.4 Z M248,133.6 C248,133.1584 247.6424,132.8 247.2,132.8 L234.4,132.8 C233.9576,132.8 233.6,133.1584 233.6,133.6 C233.6,134.0416 233.9576,134.4 234.4,134.4 L247.2,134.4 C247.6424,134.4 248,134.0416 248,133.6 L248,133.6 Z M242.4,137.6 C242.8424,137.6 243.2,137.2416 243.2,136.8 C243.2,136.3584 242.8424,136 242.4,136 L236,136 C235.5576,136 235.2,136.3584 235.2,136.8 C235.2,137.2416 235.5576,137.6 236,137.6 L242.4,137.6 L242.4,137.6 Z M220,137.6 L232.8,137.6 C233.2424,137.6 233.6,137.2416 233.6,136.8 C233.6,136.3584 233.2424,136 232.8,136 L220,136 C219.5576,136 219.2,136.3584 219.2,136.8 C219.2,137.2416 219.5576,137.6 220,137.6 L220,137.6 Z M220,134.4 L223.2,134.4 C223.6424,134.4 224,134.0416 224,133.6 C224,133.1584 223.6424,132.8 223.2,132.8 L220,132.8 C219.5576,132.8 219.2,133.1584 219.2,133.6 C219.2,134.0416 219.5576,134.4 220,134.4 L220,134.4 Z M226.4,132.8 C225.9576,132.8 225.6,133.1584 225.6,133.6 C225.6,134.0416 225.9576,134.4 226.4,134.4 L231.2,134.4 C231.6424,134.4 232,134.0416 232,133.6 C232,133.1584 231.6424,132.8 231.2,132.8 L226.4,132.8 L226.4,132.8 Z M237.6,146.4 C237.6,145.9584 237.2424,145.6 236.8,145.6 L234.4,145.6 C233.9576,145.6 233.6,145.9584 233.6,146.4 C233.6,146.8416 233.9576,147.2 234.4,147.2 L236.8,147.2 C237.2424,147.2 237.6,146.8416 237.6,146.4 L237.6,146.4 Z M220,147.2 L223.2,147.2 C223.6424,147.2 224,146.8416 224,146.4 C224,145.9584 223.6424,145.6 223.2,145.6 L220,145.6 C219.5576,145.6 219.2,145.9584 219.2,146.4 C219.2,146.8416 219.5576,147.2 220,147.2 L220,147.2 Z M231.2,145.6 L226.4,145.6 C225.9576,145.6 225.6,145.9584 225.6,146.4 C225.6,146.8416 225.9576,147.2 226.4,147.2 L231.2,147.2 C231.6424,147.2 232,146.8416 232,146.4 C232,145.9584 231.6424,145.6 231.2,145.6 L231.2,145.6 Z M220,150.4 L229.6,150.4 C230.0424,150.4 230.4,150.0416 230.4,149.6 C230.4,149.1584 230.0424,148.8 229.6,148.8 L220,148.8 C219.5576,148.8 219.2,149.1584 219.2,149.6 C219.2,150.0416 219.5576,150.4 220,150.4 L220,150.4 Z M232.8,150.4 L234.4,150.4 C234.8424,150.4 235.2,150.0416 235.2,149.6 C235.2,149.1584 234.8424,148.8 234.4,148.8 L232.8,148.8 C232.3576,148.8 232,149.1584 232,149.6 C232,150.0416 232.3576,150.4 232.8,150.4 L232.8,150.4 Z M220,153.6 L224.8,153.6 C225.2424,153.6 225.6,153.2416 225.6,152.8 C225.6,152.3584 225.2424,152 224.8,152 L220,152 C219.5576,152 219.2,152.3584 219.2,152.8 C219.2,153.2416 219.5576,153.6 220,153.6 L220,153.6 Z M227.2,152.8 C227.2,153.2416 227.5576,153.6 228,153.6 L236,153.6 C236.4424,153.6 236.8,153.2416 236.8,152.8 C236.8,152.3584 236.4424,152 236,152 L228,152 C227.5576,152 227.2,152.3584 227.2,152.8 L227.2,152.8 Z M244.8,140 C244.8,139.5584 244.4424,139.2 244,139.2 L231.2,139.2 C230.7576,139.2 230.4,139.5584 230.4,140 C230.4,140.4416 230.7576,140.8 231.2,140.8 L244,140.8 C244.4424,140.8 244.8,140.4416 244.8,140 L244.8,140 Z M239.2,143.2 C239.2,142.7584 238.8424,142.4 238.4,142.4 L232.8,142.4 C232.3576,142.4 232,142.7584 232,143.2 C232,143.6416 232.3576,144 232.8,144 L238.4,144 C238.8424,144 239.2,143.6416 239.2,143.2 L239.2,143.2 Z M220,144 L229.6,144 C230.0424,144 230.4,143.6416 230.4,143.2 C230.4,142.7584 230.0424,142.4 229.6,142.4 L220,142.4 C219.5576,142.4 219.2,142.7584 219.2,143.2 C219.2,143.6416 219.5576,144 220,144 L220,144 Z M220,140.8 L228,140.8 C228.4424,140.8 228.8,140.4416 228.8,140 C228.8,139.5584 228.4424,139.2 228,139.2 L220,139.2 C219.5576,139.2 219.2,139.5584 219.2,140 C219.2,140.4416 219.5576,140.8 220,140.8 L220,140.8 Z M256,149.6 L256,152.8 C256,153.2416 255.6424,153.6 255.2,153.6 L253.9816,153.6 C253.8976,153.8384 253.8008,154.072 253.692,154.3 L254.5528,155.1608 C254.8656,155.4736 254.8656,155.98 254.5528,156.292 L252.2904,158.5544 C252.1408,158.7048 251.9376,158.7888 251.7248,158.7888 C251.5128,158.7888 251.3096,158.7048 251.1592,158.5544 L250.2976,157.6928 C250.0704,157.8008 249.8376,157.8976 249.5992,157.9816 L249.5992,159.2 C249.5992,159.6416 249.2416,160 248.7992,160 L245.5992,160 C245.1568,160 244.7992,159.6416 244.7992,159.2 L244.7992,157.9816 C244.5616,157.8976 244.3288,157.8008 244.1008,157.692 L243.24,158.5528 C242.94,158.8528 242.4088,158.8528 242.1088,158.5528 L239.8464,156.2904 C239.5336,155.9784 239.5336,155.472 239.8464,155.1592 L240.7072,154.2984 C240.5992,154.0704 240.5024,153.8376 240.4184,153.6 L239.2,153.6 C238.7576,153.6 238.4,153.2416 238.4,152.8 L238.4,149.6 C238.4,149.1584 238.7576,148.8 239.2,148.8 L240.4184,148.8 C240.5024,148.5616 240.5992,148.328 240.708,148.1 L239.8472,147.2392 C239.5344,146.9264 239.5344,146.42 239.8472,146.108 L242.1088,143.8456 C242.4088,143.5456 242.94,143.5456 243.24,143.8456 L244.1016,144.7072 C244.3288,144.5984 244.5624,144.5016 244.8008,144.4176 L244.8008,143.2 C244.8008,142.7584 245.1584,142.4 245.6008,142.4 L248.8,142.4 C249.2424,142.4 249.6,142.7584 249.6,143.2 L249.6,144.4176 C249.8384,144.5016 250.072,144.5984 250.2984,144.7064 L251.16,143.8456 C251.4728,143.5344 251.9792,143.5336 252.2912,143.8464 L254.5536,146.1088 C254.8664,146.4208 254.8664,146.9272 254.5536,147.24 L253.6928,148.1008 C253.8016,148.3288 253.8976,148.5624 253.9816,148.8 L255.2,148.8 C255.6424,148.8 256,149.1584 256,149.6 L256,149.6 Z M254.4,150.4 L253.3896,150.4 C253.0248,150.4 252.7064,150.1528 252.6152,149.7992 C252.4848,149.2928 252.2848,148.8088 252.0192,148.3608 C251.8344,148.0464 251.8848,147.6464 252.1432,147.388 L252.8568,146.6744 L251.7256,145.5432 L251.012,146.2568 C250.7528,146.5144 250.352,146.5648 250.0392,146.3792 C249.5928,146.116 249.1088,145.916 248.6,145.784 C248.2472,145.6928 248,145.3744 248,145.0096 L248,144 L246.4008,144 L246.4008,145.0096 C246.4008,145.3744 246.1536,145.6928 245.8008,145.784 C245.292,145.916 244.8072,146.116 244.36,146.38 C244.0472,146.5656 243.6472,146.5152 243.388,146.256 L242.6744,145.5424 L241.544,146.6736 L242.2568,147.3872 C242.5152,147.6456 242.5656,148.0456 242.3808,148.36 C242.1152,148.8072 241.9152,149.292 241.7848,149.7992 C241.6936,150.1528 241.3752,150.4 241.0104,150.4 L240,150.4 L240,152 L241.0104,152 C241.3752,152 241.6936,152.2472 241.7848,152.6 C241.9152,153.1064 242.1152,153.5904 242.3808,154.0384 C242.5656,154.3528 242.5152,154.7528 242.2568,155.0112 L241.5432,155.7248 L242.6744,156.856 L243.388,156.1424 C243.6472,155.884 244.048,155.8336 244.3608,156.0192 C244.8112,156.2848 245.2944,156.4848 245.7976,156.6144 C246.152,156.7048 246.3992,157.024 246.3992,157.3888 L246.3992,158.4 L247.9992,158.4 L247.9992,157.3896 C247.9992,157.0248 248.2464,156.7056 248.6,156.6152 C249.1064,156.4848 249.5904,156.284 250.0384,156.02 C250.352,155.8344 250.7536,155.8848 251.0112,156.1432 L251.7248,156.8576 L252.856,155.7264 L252.1424,155.0128 C251.8832,154.7544 251.8336,154.3536 252.0192,154.0392 C252.2848,153.5912 252.4848,153.1072 252.6152,152.6008 C252.7064,152.2472 253.0248,152 253.3896,152 L254.4,152 L254.4,150.4 L254.4,150.4 Z M249.6,151.2 C249.6,152.5232 248.5232,153.6 247.2,153.6 C245.8768,153.6 244.8,152.5232 244.8,151.2 C244.8,149.8768 245.8768,148.8 247.2,148.8 C248.5232,148.8 249.6,149.8768 249.6,151.2 L249.6,151.2 Z M248,151.2 C248,150.7592 247.6416,150.4 247.2,150.4 C246.7584,150.4 246.4,150.7592 246.4,151.2 C246.4,151.6408 246.7584,152 247.2,152 C247.6416,152 248,151.6408 248,151.2 L248,151.2 Z M239.2,158.4 L212,158.4 C210.6768,158.4 209.6,157.3232 209.6,156 L209.6,124 C209.6,123.5584 209.2424,123.2 208.8,123.2 C208.3576,123.2 208,123.5584 208,124 L208,156 C208,158.2056 209.7944,160 212,160 L239.2,160 C239.6424,160 240,159.6416 240,159.2 C240,158.7584 239.6424,158.4 239.2,158.4 L239.2,158.4 Z M252,112 L212,112 C209.7944,112 208,113.7944 208,116 L208,120.8 C208,121.2416 208.3576,121.6 208.8,121.6 L252,121.6 C252.4424,121.6 252.8,121.2416 252.8,120.8 C252.8,120.3584 252.4424,120 252,120 L209.6,120 L209.6,116 C209.6,114.6768 210.6768,113.6 212,113.6 L252,113.6 C253.3232,113.6 254.4,114.6768 254.4,116 L254.4,143.2 C254.4,143.6416 254.7576,144 255.2,144 C255.6424,144 256,143.6416 256,143.2 L256,116 C256,113.7944 254.2056,112 252,112 L252,112 Z" id="web-development"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/Training.svg b/sources/pyside6/doc/images/Training.svg
new file mode 100644
index 000000000..96ecf71ec
--- /dev/null
+++ b/sources/pyside6/doc/images/Training.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="38px" height="38px" viewBox="0 0 38 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>presentation-man</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-264.000000, -5885.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="Support" transform="translate(277.000000, 4042.000000)">
+ <g id="1" transform="translate(30.774880, 308.000000)">
+ <path d="M38.2251201,6.9 L38.2251201,9.43333333 C38.2251201,9.78293333 37.9413868,10.0666667 37.5917868,10.0666667 L36.9584534,10.0666667 L36.9584534,24.6333333 C36.9584534,24.9829333 36.6747201,25.2666667 36.3251201,25.2666667 C35.9755201,25.2666667 35.6917868,24.9829333 35.6917868,24.6333333 L35.6917868,9.43333333 C35.6917868,9.08373333 35.9755201,8.8 36.3251201,8.8 L36.9584534,8.8 L36.9584534,7.53333333 L1.49178678,7.53333333 L1.49178678,8.8 L33.7917868,8.8 C34.1413868,8.8 34.4251201,9.08373333 34.4251201,9.43333333 C34.4251201,9.78293333 34.1413868,10.0666667 33.7917868,10.0666667 L0.858453443,10.0666667 C0.508853443,10.0666667 0.22512011,9.78293333 0.22512011,9.43333333 L0.22512011,6.9 C0.22512011,6.5504 0.508853443,6.26666667 0.858453443,6.26666667 L18.5917868,6.26666667 L18.5917868,5.63333333 C18.5917868,5.28373333 18.8755201,5 19.2251201,5 C19.5747201,5 19.8584534,5.28373333 19.8584534,5.63333333 L19.8584534,6.26666667 L37.5917868,6.26666667 C37.9413868,6.26666667 38.2251201,6.5504 38.2251201,6.9 L38.2251201,6.9 Z M8.45845344,15.1333333 L13.5251201,15.1333333 C13.8747201,15.1333333 14.1584534,14.8496 14.1584534,14.5 C14.1584534,14.1504 13.8747201,13.8666667 13.5251201,13.8666667 L8.45845344,13.8666667 C8.10885344,13.8666667 7.82512011,14.1504 7.82512011,14.5 C7.82512011,14.8496 8.10885344,15.1333333 8.45845344,15.1333333 L8.45845344,15.1333333 Z M8.45845344,18.9333333 L19.8584534,18.9333333 C20.2080534,18.9333333 20.4917868,18.6496 20.4917868,18.3 C20.4917868,17.9504 20.2080534,17.6666667 19.8584534,17.6666667 L8.45845344,17.6666667 C8.10885344,17.6666667 7.82512011,17.9504 7.82512011,18.3 C7.82512011,18.6496 8.10885344,18.9333333 8.45845344,18.9333333 L8.45845344,18.9333333 Z M18.5917868,15.1333333 C18.9413868,15.1333333 19.2251201,14.8496 19.2251201,14.5 C19.2251201,14.1504 18.9413868,13.8666667 18.5917868,13.8666667 L16.0584534,13.8666667 C15.7088534,13.8666667 15.4251201,14.1504 15.4251201,14.5 C15.4251201,14.8496 15.7088534,15.1333333 16.0584534,15.1333333 L18.5917868,15.1333333 L18.5917868,15.1333333 Z M8.45845344,22.7333333 L10.3584534,22.7333333 C10.7080534,22.7333333 10.9917868,22.4496 10.9917868,22.1 C10.9917868,21.7504 10.7080534,21.4666667 10.3584534,21.4666667 L8.45845344,21.4666667 C8.10885344,21.4666667 7.82512011,21.7504 7.82512011,22.1 C7.82512011,22.4496 8.10885344,22.7333333 8.45845344,22.7333333 L8.45845344,22.7333333 Z M19.8584534,21.4666667 L13.5251201,21.4666667 C13.1755201,21.4666667 12.8917868,21.7504 12.8917868,22.1 C12.8917868,22.4496 13.1755201,22.7333333 13.5251201,22.7333333 L19.8584534,22.7333333 C20.2080534,22.7333333 20.4917868,22.4496 20.4917868,22.1 C20.4917868,21.7504 20.2080534,21.4666667 19.8584534,21.4666667 L19.8584534,21.4666667 Z M31.2996201,25.2749 C30.9690201,25.2742667 30.6757868,25.4953 30.6308201,25.8221 L28.7308201,39.7478333 C28.6839534,40.0942667 28.9258868,40.4134667 29.2729534,40.4609667 C29.3020868,40.4647667 29.3305868,40.4666667 29.3597201,40.4666667 C29.6713201,40.4666667 29.9423868,40.2367667 29.9860868,39.9188333 L31.8107201,26.5472667 C33.9976201,26.6023667 35.4935534,27.0178333 36.2611534,27.7841667 C36.7304534,28.2522 36.9584534,28.8792 36.9584534,29.7 L36.9584534,39.8333333 C36.9584534,40.1829333 37.2421868,40.4666667 37.5917868,40.4666667 C37.9413868,40.4666667 38.2251201,40.1829333 38.2251201,39.8333333 L38.2251201,29.7 C38.2251201,28.5416333 37.8653868,27.5954333 37.1560534,26.888 C36.0692534,25.8024667 34.1534201,25.2749 31.2996201,25.2749 L31.2996201,25.2749 Z M25.5527534,25.8145 L27.4527534,39.7478333 C27.4996201,40.0942667 27.2570534,40.4134667 26.9106201,40.4609667 C26.5654534,40.5097333 26.2443534,40.2659 26.1974868,39.9188333 L24.3722201,26.5333333 L14.1584534,26.5333333 L14.1584534,29.0666667 L21.1251201,29.0666667 C21.4506534,29.0666667 21.7229868,29.3130333 21.7552868,29.6366667 L23.0219534,42.3033333 C23.0567868,42.6516667 22.8028201,42.962 22.4551201,42.9968333 C22.4335868,42.9987333 22.4120534,43 22.3911534,43 C22.0694201,43 21.7945534,42.7561667 21.7616201,42.43 L20.5519534,30.3333333 L12.2584534,30.3333333 C9.30648678,30.3333333 7.82512011,27.4909333 7.82512011,25.9 C7.82512011,25.5504 8.10885344,25.2666667 8.45845344,25.2666667 L24.9251201,25.2666667 C25.2417868,25.2666667 25.5096868,25.501 25.5527534,25.8145 L25.5527534,25.8145 Z M12.8917868,26.5333333 L9.20135344,26.5333333 C9.51105344,27.5688333 10.4863868,29.0666667 12.2584534,29.0666667 L12.8917868,29.0666667 L12.8917868,26.5333333 L12.8917868,26.5333333 Z M29.3584534,26.5333333 C29.3584534,25.8347667 28.7903534,25.2666667 28.0917868,25.2666667 C27.3932201,25.2666667 26.8251201,25.8347667 26.8251201,26.5333333 C26.8251201,27.0001 27.0816201,27.4041667 27.4584534,27.6239333 L27.4584534,32.2333333 C27.4584534,32.5829333 27.7421868,32.8666667 28.0917868,32.8666667 C28.4413868,32.8666667 28.7251201,32.5829333 28.7251201,32.2333333 L28.7251201,27.6239333 C29.1019534,27.4041667 29.3584534,27.0001 29.3584534,26.5333333 L29.3584534,26.5333333 Z M33.1584534,15.1333333 L33.1584534,15.3037 C33.5365534,15.5228333 33.7917868,15.9319667 33.7917868,16.4 L33.7917868,17.6666667 C33.7917868,18.1442 33.5257868,18.5615667 33.1337534,18.7769 C33.0134201,19.9941667 32.4839534,21.0657667 32.4586201,21.1164333 C31.8841868,22.2646667 31.0165201,24 28.0917868,24 C25.1670534,24 24.2993868,22.2646667 23.7255868,21.1164333 C23.6996201,21.0657667 23.1701534,19.9941667 23.0498201,18.7769 C22.6577868,18.5615667 22.3917868,18.1442 22.3917868,17.6666667 L22.3917868,16.4 C22.3917868,15.9319667 22.6470201,15.5228333 23.0251201,15.3037 L23.0251201,15.1333333 C23.0251201,13.0376333 24.7294201,11.3333333 26.8251201,11.3333333 L29.3584534,11.3333333 C31.4541534,11.3333333 33.1584534,13.0376333 33.1584534,15.1333333 L33.1584534,15.1333333 Z M32.5251201,16.4 C32.1755201,16.4 31.8917868,16.1162667 31.8917868,15.7666667 L31.8917868,15.1333333 C31.8917868,13.7362 30.7555868,12.6 29.3584534,12.6 L26.8251201,12.6 C25.4279868,12.6 24.2917868,13.7362 24.2917868,15.1333333 L24.2917868,15.7666667 C24.2917868,16.1162667 24.0080534,16.4 23.6584534,16.4 L23.6584534,17.6666667 C24.0080534,17.6666667 24.2917868,17.9504 24.2917868,18.3 C24.2917868,19.3956667 24.8529201,20.5394667 24.8586201,20.5508667 C25.5179201,21.8688333 26.0993201,22.7333333 28.0917868,22.7333333 C30.0842534,22.7333333 30.6656534,21.8688333 31.3249534,20.5502333 C31.3306534,20.5394667 31.8917868,19.3956667 31.8917868,18.3 C31.8917868,17.9504 32.1755201,17.6666667 32.5251201,17.6666667 L32.5251201,16.4 L32.5251201,16.4 Z M29.9917868,16.4 L29.3584534,16.4 C29.0088534,16.4 28.7251201,16.6837333 28.7251201,17.0333333 C28.7251201,17.3829333 29.0088534,17.6666667 29.3584534,17.6666667 L29.9917868,17.6666667 C30.3413868,17.6666667 30.6251201,17.3829333 30.6251201,17.0333333 C30.6251201,16.6837333 30.3413868,16.4 29.9917868,16.4 L29.9917868,16.4 Z M26.8251201,16.4 L26.1917868,16.4 C25.8421868,16.4 25.5584534,16.6837333 25.5584534,17.0333333 C25.5584534,17.3829333 25.8421868,17.6666667 26.1917868,17.6666667 L26.8251201,17.6666667 C27.1747201,17.6666667 27.4584534,17.3829333 27.4584534,17.0333333 C27.4584534,16.6837333 27.1747201,16.4 26.8251201,16.4 L26.8251201,16.4 Z M33.7917868,32.8666667 C33.4421868,32.8666667 33.1584534,33.1504 33.1584534,33.5 L33.1584534,42.3666667 C33.1584534,42.7162667 33.4421868,43 33.7917868,43 C34.1413868,43 34.4251201,42.7162667 34.4251201,42.3666667 L34.4251201,33.5 C34.4251201,33.1504 34.1413868,32.8666667 33.7917868,32.8666667 L33.7917868,32.8666667 Z M19.2251201,32.8666667 L4.65845344,32.8666667 C3.57545344,32.8666667 2.75845344,32.0496667 2.75845344,30.9666667 L2.75845344,11.9666667 C2.75845344,11.6170667 2.47472011,11.3333333 2.12512011,11.3333333 C1.77552011,11.3333333 1.49178678,11.6170667 1.49178678,11.9666667 L1.49178678,30.9666667 C1.49178678,32.7425333 2.88258678,34.1333333 4.65845344,34.1333333 L19.2251201,34.1333333 C19.5747201,34.1333333 19.8584534,33.8496 19.8584534,33.5 C19.8584534,33.1504 19.5747201,32.8666667 19.2251201,32.8666667 L19.2251201,32.8666667 Z" id="presentation-man"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/Tutorials.svg b/sources/pyside6/doc/images/Tutorials.svg
new file mode 100644
index 000000000..1bbf54e53
--- /dev/null
+++ b/sources/pyside6/doc/images/Tutorials.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="38px" height="38px" viewBox="0 0 38 38" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>design-skills</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-798.000000, -5886.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="Support" transform="translate(277.000000, 4042.000000)">
+ <g id="1" transform="translate(564.490048, 308.000000)">
+ <path d="M0.509951956,25.6333333 L0.509951956,9.16666667 C0.509951956,7.539 2.04895196,6 3.67661862,6 L7.47661862,6 C7.82621862,6 8.10995196,6.28373333 8.10995196,6.63333333 C8.10995196,6.98293333 7.82621862,7.26666667 7.47661862,7.26666667 L3.67661862,7.26666667 C2.75321862,7.26666667 1.77661862,8.24326667 1.77661862,9.16666667 L1.77661862,25.6333333 C1.77661862,25.9829333 1.49288529,26.2666667 1.14328529,26.2666667 C0.793685289,26.2666667 0.509951956,25.9829333 0.509951956,25.6333333 L0.509951956,25.6333333 Z M35.3432853,6 L29.009952,6 C28.660352,6 28.3766186,6.28373333 28.3766186,6.63333333 C28.3766186,6.98293333 28.660352,7.26666667 29.009952,7.26666667 L35.3432853,7.26666667 C36.2666853,7.26666667 37.2432853,8.24326667 37.2432853,9.16666667 L37.2432853,31.9666667 C37.2432853,32.8900667 36.2666853,33.8666667 35.3432853,33.8666667 L3.67661862,33.8666667 C2.75321862,33.8666667 1.77661862,32.8900667 1.77661862,31.9666667 L1.77661862,28.8 L35.3432853,28.8 C35.6928853,28.8 35.9766186,28.5162667 35.9766186,28.1666667 C35.9766186,27.8170667 35.6928853,27.5333333 35.3432853,27.5333333 L1.14328529,27.5333333 C0.793685289,27.5333333 0.509951956,27.8170667 0.509951956,28.1666667 L0.509951956,31.9666667 C0.509951956,33.5943333 2.04895196,35.1333333 3.67661862,35.1333333 L35.3432853,35.1333333 C36.970952,35.1333333 38.509952,33.5943333 38.509952,31.9666667 L38.509952,9.16666667 C38.509952,7.539 36.970952,6 35.3432853,6 L35.3432853,6 Z M18.2432853,31.3333333 C18.2432853,32.0319 18.8113853,32.6 19.509952,32.6 C20.2085186,32.6 20.7766186,32.0319 20.7766186,31.3333333 C20.7766186,30.6347667 20.2085186,30.0666667 19.509952,30.0666667 C18.8113853,30.0666667 18.2432853,30.6347667 18.2432853,31.3333333 L18.2432853,31.3333333 Z M26.4766186,42.7333333 L25.8432853,42.7333333 L25.8432853,42.1 C25.8432853,41.7504 25.559552,41.4666667 25.209952,41.4666667 C24.860352,41.4666667 24.5766186,41.7504 24.5766186,42.1 L24.5766186,42.7333333 L23.309952,42.7333333 L23.309952,42.1 C23.309952,41.7504 23.0262186,41.4666667 22.6766186,41.4666667 C22.3270186,41.4666667 22.0432853,41.7504 22.0432853,42.1 L22.0432853,42.7333333 L20.7766186,42.7333333 L20.7766186,42.1 C20.7766186,41.7504 20.4928853,41.4666667 20.1432853,41.4666667 C19.7936853,41.4666667 19.509952,41.7504 19.509952,42.1 L19.509952,42.7333333 L18.2432853,42.7333333 L18.2432853,42.1 C18.2432853,41.7504 17.959552,41.4666667 17.609952,41.4666667 C17.260352,41.4666667 16.9766186,41.7504 16.9766186,42.1 L16.9766186,42.7333333 L15.709952,42.7333333 L15.709952,42.1 C15.709952,41.7504 15.4262186,41.4666667 15.0766186,41.4666667 C14.7270186,41.4666667 14.4432853,41.7504 14.4432853,42.1 L14.4432853,42.7333333 L13.1766186,42.7333333 L13.1766186,42.1 C13.1766186,41.7504 12.8928853,41.4666667 12.5432853,41.4666667 C12.1936853,41.4666667 11.909952,41.7504 11.909952,42.1 L11.909952,42.7333333 L10.6432853,42.7333333 L10.6432853,42.1 C10.6432853,41.7504 10.359552,41.4666667 10.009952,41.4666667 C9.66035196,41.4666667 9.37661862,41.7504 9.37661862,42.1 L9.37661862,42.7333333 L8.10995196,42.7333333 L8.10995196,42.1 C8.10995196,41.7504 7.82621862,41.4666667 7.47661862,41.4666667 C7.12701862,41.4666667 6.84328529,41.7504 6.84328529,42.1 L6.84328529,42.7333333 L5.57661862,42.7333333 L5.57661862,42.1 C5.57661862,41.7504 5.29288529,41.4666667 4.94328529,41.4666667 C4.59368529,41.4666667 4.30995196,41.7504 4.30995196,42.1 L4.30995196,42.7333333 L3.67661862,42.7333333 C3.32701862,42.7333333 3.04328529,43.0170667 3.04328529,43.3666667 C3.04328529,43.7162667 3.32701862,44 3.67661862,44 L26.4766186,44 C26.8262186,44 27.109952,43.7162667 27.109952,43.3666667 C27.109952,43.0170667 26.8262186,42.7333333 26.4766186,42.7333333 L26.4766186,42.7333333 Z M16.9766186,39.5666667 L16.9766186,37.0333333 C16.9766186,36.6837333 16.6928853,36.4 16.3432853,36.4 C15.9936853,36.4 15.709952,36.6837333 15.709952,37.0333333 L15.709952,39.5666667 C15.709952,39.9162667 15.9936853,40.2 16.3432853,40.2 C16.6928853,40.2 16.9766186,39.9162667 16.9766186,39.5666667 L16.9766186,39.5666667 Z M22.6766186,40.2 C23.0262186,40.2 23.309952,39.9162667 23.309952,39.5666667 L23.309952,37.0333333 C23.309952,36.6837333 23.0262186,36.4 22.6766186,36.4 C22.3270186,36.4 22.0432853,36.6837333 22.0432853,37.0333333 L22.0432853,39.5666667 C22.0432853,39.9162667 22.3270186,40.2 22.6766186,40.2 L22.6766186,40.2 Z M35.9766186,42.7333333 L35.9766186,43.3666667 C35.9766186,43.7162667 35.6928853,44 35.3432853,44 L30.2766186,44 C29.9270186,44 29.6432853,43.7162667 29.6432853,43.3666667 L29.6432853,42.7333333 C29.6432853,41.3362 30.7794853,40.2 32.1766186,40.2 L33.4432853,40.2 C34.8404186,40.2 35.9766186,41.3362 35.9766186,42.7333333 L35.9766186,42.7333333 Z M34.709952,42.7333333 C34.709952,42.0347667 34.141852,41.4666667 33.4432853,41.4666667 L32.1766186,41.4666667 C31.478052,41.4666667 30.909952,42.0347667 30.909952,42.7333333 L34.709952,42.7333333 L34.709952,42.7333333 Z M22.6766186,26.2666667 C23.0262186,26.2666667 23.309952,25.9829333 23.309952,25.6333333 L23.309952,11.8817667 L25.8432853,7.82843333 L27.8674186,11.0666667 L25.209952,11.0666667 C24.860352,11.0666667 24.5766186,11.3504 24.5766186,11.7 C24.5766186,12.0496 24.860352,12.3333333 25.209952,12.3333333 L29.009952,12.3333333 C29.2404853,12.3333333 29.4520186,12.2085667 29.5641186,12.0071667 C29.6755853,11.8057667 29.669252,11.5594 29.5470186,11.3643333 L26.380352,6.29766667 C26.148552,5.92716667 25.5380186,5.92716667 25.3062186,6.29766667 L22.139552,11.3643333 C22.076852,11.4650333 22.0432853,11.5809333 22.0432853,11.7 L22.0432853,25.6333333 C22.0432853,25.9829333 22.3270186,26.2666667 22.6766186,26.2666667 L22.6766186,26.2666667 Z M10.009952,26.2666667 L13.809952,26.2666667 C14.159552,26.2666667 14.4432853,25.9829333 14.4432853,25.6333333 C14.4432853,25.2837333 14.159552,25 13.809952,25 L10.6432853,25 L10.6432853,23.7333333 L11.2766186,23.7333333 C11.6262186,23.7333333 11.909952,23.4496 11.909952,23.1 C11.909952,22.7504 11.6262186,22.4666667 11.2766186,22.4666667 L10.6432853,22.4666667 L10.6432853,21.2 L11.2766186,21.2 C11.6262186,21.2 11.909952,20.9162667 11.909952,20.5666667 C11.909952,20.2170667 11.6262186,19.9333333 11.2766186,19.9333333 L10.6432853,19.9333333 L10.6432853,18.6666667 L13.809952,18.6666667 C14.159552,18.6666667 14.4432853,18.3829333 14.4432853,18.0333333 C14.4432853,17.6837333 14.159552,17.4 13.809952,17.4 L10.6432853,17.4 L10.6432853,16.1333333 L11.2766186,16.1333333 C11.6262186,16.1333333 11.909952,15.8496 11.909952,15.5 C11.909952,15.1504 11.6262186,14.8666667 11.2766186,14.8666667 L10.6432853,14.8666667 L10.6432853,13.6 L11.2766186,13.6 C11.6262186,13.6 11.909952,13.3162667 11.909952,12.9666667 C11.909952,12.6170667 11.6262186,12.3333333 11.2766186,12.3333333 L10.6432853,12.3333333 L10.6432853,11.0666667 L13.809952,11.0666667 C14.159552,11.0666667 14.4432853,10.7829333 14.4432853,10.4333333 C14.4432853,10.0837333 14.159552,9.8 13.809952,9.8 L10.6432853,9.8 L10.6432853,7.26666667 L19.509952,7.26666667 L19.509952,25.6333333 C19.509952,25.9829333 19.7936853,26.2666667 20.1432853,26.2666667 C20.4928853,26.2666667 20.7766186,25.9829333 20.7766186,25.6333333 L20.7766186,6.63333333 C20.7766186,6.28373333 20.4928853,6 20.1432853,6 L10.009952,6 C9.66035196,6 9.37661862,6.28373333 9.37661862,6.63333333 L9.37661862,25.6333333 C9.37661862,25.9829333 9.66035196,26.2666667 10.009952,26.2666667 L10.009952,26.2666667 Z M29.009952,13.6 C28.660352,13.6 28.3766186,13.8837333 28.3766186,14.2333333 L28.3766186,25.6333333 C28.3766186,25.9829333 28.660352,26.2666667 29.009952,26.2666667 C29.359552,26.2666667 29.6432853,25.9829333 29.6432853,25.6333333 L29.6432853,14.2333333 C29.6432853,13.8837333 29.359552,13.6 29.009952,13.6 L29.009952,13.6 Z M25.209952,14.2333333 L25.209952,25.6333333 C25.209952,25.9829333 25.4936853,26.2666667 25.8432853,26.2666667 C26.1928853,26.2666667 26.4766186,25.9829333 26.4766186,25.6333333 L26.4766186,14.2333333 C26.4766186,13.8837333 26.1928853,13.6 25.8432853,13.6 C25.4936853,13.6 25.209952,13.8837333 25.209952,14.2333333 L25.209952,14.2333333 Z" id="design-skills"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/cpp_python.svg b/sources/pyside6/doc/images/cpp_python.svg
new file mode 100644
index 000000000..163df9ee0
--- /dev/null
+++ b/sources/pyside6/doc/images/cpp_python.svg
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="38px"
+ height="38px"
+ viewBox="0 0 38 38"
+ version="1.1"
+ id="svg22"
+ sodipodi:docname="cpp_python.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <sodipodi:namedview
+ id="namedview24"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="11.381579"
+ inkscape:cx="14.057803"
+ inkscape:cy="17.528324"
+ inkscape:window-width="1920"
+ inkscape:window-height="1062"
+ inkscape:window-x="0"
+ inkscape:window-y="18"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="chat-dialog" />
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title
+ id="title2">chat-dialog</title>
+ <desc
+ id="desc4">Created with Sketch.</desc>
+ <defs
+ id="defs13">
+ <linearGradient
+ x1="100%"
+ y1="100%"
+ x2="-22.8515625%"
+ y2="-33.2356771%"
+ id="linearGradient-1">
+ <stop
+ stop-color="#6FFF80"
+ offset="0%"
+ id="stop6" />
+ <stop
+ stop-color="#43CE57"
+ offset="37.2587344%"
+ id="stop8" />
+ <stop
+ stop-color="#425FD0"
+ offset="100%"
+ id="stop10" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient-1"
+ id="linearGradient4458"
+ x1="1"
+ y1="1"
+ x2="-0.22851562"
+ y2="-0.33235675"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(145.49943,77.584003)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient-1"
+ id="linearGradient11948"
+ x1="1"
+ y1="1"
+ x2="-0.22851562"
+ y2="-0.33235675"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(144.59116,75.64207)" />
+ </defs>
+ <g
+ id="Mainpage"
+ stroke="none"
+ stroke-width="1"
+ fill="none"
+ fill-rule="evenodd">
+ <g
+ id="Mainpage_Layout_V4_Megamenu"
+ transform="translate(-882.000000, -7064.000000)"
+ fill="url(#linearGradient-1)">
+ <g
+ id="Content"
+ transform="translate(-44.000000, 1530.000000)">
+ <g
+ id="Buynow"
+ transform="translate(68.000000, 3932.000000)">
+ <g
+ transform="translate(712.000000, 1527.000000)"
+ id="chat-dialog">
+ <path
+ d="m 184,78.166667 v 11.4 c 0,1.7461 -1.4212,3.166666 -3.1673,3.166666 h -15.2 c -1.74547,0 -3.16603,-1.420566 -3.16603,-3.166666 V 82.6 c 0,-0.3496 0.28373,-0.633333 0.63333,-0.633333 0.3496,0 0.63333,0.283733 0.63333,0.633333 v 6.966667 c 0,1.047533 0.85184,1.9 1.89937,1.9 h 15.2 c 1.04753,0 1.90063,-0.852467 1.90063,-1.9 v -11.4 c 0,-1.047534 -0.8531,-1.9 -1.90063,-1.9 h -20.0032 l 3.98557,3.985566 c 0.24763,0.247634 0.24763,0.6479 0,0.895534 -0.24764,0.247633 -0.6479,0.247633 -0.89554,0 L 158.85223,76.0811 C 158.6711,75.899967 158.61663,75.627633 158.7148,75.390767 158.81297,75.154533 159.04413,75 159.3,75 h 21.5327 C 182.5788,75 184,76.420567 184,78.166667 Z m -13.3,17.1 h -21.7664 c -1.61753,0 -2.9336,1.420566 -2.9336,3.166666 v 11.399997 c 0,1.7461 1.31607,3.16667 2.9336,3.16667 h 15.3995 c 1.70493,0 3.20023,-1.47947 3.20023,-3.16983 v -6.96604 c -0.002,-0.34896 -0.285,-0.6308 -0.63333,-0.6308 h -0.003 c -0.3496,0.002 -0.63206,0.2869 -0.63016,0.6365 v 6.9635 c 0,1.07034 -1.0393,1.9 -1.93357,1.9 h -15.3995 c -0.91897,0 -1.66693,-0.85246 -1.66693,-1.9 V 98.433333 c 0,-1.047533 0.74796,-1.9 1.66693,-1.9 h 20.2445 l -3.96087,3.986837 c -0.24636,0.24826 -0.2451,0.64916 0.003,0.89553 0.24827,0.247 0.64917,0.24573 0.89553,-0.003 l 5.0331,-5.06667 c 0.1805,-0.181767 0.2337,-0.453467 0.13554,-0.6897 -0.0975,-0.236233 -0.3287,-0.390133 -0.58457,-0.390133 z M 146,81.333333 v -1.266666 c 0,-0.468034 0.25523,-0.877167 0.63333,-1.0963 V 78.8 c 0,-2.0957 1.7043,-3.8 3.8,-3.8 h 2.53334 c 2.0957,0 3.8,1.7043 3.8,3.8 v 0.170367 c 0.3781,0.219133 0.63333,0.628266 0.63333,1.0963 v 1.266666 c 0,0.477534 -0.266,0.8949 -0.65803,1.110234 -0.12034,1.217266 -0.6498,2.288866 -0.67577,2.339533 -0.5738,1.148233 -1.44147,2.883567 -4.3662,2.883567 -2.92473,0 -3.7924,-1.735334 -4.36683,-2.883567 -0.0253,-0.05067 -0.55417,-1.122267 -0.67514,-2.339533 C 146.266,82.228233 146,81.810867 146,81.333333 Z m 1.26667,0 c 0.3496,0 0.63333,0.283734 0.63333,0.633334 0,1.095666 0.56113,2.239466 0.56683,2.250866 C 149.1255,85.5355 149.7069,86.4 151.7,86.4 c 1.99247,0 2.5745,-0.8645 3.23317,-2.1831 0.006,-0.01077 0.56683,-1.154567 0.56683,-2.250233 0,-0.3496 0.28373,-0.633334 0.63333,-0.633334 v -1.266666 c -0.3496,0 -0.63333,-0.283734 -0.63333,-0.633334 V 78.8 c 0,-1.397133 -1.1362,-2.533333 -2.53333,-2.533333 h -2.53334 c -1.39713,0 -2.53333,1.1362 -2.53333,2.533333 v 0.633333 c 0,0.3496 -0.28373,0.633334 -0.63333,0.633334 z m 5.7,0 H 153.6 c 0.3496,0 0.63333,-0.283733 0.63333,-0.633333 0,-0.3496 -0.28373,-0.633333 -0.63333,-0.633333 h -0.63333 c -0.3496,0 -0.63334,0.283733 -0.63334,0.633333 0,0.3496 0.28374,0.633333 0.63334,0.633333 z m -3.16667,0 h 0.63333 c 0.3496,0 0.63334,-0.283733 0.63334,-0.633333 0,-0.3496 -0.28374,-0.633333 -0.63334,-0.633333 H 149.8 c -0.3496,0 -0.63333,0.283733 -0.63333,0.633333 0,0.3496 0.28373,0.633333 0.63333,0.633333 z M 184,100.33333 V 101.6 c 0,0.47753 -0.266,0.8949 -0.6574,1.11023 -0.12097,1.21727 -0.65043,2.28887 -0.6764,2.33954 -0.5738,1.14823 -1.44147,2.88356 -4.3662,2.88356 -2.92473,0 -3.7924,-1.73533 -4.36683,-2.88356 -0.0253,-0.0507 -0.5548,-1.12227 -0.67577,-2.33954 C 172.866,102.4949 172.6,102.07753 172.6,101.6 v -1.26667 c 0,-0.46803 0.2546,-0.877163 0.63333,-1.096297 v -0.170366 c 0,-2.0957 1.7043,-3.8 3.8,-3.8 h 2.53334 c 2.0957,0 3.8,1.7043 3.8,3.8 v 0.170366 C 183.7454,99.456167 184,99.8653 184,100.33333 Z m -1.26667,0 C 182.3831,100.33333 182.1,100.0496 182.1,99.7 v -0.633333 c 0,-1.397134 -1.1362,-2.533334 -2.53333,-2.533334 h -2.53334 c -1.39713,0 -2.53333,1.1362 -2.53333,2.533334 V 99.7 c 0,0.3496 -0.2831,0.63333 -0.63333,0.63333 V 101.6 c 0.35023,0 0.63333,0.28373 0.63333,0.63333 0,1.09567 0.56113,2.23947 0.56683,2.25087 0.65867,1.31797 1.24007,2.18247 3.23317,2.18247 1.9931,0 2.5745,-0.8645 3.23317,-2.1831 0.006,-0.0108 0.56683,-1.15457 0.56683,-2.25024 0,-0.3496 0.2831,-0.63333 0.63333,-0.63333 z m -2.53333,0 h -0.63333 c -0.35024,0 -0.63334,0.28374 -0.63334,0.63334 0,0.3496 0.2831,0.63333 0.63334,0.63333 H 180.2 c 0.35023,0 0.63333,-0.28373 0.63333,-0.63333 0,-0.3496 -0.2831,-0.63334 -0.63333,-0.63334 z m -3.16667,0 H 176.4 c -0.35023,0 -0.63333,0.28374 -0.63333,0.63334 0,0.3496 0.2831,0.63333 0.63333,0.63333 h 0.63333 c 0.35024,0 0.63334,-0.28373 0.63334,-0.63333 0,-0.3496 -0.2831,-0.63334 -0.63334,-0.63334 z"
+ id="path15"
+ sodipodi:nodetypes="ssssssssssssssccscccsssssssssscsccssssssccccccssscsssscssccsccscscscsccssssssccssssssssssssssssccsccsscsssscscssssssccscscsccssssssssssssss" />
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-weight:bold;font-size:8px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold Italic';letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4458)"
+ x="149.47179"
+ y="107.35308"
+ id="text4456"><tspan
+ sodipodi:role="line"
+ id="tspan4454"
+ x="149.47179"
+ y="107.35308"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:8px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Semi-Bold';fill:url(#linearGradient4458)">C++</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-weight:bold;font-size:5.33333px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold Italic';letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient11948)"
+ x="164.67328"
+ y="85.527855"
+ id="text11946"><tspan
+ sodipodi:role="line"
+ id="tspan11944"
+ x="164.67328"
+ y="85.527855"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.33333px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:url(#linearGradient11948)">Python</tspan></text>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+ <metadata
+ id="metadata841">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title>chat-dialog</dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/sources/pyside6/doc/images/linux.svg b/sources/pyside6/doc/images/linux.svg
new file mode 100644
index 000000000..af05345a2
--- /dev/null
+++ b/sources/pyside6/doc/images/linux.svg
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.0"
+ viewBox="0 0 266 312"
+ id="svg4"
+ sodipodi:docname="linux.svg"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ id="namedview6"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="2.7916667"
+ inkscape:cx="119.46269"
+ inkscape:cy="156.35821"
+ inkscape:window-width="2552"
+ inkscape:window-height="1432"
+ inkscape:window-x="1924"
+ inkscape:window-y="4"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4" />
+ <path
+ d="M128.6640625 79.2793c0 1-1 1-1 1h-1c-1 0-1-1-2-2 0 0-1-1-1-2s0-1 1-1l2 1c1 1 2 2 2 3m-18-10c0-5-2-8-5-8 0 0 0 1-1 1v2h3c0 2 1 3 1 5h2m35-5c2 0 3 2 4 5h2c-1-1-1-2-1-3s0-2-1-3-2-2-3-2c0 0-1 1-2 1 0 1 1 1 1 2m-30 16c-1 0-1 0-1-1s0-2 1-3c2 0 3-1 3-1 1 0 1 1 1 1 0 1-1 2-3 4h-1m-11-1c-4-2-5-5-5-10 0-3 0-5 2-7 1-2 3-3 5-3s3 1 5 3c1 3 2 6 2 9v2h1v-1c1 0 1-2 1-6 0-3 0-6-2-9s-4-5-8-5c-3 0-6 2-7 5-2 4-2.4 7-2.4 12 0 4 1.4 8 5.4 12 1-1 2-1 3-2m125 141c1 0 1-.4 1-1.3 0-2.2-1-4.8-4-7.7-3-3-8-4.9-14-5.7-1-.1-2-.1-2-.1-1-.2-1-.2-2-.2-1-.1-3-.3-4-.5 3-9.3 4-17.5 4-24.7 0-10-2-17-6-23s-8-9-13-10c-1 1-1 1-1 2 5 2 10 6 13 12 3 7 4 13 4 20 0 5.6-1 13.9-5 24.5-4 1.6-8 5.3-11 11.1 0 .9 0 1.4 1 1.4 0 0 1-.9 2-2.6 2-1.7 3-3.4 5-5.1 3-1.7 5-2.6 8-2.6 5 0 10 .7 13 2.1 4 1.3 6 2.7 7 4.3 1 1.5 2 2.9 3 4.2 0 1.3 1 1.9 1 1.9m-92-145c-1-1-1-3-1-5 0-4 0-6 2-9 2-2 4-3 6-3 3 0 5 2 7 4 1 3 2 5 2 8 0 5-2 8-6 9 0 0 1 1 2 1 2 0 3 1 5 2 1-6 2-10 2-15 0-6-1-10-3-13-3-3-6-4-10-4-3 0-6 1-9 3-2 3-3 5-3 8 0 5 1 9 3 13 1 0 2 1 3 1m12 16c-13 9-23 13-31 13-7 0-14-3-20-8 1 2 2 4 3 5l6 6c4 4 9 6 14 6 7 0 15-4 25-11l9-6c2-2 4-4 4-7 0-1 0-2-1-2-1-2-6-5-16-8-9-4-16-6-20-6-3 0-8 2-15 6-6 4-10 8-10 12 0 0 1 1 2 3 6 5 12 8 18 8 8 0 18-4 31-14v2c1 0 1 1 1 1m23 202c4 7.52 11 11.3 19 11.3 2 0 4-.3 6-.9 2-.4 4-1.1 5-1.9 1-.7 2-1.4 3-2.2 2-.7 2-1.2 3-1.7l17-14.7c4-3.19 8-5.98 13-8.4 4-2.4 8-4 10-4.9 3-.8 5-2 7-3.6 1-1.5 2-3.4 2-5.8 0-2.9-2-5.1-4-6.7s-4-2.7-6-3.4-4-2.3-7-5c-2-2.6-4-6.2-5-10.9l-1-5.8c-1-2.7-1-4.7-2-5.8 0-.3 0-.4-1-.4s-3 .9-4 2.6c-2 1.7-4 3.6-6 5.6-1 2-4 3.8-6 5.5-3 1.7-6 2.6-8 2.6-8 0-12-2.2-15-6.5-2-3.2-3-6.9-4-11.1-2-1.7-3-2.6-5-2.6-5 0-7 5.2-7 15.7v31.1c0 .9-1 2.9-1 6-1 3.1-1 6.62-1 10.6l-2 11.1v.17m-145-5.29c9.3 1.36 20 4.27 32.1 8.71 12.1 4.4 19.5 6.7 22.2 6.7 7 0 12.8-3.1 17.6-9.09 1-1.94 1-4.22 1-6.84 0-9.45-5.7-21.4-17.1-35.9l-6.8-9.1c-1.4-1.9-3.1-4.8-5.3-8.7-2.1-3.9-4-6.9-5.5-9-1.3-2.3-3.4-4.6-6.1-6.9-2.6-2.3-5.6-3.8-8.9-4.6-4.2.8-7.1 2.2-8.5 4.1s-2.2 4-2.4 6.2c-.3 2.1-.9 3.5-1.9 4.2-1 .6-2.7 1.1-5 1.6-.5 0-1.4 0-2.7.1h-2.7c-5.3 0-8.9.6-10.8 1.6-2.5 2.9-3.8 6.2-3.8 9.7 0 1.6.4 4.3 1.2 8.1.8 3.7 1.2 6.7 1.2 8.8 0 4.1-1.2 8.2-3.7 12.3-2.5 4.3-3.8 7.5-3.8 9.78 1 3.88 7.6 6.61 19.7 8.21m33.3-90.9c0-6.9 1.8-14.5 5.5-23.5 3.6-9 7.2-15 10.7-19-.2-1-.7-1-1.5-1l-1-1c-2.9 3-6.4 10-10.6 20-4.2 9-6.4 17.3-6.4 23.4 0 4.5 1.1 8.4 3.1 11.8 2.2 3.3 7.5 8.1 15.9 14.2l10.6 6.9c11.3 9.8 17.3 16.6 17.3 20.6 0 2.1-1 4.2-4 6.5-2 2.4-4.7 3.6-7 3.6-.2 0-.3.2-.3.7 0 .1 1 2.1 3.1 6 4.2 5.7 13.2 8.5 25.2 8.5 22 0 39-9 52-27 0-5 0-8.1-1-9.4v-3.7c0-6.5 1-11.4 3-14.6s4-4.7 7-4.7c2 0 4 .7 6 2.2 1-7.7 1-14.4 1-20.4 0-9.1 0-16.6-2-23.6-1-6-3-11-5-15l-6-9c-2-3-3-6-5-9-1-4-2-7-2-12-3-5-5-10-8-15-2-5-4-10-6-14l-9 7c-10 7-18 10-25 10-6 0-11-1-14-5l-6-5c0 3-1 7-3 11l-6.3 12c-2.8 7-4.3 11-4.6 14-.4 2-.7 4-.9 4l-7.5 15c-8.1 15-12.2 28.9-12.2 40.4 0 2.3.2 4.7.6 7.1-4.5-3.1-6.7-7.4-6.7-13m71.6 94.6c-13 0-23 1.76-30 5.25v-.3c-5 6-10.6 9.1-18.4 9.1-4.9 0-12.6-1.9-23-5.7-10.5-3.6-19.8-6.36-27.9-8.18-.8-.23-2.6-.57-5.5-1.03-2.8-.45-5.4-.91-7.7-1.37-2.1-.45-4.5-1.13-7.1-2.05-2.5-.79-4.5-1.82-6-3.07-1.38-1.26-2.06-2.68-2.06-4.27 0-1.6.34-3.31 1.02-5.13.64-1.1 1.34-2.2 2.04-3.2.7-1.1 1.3-2.1 1.7-3.1.6-.9 1-1.8 1.4-2.8.4-.9.8-1.8 1-2.9.2-1 .4-2 .4-3s-.4-4-1.2-9.3c-.8-5.2-1.2-8.5-1.2-9.9 0-4.4 1-7.9 3.2-10.4s4.3-3.8 6.5-3.8h11.5c.9 0 2.3-.5 4.4-1.7.7-1.6 1.3-2.9 1.7-4.1.5-1.2.7-2.1.9-2.5.2-.6.4-1.2.6-1.7.4-.7.9-1.5 1.6-2.3-.8-1-1.2-2.3-1.2-3.9 0-1.1 0-2.1.2-2.7 0-3.6 1.7-8.7 5.3-15.4l3.5-6.3c2.9-5.4 5.1-9.4 6.7-13.4 1.7-4 3.5-10 5.5-18 1.6-7 5.4-14 11.4-21l7.5-9c5.2-6 8.6-11 10.5-15s2.9-9 2.9-13c0-2-.5-8-1.6-18-1-10-1.5-20-1.5-29 0-7 .6-12 1.9-17s3.6-10 7-14c3-4 7-8 13-10s13-3 21-3c3 0 6 0 9 1 3 0 7 1 12 3 4 2 8 4 11 7 4 3 7 8 10 13 2 6 4 12 5 20 1 5 1 10 2 17 0 6 1 10 1 13 1 3 1 7 2 12 1 4 2 8 4 11 2 4 4 8 7 12 3 5 7 10 11 16 9 10 16 21 20 32 5 10 8 23 8 36.9 0 6.9-1 13.6-3 20.1 2 0 3 .8 4 2.2s2 4.4 3 9.1l1 7.4c1 2.2 2 4.3 5 6.1 2 1.8 4 3.3 7 4.5 2 1 5 2.4 7 4.2 2 2 3 4.1 3 6.3 0 3.4-1 5.9-3 7.7-2 2-4 3.4-7 4.3-2 1-6 3-12 5.82-5 2.96-10 6.55-15 10.8l-10 8.51c-4 3.9-8 6.7-11 8.4-3 1.8-7 2.7-11 2.7l-7-.8c-8-2.1-13-6.1-16-12.2-16-1.94-29-2.9-37-2.9"
+ id="path2"
+ style="fill:#53586b;fill-opacity:1" />
+</svg>
diff --git a/sources/pyside6/doc/images/macos.svg b/sources/pyside6/doc/images/macos.svg
new file mode 100644
index 000000000..01b8cb002
--- /dev/null
+++ b/sources/pyside6/doc/images/macos.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ viewBox="0 0 4875 4875"
+ version="1.1"
+ id="svg4"
+ sodipodi:docname="macOS.svg"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ id="namedview6"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="0.17866667"
+ inkscape:cx="2056.9029"
+ inkscape:cy="2443.097"
+ inkscape:window-width="1920"
+ inkscape:window-height="1080"
+ inkscape:window-x="1920"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4" />
+ <path
+ fill="#666"
+ d="m 4217.2809,3659.1573 c -67.1033,155.0227 -146.5318,297.7206 -238.5597,428.9145 -125.4425,178.8514 -228.1514,302.6507 -307.3064,371.3978 -122.7033,112.843 -254.1713,170.6343 -394.952,173.9209 -101.0661,0 -222.9479,-28.7587 -364.8238,-87.0974 -142.3418,-58.0655 -273.1524,-86.8235 -392.7608,-86.8235 -125.4424,0 -259.9782,28.758 -403.8809,86.8235 -144.1218,58.3387 -260.2248,88.7411 -348.9927,91.7538 -135.0014,5.7518 -269.5646,-53.6831 -403.8809,-178.5773 -85.7283,-74.7731 -192.9569,-202.9541 -321.4121,-384.5447 C 902.88949,3881.0097 789.58031,3656.1447 700.81195,3399.782 605.74429,3122.8775 558.08701,2854.7371 558.08701,2595.1424 c 0,-297.3638 64.25482,-553.8363 192.95678,-768.7591 101.14827,-172.6342 235.71135,-308.8131 404.12711,-408.7836 168.4162,-99.9703 350.3899,-150.914 546.3595,-154.1734 107.2285,0 247.8447,33.1682 422.5877,98.3545 174.25,65.4052 286.1345,98.5736 335.1882,98.5736 36.6747,0 160.9663,-38.7834 371.6716,-116.1026 199.256,-71.705 367.4256,-101.3949 505.1932,-89.7 373.3149,30.1284 653.78,177.2902 840.3002,442.4178 -333.8741,202.2962 -499.0309,485.6375 -495.7444,849.1192 3.0132,283.1218 105.7221,518.7232 307.5803,705.7915 91.4803,86.8235 193.6417,153.9273 307.3064,201.5844 -24.6494,71.4857 -50.6695,139.9584 -78.3327,205.6926 z M 3361.0953,290.01478 c 0,221.90982 -81.0722,429.10615 -242.6678,620.88525 -195.0111,227.98777 -430.8867,359.72937 -686.6746,338.94127 -3.2589,-26.6223 -5.1489,-54.6418 -5.1489,-84.085 0,-213.03328 92.7396,-441.02035 257.431,-627.43123 82.222,-94.38292 186.794,-172.86107 313.606,-235.46509 126.5378,-61.66949 246.2285,-95.77377 358.7983,-101.61416 3.2866,29.66615 4.656,59.3338 4.656,88.76593 z"
+ id="path2"
+ style="fill:#53586b;fill-opacity:1;stroke-width:4.43719" />
+</svg>
diff --git a/sources/pyside6/doc/images/screenshot_hello.png b/sources/pyside6/doc/images/screenshot_hello.png
new file mode 100644
index 000000000..41ebbf01b
--- /dev/null
+++ b/sources/pyside6/doc/images/screenshot_hello.png
Binary files differ
diff --git a/sources/pyside6/doc/images/stopwatch.svg b/sources/pyside6/doc/images/stopwatch.svg
new file mode 100644
index 000000000..12f313ae6
--- /dev/null
+++ b/sources/pyside6/doc/images/stopwatch.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="49px" height="48px" viewBox="0 0 49 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
+ <title>stopwatch</title>
+ <desc>Created with Sketch.</desc>
+ <defs>
+ <linearGradient x1="100%" y1="100%" x2="-22.8515625%" y2="-33.2356771%" id="linearGradient-1">
+ <stop stop-color="#6FFF80" offset="0%"></stop>
+ <stop stop-color="#43CE57" offset="37.2587344%"></stop>
+ <stop stop-color="#425FD0" offset="100%"></stop>
+ </linearGradient>
+ </defs>
+ <g id="Mainpage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Mainpage_Layout_V4_Megamenu" transform="translate(-695.000000, -1755.000000)" fill="url(#linearGradient-1)">
+ <g id="Content" transform="translate(-44.000000, 1530.000000)">
+ <g id="WhatQtis" transform="translate(194.000000, 0.000000)">
+ <g id="Block2" transform="translate(378.657594, 178.000000)">
+ <path d="M189.4002,50.2 C177.049,50.2 167.0002,60.2488 167.0002,72.6 C167.0002,73.4096 167.0474,74.2464 167.141,75.088 C167.1898,75.5272 167.5882,75.84 168.0242,75.7952 C168.4634,75.7464 168.7802,75.3504 168.7314,74.912 C168.6442,74.128 168.6002,73.3504 168.6002,72.6 C168.6002,61.1312 177.9314,51.8 189.4002,51.8 C200.8698,51.8 210.2002,61.1312 210.2002,72.6 C210.2002,84.0688 200.8698,93.4 189.4002,93.4 C185.5434,93.4 181.7762,92.3344 178.5058,90.3192 C178.1306,90.0864 177.637,90.204 177.405,90.58 C177.173,90.956 177.2906,91.4496 177.6666,91.6808 C181.189,93.852 185.2466,95 189.4002,95 C201.7514,95 211.8002,84.9512 211.8002,72.6 C211.8002,60.2488 201.7514,50.2 189.4002,50.2 L189.4002,50.2 Z M186.2002,87.8 C186.2002,87.3584 185.8418,87 185.4002,87 L171.0002,87 C170.5586,87 170.2002,87.3584 170.2002,87.8 C170.2002,88.2416 170.5586,88.6 171.0002,88.6 L185.4002,88.6 C185.8418,88.6 186.2002,88.2416 186.2002,87.8 L186.2002,87.8 Z M181.4002,83 C181.4002,82.5584 181.0418,82.2 180.6002,82.2 L167.8002,82.2 C167.3586,82.2 167.0002,82.5584 167.0002,83 C167.0002,83.4416 167.3586,83.8 167.8002,83.8 L180.6002,83.8 C181.0418,83.8 181.4002,83.4416 181.4002,83 L181.4002,83 Z M168.6002,78.2 C168.6002,78.6416 168.9586,79 169.4002,79 L175.8002,79 C176.2418,79 176.6002,78.6416 176.6002,78.2 C176.6002,77.7584 176.2418,77.4 175.8002,77.4 L169.4002,77.4 C168.9586,77.4 168.6002,77.7584 168.6002,78.2 L168.6002,78.2 Z M189.4002,71 C188.5178,71 187.8002,71.7176 187.8002,72.6 C187.8002,73.4824 188.5178,74.2 189.4002,74.2 C190.2826,74.2 191.0002,73.4824 191.0002,72.6 C191.0002,71.7176 190.2826,71 189.4002,71 L189.4002,71 Z M176.9426,59.0304 L187.7842,69.8536 C188.2602,69.5728 188.8082,69.4 189.4002,69.4 C191.165,69.4 192.6002,70.8352 192.6002,72.6 C192.6002,74.3648 191.165,75.8 189.4002,75.8 C187.6354,75.8 186.2002,74.3648 186.2002,72.6 C186.2002,72.0088 186.3722,71.4608 186.653,70.9848 L175.8122,60.1624 C175.5002,59.8504 175.4994,59.344 175.8114,59.0312 C176.1234,58.7168 176.6298,58.7168 176.9426,59.0304 L176.9426,59.0304 Z M193.1778,89.8096 L193.385,90.5816 C193.4818,90.9384 193.805,91.1736 194.157,91.1736 C194.2258,91.1736 194.2962,91.1648 194.3658,91.1464 C194.7922,91.0312 195.0458,90.592 194.9306,90.1656 L194.7226,89.3936 C194.6082,88.9672 194.1674,88.7128 193.7426,88.8288 C193.3162,88.944 193.0626,89.3832 193.1778,89.8096 L193.1778,89.8096 Z M197.5034,88.2448 L197.9042,88.9368 C198.0522,89.1928 198.3202,89.336 198.597,89.336 C198.733,89.336 198.8714,89.3008 198.997,89.228 C199.3802,89.0072 199.5106,88.5176 199.2882,88.1352 L198.8874,87.4432 C198.6658,87.0608 198.1762,86.9304 197.7946,87.1512 C197.4122,87.3728 197.2818,87.8624 197.5034,88.2448 L197.5034,88.2448 Z M201.2754,85.6128 L201.8418,86.1784 C201.9978,86.3344 202.2026,86.4128 202.4074,86.4128 C202.6122,86.4128 202.817,86.3344 202.9738,86.1776 C203.285,85.8656 203.285,85.3584 202.973,85.0464 L202.4066,84.4808 C202.0938,84.1688 201.5866,84.168 201.2746,84.4816 C200.9626,84.7944 200.9626,85.3008 201.2754,85.6128 L201.2754,85.6128 Z M205.0386,80.7096 C204.6554,80.4888 204.1666,80.6192 203.9458,81.0024 C203.7242,81.3848 203.8554,81.8744 204.2386,82.0952 L204.9314,82.4952 C205.057,82.568 205.1946,82.6024 205.3306,82.6024 C205.6074,82.6024 205.8762,82.4592 206.0242,82.2024 C206.2458,81.8192 206.1146,81.3304 205.7314,81.1096 L205.0386,80.7096 Z M206.9634,78.1376 C207.033,78.156 207.1026,78.1656 207.1714,78.1656 C207.5242,78.1656 207.8482,77.9296 207.9434,77.572 C208.057,77.1448 207.8042,76.7064 207.3778,76.592 L206.6042,76.3848 C206.1794,76.2704 205.7386,76.524 205.6242,76.9504 C205.5106,77.3776 205.7634,77.8168 206.1898,77.9304 L206.9634,78.1376 Z M204.6018,73.4024 L207.8002,73.4024 C208.2426,73.4024 208.6002,73.044 208.6002,72.6024 C208.6002,72.1608 208.2426,71.8024 207.8002,71.8024 L204.6018,71.8024 C204.1594,71.8024 203.8018,72.1608 203.8018,72.6024 C203.8018,73.044 204.1594,73.4024 204.6018,73.4024 L204.6018,73.4024 Z M205.6258,68.2536 C205.721,68.6112 206.045,68.8472 206.3978,68.8472 C206.4666,68.8472 206.5362,68.8384 206.6058,68.8192 L207.3794,68.6128 C207.8058,68.4984 208.0586,68.06 207.945,67.6328 C207.8306,67.2064 207.3914,66.9528 206.965,67.0672 L206.1914,67.2744 C205.765,67.388 205.5122,67.8272 205.6258,68.2536 L205.6258,68.2536 Z M204.9354,62.7088 L204.2418,63.1088 C203.8586,63.3296 203.7266,63.8184 203.9482,64.2008 C204.0954,64.4584 204.365,64.6016 204.6418,64.6016 C204.777,64.6016 204.9146,64.5672 205.0402,64.4944 L205.7338,64.0944 C206.117,63.8736 206.249,63.3848 206.0274,63.0016 C205.8074,62.6192 205.3186,62.4872 204.9354,62.7088 L204.9354,62.7088 Z M201.8442,60.956 C202.049,60.956 202.2522,60.8784 202.409,60.7224 L202.9762,60.1568 C203.289,59.8448 203.289,59.3384 202.9778,59.0256 C202.6658,58.7136 202.1594,58.712 201.8466,59.024 L201.2794,59.5896 C200.9658,59.9016 200.9658,60.408 201.2778,60.7208 C201.4338,60.8776 201.6386,60.956 201.8442,60.956 L201.8442,60.956 Z M184.8434,56.4008 C184.9114,56.4008 184.981,56.392 185.0498,56.3736 C185.4762,56.2608 185.7306,55.8224 185.617,55.3952 L185.4114,54.6224 C185.2978,54.196 184.8586,53.9408 184.433,54.0552 C184.0058,54.168 183.7514,54.6064 183.8658,55.0336 L184.0706,55.8064 C184.1666,56.1648 184.4898,56.4008 184.8434,56.4008 L184.8434,56.4008 Z M180.601,58.1584 C180.7362,58.1584 180.8738,58.124 181.0002,58.0512 C181.3826,57.8304 181.5138,57.3416 181.293,56.9584 L180.893,56.2656 C180.6714,55.8832 180.1826,55.7512 179.8002,55.9728 C179.4178,56.1936 179.2866,56.6832 179.5074,57.0656 L179.9074,57.7584 C180.0554,58.0152 180.3242,58.1584 180.601,58.1584 L180.601,58.1584 Z M197.7986,58.0504 C197.9242,58.124 198.0626,58.1584 198.1986,58.1584 C198.4746,58.1584 198.7434,58.016 198.8914,57.7592 L199.2922,57.0672 C199.5146,56.6848 199.3834,56.1952 199.001,55.9744 C198.6194,55.752 198.129,55.8832 197.9082,56.2656 L197.5074,56.9576 C197.285,57.34 197.4162,57.8296 197.7986,58.0504 L197.7986,58.0504 Z M193.7474,56.3728 C193.817,56.3912 193.8866,56.4 193.9554,56.4 C194.3082,56.4 194.6314,56.1648 194.7274,55.808 L194.9354,55.0352 C195.0498,54.6088 194.797,54.1696 194.3706,54.0544 C193.9466,53.9408 193.5058,54.1928 193.3898,54.6192 L193.1826,55.392 C193.0674,55.8184 193.3202,56.2576 193.7474,56.3728 L193.7474,56.3728 Z M188.6002,87.8 L188.6002,91 C188.6002,91.4416 188.9586,91.8 189.4002,91.8 C189.8418,91.8 190.2002,91.4416 190.2002,91 L190.2002,87.8 C190.2002,87.3584 189.8418,87 189.4002,87 C188.9586,87 188.6002,87.3584 188.6002,87.8 L188.6002,87.8 Z M190.2002,57.4 L190.2002,54.2 C190.2002,53.7584 189.8418,53.4 189.4002,53.4 C188.9586,53.4 188.6002,53.7584 188.6002,54.2 L188.6002,57.4 C188.6002,57.8416 188.9586,58.2 189.4002,58.2 C189.8418,58.2 190.2002,57.8416 190.2002,57.4 L190.2002,57.4 Z M168.9314,55.8 L169.4002,56.2688 L173.069,52.6 L172.6002,52.1312 L168.9314,55.8 Z M167.2346,56.3656 C166.9218,56.0528 166.9218,55.5472 167.2346,55.2344 L172.0346,50.4344 C172.3474,50.1216 172.853,50.1216 173.1658,50.4344 L174.7658,52.0344 C175.0786,52.3472 175.0786,52.8528 174.7658,53.1656 L169.9658,57.9656 C169.8098,58.1216 169.605,58.2 169.4002,58.2 C169.1954,58.2 168.9906,58.1216 168.8346,57.9656 L167.2346,56.3656 Z M187.0002,48.6 L191.8002,48.6 C192.2426,48.6 192.6002,48.2416 192.6002,47.8 C192.6002,47.3584 192.2426,47 191.8002,47 L187.0002,47 C186.5586,47 186.2002,47.3584 186.2002,47.8 C186.2002,48.2416 186.5586,48.6 187.0002,48.6 L187.0002,48.6 Z M207.2074,55.924 L210.7658,52.3656 C211.0786,52.0528 211.0786,51.5472 210.7658,51.2344 C210.453,50.9216 209.9474,50.9216 209.6346,51.2344 L206.0762,54.7928 C205.7634,55.1056 205.7634,55.612 206.0762,55.924 C206.2322,56.0808 206.437,56.1584 206.6418,56.1584 C206.8466,56.1584 207.0506,56.0808 207.2074,55.924 L207.2074,55.924 Z M215.0002,51.8 C215.0002,54.4472 212.8474,56.6 210.2002,56.6 C209.7578,56.6 209.4002,56.2416 209.4002,55.8 C209.4002,55.3584 209.7578,55 210.2002,55 C211.965,55 213.4002,53.5648 213.4002,51.8 C213.4002,50.0352 211.965,48.6 210.2002,48.6 C208.4354,48.6 207.0002,50.0352 207.0002,51.8 C207.0002,52.2416 206.6426,52.6 206.2002,52.6 C205.7578,52.6 205.4002,52.2416 205.4002,51.8 C205.4002,49.1528 207.553,47 210.2002,47 C212.8474,47 215.0002,49.1528 215.0002,51.8 L215.0002,51.8 Z" id="stopwatch"></path>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/sources/pyside6/doc/images/windows.svg b/sources/pyside6/doc/images/windows.svg
new file mode 100644
index 000000000..a40519bb0
--- /dev/null
+++ b/sources/pyside6/doc/images/windows.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ viewBox="0 0 4875 4875"
+ version="1.1"
+ id="svg4"
+ sodipodi:docname="windows.svg"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ id="namedview6"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="0.17866667"
+ inkscape:cx="2224.8134"
+ inkscape:cy="2437.5"
+ inkscape:window-width="2552"
+ inkscape:window-height="1432"
+ inkscape:window-x="1924"
+ inkscape:window-y="4"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4" />
+ <path
+ fill="#0078d4"
+ d="M0 0h2311v2310H0zm2564 0h2311v2310H2564zM0 2564h2311v2311H0zm2564 0h2311v2311H2564"
+ id="path2"
+ style="fill:#53586b;fill-opacity:1" />
+</svg>
diff --git a/sources/pyside6/doc/import_inheritance.py b/sources/pyside6/doc/import_inheritance.py
new file mode 100644
index 000000000..e694941c9
--- /dev/null
+++ b/sources/pyside6/doc/import_inheritance.py
@@ -0,0 +1,152 @@
+import inspect
+import sys
+
+"""Helpers for determining base classes by importing the class.
+When passed something like:
+ PySide6.QtCore.QStateMachine.SignalEvent
+try to import the underlying module and return a
+handle to the object. In a loop, import
+ PySide6.QtCore.QStateMachine.SignalEvent
+ PySide6.QtCore.QStateMachine
+ PySide6.QtCore
+until the import succeeds and walk up the attributes
+to obtain the object."""
+
+
+TEST_DRIVER_USAGE = """Usage: import_inheritance.py class_name [current_module]
+
+Example:
+python import_inheritance.py PySide6.QtWidgets.QWizard PySide6.QtWidgets
+"""
+
+
+class InheritanceException(Exception):
+ pass
+
+
+def _importClassOrModule(name):
+ components = name.split('.')
+ for i in range(len(components), 0, -1):
+ importPath = '.'.join(components[: i])
+ try:
+ __import__(importPath)
+ except ImportError:
+ continue
+ if i == len(components):
+ return sys.modules[importPath]
+ remaining = components[i:]
+ cls = sys.modules[importPath]
+ for component in remaining:
+ try:
+ cls = getattr(cls, component)
+ except Exception: # No such attribute
+ return None
+ return cls
+ return None
+
+
+def _import_class_or_module(name, currmodule):
+ """
+ Import a class using its fully-qualified *name*.
+ """
+ todoc = _importClassOrModule(name)
+ if not todoc and currmodule is not None:
+ todoc = _importClassOrModule(f"{currmodule}.{name}")
+ if not todoc:
+ moduleStr = f'(module {currmodule})' if currmodule else ''
+ raise InheritanceException(f'Could not import class {name} specified for '
+ f'inheritance diagram {moduleStr}.')
+ if inspect.isclass(todoc):
+ return [todoc]
+ elif inspect.ismodule(todoc):
+ classes = []
+ for cls in todoc.__dict__.values():
+ if inspect.isclass(cls) and cls.__module__ == todoc.__name__:
+ classes.append(cls)
+ return classes
+ raise InheritanceException(f'{name} specified for inheritance diagram is '
+ 'not a class or module')
+
+
+def _import_classes(class_names, currmodule):
+ """Import a list of classes."""
+ classes = []
+ for name in class_names:
+ classes.extend(_import_class_or_module(name, currmodule))
+ return classes
+
+
+def _class_name(cls, parts=0):
+ """Given a class object, return a fully-qualified name.
+
+ This works for things I've tested in matplotlib so far, but may not be
+ completely general.
+ """
+ module = cls.__module__
+ if module == '__builtin__':
+ fullname = cls.__name__
+ else:
+ fullname = f"{module}.{cls.__qualname__}"
+ if parts == 0:
+ return fullname
+ name_parts = fullname.split('.')
+ return '.'.join(name_parts[-parts:])
+
+
+def _class_info(classes, builtins=None, show_builtins=False, parts=0):
+ """Return name and bases for all classes that are ancestors of
+ *classes*.
+
+ *parts* gives the number of dotted name parts that is removed from the
+ displayed node names.
+ """
+ all_classes = {}
+ builtins_list = builtins.values() if builtins else []
+
+ def recurse(cls):
+ if not show_builtins and cls in builtins_list:
+ return
+
+ nodename = _class_name(cls, parts)
+ fullname = _class_name(cls, 0)
+
+ baselist = []
+ all_classes[cls] = (nodename, fullname, baselist)
+ for base in cls.__bases__:
+ if not show_builtins and base in builtins_list:
+ continue
+ if base.__name__ == "Object" and base.__module__ == "Shiboken":
+ continue
+ baselist.append(_class_name(base, parts))
+ if base not in all_classes:
+ recurse(base)
+
+ for cls in classes:
+ recurse(cls)
+
+ return list(all_classes.values())
+
+
+def get_inheritance_entries_by_import(class_names, currmodule,
+ builtins=None,
+ show_builtins=False, parts=0):
+ classes = _import_classes(class_names, currmodule)
+ class_info = _class_info(classes, builtins, show_builtins, parts)
+ if not class_info:
+ raise InheritanceException('No classes found for '
+ 'inheritance diagram')
+ return class_info
+
+
+if __name__ == "__main__":
+ module = None
+ if len(sys.argv) < 2:
+ print(TEST_DRIVER_USAGE)
+ sys.exit(-1)
+ class_name = sys.argv[1]
+ if len(sys.argv) >= 3:
+ module = sys.argv[2]
+ entries = get_inheritance_entries_by_import([class_name], module, None,
+ False, 2)
+ for e in entries:
+ print(e)
diff --git a/sources/pyside6/doc/index.rst b/sources/pyside6/doc/index.rst
new file mode 100644
index 000000000..1bb28f9c1
--- /dev/null
+++ b/sources/pyside6/doc/index.rst
@@ -0,0 +1,222 @@
+|project|
+*********
+
+.. ifconfig:: output_format == 'html'
+
+ **Qt for Python** offers the official Python bindings for `Qt`_,
+ which enables you to use Python to write your Qt applications.
+ The project has two main components:
+
+ * `PySide6`_, so that you can use Qt6 APIs in your Python applications, and
+ * `Shiboken6 <shiboken6/index.html>`__, a binding generator tool, which can
+ be used to expose C++ projects to Python, and a Python module with
+ some utility functions.
+
+.. ifconfig:: output_format == 'qthelp'
+
+ **Qt for Python** offers the official Python bindings for `Qt`_,
+ which enables you to use Python to write your Qt applications.
+ The project has two main components:
+
+ * `PySide6`_, so that you can use Qt6 APIs in your Python applications, and
+ * `Shiboken6 <../shiboken6/index.html>`__, a binding generator tool, which can
+ be used to expose C++ projects to Python, and a Python module with
+ some utility functions.
+
+`Porting from PySide2 to PySide6`_ provides information on porting existing PySide2
+applications.
+
+This project is available under the LGPLv3/GPLv3 and the `Qt commercial license`_.
+
+.. _Qt: https://doc.qt.io
+.. _PySide6: quickstart.html
+.. _`Qt commercial license`: https://www.qt.io/licensing/
+.. _`Porting from PySide2 to PySide6`: gettingstarted/porting_from2.html
+
+Quick Start
+===========
+
+You can obtain the latest stable version by running ``pip install pyside6``.
+If you want to build it yourself, check the `getting started guide`_.
+
+To learn how to use it, check out `write your first application`_,
+and to learn what is installed with the ``pyside6``, check the
+`package content, structure, and tools`_ page.
+
+
+.. _`getting started guide`: gettingstarted/index.html
+.. _`write your first application`: quickstart.html
+.. _`package content, structure, and tools`: gettingstarted/package_details.html
+
+Documentation
+=============
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card::
+ :img-top: images/Desktop.svg
+ :class-item: text-center
+
+ Write your first Qt application.
+ +++
+ .. button-ref:: quick-start
+ :color: primary
+ :outline:
+ :expand:
+
+ Start here!
+
+ .. grid-item-card::
+ :img-top: images/Support.svg
+ :class-item: text-center
+
+ Modules, docs, and cross compilation.
+ +++
+ .. button-ref:: gettingstarted/index
+ :color: primary
+ :outline:
+ :expand:
+
+ Build Instructions
+
+ .. grid-item-card::
+ :img-top: images/Commercial.svg
+ :class-item: text-center
+
+ Packages, installation, and details.
+ +++
+ .. button-ref:: commercial-page
+ :color: primary
+ :outline:
+ :expand:
+
+ Commercial
+
+ .. grid-item-card::
+ :img-top: images/Dev.svg
+ :class-item: text-center
+
+ PySide API reference.
+ +++
+ .. button-ref:: pyside-api
+ :color: primary
+ :outline:
+ :expand:
+
+ API Docs
+
+ .. grid-item-card::
+ :img-top: images/Tutorials.svg
+ :class-item: text-center
+
+ Learn with step-by-step guides.
+ +++
+ .. button-ref:: tutorials/index
+ :color: primary
+ :outline:
+ :expand:
+
+ Tutorials
+
+ .. grid-item-card::
+ :img-top: images/Examples.svg
+ :class-item: text-center
+
+ Check all the available examples.
+ +++
+ .. button-ref:: examples/index
+ :color: primary
+ :outline:
+ :expand:
+
+ Examples
+
+ .. grid-item-card::
+ :img-top: images/Training.svg
+ :class-item: text-center
+
+ Watch webinars, talks, and more.
+ +++
+ .. button-ref:: videos
+ :color: primary
+ :outline:
+ :expand:
+
+ Videos
+
+ .. grid-item-card::
+ :img-top: images/Tooling.svg
+ :class-item: text-center
+
+ Discover the tools included.
+ +++
+ .. button-ref:: package_tools
+ :color: primary
+ :outline:
+ :expand:
+
+ Tooling
+
+ .. grid-item-card::
+ :img-top: images/Deployment.svg
+ :class-item: text-center
+
+ Learn to deploy your applications.
+ +++
+ .. button-ref:: deployment-guides
+ :color: primary
+ :outline:
+ :expand:
+
+ Deployment
+
+ .. grid-item-card::
+ :img-top: images/cpp_python.svg
+ :class-item: text-center
+
+ Generate C++ to Python bindings.
+ +++
+ .. button-link:: shiboken6/index.html
+ :color: primary
+ :outline:
+ :expand:
+
+ Shiboken
+
+ .. grid-item-card::
+ :img-top: images/stopwatch.svg
+ :class-item: text-center
+
+ API differences and known issues.
+ +++
+ .. button-ref:: considerations
+ :color: primary
+ :outline:
+ :expand:
+
+ Considerations
+
+ .. grid-item-card::
+ :img-top: images/Development.svg
+ :class-item: text-center
+
+ Notes for Developers.
+ +++
+ .. button-ref:: developer-notes
+ :color: primary
+ :outline:
+ :expand:
+
+ Developers
+
+
+We have also a `wiki page`_ where you can find how to report bugs, contribute or contact the community.
+
+.. _`wiki page`: https://wiki.qt.io/Qt_for_Python
+
+.. toctree::
+ :hidden:
+ :glob:
+
+ contents.rst
diff --git a/sources/pyside6/doc/inheritance_diagram.py b/sources/pyside6/doc/inheritance_diagram.py
new file mode 100644
index 000000000..e972fac4c
--- /dev/null
+++ b/sources/pyside6/doc/inheritance_diagram.py
@@ -0,0 +1,165 @@
+# -*- coding: utf-8 -*-
+r"""
+ sphinx.ext.inheritance_diagram
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Defines a docutils directive for inserting inheritance diagrams.
+
+ Provide the directive with one or more classes or modules (separated
+ by whitespace). For modules, all of the classes in that module will
+ be used.
+
+ Example::
+
+ Given the following classes:
+
+ class A: pass
+ class B(A): pass
+ class C(A): pass
+ class D(B, C): pass
+ class E(B): pass
+
+ .. inheritance-diagram: D E
+
+ Produces a graph like the following:
+
+ A
+ / \
+ B C
+ / \ /
+ E D
+
+ The graph is inserted as a PNG+image map into HTML and a PDF in
+ LaTeX.
+
+ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ :copyright: Copyright 2010-2011 by the PySide team.
+ :license: BSD, see LICENSE for details.
+"""
+
+try:
+ from hashlib import md5
+except ImportError:
+ from md5 import md5
+
+from docutils import nodes
+from docutils.parsers.rst import directives, Directive
+
+from sphinx.ext.graphviz import render_dot_html, render_dot_latex
+
+from inheritance_graph import InheritanceGraph
+from import_inheritance import (InheritanceException)
+
+
+class inheritance_diagram(nodes.General, nodes.Element):
+ """
+ A docutils node to use as a placeholder for the inheritance diagram.
+ """
+ pass
+
+
+class InheritanceDiagram(Directive):
+ """
+ Run when the inheritance_diagram directive is first encountered.
+ """
+ has_content = False
+ required_arguments = 1
+ optional_arguments = 0
+ final_argument_whitespace = True
+ option_spec = {
+ 'parts': directives.nonnegative_int,
+ }
+
+ def run(self):
+ node = inheritance_diagram()
+ node.document = self.state.document
+ env = self.state.document.settings.env
+ class_names = self.arguments[0].split()
+ class_role = env.get_domain('py').role('class')
+ # Store the original content for use as a hash
+ node['parts'] = self.options.get('parts', 0)
+ node['content'] = ', '.join(class_names)
+
+ # Create a graph starting with the list of classes
+ try:
+ graph = InheritanceGraph(
+ class_names, env.temp_data.get('py:module'),
+ __builtins__, parts=node['parts'])
+ except InheritanceException as err:
+ return [node.document.reporter.warning(err.args[0],
+ line=self.lineno)]
+
+ # Create xref nodes for each target of the graph's image map and
+ # add them to the doc tree so that Sphinx can resolve the
+ # references to real URLs later. These nodes will eventually be
+ # removed from the doctree after we're done with them.
+ for name in graph.get_all_class_names():
+ refnodes, x = class_role('class', f':class:`{name}`', name,
+ 0, self.state)
+ node.extend(refnodes)
+ # Store the graph object so we can use it to generate the
+ # dot file later
+ node['graph'] = graph
+ return [node]
+
+
+def get_graph_hash(node):
+ hashString = node['content'] + str(node['parts'])
+ return md5(hashString.encode('utf-8')).hexdigest()[-10:]
+
+
+def html_visit_inheritance_diagram(self, node):
+ """
+ Output the graph for HTML. This will insert a PNG with clickable
+ image map.
+ """
+ graph = node['graph']
+
+ graph_hash = get_graph_hash(node)
+ name = f'inheritance{graph_hash}'
+
+ # Create a mapping from fully-qualified class names to URLs.
+ urls = {}
+ for child in node:
+ ref_title = child.get('reftitle')
+ uri = child.get('refuri')
+ if uri and ref_title:
+ urls[ref_title] = uri
+
+ dotcode = graph.generate_dot(name, urls, env=self.builder.env)
+ render_dot_html(self, node, dotcode, {}, 'inheritance', 'inheritance',
+ alt='Inheritance diagram of ' + node['content'])
+ raise nodes.SkipNode
+
+
+def latex_visit_inheritance_diagram(self, node):
+ """
+ Output the graph for LaTeX. This will insert a PDF.
+ """
+ graph = node['graph']
+
+ graph_hash = get_graph_hash(node)
+ name = f'inheritance{graph_hash}'
+
+ dotcode = graph.generate_dot(name, env=self.builder.env,
+ graph_attrs={'size': '"6.0,6.0"'})
+ render_dot_latex(self, node, dotcode, {}, 'inheritance')
+ raise nodes.SkipNode
+
+
+def skip(self, node):
+ raise nodes.SkipNode
+
+
+def setup(app):
+ app.setup_extension('sphinx.ext.graphviz')
+ app.add_node(
+ inheritance_diagram,
+ latex=(latex_visit_inheritance_diagram, None),
+ html=(html_visit_inheritance_diagram, None),
+ text=(skip, None),
+ man=(skip, None))
+ app.add_directive('inheritance-diagram', InheritanceDiagram)
+ app.add_config_value('inheritance_graph_attrs', {}, False),
+ app.add_config_value('inheritance_node_attrs', {}, False),
+ app.add_config_value('inheritance_edge_attrs', {}, False),
diff --git a/sources/pyside6/doc/inheritance_diagram.pyproject b/sources/pyside6/doc/inheritance_diagram.pyproject
new file mode 100644
index 000000000..a44dc93b8
--- /dev/null
+++ b/sources/pyside6/doc/inheritance_diagram.pyproject
@@ -0,0 +1,6 @@
+{
+ "files": ["inheritance_diagram.py",
+ "import_inheritance.py",
+ "inheritance_graph.py",
+ "json_inheritance.py"]
+}
diff --git a/sources/pyside6/doc/inheritance_graph.py b/sources/pyside6/doc/inheritance_graph.py
new file mode 100644
index 000000000..00e0ac486
--- /dev/null
+++ b/sources/pyside6/doc/inheritance_graph.py
@@ -0,0 +1,145 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import sys
+
+from import_inheritance import (get_inheritance_entries_by_import)
+from json_inheritance import (is_inheritance_from_json_enabled,
+ get_inheritance_entries_from_json)
+
+
+TEST_DRIVER_USAGE = """Usage: inheritance_graph.py [module] [class]
+
+Example:
+python inheritance_graph.py PySide6.QtWidgets PySide6.QtWidgets.QWizard
+"""
+
+
+def format_dict(d):
+ """Format the URL dict for error message."""
+ result = '{'
+ n = 0
+ for k, v in d.items():
+ n += 1
+ if n > 10:
+ result += "..."
+ break
+ if n > 1:
+ result += ", "
+ result += f'"{k}": "{v}"'
+ result += '}'
+ return result
+
+
+class InheritanceGraph(object):
+ """
+ Given a list of classes, determines the set of classes that they inherit
+ from all the way to the root "object", and then is able to generate a
+ graphviz dot graph from them.
+ """
+ def __init__(self, class_names, currmodule, builtins=None, show_builtins=False, parts=0):
+ """
+ *class_names* is a list of child classes to show bases from.
+
+ If *show_builtins* is True, then Python builtins will be shown
+ in the graph.
+ """
+ self.class_names = class_names
+ if is_inheritance_from_json_enabled():
+ self.class_info = get_inheritance_entries_from_json(class_names)
+ else:
+ self.class_info = get_inheritance_entries_by_import(class_names,
+ currmodule,
+ builtins,
+ show_builtins,
+ parts)
+
+ def get_all_class_names(self):
+ """
+ Get all of the class names involved in the graph.
+ """
+ return [fullname for (_, fullname, _) in self.class_info]
+
+ # These are the default attrs for graphviz
+ default_graph_attrs = {
+ 'rankdir': 'LR',
+ 'size': '"8.0, 12.0"',
+ }
+ default_node_attrs = {
+ 'shape': 'box',
+ 'fontsize': 10,
+ 'height': 0.25,
+ 'fontname': '"Vera Sans, DejaVu Sans, Liberation Sans, '
+ 'Arial, Helvetica, sans"',
+ 'style': '"setlinewidth(0.5)"',
+ }
+ default_edge_attrs = {
+ 'arrowsize': 0.5,
+ 'style': '"setlinewidth(0.5)"',
+ }
+
+ def _format_node_attrs(self, attrs):
+ return ','.join([f'{x[0]}={x[1]}' for x in attrs.items()])
+
+ def _format_graph_attrs(self, attrs):
+ return ''.join([f"{x[0]}={x[1]};\n" for x in attrs.items()])
+
+ def generate_dot(self, name, urls={}, env=None,
+ graph_attrs={}, node_attrs={}, edge_attrs={}):
+ """
+ Generate a graphviz dot graph from the classes that
+ were passed in to __init__.
+
+ *name* is the name of the graph.
+
+ *urls* is a dictionary mapping class names to HTTP URLs.
+
+ *graph_attrs*, *node_attrs*, *edge_attrs* are dictionaries containing
+ key/value pairs to pass on as graphviz properties.
+ """
+ g_attrs = self.default_graph_attrs.copy()
+ n_attrs = self.default_node_attrs.copy()
+ e_attrs = self.default_edge_attrs.copy()
+ g_attrs.update(graph_attrs)
+ n_attrs.update(node_attrs)
+ e_attrs.update(edge_attrs)
+ if env:
+ g_attrs.update(env.config.inheritance_graph_attrs)
+ n_attrs.update(env.config.inheritance_node_attrs)
+ e_attrs.update(env.config.inheritance_edge_attrs)
+
+ res = []
+ res.append(f'digraph {name} {{\n')
+ res.append(self._format_graph_attrs(g_attrs))
+
+ for name, fullname, bases in self.class_info:
+ # Write the node
+ this_node_attrs = n_attrs.copy()
+ url = urls.get(fullname)
+ if url is not None:
+ this_node_attrs['URL'] = f'"{url}"'
+ this_node_attrs['target'] = '"_top"' # Browser target frame attribute (same page)
+ else:
+ urls_str = format_dict(urls)
+ print(f'inheritance_graph.py: No URL found for {name} ({fullname}) in {urls_str}.',
+ file=sys.stderr)
+ attribute = self._format_node_attrs(this_node_attrs)
+ res.append(f' "{name}" [{attribute}];\n')
+
+ # Write the edges
+ for base_name in bases:
+ attribute = self._format_node_attrs(e_attrs)
+ res.append(f' "{base_name}" -> "{name}" [{attribute}];\n')
+ res.append('}\n')
+ return ''.join(res)
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print(TEST_DRIVER_USAGE)
+ sys.exit(-1)
+ module = sys.argv[1]
+ class_names = sys.argv[2:]
+ graph = InheritanceGraph(class_names, module)
+ dot = graph.generate_dot("test")
+ print(dot)
diff --git a/sources/pyside6/doc/json_inheritance.py b/sources/pyside6/doc/json_inheritance.py
new file mode 100644
index 000000000..06be33ea4
--- /dev/null
+++ b/sources/pyside6/doc/json_inheritance.py
@@ -0,0 +1,74 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import json
+import os
+import sys
+from pathlib import Path
+
+
+"""Helpers for determining base classes by reading a JSON
+ file written by shiboken's doc generator."""
+
+
+TEST_DRIVER_USAGE = """Usage: json_inheritance.py class_name json_file
+
+Example:
+python json_inheritance.py PySide6.QtWidgets.QWizard ~/inheritance.json
+"""
+
+
+ENV_VAR = "INHERITANCE_FILE"
+
+
+def strip_module(class_name):
+ return class_name[8:] if class_name.startswith("PySide") else class_name
+
+
+def get_inheritance_entries_recursion(json_dict, class_name):
+ """Get all edges of the inheritance graph of class_name."""
+ result = []
+ bases_entry = json_dict.get(class_name)
+ bases = bases_entry if bases_entry else []
+ node_name = strip_module(class_name)
+ base_list = [strip_module(b) for b in bases]
+ result.append((node_name, class_name, base_list))
+ for b in bases:
+ nested_bases = get_inheritance_entries_recursion(json_dict, b)
+ if nested_bases:
+ result.extend(nested_bases)
+ return result
+
+
+def _get_inheritance_entries_from_json(json_file, class_names):
+ """Get all edges of the inheritance graph of class_name
+ from the JSON file generated by shiboken."""
+ result = []
+ try:
+ with Path(json_file).open("r") as f:
+ json_dict = json.load(f)
+ for c in class_names:
+ result.extend(get_inheritance_entries_recursion(json_dict, c))
+ except (json.JSONDecodeError, KeyError) as e:
+ print(f"Error reading {json_file}: {e}")
+ raise
+ return result
+
+
+def is_inheritance_from_json_enabled():
+ return os.environ.get(ENV_VAR)
+
+
+def get_inheritance_entries_from_json(class_names):
+ json_file = os.environ[ENV_VAR]
+ return _get_inheritance_entries_from_json(json_file, class_names)
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print(TEST_DRIVER_USAGE)
+ sys.exit(-1)
+ class_name = sys.argv[1]
+ json_file = sys.argv[2]
+ for e in _get_inheritance_entries_from_json(json_file, [class_name]):
+ print(e)
diff --git a/sources/pyside6/doc/modules.rst b/sources/pyside6/doc/modules.rst
new file mode 100644
index 000000000..8e77a4616
--- /dev/null
+++ b/sources/pyside6/doc/modules.rst
@@ -0,0 +1,234 @@
+Qt Modules Supported by Qt for Python
+=====================================
+
+.. toctree::
+ :hidden:
+ :glob:
+
+ PySide6/Qt*/index
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: :mod:`QtBluetooth <PySide6.QtBluetooth>`
+
+ The Bluetooth API provides connectivity between Bluetooth enabled
+ devices.
+
+
+ .. grid-item-card:: :mod:`QtCharts <PySide6.QtCharts>`
+
+ Provides a set of easy to use chart components.
+
+ .. grid-item-card:: :mod:`QtConcurrent <PySide6.QtConcurrent>`
+
+ Provides high-level APIs that make it possible to write multi-threaded
+ programs without using low-level threading primitives such as mutexes,
+ read-write locks, wait conditions, or semaphores.
+
+
+ .. grid-item-card:: :mod:`QtCore <PySide6.QtCore>`
+
+ Provides core non-GUI functionality.
+
+ .. grid-item-card:: :mod:`QtDataVisualization <PySide6.QtDataVisualization>`
+
+ Provides a way to visualize data in 3D as bar, scatter, and surface
+ graphs.
+
+ .. grid-item-card:: :mod:`QtDBus <PySide6.QtDBus>`
+
+ D-Bus is an Inter-Process Communication (IPC) and Remote Procedure
+ Calling (RPC) mechanism originally developed for Linux to replace
+ existing and competing IPC solutions with one unified protocol
+
+ .. grid-item-card:: :mod:`QtDesigner <PySide6.QtDesigner>`
+
+ Provides classes to extend *Qt Widgets Designer*.
+
+ .. grid-item-card:: :mod:`QtGui <PySide6.QtGui>`
+
+ Extends QtCore with GUI functionality.
+
+ .. grid-item-card:: :mod:`QtHelp <PySide6.QtHelp>`
+
+ Provides classes for integrating online documentation in applications.
+
+ .. grid-item-card:: :mod:`Qt Multimedia <PySide6.QtMultimedia>`
+
+ Provides API for multimedia-specific use cases.
+
+ .. grid-item-card:: :mod:`Qt Multimedia Widgets <PySide6.QtMultimediaWidgets>`
+
+ Provides the widget-based multimedia API.
+
+ .. grid-item-card:: :mod:`QtNetwork <PySide6.QtNetwork>`
+
+ Offers classes that let you to write TCP/IP clients and servers.
+
+ .. grid-item-card:: :mod:`Qt Network Authorization <PySide6.QtNetworkAuth>`
+
+ Provides a set of APIs that enable Qt applications to obtain limited
+ access to online accounts and HTTP services without exposing users'
+ passwords.
+
+ .. grid-item-card:: :mod:`QtNfc <PySide6.QtNfc>`
+
+ The NFC API provides connectivity between NFC enabled devices.
+
+ .. grid-item-card:: :mod:`QtOpenGL <PySide6.QtOpenGL>`
+
+ Offers classes that make it easy to use OpenGL in Qt applications.
+
+ .. grid-item-card:: :mod:`QtOpenGL Widgets <PySide6.QtOpenGLWidgets>`
+
+ Provides the OpenGLWidget class enabling OpenGL rendering for
+ a certain part of the widget tree.
+
+ .. grid-item-card:: :mod:`Qt Positioning <PySide6.QtPositioning>`
+
+ Provides access to position, satellite info and area monitoring
+ classes.
+
+ .. grid-item-card:: :mod:`Qt PDF <PySide6.QtPdf>`
+
+ Classes and functions for rendering PDF documents.
+
+ .. grid-item-card:: :mod:`Qt PDF Widgets <PySide6.QtPdfWidgets>`
+
+ A PDF viewer widget.
+
+ .. grid-item-card:: :mod:`QtPrintSupport <PySide6.QtPrintSupport>`
+
+ Provides extensive cross-platform support for printing.
+
+ .. grid-item-card:: :mod:`QtQml <PySide6.QtQml>`
+
+ Python API for Qt QML.
+
+ .. grid-item-card:: :mod:`QtQuick <PySide6.QtQuick>`
+
+ Provides classes for embedding Qt Quick in Qt applications.
+
+ .. grid-item-card:: :mod:`QtQuickControls2 <PySide6.QtQuickControls2>`
+
+ Provides classes for setting up the controls from C++.
+
+ .. grid-item-card:: :mod:`QtQuickTest <PySide6.QtQuickTest>`
+
+ A unit test framework for QML applications where test cases are written as JavaScript functions.
+
+ .. grid-item-card:: :mod:`QtQuickWidgets <PySide6.QtQuickWidgets>`
+
+ Provides the QQuickWidget class for embedding Qt Quick in widget-based applications.
+
+ .. grid-item-card:: :mod:`QtRemoteObjects <PySide6.QtRemoteObjects>`
+
+ Inter-Process Communication (IPC) module developed for Qt. This module
+ extends Qt's existing functionalities to enable information exchange
+ between processes or computers, easily.
+
+ .. grid-item-card:: :mod:`Qt Scxml <PySide6.QtScxml>`
+
+ Provides classes to create and use state machines from SCXML files.
+
+ .. grid-item-card:: :mod:`Qt Sensors <PySide6.QtSensors>`
+
+ Provides access to sensor hardware.
+
+ .. grid-item-card:: :mod:`Qt Serial Bus <PySide6.QtSerialBus>`
+
+ Provides access to serial industrial bus interfaces. Currently, the
+ module supports the CAN bus and Modbus protocols.
+
+ .. grid-item-card:: :mod:`Qt Serial Port <PySide6.QtSerialPort>`
+
+ Provides classes to interact with hardware and virtual serial ports.
+
+ .. grid-item-card:: :mod:`Qt Spatial Audio <PySide6.QtSpatialAudio>`
+
+ Provides APIs for modeling sound source and their surrounds in 3D
+ space.
+
+ .. grid-item-card:: :mod:`QtSql <PySide6.QtSql>`
+
+ Helps you provide seamless database integration to your Qt
+ applications.
+
+ .. grid-item-card:: :mod:`QtStateMachine <PySide6.QtStateMachine>`
+
+ Provides classes for creating and executing state graphs.
+
+ .. grid-item-card:: :mod:`QtSvg <PySide6.QtSvg>`
+
+ Provides classes for displaying the contents of SVG files.
+
+ .. grid-item-card:: :mod:`QtSvgWidgets <PySide6.QtSvgWidgets>`
+
+ Provides a widget that is used to display the contents of SVG files.
+
+ .. grid-item-card:: :mod:`QtTest <PySide6.QtTest>`
+
+ Provides classes for unit testing Qt applications and libraries.
+
+ .. grid-item-card:: :mod:`QtUiTools <PySide6.QtUiTools>`
+
+ Provides classes to handle forms created with *Qt Widgets Designer*.
+
+ .. grid-item-card:: :mod:`Qt WebChannel <PySide6.QtWebChannel>`
+
+ Provides access to QObject or QML objects from HTML clients for
+ seamless integration of Qt applications with HTML/JavaScript clients.
+
+ .. grid-item-card:: :mod:`QtWebEngine Core C++ Classes <PySide6.QtWebEngineCore>`
+
+ Provides public API shared by both QtWebEngine and QtWebEngineWidgets.
+
+ .. grid-item-card:: :mod:`QtWebEngine Widgets C++ Classes <PySide6.QtWebEngineWidgets>`
+
+ Provides C++ classes for rendering web content in a QWidget based
+ application.
+
+ .. grid-item-card:: :mod:`QtWebEngine QML Types <PySide6.QtWebEngineQuick>`
+
+ Provides QML types for rendering web content within a QML application.
+
+ .. grid-item-card:: :mod:`Qt WebSockets <PySide6.QtWebSockets>`
+
+ Provides WebSocket communication compliant with RFC 6455.
+
+ .. grid-item-card:: :mod:`QtWidgets <PySide6.QtWidgets>`
+
+ Extends Qt GUI with C++ widget functionality.
+
+ .. grid-item-card:: :mod:`QtXml <PySide6.QtXml>`
+
+ Provides a C++ implementation of DOM.
+
+ .. grid-item-card:: :mod:`Qt3DAnimation <PySide6.Qt3DAnimation>`
+
+ Provides basic elements required to animate 3D objects.
+
+ .. grid-item-card:: :mod:`Qt3D Core <PySide6.Qt3DCore>`
+
+ Contains functionality to support near-realtime simulation systems.
+
+ .. grid-item-card:: :mod:`Qt3D Extras <PySide6.Qt3DExtras>`
+
+ Provides a set of prebuilt elements to help you get started with Qt 3D.
+
+ .. grid-item-card:: :mod:`Qt3D Input <PySide6.Qt3DInput>`
+
+ Provides classes for handling user input in applications using Qt 3D.
+
+ .. grid-item-card:: :mod:`Qt3D Logic <PySide6.Qt3DLogic>`
+
+ Enables synchronizing frames with the Qt 3D backend.
+
+ .. grid-item-card:: :mod:`Qt3D Render <PySide6.Qt3DRender>`
+
+ Contains functionality to support 2D and 3D rendering using Qt 3D.
+
+ .. grid-item-card:: :mod:`QtAsyncio <PySide6.QtAsyncio>`
+
+ Provides integration between asyncio and Qt's event loop.
diff --git a/sources/pyside6/doc/pyside-config.qdocconf.in b/sources/pyside6/doc/pyside-config.qdocconf.in
new file mode 100644
index 000000000..7807c9d52
--- /dev/null
+++ b/sources/pyside6/doc/pyside-config.qdocconf.in
@@ -0,0 +1,19 @@
+buildversion = @PYSIDE_QT_VERSION@
+navigation.homepage = Qt for Python
+
+macro.nullptr = "\\c{None}"
+
+outputdir = @DOC_DATA_DIR@
+outputformats = WebXML
+WebXML.quotinginformation = true
+WebXML.nosubdirs = true
+WebXML.outputsubdir = webxml
+
+spurious += "Hostile character .*"
+
+#excludes qdoc statements that are not relevant for PySide6
+defines += qtforpython
+
+includepaths += \
+ -I @QT_INCLUDE_DIR@ \
+ -I @mkspecInclude@ \
diff --git a/sources/pyside6/doc/pysideinclude.py b/sources/pyside6/doc/pysideinclude.py
new file mode 100644
index 000000000..8e2834cce
--- /dev/null
+++ b/sources/pyside6/doc/pysideinclude.py
@@ -0,0 +1,148 @@
+#
+# This code is a modified version of the code found in sphinx distribution
+# the same license of sphinx distribution applies to this file as well.
+#
+
+import os
+import sys
+import codecs
+from os import path
+
+from docutils import nodes
+from docutils.parsers.rst import Directive, directives
+
+from sphinx.util import parselinenos
+
+
+class PySideInclude(Directive):
+ """
+ Like ``.. include:: :literal:``, but only warns if the include file is
+ not found, and does not raise errors. Also has several options for
+ selecting what to include.
+ """
+
+ has_content = False
+ required_arguments = 1
+ optional_arguments = 0
+ final_argument_whitespace = False
+ option_spec = {
+ 'linenos': directives.flag,
+ 'tab-width': int,
+ 'language': directives.unchanged_required,
+ 'encoding': directives.encoding,
+ 'pyobject': directives.unchanged_required,
+ 'lines': directives.unchanged_required,
+ 'start-after': directives.unchanged_required,
+ 'end-before': directives.unchanged_required,
+ 'prepend': directives.unchanged_required,
+ 'append': directives.unchanged_required,
+ 'snippet': directives.unchanged_required,
+ }
+
+ def run(self):
+ document = self.state.document
+ filename = self.arguments[0]
+ if not document.settings.file_insertion_enabled:
+ return [document.reporter.warning('File insertion disabled',
+ line=self.lineno)]
+ env = document.settings.env
+ if filename.startswith('/') or filename.startswith(os.sep):
+ rel_fn = filename[1:]
+ else:
+ docdir = path.dirname(env.doc2path(env.docname, base=None))
+ rel_fn = path.join(docdir, filename)
+ try:
+ fn = path.join(env.srcdir, rel_fn)
+ except UnicodeDecodeError:
+ # the source directory is a bytestring with non-ASCII characters;
+ # let's try to encode the rel_fn in the file system encoding
+ rel_fn = rel_fn.encode(sys.getfilesystemencoding())
+ fn = path.join(env.srcdir, rel_fn)
+
+ if 'pyobject' in self.options and 'lines' in self.options:
+ return [document.reporter.warning(
+ 'Cannot use both "pyobject" and "lines" options',
+ line=self.lineno)]
+
+ encoding = self.options.get('encoding', env.config.source_encoding)
+ codec_info = codecs.lookup(encoding)
+ try:
+ f = codecs.StreamReaderWriter(open(fn, 'Ub'),
+ codec_info[2], codec_info[3], 'strict')
+ lines = f.readlines()
+ f.close()
+ except (IOError, OSError):
+ return [document.reporter.warning(
+ 'Include file %r not found or reading it failed' % filename,
+ line=self.lineno)]
+ except UnicodeError:
+ return [document.reporter.warning(
+ 'Encoding %r used for reading included file %r seems to '
+ 'be wrong, try giving an :encoding: option' %
+ (encoding, filename))]
+
+ objectname = self.options.get('pyobject')
+ if objectname is not None:
+ from sphinx.pycode import ModuleAnalyzer
+ analyzer = ModuleAnalyzer.for_file(fn, '')
+ tags = analyzer.find_tags()
+ if objectname not in tags:
+ return [document.reporter.warning(
+ 'Object named %r not found in include file %r' %
+ (objectname, filename), line=self.lineno)]
+ else:
+ lines = lines[tags[objectname][1] - 1: tags[objectname][2] - 1]
+
+ linespec = self.options.get('lines')
+ if linespec is not None:
+ try:
+ linelist = parselinenos(linespec, len(lines))
+ except ValueError as err:
+ return [document.reporter.warning(str(err), line=self.lineno)]
+ lines = [lines[i] for i in linelist]
+
+ startafter = self.options.get('start-after')
+ endbefore = self.options.get('end-before')
+ prepend = self.options.get('prepend')
+ append = self.options.get('append')
+ snippet = self.options.get('snippet')
+
+ if snippet:
+ startafter = "//![%s]" % snippet
+ endbefore = "//![%s]" % snippet
+
+ if startafter is not None or endbefore is not None:
+ use = not startafter
+ res = []
+ for line in lines:
+ if not use and startafter and startafter in line:
+ use = True
+ elif use and endbefore and endbefore in line:
+ use = False
+ break
+ elif use:
+ if not line.startswith("//!"):
+ res.append(line)
+ lines = res
+
+ if prepend:
+ lines.insert(0, prepend + '\n')
+ if append:
+ lines.append(append + '\n')
+
+ text = ''.join(lines)
+ if self.options.get('tab-width'):
+ text = text.expandtabs(self.options['tab-width'])
+ retnode = nodes.literal_block(text, text, source=fn)
+ retnode.line = 1
+ retnode.attributes['line_number'] = self.lineno
+ if self.options.get('language', ''):
+ retnode['language'] = self.options['language']
+ if 'linenos' in self.options:
+ retnode['linenos'] = True
+ document.settings.env.note_dependency(rel_fn)
+ return [retnode]
+
+
+def setup(app):
+ app.add_directive('pysideinclude', PySideInclude)
diff --git a/sources/pyside6/doc/qdoc_spawner.py.in b/sources/pyside6/doc/qdoc_spawner.py.in
new file mode 100644
index 000000000..d9d434366
--- /dev/null
+++ b/sources/pyside6/doc/qdoc_spawner.py.in
@@ -0,0 +1,105 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import argparse
+import subprocess
+import os
+import sys
+import time
+from multiprocessing import Pool, cpu_count
+from pathlib import Path
+
+
+def run_qdoc(file, qdoc_args, args):
+ env = os.environ
+ env["BUILDDIR"] = args.build_dir
+ env["QT_INSTALL_DOCS"] = args.qt_install_docs
+ env["QT_VERSION"] = args.qt_version
+ env["QT_VER"] = ".".join(args.qt_version.split(".")[:2])
+ env["QT_VERSION_TAG"] = args.qt_version
+
+ command = [
+ args.qdoc_bin,
+ file,
+ *qdoc_args,
+ "-installdir",
+ args.doc_data_dir,
+ "-outputdir",
+ args.doc_data_dir,
+ ]
+
+ start_time = time.time()
+ _ = subprocess.Popen(command, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = _.communicate()
+ returncode = _.wait()
+ duration = round(time.time() - start_time)
+
+ if args.verbose or returncode != 0 or err:
+ cmd_str = " ".join(command)
+ print(f"> Output of: {cmd_str}")
+ if out:
+ print(out.decode("utf-8"), file=sys.stdout)
+ if err:
+ print(err.decode("utf-8"), file=sys.stderr)
+ print(f"> Finished: {file} {duration}s (exit code {returncode})")
+
+ if returncode != 0:
+ raise Exception(f"Failing executing the command {command} ({returncode})")
+
+
+def get_qdocconf_files():
+ if not Path("pyside.qdocconf").exists():
+ print("ERROR: the working dir doesn't include a 'pyside.qdocconf' file")
+ sys.exit(-1)
+
+ # Generate the temporary qdocconf files
+ # This is necessary because using a file like 'pyside-qtcore.qtdocconf'
+ # will generate an error, because inside we call functions like 'include()'
+ files_single_exec = []
+ files_prepare = []
+ with open("pyside.qdocconf") as f:
+ for i in f.read().splitlines():
+ _p = Path(i)
+ _name = f"_{_p.stem}.qdocconf"
+ with open(_name, "w", encoding="utf-8") as f:
+ f.write(i)
+ files_single_exec.append(_name)
+ files_prepare.append(i.strip())
+
+ return files_prepare, files_single_exec
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(prog="qdoc spawner")
+ parser.add_argument("--qt", dest="qt_version", action="store", required=True)
+ parser.add_argument("--doc-data-dir", dest="doc_data_dir", action="store", required=True)
+ parser.add_argument("--qdoc-binary", dest="qdoc_bin", action="store", required=True)
+ parser.add_argument("--build-dir", dest="build_dir", action="store", required=True)
+ parser.add_argument("--qt-install-docs", dest="qt_install_docs", action="store", required=True)
+ parser.add_argument("--parallel", dest="parallel", action="store", default="4")
+ parser.add_argument("--verbose", dest="verbose", action="store_true", default=False)
+
+ args = parser.parse_args()
+
+ core_index = Path(args.doc_data_dir) / "webxml" / "qtcore-index.webxml"
+ if core_index.is_file():
+ print(f"qdoc_spawner: {core_index} already exists, bailing out")
+ sys.exit(0)
+
+ files_prepare, files_single_exec = get_qdocconf_files()
+
+ parallel = args.parallel
+ if parallel == "auto":
+ parallel = cpu_count()
+
+ try:
+ # mode: -prepare -no-link-errors
+ with Pool(int(parallel)) as p:
+ p.starmap(run_qdoc, [(str(f), ["-prepare", "-no-link-errors"], args) for f in files_prepare])
+
+ # mode: -single-exec
+ with Pool(int(parallel)) as p:
+ p.starmap(run_qdoc, [(str(f), ["-single-exec"], args) for f in files_single_exec])
+ except Exception as e:
+ print(f"qdoc_spawner: error: {e}", file=sys.stderr)
+ sys.exit(-1)
diff --git a/sources/pyside6/doc/qtattributionsscannertorst.py b/sources/pyside6/doc/qtattributionsscannertorst.py
new file mode 100644
index 000000000..677371c45
--- /dev/null
+++ b/sources/pyside6/doc/qtattributionsscannertorst.py
@@ -0,0 +1,123 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+Tool to run qtattributionsscanner and convert its output to rst
+"""
+
+import os
+import json
+import subprocess
+import warnings
+from argparse import ArgumentParser, RawTextHelpFormatter
+from pathlib import Path
+
+
+USAGE = "Usage: qtattributionsscannertorst [directory] [file]'"
+
+
+libexec_dir = None
+
+
+def indent(lines, indent):
+ result = ''
+ for line in lines:
+ result = f"{result}{indent}{line}\n"
+ return result
+
+
+rstHeader = """Licenses Used in Qt for Python
+******************************
+
+Qt for Python contains some code that is not provided under the
+GNU Lesser General Public License (LGPL) or the Qt Commercial License,
+but rather under specific licenses from the original authors.
+The Qt Company gratefully acknowledges these and other contributions
+to Qt for Python. We recommend that programs that use Qt for Python
+also acknowledge these contributions, and quote these license
+statements in an appendix to the documentation.
+
+Note: You only need to comply with (and acknowledge) the licenses of
+the third-party components that you are using with your application.
+Click the name of the component to see the licensing details.
+
+Third-party Licenses
+^^^^^^^^^^^^^^^^^^^^
+
+The licenses for the third-party sources used by Qt itself are listed
+in
+`Qt documentation <https://doc.qt.io/qt-5/licenses-used-in-qt.html>`_.
+The following table lists parts of Qt for Python that incorporates
+code licensed under third-party opensource licenses:
+
+"""
+
+
+def rstHeadline(title):
+ return f"{title}\n{'-' * len(title)}\n"
+
+
+def rstUrl(title, url):
+ return f"`{title} <{url}>`_"
+
+
+def rstLiteralBlock(lines):
+ return f"::\n\n{indent(lines, ' ')}\n\n"
+
+
+def rstLiteralBlockFromText(text):
+ return rstLiteralBlock(text.strip().split('\n'))
+
+
+def readFile(fileName):
+ with open(fileName, 'r') as file:
+ return file.readlines()
+
+
+def get_libexec_dir():
+ libexec_b = subprocess.check_output("qtpaths6 -query QT_INSTALL_LIBEXECS", shell=True)
+ return libexec_b.decode('utf-8').strip()
+
+
+def runScanner(directory, targetFileName, libexec_dir):
+ # qtattributionsscanner recursively searches for qt_attribution.json files
+ # and outputs them in JSON with the paths of the 'LicenseFile' made absolute
+ scanner = os.path.join(libexec_dir, 'qtattributionsscanner')
+ command = f'{scanner} --output-format json {directory}'
+ jsonS = subprocess.check_output(command, shell=True)
+ if not jsonS:
+ raise RuntimeError(f'{command} failed to produce output.')
+
+ with open(targetFileName, 'w') as targetFile:
+ targetFile.write(rstHeader)
+ for entry in json.loads(jsonS.decode('utf-8')):
+ content = f"{entry['Name']}\n{entry['Description']}\n{entry['QtUsage']}\n\n"
+ url = entry['Homepage']
+ version = entry['Version']
+ if url and version:
+ content = f"{content}{rstUrl('Project Homepage', url)}, upstream version: {version}\n\n" # noqa E:501
+ copyright = entry['Copyright']
+ if copyright:
+ content += rstLiteralBlockFromText(copyright)
+ content += entry['License'] + '\n\n'
+ licenseFile = entry['LicenseFile']
+ if licenseFile:
+ if Path(licenseFile).is_file():
+ content += rstLiteralBlock(readFile(licenseFile))
+ else:
+ warnings.warn(f'"{licenseFile}" is not a file', RuntimeWarning)
+ targetFile.write(content)
+
+
+if __name__ == '__main__':
+ parser = ArgumentParser(description=USAGE, formatter_class=RawTextHelpFormatter)
+ parser.add_argument("-l", "--libexec", type=str, help="libexec directory of Qt")
+ parser.add_argument('directory')
+ parser.add_argument('target')
+ options = parser.parse_args()
+ directory = options.directory
+ targetFileName = options.target
+ libexec_dir = options.libexec
+ if not libexec_dir:
+ libexec_dir = get_libexec_dir()
+ runScanner(directory, targetFileName, libexec_dir)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qt3dextras.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qt3dextras.qdocconf.in
new file mode 100644
index 000000000..b36b918a3
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qt3dextras.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qt3d/src/core/doc/qt3d.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qt3d/src/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtbluetooth.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtbluetooth.qdocconf.in
new file mode 100644
index 000000000..0867ff0c2
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtbluetooth.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtconnectivity/src/bluetooth/doc/qtbluetooth.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtcharts.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtcharts.qdocconf.in
new file mode 100644
index 000000000..1a58c2dc4
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtcharts.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtcharts/src/charts/doc/qtcharts.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtconcurrent.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtconcurrent.qdocconf.in
new file mode 100644
index 000000000..a6976c24b
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtconcurrent.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/concurrent/doc/qtconcurrent.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtcore.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtcore.qdocconf.in
new file mode 100644
index 000000000..5fb7248c9
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtcore.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/corelib/doc/qtcore.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in
new file mode 100644
index 000000000..c9fcb317c
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtdatavis3d/src/datavisualization/doc/qtdatavis3d.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtdbus.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtdbus.qdocconf.in
new file mode 100644
index 000000000..d291d92bd
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtdbus.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/dbus/doc/qtdbus.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtdesigner.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtdesigner.qdocconf.in
new file mode 100644
index 000000000..30d201be9
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtdesigner.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qttools/src/designer/src/designer/doc/qtdesigner.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtdoc.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtdoc.qdocconf.in
new file mode 100644
index 000000000..88cc3eac4
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtdoc.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtdoc/doc/config/qtdoc.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtgui.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtgui.qdocconf.in
new file mode 100644
index 000000000..77e7e6e18
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtgui.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/gui/doc/qtgui.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qthelp.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qthelp.qdocconf.in
new file mode 100644
index 000000000..9336909c1
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qthelp.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qttools/src/assistant/help/doc/qthelp.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in
new file mode 100644
index 000000000..5415c392c
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtmultimedia/src/multimedia/doc/qtmultimedia.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtmultimedia/src/multimedia/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtnetwork.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtnetwork.qdocconf.in
new file mode 100644
index 000000000..addec9aee
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtnetwork.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/network/doc/qtnetwork.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtnetworkauth.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtnetworkauth.qdocconf.in
new file mode 100644
index 000000000..45a20bdd9
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtnetworkauth.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtnetworkauth/src/oauth/doc/qtnetworkauth.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtnfc.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtnfc.qdocconf.in
new file mode 100644
index 000000000..833bbc019
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtnfc.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtconnectivity/src/nfc/doc/qtnfc.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtopengl.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtopengl.qdocconf.in
new file mode 100644
index 000000000..34895f0c6
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtopengl.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/opengl/doc/qtopengl.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtpdf.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtpdf.qdocconf.in
new file mode 100644
index 000000000..43eb302af
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtpdf.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtwebengine/src/pdf/doc/qtpdf.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtwebengine/src/pdf/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtpositioning.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtpositioning.qdocconf.in
new file mode 100644
index 000000000..f08a1ec07
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtpositioning.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtpositioning/src/positioning/doc/qtpositioning.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtpositioning/src/positioning/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtprintsupport.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtprintsupport.qdocconf.in
new file mode 100644
index 000000000..04c554434
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtprintsupport.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/printsupport/doc/qtprintsupport.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtqml.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtqml.qdocconf.in
new file mode 100644
index 000000000..546ea7b0a
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtqml.qdocconf.in
@@ -0,0 +1,5 @@
+#The index page for QtQml lists only the APIs. Including this qdocconf
+#should also include the text and snippets from the module page
+include(@QT_SRC_DIR@/../qtdeclarative/src/qml/doc/qtqml.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtdeclarative/src/qml/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtquickcontrols2.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtquickcontrols2.qdocconf.in
new file mode 100644
index 000000000..4d0a55946
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtquickcontrols2.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtdeclarative/src/quickcontrols/doc/qtquickcontrols.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtdeclarative/src/quickcontrols
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtquicktest.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtquicktest.qdocconf.in
new file mode 100644
index 000000000..1d8397537
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtquicktest.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtdeclarative/src/qmltest/doc/qtqmltest.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtdeclarative/src/qmltest
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in
new file mode 100644
index 000000000..6f59645f3
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtdeclarative/src/quick/doc/qtquick.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtdeclarative/src/quick/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtremoteobjects.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtremoteobjects.qdocconf.in
new file mode 100644
index 000000000..dfad130e6
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtremoteobjects.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtremoteobjects/src/remoteobjects/doc/qtremoteobjects.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtscxml.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtscxml.qdocconf.in
new file mode 100644
index 000000000..30b61a785
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtscxml.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtscxml/src/scxml/doc/qtscxml.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtscxml/src/scxml/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtsensors.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtsensors.qdocconf.in
new file mode 100644
index 000000000..b407db75c
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtsensors.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtsensors/src/sensors/doc/qtsensors.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtsensors/src/sensors/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtserialbus.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtserialbus.qdocconf.in
new file mode 100644
index 000000000..4c67664a5
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtserialbus.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtserialbus/src/serialbus/doc/qtserialbus.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtserialport.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtserialport.qdocconf.in
new file mode 100644
index 000000000..da1b75f7d
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtserialport.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtserialport/src/serialport/doc/qtserialport.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtspatialaudio.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtspatialaudio.qdocconf.in
new file mode 100644
index 000000000..be64648a5
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtspatialaudio.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtmultimedia/src/spatialaudio/doc/qtspatialaudio.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtmultimedia/src/spatialaudio/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtsql.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtsql.qdocconf.in
new file mode 100644
index 000000000..8f41c552c
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtsql.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/sql/doc/qtsql.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtsvg.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtsvg.qdocconf.in
new file mode 100644
index 000000000..e3c39a645
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtsvg.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtsvg/src/svg/doc/qtsvg.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qttest.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qttest.qdocconf.in
new file mode 100644
index 000000000..b092d9294
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qttest.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/testlib/doc/qttestlib.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qttexttospeech.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qttexttospeech.qdocconf.in
new file mode 100644
index 000000000..175b0f4f8
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qttexttospeech.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtspeech/src/tts/doc/qttexttospeech.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtspeech/src/tts/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtuitools.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtuitools.qdocconf.in
new file mode 100644
index 000000000..a950a0b4b
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtuitools.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qttools/src/uitools/doc/qtuitools.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtwebchannel.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtwebchannel.qdocconf.in
new file mode 100644
index 000000000..f3f2f5cf4
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtwebchannel.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtwebchannel/src/webchannel/doc/qtwebchannel.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in
new file mode 100644
index 000000000..90c8d1b1f
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in
@@ -0,0 +1,3 @@
+include(@QT_SRC_DIR@/../qtwebengine/src/core/doc/qtwebengine.qdocconf)
+includepaths += -I @QT_SRC_DIR@/../qtwebengine/src/core/doc
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtwebsockets.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtwebsockets.qdocconf.in
new file mode 100644
index 000000000..082b94883
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtwebsockets.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/../qtwebsockets/src/websockets/doc/qtwebsockets.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtwidgets.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtwidgets.qdocconf.in
new file mode 100644
index 000000000..90e887f38
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtwidgets.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/widgets/doc/qtwidgets.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/qtmodules/pyside-qtxml.qdocconf.in b/sources/pyside6/doc/qtmodules/pyside-qtxml.qdocconf.in
new file mode 100644
index 000000000..f9ccce7d7
--- /dev/null
+++ b/sources/pyside6/doc/qtmodules/pyside-qtxml.qdocconf.in
@@ -0,0 +1,2 @@
+include(@QT_SRC_DIR@/src/xml/doc/qtxml.qdocconf)
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside6/doc/quickstart.rst b/sources/pyside6/doc/quickstart.rst
new file mode 100644
index 000000000..7e1a210f2
--- /dev/null
+++ b/sources/pyside6/doc/quickstart.rst
@@ -0,0 +1,287 @@
+.. _quick-start:
+
+Quick start
+===========
+
+New to Qt? Check also the :ref:`faq-section` section at the end of this page.
+In case you own a Qt License, please refer to :ref:`commercial-page`.
+
+.. note:: Having Qt installed in your system will not interfere with your
+ PySide6 installation if you do it via ``pip install``, because the Python
+ packages (wheels) include already Qt binaries. Most notably, style plugins
+ from the system won't have any effect on PySide applications.
+
+Requirements
+------------
+
+Before you can install |project|, first you must install the following software:
+
+* Python 3.7+,
+* We **highly** recommend using a virtual environment, such as
+ `venv <https://docs.python.org/3/library/venv.html>`_ or
+ `virtualenv <https://virtualenv.pypa.io/en/latest>`_
+ and avoid installing PySide6 via ``pip`` in your system.
+
+.. note:: For Windows users, please use the interpreter from https://python.org/download
+ rather than the one installed from the Microsoft Store.
+
+Installation
+------------
+
+.. note:: For a commercial installation, refer to :ref:`commercial-page`.
+
+* **Creating and activating an environment**
+ You can do this by running the following on a terminal:
+
+ * Create environment (Your Python executable might be called ``python3``)::
+
+ python -m venv env
+
+ * Activate the environment (Linux and macOS)::
+
+ source env/bin/activate
+
+ * Activate the environment (Windows)::
+
+ env\Scripts\activate.bat
+
+ Check this animation on how to do it:
+
+ .. image:: https://qt-wiki-uploads.s3.amazonaws.com/images/8/8a/Pyside6_install.gif
+ :alt: Installation GIF
+
+* **Installing PySide6**
+
+ Now you are ready to install the |project| packages using ``pip``.
+ From the terminal, run the following command:
+
+ * For the latest version::
+
+ pip install pyside6
+
+ * For a specific version, like 6.4.1::
+
+ pip install pyside6==6.4.1
+
+ * It is also possible to install a specific snapshot from our servers.
+ To do so, you can use the following command::
+
+ pip install --index-url=https://download.qt.io/snapshots/ci/pyside/6.4/latest pyside6 --trusted-host download.qt.io
+
+ .. note:: Starting with 6.4.3, PySide6 can be used from inside a
+ `conda <https://conda.io>`_ environment, but any manual changes you make to
+ the ``qt.conf`` file will be ignored. If you want to set custom values to
+ the Qt configuration, set them in a ``qt6.conf`` file instead.
+ Read more about `qt.conf`_.
+
+.. _`qt.conf`: https://doc.qt.io/qt-6/qt-conf.html
+
+* **Test your installation**
+
+ Now that you have |project| installed, test your setup by running the following Python
+ constructs to print version information::
+
+ import PySide6.QtCore
+
+ # Prints PySide6 version
+ print(PySide6.__version__)
+
+ # Prints the Qt version used to compile PySide6
+ print(PySide6.QtCore.__version__)
+
+.. note:: For more information about what's included in the ``pyside6``
+ package, check :ref:`package_details`.
+
+Create a Simple Qt Widgets Application
+--------------------------------------
+
+Your |project| setup is ready. You can explore it further by developing a simple application
+that prints "Hello World" in several languages. The following instructions will
+guide you through the development process:
+
+* **Imports**
+
+ Create a new file named :code:`hello_world.py`, and add the following imports to it.::
+
+ import sys
+ import random
+ from PySide6 import QtCore, QtWidgets, QtGui
+
+ The |pymodname| Python module provides access to the Qt APIs as its submodule.
+ In this case, you are importing the :ref:`QtCore`, :ref:`QtWidgets`, and :ref:`QtGui` submodules.
+
+* **Main Class**
+
+ Define a class named :code:`MyWidget`, which extends :ref:`QWidget` and
+ includes a :ref:`QPushButton` and :ref:`QLabel`.::
+
+ class MyWidget(QtWidgets.QWidget):
+ def __init__(self):
+ super().__init__()
+
+ self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]
+
+ self.button = QtWidgets.QPushButton("Click me!")
+ self.text = QtWidgets.QLabel("Hello World",
+ alignment=QtCore.Qt.AlignCenter)
+
+ self.layout = QtWidgets.QVBoxLayout(self)
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+
+ self.button.clicked.connect(self.magic)
+
+ @QtCore.Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+ The ``MyWidget`` class has the :code:`magic` member function that randomly
+ chooses an item from the :code:`hello` list. When you click the button, the
+ :code:`magic` function is called.
+
+* **Application execution**
+
+ Now, add a main function where you instantiate :code:`MyWidget` and :code:`show` it.::
+
+ if __name__ == "__main__":
+ app = QtWidgets.QApplication([])
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec())
+
+ Run your example by writing the following command: :command:`python hello_world.py`.
+
+ Try clicking the button at the bottom to see which greeting you get.
+
+ .. image:: images/screenshot_hello.png
+ :alt: Hello World application
+
+Create a Simple Quick Application
+---------------------------------
+
+To do the same using Qt Quick:
+
+* **Imports**
+
+ Create a new file named :code:`hello_world_quick.py`, and add the following imports to it.::
+
+ import sys
+ from PySide6.QtGui import QGuiApplication
+ from PySide6.QtQml import QQmlApplicationEngine
+
+* **Declarative UI**
+
+ The UI can be described in the QML language (assigned to a Python variable)::
+
+ QML = """
+ import QtQuick
+ import QtQuick.Controls
+ import QtQuick.Layouts
+
+ Window {
+ width: 300
+ height: 200
+ visible: true
+ title: "Hello World"
+
+ readonly property list<string> texts: ["Hallo Welt", "Hei maailma",
+ "Hola Mundo", "Привет мир"]
+
+ function setText() {
+ var i = Math.round(Math.random() * 3)
+ text.text = texts[i]
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+
+ Text {
+ id: text
+ text: "Hello World"
+ Layout.alignment: Qt.AlignHCenter
+ }
+ Button {
+ text: "Click me"
+ Layout.alignment: Qt.AlignHCenter
+ onClicked: setText()
+ }
+ }
+ }
+ """
+
+ .. note:: Keep in mind ideally this content should go into
+ a ``qml`` file, but for simplicity, we are using a string variable.
+
+* **Application execution**
+
+ Now, add a main function where you instantiate a :ref:`QQmlApplicationEngine` and
+ load the QML::
+
+ if __name__ == "__main__":
+ app = QGuiApplication(sys.argv)
+ engine = QQmlApplicationEngine()
+ engine.loadData(QML.encode('utf-8'))
+ if not engine.rootObjects():
+ sys.exit(-1)
+ exit_code = app.exec()
+ del engine
+ sys.exit(exit_code)
+
+
+ .. note:: This is a simplified example. Normally, the QML code should be in a separate
+ :code:`.qml` file, which can be edited by design tools.
+
+.. _faq-section:
+
+Frequently Asked Questions
+--------------------------
+
+Here you can find a couple of common questions and situations that will
+clarify questions before you start programming.
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: What is Qt
+ :link: faq/whatisqt.html
+
+ Qt, QML, Widgets... What is the difference?
+
+ .. grid-item-card:: Compatible IDEs
+ :link: faq/whichide.html
+
+ Which IDEs are compatible with PySide?
+
+ .. grid-item-card:: Binding Generation
+ :link: faq/whatisshiboken.html
+
+ What is Shiboken?
+
+ .. grid-item-card:: File types
+ :link: faq/typesoffiles.html
+
+ File Types in PySide
+
+ .. grid-item-card:: App distribution
+ :link: faq/distribution.html
+
+ Distributing your application to other systems and platforms
+
+ .. grid-item-card:: Why Qt for Python?
+ :link: faq/whyqtforpython.html
+
+ As a Qt/C++ developer, why should I consider Qt for Python?
+
+.. toctree::
+ :hidden:
+
+ faq/whatisqt.rst
+ faq/whichide.rst
+ faq/whatisshiboken.rst
+ faq/typesoffiles.rst
+ faq/distribution.rst
+ faq/whyqtforpython.rst
+
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_0.cpp.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_0.cpp.py
new file mode 100644
index 000000000..d21595041
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_0.cpp.py
@@ -0,0 +1,4 @@
+i, ok = QInputDialog.getInt(self, "QInputDialog::getInt()",
+ "Percentage:", 25, 0, 100, 1)
+if ok:
+ integerLabel.setText(f"{i}")
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_1.cpp.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_1.cpp.py
new file mode 100644
index 000000000..4cb3dfdb3
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_1.cpp.py
@@ -0,0 +1,5 @@
+d, ok = QInputDialog.getDouble(self, "QInputDialog::getDouble()",
+ "Amount:", 37.56, -10000, 10000, 2,
+ Qt.WindowFlags(), 1)
+if ok:
+ doubleLabel.setText(f"${d}")
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_2.cpp.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_2.cpp.py
new file mode 100644
index 000000000..7e3d27afb
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_2.cpp.py
@@ -0,0 +1,5 @@
+items = ["Spring", "Summer", "Fall", "Winter"]
+item, ok = QInputDialog.getItem(self, "QInputDialog::getItem()",
+ "Season:", items, 0, False)
+if ok and item:
+ itemLabel.setText(item)
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_3.cpp.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_3.cpp.py
new file mode 100644
index 000000000..85a22a16c
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_3.cpp.py
@@ -0,0 +1,5 @@
+text, ok = QInputDialog.getText(self, "QInputDialog.getText()",
+ "User name:", QLineEdit.Normal,
+ QDir.home().dirName())
+if ok and text:
+ textLabel.setText(text)
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_4.cpp.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_4.cpp.py
new file mode 100644
index 000000000..d16045141
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/dialogs/standarddialogs/dialog_4.cpp.py
@@ -0,0 +1,4 @@
+text, ok = QInputDialog.getMultiLineText(self, "QInputDialog.getMultiLineText()", ""
+ "Address:", "John Doe\nFreedom Street")
+if ok and text:
+ multiLineTextLabel.setText(text)
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/itemviews/spinboxdelegate/delegate_0.h.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/itemviews/spinboxdelegate/delegate_0.h.py
new file mode 100644
index 000000000..de386a5ac
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/itemviews/spinboxdelegate/delegate_0.h.py
@@ -0,0 +1,18 @@
+class SpinBoxDelegate(QStyledItemDelegate):
+ """A delegate that allows the user to change integer values from the model
+ using a spin box widget. """
+
+ def __init__(self, parent=None):
+ ...
+
+ def createEditor(self, parent, option, index):
+ ...
+
+ def setEditorData(self, editor, index):
+ ...
+
+ def setModelData(self, editor, model, index):
+ ...
+
+ def updateEditorGeometry(self, editor, option, index):
+ ...
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/1_readonly/mymodel_Quoting_ModelView_Tutorial.h.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/1_readonly/mymodel_Quoting_ModelView_Tutorial.h.py
new file mode 100644
index 000000000..231792c5d
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/1_readonly/mymodel_Quoting_ModelView_Tutorial.h.py
@@ -0,0 +1,15 @@
+from PySide6.QtCore import QAbstractTableModel
+
+class MyModel(QAbstractTableModel):
+
+ def __init__(self, parent = None):
+ ...
+
+ def rowCount(self, parent = None):
+ ...
+
+ def columnCount(self, parent = None):
+ ...
+
+ def data(self, index, role = Qt.DisplayRole):
+ ...
diff --git a/sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/5_edit/mymodel_Quoting_ModelView_Tutorial.h.py b/sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/5_edit/mymodel_Quoting_ModelView_Tutorial.h.py
new file mode 100644
index 000000000..4da28f0a0
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/examples/widgets/tutorials/modelview/5_edit/mymodel_Quoting_ModelView_Tutorial.h.py
@@ -0,0 +1,27 @@
+from PySide6.QtCore import QAbstractTableModel
+
+COLS = 3
+ROWS = 2
+
+
+class MyModel(QAbstractTableModel):
+
+ editCompleted = Signal(str)
+
+ def __init__(self, parent=None):
+ ...
+
+ def rowCount(self, parent=None):
+ ...
+
+ def columnCount(self, parent=None):
+ ...
+
+ def data(self, index, role=Qt.DisplayRole):
+ ...
+
+ def setData(self, index, value, role):
+ ...
+
+ def flags(self, index):
+ ...
diff --git a/sources/pyside6/doc/snippets/qtbase/src/gui/doc/snippets/code/src_gui_painting_qpainter_drawText.cpp.py b/sources/pyside6/doc/snippets/qtbase/src/gui/doc/snippets/code/src_gui_painting_qpainter_drawText.cpp.py
new file mode 100644
index 000000000..cad2c5395
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/src/gui/doc/snippets/code/src_gui_painting_qpainter_drawText.cpp.py
@@ -0,0 +1,13 @@
+painter = QPainter(self)
+font = painter.font()
+font.setPixelSize(48)
+painter.setFont(font)
+rectangle = QRect(0, 0, 100, 50)
+boundingRect = painter.drawText(rectangle, 0, "Hello")
+pen = painter.pen()
+pen.setStyle(Qt.DotLine)
+painter.setPen(pen)
+painter.drawRect(boundingRect.adjusted(0, 0, -pen.width(), -pen.width()))
+pen.setStyle(Qt.DashLine)
+painter.setPen(pen)
+painter.drawRect(rectangle.adjusted(0, 0, -pen.width(), -pen.width()))
diff --git a/sources/pyside6/doc/snippets/qtbase/src/widgets/doc/snippets/stringlistmodel/model_0.h.py b/sources/pyside6/doc/snippets/qtbase/src/widgets/doc/snippets/stringlistmodel/model_0.h.py
new file mode 100644
index 000000000..02a02aaf8
--- /dev/null
+++ b/sources/pyside6/doc/snippets/qtbase/src/widgets/doc/snippets/stringlistmodel/model_0.h.py
@@ -0,0 +1,24 @@
+class StringListModel(QAbstractListModel):
+ def __init__(self, strings, parent=None):
+ ...
+
+ def rowCount(self, parent=QModelIndex()):
+ ...
+
+ def data(self, index, role):
+ ...
+
+ def headerData(self, section, orientation, role=Qt.DisplayRole):
+ ...
+
+ def flags(self, index):
+ ...
+
+ def setData(self, index, value, role=Qt.EditRole):
+ ...
+
+ def insertRows(self, position, rows, parent):
+ ...
+
+ def removeRows(self, position, rows, parent):
+ ...
diff --git a/sources/pyside6/doc/src/README.md b/sources/pyside6/doc/src/README.md
new file mode 100644
index 000000000..df37cf691
--- /dev/null
+++ b/sources/pyside6/doc/src/README.md
@@ -0,0 +1 @@
+Any qdoc source files in this directory will be parsed when generating docs.
diff --git a/sources/pyside6/doc/tools/index.rst b/sources/pyside6/doc/tools/index.rst
new file mode 100644
index 000000000..b421a428f
--- /dev/null
+++ b/sources/pyside6/doc/tools/index.rst
@@ -0,0 +1,211 @@
+.. _package_tools:
+
+Tools
+=====
+
+Following the same idea from the modules, we also include in the packages
+(wheels) Qt tools that are important for any Qt application development
+workflow, like ``uic``, ``rcc``, etc.
+
+All the tools **must** be used from the PySide wrappers, and not directly.
+For example, if exploring the ``site-packages/`` directory on your installation
+you find ``uic.exe`` (on Windows), you should not click on that, and use
+``pyside6-uic.exe`` instead.
+The reason for this is the proper setup of PATHs, plugins, and more,
+to properly work with the installed Python package.
+
+Here you can find all the tools we include in |project| starting
+from 6.3.0, grouped by different topics:
+
+Project development
+~~~~~~~~~~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-project``
+ :link: pyside6-project
+ :link-type: ref
+
+ to build *Qt Widgets Designer* forms (``.ui`` files),
+ resource files (``.qrc``) and QML type files (``.qmltype``)
+ from a ``.pyproject`` file.
+
+Widget Development
+~~~~~~~~~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-designer``
+ :link: pyside6-designer
+ :link-type: ref
+
+ drag-and-drop tool for designing Widget UIs (generates ``.ui`` files,
+ see :ref:`using_ui_files`).
+
+ .. grid-item-card:: ``pyside6-uic``
+ :link: pyside6-uic
+ :link-type: ref
+
+ to generate Python code from ``.ui`` form files.
+
+ .. grid-item-card:: ``pyside6-rcc``
+ :link: pyside6-rcc
+ :link-type: ref
+
+ to generate serialized data from ``.qrc`` resources files.
+ Keep in mind these files can be used in other non-widget projects.
+
+
+QML Development
+~~~~~~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-qmllint``
+ :link: pyside6-qmllint
+ :link-type: ref
+
+ that verifies the syntactic validity of QML files.
+
+ .. grid-item-card:: ``pyside6-qmltyperegistrar``
+ :link: pyside6-qmltyperegistrar
+ :link-type: ref
+
+ to read metatypes files and generate files that contain the necessary
+ code to register all the types marked with relevant macros.
+
+ .. grid-item-card:: ``pyside6-qmlimportscanner``
+ :link: pyside6-qmlimportscanner
+ :link-type: ref
+
+ to identify the QML modules imported from a
+ project/QML files and dump the result as a JSON array.
+
+ .. grid-item-card:: ``pyside6-qmlcachegen``
+ :link: pyside6-qmlcachegen
+ :link-type: ref
+
+ to compile QML to bytecode at compile time for bundling inside the
+ binary.
+
+ .. grid-item-card:: ``pyside6-qml``
+ :link: pyside6-qml
+ :link-type: ref
+
+ to enable quick prototyping with QML files. This tool mimics some of
+ the capabilities of Qt's ``QML`` runtime utility by
+ directly invoking QQmlEngine/QQuickView.
+
+Translations
+~~~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-linguist``
+ :link: pyside6-linguist
+ :link-type: ref
+
+ for translating text in applications.
+
+ .. grid-item-card:: ``pyside6-lrelease``
+ :link: pyside6-lrelease
+ :link-type: ref
+
+ to create run-time translation files for the application.
+
+ .. grid-item-card:: ``pyside6-lupdate``
+ :link: pyside6-lupdate
+ :link-type: ref
+
+ to synchronize source code and translations.
+
+Qt Help
+~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-assistant``
+ :link: pyside6-assistant
+ :link-type: ref
+
+ for viewing online documentation in Qt Help file format.
+ Read more about the formats on the `QtHelp Framework`_ page.
+
+.. _`QtHelp Framework`: https://doc.qt.io/qt-6/qthelp-framework.html
+
+PySide Utilities
+~~~~~~~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-genpyi``
+ :link: pyside6-genpyi
+ :link-type: ref
+
+ to generate Python stubs (``.pyi`` files) for Qt modules.
+
+ .. grid-item-card:: ``pyside6-metaobjectdump``
+ :link: pyside6-metaobjectdump
+ :link-type: ref
+
+ a tool to print out the metatype information in JSON to be used as
+ input for ``qmltyperegistrar``.
+
+Deployment
+~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-deploy``
+ :link: pyside6-deploy
+ :link-type: ref
+
+ to deploy PySide6 applications to desktop platforms - Linux, Windows
+ and macOS.
+
+ .. grid-item-card:: ``pyside6-android-deploy``
+ :link: pyside6-android-deploy
+ :link-type: ref
+
+ to deploy PySide6 application as an Android app targeting different
+ Android platforms - aarch64, armv7a, i686, x86_64.
+
+Shader Tools
+~~~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-qsb``
+ :link: pyside6-qsb
+ :link-type: ref
+
+ a command-line tool provided by the Qt Shader Tools modules to
+ generate and inspect .qsb files.
+
+Qt Quick 3D
+~~~~~~~~~~~
+
+.. grid:: 2
+ :gutter: 3 3 4 5
+
+ .. grid-item-card:: ``pyside6-balsam``
+ :link: pyside6-balsam
+ :link-type: ref
+
+ a command line tool that takes assets created in digital content
+ creation tools like Maya, 3ds Max or Blender and converts them into an
+ efficient runtime format for use with Qt Quick 3D.
+
+ .. grid-item-card:: ``pyside6-balsamui``
+ :link: pyside6-balsamui
+ :link-type: ref
+
+ a graphical user interface for the ``pyside6-balsam`` tool.
diff --git a/sources/pyside6/doc/tools/pyside-assistant.rst b/sources/pyside6/doc/tools/pyside-assistant.rst
new file mode 100644
index 000000000..c9b3470c3
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-assistant.rst
@@ -0,0 +1,21 @@
+.. _pyside6-assistant:
+
+pyside6-assistant
+=================
+
+``pyside6-assistant`` is a tool that wraps `Qt Assistant`_, the help
+viewer of Qt for use with the Qt help file format (see `The Qt Help Framework`_).
+
+The version of assistant shipped with Qt for Python does not contain
+any documentation.
+
+You can build the Qt for Python documentation in the Qt help file format
+(see :ref:`building_documentation`) and register it for use in `Preferences`
+dialog of ``pyside6-assistant`` (`Edit/Preferences`).
+
+.. image:: pyside6-assistant_screenshot.webp
+ :width: 381
+ :alt: PySide6 Assistant Screenshot
+
+.. _`Qt Assistant`: https://doc.qt.io/qt-6/qtassistant-index.html
+.. _`The Qt Help Framework`: https://doc.qt.io/qt-6/qthelp-framework.html
diff --git a/sources/pyside6/doc/tools/pyside-designer.rst b/sources/pyside6/doc/tools/pyside-designer.rst
new file mode 100644
index 000000000..4cde6b2bf
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-designer.rst
@@ -0,0 +1,91 @@
+.. _pyside6-designer:
+
+pyside6-designer
+================
+
+``pyside6-designer`` is a tool that wraps the `Qt Widgets Designer`_,
+to enable you to design Qt Widgets applications with a *drag-and-drop*
+approach.
+
+.. image:: pyside6-designer_screenshot.webp
+ :width: 100%
+ :alt: PySide6 Designer Screenshot
+
+Usage
+-----
+
+With ``pyside6-designer`` you can design your application in a simple way,
+to later save the end result in a ``.ui`` file. When you start the tool, you
+will see a dialog to select the base window: a QWidget, a QMainWindow, etc.
+
+.. image:: pyside6-designer_base_screenshot.webp
+ :width: 50%
+ :alt: PySide6 Designer Initial Screenshot
+
+Once you select one of those options, you can start placing widgets
+into the interface, and have access to the whole structure, properties,
+and more.
+
+.. image:: pyside6-designer_sections_screenshot.webp
+ :width: 100%
+ :alt: PySide6 Designer Initial Screenshot
+
+A simple distinction of the areas you might use is described in the
+previous screenshot. In the section **1** you will find all the elements
+you can use in your application, which is the area **2**.
+The application designs follows a hierarchical configuration,
+in **3** you can see the structure of the example which contains
+only a ``QMainWindow`` and a ``QPushButton``. Lastly
+you can access and modify the properties of the item in **4**,
+where you could adjust dimensions, names, etc.
+
+
+When your application is finished, you will save your design in a ``.ui``
+file. This ``.ui`` file can later be converted into a Python file,
+with the help of the :ref:`pyside6-uic` tool. You can find
+more details of this process in: :ref:`using_ui_files`.
+
+If you are interested in more functionality of the tool, you can check
+the official `Qt Widgets Designer Manual`_.
+
+
+Custom Widgets
+--------------
+
+One of the features that the `Qt Widgets Designer`_ provides is the possibility
+of loading custom widgets, in order to facilitate the development with ad-hoc
+widgets.
+
+On the following screenshot, you can see a new component on the left column
+that is already added on the main widget, a tic-tac-toe custom widget.
+
+.. image:: pyside6-designer_customwidgets_screenshot.webp
+ :width: 100%
+ :alt: PySide6 Designer Custom Widgets Screenshot
+
+To achieve this, you need to register a custom widget by setting the environment
+variable ``PYSIDE_DESIGNER_PLUGINS`` to the directory where your register file
+is located. The registration file for the tic-tac-toe widget looks like this:
+
+.. code-block:: Python
+
+ from tictactoe import TicTacToe
+ from tictactoeplugin import TicTacToePlugin
+
+ from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
+
+
+ if __name__ == '__main__':
+ QPyDesignerCustomWidgetCollection.addCustomWidget(TicTacToePlugin())
+
+As you can see in the previous code, ``TicTacToe`` is the custom widget,
+imported from a different file, and the ``TicTacToePlugin`` is the interface
+layer for `Qt Widgets Designer`_ to recognize it.
+We provide a helper class, ``QPyDesignerCustomWidgetCollection``, to
+simplify the registration process.
+
+If you are interested in all the details of this specific case, you can
+check the :ref:`task-menu-extension-example`.
+
+.. _`Qt Widgets Designer`: https://doc.qt.io/qt-6/qtdesigner-manual.html
+.. _`Qt Widgets Designer Manual`: https://doc.qt.io/qt-6/qtdesigner-manual.html
diff --git a/sources/pyside6/doc/tools/pyside-genpyi.rst b/sources/pyside6/doc/tools/pyside-genpyi.rst
new file mode 100644
index 000000000..0240c5005
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-genpyi.rst
@@ -0,0 +1,52 @@
+.. _pyside6-genpyi:
+
+pyside6-genpyi
+==============
+
+`pyside6-genpyi` is a command line tool to generate Python stub files
+(.pyi) for PySide modules. Stub files define signatures of all classes,
+methods (including overloads), constants and enums of the PySide
+modules. Signatures also contain type hints. This helps PySide integrate
+with Python type checkers and IDEs. For example, if you use any function
+from the Qt API with PySide, your IDE's function lookup feature will
+show you the function signature and its parameters and return value
+including types.
+
+PySide6 already ships with stub files that were generated with
+`pyside6-genpyi`. However, if you want to generate new stub files for
+several (or all) modules, for example to toggle a few features, you can
+run `pyside6-genpyi` manually. If you want to generate stub files for
+your own custom module, refer to :ref:`shiboken6-genpyi`.
+
+
+Usage
+-----
+
+To generate stub files for a PySide module, run the following command:
+
+.. code-block:: bash
+
+ pyside6-genpyi <module_names> [OPTIONS]
+
+where `<module_names>` is a space-separated list of module names (the
+modules must be importable from the working directory) and where
+`[OPTIONS]` can be one of the following:
+
+* **--quiet**: Run the tool quietly without output to stdout.
+* **--outpath <output_dir>**: Specify the output directory for the
+ generated stub files. If not specified, the stub files are generated
+ in the location of the module binary.
+* **--sys-path <paths>**: Prepend the system path (`sys.path`) with a
+ space-separated list of strings `<paths>`. This is useful if the
+ module is not installed in a default lookup location.
+* **--feature <features>**: A space-separate list of optional PySide
+ features to enable (see :ref:`pysideapi2`). This option has no effect
+ when using PyPy. Currently, the following features are available:
+
+ * **snake_case**: All methods in the module are switched from
+ ``camelCase`` to ``snake_case``. A single upper case letter is
+ replaced by an underscore and the lower case letter.
+ * **true_property**: All getter and setter functions in the module
+ which are marked as a property in the Qt6 docs are replaced by Python
+ property objects. Properties are also listed as such in the according
+ QMetaObject of a class.
diff --git a/sources/pyside6/doc/tools/pyside-linguist.rst b/sources/pyside6/doc/tools/pyside-linguist.rst
new file mode 100644
index 000000000..e13124a8e
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-linguist.rst
@@ -0,0 +1,20 @@
+.. _pyside6-linguist:
+
+pyside6-linguist
+=================
+
+``pyside6-linguist`` is a tool that wraps `Qt Linguist`_, Qt's tool to
+translate user interfaces and manage application localizations. It
+supports Qt's own TS file format as well as the XML Localization
+Interchange File Format (XLIFF). There are no differences between the
+version bundled with PySide and the one from Qt.
+
+For more information on how to use this tool, read Qt's documentation
+here: `Qt Linguist`_. Read more about how to translate PySide
+applications here: :ref:`translations`.
+
+.. image:: pyside6-linguist_screenshot.webp
+ :width: 500
+ :alt: PySide6 Linguist Screenshot
+
+.. _`Qt Linguist`: https://doc.qt.io/qt-6/qtlinguist-index.html
diff --git a/sources/pyside6/doc/tools/pyside-lrelease.rst b/sources/pyside6/doc/tools/pyside-lrelease.rst
new file mode 100644
index 000000000..7c628f2aa
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-lrelease.rst
@@ -0,0 +1,25 @@
+.. _pyside6-lrelease:
+
+pyside6-lrelease
+================
+
+.. note:: This tool is automatically called by :ref:`pyside6-project`
+ so you don't need to call it manually. *Qt Creator* will take care
+ of this step as well while executing a project.
+
+``pyside6-lrelease`` is a command line tool wrapping `lrelease`_. It produces
+``.qm`` files out of ``.ts`` files. The ``.qm`` file format is a compact binary
+format that the localized application uses. It provides extremely fast lookup
+for translations (see :ref:`translations`).
+
+Usage
+-----
+
+To convert a ``.ts`` file of the :ref:`qt-linguist-example`
+into its binary representation, run:
+
+.. code-block:: bash
+
+ pyside6-lrelease example_de.ts -qm example_de.qm
+
+.. _`lrelease`: https://doc.qt.io/qt-6/linguist-lrelease.html
diff --git a/sources/pyside6/doc/tools/pyside-lupdate.rst b/sources/pyside6/doc/tools/pyside-lupdate.rst
new file mode 100644
index 000000000..1c0d73c15
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-lupdate.rst
@@ -0,0 +1,23 @@
+.. _pyside6-lupdate:
+
+pyside6-lupdate
+===============
+
+.. note:: This tool is automatically called by :ref:`pyside6-project`
+ so you don't need to call it manually.
+
+``pyside6-lupdate`` is a command line tool wrapping `lupdate`_. It finds
+translatable strings in Python, ``.ui``, and ``.qml`` files and generates or
+updates ``.ts`` files (see :ref:`translations`).
+
+Usage
+-----
+
+To create or update the ``.ts`` file of the :ref:`qt-linguist-example`,
+run:
+
+.. code-block:: bash
+
+ pyside6-lupdate main.py main.qml form.ui -ts example_de.ts
+
+.. _`lupdate`: https://doc.qt.io/qt-6/linguist-lupdate.html
diff --git a/sources/pyside6/doc/tools/pyside-metaobjectdump.rst b/sources/pyside6/doc/tools/pyside-metaobjectdump.rst
new file mode 100644
index 000000000..1522b7ad5
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-metaobjectdump.rst
@@ -0,0 +1,92 @@
+.. _pyside6-metaobjectdump:
+
+pyside6-metaobjectdump
+======================
+
+``pyside6-metaobjectdump`` is a command line tool. It scans Python source
+files and dumps out information on classes to be registered with QML in
+JSON-format. This serves as input for the :ref:`pyside6-qmltyperegistrar` tool.
+
+The tool is the equivalent of the `moc`_ tool in Qt / C++.
+
+It is automatically run by the :ref:`pyside6-project` tool
+when passing the ``qmllint`` argument instructing it to check
+the QML source files.
+
+Usage
+-----
+
+Classes to be registered with QML are indicated by QML decorators
+like :deco:`QmlElement`. Invoking:
+
+.. code-block:: bash
+
+ pyside6-metaobjectdump birthdayparty.py
+
+produces the JSON data on stdout:
+
+.. code-block:: json
+
+ [
+ {
+ "classes": [
+ {
+ "className": "BirthdayParty",
+ "qualifiedClassName": "BirthdayParty",
+ "object": true,
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ],
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "auto"
+ }
+ ],
+ "properties": [
+ {
+ "name": "host",
+ "type": "Person",
+ "index": 0,
+ "read": "host",
+ "notify": "host_changed",
+ "write": "host"
+ },
+ {
+ "name": "guests",
+ "type": "QQmlListProperty<Person>",
+ "index": 1
+ }
+ ],
+ "signals": [
+ {
+ "access": "public",
+ "name": "host_changed",
+ "arguments": [],
+ "returnType": "void"
+ },
+ {
+ "access": "public",
+ "name": "guests_changed",
+ "arguments": [],
+ "returnType": "void"
+ }
+ ]
+ }
+ ],
+ "outputRevision": 68,
+ "QML_IMPORT_NAME": "People",
+ "QML_IMPORT_MAJOR_VERSION": 1,
+ "QML_IMPORT_MINOR_VERSION": 0,
+ "QT_MODULES": [
+ "QtCore",
+ "QtQml"
+ ],
+ "inputFile": ".../examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.py"
+ }
+ ]
+
+.. _`moc`: https://doc.qt.io/qt-6/moc.html
diff --git a/sources/pyside6/doc/tools/pyside-project.rst b/sources/pyside6/doc/tools/pyside-project.rst
new file mode 100644
index 000000000..0359e1b7d
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-project.rst
@@ -0,0 +1,64 @@
+.. _pyside6-project:
+
+pyside6-project
+===============
+
+`pyside6-project` is a command line tool for creating, building and deploying
+|project| applications. It operates on a project file which is also used by
+`Qt Creator`_.
+
+Project file format
+-------------------
+
+The project file format is a simple `JSON`_-based format with the suffix
+``.pyproject`` listing all files of the project excluding generated files
+(typically ``.py``, ``.qml``, ``.qrc``, ``.ts``, or ``.ui`` files):
+
+.. code-block:: json
+
+ {
+ "files": ["main.py"]
+ }
+
+
+Usage
+-----
+
+The tool has several subcommands. New projects can be created using
+the below commands, passing the project name (directory):
+
+*new-ui*
+ Creates a new QtWidgets project with a *Qt Widgets Designer*-based main
+ window.
+
+*new-widget*
+ Creates a new QtWidgets project with a main window.
+
+*new-quick*
+ Creates a new QtQuick project.
+
+The other commands take the project file as an argument.
+It is also possible to specify a directory containing the project file.
+
+*build*
+ Builds the project, generating the required build artifacts
+ (see :ref:`using_ui_files`, :ref:`using_qrc_files`).
+
+*run*
+ Builds the project and runs the main.
+
+*deploy*
+ Deploys the application (see see :ref:`pyside6-deploy`).
+
+*lupdate*
+ Updates translation (.ts) files (see :ref:`translations`).
+
+*clean*
+ Cleans the build artifacts.
+
+*qmllint*
+ Runs the ``qmllint`` tool, checking the QML files.
+
+
+.. _`Qt Creator`: https://www.qt.io/product/development-tools
+.. _`JSON`: https://www.json.org/
diff --git a/sources/pyside6/doc/tools/pyside-qml.rst b/sources/pyside6/doc/tools/pyside-qml.rst
new file mode 100644
index 000000000..0502dd94a
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-qml.rst
@@ -0,0 +1,84 @@
+.. _pyside6-qml:
+
+pyside6-qml
+===========
+
+``pyside6-qml`` mimics some capabilities of Qt's `qml <qml_runtime>`_ runtime utility by directly
+invoking QQmlEngine/QQuickView. It enables prototyping with QML/QtQuick without the need to write
+any Python code that loads the QML files either through `QQmlApplicationEngine <qqmlappengine>`_ or
+the `QQuickView <qquickview>`_ class. The tool also detects the QML classes implemented in Python
+and registers them with the QML type system.
+
+Usage
+-----
+
+Consider the example `Extending QML - Plugins Example <extending_qml_example>`_. This example does
+not have a Python file with a ``main`` function that initializes a QmlEngine to load the QML file
+``app.qml``. You can run the example by running
+
+.. code-block:: bash
+
+ pyside6-qml examples/qml/tutorials/extending-qml/chapter6-plugins/app.qml -I examples/qml/tutorials/extending-qml/chapter6-plugins/Charts
+
+The ``-I`` flag is used to point ``pyside6-qml`` to the folder containing Python files that
+implement QML classes.
+
+Command Line Options
+--------------------
+
+Here are all the command line options of ``pyside6-qml``:
+
+Arguments
+^^^^^^^^^
+
+* **file**: This option refers to the QML file to be loaded by ``pyside6-qml``. This option does not
+ have a name or a flag. Therefore, this option should be the first option supplied to
+ ``pyside6-qml``. For example,
+
+.. code-block:: bash
+
+ pyside6-qml /path/to/test.qml
+
+Options
+^^^^^^^
+
+* **--module-paths/-I**: Specify space-separated folder/file paths which point to the Python files
+ that implement QML classes. By default, the parent directory of the QML file supplied to
+ ``pyside6-qml`` is searched recursively for all Python files and they are imported. Otherwise,
+ only the paths given in module paths are searched.
+
+* **--verbose/-v**: Run ``pyside6-qml`` in verbose mode. When run in this mode, pyside6-qml prints
+ log messages during various stages of processing.
+
+Options that align with `QML <qml_runtime>`_ runtime utility
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* **--app-typ/-a**: Specifies which application class to use. It takes one of the three values -
+ ``core, gui, widget``. The default value is *gui*.
+
+* **--config/-c**: Load the given built-in configuration. It takes one of two values - ``default,
+ resizeToItem``. This option is only relevant for a QtQuick application. If ``default`` is used,
+ the view resizes to the size of the root item in the QML. If ``resizeToItem`` is used, the view
+ automatically resizes the root item to the size of the view.
+
+* **--list-conf**: List the built-in configurations. ``pyside6-qml`` has two built-in configurations
+ - ``default`` and ``resizeToItem``. See the option ``--config`` for more information.
+
+* **--rhi/-r**: Specifies the backend for the Qt graphics abstraction (RHI). It takes one of the
+ four values - ``vulkan, metal, d3dll, gl``.
+
+* **--verbose/-v**: List the built-in configurations. ``pyside6-qml`` has two built-in
+ configurations - *default* and *resizeToItem*. See the option ``--config`` for more information.
+
+* **--gles**: Force use of GLES (AA_UseOpenGLES).
+
+* **--desktop**: Force use of desktop OpenGL (AA_UseDesktopOpenGL).
+
+* **--software**: Force use of software rendering(AA_UseSoftwareOpenGL).
+
+* **--disable-context-sharing**: Disable the use of a shared GL context for QtQuick Windows".
+
+.. _`qml_runtime`: https://doc.qt.io/qt-6/qtquick-qml-runtime.html
+.. _`qqmlappengine`: https://doc.qt.io/qt-6/qqmlapplicationengine.html
+.. _`qquickview`: https://doc.qt.io/qt-6/qquickview.html
+.. _`extending_qml_example`: https://doc.qt.io/qtforpython-6/examples/example_qml_tutorials_extending-qml_chapter6-plugins.html
diff --git a/sources/pyside6/doc/tools/pyside-qmlcachegen.rst b/sources/pyside6/doc/tools/pyside-qmlcachegen.rst
new file mode 100644
index 000000000..ecd8e6afd
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-qmlcachegen.rst
@@ -0,0 +1,25 @@
+.. _pyside6-qmlcachegen:
+
+pyside6-qmlcachegen
+===================
+
+``pyside6-qmlcachegen`` is a command line tool that wraps `qmlcachegen`_.
+This tool creates C++ code or `QML byte code` for ``.qml`` files. For
+Qt for Python, only `QML byte code` is relevant. The file suffix is
+``.qmlc`` and it works similar to compiled Python bytecode
+(``.pyc`` files).
+
+Usage
+-----
+
+The command line option ``--only-bytecode`` should be used to
+create `QML byte code`. For example:
+
+.. code-block:: bash
+
+ qmlcachegen --only-bytecode gallery.qml
+
+produces a file ``gallery.qmlc`` containing `QML byte code` which is
+automatically loaded by the QML engine.
+
+.. _`qmlcachegen`: https://doc.qt.io/qt-6/qtqml-tool-qmlcachegen.html
diff --git a/sources/pyside6/doc/tools/pyside-qmllint.rst b/sources/pyside6/doc/tools/pyside-qmllint.rst
new file mode 100644
index 000000000..54a72470e
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-qmllint.rst
@@ -0,0 +1,49 @@
+.. _pyside6-qmllint:
+
+pyside6-qmllint
+===============
+
+``pyside6-qmllint`` is a command line tool that wraps `qmllint`_. This tool
+verifies the syntatic validity of QML files and warns about some QML
+anti-patterns.
+
+It is automatically run by the :ref:`pyside6-project` tool
+when passing the ``qmllint`` argument instructing it to check
+the QML source files.
+
+Usage
+-----
+
+The tool should normally not be invoked manually since it requires
+a number of import paths and additional type information
+generated by :ref:`pyside6-qmltyperegistrar` to function.
+
+For example, for a ``.qml`` file like:
+
+.. code-block:: javascript
+
+ import QtQuick
+ import QtQuick.Controls
+
+ Item {
+ Text {
+ id: name
+ text: qsTr("Hello World")
+ }
+ }
+
+when running:
+
+.. code-block:: bash
+
+ pyside6-qmllint Main.qml
+
+it would warn about unused imports:
+
+.. code-block::
+
+ Info: Main.qml:2:1: Unused import [unused-imports]
+ import QtQuick.Controls
+ ^^^^^^
+
+.. _`qmllint`: https://doc.qt.io/qt-6/qtquick-tool-qmllint.html
diff --git a/sources/pyside6/doc/tools/pyside-qmltyperegistrar.rst b/sources/pyside6/doc/tools/pyside-qmltyperegistrar.rst
new file mode 100644
index 000000000..0e8d66bd5
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-qmltyperegistrar.rst
@@ -0,0 +1,17 @@
+.. _pyside6-qmltyperegistrar:
+
+pyside6-qmltyperegistrar
+========================
+
+``pyside6-qmltyperegistrar`` is a command line tool that wraps the
+``qmltyperegistrar`` tool of Qt.
+
+It takes the file produced by :ref:`pyside6-metaobjectdump`
+as input and generates C++ code to register C++ classes to QML
+and a ``.qmltypes`` file containing a JSON description of the
+classes. For Qt for Python, only the ``.qmltypes`` file
+is of interest as input for :ref:`pyside6-qmllint`.
+
+The tool is automatically run by the :ref:`pyside6-project` tool
+when passing the ``qmllint`` argument instructing it to check
+the QML source files.
diff --git a/sources/pyside6/doc/tools/pyside-rcc.rst b/sources/pyside6/doc/tools/pyside-rcc.rst
new file mode 100644
index 000000000..e5688485e
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-rcc.rst
@@ -0,0 +1,55 @@
+.. _pyside6-rcc:
+
+pyside6-rcc
+===========
+
+.. note:: This tool is automatically called by :ref:`pyside6-project`
+ so you don't need to call it manually. *Qt Creator* will take care
+ of this step as well while executing a project.
+
+
+``pyside6-rcc`` is a command line tool for converting ``.qrc`` files into ``.py``
+files, so they can be used within your Python code.
+
+The tool is a wrapper around the `rcc`_ tool, which was originally
+designed to generate C++ code, but it also has Python support.
+
+Even though the equivalent of ``pyside6-rcc`` is running ``rcc -g python``
+we strongly recommend you to rely on ``pyside6-rcc`` in order to avoid
+mismatches between versions for the generated code.
+
+Usage
+-----
+
+Once you have gathered your resources on a qrc file,
+you can transform your ``.qrc`` file with the following command:
+
+.. code-block:: bash
+
+ pyside6-rcc your_file.qrc -o rc_your_file.py
+
+It is important to use the ``-o`` option to generate the Python file with the
+conversion, otherwise you will receive all the output as stdout in your terminal.
+
+To enable the usage of those resources in your program, you need to import
+the file:
+
+.. code-block:: Python
+
+ import rc_your_file
+
+then you can use a specific resource, for example an image, with the prefix ``:/``,
+for example:
+
+.. code-block:: Python
+
+ pixmap = QPixmap(":/icons/image.png")
+
+
+For additional options, you can use ``pyside6-rcc -h`` in order to get
+more information about additional options.
+
+Visit the tutorial :ref:`using_qrc_files` for a hands-on example.
+
+.. _`rcc`: https://doc.qt.io/qt-6/rcc.html
+
diff --git a/sources/pyside6/doc/tools/pyside-uic.rst b/sources/pyside6/doc/tools/pyside-uic.rst
new file mode 100644
index 000000000..ba4e36b4e
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside-uic.rst
@@ -0,0 +1,59 @@
+.. _pyside6-uic:
+
+pyside6-uic
+===========
+
+.. note:: This tool is automatically called by :ref:`pyside6-project`
+ so you don't need to call it manually. *Qt Creator* will take care
+ of this step as well while executing a project.
+
+``pyside6-uic`` is a command line tool for converting ``.ui`` files into ``.py``
+files, with the objective of using application designs as Python classes.
+
+The tool is a wrapper around the `uic`_ tool, which was originally
+designed to generate C++ code, but it also has Python support.
+
+Even though the equivalent of ``pyside6-uic`` is running ``uic -g python``
+we strongly recommend you to rely on ``pyside6-uic`` in order to avoid
+mismatches between versions for the generated code.
+
+Usage
+-----
+
+Once you have designed your application with :ref:`pyside6-designer`,
+you can transform your ``.ui`` file with the following command:
+
+.. code-block:: bash
+
+ pyside6-uic your_file.ui -o ui_your_file.py
+
+It is important to use the ``-o`` option to generate the Python file with the
+conversion, otherwise you will receive all the output as stdout in your terminal.
+
+The structure of the generated Python file will be similar in all cases,
+and you will get one class called ``Ui_TheNameOfYourDesign(object)`` that
+is in charge of positioning all the elements like your design.
+
+To use this Python file, you should follow our tutorial in
+:ref:`using_ui_files`, but in summary, it is mainly importing the class
+from the generated file and setting it up in your code:
+
+.. code-block:: Python
+
+ self.ui = Ui_TheNameOfYourDesign()
+ self.ui.setupUi(self)
+
+For additional options, you can use ``pyside-uic -h`` in order to get
+more information related to relative imports, absolute imports, using resources,
+translations, etc.
+
+.. note:: Remember that you need to have a class corresponding to the base
+ form you selected in :ref:`pyside6-designer`, a ``QWidget``, or ``QDialog``,
+ or ``QMainWindow``, etc, in order for ``setupUi`` to work. Check
+ :ref:`using_ui_files` for more information.
+
+.. warning:: Do not modify the content of the generated Python file from your
+ ``.ui`` file, otherwise everything will be lost when you re-generate it.
+
+.. _`uic`: https://doc.qt.io/qt-6/uic.html
+
diff --git a/sources/pyside6/doc/tools/pyside6-assistant_screenshot.webp b/sources/pyside6/doc/tools/pyside6-assistant_screenshot.webp
new file mode 100644
index 000000000..7d898d8e6
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-assistant_screenshot.webp
Binary files differ
diff --git a/sources/pyside6/doc/tools/pyside6-balsam.rst b/sources/pyside6/doc/tools/pyside6-balsam.rst
new file mode 100644
index 000000000..c6677f6a3
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-balsam.rst
@@ -0,0 +1,59 @@
+.. _pyside6-balsam:
+
+pyside6-balsam
+==============
+
+``pyside6-qsb`` is a tool that wraps the `balsam <Balsam Asset Import Tool>`_
+tool provided with Qt Quick 3D. The Balsam tool is a command line application
+that is part of Qt Quick 3D's asset conditioning pipeline. The purpose is to
+take assets created in digital content creation tools like `Maya`_, `3ds Max`_
+or `Blender`_ and converts them into an efficient runtime format for use with Qt
+Quick 3D. It is not possible, nor does it make sense to reference the
+interchange formats directly in applications because a large amount of
+resources are needed to parse and condition the content of the asset before it
+is usable for real-time rendering. Instead, the interchange formats can be
+converted via the Balsam tool into QML Components and resources like geometry
+and textures.
+
+
+For more information on how to use this tool, read Qt's documentation
+here: `Balsam Asset Import Tool`_.
+
+Usage
+-----
+
+.. code-block:: bash
+
+ pyside6-balsam [options] sourceFileName
+
+To convert a 3D asset contained in the file ``testModel.fbx`` with
+``pyside6-balsam`` the following command would be used:
+
+.. code-block:: bash
+
+ pyside6-balsam testModel.fbx
+
+This would generate the following files:
+
+* meshes/testModel.mesh
+* TestModel.qml
+
+Which can then be used in a Qt Quick 3D project by using that QML Component:
+
+.. code-block:: xml
+
+ import QtQuick3D 1.0
+
+ Scene {
+ Model {
+ source: "TestModel.qml"
+ }
+ }
+
+For other modes of operation, refer to the `Balsam Asset Import Tool`_.
+
+.. _`Balsam Asset Import Tool`: https://doc.qt.io/qt-6/qtquick3d-tool-balsam.html
+.. _Maya: https://www.autodesk.com/products/maya/overview
+.. _3ds Max: https://www.autodesk.com/products/3ds-max/overview
+.. _Blender: https://www.blender.org/
+
diff --git a/sources/pyside6/doc/tools/pyside6-balsamui.rst b/sources/pyside6/doc/tools/pyside6-balsamui.rst
new file mode 100644
index 000000000..f34cb6045
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-balsamui.rst
@@ -0,0 +1,22 @@
+.. _pyside6-balsamui:
+
+pyside6-balsamui
+================
+
+``pyside6-balsamui`` is graphical user interface frontend to the command line
+tool :ref:`pyside6-balsam`. The purpose of the tool is to take assets created
+in digital content creation tools like `Maya`_, `3ds Max`_ or `Blender`_ and
+converts them into an efficient runtime format for use with Qt Quick 3D.
+
+For more information on the further capabilities of the tool, read Qt's
+documentation here: `Balsam Asset Import Tool`_.
+
+.. image:: pyside6-balsamui_screenshot.webp
+ :width: 500
+ :alt: pyside6-balsamui screenshot
+
+.. _`Balsam Asset Import Tool`: https://doc.qt.io/qt-6/qtquick3d-tool-balsam.html
+.. _Maya: https://www.autodesk.com/products/maya/overview
+.. _3ds Max: https://www.autodesk.com/products/3ds-max/overview
+.. _Blender: https://www.blender.org/
+
diff --git a/sources/pyside6/doc/tools/pyside6-balsamui_screenshot.webp b/sources/pyside6/doc/tools/pyside6-balsamui_screenshot.webp
new file mode 100644
index 000000000..5c194fdb6
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-balsamui_screenshot.webp
Binary files differ
diff --git a/sources/pyside6/doc/tools/pyside6-designer_base_screenshot.webp b/sources/pyside6/doc/tools/pyside6-designer_base_screenshot.webp
new file mode 100644
index 000000000..88ff77786
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-designer_base_screenshot.webp
Binary files differ
diff --git a/sources/pyside6/doc/tools/pyside6-designer_customwidgets_screenshot.webp b/sources/pyside6/doc/tools/pyside6-designer_customwidgets_screenshot.webp
new file mode 100644
index 000000000..c84436c1d
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-designer_customwidgets_screenshot.webp
Binary files differ
diff --git a/sources/pyside6/doc/tools/pyside6-designer_screenshot.webp b/sources/pyside6/doc/tools/pyside6-designer_screenshot.webp
new file mode 100644
index 000000000..27f03652b
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-designer_screenshot.webp
Binary files differ
diff --git a/sources/pyside6/doc/tools/pyside6-designer_sections_screenshot.webp b/sources/pyside6/doc/tools/pyside6-designer_sections_screenshot.webp
new file mode 100644
index 000000000..6ff025503
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-designer_sections_screenshot.webp
Binary files differ
diff --git a/sources/pyside6/doc/tools/pyside6-linguist_screenshot.webp b/sources/pyside6/doc/tools/pyside6-linguist_screenshot.webp
new file mode 100644
index 000000000..cd91007ba
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-linguist_screenshot.webp
Binary files differ
diff --git a/sources/pyside6/doc/tools/pyside6-qmlimportscanner.rst b/sources/pyside6/doc/tools/pyside6-qmlimportscanner.rst
new file mode 100644
index 000000000..ba27414d7
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-qmlimportscanner.rst
@@ -0,0 +1,53 @@
+.. _pyside6-qmlimportscanner:
+
+pyside6-qmlimportscanner
+========================
+
+``pyside6-qmlimportscanner`` is a command line tool that wraps the
+``qmlimportscanner`` tool of Qt.
+
+
+The tool is automatically run by the :ref:`pyside6-project` tool
+when passing the ``qmllint`` argument instructing it to check
+the QML source files.
+
+Usage
+-----
+
+Invoking the tool in the directory of the :ref:`filesystemexplorer_example`
+example using:
+
+.. code-block:: bash
+
+ pyside6-qmlimportscanner -rootPath .
+
+produces:
+
+.. code-block:: json
+
+ [
+ {
+ "name": "QtQuick",
+ "type": "module"
+ },
+ {
+ "name": "QtQuick.Controls.Basic",
+ "type": "module"
+ },
+ {
+ "name": "QtQuick.Layouts",
+ "type": "module"
+ },
+ {
+ "name": "FileSystemModule",
+ "type": "module"
+ },
+ {
+ "name": "QtQuick.Controls",
+ "type": "module"
+ },
+ {
+ "name": "QtQuick.Effects",
+ "type": "module"
+ }
+ ]
diff --git a/sources/pyside6/doc/tools/pyside6-qsb.rst b/sources/pyside6/doc/tools/pyside6-qsb.rst
new file mode 100644
index 000000000..f6f1847d4
--- /dev/null
+++ b/sources/pyside6/doc/tools/pyside6-qsb.rst
@@ -0,0 +1,39 @@
+.. _pyside6-qsb:
+
+pyside6-qsb
+===========
+
+``pyside6-qsb`` is a tool that wraps the `qsb <QSB Manual>`_ tool. qsb is a
+command line tool provided by the `Qt Shader Tools`_ module. It integrates
+third-party libraries such as `glslang`_ and `SPIRV-Cross`_, optionally invokes
+external tools, such as ``fxc`` or ``spirv-opt``, and generates .qsb files.
+Additionally, it can be used to inspect the contents of a .qsb package.
+
+For more information on how to use this tool, read Qt's documentation
+here: `QSB Manual`_.
+
+Usage
+-----
+
+To create a qsb file from a shader file, e.g., ``shader.frag``, use the
+following command:
+
+.. code-block:: bash
+
+ pyside6-qsb -o shader.frag.qsb shader.frag
+
+To inspect the file produced, i.e., ``shader.frag.qsb``, use the following
+command:
+
+.. code-block:: bash
+
+ pyside6-qsb -d shader.frag.qsb
+
+This will print the reflection metadata (in JSON form) and the included shaders.
+
+For other modes of operation, refer to the `QSB Manual`_.
+
+.. _`glslang`: https://github.com/KhronosGroup/glslang
+.. _`spirv-cross`: https://github.com/KhronosGroup/SPIRV-Cross
+.. _`QSB Manual`: https://doc.qt.io/qt-6/qtshadertools-qsb.html
+.. _`Qt Shader Tools`: https://doc.qt.io/qt-6/qtshadertools-index.html
diff --git a/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.png b/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.png
new file mode 100644
index 000000000..bfdc23fe0
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst b/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst
new file mode 100644
index 000000000..c5464640b
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst
@@ -0,0 +1,95 @@
+Using a Simple Button
+=====================
+
+In this tutorial, we'll show you how to handle **signals and slots**
+using Qt for Python. **Signals and slots** is a Qt feature that lets
+your graphical widgets communicate with other graphical widgets or
+your python code. Our application creates a button that logs the
+`Button clicked, Hello!` message to the python console each time you
+click it.
+
+Let's start by importing the necessary PySide6 classes and python
+`sys` module:
+::
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QPushButton
+ from PySide6.QtCore import Slot
+
+Let's also create a python function that logs the message to the
+console:
+::
+
+ # Greetings
+ @Slot()
+ def say_hello():
+ print("Button clicked, Hello!")
+
+.. note:: The `@Slot()` is a decorator that identifies a function as
+ a slot. It is not important to understand why for now,
+ but use it always to avoid unexpected behavior.
+
+Now, as mentioned in previous examples you must create the
+`QApplication` to run your PySide6 code:
+::
+
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+
+Let's create the clickable button, which is a `QPushButton` instance.
+To label the button, we pass a python string to the constructor:
+::
+
+ # Create a button
+ button = QPushButton("Click me")
+
+Before we show the button, we must connect it to the `say_hello()`
+function that we defined earlier. There are two ways of doing this;
+using the old style or the new style, which is more pythonic. Let's
+use the new style in this case. You can find more information about
+both these styles in the
+`Signals and Slots in PySide6 <https://wiki.qt.io/Qt_for_Python_Signals_and_Slots>`_
+wiki page.
+
+The `QPushButton` has a predefined signal called **clicked**, which
+is triggered every time the button is clicked. We'll connect this
+signal to the `say_hello()` function:
+::
+
+ # Connect the button to the function
+ button.clicked.connect(say_hello)
+
+Finally, we show the button and start the Qt main loop:
+
+.. code-block:: python
+
+ # Show the button
+ button.show()
+ # Run the main Qt loop
+ app.exec()
+
+Here is the complete code for this example:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QPushButton
+ from PySide6.QtCore import Slot
+
+ @Slot()
+ def say_hello():
+ print("Button clicked, Hello!")
+
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+ # Create a button, connect it and show it
+ button = QPushButton("Click me")
+ button.clicked.connect(say_hello)
+ button.show()
+ # Run the main Qt loop
+ app.exec()
+
+After a few clicks, you will get something like this on your terminal:
+
+.. image:: clickablebutton.png
+ :alt: Clickable Button Example
diff --git a/sources/pyside6/doc/tutorials/basictutorial/dialog.png b/sources/pyside6/doc/tutorials/basictutorial/dialog.png
new file mode 100644
index 000000000..ad5690927
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/dialog.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/dialog.rst b/sources/pyside6/doc/tutorials/basictutorial/dialog.rst
new file mode 100644
index 000000000..b7712672b
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/dialog.rst
@@ -0,0 +1,149 @@
+Creating a Dialog Application
+=============================
+
+This tutorial shows how to build a simple dialog with some
+basic widgets. The idea is to let users provide their name
+in a ``QLineEdit``, and the dialog greets them on click of a
+``QPushButton``.
+
+Let us just start with a simple stub that creates and shows
+a dialog. This stub is updated during the course of this
+tutorial, but you can use this stub as is if you need to:
+::
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QDialog, QLineEdit, QPushButton
+
+ class Form(QDialog):
+
+ def __init__(self, parent=None):
+ super(Form, self).__init__(parent)
+ self.setWindowTitle("My Form")
+
+
+ if __name__ == '__main__':
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+ # Create and show the form
+ form = Form()
+ form.show()
+ # Run the main Qt loop
+ sys.exit(app.exec())
+
+The imports aren't new to you, the same for the creation of the
+``QApplication`` and the execution of the Qt main loop.
+The only novelty here is the **class definition**.
+
+You can create any class that subclasses PySide6 widgets.
+In this case, we are subclassing ``QDialog`` to define a custom
+dialog, which we name as **Form**. We have also implemented the
+``init()`` method that calls the ``QDialog``'s init method with the
+parent widget, if any. Also, the new ``setWindowTitle()`` method
+just sets the title of the dialog window. In ``main()``, you can see
+that we are creating a *Form object* and showing it to the world.
+
+Create the Widgets
+------------------
+
+We are going to create two widgets: a ``QLineEdit`` where users can
+enter their name, and a ``QPushButton`` that prints the contents of
+the ``QLineEdit``.
+So, let's add the following code to the ``init()`` method of our Form:
+::
+
+ # Create widgets
+ self.edit = QLineEdit("Write my name here..")
+ self.button = QPushButton("Show Greetings")
+
+It's obvious from the code that both widgets will show the corresponding
+texts.
+
+Create a layout to organize the Widgets
+---------------------------------------
+
+Qt comes with layout-support that helps you organize the widgets
+in your application. In this case, let's use ``QVBoxLayout`` to lay out
+the widgets vertically. Add the following code to the ``init()`` method,
+after creating the widgets:
+::
+
+ # Create layout and add widgets
+ layout = QVBoxLayout(self)
+ layout.addWidget(self.edit)
+ layout.addWidget(self.button)
+
+So, we create the layout, add the widgets with ``addWidget()``.
+
+Create the function to greet and connect the Button
+---------------------------------------------------
+
+Finally, we just have to add a function to our custom **Form**
+and *connect* our button to it. Our function will be a part of
+the Form, so you have to add it after the ``init()`` function:
+::
+
+ # Greets the user
+ def greetings(self):
+ print(f"Hello {self.edit.text()}")
+
+Our function just prints the contents of the ``QLineEdit`` to the
+python console. We have access to the text by means of the
+``QLineEdit.text()`` method.
+
+Now that we have everything, we just need to *connect* the
+``QPushButton`` to the ``Form.greetings()`` method. To do so, add the
+following line to the ``init()`` method:
+::
+
+ # Add button signal to greetings slot
+ self.button.clicked.connect(self.greetings)
+
+Once executed, you can enter your name in the ``QLineEdit`` and watch
+the console for greetings.
+
+Complete code
+-------------
+
+Here is the complete code for this tutorial:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import (QLineEdit, QPushButton, QApplication,
+ QVBoxLayout, QDialog)
+
+ class Form(QDialog):
+
+ def __init__(self, parent=None):
+ super(Form, self).__init__(parent)
+ # Create widgets
+ self.edit = QLineEdit("Write my name here")
+ self.button = QPushButton("Show Greetings")
+ # Create layout and add widgets
+ layout = QVBoxLayout()
+ layout.addWidget(self.edit)
+ layout.addWidget(self.button)
+ # Set dialog layout
+ self.setLayout(layout)
+ # Add button signal to greetings slot
+ self.button.clicked.connect(self.greetings)
+
+ # Greets the user
+ def greetings(self):
+ print(f"Hello {self.edit.text()}")
+
+ if __name__ == '__main__':
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+ # Create and show the form
+ form = Form()
+ form.show()
+ # Run the main Qt loop
+ sys.exit(app.exec())
+
+
+When you execute the code, and write down your name,
+the button will display messages on the terminal:
+
+.. image:: dialog.png
+ :alt: Simple Dialog Example
diff --git a/sources/pyside6/doc/tutorials/basictutorial/greenapplication.png b/sources/pyside6/doc/tutorials/basictutorial/greenapplication.png
new file mode 100644
index 000000000..29ea0a701
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/greenapplication.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons.png b/sources/pyside6/doc/tutorials/basictutorial/icons.png
new file mode 100644
index 000000000..a5a554eba
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons.zip b/sources/pyside6/doc/tutorials/basictutorial/icons.zip
new file mode 100644
index 000000000..e279e37b8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons.zip
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons/forward.png b/sources/pyside6/doc/tutorials/basictutorial/icons/forward.png
new file mode 100644
index 000000000..c7a532dfe
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons/forward.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons/pause.png b/sources/pyside6/doc/tutorials/basictutorial/icons/pause.png
new file mode 100644
index 000000000..d0beadb43
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons/pause.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons/play.png b/sources/pyside6/doc/tutorials/basictutorial/icons/play.png
new file mode 100644
index 000000000..345685337
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons/play.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons/previous.png b/sources/pyside6/doc/tutorials/basictutorial/icons/previous.png
new file mode 100644
index 000000000..979f18565
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons/previous.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons/stop.png b/sources/pyside6/doc/tutorials/basictutorial/icons/stop.png
new file mode 100644
index 000000000..1e88ded3a
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons/stop.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/player-new.png b/sources/pyside6/doc/tutorials/basictutorial/player-new.png
new file mode 100644
index 000000000..8e45c757d
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/player-new.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/player.png b/sources/pyside6/doc/tutorials/basictutorial/player.png
new file mode 100644
index 000000000..0563d3223
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/player.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/qml.rst b/sources/pyside6/doc/tutorials/basictutorial/qml.rst
new file mode 100644
index 000000000..49cd3d94a
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/qml.rst
@@ -0,0 +1,79 @@
+Your First QtQuick/QML Application
+**********************************
+
+QML_ is a declarative language that lets you develop applications
+faster than with traditional languages. It is ideal for designing the
+UI of your application because of its declarative nature. In QML, a
+user interface is specified as a tree of objects with properties. In
+this tutorial, we will show how to make a simple "Hello World"
+application with PySide6 and QML.
+
+A PySide6/QML application consists, at least, of two different files -
+a file with the QML description of the user interface, and a python file
+that loads the QML file. To make things easier, let's save both files in
+the same directory.
+
+Here is a simple QML file called :code:`view.qml`:
+
+.. code-block:: javascript
+
+ import QtQuick
+
+ Rectangle {
+ id: main
+ width: 200
+ height: 200
+ color: "green"
+
+ Text {
+ text: "Hello World"
+ anchors.centerIn: main
+ }
+ }
+
+We start by importing :code:`QtQuick`, which is a QML module.
+
+The rest of the QML code is pretty straightforward for those who
+have previously used HTML or XML files. Basically, we are creating
+a green rectangle with the size `200*200`, and adding a Text element
+that reads "Hello World". The code :code:`anchors.centerIn: main` makes
+the text appear centered within the object with :code:`id: main`,
+which is the Rectangle in this case.
+
+Now, let's see how the code looks on the PySide6.
+Let's call it :code:`main.py`:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import QApplication
+ from PySide6.QtQuick import QQuickView
+
+ if __name__ == "__main__":
+ app = QApplication()
+ view = QQuickView()
+
+ view.setSource("view.qml")
+ view.show()
+ sys.exit(app.exec())
+
+If you are already familiar with PySide6 and have followed our
+tutorials, you have already seen much of this code.
+The only novelties are that you must :code:`import QtQuick` and set the
+source of the :code:`QQuickView` object to the URL of your QML file.
+Then, similar to what you do with any Qt widget, you call
+:code:`QQuickView.show()`.
+
+.. note:: If you are programming for desktop, you should consider
+ adding `view.setResizeMode(QQuickView.SizeRootObjectToView)`
+ before showing the view.
+
+When you execute the :code:`main.py` script, you will see the following
+application:
+
+
+.. image:: greenapplication.png
+ :alt: Simple QML and Python example
+ :align: center
+
+.. _QML: https://doc.qt.io/qt-6/qmlapplications.html
diff --git a/sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst b/sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst
new file mode 100644
index 000000000..858293beb
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst
@@ -0,0 +1,173 @@
+.. _using_qrc_files:
+
+Using ``.qrc`` Files (``pyside6-rcc``)
+**************************************
+
+The `Qt Resource System`_ is a mechanism for storing binary files
+in an application.
+
+The files will be embedded into the application and be acessible for the
+``QFile`` class and the constructors of the ``QIcon`` and ``QPixmap``
+classes taking a file name by using a special file name starting with ``:/``.
+
+The most common uses are for custom images, icons, fonts, among others.
+
+In this tutorial you will learn how to load custom images as button icons.
+
+For inspiration, we will try to adapt the multimedia player example
+from Qt.
+
+As you can see on the following image, the ``QPushButton`` that are used
+for the media actions (play, pause, stop, and so on) are using the
+default icons meant for such actions.
+
+.. image:: player.png
+ :alt: Multimedia Player Qt Example
+
+You could make the application more attractive by designing the icons,
+but in case you don't want to design them, you can download and use them.
+
+:download:`Download icons <icons.zip>`
+
+.. image:: icons.png
+ :alt: New Multimedia icons
+
+You can find more information about the ``rcc`` command, and ``.qrc`` file
+format, and the resource system in general in the `Qt Resource System`_
+site.
+
+
+The ``.qrc`` file
+=================
+
+Before running any command, add information about the resources to a ``.qrc``
+file.
+In the following example, notice how the resources are listed in ``icons.qrc``
+
+::
+
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+ <file>icons/play.png</file>
+ <file>icons/pause.png</file>
+ <file>icons/stop.png</file>
+ <file>icons/previous.png</file>
+ <file>icons/forward.png</file>
+ </qresource>
+ </RCC>
+
+
+Generating a Python file
+=========================
+
+Now that the ``icons.qrc`` file is ready, use the ``pyside6-rcc`` tool to generate
+a Python class containing the binary information about the resources
+
+To do this, we need to run::
+
+ pyside6-rcc icons.qrc -o rc_icons.py
+
+The ``-o`` option lets you specify the output filename,
+which is ``rc_icons.py`` in this case.
+
+To use the generated file, add the following import at the top of your main Python file::
+
+ import rc_icons
+
+
+Changes in the code
+===================
+
+As you are modifying an existing example, you need to modify the following
+lines:
+
+.. code-block:: python
+
+ from PySide6.QtGui import QIcon, QKeySequence
+ playIcon = self.style().standardIcon(QStyle.SP_MediaPlay)
+ previousIcon = self.style().standardIcon(QStyle.SP_MediaSkipBackward)
+ pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause)
+ nextIcon = self.style().standardIcon(QStyle.SP_MediaSkipForward)
+ stopIcon = self.style().standardIcon(QStyle.SP_MediaStop)
+
+and replace them with the following:
+
+.. code-block:: python
+
+ from PySide6.QtGui import QIcon, QKeySequence, QPixmap
+ playIcon = QIcon(QPixmap(":/icons/play.png"))
+ previousIcon = QIcon(QPixmap(":/icons/previous.png"))
+ pauseIcon = QIcon(QPixmap(":/icons/pause.png"))
+ nextIcon = QIcon(QPixmap(":/icons/forward.png"))
+ stopIcon = QIcon(QPixmap(":/icons/stop.png"))
+
+This ensures that the new icons are used instead of the default ones provided
+by the application theme.
+Notice that the lines are not consecutive, but are in different parts
+of the file.
+
+After all your imports, add the following
+
+.. code-block:: python
+
+ import rc_icons
+
+Now, the constructor of your class should look like this:
+
+.. code-block:: python
+
+ def __init__(self):
+ super(MainWindow, self).__init__()
+
+ self.playlist = QMediaPlaylist()
+ self.player = QMediaPlayer()
+
+ toolBar = QToolBar()
+ self.addToolBar(toolBar)
+
+ fileMenu = self.menuBar().addMenu("&File")
+ openAction = QAction(QIcon.fromTheme("document-open"),
+ "&Open...", self, shortcut=QKeySequence.Open,
+ triggered=self.open)
+ fileMenu.addAction(openAction)
+ exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit",
+ self, shortcut="Ctrl+Q", triggered=self.close)
+ fileMenu.addAction(exitAction)
+
+ playMenu = self.menuBar().addMenu("&Play")
+ playIcon = QIcon(QPixmap(":/icons/play.png"))
+ self.playAction = toolBar.addAction(playIcon, "Play")
+ self.playAction.triggered.connect(self.player.play)
+ playMenu.addAction(self.playAction)
+
+ previousIcon = QIcon(QPixmap(":/icons/previous.png"))
+ self.previousAction = toolBar.addAction(previousIcon, "Previous")
+ self.previousAction.triggered.connect(self.previousClicked)
+ playMenu.addAction(self.previousAction)
+
+ pauseIcon = QIcon(QPixmap(":/icons/pause.png"))
+ self.pauseAction = toolBar.addAction(pauseIcon, "Pause")
+ self.pauseAction.triggered.connect(self.player.pause)
+ playMenu.addAction(self.pauseAction)
+
+ nextIcon = QIcon(QPixmap(":/icons/forward.png"))
+ self.nextAction = toolBar.addAction(nextIcon, "Next")
+ self.nextAction.triggered.connect(self.playlist.next)
+ playMenu.addAction(self.nextAction)
+
+ stopIcon = QIcon(QPixmap(":/icons/stop.png"))
+ self.stopAction = toolBar.addAction(stopIcon, "Stop")
+ self.stopAction.triggered.connect(self.player.stop)
+ playMenu.addAction(self.stopAction)
+
+ # many lines were omitted
+
+Executing the example
+=====================
+
+Run the application by calling ``python main.py`` to checkout the new icon-set:
+
+.. image:: player-new.png
+ :alt: New Multimedia Player Qt Example
+
+.. _`Qt Resource System`: https://doc.qt.io/qt-5/resources.html
diff --git a/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst b/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst
new file mode 100644
index 000000000..0bfd9e276
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst
@@ -0,0 +1,263 @@
+.. _signals-and-slots:
+
+Signals and Slots
+=================
+
+Due to the nature of Qt, ``QObject``\s require a way to communicate, and that's
+the reason for this mechanism to be a **central feature of Qt**.
+
+In simple terms, you can understand **Signal and Slots** in the same way you
+interact with the lights in your house. When you move the light switch
+(signal) you get a result which may be that your light bulbs are switched
+on/off (slot).
+
+While developing interfaces, you can get a real example by the effect of
+clicking a button: the 'click' will be the signal, and the slot will be what
+happens when that button is clicked, like closing a window, saving a document,
+etc.
+
+.. note::
+ If you have experience with other frameworks or toolkits, it's likely
+ that you read a concept called 'callback'. Leaving the implementation
+ details aside, a callback will be related to a notification function,
+ passing a pointer to a function in case it's required due to the events
+ that happen in your program. This approach might sound similar, but
+ there are essential differences that make it an unintuitive approach,
+ like ensuring the type correctness of callback arguments, and some others.
+
+All classes that inherit from ``QObject`` or one of its subclasses, like
+``QWidget`` can contain signals and slots. **Signals are emitted by objects**
+when they change their state in a way that may be interesting to other objects.
+This is all the object does to communicate. It does not know or care whether
+anything is receiving the signals it emits. This is true information
+encapsulation, and ensures that the object can be used as a software component.
+
+**Slots can be used for receiving signals**, but they are also normal member
+functions. Just as an object does not know if anything receives its signals,
+a slot does not know if it has any signals connected to it. This ensures that
+truly independent components can be created with Qt.
+
+You can connect as many signals as you want to a single slot, and a signal can
+be connected to as many slots as you need. It is even possible to connect
+a signal directly to another signal. (This will emit the second signal
+immediately whenever the first is emitted.)
+
+Qt's widgets have many predefined signals and slots. For example,
+``QAbstractButton`` (base class of buttons in Qt) has a ``clicked()``
+signal and ``QLineEdit`` (single line input field) has a slot named
+``clear()``. So, a text input field with a button to clear the text
+could be implemented by placing a ``QToolButton`` to the right of the
+``QLineEdit`` and connecting its ``clicked()`` signal to the slot
+``clear()``. This is done using the ``connect()`` method of the signal:
+
+.. code-block:: python
+
+ button = QToolButton()
+ line_edit = QLineEdit()
+ button.clicked.connect(line_edit.clear)
+
+``connect()`` returns a ``QMetaObject.Connection`` object, which can be
+used with the ``disconnect()`` method to sever the connection.
+
+Signals can also be connected to free functions:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QPushButton
+
+
+ def function():
+ print("The 'function' has been called!")
+
+ app = QApplication()
+ button = QPushButton("Call function")
+ button.clicked.connect(function)
+ button.show()
+ sys.exit(app.exec())
+
+Connections can be spelled out in code or, for widget forms,
+designed in the
+`Signal-Slot Editor <https://doc.qt.io/qt-6/designer-connection-mode.html>`_
+of *Qt Widgets Designer*.
+
+The Signal Class
+----------------
+
+When writing classes in Python, signals are declared as class level
+variables of the class ``QtCore.Signal()``. A QWidget-based button
+that emits a ``clicked()`` signal could look as
+follows:
+
+.. code-block:: python
+
+ from PySide6.QtCore import Qt, Signal
+ from PySide6.QtWidgets import QWidget
+
+ class Button(QWidget):
+
+ clicked = Signal(Qt.MouseButton)
+
+ ...
+
+ def mousePressEvent(self, event):
+ self.clicked.emit(event.button())
+
+The constructor of ``Signal`` takes a tuple or a list of Python types
+and C types:
+
+.. code-block:: python
+
+ signal1 = Signal(int) # Python types
+ signal2 = Signal(QUrl) # Qt Types
+ signal3 = Signal(int, str, int) # more than one type
+ signal4 = Signal((float,), (QDate,)) # optional types
+
+In addition to that, it can receive also a named argument ``name`` that defines
+the signal name. If nothing is passed, the new signal will have the same name
+as the variable that it is being assigned to.
+
+.. code-block:: python
+
+ # TODO
+ signal5 = Signal(int, name='rangeChanged')
+ # ...
+ rangeChanged.emit(...)
+
+Another useful option of ``Signal`` is the arguments name,
+useful for QML applications to refer to the emitted values by name:
+
+.. code-block:: python
+
+ sumResult = Signal(int, arguments=['sum'])
+
+.. code-block:: javascript
+
+ Connections {
+ target: ...
+ function onSumResult(sum) {
+ // do something with 'sum'
+ }
+
+
+.. _slot-decorator:
+
+The Slot Class
+--------------
+
+Slots in QObject-derived classes should be indicated by the decorator
+``@QtCore.Slot()``. Again, to define a signature just pass the types
+similar to the ``QtCore.Signal()`` class.
+
+.. code-block:: python
+
+ @Slot(str)
+ def slot_function(self, s):
+ ...
+
+
+``Slot()`` also accepts a ``name`` and a ``result`` keyword.
+The ``result`` keyword defines the type that will be returned and can be a C or
+Python type. The ``name`` keyword behaves the same way as in ``Signal()``. If
+nothing is passed as name then the new slot will have the same name as the
+function that is being decorated.
+
+We recommend marking all methods used by signal connections with a
+``@QtCore.Slot()`` decorator. Not doing causes run-time overhead due to the
+method being added to the ``QMetaObject`` when creating the connection. This is
+particularly important for ``QObject`` classes registered with QML, where
+missing decorators can introduce bugs.
+
+Missing decorators can be diagnosed by setting activating warnings of the
+logging category ``qt.pyside.libpyside``; for example by setting the
+environment variable:
+
+.. code-block:: bash
+
+ export QT_LOGGING_RULES="qt.pyside.libpyside.warning=true"
+
+.. _overloading-signals-and-slots:
+
+Overloading Signals and Slots with Different Types
+--------------------------------------------------
+
+It is actually possible to use signals and slots of the same name with different
+parameter type lists. This is legacy from Qt 5 and not recommended for new code.
+In Qt 6, signals have distinct names for different types.
+
+The following example uses two handlers for a Signal and a Slot to showcase
+the different functionality.
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QPushButton
+ from PySide6.QtCore import QObject, Signal, Slot
+
+
+ class Communicate(QObject):
+ # create two new signals on the fly: one will handle
+ # int type, the other will handle strings
+ speak = Signal((int,), (str,))
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self.speak[int].connect(self.say_something)
+ self.speak[str].connect(self.say_something)
+
+ # define a new slot that receives a C 'int' or a 'str'
+ # and has 'say_something' as its name
+ @Slot(int)
+ @Slot(str)
+ def say_something(self, arg):
+ if isinstance(arg, int):
+ print("This is a number:", arg)
+ elif isinstance(arg, str):
+ print("This is a string:", arg)
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ someone = Communicate()
+
+ # emit 'speak' signal with different arguments.
+ # we have to specify the str as int is the default
+ someone.speak.emit(10)
+ someone.speak[str].emit("Hello everybody!")
+
+
+.. _signals-and-slots-strings:
+
+Specifying Signals and Slots by Method Signature Strings
+--------------------------------------------------------
+
+
+Signals and slots can also be specified as C++ method signature
+strings passed through the ``SIGNAL()`` and/or ``SLOT()`` functions:
+
+.. code-block:: python
+
+ from PySide6.QtCore import SIGNAL, SLOT
+
+ button.connect(SIGNAL("clicked(Qt::MouseButton)"),
+ action_handler, SLOT("action1(Qt::MouseButton)"))
+
+This is not normally recommended; it is only needed
+for a few cases where signals are only accessible via ``QMetaObject``
+(``QAxObject``, ``QAxWidget``, ``QDBusInterface`` or ``QWizardPage::registerField()``):
+
+.. code-block:: python
+
+ wizard.registerField("text", line_edit, "text",
+ SIGNAL("textChanged(QString)"))
+
+The signature strings can be found by querying ``QMetaMethod.methodSignature()``
+when introspecting ``QMetaObject``:
+
+.. code-block:: python
+
+ mo = widget.metaObject()
+ for m in range(mo.methodOffset(), mo.methodCount()):
+ print(mo.method(m).methodSignature())
+
+Slots should be decorated using :ref:`@Slot <slot-decorator>`.
diff --git a/sources/pyside6/doc/tutorials/basictutorial/signals_slots.png b/sources/pyside6/doc/tutorials/basictutorial/signals_slots.png
new file mode 100644
index 000000000..0801cf16e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/signals_slots.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/style.qss b/sources/pyside6/doc/tutorials/basictutorial/style.qss
new file mode 100644
index 000000000..b84b98f05
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/style.qss
@@ -0,0 +1,23 @@
+QListWidget {
+ color: #FFFFFF;
+ background-color: #33373B;
+}
+
+QListWidget::item {
+ height: 50px;
+}
+
+QListWidget::item:selected {
+ background-color: #2ABf9E;
+}
+
+QLabel {
+ background-color: #FFFFFF;
+ qproperty-alignment: AlignCenter;
+}
+
+QPushButton {
+ background-color: #2ABf9E;
+ padding: 20px;
+ font-size: 18px;
+}
diff --git a/sources/pyside6/doc/tutorials/basictutorial/tablewidget.png b/sources/pyside6/doc/tutorials/basictutorial/tablewidget.png
new file mode 100644
index 000000000..e2549f7d0
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/tablewidget.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/tablewidget.rst b/sources/pyside6/doc/tutorials/basictutorial/tablewidget.rst
new file mode 100644
index 000000000..5c04529fd
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/tablewidget.rst
@@ -0,0 +1,97 @@
+Displaying Data Using a Table Widget
+====================================
+
+If you want to display data arranged in a table, use a ``QTableWidget`` to do
+so, without dealing with much configuration.
+
+Notice that using a ``QTableWidget`` is not the only path to display
+information in tables. You can also create a data model and display it using
+a ``QTableView``, but that is not in the scope of this tutorial.
+
+.. note:: This Widget is a ready-to-use version of something you can customize
+ further on. To know more about the Model/View architecture in Qt, refer to
+ its `official documentation <https://doc.qt.io/qt-6/model-view-programming.html>`_.
+
+1. Import ``QTableWidget``, ``QTableWidgetItem``, and ``QColor`` to display
+ background colors:
+
+ .. code-block:: python
+
+ import sys
+ from PySide6.QtGui import QColor
+ from PySide6.QtWidgets import (QApplication, QTableWidget,
+ QTableWidgetItem)
+
+2. Create a simple data model containing the list of names and hex codes for
+ different colors:
+
+ .. code-block:: python
+
+ colors = [("Red", "#FF0000"),
+ ("Green", "#00FF00"),
+ ("Blue", "#0000FF"),
+ ("Black", "#000000"),
+ ("White", "#FFFFFF"),
+ ("Electric Green", "#41CD52"),
+ ("Dark Blue", "#222840"),
+ ("Yellow", "#F9E56d")]
+
+3. Define a function to translate the hex code into an RGB equivalent:
+
+ .. code-block:: python
+
+ def get_rgb_from_hex(code):
+ code_hex = code.replace("#", "")
+ rgb = tuple(int(code_hex[i:i+2], 16) for i in (0, 2, 4))
+ return QColor.fromRgb(rgb[0], rgb[1], rgb[2])
+
+4. Initialize the ``QApplication`` singleton:
+
+ .. code-block:: python
+
+ app = QApplication()
+
+5. Configure the ``QTableWidget`` to have a number of rows equivalent
+ to the amount of items from the ``colors`` structure, and a number of
+ columns with the members of one color entry, plus one.
+ You can set the column name using the ``setHorizontalHeaderLabels`` as
+ described below:
+
+ .. code-block:: python
+
+ table = QTableWidget()
+ table.setRowCount(len(colors))
+ table.setColumnCount(len(colors[0]) + 1)
+ table.setHorizontalHeaderLabels(["Name", "Hex Code", "Color"])
+
+ .. note:: the reason of using ``+ 1`` is to include a new column where
+ we can display the color.
+
+6. Iterate the data structure, create the ``QTableWidgetItems`` instances, and
+ add them into the table using a ``x, y`` coordinate. Here the data is being
+ assigned row-per-row:
+
+ .. code-block:: python
+
+ for i, (name, code) in enumerate(colors):
+ item_name = QTableWidgetItem(name)
+ item_code = QTableWidgetItem(code)
+ item_color = QTableWidgetItem()
+ item_color.setBackground(get_rgb_from_hex(code))
+ table.setItem(i, 0, item_name)
+ table.setItem(i, 1, item_code)
+ table.setItem(i, 2, item_color)
+
+7. Show the table and execute the ``QApplication``.
+
+ .. code-block:: python
+
+ table.show()
+ sys.exit(app.exec())
+
+
+The final application will look like this:
+
+.. image:: tablewidget.png
+ :alt: QTableWidget example
+ :align: center
diff --git a/sources/pyside6/doc/tutorials/basictutorial/translations.png b/sources/pyside6/doc/tutorials/basictutorial/translations.png
new file mode 100644
index 000000000..b9fc1ba17
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/translations.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/translations.rst b/sources/pyside6/doc/tutorials/basictutorial/translations.rst
new file mode 100644
index 000000000..21c16cdcd
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/translations.rst
@@ -0,0 +1,232 @@
+.. _translations:
+
+Translating Applications
+========================
+
+.. image:: translations.png
+ :alt: Translation Image
+
+Qt Linguist
+-----------
+
+`Qt Linguist`_ and
+its related tools can be used to provide translations for applications.
+
+The :ref:`qt-linguist-example` example illustrates this. The example is
+very simple, it has a menu and shows a list of programming languages with
+multiselection.
+
+Translation works by passing the message strings through function calls that
+look up the translation. Each ``QObject`` instance provides a ``tr()``
+function for that purpose. There is also ``QCoreApplication.translate()``
+for adding translated texts to non-QObject classes.
+
+Qt ships its own translations containing the error messages and standard
+dialog captions.
+
+The linguist example has a number of messages enclosed in ``self.tr()``.
+The status bar message shown in response to a selection change uses
+a plural form depending on a count:
+
+.. code-block:: python
+
+ count = len(self._list_widget.selectionModel().selectedRows())
+ message = self.tr("%n language(s) selected", "", count)
+
+The translation workflow for the example is as follows:
+The translated messages are extracted using the ``lupdate`` tool,
+producing XML-based ``.ts`` files:
+
+.. code-block:: bash
+
+ pyside6-lupdate main.py -ts example_de.ts
+
+If ``example_de.ts`` already exists, it will be updated with the new
+messages added to the code in-between.
+
+If there are form files (``.ui``) and/or QML files (``.qml``) in the project,
+they should be passed to the ``pyside6-lupdate`` tool as well:
+
+.. code-block:: bash
+
+ pyside6-lupdate main.py main.qml form.ui -ts example_de.ts
+
+The source files generated by ``pyside6-uic`` from the form files
+should **not** be passed.
+
+The ``lupdate`` mode of ``pyside6-project`` can also be used for this. It
+collects all source files and runs ``pyside6-lupdate`` when ``.ts`` file(s)
+are given in the ``.pyproject`` file:
+
+.. code-block:: bash
+
+ pyside6-project lupdate .
+
+``.ts`` files are translated using *Qt Linguist*. Once this is complete,
+the files are converted to a binary form (``.qm`` files):
+
+.. code-block:: bash
+
+ pyside6-lrelease example_de.ts -qm example_de.qm
+
+``pyside6-project`` will build the ``.qm`` file automatically when
+``.ts`` file(s) are given in the ``.pyproject`` file:
+
+.. code-block:: bash
+
+ pyside6-project build .
+
+To avoid having to ship the ``.qm`` files, it is recommend
+to put them into a Qt resource file along with icons and other
+applications resources (see :ref:`using_qrc_files`).
+The resource file ``linguist.qrc`` provides the ``example_de.qm``
+under ``:/translations``:
+
+.. code-block:: xml
+
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="translations">
+ <file>example_de.qm</file>
+ </qresource>
+ </RCC>
+
+At runtime, the translations need to be loaded using the ``QTranslator`` class:
+
+.. code-block:: python
+
+ path = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
+ translator = QTranslator(app)
+ if translator.load(QLocale.system(), 'qtbase', '_', path):
+ app.installTranslator(translator)
+ translator = QTranslator(app)
+ path = ':/translations'
+ if translator.load(QLocale.system(), 'example', '_', path):
+ app.installTranslator(translator)
+
+The code first loads the translations shipped for Qt and then
+the translations of the applications loaded from resources.
+
+The example can then be run in German:
+
+.. code-block:: bash
+
+ LANG=de python main.py
+
+.. _Qt Linguist: https://doc.qt.io/qt-6/qtlinguist-index.html
+
+GNU gettext
+-----------
+
+The `GNU gettext`_ module
+can be used to provide translations for applications.
+
+The :ref:`gettext-example` example illustrates this. The example is
+very simple, it has a menu and shows a list of programming languages with
+multiselection.
+
+Translation works by passing the message strings through function calls that
+look up the translation. It is common to alias the main translation function
+to ``_``. There is a special translation function for sentences that contain
+a plural form depending on a count ("{0} items(s) selected"). It is commonly
+aliased to ``ngettext``.
+
+Those functions are defined at the top:
+
+.. code-block:: python
+
+ import gettext
+ # ...
+ _ = None
+ ngettext = None
+
+and later assigned as follows:
+
+.. code-block:: python
+
+ src_dir = Path(__file__).resolve().parent
+ try:
+ translation = gettext.translation('example', localedir=src_dir / 'locales')
+ if translation:
+ translation.install()
+ _ = translation.gettext
+ ngettext = translation.ngettext
+ except FileNotFoundError:
+ pass
+ if not _:
+ _ = gettext.gettext
+ ngettext = gettext.ngettext
+
+This specifies that our translation file has the base name ``example`` and
+will be found in the source tree under ``locales``. The code will try
+to load a translation matching the current language.
+
+Messages to be translated look like:
+
+.. code-block:: python
+
+ file_menu = self.menuBar().addMenu(_("&File"))
+
+The status bar message shown in response to a selection change uses
+a plural form depending on a count:
+
+.. code-block:: python
+
+ count = len(self._list_widget.selectionModel().selectedRows())
+ message = ngettext("{0} language selected",
+ "{0} languages selected", count).format(count)
+
+The ``ngettext()`` function takes the singular form, plural form and the count.
+The returned string still contains the formatting placeholder, so it needs
+to be passed through ``format()``.
+
+In order to translate the messages to say German, a template file (``.pot``)
+is first created:
+
+.. code-block:: bash
+
+ mkdir -p locales/de_DE/LC_MESSAGES
+ xgettext -L Python -o locales/example.pot main.py
+
+This file has a few generic placeholders which can be replaced by the
+appropriate values. It is then copied to the ``de_DE/LC_MESSAGES`` directory.
+
+.. code-block:: bash
+
+ cd locales/de_DE/LC_MESSAGES/
+ cp ../../example.pot .
+
+Further adaptions need to be made to account for the German plural
+form and encoding:
+
+.. code-block::
+
+ "Project-Id-Version: PySide6 gettext example\n"
+ "POT-Creation-Date: 2021-07-05 14:16+0200\n"
+ "Language: de_DE\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+Below, the translated messages can be given:
+
+.. code-block::
+
+ #: main.py:57
+ msgid "&File"
+ msgstr "&Datei"
+
+Finally, the ``.pot`` is converted to its binary form (machine object file,
+``.mo``), which needs to be deployed:
+
+.. code-block:: bash
+
+ msgfmt -o example.mo example.pot
+
+The example can then be run in German:
+
+.. code-block:: bash
+
+ LANG=de python main.py
+
+.. _GNU gettext: https://docs.python.org/3/library/gettext.html
diff --git a/sources/pyside6/doc/tutorials/basictutorial/treewidget.png b/sources/pyside6/doc/tutorials/basictutorial/treewidget.png
new file mode 100644
index 000000000..990fe977b
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/treewidget.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/treewidget.rst b/sources/pyside6/doc/tutorials/basictutorial/treewidget.rst
new file mode 100644
index 000000000..f431cb5c4
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/treewidget.rst
@@ -0,0 +1,79 @@
+Displaying Data Using a Tree Widget
+===================================
+
+If you want to display data arranged in a tree, use a ``QTreeWidget`` to do so.
+
+Notice that using a ``QTreeWidget`` is not the only path to display
+information in trees. You can also create a data model and display it using a
+``QTreeView``, but that is not in the scope of this tutorial.
+
+.. note:: This Widget is a ready-to-use version of something you can customize
+ further on. To know more about the Model/View architecture in Qt, refer to
+ its `official documentation <https://doc.qt.io/qt-6/model-view-programming.html>`_.
+
+#. Import ``QTreeWidget`` and ``QTreeWidgetItem`` for this application:
+
+ .. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
+
+#. Define a dictionary with project structures to display the information as a
+ tree, with files belonging to each project:
+
+ .. code-block:: python
+
+ data = {"Project A": ["file_a.py", "file_a.txt", "something.xls"],
+ "Project B": ["file_b.csv", "photo.jpg"],
+ "Project C": []}
+
+#. Initialize the ``QApplication`` singleton:
+
+ .. code-block:: python
+
+ app = QApplication()
+
+#. Configure the ``QTreeWidget`` to have two columns, one for the item name,
+ and the other for item type information of the files in the project
+ directories.
+ You can set the column name with the ``setHeaderLabels`` as described below:
+
+ .. code-block:: python
+
+ tree = QTreeWidget()
+ tree.setColumnCount(2)
+ tree.setHeaderLabels(["Name", "Type"])
+
+#. Iterate the data structure, create the ``QTreeWidgetItem`` elements, and add
+ the corresponding children to each parent.
+ We also extract the extension name for only the files and add them
+ into the second column.
+ In the constructor, you can see that each element (``QTreeWidgetItem``) is
+ added to different columns of the tree (``QTreeWidget``).
+
+ .. code-block:: python
+
+ items = []
+ for key, values in data.items():
+ item = QTreeWidgetItem([key])
+ for value in values:
+ ext = value.split(".")[-1].upper()
+ child = QTreeWidgetItem([value, ext])
+ item.addChild(child)
+ items.append(item)
+
+ tree.insertTopLevelItems(0, items)
+
+#. Show the tree and execute the ``QApplication``.
+
+ .. code-block:: python
+
+ tree.show()
+ sys.exit(app.exec())
+
+
+The final application will look like this:
+
+.. image:: treewidget.png
+ :alt: QTreeWidget example
+ :align: center
diff --git a/sources/pyside6/doc/tutorials/basictutorial/uifiles.png b/sources/pyside6/doc/tutorials/basictutorial/uifiles.png
new file mode 100644
index 000000000..918efec6d
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/uifiles.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside6/doc/tutorials/basictutorial/uifiles.rst
new file mode 100644
index 000000000..cb945908d
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/uifiles.rst
@@ -0,0 +1,304 @@
+.. _using_ui_files:
+
+Using ``.ui`` files from Designer or QtCreator with ``QUiLoader`` and ``pyside6-uic``
+*************************************************************************************
+
+This page describes the use of
+`Qt Widgets Designer <https://doc.qt.io/qt-6/qtdesigner-manual.html>`_ to create
+graphical interfaces based on Qt Widgets for your Qt for Python project.
+*Qt Widgets Designer* is a graphical UI design tool which is available as a
+standalone binary (``pyside6-designer``) or embedded into the
+`Qt Creator IDE <https://doc.qt.io/qtcreator>`_. Its use within *Qt Creator*
+is described at
+`Using Qt Widgets Designer <https://doc.qt.io/qtcreator/creator-using-qt-designer.html>`_.
+
+.. image:: uifiles.png
+ :alt: Designer and the equivalent code
+
+The designs are stored in ``.ui`` files, which is an XML-based format. It will
+be converted to Python or C++ code populating a widget instance at project build
+time by the `pyside6-uic <https://doc.qt.io/qt-6/uic.html>`_ tool.
+
+To create a new Qt Design Form in *Qt Creator*, choose
+``File/New File Or Project`` and "Main Window" for template. Save it as
+``mainwindow.ui``. Add a ``QPushButton`` to the center of the centralwidget.
+
+Your file ``mainwindow.ui`` should look something like this:
+
+.. code-block:: xml
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>80</y>
+ <width>201</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QToolBar" name="mainToolBar">
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+ </ui>
+
+Now we are ready to decide how to use the **UI file** from Python.
+
+Option A: Generating a Python class
+===================================
+
+The standard way to interact with a **UI file** is to generate a Python
+class from it. This is possible thanks to the ``pyside6-uic`` tool.
+To use this tool, you need to run the following command on a console::
+
+ pyside6-uic mainwindow.ui -o ui_mainwindow.py
+
+We redirect all the output of the command to a file called ``ui_mainwindow.py``,
+which will be imported directly::
+
+ from ui_mainwindow import Ui_MainWindow
+
+Now to use it, we should create a personalized class for our widget
+to **setup** this generated design.
+
+To understand the idea, let's take a look at the whole code:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QMainWindow
+ from PySide6.QtCore import QFile
+ from ui_mainwindow import Ui_MainWindow
+
+ class MainWindow(QMainWindow):
+ def __init__(self):
+ super(MainWindow, self).__init__()
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ window = MainWindow()
+ window.show()
+
+ sys.exit(app.exec())
+
+What is inside the *if* statement is already known from the previous
+examples, and our new basic class contains only two new lines
+that are in charge of loading the generated python class from the UI
+file:
+
+.. code-block:: python
+
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+
+.. note::
+
+ You must run ``pyside6-uic`` again every time you make changes
+ to the **UI file**.
+
+Option B: Loading it directly
+=============================
+
+To load the UI file directly, we will need a class from the **QtUiTools**
+module:
+
+.. code-block:: python
+
+ from PySide6.QtUiTools import QUiLoader
+
+The ``QUiLoader`` lets us load the **ui file** dynamically
+and use it right away:
+
+.. code-block:: python
+
+ ui_file = QFile("mainwindow.ui")
+ ui_file.open(QFile.ReadOnly)
+
+ loader = QUiLoader()
+ window = loader.load(ui_file)
+ window.show()
+
+The complete code of this example looks like this:
+
+.. code-block:: python
+
+ # File: main.py
+ import sys
+ from PySide6.QtUiTools import QUiLoader
+ from PySide6.QtWidgets import QApplication
+ from PySide6.QtCore import QFile, QIODevice
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ ui_file_name = "mainwindow.ui"
+ ui_file = QFile(ui_file_name)
+ if not ui_file.open(QIODevice.ReadOnly):
+ print(f"Cannot open {ui_file_name}: {ui_file.errorString()}")
+ sys.exit(-1)
+ loader = QUiLoader()
+ window = loader.load(ui_file)
+ ui_file.close()
+ if not window:
+ print(loader.errorString())
+ sys.exit(-1)
+ window.show()
+
+ sys.exit(app.exec())
+
+Then to execute it we just need to run the following on a
+command prompt:
+
+.. code-block:: bash
+
+ python main.py
+
+.. note::
+
+ ``QUiLoader`` uses ``connect()`` calls taking the function signatures as string
+ arguments for signal/slot connections.
+ It is thus unable to handle Python types like ``str`` or ``list`` from
+ custom widgets written in Python since these types are internally mapped
+ to different C++ types.
+
+.. _designer_custom_widgets:
+
+Custom Widgets in Qt Widgets Designer
+=====================================
+
+*Qt Widgets Designer* is able to use user-provided (custom) widgets.
+They are shown in the widget box and can be dragged onto the form just like
+Qt's widgets (see
+`Using Custom Widgets with Qt Widgets Designer <https://doc.qt.io/qt-6/designer-using-custom-widgets.html>`_
+). Normally, this requires implementing the widget as a plugin to
+*Qt Widgets Designer* written in C++ implementing its
+`QDesignerCustomWidgetInterface`_ .
+
+Qt for Python provides a simple interface for this which is similar to
+:meth:`registerCustomWidget()<PySide6.QtUiTools.QUiLoader.registerCustomWidget>`.
+
+The widget needs to be provided as a Python module, as shown by
+the :ref:`widgetbinding-example` (file ``wigglywidget.py``) or
+the :ref:`task-menu-extension-example` (file ``tictactoe.py``).
+
+Registering this with *Qt Widgets Designer* is done by providing
+a registration script named ``register*.py`` and pointing
+the path-type environment variable ``PYSIDE_DESIGNER_PLUGINS``
+to the directory.
+
+The code of the registration script looks as follows:
+
+.. code-block:: python
+
+ # File: registerwigglywidget.py
+ from wigglywidget import WigglyWidget
+
+ import QtDesigner
+
+
+ TOOLTIP = "A cool wiggly widget (Python)"
+ DOM_XML = """
+ <ui language='c++'>
+ <widget class='WigglyWidget' name='wigglyWidget'>
+ <property name='geometry'>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>200</height>
+ </rect>
+ </property>
+ <property name='text'>
+ <string>Hello, world</string>
+ </property>
+ </widget>
+ </ui>
+ """
+
+ QPyDesignerCustomWidgetCollection.registerCustomWidget(WigglyWidget, module="wigglywidget",
+ tool_tip=TOOLTIP, xml=DOM_XML)
+
+
+QPyDesignerCustomWidgetCollection provides an implementation of
+`QDesignerCustomWidgetCollectionInterface`_
+exposing custom widgets to *Qt Widgets Designer* with static convenience
+functions for registering types or adding instances of
+`QDesignerCustomWidgetInterface`_ .
+
+The function
+:meth:`registerCustomWidget()<PySide6.QtDesigner.QPyDesignerCustomWidgetCollection.registerCustomWidget>`
+is used to register a widget type with *Qt Widgets Designer*. In the simple case, it
+can be used like ``QUiLoader.registerCustomWidget()``. It takes the custom widget
+type and some optional keyword arguments passing values that correspond to the
+getters of
+`QDesignerCustomWidgetInterface`_ :
+
+When launching *Qt Widgets Designer* via its launcher ``pyside6-designer``,
+the custom widget should be visible in the widget box.
+
+For advanced usage, it is also possible to pass the function an implementation
+of the class QDesignerCustomWidgetInterface instead of the type to
+:meth:`addCustomWidget()<PySide6.QtDesigner.QPyDesignerCustomWidgetCollection.addCustomWidget>`.
+This is shown in taskmenuextension example, where a custom context menu
+is registered for the custom widget. The example is a port of the
+corresponding C++
+`Task Menu Extension Example <https://doc.qt.io/qt-6/qtdesigner-taskmenuextension-example.html>`_ .
+
+.. _QDesignerCustomWidgetCollectionInterface: https://doc.qt.io/qt-6/qdesignercustomwidgetcollectioninterface.html
+.. _QDesignerCustomWidgetInterface: https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html
+
+Troubleshooting the Qt Widgets Designer Plugin
+++++++++++++++++++++++++++++++++++++++++++++++
+
+- The launcher ``pyside6-designer`` must be used. The standalone
+ *Qt Widgets Designer* will not load the plugin.
+- The menu item **Help/About Plugin** brings up a dialog showing the plugins
+ found and potential load error messages.
+- Check the console or Windows Debug view for further error messages.
+- Due to the buffering of output by Python, error messages may appear
+ only after *Qt Widgets Designer* has terminated.
+- When building Qt for Python, be sure to set the ``--standalone`` option
+ for the plugin to be properly installed.
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgets.png b/sources/pyside6/doc/tutorials/basictutorial/widgets.png
new file mode 100644
index 000000000..de7a969f9
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgets.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgets.rst b/sources/pyside6/doc/tutorials/basictutorial/widgets.rst
new file mode 100644
index 000000000..ef14c7e99
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgets.rst
@@ -0,0 +1,52 @@
+Your First QtWidgets Application
+*********************************
+
+As with any other programming framework,
+you start with the traditional "Hello World" program.
+
+Here is a simple example of a Hello World application in PySide6:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtWidgets import QApplication, QLabel
+
+ app = QApplication(sys.argv)
+ label = QLabel("Hello World!")
+ label.show()
+ app.exec()
+
+
+When you execute it the code, the application will look like:
+
+.. image:: widgets.png
+ :alt: Simple Widget
+
+
+For a widget application using PySide6, you must always start by
+importing the appropriate class from the `PySide6.QtWidgets` module.
+
+After the imports, you create a `QApplication` instance. As Qt can
+receive arguments from command line, you may pass any argument to
+the QApplication object. Usually, you don't need to pass any
+arguments so you can leave it as is, or use the following approach:
+
+.. code-block:: python
+
+ app = QApplication([])
+
+After the creation of the application object, we have created a
+`QLabel` object. A `QLabel` is a widget that can present text
+(simple or rich, like html), and images:
+
+.. code-block:: python
+
+ # This HTML approach will be valid too!
+ label = QLabel("<font color=red size=40>Hello World!</font>")
+
+.. note:: After creating the label, we call `show()` on it.
+
+Finally, we call `app.exec()` to enter the Qt main loop and start
+to execute the Qt code. In reality, it is only here where the label
+is shown, but this can be ignored for now.
+
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-no.png b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-no.png
new file mode 100644
index 000000000..f8346533f
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-no.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-no.png b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-no.png
new file mode 100644
index 000000000..d510a80cd
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-no.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-yes.png b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-yes.png
new file mode 100644
index 000000000..e7a0c0ef7
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-simple-yes.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-yes.png b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-yes.png
new file mode 100644
index 000000000..9b83b8267
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling-yes.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.py b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.py
new file mode 100644
index 000000000..106483b7b
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QListWidget,
+ QListWidgetItem, QPushButton, QVBoxLayout,
+ QWidget)
+
+_placeholder = """
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
+velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+occaecat cupidatat non proident, sunt in culpa qui officia deserunt
+mollit anim id est laborum
+"""
+
+
+class Widget(QWidget):
+ def __init__(self, parent=None):
+ super(Widget, self).__init__(parent)
+
+ menu_widget = QListWidget()
+ for i in range(10):
+ item = QListWidgetItem(f"Item {i}")
+ item.setTextAlignment(Qt.AlignCenter)
+ menu_widget.addItem(item)
+
+ text_widget = QLabel(_placeholder)
+ button = QPushButton("Something")
+
+ content_layout = QVBoxLayout()
+ content_layout.addWidget(text_widget)
+ content_layout.addWidget(button)
+ main_widget = QWidget()
+ main_widget.setLayout(content_layout)
+
+ layout = QHBoxLayout()
+ layout.addWidget(menu_widget, 1)
+ layout.addWidget(main_widget, 4)
+ self.setLayout(layout)
+
+
+if __name__ == "__main__":
+ app = QApplication()
+
+ w = Widget()
+ w.show()
+
+ _style = None
+ with open("style.qss", "r") as f:
+ _style = f.read()
+ app.setStyleSheet(_style)
+
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst
new file mode 100644
index 000000000..2fa51c0a8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst
@@ -0,0 +1,171 @@
+.. _widgetstyling:
+
+Styling the Widgets Application
+===============================
+
+Qt Widgets application use a default theme depending on the platform.
+In some cases, there are system-wide configurations that modify the Qt theme,
+and applications are displayed differently.
+
+However, you can take care of your own widgets and provide a custom style
+to each component. As an example, look at the following simple snippet:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtCore import Qt
+ from PySide6.QtWidgets import QApplication, QLabel
+
+ if __name__ == "__main__":
+ app = QApplication()
+ w = QLabel("This is a placeholder text")
+ w.setAlignment(Qt.AlignCenter)
+ w.show()
+ sys.exit(app.exec())
+
+When you execute this code, you will see a simple ``QLabel`` aligned at the
+center, and with a placeholder text.
+
+.. image:: widgetstyling-simple-no.png
+ :alt: Simple Widget with no style
+
+You can style your application using the CSS-like syntax.
+For more information, see `Qt Style Sheets Reference`_.
+
+A ``QLabel`` can be styled differently by setting some of its CSS
+properties, such as ``background-color`` and ``font-family``,
+so let's see how does the code look like with these changes:
+
+.. code-block:: python
+
+ import sys
+ from PySide6.QtCore import Qt
+ from PySide6.QtWidgets import QApplication, QLabel
+
+ if __name__ == "__main__":
+ app = QApplication()
+ w = QLabel("This is a placeholder text")
+ w.setAlignment(Qt.AlignCenter)
+ w.setStyleSheet("""
+ background-color: #262626;
+ color: #FFFFFF;
+ font-family: Titillium;
+ font-size: 18px;
+ """)
+ w.show()
+ sys.exit(app.exec())
+
+Now when you run the code, notice that the ``QLabel`` looks different with your
+custom style:
+
+.. image:: widgetstyling-simple-yes.png
+ :alt: Simple Widget with Style
+
+
+.. note::
+
+ If you don't have the font ``Titillium`` installed, you can try with any
+ other you prefer.
+ Remember you can list your installed fonts using ``QFontDatabase``,
+ specifically the ``families()`` method.
+
+
+Styling each UI element separately like you did in the previous snippet is a
+lot of work. The easier alternative for this is to use Qt Style Sheets,
+which is one or more ``.qss`` files defining the style for the UI elements in
+your application.
+
+More examples can be found in the `Qt Style Sheet Examples`_ documentation
+page.
+
+
+.. _`Qt Style Sheets Reference`: https://doc.qt.io/qt-5/stylesheet-reference.html
+.. _`Qt Style Sheet Examples`: https://doc.qt.io/qt-5/stylesheet-examples.html
+
+Qt Style Sheets
+---------------
+
+.. warning::
+
+ Before starting modifying your application, keep in mind that you will be
+ responsible for all the graphical details of the application.
+ Altering margins, and sizes might end up looking strange or incorrect, so you
+ need to be careful when altering the style.
+ It's recommended to create a full new Qt style to cover all the possible
+ corner cases.
+
+A ``qss`` file is quite similar to a CSS file, but you need to specify the Widget
+component and optionally the name of the object::
+
+ QLabel {
+ background-color: red;
+ }
+
+ QLabel#title {
+ font-size: 20px;
+ }
+
+The first style defines a ``background-color`` for all ``QLabel`` objects in your
+application, whereas the later one styles the ``title`` object only.
+
+.. note::
+
+ You can set object names with the `setObjectName(str)` function to any Qt
+ object, for example: for a `label = QLabel("Test")`, you can write
+ `label.setObjectName("title")`
+
+
+Once you have a ``qss`` file for your application, you can apply it by reading
+the file and using the ``QApplication.setStyleSheet(str)`` function:
+
+.. code-block:: python
+
+ if __name__ == "__main__":
+ app = QApplication()
+
+ w = Widget()
+ w.show()
+
+ with open("style.qss", "r") as f:
+ _style = f.read()
+ app.setStyleSheet(_style)
+
+ sys.exit(app.exec())
+
+Having a general ``qss`` file allows you to decouple the styling aspects of
+the code, without mixing it in the middle of the general functionality, and you
+can simply enable it or disable it.
+
+Look at this new example, with more widgets components:
+
+.. literalinclude:: widgetstyling.py
+ :linenos:
+ :lines: 22-44
+
+This displays a two column widget, with a ``QListWidget`` on the left and a
+``QLabel`` and a ``QPushButton`` on the right. It looks like this when you run the
+code:
+
+.. image:: widgetstyling-no.png
+ :alt: Widget with no style
+
+If you add content to the previously described ``style.qss`` file, you can modify
+the look-n-feel of the previous example:
+
+.. literalinclude:: style.qss
+ :linenos:
+
+The style changes mainly the color of the different widgets, alter the
+alignment, and includes some spacing.
+You can also use state-based styling on the QListWidget *items* for example, to
+style them differently depending on whether they are *selected* or not.
+
+After applying all the styling alternatives you explored in this topic, notice
+that the ``QLabel`` example looks a lot different now.
+Try running the code to check its new look:
+
+.. image:: widgetstyling-yes.png
+ :alt: Widget with style
+
+You have the freedom to tune your style sheets and provide a really nice
+look-n-feel to all your applications.
diff --git a/sources/pyside6/doc/tutorials/datavisualize/add_chart.rst b/sources/pyside6/doc/tutorials/datavisualize/add_chart.rst
new file mode 100644
index 000000000..59a9d9ee0
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/add_chart.rst
@@ -0,0 +1,20 @@
+Chapter 5 - Add a chart view
+=============================
+
+A table is nice to present data, but a chart is even better. For this, you
+need the QtCharts module that provides many types of plots and options to
+graphically represent data.
+
+The placeholder for a plot is a QChartView, and inside that Widget you can
+place a QChart. As a first step, try including only this without any data to
+plot.
+
+Make the following highlighted changes to :code:`main_widget.py` from the
+previous chapter to add a QChartView:
+
+.. literalinclude:: datavisualize5/main_widget.py
+ :linenos:
+ :lines: 3-
+ :emphasize-lines: 2-3,6,22-36,47-49
+
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/add_mainwindow.rst b/sources/pyside6/doc/tutorials/datavisualize/add_mainwindow.rst
new file mode 100644
index 000000000..623372a07
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/add_mainwindow.rst
@@ -0,0 +1,32 @@
+Chapter 3 - Create an empty QMainWindow
+==========================================
+
+You can now think of presenting your data in a UI. A QMainWindow provides a
+convenient structure for GUI applications, such as a menu bar and status bar.
+The following image shows the layout that QMainWindow offers out-of-the box:
+
+.. image:: images/QMainWindow-layout.png
+ :alt: QMainWindow layout
+ :align: right
+
+In this case, let your application inherit from QMainWindow, and add the
+following UI elements:
+
+* A "File" menu to open a File dialog.
+* An "Exit" menu close the window.
+* A status message on the status bar when the application starts.
+
+In addition, you can define a fixed size for the window or adjust it based on
+the resolution you currently have. In the following snippet, you will see how
+window size is defined based on available screen width (80%) and height (70%).
+
+.. note:: You can achieve a similar structure using other Qt elements like
+ QMenuBar, QWidget, and QStatusBar. Refer the QMainWindow layout for
+ guidance.
+
+.. literalinclude:: datavisualize3/main_window.py
+ :language: python
+ :linenos:
+ :lines: 4-
+
+Try running the script to see what output you get with it.
diff --git a/sources/pyside6/doc/tutorials/datavisualize/add_tableview.rst b/sources/pyside6/doc/tutorials/datavisualize/add_tableview.rst
new file mode 100644
index 000000000..f658640bf
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/add_tableview.rst
@@ -0,0 +1,70 @@
+Chapter 4 - Add a QTableView
+=============================
+
+Now that you have a QMainWindow, you can include a centralWidget to your
+interface. Usually, a QWidget is used to display data in most data-driven
+applications. Use a table view to display your data.
+
+The first step is to add a horizontal layout with just a QTableView. You
+can create a QTableView object and place it inside a QHBoxLayout. Once the
+QWidget is properly built, pass the object to the QMainWindow as its central
+widget.
+
+Remember that a QTableView needs a model to display information. In this case,
+you can use a QAbstractTableModel instance.
+
+.. note:: You could also use the default item model that comes with a
+ QTableWidget instead. QTableWidget is a convenience class that reduces
+ your codebase considerably as you don't need to implement a data model.
+ However, it's less flexible than a QTableView, as QTableWidget cannot be
+ used with just any data. For more insight about Qt's model-view framework,
+ refer to the
+ `Model View Programming <https://doc.qt.io/qt-5/model-view-programming.html>`
+ documentation.
+
+Implementing the model for your QTableView, allows you to:
+- set the headers,
+- manipulate the formats of the cell values (remember we have UTC time and float
+numbers),
+- set style properties like text alignment,
+- and even set color properties for the cell or its content.
+
+To subclass the QAbstractTable, you must reimplement its virtual methods,
+rowCount(), columnCount(), and data(). This way, you can ensure that the data
+is handled properly. In addition, reimplement the headerData() method to
+provide the header information to the view.
+
+Here is a script that implements the CustomTableModel:
+
+.. literalinclude:: datavisualize4/table_model.py
+ :language: python
+ :linenos:
+ :lines: 3-
+
+Now, create a QWidget that has a QTableView, and connect it to your
+CustomTableModel.
+
+.. literalinclude:: datavisualize4/main_widget.py
+ :language: python
+ :linenos:
+ :emphasize-lines: 12-17
+ :lines: 3-
+
+You also need minor changes to the :code:`main_window.py` and
+:code:`main.py` from chapter 3 to include the Widget inside the
+MainWindow.
+
+In the following snippets you'll see those changes highlighted:
+
+.. literalinclude:: datavisualize4/main_window.py
+ :language: python
+ :linenos:
+ :lines: 3-
+ :emphasize-lines: 8,11
+
+.. literalinclude:: datavisualize4/main.py
+ :language: python
+ :linenos:
+ :lines: 3-
+ :emphasize-lines: 46-47
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/all_hour.csv b/sources/pyside6/doc/tutorials/datavisualize/all_hour.csv
new file mode 100644
index 000000000..400947c3c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/all_hour.csv
@@ -0,0 +1,8 @@
+time,latitude,longitude,depth,mag,magType,nst,gap,dmin,rms,net,id,updated,place,type,horizontalError,depthError,magError,magNst,status,locationSource,magSource
+2019-01-10T12:11:24.810Z,34.1281662,-117.7754974,4.46,1.18,ml,22,69,0.04475,0.13,ci,ci38421072,2019-01-10T12:13:30.138Z,"3km NNW of La Verne, CA",earthquake,0.3,0.55,0.246,6,automatic,ci,ci
+2019-01-10T12:04:26.320Z,19.4433327,-155.6159973,0.72,1.79,md,22,99,0.04026,0.3,hv,hv70763571,2019-01-10T12:07:28.690Z,"26km E of Honaunau-Napoopoo, Hawaii",earthquake,0.6,1.79,0.28,6,automatic,hv,hv
+2019-01-10T11:57:48.980Z,33.3225,-116.3931667,4.84,0.62,ml,15,211,0.05776,0.16,ci,ci38421064,2019-01-10T12:01:29.166Z,"8km NNW of Borrego Springs, CA",earthquake,0.71,0.68,0.111,11,automatic,ci,ci
+2019-01-10T11:52:09.490Z,38.8356667,-122.8366699,1.28,2.74,md,25,77,0.003061,0.04,nc,nc73131566,2019-01-10T12:14:02.757Z,"10km NW of The Geysers, CA",earthquake,0.19,0.29,0.06,7,automatic,nc,nc
+2019-01-10T11:25:44.854Z,65.1082,-149.3701,20.6,2.1,ml,,,,1.02,ak,ak019gq2oer,2019-01-10T11:37:07.060Z,"60km NNW of North Nenana, Alaska",earthquake,,0.3,,,automatic,ak,ak
+2019-01-10T11:25:23.786Z,69.1518,-144.4977,10.4,3.7,ml,,,,0.74,ak,ak019gq2ndz,2019-01-10T11:47:11.284Z,"114km SSW of Kaktovik, Alaska",earthquake,,1.6,,,reviewed,ak,ak
+2019-01-10T11:16:11.761Z,61.3318,-150.0708,20.1,2.7,ml,,,,0.83,ak,ak019gq0ozj,2019-01-10T11:29:24.610Z,"15km NW of Anchorage, Alaska",earthquake,,0.4,,,automatic,ak,ak
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize1/main.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize1/main.py
new file mode 100644
index 000000000..995b9906a
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize1/main.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import argparse
+import pandas as pd
+
+
+def read_data(fname):
+ return pd.read_csv(fname)
+
+
+if __name__ == "__main__":
+ options = argparse.ArgumentParser()
+ options.add_argument("-f", "--file", type=str, required=True)
+ args = options.parse_args()
+ data = read_data(args.file)
+ print(data)
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize2/main.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize2/main.py
new file mode 100644
index 000000000..9ea96097c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize2/main.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import argparse
+import pandas as pd
+
+from PySide6.QtCore import QDateTime, QTimeZone
+
+
+def transform_date(utc, timezone=None):
+ utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ"
+ new_date = QDateTime().fromString(utc, utc_fmt)
+ if timezone:
+ new_date.setTimeZone(timezone)
+ return new_date
+
+
+def read_data(fname):
+ # Read the CSV content
+ df = pd.read_csv(fname)
+
+ # Remove wrong magnitudes
+ df = df.drop(df[df.mag < 0].index)
+ magnitudes = df["mag"]
+
+ # My local timezone
+ timezone = QTimeZone(b"Europe/Berlin")
+
+ # Get timestamp transformed to our timezone
+ times = df["time"].apply(lambda x: transform_date(x, timezone))
+
+ return times, magnitudes
+
+
+if __name__ == "__main__":
+ options = argparse.ArgumentParser()
+ options.add_argument("-f", "--file", type=str, required=True)
+ args = options.parse_args()
+ data = read_data(args.file)
+ print(data)
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main.py
new file mode 100644
index 000000000..bbf85e17d
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+import argparse
+import pandas as pd
+
+from PySide6.QtCore import QDateTime, QTimeZone
+from PySide6.QtWidgets import QApplication
+from main_window import MainWindow
+
+
+def transform_date(utc, timezone=None):
+ utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ"
+ new_date = QDateTime().fromString(utc, utc_fmt)
+ if timezone:
+ new_date.setTimeZone(timezone)
+ return new_date
+
+
+def read_data(fname):
+ # Read the CSV content
+ df = pd.read_csv(fname)
+
+ # Remove wrong magnitudes
+ df = df.drop(df[df.mag < 0].index)
+ magnitudes = df["mag"]
+
+ # My local timezone
+ timezone = QTimeZone(b"Europe/Berlin")
+
+ # Get timestamp transformed to our timezone
+ times = df["time"].apply(lambda x: transform_date(x, timezone))
+
+ return times, magnitudes
+
+
+if __name__ == "__main__":
+ options = argparse.ArgumentParser()
+ options.add_argument("-f", "--file", type=str, required=True)
+ args = options.parse_args()
+ data = read_data(args.file)
+
+ # Qt Application
+ app = QApplication(sys.argv)
+
+ window = MainWindow()
+ window.show()
+
+ sys.exit(app.exec())
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main_window.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main_window.py
new file mode 100644
index 000000000..745f2fefe
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize3/main_window.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Slot
+from PySide6.QtGui import QAction, QKeySequence
+from PySide6.QtWidgets import QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ QMainWindow.__init__(self)
+ self.setWindowTitle("Eartquakes information")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = QAction("Exit", self)
+ exit_action.setShortcut(QKeySequence.Quit)
+ exit_action.triggered.connect(self.close)
+
+ self.file_menu.addAction(exit_action)
+
+ # Status Bar
+ self.status = self.statusBar()
+ self.status.showMessage("Data loaded and plotted")
+
+ # Window dimensions
+ geometry = self.screen().availableGeometry()
+ self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7)
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main.py
new file mode 100644
index 000000000..87b962bd3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+import argparse
+import pandas as pd
+
+from PySide6.QtCore import QDateTime, QTimeZone
+from PySide6.QtWidgets import QApplication
+from main_window import MainWindow
+from main_widget import Widget
+
+
+def transform_date(utc, timezone=None):
+ utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ"
+ new_date = QDateTime().fromString(utc, utc_fmt)
+ if timezone:
+ new_date.setTimeZone(timezone)
+ return new_date
+
+
+def read_data(fname):
+ # Read the CSV content
+ df = pd.read_csv(fname)
+
+ # Remove wrong magnitudes
+ df = df.drop(df[df.mag < 0].index)
+ magnitudes = df["mag"]
+
+ # My local timezone
+ timezone = QTimeZone(b"Europe/Berlin")
+
+ # Get timestamp transformed to our timezone
+ times = df["time"].apply(lambda x: transform_date(x, timezone))
+
+ return times, magnitudes
+
+
+if __name__ == "__main__":
+ options = argparse.ArgumentParser()
+ options.add_argument("-f", "--file", type=str, required=True)
+ args = options.parse_args()
+ data = read_data(args.file)
+
+ # Qt Application
+ app = QApplication(sys.argv)
+
+ widget = Widget(data)
+ window = MainWindow(widget)
+ window.show()
+
+ sys.exit(app.exec())
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_widget.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_widget.py
new file mode 100644
index 000000000..2a2bfeb09
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_widget.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtWidgets import (QHBoxLayout, QHeaderView, QSizePolicy,
+ QTableView, QWidget)
+
+from table_model import CustomTableModel
+
+
+class Widget(QWidget):
+ def __init__(self, data):
+ QWidget.__init__(self)
+
+ # Getting the Model
+ self.model = CustomTableModel(data)
+
+ # Creating a QTableView
+ self.table_view = QTableView()
+ self.table_view.setModel(self.model)
+
+ # QTableView Headers
+ self.horizontal_header = self.table_view.horizontalHeader()
+ self.vertical_header = self.table_view.verticalHeader()
+ self.horizontal_header.setSectionResizeMode(
+ QHeaderView.ResizeToContents
+ )
+ self.vertical_header.setSectionResizeMode(
+ QHeaderView.ResizeToContents
+ )
+ self.horizontal_header.setStretchLastSection(True)
+
+ # QWidget Layout
+ self.main_layout = QHBoxLayout()
+ size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+
+ ## Left layout
+ size.setHorizontalStretch(1)
+ self.table_view.setSizePolicy(size)
+ self.main_layout.addWidget(self.table_view)
+
+ # Set the layout to the QWidget
+ self.setLayout(self.main_layout)
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_window.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_window.py
new file mode 100644
index 000000000..ebe2997a1
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/main_window.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Slot
+from PySide6.QtGui import QAction, QKeySequence
+from PySide6.QtWidgets import QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ QMainWindow.__init__(self)
+ self.setWindowTitle("Eartquakes information")
+ self.setCentralWidget(widget)
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ ## Exit QAction
+ exit_action = QAction("Exit", self)
+ exit_action.setShortcut(QKeySequence.Quit)
+ exit_action.triggered.connect(self.close)
+
+ self.file_menu.addAction(exit_action)
+
+ # Status Bar
+ self.status = self.statusBar()
+ self.status.showMessage("Data loaded and plotted")
+
+ # Window dimensions
+ geometry = self.screen().availableGeometry()
+ self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7)
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/table_model.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/table_model.py
new file mode 100644
index 000000000..08eeeeed6
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize4/table_model.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Qt, QAbstractTableModel, QModelIndex
+from PySide6.QtGui import QColor
+
+
+class CustomTableModel(QAbstractTableModel):
+ def __init__(self, data=None):
+ QAbstractTableModel.__init__(self)
+ self.load_data(data)
+
+ def load_data(self, data):
+ self.input_dates = data[0].values
+ self.input_magnitudes = data[1].values
+
+ self.column_count = 2
+ self.row_count = len(self.input_magnitudes)
+
+ def rowCount(self, parent=QModelIndex()):
+ return self.row_count
+
+ def columnCount(self, parent=QModelIndex()):
+ return self.column_count
+
+ def headerData(self, section, orientation, role):
+ if role != Qt.DisplayRole:
+ return None
+ if orientation == Qt.Horizontal:
+ return ("Date", "Magnitude")[section]
+ else:
+ return f"{section}"
+
+ def data(self, index, role=Qt.DisplayRole):
+ column = index.column()
+ row = index.row()
+
+ if role == Qt.DisplayRole:
+ if column == 0:
+ date = self.input_dates[row].toPython()
+ return str(date)[:-3]
+ elif column == 1:
+ magnitude = self.input_magnitudes[row]
+ return f"{magnitude:.2f}"
+ elif role == Qt.BackgroundRole:
+ return QColor(Qt.white)
+ elif role == Qt.TextAlignmentRole:
+ return Qt.AlignRight
+
+ return None
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main.py
new file mode 100644
index 000000000..87b962bd3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+import argparse
+import pandas as pd
+
+from PySide6.QtCore import QDateTime, QTimeZone
+from PySide6.QtWidgets import QApplication
+from main_window import MainWindow
+from main_widget import Widget
+
+
+def transform_date(utc, timezone=None):
+ utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ"
+ new_date = QDateTime().fromString(utc, utc_fmt)
+ if timezone:
+ new_date.setTimeZone(timezone)
+ return new_date
+
+
+def read_data(fname):
+ # Read the CSV content
+ df = pd.read_csv(fname)
+
+ # Remove wrong magnitudes
+ df = df.drop(df[df.mag < 0].index)
+ magnitudes = df["mag"]
+
+ # My local timezone
+ timezone = QTimeZone(b"Europe/Berlin")
+
+ # Get timestamp transformed to our timezone
+ times = df["time"].apply(lambda x: transform_date(x, timezone))
+
+ return times, magnitudes
+
+
+if __name__ == "__main__":
+ options = argparse.ArgumentParser()
+ options.add_argument("-f", "--file", type=str, required=True)
+ args = options.parse_args()
+ data = read_data(args.file)
+
+ # Qt Application
+ app = QApplication(sys.argv)
+
+ widget = Widget(data)
+ window = MainWindow(widget)
+ window.show()
+
+ sys.exit(app.exec())
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_widget.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_widget.py
new file mode 100644
index 000000000..15b7e97e5
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_widget.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QDateTime, Qt
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import (QWidget, QHeaderView, QHBoxLayout, QTableView,
+ QSizePolicy)
+from PySide6.QtCharts import QChart, QChartView, QLineSeries, QDateTimeAxis, QValueAxis
+
+from table_model import CustomTableModel
+
+
+class Widget(QWidget):
+ def __init__(self, data):
+ QWidget.__init__(self)
+
+ # Getting the Model
+ self.model = CustomTableModel(data)
+
+ # Creating a QTableView
+ self.table_view = QTableView()
+ self.table_view.setModel(self.model)
+
+ # QTableView Headers
+ self.horizontal_header = self.table_view.horizontalHeader()
+ self.vertical_header = self.table_view.verticalHeader()
+ self.horizontal_header.setSectionResizeMode(QHeaderView.ResizeToContents)
+ self.vertical_header.setSectionResizeMode(QHeaderView.ResizeToContents)
+ self.horizontal_header.setStretchLastSection(True)
+
+ # Creating QChart
+ self.chart = QChart()
+ self.chart.setAnimationOptions(QChart.AllAnimations)
+
+ # Creating QChartView
+ self.chart_view = QChartView(self.chart)
+ self.chart_view.setRenderHint(QPainter.Antialiasing)
+
+ # QWidget Layout
+ self.main_layout = QHBoxLayout()
+ size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+
+ ## Left layout
+ size.setHorizontalStretch(1)
+ self.table_view.setSizePolicy(size)
+ self.main_layout.addWidget(self.table_view)
+
+ ## Right Layout
+ size.setHorizontalStretch(4)
+ self.chart_view.setSizePolicy(size)
+ self.main_layout.addWidget(self.chart_view)
+
+ # Set the layout to the QWidget
+ self.setLayout(self.main_layout)
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_window.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_window.py
new file mode 100644
index 000000000..ed12c1f8f
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/main_window.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Slot
+from PySide6.QtGui import QAction, QKeySequence
+from PySide6.QtWidgets import QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ QMainWindow.__init__(self)
+ self.setWindowTitle("Eartquakes information")
+ self.setCentralWidget(widget)
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = QAction("Exit", self)
+ exit_action.setShortcut(QKeySequence.Quit)
+ exit_action.triggered.connect(self.close)
+
+ self.file_menu.addAction(exit_action)
+
+ # Status Bar
+ self.status = self.statusBar()
+ self.status.showMessage("Data loaded and plotted")
+
+ # Window dimensions
+ geometry = self.screen().availableGeometry()
+ self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7)
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/table_model.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/table_model.py
new file mode 100644
index 000000000..08eeeeed6
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize5/table_model.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Qt, QAbstractTableModel, QModelIndex
+from PySide6.QtGui import QColor
+
+
+class CustomTableModel(QAbstractTableModel):
+ def __init__(self, data=None):
+ QAbstractTableModel.__init__(self)
+ self.load_data(data)
+
+ def load_data(self, data):
+ self.input_dates = data[0].values
+ self.input_magnitudes = data[1].values
+
+ self.column_count = 2
+ self.row_count = len(self.input_magnitudes)
+
+ def rowCount(self, parent=QModelIndex()):
+ return self.row_count
+
+ def columnCount(self, parent=QModelIndex()):
+ return self.column_count
+
+ def headerData(self, section, orientation, role):
+ if role != Qt.DisplayRole:
+ return None
+ if orientation == Qt.Horizontal:
+ return ("Date", "Magnitude")[section]
+ else:
+ return f"{section}"
+
+ def data(self, index, role=Qt.DisplayRole):
+ column = index.column()
+ row = index.row()
+
+ if role == Qt.DisplayRole:
+ if column == 0:
+ date = self.input_dates[row].toPython()
+ return str(date)[:-3]
+ elif column == 1:
+ magnitude = self.input_magnitudes[row]
+ return f"{magnitude:.2f}"
+ elif role == Qt.BackgroundRole:
+ return QColor(Qt.white)
+ elif role == Qt.TextAlignmentRole:
+ return Qt.AlignRight
+
+ return None
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main.py
new file mode 100644
index 000000000..2d851cc14
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main.py
@@ -0,0 +1,55 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+import argparse
+import pandas as pd
+
+from PySide6.QtCore import QDateTime, QTimeZone
+from PySide6.QtWidgets import QApplication
+
+from main_window import MainWindow
+from main_widget import Widget
+
+
+def transform_date(utc, timezone=None):
+ utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ"
+ new_date = QDateTime().fromString(utc, utc_fmt)
+ if timezone:
+ new_date.setTimeZone(timezone)
+ return new_date
+
+
+def read_data(fname):
+ # Read the CSV content
+ df = pd.read_csv(fname)
+
+ # Remove wrong magnitudes
+ df = df.drop(df[df.mag < 0].index)
+ magnitudes = df["mag"]
+
+ # My local timezone
+ timezone = QTimeZone(b"Europe/Berlin")
+
+ # Get timestamp transformed to our timezone
+ times = df["time"].apply(lambda x: transform_date(x, timezone))
+
+ return times, magnitudes
+
+
+if __name__ == "__main__":
+ options = argparse.ArgumentParser()
+ options.add_argument("-f", "--file", type=str, required=True)
+ args = options.parse_args()
+ data = read_data(args.file)
+
+ # Qt Application
+ app = QApplication(sys.argv)
+
+ # QWidget
+ widget = Widget(data)
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+
+ window.show()
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_widget.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_widget.py
new file mode 100644
index 000000000..cbcc126a1
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_widget.py
@@ -0,0 +1,95 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QDateTime, Qt
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import (QWidget, QHeaderView, QHBoxLayout, QTableView,
+ QSizePolicy)
+from PySide6.QtCharts import QChart, QChartView, QLineSeries, QDateTimeAxis, QValueAxis
+
+from table_model import CustomTableModel
+
+
+class Widget(QWidget):
+ def __init__(self, data):
+ QWidget.__init__(self)
+
+ # Getting the Model
+ self.model = CustomTableModel(data)
+
+ # Creating a QTableView
+ self.table_view = QTableView()
+ self.table_view.setModel(self.model)
+
+ # QTableView Headers
+ resize = QHeaderView.ResizeToContents
+ self.horizontal_header = self.table_view.horizontalHeader()
+ self.vertical_header = self.table_view.verticalHeader()
+ self.horizontal_header.setSectionResizeMode(resize)
+ self.vertical_header.setSectionResizeMode(resize)
+ self.horizontal_header.setStretchLastSection(True)
+
+ # Creating QChart
+ self.chart = QChart()
+ self.chart.setAnimationOptions(QChart.AllAnimations)
+ self.add_series("Magnitude (Column 1)", [0, 1])
+
+ # Creating QChartView
+ self.chart_view = QChartView(self.chart)
+ self.chart_view.setRenderHint(QPainter.Antialiasing)
+
+ # QWidget Layout
+ self.main_layout = QHBoxLayout()
+ size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+
+ # Left layout
+ size.setHorizontalStretch(1)
+ self.table_view.setSizePolicy(size)
+ self.main_layout.addWidget(self.table_view)
+
+ # Right Layout
+ size.setHorizontalStretch(4)
+ self.chart_view.setSizePolicy(size)
+ self.main_layout.addWidget(self.chart_view)
+
+ # Set the layout to the QWidget
+ self.setLayout(self.main_layout)
+
+ def add_series(self, name, columns):
+ # Create QLineSeries
+ self.series = QLineSeries()
+ self.series.setName(name)
+
+ # Filling QLineSeries
+ for i in range(self.model.rowCount()):
+ # Getting the data
+ t = self.model.index(i, 0).data()
+ date_fmt = "yyyy-MM-dd HH:mm:ss.zzz"
+
+ x = QDateTime().fromString(t, date_fmt).toSecsSinceEpoch()
+ y = float(self.model.index(i, 1).data())
+
+ if x > 0 and y > 0:
+ self.series.append(x, y)
+
+ self.chart.addSeries(self.series)
+
+ # Setting X-axis
+ self.axis_x = QDateTimeAxis()
+ self.axis_x.setTickCount(10)
+ self.axis_x.setFormat("dd.MM (h:mm)")
+ self.axis_x.setTitleText("Date")
+ self.chart.addAxis(self.axis_x, Qt.AlignBottom)
+ self.series.attachAxis(self.axis_x)
+ # Setting Y-axis
+ self.axis_y = QValueAxis()
+ self.axis_y.setTickCount(10)
+ self.axis_y.setLabelFormat("%.2f")
+ self.axis_y.setTitleText("Magnitude")
+ self.chart.addAxis(self.axis_y, Qt.AlignLeft)
+ self.series.attachAxis(self.axis_y)
+
+ # Getting the color from the QChart to use it on the QTableView
+ color_name = self.series.pen().color().name()
+ self.model.color = f"{color_name}"
+
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_window.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_window.py
new file mode 100644
index 000000000..116e53dc3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/main_window.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Slot
+from PySide6.QtGui import QAction, QKeySequence, QScreen
+from PySide6.QtWidgets import QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ QMainWindow.__init__(self)
+ self.setWindowTitle("Eartquakes information")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = QAction("Exit", self)
+ exit_action.setShortcut(QKeySequence.Quit)
+ exit_action.triggered.connect(self.close)
+
+ self.file_menu.addAction(exit_action)
+
+ # Status Bar
+ self.status = self.statusBar()
+ self.status.showMessage("Data loaded and plotted")
+
+ # Window dimensions
+ geometry = self.screen().availableGeometry()
+ self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7)
+ self.setCentralWidget(widget)
diff --git a/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/table_model.py b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/table_model.py
new file mode 100644
index 000000000..4952c0c38
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/datavisualize6/table_model.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Qt, QAbstractTableModel, QModelIndex
+from PySide6.QtGui import QColor
+
+
+class CustomTableModel(QAbstractTableModel):
+ def __init__(self, data=None):
+ QAbstractTableModel.__init__(self)
+ self.color = None
+ self.load_data(data)
+
+ def load_data(self, data):
+ self.input_dates = data[0].values
+ self.input_magnitudes = data[1].values
+
+ self.column_count = 2
+ self.row_count = len(self.input_magnitudes)
+
+ def rowCount(self, parent=QModelIndex()):
+ return self.row_count
+
+ def columnCount(self, parent=QModelIndex()):
+ return self.column_count
+
+ def headerData(self, section, orientation, role):
+ if role != Qt.DisplayRole:
+ return None
+ if orientation == Qt.Horizontal:
+ return ("Date", "Magnitude")[section]
+ else:
+ return f"{section}"
+
+ def data(self, index, role=Qt.DisplayRole):
+ column = index.column()
+ row = index.row()
+
+ if role == Qt.DisplayRole:
+ if column == 0:
+ date = self.input_dates[row].toPython()
+ return str(date)[:-3]
+ elif column == 1:
+ magnitude = self.input_magnitudes[row]
+ return f"{magnitude:.2f}"
+ elif role == Qt.BackgroundRole:
+ return (QColor(Qt.white), QColor(self.color))[column]
+ elif role == Qt.TextAlignmentRole:
+ return Qt.AlignRight
+
+ return None
diff --git a/sources/pyside6/doc/tutorials/datavisualize/filter_data.rst b/sources/pyside6/doc/tutorials/datavisualize/filter_data.rst
new file mode 100644
index 000000000..edfac3862
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/filter_data.rst
@@ -0,0 +1,29 @@
+Chapter 2 - Filtering data
+===========================
+
+In the previous chapter, you learned how to read and print data that is a
+bit raw. Now, try to select a few columns and handle them properly.
+
+Start with these two columns: Time (time) and Magnitude (mag). After getting
+the information from these columns, filter and adapt the data. Try formatting
+the date to Qt types.
+
+There is not much to do for the Magnitude column, as it's just a floating point
+number. You could take special care to check if the data is correct. This could
+be done by filtering the data that follows the condition, "magnitude > 0", to
+avoid faulty data or unexpected behavior.
+
+The Date column provides data in UTC format (for example,
+2018-12-11T21:14:44.682Z), so you could easily map it to a QDateTime object
+defining the structure of the string. Additionally, you can adapt the time
+based on the timezone you are in, using QTimeZone.
+
+The following script filters and formats the CSV data as described earlier:
+
+.. literalinclude:: datavisualize2/main.py
+ :language: python
+ :linenos:
+ :lines: 3-
+
+Now that you have a tuple of QDateTime and float data, try improving the
+output further. That's what you'll learn in the following chapters.
diff --git a/sources/pyside6/doc/tutorials/datavisualize/images/QMainWindow-layout.png b/sources/pyside6/doc/tutorials/datavisualize/images/QMainWindow-layout.png
new file mode 100644
index 000000000..075d796b8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/images/QMainWindow-layout.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/datavisualize/images/datavisualization_app.png b/sources/pyside6/doc/tutorials/datavisualize/images/datavisualization_app.png
new file mode 100644
index 000000000..8d7e4ba13
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/images/datavisualization_app.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/datavisualize/index.rst b/sources/pyside6/doc/tutorials/datavisualize/index.rst
new file mode 100644
index 000000000..35b56706a
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/index.rst
@@ -0,0 +1,31 @@
+Data Visualization Tool Tutorial
+*********************************
+
+In this tutorial, you'll learn about the data visualization capabilities
+of |project|. To start with, find some open data to visualize. For example,
+data about the magnitude of earthquakes during the last hour published on the
+US Geological Survey website. You could download the
+`All earthquakes <https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.csv>`_
+open data in a CSV format for this tutorial.
+
+.. image:: images/datavisualization_app.png
+ :width: 800
+ :alt: Data Visualization Screenshot
+
+In the following chapters of this tutorial you'll learn how to
+visualize data from a CSV in a line chart.
+
+.. toctree::
+ :glob:
+ :titlesonly:
+
+ read*
+ filter*
+ add_main*
+ add_tab*
+ add_chart*
+ plot*
+
+You can download the sources from `here`_.
+
+.. _here: https://code.qt.io/cgit/pyside/pyside-setup.git/tree/sources/pyside6/doc/tutorials/datavisualize
diff --git a/sources/pyside6/doc/tutorials/datavisualize/plot_datapoints.rst b/sources/pyside6/doc/tutorials/datavisualize/plot_datapoints.rst
new file mode 100644
index 000000000..f71fca4c8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/plot_datapoints.rst
@@ -0,0 +1,27 @@
+Chapter 6 - Plot the data in the ChartView
+===========================================
+
+The last step of this tutorial is to plot the CSV data inside our QChart. For
+this, you need to go over our data and include the data on a QLineSeries.
+
+After adding the data to the series, you can modify the axis to properly
+display the QDateTime on the X-axis, and the magnitude values on the Y-axis.
+
+Here is the updated :code:`main_widget.py` that includes an additional
+function to plot data using a QLineSeries:
+
+.. literalinclude:: datavisualize6/main_widget.py
+ :language: python
+ :linenos:
+ :lines: 3-
+ :emphasize-lines: 33,56-91
+
+Now, run the application to visualize the earthquake magnitudes
+data at different times.
+
+.. image:: images/datavisualization_app.png
+ :width: 600
+ :alt: Data Visualization Screenshot
+
+Try modifying the sources to get different output. For example, you could try
+to plot more data from the CSV.
diff --git a/sources/pyside6/doc/tutorials/datavisualize/read_data.rst b/sources/pyside6/doc/tutorials/datavisualize/read_data.rst
new file mode 100644
index 000000000..53b0d1cb0
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/datavisualize/read_data.rst
@@ -0,0 +1,41 @@
+Chapter 1 - Reading data from a CSV
+===================================
+
+There are several ways to read data from a CSV file. The following are the most
+common ways:
+
+- Native reading
+- the `CSV module <https://docs.python.org/3/library/csv.html>`_
+- the `numpy module <https://www.numpy.org>`_
+- the `pandas module <https://pandas.pydata.org/>`_
+
+In this chapter, you will learn to use pandas to read and filter CSV data.
+In addition, you could pass the data file through a command-line option to your
+script.
+
+The following python script, :code:`main.py`, demonstrates how to do it:
+
+.. literalinclude:: datavisualize1/main.py
+ :language: python
+ :linenos:
+ :lines: 3-
+
+The Python script uses the :code:`argparse` module to accept and parse input
+from the command line. It then uses the input, which in this case is the filename,
+to read and print data to the prompt.
+
+Try running the script in the following way to check if you get desired output:
+
+::
+
+ $python datavisualize1/main.py -f all_hour.csv
+ time latitude longitude depth ... magNst status locationSource magSource
+ 0 2019-01-10T12:11:24.810Z 34.128166 -117.775497 4.46 ... 6.0 automatic ci ci
+ 1 2019-01-10T12:04:26.320Z 19.443333 -155.615997 0.72 ... 6.0 automatic hv hv
+ 2 2019-01-10T11:57:48.980Z 33.322500 -116.393167 4.84 ... 11.0 automatic ci ci
+ 3 2019-01-10T11:52:09.490Z 38.835667 -122.836670 1.28 ... 7.0 automatic nc nc
+ 4 2019-01-10T11:25:44.854Z 65.108200 -149.370100 20.60 ... NaN automatic ak ak
+ 5 2019-01-10T11:25:23.786Z 69.151800 -144.497700 10.40 ... NaN reviewed ak ak
+ 6 2019-01-10T11:16:11.761Z 61.331800 -150.070800 20.10 ... NaN automatic ak ak
+
+ [7 rows x 22 columns]
diff --git a/sources/pyside6/doc/tutorials/debugging/mixed_debugging.rst b/sources/pyside6/doc/tutorials/debugging/mixed_debugging.rst
new file mode 100644
index 000000000..85c326347
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/mixed_debugging.rst
@@ -0,0 +1,126 @@
+How To Debug a C++ Extension of a PySide6 Application?
+******************************************************
+
+When debugging PySide code, very often you would also like to debug the
+corresponding C++ extension of the PySide module. This is done by attaching your
+debugger to the Python interpreter. In this tutorial, we are going to take you
+through a comprehensive guide in building Qt 6, using the built Qt 6 to build
+PySide6, and then starting a debugging process in either *Qt Creator* or VSCode.
+
+With VSCode, you should be able to see the combined call stacks for both C++ and
+Python together. With *Qt Creator*, unfortunately you would only be able to
+debug the native C++ code of the PySide module; that is you won't be able to set
+breakpoints inside the Python code.
+
+.. note:: This tutorial is created on Ubuntu 20.04 LTS with the debugger as GDB.
+ As such, this tutorial is mainly focused on Linux users. Nevertheless, links to
+ setup everything in other platforms are mentioned along with each
+ sub-section.
+
+Let's get started.
+
+Install All The Library Dependencies Based on Your Platform
+-----------------------------------------------------------
+
+.. code-block:: bash
+
+ sudo apt install libfontconfig1-dev libfreetype6-dev \
+ libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev \
+ libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev \
+ libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev \
+ libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev \
+ libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev \
+ libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev \
+ libxkbcommon-dev libxkbcommon-x11-dev libatspi2.0-dev \
+ libopengl0 -y
+
+If you have to use the Qt Multimedia module, you have to install gstreamer also.
+
+.. code-block:: bash
+
+ sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
+ libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base \
+ gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
+ gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc \
+ gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl \
+ gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio
+
+Generally, any information on missing packages can be found by inspecting the
+config.summary in you CMake build folder.
+
+.. note:: For other platforms install the same packages using the instructions
+ mentioned here `Qt Install on Linux <https://doc.qt.io/qt-6/linux-requirements.html>`_
+
+Build Qt
+--------
+
+This is an optional step in case you only want to debug the CPython bindings or if you have DEBUG_SYMBOLS for Qt 6 already.
+
+There are multiple ways to build Qt - configure script or manually with CMake.
+Find the build system information `Qt 6 Build System
+<https://www.qt.io/blog/qt-6-build-system>`_.
+
+1. Get the source code.
+
+ .. code-block:: bash
+
+ git clone git://code.qt.io/qt/qt5.git
+ # Get submodules
+ cd qt5
+ perl init-repository
+
+2. Once you have the source code, the next step is to generate the build using
+ CMake, then building and installing it.
+
+ .. code-block:: bash
+
+ cmake -GNinja -DCMAKE_BUILD_TYPE=Debug \
+ -DCMAKE_INSTALL_PREFIX=/path/to/install/Qt -DBUILD_qtwebengine=OFF ..
+ cmake --build . --parallel
+ cmake --install .
+
+ As you notice here, we are skipping the Qt WebEngine module because this greatly
+ decreases the build time. However, PySide6 supports Qt WebEngine
+ features. So feel free to add it, if you need it.
+
+More instructions on building Qt 6 can be found in the following links:
+
+* https://wiki.qt.io/Building_Qt_6_from_Git
+* https://code.qt.io/cgit/qt/qtbase.git/tree/cmake/README.md
+* https://code.qt.io/cgit/qt/qtbase.git/tree/cmake/configure-cmake-mapping.md
+
+Add the **bin** and **lib** path to the environment variables
+--------------------------------------------------------------
+
+.. code-block:: bash
+
+ export PATH="/path/to/custom/qt/bin:$PATH"
+ export LD_LIBRARY_PATH="/path/to/custom/qt/lib:$LD_LIBRARY_PATH"
+
+Build PySide6 using the Qt 6 that you built earlier
+----------------------------------------------------
+
+Follow the steps mentioned `Getting Started - Qt for Python
+<https://doc.qt.io/qtforpython/gettingstarted/index.html>`_
+
+You may manually select the modules to install using the ``--module-subset`` cli
+argument for `setup.py`. This was my installation script
+
+.. code-block:: bash
+
+ python setup.py install --qpaths=/path/to/qpaths --debug \
+ --ignore-git --reuse-build
+
+It is recommended to use a Python virtual environment rather than installing in the global Python.
+
+Debugging the process using your preferred IDE
+----------------------------------------------
+
+The following sections guide you through the setup for *Qt Creator* or VSCode.
+
+.. toctree::
+ :glob:
+ :titlesonly:
+
+ qtcreator/qtcreator
+ vscode/vscode
diff --git a/sources/pyside6/doc/tutorials/debugging/qml_debugging.rst b/sources/pyside6/doc/tutorials/debugging/qml_debugging.rst
new file mode 100644
index 000000000..223e608fc
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/qml_debugging.rst
@@ -0,0 +1,32 @@
+Using Qt Creator's QML Debugger for a PySide6 QML Application
+*************************************************************
+
+Besides the C++ debugger, *Qt Creator* provides a `QML debugger`_ which lets you
+inspect JavaScript code. It works by connecting to a socket server run by the
+``QmlEngine`` instance. The port is passed on the command line. To enable it,
+add the below code to your QML application:
+
+.. code-block:: python
+
+ from argparse import ArgumentParser, RawTextHelpFormatter
+
+ ...
+
+ if __name__ == "__main__":
+ argument_parser = ArgumentParser(...)
+ argument_parser.add_argument("-qmljsdebugger", action="store",
+ help="Enable QML debugging")
+ options = argument_parser.parse_args()
+ if options.qmljsdebugger:
+ QQmlDebuggingEnabler.enableDebugging(True)
+ app = QApplication(sys.argv)
+
+
+For instructions on how to use the QML debugger, see
+`Debugging a Qt Quick Example Application`_.
+
+.. note:: The code should be removed or disabled when shipping the application
+ as it poses a security risk.
+
+.. _`QML debugger`: https://doc.qt.io/qtcreator/creator-debugging-qml.html
+.. _`Debugging a Qt Quick Example Application`: https://doc.qt.io/qtcreator/creator-qml-debugging-example.html
diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/breakpoint_cpp.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/breakpoint_cpp.png
new file mode 100644
index 000000000..c8197118e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/breakpoint_cpp.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_create.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_create.png
new file mode 100644
index 000000000..8362c3310
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_create.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_run_config.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_run_config.png
new file mode 100644
index 000000000..4f0bbe3d4
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/custom_executable_run_config.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/qtcreator.rst b/sources/pyside6/doc/tutorials/debugging/qtcreator/qtcreator.rst
new file mode 100644
index 000000000..a78a67fad
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/qtcreator.rst
@@ -0,0 +1,39 @@
+Debugging PySide with Qt Creator (Linux)
+****************************************
+
+As opposed to VSCode, presently *Qt Creator* does not support mixed mode debugging.
+However, we can debug the C++ implementation of the corresponding Python PySide
+code. Unlike VSCode, *Qt Creator* provides a very easy interface to attach GDB to
+the Python interpreter. It saves you from doing all the extra configuration
+steps, that have to be done with VSCode.
+
+Here are the steps:
+
+1. Set a breakpoint on the C++ code.
+
+2. Go to Projects -> Run -> Run Configuration -> Add. This is going to open a
+ new window shown below.
+
+ .. image:: custom_executable_create.png
+ :alt: creation of custom executable
+ :align: center
+
+3. Click on Custom Executable and `Create` a new configuration. Feed in the
+ details like shown below.
+
+ .. image:: custom_executable_run_config.png
+ :alt: run configuration of custom executable
+ :align: center
+
+4. Debug -> Start Debugging -> Start Debugging Without Deployment.
+
+ .. image:: start_debugging_without_deployment.png
+ :alt: start debugging without deployment
+ :align: center
+
+You will now hit you breakpoint and can start debugging your code.
+
+.. image:: breakpoint_cpp.png
+ :alt: breakpoint cpp
+ :align: center
+
diff --git a/sources/pyside6/doc/tutorials/debugging/qtcreator/start_debugging_without_deployment.png b/sources/pyside6/doc/tutorials/debugging/qtcreator/start_debugging_without_deployment.png
new file mode 100644
index 000000000..9ce0688d3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/qtcreator/start_debugging_without_deployment.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_cpp.png b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_cpp.png
new file mode 100644
index 000000000..57577eea4
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_cpp.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_wrapper.png b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_wrapper.png
new file mode 100644
index 000000000..319577fea
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/vscode/audioformat_wrapper.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/breakpoint_gdb.png b/sources/pyside6/doc/tutorials/debugging/vscode/breakpoint_gdb.png
new file mode 100644
index 000000000..b9bc4acde
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/vscode/breakpoint_gdb.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/find_process_gdb.png b/sources/pyside6/doc/tutorials/debugging/vscode/find_process_gdb.png
new file mode 100644
index 000000000..65176d9bb
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/vscode/find_process_gdb.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/python_set_interpreter.png b/sources/pyside6/doc/tutorials/debugging/vscode/python_set_interpreter.png
new file mode 100644
index 000000000..1a26c9d9c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/vscode/python_set_interpreter.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/debugging/vscode/vscode.rst b/sources/pyside6/doc/tutorials/debugging/vscode/vscode.rst
new file mode 100644
index 000000000..b2a527b0e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/debugging/vscode/vscode.rst
@@ -0,0 +1,192 @@
+Debugging PySide with VSCode (Linux + Windows)
+**********************************************
+
+VSCode enables you to use more than one debugger in a single debugging session.
+This means that we can use Python PDB and GDB (or the MSVC debugger for Windows)
+in a single session. With VSCode you would be able to do the following:
+
+* See the call stacks for both Python and C++ together.
+* Put breakpoints in both the Python and the C++ code.
+* Step from Python to C++ code and vice versa.
+
+For Windows, see :ref:`creating_windows_debug_builds`.
+
+Let's get started with setting up everything and debugging a Python process.
+
+Setting the Python interpreter
+------------------------------
+
+In order to debug Python code, it is necessary to set the correct Python
+interpreter in VSCode - this will ensure that all Python integrations of VSCode
+use the same interpreter. However, this does not affect C++ debugging, and the
+Python executable path must be set for the corresponding launch target
+separately (see the section below).
+
+To set the Python interpreter, open a Python file and click the corresponding
+option on the right side of the VSCode status bar, which should look similar to
+this:
+
+.. image:: python_set_interpreter.png
+ :alt: set Python interpreter
+ :align: center
+
+Alternatively, open the VSCode command palette (F1 or Ctrl + Shift + P) and
+search for "Python: Select Interpreter".
+
+Creating Configurations in launch.json
+--------------------------------------
+
+``Run -> Add Configuration -> Python -> Python File``
+
+This should create a launch.json file which looks like this:
+
+.. code-block:: javascript
+
+ {
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Python: Current File",
+ "type": "python",
+ "request": "launch",
+ "program": "${file}",
+ "console": "integratedTerminal"
+ }
+ ]
+ }
+
+It should already consist of a configuration named "Python: Current File",
+which allows us to debug the current open Python file.
+
+Now, we need to add a configuration to attach the C++ debugger to the Python
+process that is already running in debug mode. If you have the C/C++ extension
+installed and the appropriate debugger for your system, VSCode should be able
+to automatically offer to add a configuration. On Linux, this is suggested with
+the name
+
+* "C/C++: (gdb) Attach"
+
+and on Windows with the name
+
+* "C/C++: (Windows) Attach"
+
+Your launch.json should now look like this on Linux:
+
+.. code-block:: javascript
+
+ {
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Python: Current File",
+ "type": "python",
+ "request": "launch",
+ "program": "${file}",
+ "console": "integratedTerminal"
+ },
+ {
+ "name": "(gdb) Attach",
+ "type": "cppdbg",
+ "request": "attach",
+ "program": "/path/to/python",
+ "processId": "${command:pickProcess}",
+ "MIMode": "gdb", "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ]
+ }
+ ]
+ }
+
+And like this on Windows:
+
+.. code-block:: javascript
+
+ {
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Python: Current File",
+ "type": "python",
+ "request": "launch",
+ "program": "${file}",
+ "console": "integratedTerminal"
+ },
+ {
+ "name": "(Windows) Attach",
+ "type": "cppvsdbg",
+ "request": "attach",
+ "processId": "${command:pickProcess}",
+ }
+ ]
+ }
+
+For Linux, also make sure that the value of "program" refers to your Python
+interpreter inside your virtual environment (for Windows this is not needed).
+We need the processId to attach the gdb debugger to the process. With
+"${command:pickProcess}", we find the processId on the go, as we will see later.
+
+Now, we are ready to debug.
+
+Debug The Process
+-----------------
+
+1. Set a breakpoint in the Python code.
+
+2. Go to ``Run And Debug`` (Ctrl + Shift + D) and run the "Python: Current File"
+ by clicking the run symbol (green right-arrow). This will hit the breakpoint
+ and will halt the Python debugger.
+
+3. Using the drop-down menu change from "Python:
+ Current File" to "(gdb) Attach" or "(Windows) Attach". Your setup should now
+ look like this.
+
+ .. image:: breakpoint_gdb.png
+ :alt: breakpoint before attach gdb
+ :align: center
+
+4. Run "(gdb) Attach" or "(Windows) Attach" and this should ask you for the
+ processId of the Python process to which you want to attach the C++ debugger.
+ VSCode also lets you search for the process by its name.
+
+ .. tip:: You can find the processId by running ``ps aux | grep python``
+
+ .. image:: find_process_gdb.png
+ :alt: find process vscode
+ :align: center
+
+5. VSCode might now ask you for superuser permissions. In that case, type 'y'
+ and enter your password.
+
+ .. code-block:: bash
+
+ Superuser access is required to attach to a process. Attaching as
+ superuser can potentially harm your computer. Do you want to continue?
+ [y/N]_
+
+6. That is it. You should now be able to hit the breakpoints that you have set
+ on the C++ counterparts.
+
+ .. figure:: audioformat_wrapper.png
+ :alt: Breakpoint set on the shiboken wrapper class
+ :align: left
+
+ Breakpoint set on the shiboken wrapper class
+
+ .. figure:: audioformat_cpp.png
+ :alt: Breakpoint set on C++ implementation
+ :align: left
+
+ Breakpoint set on C++ implementation
diff --git a/sources/pyside6/doc/tutorials/expenses/expenses.rst b/sources/pyside6/doc/tutorials/expenses/expenses.rst
new file mode 100644
index 000000000..2064488ae
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/expenses.rst
@@ -0,0 +1,285 @@
+Expenses Tool Tutorial
+======================
+
+In this tutorial you will learn the following concepts:
+ * creating user interfaces programatically,
+ * layouts and widgets,
+ * overloading Qt classes,
+ * connecting signal and slots,
+ * interacting with QWidgets,
+ * and building your own application.
+
+The requirements:
+ * A simple window for the application
+ (`QMainWindow <https://doc.qt.io/qtforpython/PySide6/QtWidgets/QMainWindow.html>`_).
+ * A table to keep track of the expenses
+ (`QTableWidget <https://doc.qt.io/qtforpython/PySide6/QtWidgets/QTableWidget.html>`_).
+ * Two input fields to add expense information
+ (`QLineEdit <https://doc.qt.io/qtforpython/PySide6/QtWidgets/QLineEdit.html>`_).
+ * Buttons to add information to the table, plot data, clear table, and exit the application
+ (`QPushButton <https://doc.qt.io/qtforpython/PySide6/QtWidgets/QPushButton.html>`_).
+ * A verification step to avoid invalid data entry.
+ * A chart to visualize the expense data
+ (`QChart <https://doc.qt.io/qtforpython/PySide6/QtCharts/QChart.html>`_) that will
+ be embedded in a chart view
+ (`QChartView <https://doc.qt.io/qtforpython/PySide6/QtCharts/QChartView.html>`_).
+
+Empty window
+------------
+
+The base structure for a `QApplication` is located inside the `if __name__ == "__main__":`
+code block.
+
+.. code-block:: python
+ :linenos:
+
+ if __name__ == "__main__":
+ app = QApplication([])
+ # ...
+ sys.exit(app.exec())
+
+Now, to start the development, create an empty window called `MainWindow`.
+You could do that by defining a class that inherits from `QMainWindow`.
+
+.. literalinclude:: steps/01-expenses.py
+ :linenos:
+ :lines: 8-22
+ :emphasize-lines: 1-4
+
+Now that our class is defined, create an instance of it and call `show()`.
+
+.. literalinclude:: steps/01-expenses.py
+ :linenos:
+ :lines: 8-22
+ :emphasize-lines: 10-12
+
+Menu bar
+--------
+
+Using a `QMainWindow` gives some features for free, among them a *menu bar*. To use it, you need
+to call the method `menuBar()` and populate it inside the `MainWindow` class.
+
+.. literalinclude:: steps/02-expenses.py
+ :linenos:
+ :lines: 9-19
+ :emphasize-lines: 10
+
+Notice that the code snippet adds a *File* menu with the *Exit* option only.
+
+The *Exit* option must be connected to a slot that triggers the application to exit. We pass
+``QWidget.close()`` here. After the last window has been closed, the application exits.
+
+Empty widget and data
+---------------------
+
+The `QMainWindow` enables us to set a central widget that will be displayed when showing the window
+(`read more <https://doc.qt.io/qt-5/qmainwindow.html#details>`_).
+This central widget could be another class derived from `QWidget`.
+
+Additionally, you will define example data to visualize later.
+
+.. literalinclude:: steps/04-expenses.py
+ :linenos:
+ :lines: 8-15
+
+With the `Widget` class in place, modify `MainWindow`'s initialization code
+
+.. literalinclude:: steps/04-expenses.py
+ :linenos:
+ :lines: 37-40
+
+Window layout
+-------------
+
+Now that the main empty window is in place, you need to start adding widgets to achieve the main
+goal of creating an expenses application.
+
+After declaring the example data, you can visualize it on a simple `QTableWidget`. To do so, you
+will add this procedure to the `Widget` constructor.
+
+.. warning:: Only for the example purpose a QTableWidget will be used,
+ but for more performance-critical applications the combination
+ of a model and a QTableView is encouraged.
+
+.. literalinclude:: steps/05-expenses.py
+ :linenos:
+ :lines: 11-31
+
+As you can see, the code also includes a `QHBoxLayout` that provides the container to place widgets
+horizontally.
+
+Additionally, the `QTableWidget` allows for customizing it, like adding the labels for the two
+columns that will be used, and to *stretch* the content to use the whole `Widget` space.
+
+The last line of code refers to *filling the table**, and the code to perform that task is
+displayed below.
+
+.. literalinclude:: steps/05-expenses.py
+ :linenos:
+ :lines: 33-39
+
+Having this process on a separate method is a good practice to leave the constructor more readable,
+and to split the main functions of the class in independent processes.
+
+
+Right side layout
+-----------------
+
+Because the data that is being used is just an example, you are required to include a mechanism to
+input items to the table, and extra buttons to clear the table's content, and also quit the
+application.
+
+For input lines along with descriptive labels, you will use a `QFormLayout`. Then,
+you will nest the form layout into a `QVBoxLayout` along with the buttons.
+
+.. literalinclude:: steps/06-expenses.py
+ :linenos:
+ :lines: 27-43
+
+Leaving the table on the left side and these newly included widgets to the right side
+will be just a matter to add a layout to our main `QHBoxLayout` as you saw in the previous
+example:
+
+.. literalinclude:: steps/06-expenses.py
+ :linenos:
+ :lines: 45-48
+
+The next step will be connecting those new buttons to slots.
+
+
+Adding elements
+---------------
+
+Each `QPushButton` have a signal called *clicked*, that is emitted when you click on the button.
+This will be more than enough for this example, but you can see other signals in the `official
+documentation <https://doc.qt.io/qtforpython/PySide6/QtWidgets/QAbstractButton.html#signals>`_.
+
+.. literalinclude:: steps/07-expenses.py
+ :linenos:
+ :lines: 50-52
+
+As you can see on the previous lines, we are connecting each *clicked* signal to different slots.
+In this example slots are normal class methods in charge of perform a determined task associated
+with our buttons. It is really important to decorate each method declaration with a `@Slot()`,
+that way, PySide6 knows internally how to register them into Qt and they
+will be invokable from `Signals` of QObjects when connected.
+
+
+.. literalinclude:: steps/07-expenses.py
+ :linenos:
+ :lines: 57-82
+ :emphasize-lines: 1, 23
+
+Since these slots are methods, we can access the class variables, like our `QTableWidget` to
+interact with it.
+
+The mechanism to add elements into the table is described as the following:
+
+ * get the *description* and *price* from the fields,
+ * insert a new empty row to the table,
+ * set the values for the empty row in each column,
+ * clear the input text fields,
+ * include the global count of table rows.
+
+To exit the application you can use the `quit()` method of the unique `QApplication` instance, and
+to clear the content of the table you can just set the table *row count*, and the internal count to
+zero.
+
+Verification step
+-----------------
+
+Adding information to the table needs to be a critical action that require a verification step
+to avoid adding invalid information, for example, empty information.
+
+You can use a signal from `QLineEdit` called *textChanged* which will be emitted every
+time something inside changes, i.e.: each key stroke.
+
+You can connect two different object's signal to the same slot, and this will be the case
+for your current application:
+
+.. literalinclude:: steps/08-expenses.py
+ :linenos:
+ :lines: 57-58
+
+The content of the *check_disable* slot will be really simple:
+
+.. literalinclude:: steps/08-expenses.py
+ :linenos:
+ :lines: 77-80
+
+You have two options, write a verification based on the current value
+of the string you retrieve, or manually get the whole content of both
+`QLineEdit`. The second is preferred in this case, so you can verify
+if the two inputs are not empty to enable the button *Add*.
+
+.. note:: Qt also provides a special class called
+ `QValidator <https://doc.qt.io/qtforpython/PySide6/QtGui/QValidator.html?highlight=qvalidator>`_
+ that you can use to validate any input.
+
+Empty chart view
+----------------
+
+New items can be added to the table, and the visualization is so far
+OK, but you can accomplish more by representing the data graphically.
+
+First you will include an empty `QChartView` placeholder into the right
+side of your application.
+
+.. literalinclude:: steps/09-expenses.py
+ :linenos:
+ :lines: 30-32
+
+Additionally the order of how you include widgets to the right
+`QVBoxLayout` will also change.
+
+.. literalinclude:: steps/09-expenses.py
+ :linenos:
+ :lines: 46-54
+ :emphasize-lines: 8
+
+Notice that before we had a line with `self.right.addStretch()`
+to fill up the vertical space between the *Add* and the *Clear* buttons,
+but now, with the `QChartView` it will not be necessary.
+
+Also, you need include a *Plot* button if you want to do it on-demand.
+
+Full application
+----------------
+
+For the final step, you will need to connect the *Plot* button
+to a slot that creates a chart and includes it into your `QChartView`.
+
+.. literalinclude:: steps/10-expenses.py
+ :linenos:
+ :lines: 62-67
+ :emphasize-lines: 3
+
+That is nothing new, since you already did it for the other buttons,
+but now take a look at how to create a chart and include it into
+your `QChartView`.
+
+.. literalinclude:: steps/10-expenses.py
+ :linenos:
+ :lines: 95-107
+
+The following steps show how to fill a `QPieSeries`:
+
+ * create a `QPieSeries`,
+ * iterate over the table row IDs,
+ * get the items at the *i* position,
+ * add those values to the *series*.
+
+Once the series has been populated with our data, you create a new `QChart`,
+add the series on it, and optionally set an alignment for the legend.
+
+The final line `self.chart_view.setChart(chart)` is in charge of bringing
+your newly created chart to the `QChartView`.
+
+The application will look like this:
+
+.. image:: expenses_tool.png
+
+And now you can see the whole code:
+
+.. literalinclude:: main.py
+ :linenos:
diff --git a/sources/pyside6/doc/tutorials/expenses/expenses_tool.png b/sources/pyside6/doc/tutorials/expenses/expenses_tool.png
new file mode 100644
index 000000000..7a6f6d1f0
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/expenses_tool.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/expenses/main.py b/sources/pyside6/doc/tutorials/expenses/main.py
new file mode 100644
index 000000000..a3a998470
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/main.py
@@ -0,0 +1,153 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import (QApplication, QFormLayout, QHeaderView,
+ QHBoxLayout, QLineEdit, QMainWindow,
+ QPushButton, QTableWidget, QTableWidgetItem,
+ QVBoxLayout, QWidget)
+from PySide6.QtCharts import QChartView, QPieSeries, QChart
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.setColumnCount(2)
+ self.table.setHorizontalHeaderLabels(["Description", "Price"])
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+ # Chart
+ self.chart_view = QChartView()
+ self.chart_view.setRenderHint(QPainter.Antialiasing)
+
+ # Right
+ self.description = QLineEdit()
+ self.description.setClearButtonEnabled(True)
+ self.price = QLineEdit()
+ self.price.setClearButtonEnabled(True)
+
+ self.add = QPushButton("Add")
+ self.clear = QPushButton("Clear")
+ self.plot = QPushButton("Plot")
+
+ # Disabling 'Add' button
+ self.add.setEnabled(False)
+
+ form_layout = QFormLayout()
+ form_layout.addRow("Description", self.description)
+ form_layout.addRow("Price", self.price)
+ self.right = QVBoxLayout()
+ self.right.addLayout(form_layout)
+ self.right.addWidget(self.add)
+ self.right.addWidget(self.plot)
+ self.right.addWidget(self.chart_view)
+ self.right.addWidget(self.clear)
+
+ # QWidget Layout
+ self.layout = QHBoxLayout(self)
+ self.layout.addWidget(self.table)
+ self.layout.addLayout(self.right)
+
+ # Signals and Slots
+ self.add.clicked.connect(self.add_element)
+ self.plot.clicked.connect(self.plot_data)
+ self.clear.clicked.connect(self.clear_table)
+ self.description.textChanged.connect(self.check_disable)
+ self.price.textChanged.connect(self.check_disable)
+
+ # Fill example data
+ self.fill_table()
+
+ @Slot()
+ def add_element(self):
+ des = self.description.text()
+ price = float(self.price.text())
+
+ self.table.insertRow(self.items)
+ description_item = QTableWidgetItem(des)
+ price_item = QTableWidgetItem(f"{price:.2f}")
+ price_item.setTextAlignment(Qt.AlignRight)
+
+ self.table.setItem(self.items, 0, description_item)
+ self.table.setItem(self.items, 1, price_item)
+
+ self.description.clear()
+ self.price.clear()
+
+ self.items += 1
+
+ @Slot()
+ def check_disable(self, s):
+ enabled = bool(self.description.text() and self.price.text())
+ self.add.setEnabled(enabled)
+
+ @Slot()
+ def plot_data(self):
+ # Get table information
+ series = QPieSeries()
+ for i in range(self.table.rowCount()):
+ text = self.table.item(i, 0).text()
+ number = float(self.table.item(i, 1).text())
+ series.append(text, number)
+
+ chart = QChart()
+ chart.addSeries(series)
+ chart.legend().setAlignment(Qt.AlignLeft)
+ self.chart_view.setChart(chart)
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ description_item = QTableWidgetItem(desc)
+ price_item = QTableWidgetItem(f"{price:.2f}")
+ price_item.setTextAlignment(Qt.AlignRight)
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, description_item)
+ self.table.setItem(self.items, 1, price_item)
+ self.items += 1
+
+ @Slot()
+ def clear_table(self):
+ self.table.setRowCount(0)
+ self.items = 0
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/main_snake_prop.py b/sources/pyside6/doc/tutorials/expenses/main_snake_prop.py
new file mode 100644
index 000000000..055544409
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/main_snake_prop.py
@@ -0,0 +1,177 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtCore import QMargins, Qt, Slot, QSize
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import (QAction, QApplication, QHeaderView, QHBoxLayout, QLabel, QLineEdit,
+ QMainWindow, QPushButton, QTableWidget, QTableWidgetItem,
+ QVBoxLayout, QWidget)
+from PySide6.QtCharts import QtCharts
+
+from __feature__ import snake_case, true_property
+
+
+class Widget(QWidget):
+ def __init__(self):
+ QWidget.__init__(self)
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.column_count = 2
+ self.table.horizontal_header_labels = ["Description", "Price"]
+ self.table.horizontal_header().section_resize_mode = QHeaderView.Stretch
+
+ # Chart
+ self.chart_view = QtCharts.QChartView()
+ self.chart_view.render_hint = QPainter.Antialiasing
+
+ # Right
+ self.description = QLineEdit()
+ self.price = QLineEdit()
+ self.add = QPushButton("Add")
+ self.clear = QPushButton("Clear")
+ self.quit = QPushButton("Quit")
+ self.plot = QPushButton("Plot")
+
+ # Disabling 'Add' button
+ self.add.enabled = False
+
+ self.right = QVBoxLayout()
+
+ self.right.contents_margins = QMargins(10, 10, 10, 10)
+ self.right.add_widget(QLabel("Description"))
+ self.right.add_widget(self.description)
+ self.right.add_widget(QLabel("Price"))
+ self.right.add_widget(self.price)
+ self.right.add_widget(self.add)
+ self.right.add_widget(self.plot)
+ self.right.add_widget(self.chart_view)
+ self.right.add_widget(self.clear)
+ self.right.add_widget(self.quit)
+
+ # QWidget Layout
+ self.layout = QHBoxLayout()
+
+ #self.table_view.setSizePolicy(size)
+ self.layout.add_widget(self.table)
+ self.layout.form_layout(self.right)
+
+ # Set the layout to the QWidget
+ self.set_layout(self.layout)
+
+ # Signals and Slots
+ self.add.clicked.connect(self.add_element)
+ self.quit.clicked.connect(self.quit_application)
+ self.plot.clicked.connect(self.plot_data)
+ self.clear.clicked.connect(self.clear_table)
+ self.description.textChanged[str].connect(self.check_disable)
+ self.price.textChanged[str].connect(self.check_disable)
+
+ # Fill example data
+ self.fill_table()
+
+ @Slot()
+ def add_element(self):
+ des = self.description.text
+ price = self.price.text
+
+ try:
+ price_item = QTableWidgetItem(f"{float(price):.2f}")
+ price_item.text_alignment = Qt.AlignRight
+
+ self.table.insert_row(self.items)
+ description_item = QTableWidgetItem(des)
+
+ self.table.set_item(self.items, 0, description_item)
+ self.table.set_item(self.items, 1, price_item)
+
+ self.description.text = ""
+ self.price.text = ""
+
+ self.items += 1
+ except ValueError:
+ print("Wrong price", price)
+
+ @Slot()
+ def check_disable(self, s):
+ if not self.description.text or not self.price.text:
+ self.add.enabled = False
+ else:
+ self.add.enabled = True
+
+ @Slot()
+ def plot_data(self):
+ # Get table information
+ series = QtCharts.QPieSeries()
+ for i in range(self.table.row_count):
+ text = self.table.item(i, 0).text()
+ number = float(self.table.item(i, 1).text())
+ series.append(text, number)
+
+ chart = QtCharts.QChart()
+ chart.add_series(series)
+ chart.legend().alignment = Qt.AlignLeft
+ self.chart_view.set_chart(chart)
+
+ @Slot()
+ def quit_application(self):
+ QApplication.quit()
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ description_item = QTableWidgetItem(desc)
+ price_item = QTableWidgetItem(f"{price:.2f}")
+ price_item.text_alignment = Qt.AlignRight
+ self.table.insert_row(self.items)
+ self.table.set_item(self.items, 0, description_item)
+ self.table.set_item(self.items, 1, price_item)
+ self.items += 1
+
+ @Slot()
+ def clear_table(self):
+ self.table.row_count = 0
+ self.items = 0
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ QMainWindow.__init__(self)
+ self.window_title = "Tutorial"
+
+ # Menu
+ self.menu = self.menu_bar()
+ self.file_menu = self.menu.add_menu("File")
+
+ # Exit QAction
+ exit_action = QAction("Exit", self)
+ exit_action.shortcut = "Ctrl+Q"
+ exit_action.triggered.connect(self.exit_app)
+
+ self.file_menu.add_action(exit_action)
+ self.set_central_widget(widget)
+
+ @Slot()
+ def exit_app(self, checked):
+ QApplication.quit()
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.size = QSize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/01-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/01-expenses.py
new file mode 100644
index 000000000..27f2aef65
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/01-expenses.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import QApplication, QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+
+ window = MainWindow()
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/02-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/02-expenses.py
new file mode 100644
index 000000000..039b818df
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/02-expenses.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import QApplication, QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+
+ window = MainWindow()
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/03-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/03-expenses.py
new file mode 100644
index 000000000..039b818df
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/03-expenses.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import QApplication, QMainWindow
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+
+ window = MainWindow()
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/04-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/04-expenses.py
new file mode 100644
index 000000000..6723690a8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/04-expenses.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import QApplication, QMainWindow, QWidget
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/05-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/05-expenses.py
new file mode 100644
index 000000000..df0362fde
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/05-expenses.py
@@ -0,0 +1,69 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import (QApplication, QHeaderView, QHBoxLayout,
+ QMainWindow, QTableWidget, QTableWidgetItem,
+ QWidget)
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.setColumnCount(2)
+ self.table.setHorizontalHeaderLabels(["Description", "Price"])
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+ # QWidget Layout
+ self.layout = QHBoxLayout(self)
+ self.layout.addWidget(self.table)
+
+ # Fill example data
+ self.fill_table()
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(desc))
+ self.table.setItem(self.items, 1, QTableWidgetItem(str(price)))
+ self.items += 1
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/06-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/06-expenses.py
new file mode 100644
index 000000000..d19a6220f
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/06-expenses.py
@@ -0,0 +1,89 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import (QApplication, QFormLayout, QHeaderView,
+ QHBoxLayout, QLineEdit, QMainWindow, QPushButton,
+ QTableWidget, QTableWidgetItem, QVBoxLayout,
+ QWidget)
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.setColumnCount(2)
+ self.table.setHorizontalHeaderLabels(["Description", "Price"])
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+ # Right
+ self.description = QLineEdit()
+ self.description.setClearButtonEnabled(True)
+ self.price = QLineEdit()
+ self.price.setClearButtonEnabled(True)
+
+ self.add = QPushButton("Add")
+ self.clear = QPushButton("Clear")
+
+ form_layout = QFormLayout()
+ form_layout.addRow("Description", self.description)
+ form_layout.addRow("Price", self.price)
+ self.right = QVBoxLayout()
+ self.right.addLayout(form_layout)
+ self.right.addWidget(self.add)
+ self.right.addStretch()
+ self.right.addWidget(self.clear)
+
+ # QWidget Layout
+ self.layout = QHBoxLayout(self)
+ self.layout.addWidget(self.table)
+ self.layout.addLayout(self.right)
+
+ # Fill example data
+ self.fill_table()
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(desc))
+ self.table.setItem(self.items, 1, QTableWidgetItem(str(price)))
+ self.items += 1
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/07-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/07-expenses.py
new file mode 100644
index 000000000..b1ed3fecc
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/07-expenses.py
@@ -0,0 +1,112 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtCore import Slot
+from PySide6.QtWidgets import (QApplication, QFormLayout, QHeaderView,
+ QHBoxLayout, QLineEdit, QMainWindow, QPushButton,
+ QTableWidget, QTableWidgetItem, QVBoxLayout,
+ QWidget)
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.setColumnCount(2)
+ self.table.setHorizontalHeaderLabels(["Description", "Price"])
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+ # Right
+ self.description = QLineEdit()
+ self.description.setClearButtonEnabled(True)
+ self.price = QLineEdit()
+ self.price.setClearButtonEnabled(True)
+
+ self.add = QPushButton("Add")
+ self.clear = QPushButton("Clear")
+
+ form_layout = QFormLayout()
+ form_layout.addRow("Description", self.description)
+ form_layout.addRow("Price", self.price)
+ self.right = QVBoxLayout()
+ self.right.addLayout(form_layout)
+ self.right.addWidget(self.add)
+ self.right.addStretch()
+
+ # QWidget Layout
+ self.layout = QHBoxLayout(self)
+ self.layout.addWidget(self.table)
+ self.layout.addLayout(self.right)
+
+ # Signals and Slots
+ self.add.clicked.connect(self.add_element)
+ self.clear.clicked.connect(self.clear_table)
+
+ # Fill example data
+ self.fill_table()
+
+ @Slot()
+ def add_element(self):
+ des = self.description.text()
+ price = self.price.text()
+
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(des))
+ self.table.setItem(self.items, 1, QTableWidgetItem(price))
+
+ self.description.clear()
+ self.price.clear()
+
+ self.items += 1
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(desc))
+ self.table.setItem(self.items, 1, QTableWidgetItem(str(price)))
+ self.items += 1
+
+ @Slot()
+ def clear_table(self):
+ self.table.setRowCount(0)
+ self.items = 0
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/08-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/08-expenses.py
new file mode 100644
index 000000000..0e7e21a32
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/08-expenses.py
@@ -0,0 +1,123 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtCore import Slot
+from PySide6.QtWidgets import (QApplication, QFormLayout, QHeaderView,
+ QHBoxLayout, QLineEdit, QMainWindow, QPushButton,
+ QTableWidget, QTableWidgetItem, QVBoxLayout,
+ QWidget)
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.setColumnCount(2)
+ self.table.setHorizontalHeaderLabels(["Description", "Price"])
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+ # Right
+ self.description = QLineEdit()
+ self.description.setClearButtonEnabled(True)
+ self.price = QLineEdit()
+ self.price.setClearButtonEnabled(True)
+
+ self.add = QPushButton("Add")
+ self.clear = QPushButton("Clear")
+
+ # Disabling 'Add' button
+ self.add.setEnabled(False)
+
+ form_layout = QFormLayout()
+ form_layout.addRow("Description", self.description)
+ form_layout.addRow("Price", self.price)
+ self.right = QVBoxLayout()
+ self.right.addLayout(form_layout)
+ self.right.addWidget(self.add)
+ self.right.addStretch()
+ self.right.addWidget(self.clear)
+
+ # QWidget Layout
+ self.layout = QHBoxLayout(self)
+ self.layout.addWidget(self.table)
+ self.layout.addLayout(self.right)
+
+ # Signals and Slots
+ self.add.clicked.connect(self.add_element)
+ self.clear.clicked.connect(self.clear_table)
+ self.description.textChanged.connect(self.check_disable)
+ self.price.textChanged.connect(self.check_disable)
+
+ # Fill example data
+ self.fill_table()
+
+ @Slot()
+ def add_element(self):
+ des = self.description.text()
+ price = self.price.text()
+
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(des))
+ self.table.setItem(self.items, 1, QTableWidgetItem(price))
+
+ self.description.clear()
+ self.price.clear()
+
+ self.items += 1
+
+ @Slot()
+ def check_disable(self, s):
+ enabled = bool(self.description.text() and self.price.text())
+ self.add.setEnabled(enabled)
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(desc))
+ self.table.setItem(self.items, 1, QTableWidgetItem(str(price)))
+ self.items += 1
+
+ @Slot()
+ def clear_table(self):
+ self.table.setRowCount(0)
+ self.items = 0
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/09-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/09-expenses.py
new file mode 100644
index 000000000..279a46512
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/09-expenses.py
@@ -0,0 +1,131 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtCore import Slot
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import (QApplication, QFormLayout, QHeaderView,
+ QHBoxLayout, QLineEdit, QMainWindow,
+ QPushButton, QTableWidget, QTableWidgetItem,
+ QVBoxLayout, QWidget)
+from PySide6.QtCharts import QChartView
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.setColumnCount(2)
+ self.table.setHorizontalHeaderLabels(["Description", "Price"])
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+ # Chart
+ self.chart_view = QChartView()
+ self.chart_view.setRenderHint(QPainter.Antialiasing)
+
+ # Right
+ self.description = QLineEdit()
+ self.description.setClearButtonEnabled(True)
+ self.price = QLineEdit()
+ self.price.setClearButtonEnabled(True)
+ self.add = QPushButton("Add")
+ self.clear = QPushButton("Clear")
+ self.plot = QPushButton("Plot")
+
+ # Disabling 'Add' button
+ self.add.setEnabled(False)
+
+ form_layout = QFormLayout()
+ form_layout.addRow("Description", self.description)
+ form_layout.addRow("Price", self.price)
+ self.right = QVBoxLayout()
+ self.right.addLayout(form_layout)
+ self.right.addWidget(self.add)
+ self.right.addWidget(self.plot)
+ self.right.addWidget(self.chart_view)
+ self.right.addWidget(self.clear)
+
+ # QWidget Layout
+ self.layout = QHBoxLayout(self)
+
+ self.layout.addWidget(self.table)
+ self.layout.addLayout(self.right)
+
+ # Signals and Slots
+ self.add.clicked.connect(self.add_element)
+ self.clear.clicked.connect(self.clear_table)
+ self.description.textChanged.connect(self.check_disable)
+ self.price.textChanged.connect(self.check_disable)
+
+ # Fill example data
+ self.fill_table()
+
+ @Slot()
+ def add_element(self):
+ des = self.description.text()
+ price = self.price.text()
+
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(des))
+ self.table.setItem(self.items, 1, QTableWidgetItem(price))
+
+ self.description.clear()
+ self.price.clear()
+
+ self.items += 1
+
+ @Slot()
+ def check_disable(self, s):
+ enabled = bool(self.description.text() and self.price.text())
+ self.add.setEnabled(enabled)
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, QTableWidgetItem(desc))
+ self.table.setItem(self.items, 1, QTableWidgetItem(str(price)))
+ self.items += 1
+
+ @Slot()
+ def clear_table(self):
+ self.table.setRowCount(0)
+ self.items = 0
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/expenses/steps/10-expenses.py b/sources/pyside6/doc/tutorials/expenses/steps/10-expenses.py
new file mode 100644
index 000000000..a3a998470
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/expenses/steps/10-expenses.py
@@ -0,0 +1,153 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import (QApplication, QFormLayout, QHeaderView,
+ QHBoxLayout, QLineEdit, QMainWindow,
+ QPushButton, QTableWidget, QTableWidgetItem,
+ QVBoxLayout, QWidget)
+from PySide6.QtCharts import QChartView, QPieSeries, QChart
+
+
+class Widget(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.items = 0
+
+ # Example data
+ self._data = {"Water": 24.5, "Electricity": 55.1, "Rent": 850.0,
+ "Supermarket": 230.4, "Internet": 29.99, "Bars": 21.85,
+ "Public transportation": 60.0, "Coffee": 22.45, "Restaurants": 120}
+
+ # Left
+ self.table = QTableWidget()
+ self.table.setColumnCount(2)
+ self.table.setHorizontalHeaderLabels(["Description", "Price"])
+ self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
+
+ # Chart
+ self.chart_view = QChartView()
+ self.chart_view.setRenderHint(QPainter.Antialiasing)
+
+ # Right
+ self.description = QLineEdit()
+ self.description.setClearButtonEnabled(True)
+ self.price = QLineEdit()
+ self.price.setClearButtonEnabled(True)
+
+ self.add = QPushButton("Add")
+ self.clear = QPushButton("Clear")
+ self.plot = QPushButton("Plot")
+
+ # Disabling 'Add' button
+ self.add.setEnabled(False)
+
+ form_layout = QFormLayout()
+ form_layout.addRow("Description", self.description)
+ form_layout.addRow("Price", self.price)
+ self.right = QVBoxLayout()
+ self.right.addLayout(form_layout)
+ self.right.addWidget(self.add)
+ self.right.addWidget(self.plot)
+ self.right.addWidget(self.chart_view)
+ self.right.addWidget(self.clear)
+
+ # QWidget Layout
+ self.layout = QHBoxLayout(self)
+ self.layout.addWidget(self.table)
+ self.layout.addLayout(self.right)
+
+ # Signals and Slots
+ self.add.clicked.connect(self.add_element)
+ self.plot.clicked.connect(self.plot_data)
+ self.clear.clicked.connect(self.clear_table)
+ self.description.textChanged.connect(self.check_disable)
+ self.price.textChanged.connect(self.check_disable)
+
+ # Fill example data
+ self.fill_table()
+
+ @Slot()
+ def add_element(self):
+ des = self.description.text()
+ price = float(self.price.text())
+
+ self.table.insertRow(self.items)
+ description_item = QTableWidgetItem(des)
+ price_item = QTableWidgetItem(f"{price:.2f}")
+ price_item.setTextAlignment(Qt.AlignRight)
+
+ self.table.setItem(self.items, 0, description_item)
+ self.table.setItem(self.items, 1, price_item)
+
+ self.description.clear()
+ self.price.clear()
+
+ self.items += 1
+
+ @Slot()
+ def check_disable(self, s):
+ enabled = bool(self.description.text() and self.price.text())
+ self.add.setEnabled(enabled)
+
+ @Slot()
+ def plot_data(self):
+ # Get table information
+ series = QPieSeries()
+ for i in range(self.table.rowCount()):
+ text = self.table.item(i, 0).text()
+ number = float(self.table.item(i, 1).text())
+ series.append(text, number)
+
+ chart = QChart()
+ chart.addSeries(series)
+ chart.legend().setAlignment(Qt.AlignLeft)
+ self.chart_view.setChart(chart)
+
+ def fill_table(self, data=None):
+ data = self._data if not data else data
+ for desc, price in data.items():
+ description_item = QTableWidgetItem(desc)
+ price_item = QTableWidgetItem(f"{price:.2f}")
+ price_item.setTextAlignment(Qt.AlignRight)
+ self.table.insertRow(self.items)
+ self.table.setItem(self.items, 0, description_item)
+ self.table.setItem(self.items, 1, price_item)
+ self.items += 1
+
+ @Slot()
+ def clear_table(self):
+ self.table.setRowCount(0)
+ self.items = 0
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, widget):
+ super().__init__()
+ self.setWindowTitle("Tutorial")
+
+ # Menu
+ self.menu = self.menuBar()
+ self.file_menu = self.menu.addMenu("File")
+
+ # Exit QAction
+ exit_action = self.file_menu.addAction("Exit", self.close)
+ exit_action.setShortcut("Ctrl+Q")
+
+ self.setCentralWidget(widget)
+
+
+if __name__ == "__main__":
+ # Qt Application
+ app = QApplication(sys.argv)
+ # QWidget
+ widget = Widget()
+ # QMainWindow using QWidget as central widget
+ window = MainWindow(widget)
+ window.resize(800, 600)
+ window.show()
+
+ # Execute application
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/Main.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/Main.qml
new file mode 100644
index 000000000..faa9175d6
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/Main.qml
@@ -0,0 +1,196 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Basic
+import QtQuick.Layouts
+import FileSystemModule
+
+pragma ComponentBehavior: Bound
+
+ApplicationWindow {
+ id: root
+
+ property bool expandPath: false
+ property bool showLineNumbers: true
+ property string currentFilePath: ""
+
+ width: 1100
+ height: 600
+ minimumWidth: 200
+ minimumHeight: 100
+ visible: true
+ color: Colors.background
+ flags: Qt.Window | Qt.FramelessWindowHint
+ title: qsTr("File System Explorer Example")
+
+ function getInfoText() : string {
+ let out = root.currentFilePath
+ if (!out)
+ return qsTr("File System Explorer")
+ return root.expandPath ? out : out.substring(out.lastIndexOf("/") + 1, out.length)
+ }
+
+ menuBar: MyMenuBar {
+ dragWindow: root
+ infoText: root.getInfoText()
+ MyMenu {
+ title: qsTr("File")
+
+ Action {
+ text: qsTr("Increase Font")
+ shortcut: StandardKey.ZoomIn
+ onTriggered: editor.text.font.pixelSize += 1
+ }
+ Action {
+ text: qsTr("Decrease Font")
+ shortcut: StandardKey.ZoomOut
+ onTriggered: editor.text.font.pixelSize -= 1
+ }
+ Action {
+ text: root.showLineNumbers ? qsTr("Toggle Line Numbers OFF")
+ : qsTr("Toggle Line Numbers ON")
+ shortcut: "Ctrl+L"
+ onTriggered: root.showLineNumbers = !root.showLineNumbers
+ }
+ Action {
+ text: root.expandPath ? qsTr("Toggle Short Path")
+ : qsTr("Toggle Expand Path")
+ enabled: root.currentFilePath
+ onTriggered: root.expandPath = !root.expandPath
+ }
+ Action {
+ text: qsTr("Reset Filesystem")
+ enabled: sidebar.currentTabIndex === 1
+ onTriggered: fileSystemView.rootIndex = undefined
+ }
+ Action {
+ text: qsTr("Exit")
+ onTriggered: Qt.exit(0)
+ shortcut: StandardKey.Quit
+ }
+ }
+
+ MyMenu {
+ title: qsTr("Edit")
+
+ Action {
+ text: qsTr("Cut")
+ shortcut: StandardKey.Cut
+ enabled: editor.text.selectedText.length > 0
+ onTriggered: editor.text.cut()
+ }
+ Action {
+ text: qsTr("Copy")
+ shortcut: StandardKey.Copy
+ enabled: editor.text.selectedText.length > 0
+ onTriggered: editor.text.copy()
+ }
+ Action {
+ text: qsTr("Paste")
+ shortcut: StandardKey.Paste
+ enabled: editor.text.canPaste
+ onTriggered: editor.text.paste()
+ }
+ Action {
+ text: qsTr("Select All")
+ shortcut: StandardKey.SelectAll
+ enabled: editor.text.length > 0
+ onTriggered: editor.text.selectAll()
+ }
+ Action {
+ text: qsTr("Undo")
+ shortcut: StandardKey.Undo
+ enabled: editor.text.canUndo
+ onTriggered: editor.text.undo()
+ }
+ }
+ }
+ // Set up the layout of the main components in a row:
+ // [ Sidebar, Navigation, Editor ]
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
+
+ // Stores the buttons that navigate the application.
+ Sidebar {
+ id: sidebar
+ dragWindow: root
+ Layout.preferredWidth: 50
+ Layout.fillHeight: true
+ }
+
+ // Allows resizing parts of the UI.
+ SplitView {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ // Customized handle to drag between the Navigation and the Editor.
+ handle: Rectangle {
+ implicitWidth: 10
+ color: SplitHandle.pressed ? Colors.color2 : Colors.background
+ border.color: SplitHandle.hovered ? Colors.color2 : Colors.background
+ opacity: SplitHandle.hovered || navigationView.width < 15 ? 1.0 : 0.0
+
+ Behavior on opacity {
+ OpacityAnimator {
+ duration: 1400
+ }
+ }
+ }
+
+ Rectangle {
+ id: navigationView
+ color: Colors.surface1
+ SplitView.preferredWidth: 250
+ SplitView.fillHeight: true
+ // The stack-layout provides different views, based on the
+ // selected buttons inside the sidebar.
+ StackLayout {
+ anchors.fill: parent
+ currentIndex: sidebar.currentTabIndex > 1 ? 1 : sidebar.currentTabIndex
+
+ // Shows the help text.
+ Text {
+ text: qsTr("This example shows how to use and visualize the file system.\n\n"
+ + "Customized Qt Quick Components have been used to achieve this look.\n\n"
+ + "You can edit the files but they won't be changed on the file system.\n\n"
+ + "Click on the folder icon to the left to get started.")
+ wrapMode: TextArea.Wrap
+ color: Colors.text
+ }
+
+ // Shows the files on the file system.
+ FileSystemView {
+ id: fileSystemView
+ color: Colors.surface1
+ onFileClicked: path => root.currentFilePath = path
+ }
+ }
+ }
+
+ // The main view that contains the editor or the scheme-manager.
+ StackLayout {
+ currentIndex: sidebar.currentTabIndex > 1 ? 1 : 0
+
+ SplitView.fillWidth: true
+ SplitView.fillHeight: true
+
+ Editor {
+ id: editor
+ showLineNumbers: root.showLineNumbers
+ currentFilePath: root.currentFilePath
+ }
+
+ ColorScheme {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+
+ }
+ }
+ }
+
+ ResizeButton {
+ resizeWindow: root
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/app.qrc b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/app.qrc
new file mode 100644
index 000000000..ccd9eefec
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/app.qrc
@@ -0,0 +1,16 @@
+<RCC>
+ <qresource prefix="/qt/qml/FileSystemModule">
+ <file>qmldir</file>
+ <file>Main.qml</file>
+ <file>qml/About.qml</file>
+ <file>qml/Editor.qml</file>
+ <file>qml/Colors.qml</file>
+ <file>qml/FileSystemView.qml</file>
+ <file>qml/Icon.qml</file>
+ <file>qml/MyMenu.qml</file>
+ <file>qml/MyMenuBar.qml</file>
+ <file>qml/ResizeButton.qml</file>
+ <file>qml/Sidebar.qml</file>
+ <file>qml/WindowDragHandler.qml</file>
+ </qresource>
+</RCC>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons.qrc b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons.qrc
new file mode 100644
index 000000000..69bddc018
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons.qrc
@@ -0,0 +1,15 @@
+<RCC>
+ <qresource>
+ <file>icons/app_icon.svg</file>
+ <file>icons/folder_closed.svg</file>
+ <file>icons/folder_open.svg</file>
+ <file>icons/generic_file.svg</file>
+ <file>icons/globe.svg</file>
+ <file>icons/info_sign.svg</file>
+ <file>icons/leaf.svg</file>
+ <file>icons/light_bulb.svg</file>
+ <file>icons/qt_logo.svg</file>
+ <file>icons/read.svg</file>
+ <file>icons/resize.svg</file>
+ </qresource>
+</RCC>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/app_icon.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/app_icon.svg
new file mode 100644
index 000000000..5aae4221f
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/app_icon.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="#EBDBB2" d="M13.25 8.5a.75.75 0 1 1-.75-.75.75.75 0 0 1 .75.75zM9.911 21.35l.816.578C10.819 21.798 13 18.666 13 13h-1a15.503 15.503 0 0 1-2.089 8.35zM4 6.703V10a2.002 2.002 0 0 1-2 2v1a2.002 2.002 0 0 1 2 2v3.297A3.707 3.707 0 0 0 7.703 22H9v-1H7.703A2.706 2.706 0 0 1 5 18.297V15a2.999 2.999 0 0 0-1.344-2.5A2.999 2.999 0 0 0 5 10V6.703A2.706 2.706 0 0 1 7.703 4H9V3H7.703A3.707 3.707 0 0 0 4 6.703zM20 10V6.703A3.707 3.707 0 0 0 16.297 3H15v1h1.297A2.706 2.706 0 0 1 19 6.703V10a2.999 2.999 0 0 0 1.344 2.5A2.999 2.999 0 0 0 19 15v3.297A2.706 2.706 0 0 1 16.297 21H15v1h1.297A3.707 3.707 0 0 0 20 18.297V15a2.002 2.002 0 0 1 2-2v-1a2.002 2.002 0 0 1-2-2z"/><path fill="none" d="M0 0h24v24H0z"/></svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_closed.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_closed.svg
new file mode 100644
index 000000000..36f119c96
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_closed.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewBox="-10 0 1792 1792"
+ id="svg51"
+ sodipodi:docname="folder_closed.svg"
+ width="1792"
+ height="1792"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs55" />
+ <sodipodi:namedview
+ id="namedview53"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="0.45033482"
+ inkscape:cx="842.70632"
+ inkscape:cy="896"
+ inkscape:window-width="1846"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg51" />
+ <path
+ fill="currentColor"
+ d="m 1718,672 v 704 q 0,92 -66,158 -66,66 -158,66 H 278 q -92,0 -158,-66 -66,-66 -66,-158 V 416 q 0,-92 66,-158 66,-66 158,-66 h 320 q 92,0 158,66 66,66 66,158 v 32 h 672 q 92,0 158,66 66,66 66,158 z"
+ id="path49" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_open.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_open.svg
new file mode 100644
index 000000000..daa55a7a1
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/folder_open.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewBox="-10 0 1792 1792"
+ id="svg139"
+ sodipodi:docname="folder_open.svg"
+ width="1792"
+ height="1792"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs143" />
+ <sodipodi:namedview
+ id="namedview141"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="0.24358259"
+ inkscape:cx="149.84651"
+ inkscape:cy="1098.1901"
+ inkscape:window-width="1846"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg139" />
+ <path
+ fill="currentColor"
+ d="M 1590,1376 V 672 q 0,-40 -28,-68 -28,-28 -68,-28 H 790 q -40,0 -68,-28 -28,-28 -28,-68 v -64 q 0,-40 -28,-68 -28,-28 -68,-28 H 278 q -40,0 -68,28 -28,28 -28,68 v 960 q 0,40 28,68 28,28 68,28 h 1216 q 40,0 68,-28 28,-28 28,-68 z m 128,-704 v 704 q 0,92 -66,158 -66,66 -158,66 H 278 q -92,0 -158,-66 -66,-66 -66,-158 V 416 q 0,-92 66,-158 66,-66 158,-66 h 320 q 92,0 158,66 66,66 66,158 v 32 h 672 q 92,0 158,66 66,66 66,158 z"
+ id="path137" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/generic_file.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/generic_file.svg
new file mode 100644
index 000000000..9c855676e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/generic_file.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewBox="-10 0 1792 1792"
+ id="svg147"
+ sodipodi:docname="generic_file.svg"
+ width="1792"
+ height="1792"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs151" />
+ <sodipodi:namedview
+ id="namedview149"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="0.12179129"
+ inkscape:cx="-578.85911"
+ inkscape:cy="1687.3127"
+ inkscape:window-width="1846"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg147" />
+ <path
+ fill="currentColor"
+ d="m 1586,476 q 14,14 28,36 H 1142 V 40 q 22,14 36,28 z m -476,164 h 544 v 1056 q 0,40 -28,68 -28,28 -68,28 H 214 q -40,0 -68,-28 -28,-28 -28,-68 V 96 Q 118,56 146,28 174,0 214,0 h 800 v 544 q 0,40 28,68 28,28 68,28 z m 160,736 v -64 q 0,-14 -9,-23 -9,-9 -23,-9 H 534 q -14,0 -23,9 -9,9 -9,23 v 64 q 0,14 9,23 9,9 23,9 h 704 q 14,0 23,-9 9,-9 9,-23 z m 0,-256 v -64 q 0,-14 -9,-23 -9,-9 -23,-9 H 534 q -14,0 -23,9 -9,9 -9,23 v 64 q 0,14 9,23 9,9 23,9 h 704 q 14,0 23,-9 9,-9 9,-23 z m 0,-256 v -64 q 0,-14 -9,-23 -9,-9 -23,-9 H 534 q -14,0 -23,9 -9,9 -9,23 v 64 q 0,14 9,23 9,9 23,9 h 704 q 14,0 23,-9 9,-9 9,-23 z"
+ id="path145" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/globe.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/globe.svg
new file mode 100644
index 000000000..081433813
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/globe.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewBox="-10 0 1792 1792"
+ id="svg155"
+ sodipodi:docname="globe.svg"
+ width="1792"
+ height="1792"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs159" />
+ <sodipodi:namedview
+ id="namedview157"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="0.12179129"
+ inkscape:cx="504.9622"
+ inkscape:cy="1720.1558"
+ inkscape:window-width="1846"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg155" />
+ <path
+ fill="currentColor"
+ d="m 886,128 q 209,0 385.5,103 176.5,103 279.5,279.5 103,176.5 103,385.5 0,209 -103,385.5 Q 1448,1458 1271.5,1561 1095,1664 886,1664 677,1664 500.5,1561 324,1458 221,1281.5 118,1105 118,896 118,687 221,510.5 324,334 500.5,231 677,128 886,128 Z m 274,521 q -2,1 -9.5,9.5 -7.5,8.5 -13.5,9.5 2,0 4.5,-5 2.5,-5 5,-11 2.5,-6 3.5,-7 6,-7 22,-15 14,-6 52,-12 34,-8 51,11 -2,-2 9.5,-13 11.5,-11 14.5,-12 3,-2 15,-4.5 12,-2.5 15,-7.5 l 2,-22 q -12,1 -17.5,-7 -5.5,-8 -6.5,-21 0,2 -6,8 0,-7 -4.5,-8 -4.5,-1 -11.5,1 -7,2 -9,1 -10,-3 -15,-7.5 -5,-4.5 -8,-16.5 -3,-12 -4,-15 -2,-5 -9.5,-10.5 -7.5,-5.5 -9.5,-10.5 -1,-2 -2.5,-5.5 -1.5,-3.5 -3,-6.5 -1.5,-3 -4,-5.5 -2.5,-2.5 -5.5,-2.5 -3,0 -7,5 -4,5 -7.5,10 -3.5,5 -4.5,5 -3,-2 -6,-1.5 -3,0.5 -4.5,1 -1.5,0.5 -4.5,3 -3,2.5 -5,3.5 -3,2 -8.5,3 -5.5,1 -8.5,2 15,-5 -1,-11 -10,-4 -16,-3 9,-4 7.5,-12 -1.5,-8 -8.5,-14 h 5 q -1,-4 -8.5,-8.5 -7.5,-4.5 -17.5,-8.5 -10,-4 -13,-6 -8,-5 -34,-9.5 -26,-4.5 -33,-0.5 -5,6 -4.5,10.5 0.5,4.5 4,14 3.5,9.5 3.5,12.5 1,6 -5.5,13 -6.5,7 -6.5,12 0,7 14,15.5 14,8.5 10,21.5 -3,8 -16,16 -13,8 -16,12 -5,8 -1.5,18.5 3.5,10.5 10.5,16.5 2,2 1.5,4 -0.5,2 -3.5,4.5 -3,2.5 -5.5,4 -2.5,1.5 -6.5,3.5 l -3,2 q -11,5 -20.5,-6 -9.5,-11 -13.5,-26 -7,-25 -16,-30 -23,-8 -29,1 -5,-13 -41,-26 -25,-9 -58,-4 6,-1 0,-15 -7,-15 -19,-12 3,-6 4,-17.5 1,-11.5 1,-13.5 3,-13 12,-23 1,-1 7,-8.5 6,-7.5 9.5,-13.5 3.5,-6 0.5,-6 35,4 50,-11 5,-5 11.5,-17 6.5,-12 10.5,-17 9,-6 14,-5.5 5,0.5 14.5,5.5 9.5,5 14.5,5 14,1 15.5,-11 1.5,-12 -7.5,-20 12,1 3,-17 -5,-7 -8,-9 -12,-4 -27,5 -8,4 2,8 -1,-1 -9.5,10.5 Q 927,340 919,346 q -8,6 -16,-5 -1,-1 -5.5,-13.5 Q 893,315 888,314 q -8,0 -16,15 3,-8 -11,-15 -14,-7 -24,-8 19,-12 -8,-27 -7,-4 -20.5,-5 -13.5,-1 -19.5,4 -5,7 -5.5,11.5 -0.5,4.5 5,8 5.5,3.5 10.5,5.5 5,2 11.5,4 6.5,2 8.5,3 14,10 8,14 -2,1 -8.5,3.5 -6.5,2.5 -11.5,4.5 -5,2 -6,4 -3,4 0,14 3,10 -2,14 -5,-5 -9,-17.5 -4,-12.5 -7,-16.5 7,9 -25,6 l -10,-1 q -4,0 -16,2 -12,2 -20.5,1 -8.5,-1 -13.5,-8 -4,-8 0,-20 1,-4 4,-2 -4,-3 -11,-9.5 -7,-6.5 -10,-8.5 -46,15 -94,41 6,1 12,-1 5,-2 13,-6.5 8,-4.5 10,-5.5 34,-14 42,-7 l 5,-5 q 14,16 20,25 -7,-4 -30,-1 -20,6 -22,12 7,12 5,18 -4,-3 -11.5,-10 -7.5,-7 -14.5,-11 -7,-4 -15,-5 -16,0 -22,1 -146,80 -235,222 7,7 12,8 4,1 5,9 1,8 2.5,11 1.5,3 11.5,-3 9,8 3,19 1,-1 44,27 19,17 21,21 3,11 -10,18 -1,-2 -9,-9 -8,-7 -9,-4 -3,5 0.5,18.5 3.5,13.5 10.5,12.5 -7,0 -9.5,16 -2.5,16 -2.5,35.5 0,19.5 -1,23.5 l 2,1 q -3,12 5.5,34.5 8.5,22.5 21.5,19.5 -13,3 20,43 6,8 8,9 3,2 12,7.5 9,5.5 15,10 6,4.5 10,10.5 4,5 10,22.5 6,17.5 14,23.5 -2,6 9.5,20 11.5,14 10.5,23 -1,0 -2.5,1 -1.5,1 -2.5,1 3,7 15.5,14 12.5,7 15.5,13 1,3 2,10 1,7 3,11 2,4 8,2 2,-20 -24,-62 -15,-25 -17,-29 -3,-5 -5.5,-15.5 Q 541,919 539,915 q 2,0 6,1.5 4,1.5 8.5,3.5 4.5,2 7.5,4 3,2 2,3 -3,7 2,17.5 5,10.5 12,18.5 7,8 17,19 10,11 12,13 6,6 14,19.5 8,13.5 0,13.5 9,0 20,10 11,10 17,20 5,8 8,26 3,18 5,24 2,7 8.5,13.5 6.5,6.5 12.5,9.5 l 16,8 q 0,0 13,7 5,2 18.5,10.5 13.5,8.5 21.5,11.5 10,4 16,4 6,0 14.5,-2.5 8.5,-2.5 13.5,-3.5 15,-2 29,15 14,17 21,21 36,19 55,11 -2,1 0.5,7.5 2.5,6.5 8,15.5 5.5,9 9,14.5 3.5,5.5 5.5,8.5 5,6 18,15 13,9 18,15 6,-4 7,-9 -3,8 7,20 10,12 18,10 14,-3 14,-32 -31,15 -49,-18 0,-1 -2.5,-5.5 -2.5,-4.5 -4,-8.5 -1.5,-4 -2.5,-8.5 -1,-4.5 0,-7.5 1,-3 5,-3 9,0 10,-3.5 1,-3.5 -2,-12.5 -3,-9 -4,-13 -1,-8 -11,-20 -10,-12 -12,-15 -5,9 -16,8 -11,-1 -16,-9 0,1 -1.5,5.5 -1.5,4.5 -1.5,6.5 -13,0 -15,-1 1,-3 2.5,-17.5 1.5,-14.5 3.5,-22.5 1,-4 5.5,-12 4.5,-8 7.5,-14.5 3,-6.5 4,-12.5 1,-6 -4.5,-9.5 -5.5,-3.5 -17.5,-2.5 -19,1 -26,20 -1,3 -3,10.5 -2,7.5 -5,11.5 -3,4 -9,7 -7,3 -24,2 -17,-1 -24,-5 -13,-8 -22.5,-29 -9.5,-21 -9.5,-37 0,-10 2.5,-26.5 2.5,-16.5 3,-25 0.5,-8.5 -5.5,-24.5 3,-2 9,-9.5 6,-7.5 10,-10.5 2,-1 4.5,-1.5 2.5,-0.5 4.5,0 2,0.5 4,-1.5 2,-2 3,-6 -1,-1 -4,-3 -3,-3 -4,-3 7,3 28.5,-1.5 21.5,-4.5 27.5,1.5 15,11 22,-2 0,-1 -2.5,-9.5 Q 870,931 872,926 q 5,27 29,9 3,3 15.5,5 12.5,2 17.5,5 3,2 7,5.5 4,3.5 5.5,4.5 1.5,1 5,-0.5 3.5,-1.5 8.5,-6.5 10,14 12,24 11,40 19,44 7,3 11,2 4,-1 4.5,-9.5 0.5,-8.5 0,-14 Q 1006,989 1005,982 l -1,-8 v -18 l -1,-8 q -15,-3 -18.5,-12 -3.5,-9 1.5,-18.5 5,-9.5 15,-18.5 1,-1 8,-3.5 7,-2.5 15.5,-6.5 8.5,-4 12.5,-8 21,-19 15,-35 7,0 11,-9 -1,0 -5,-3 -4,-3 -7.5,-5 -3.5,-2 -4.5,-2 9,-5 2,-16 5,-3 7.5,-11 2.5,-8 7.5,-10 9,12 21,2 7,-8 1,-16 5,-7 20.5,-10.5 15.5,-3.5 18.5,-9.5 7,2 8,-2 1,-4 1,-12 0,-8 3,-12 4,-5 15,-9 11,-4 13,-5 l 17,-11 q 3,-4 0,-4 18,2 31,-11 10,-11 -6,-20 3,-6 -3,-9.5 -6,-3.5 -15,-5.5 3,-1 11.5,-0.5 8.5,0.5 10.5,-1.5 15,-10 -7,-16 -17,-5 -43,12 z m -163,877 q 206,-36 351,-189 -3,-3 -12.5,-4.5 -9.5,-1.5 -12.5,-3.5 -18,-7 -24,-8 1,-7 -2.5,-13 -3.5,-6 -8,-9 -4.5,-3 -12.5,-8 -8,-5 -11,-7 -2,-2 -7,-6 -5,-4 -7,-5.5 -2,-1.5 -7.5,-4.5 -5.5,-3 -8.5,-2 -3,1 -10,1 l -3,1 q -3,1 -5.5,2.5 -2.5,1.5 -5.5,3 -3,1.5 -4,3 -1,1.5 0,2.5 -21,-17 -36,-22 -5,-1 -11,-5.5 -6,-4.5 -10.5,-7 -4.5,-2.5 -10,-1.5 -5.5,1 -11.5,7 -5,5 -6,15 -1,10 -2,13 -7,-5 0,-17.5 7,-12.5 2,-18.5 -3,-6 -10.5,-4.5 -7.5,1.5 -12,4.5 -4.5,3 -11.5,8.5 -7,5.5 -9,6.5 -2,1 -8.5,5.5 -6.5,4.5 -8.5,7.5 -3,4 -6,12 -3,8 -5,11 -2,-4 -11.5,-6.5 -9.5,-2.5 -9.5,-5.5 2,10 4,35 2,25 5,38 7,31 -12,48 -27,25 -29,40 -4,22 12,26 0,7 -8,20.5 -8,13.5 -7,21.5 0,6 2,16 z"
+ id="path153" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/info_sign.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/info_sign.svg
new file mode 100644
index 000000000..517f76360
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/info_sign.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewBox="-10 0 1792 1792"
+ id="svg163"
+ sodipodi:docname="info_sign.svg"
+ width="1792"
+ height="1792"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs167" />
+ <sodipodi:namedview
+ id="namedview165"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="0.48716518"
+ inkscape:cx="72.870561"
+ inkscape:cy="896"
+ inkscape:window-width="1846"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg163" />
+ <path
+ fill="currentColor"
+ d="m 1142,1376 v -160 q 0,-14 -9,-23 -9,-9 -23,-9 h -96 V 672 q 0,-14 -9,-23 -9,-9 -23,-9 H 662 q -14,0 -23,9 -9,9 -9,23 v 160 q 0,14 9,23 9,9 23,9 h 96 v 320 h -96 q -14,0 -23,9 -9,9 -9,23 v 160 q 0,14 9,23 9,9 23,9 h 448 q 14,0 23,-9 9,-9 9,-23 z M 1014,480 V 320 q 0,-14 -9,-23 -9,-9 -23,-9 H 790 q -14,0 -23,9 -9,9 -9,23 v 160 q 0,14 9,23 9,9 23,9 h 192 q 14,0 23,-9 9,-9 9,-23 z m 640,416 q 0,209 -103,385.5 Q 1448,1458 1271.5,1561 1095,1664 886,1664 677,1664 500.5,1561 324,1458 221,1281.5 118,1105 118,896 118,687 221,510.5 324,334 500.5,231 677,128 886,128 1095,128 1271.5,231 1448,334 1551,510.5 1654,687 1654,896 Z"
+ id="path161" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/leaf.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/leaf.svg
new file mode 100644
index 000000000..c1cabb5cf
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/leaf.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="-10 0 1034 1024">
+ <path fill="currentColor"
+d="M765 327l-14 -11l-538 502l503 -533l-14 -12q-48 -26 -106 -23.5t-109 19.5q-14 4 -28.5 10t-28.5 13q-30 14 -57.5 32.5t-52.5 41.5q-55 52 -90.5 119t-52.5 140q-5 21 -9 42t-7 42q-3 26 -5.5 52.5t-4.5 53.5q-1 22 1.5 45.5t33.5 21.5h11.5h10.5q78 -2 156 -6t153 -29
+q49 -16 94 -42.5t82 -62.5q27 -27 50 -60t39 -69.5t24 -75.5t5 -78q-3 -35 -12.5 -70t-33.5 -62v0zM844 160l30 30l-563 531z" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/light_bulb.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/light_bulb.svg
new file mode 100644
index 000000000..ed2ed55fb
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/light_bulb.svg
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewBox="-10 0 1538 1538"
+ id="svg4"
+ sodipodi:docname="light_bulb.svg"
+ width="1538"
+ height="1538"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ id="namedview6"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ fit-margin-top="1"
+ fit-margin-left="1"
+ fit-margin-right="1"
+ fit-margin-bottom="1"
+ lock-margins="true"
+ inkscape:zoom="0.16"
+ inkscape:cx="1234.375"
+ inkscape:cy="409.375"
+ inkscape:window-width="1846"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4" />
+ <path
+ fill="currentColor"
+ d="m 983,449 q 0,13 -9.5,22.5 Q 964,481 951,481 938,481 928.5,471.5 919,462 919,449 919,403 865,378 811,353 759,353 746,353 736.5,343.5 727,334 727,321 q 0,-13 9.5,-22.5 9.5,-9.5 22.5,-9.5 50,0 99.5,16 49.5,16 87,54 37.5,38 37.5,90 z m 160,0 q 0,-72 -34.5,-134 -34.5,-62 -90,-101.5 Q 963,174 895.5,151.5 828,129 759,129 690,129 622.5,151.5 555,174 499.5,213.5 444,253 409.5,315 375,377 375,449 q 0,101 68,180 10,11 30.5,33 20.5,22 30.5,33 128,153 141,298 h 228 q 13,-145 141,-298 10,-11 30.5,-33 20.5,-22 30.5,-33 68,-79 68,-180 z m 128,0 q 0,155 -103,268 -45,49 -74.5,87 -29.5,38 -59.5,95.5 -30,57.5 -34,107.5 47,28 47,82 0,37 -25,64 25,27 25,64 0,52 -45,81 13,23 13,47 0,46 -31.5,71 -31.5,25 -77.5,25 -20,44 -60,70 -40,26 -87,26 -47,0 -87,-26 -40,-26 -60,-70 -46,0 -77.5,-25 -31.5,-25 -31.5,-71 0,-24 13,-47 -45,-29 -45,-81 0,-37 25,-64 -25,-27 -25,-64 0,-54 47,-82 Q 514,957 484,899.5 454,842 424.5,804 395,766 350,717 247,604 247,449 247,350 291.5,264.5 336,179 408.5,122.5 481,66 572.5,33.5 664,1 759,1 q 95,0 186.5,32.5 91.5,32.5 164,89 72.5,56.5 117,142 Q 1271,350 1271,449 Z"
+ id="path2" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/qt_logo.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/qt_logo.svg
new file mode 100644
index 000000000..062daff3e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/qt_logo.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ width="462pt"
+ height="339pt"
+ viewBox="0 0 462 339"
+ version="1.1"
+ id="svg2"
+>
+ <path
+ fill="#41cd52"
+ d=" M 63.50 0.00 L 462.00 0.00 L 462.00 274.79 C 440.60 296.26 419.13 317.66 397.61 339.00 L 0.00 339.00 L 0.00 63.39 C 21.08 42.18 42.34 21.13 63.50 0.00 Z"
+ id="path6"/>
+ <path
+ d=" M 122.37 71.33 C 137.50 61.32 156.21 58.79 174.00 58.95 C 190.94 59.16 208.72 62.13 222.76 72.24 C 232.96 79.41 239.59 90.48 244.01 101.93 C 251.16 120.73 253.26 141.03 253.50 161.01 C 253.53 181.13 252.62 201.69 245.96 220.86 C 241.50 233.90 233.01 245.48 221.81 253.52 C 229.87 266.58 238.09 279.54 246.15 292.60 C 236.02 297.27 225.92 301.97 215.78 306.62 C 207.15 292.38 198.56 278.11 189.90 263.89 C 178.19 265.81 166.21 265.66 154.44 264.36 C 140.34 262.67 125.97 258.37 115.09 248.88 C 106.73 241.64 101.48 231.51 97.89 221.21 C 92.01 203.79 90.43 185.25 90.16 166.97 C 90.02 147.21 91.28 127.14 97.24 108.18 C 101.85 93.92 109.48 79.69 122.37 71.33 Z"
+ id="path8"
+ fill="#ffffff"/>
+ <path
+ d=" M 294.13 70.69 C 304.73 70.68 315.33 70.68 325.93 70.69 C 325.96 84.71 325.92 98.72 325.95 112.74 C 339.50 112.76 353.05 112.74 366.60 112.75 C 366.37 121.85 366.12 130.95 365.86 140.05 C 352.32 140.08 338.79 140.04 325.25 140.07 C 325.28 163.05 325.18 186.03 325.30 209.01 C 325.56 215.30 325.42 221.94 328.19 227.75 C 330.21 232.23 335.65 233.38 340.08 233.53 C 348.43 233.50 356.77 233.01 365.12 232.86 C 365.63 241.22 366.12 249.59 366.60 257.95 C 349.99 260.74 332.56 264.08 316.06 258.86 C 309.11 256.80 302.63 252.19 299.81 245.32 C 294.76 233.63 294.35 220.62 294.13 208.07 C 294.11 185.40 294.13 162.74 294.12 140.07 C 286.73 140.05 279.34 140.08 271.95 140.05 C 271.93 130.96 271.93 121.86 271.95 112.76 C 279.34 112.73 286.72 112.77 294.11 112.74 C 294.14 98.72 294.10 84.71 294.13 70.69 Z"
+ id="path10"
+ fill="#ffffff"/>
+ <path
+ fill="#41cd52"
+ d=" M 160.51 87.70 C 170.80 86.36 181.60 86.72 191.34 90.61 C 199.23 93.73 205.93 99.84 209.47 107.58 C 214.90 119.31 216.98 132.26 218.03 145.05 C 219.17 162.07 219.01 179.25 216.66 196.17 C 215.01 206.24 212.66 216.85 205.84 224.79 C 198.92 232.76 188.25 236.18 178.01 236.98 C 167.21 237.77 155.82 236.98 146.07 231.87 C 140.38 228.84 135.55 224.09 132.73 218.27 C 129.31 211.30 127.43 203.69 126.11 196.07 C 122.13 171.91 121.17 146.91 126.61 122.89 C 128.85 113.83 132.11 104.53 138.73 97.70 C 144.49 91.85 152.51 88.83 160.51 87.70 Z"
+ id="path12"/>
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/read.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/read.svg
new file mode 100644
index 000000000..c3af473d2
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/read.svg
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ viewBox="-11 0 1792 1792"
+ id="svg184"
+ sodipodi:docname="read.svg"
+ width="1792"
+ height="1792"
+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs188" />
+ <sodipodi:namedview
+ id="namedview186"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="0.24358259"
+ inkscape:cx="519.33104"
+ inkscape:cy="1089.9794"
+ inkscape:window-width="1846"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg184" />
+ <path
+ fill="currentColor"
+ d="m 1691.8576,478 q 40,57 18,129 l -275,906 q -19,64 -76.5,107.5 -57.5,43.5 -122.5,43.5 H 312.85764 q -77,0 -148.5,-53.5 Q 92.857644,1557 64.857644,1479 q -24,-67 -2,-127 0,-4 3,-27 3,-23 4,-37 1,-8 -3,-21.5 -4,-13.5 -3,-19.5 2,-11 8,-21 6,-10 16.5,-23.5 10.5,-13.5 16.499996,-23.5 23,-38 45,-91.5 22,-53.5 30,-91.5 3,-10 0.5,-30 -2.5,-20 -0.5,-28 3,-11 17,-28 14,-17 17,-23 21,-36 42,-92 21,-56 25,-90 1,-9 -2.5,-32 -3.5,-23 0.5,-28 4,-13 22,-30.5 18,-17.5 22,-22.5 19,-26 42.5,-84.5 23.5,-58.5 27.5,-96.5 1,-8 -3,-25.5 -4,-17.5 -2,-26.5 2,-8 9,-18 7,-10 18,-23 11,-13 17,-21 8,-12 16.5,-30.5 8.5,-18.5 15,-35 6.5,-16.5 16,-36 9.5,-19.5 19.5,-32 10,-12.5 26.5,-23.5 16.5,-11 36,-11.5 19.5,-0.5 47.5,5.5 l -1,3 q 38,-9 51,-9 h 760.99996 q 74,0 114,56 40,56 18,130 l -274,906 q -36,119 -71.5,153.5 -35.5,34.5 -128.5,34.5 H 208.85764 q -27,0 -38,15 -11,16 -1,43 24,70 144,70 h 922.99996 q 29,0 56,-15.5 27,-15.5 35,-41.5 l 300,-987 q 7,-22 5,-57 38,15 59,43 z m -1063.99996,2 q -4,13 2,22.5 6,9.5 20,9.5 h 607.99996 q 13,0 25.5,-9.5 12.5,-9.5 16.5,-22.5 l 21,-64 q 4,-13 -2,-22.5 -6,-9.5 -20,-9.5 H 690.85764 q -13,0 -25.5,9.5 -12.5,9.5 -16.5,22.5 z m -83,256 q -4,13 2,22.5 6,9.5 20,9.5 h 607.99996 q 13,0 25.5,-9.5 12.5,-9.5 16.5,-22.5 l 21,-64 q 4,-13 -2,-22.5 -6,-9.5 -20,-9.5 H 607.85764 q -13,0 -25.5,9.5 -12.5,9.5 -16.5,22.5 z"
+ id="path182" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/resize.svg b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/resize.svg
new file mode 100644
index 000000000..e86d612f3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/icons/resize.svg
@@ -0,0 +1,6 @@
+<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'>
+ <line x1="00" y1="100" x2="100" y2="00" stroke="black" stroke-width="3" />
+ <line x1="20" y1="100" x2="100" y2="20" stroke="black" stroke-width="3" />
+ <line x1="40" y1="100" x2="100" y2="40" stroke="black" stroke-width="3" />
+ <line x1="60" y1="100" x2="100" y2="60" stroke="black" stroke-width="3" />
+</svg>
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/About.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/About.qml
new file mode 100644
index 000000000..178bf03e4
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/About.qml
@@ -0,0 +1,93 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Basic
+import FileSystemModule
+
+ApplicationWindow {
+ id: root
+ width: 650
+ height: 550
+ flags: Qt.Window | Qt.FramelessWindowHint
+ color: Colors.surface1
+
+ menuBar: MyMenuBar {
+ id: menuBar
+
+ dragWindow: root
+ implicitHeight: 27
+ infoText: "About Qt"
+ }
+
+ Image {
+ id: logo
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.margins: 20
+
+ source: "../icons/qt_logo.svg"
+ sourceSize.width: 80
+ sourceSize.height: 80
+ fillMode: Image.PreserveAspectFit
+
+ smooth: true
+ antialiasing: true
+ asynchronous: true
+ }
+
+ ScrollView {
+ anchors.top: logo.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.margins: 20
+
+ TextArea {
+ selectedTextColor: Colors.textFile
+ selectionColor: Colors.selection
+ horizontalAlignment: Text.AlignHCenter
+ textFormat: Text.RichText
+
+ text: qsTr("<h3>About Qt</h3>"
+ + "<p>This program uses Qt version %1.</p>"
+ + "<p>Qt is a C++ toolkit for cross-platform application "
+ + "development.</p>"
+ + "<p>Qt provides single-source portability across all major desktop "
+ + "operating systems. It is also available for embedded Linux and other "
+ + "embedded and mobile operating systems.</p>"
+ + "<p>Qt is available under multiple licensing options designed "
+ + "to accommodate the needs of our various users.</p>"
+ + "<p>Qt licensed under our commercial license agreement is appropriate "
+ + "for development of proprietary/commercial software where you do not "
+ + "want to share any source code with third parties or otherwise cannot "
+ + "comply with the terms of GNU (L)GPL.</p>"
+ + "<p>Qt licensed under GNU (L)GPL is appropriate for the "
+ + "development of Qt&nbsp;applications provided you can comply with the terms "
+ + "and conditions of the respective licenses.</p>"
+ + "<p>Please see <a href=\"http://%2/\">%2</a> "
+ + "for an overview of Qt licensing.</p>"
+ + "<p>Copyright (C) %3 The Qt Company Ltd and other "
+ + "contributors.</p>"
+ + "<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>"
+ + "<p>Qt is The Qt Company Ltd product developed as an open source "
+ + "project. See <a href=\"http://%4/\">%4</a> for more information.</p>")
+ .arg(Application.version).arg("qt.io/licensing").arg("2023").arg("qt.io")
+ color: Colors.textFile
+ wrapMode: Text.WordWrap
+ readOnly: true
+ antialiasing: true
+ background: null
+
+ onLinkActivated: function(link) {
+ Qt.openUrlExternally(link)
+ }
+ }
+ }
+
+ ResizeButton {
+ resizeWindow: root
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ColorScheme.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ColorScheme.qml
new file mode 100644
index 000000000..19c8cd905
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ColorScheme.qml
@@ -0,0 +1,118 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import FileSystemModule
+
+ColumnLayout {
+ id: colorScheme
+
+ spacing: 20
+
+ // Inline component that customizes TabButton
+ component MyTabButton: TabButton {
+ id: root
+
+ implicitWidth: 150
+ implicitHeight: 30
+ padding: 6
+ spacing: 6
+
+ contentItem: Text {
+ anchors.centerIn: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ text: root.text
+ font.bold: true
+ color: Colors.text
+ }
+
+ background: Rectangle {
+ anchors.fill: parent
+ implicitHeight: 40
+
+ color: root.checked ? Colors.active : Colors.selection
+ Rectangle {
+ height: 4
+ width: parent.width
+ color: root.checked ? Colors.color1 : Colors.selection
+ }
+ }
+ }
+
+ Item {
+ // Spacer item
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ Text {
+ Layout.alignment: Qt.AlignHCenter
+
+ text: "Select a Scheme!"
+ font.pointSize: 30
+ font.bold: true
+ color: Colors.text
+ }
+
+ // Display all the color-scheme names. The model is a string-list provided
+ // by our python class.
+ TabBar {
+ id: schemeSelector
+
+ Layout.alignment: Qt.AlignHCenter
+
+ background: Rectangle {
+ color: Colors.surface1
+ }
+
+ Repeater {
+ model: Colors.getKeys()
+ MyTabButton {
+ text: modelData
+ onClicked: {
+ Colors.setScheme(modelData)
+ themePreviewContainer.background
+ = (modelData === "Solarized") ? "#777777" : "#FEFAEC"
+ }
+ }
+ }
+ }
+
+ // The current colors can be visualized using the same method as above.
+ Rectangle {
+ id: themePreviewContainer
+
+ property color background: "#FEFAEC"
+
+ Layout.alignment: Qt.AlignHCenter
+
+ width: 700
+ height: 50
+ radius: 10
+ color: background
+
+ // Display all used colors inside a row
+ Row {
+ anchors.centerIn: parent
+ spacing: 10
+
+ Repeater {
+ model: Colors.currentColors
+ Rectangle {
+ width: 35
+ height: width
+ radius: width / 2
+ color: modelData
+ }
+ }
+ }
+ }
+ Item {
+ // Spacer item
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Editor.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Editor.qml
new file mode 100644
index 000000000..80f7c04c5
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Editor.qml
@@ -0,0 +1,160 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import FileSystemModule
+
+pragma ComponentBehavior: Bound
+
+// This is the text editor that displays the currently open file, including
+// their corresponding line numbers.
+Rectangle {
+ id: root
+
+ required property string currentFilePath
+ required property bool showLineNumbers
+ property alias text: textArea
+ property int currentLineNumber: -1
+ property int rowHeight: Math.ceil(fontMetrics.lineSpacing)
+
+ color: Colors.background
+
+ onWidthChanged: textArea.update()
+ onHeightChanged: textArea.update()
+
+ RowLayout {
+ anchors.fill: parent
+ // We use a flickable to synchronize the position of the editor and
+ // the line numbers. This is necessary because the line numbers can
+ // extend the available height.
+ Flickable {
+ id: lineNumbers
+
+ // Calculate the width based on the logarithmic scale.
+ Layout.preferredWidth: fontMetrics.averageCharacterWidth
+ * (Math.floor(Math.log10(textArea.lineCount)) + 1) + 10
+ Layout.fillHeight: true
+
+ interactive: false
+ contentY: editorFlickable.contentY
+ visible: textArea.text !== "" && root.showLineNumbers
+
+ Column {
+ anchors.fill: parent
+ Repeater {
+ id: repeatedLineNumbers
+
+ model: LineNumberModel {
+ lineCount: textArea.text !== "" ? textArea.lineCount : 0
+ }
+
+ delegate: Item {
+ required property int index
+
+ width: parent.width
+ height: root.rowHeight
+ Label {
+ id: numbers
+
+ text: parent.index + 1
+
+ width: parent.width
+ height: parent.height
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+
+ color: (root.currentLineNumber === parent.index)
+ ? Colors.iconIndicator : Qt.darker(Colors.text, 2)
+ font: textArea.font
+ }
+ Rectangle {
+ id: indicator
+
+ anchors.left: numbers.right
+ width: 1
+ height: parent.height
+ color: Qt.darker(Colors.text, 3)
+ }
+ }
+ }
+ }
+ }
+
+ Flickable {
+ id: editorFlickable
+
+ property alias textArea: textArea
+
+ // We use an inline component to customize the horizontal and vertical
+ // scroll-bars. This is convenient when the component is only used in one file.
+ component MyScrollBar: ScrollBar {
+ id: scrollBar
+ background: Rectangle {
+ implicitWidth: scrollBar.interactive ? 8 : 4
+ implicitHeight: scrollBar.interactive ? 8 : 4
+
+ opacity: scrollBar.active && scrollBar.size < 1.0 ? 1.0 : 0.0
+ color: Colors.background
+ Behavior on opacity {
+ OpacityAnimator {
+ duration: 500
+ }
+ }
+ }
+ contentItem: Rectangle {
+ implicitWidth: scrollBar.interactive ? 8 : 4
+ implicitHeight: scrollBar.interactive ? 8 : 4
+ opacity: scrollBar.active && scrollBar.size < 1.0 ? 1.0 : 0.0
+ color: Colors.color1
+ Behavior on opacity {
+ OpacityAnimator {
+ duration: 1000
+ }
+ }
+ }
+ }
+
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ ScrollBar.horizontal: MyScrollBar {}
+ ScrollBar.vertical: MyScrollBar {}
+
+ boundsBehavior: Flickable.StopAtBounds
+
+ TextArea.flickable: TextArea {
+ id: textArea
+ anchors.fill: parent
+
+ focus: false
+ topPadding: 0
+ leftPadding: 10
+
+ text: FileSystemModel.readFile(root.currentFilePath)
+ tabStopDistance: fontMetrics.averageCharacterWidth * 4
+
+ // Grab the current line number from the C++ interface.
+ onCursorPositionChanged: {
+ root.currentLineNumber = FileSystemModel.currentLineNumber(
+ textArea.textDocument, textArea.cursorPosition)
+ }
+
+ color: Colors.textFile
+ selectedTextColor: Colors.textFile
+ selectionColor: Colors.selection
+
+ textFormat: TextEdit.PlainText
+ renderType: Text.QtRendering
+ selectByMouse: true
+ antialiasing: true
+ background: null
+ }
+
+ FontMetrics {
+ id: fontMetrics
+ font: textArea.font
+ }
+ }
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/FileSystemView.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/FileSystemView.qml
new file mode 100644
index 000000000..db955168c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/FileSystemView.qml
@@ -0,0 +1,156 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Effects
+import QtQuick.Controls.Basic
+import FileSystemModule
+
+pragma ComponentBehavior: Bound
+
+// This is the file system view which gets populated by the C++ model.
+Rectangle {
+ id: root
+
+ signal fileClicked(string filePath)
+ property alias rootIndex: fileSystemTreeView.rootIndex
+
+ TreeView {
+ id: fileSystemTreeView
+
+ property int lastIndex: -1
+
+ anchors.fill: parent
+ model: FileSystemModel
+ rootIndex: FileSystemModel.rootIndex
+ boundsBehavior: Flickable.StopAtBounds
+ boundsMovement: Flickable.StopAtBounds
+ clip: true
+
+ Component.onCompleted: fileSystemTreeView.toggleExpanded(0)
+
+ // The delegate represents a single entry in the filesystem.
+ delegate: TreeViewDelegate {
+ id: treeDelegate
+ indentation: 8
+ implicitWidth: fileSystemTreeView.width > 0 ? fileSystemTreeView.width : 250
+ implicitHeight: 25
+
+ // Since we have the 'ComponentBehavior Bound' pragma, we need to
+ // require these properties from our model. This is a convenient way
+ // to bind the properties provided by the model's role names.
+ required property int index
+ required property url filePath
+ required property string fileName
+
+ indicator: Image {
+ id: directoryIcon
+
+ x: treeDelegate.leftMargin + (treeDelegate.depth * treeDelegate.indentation)
+ anchors.verticalCenter: parent.verticalCenter
+ source: treeDelegate.hasChildren ? (treeDelegate.expanded
+ ? "../icons/folder_open.svg" : "../icons/folder_closed.svg")
+ : "../icons/generic_file.svg"
+ sourceSize.width: 20
+ sourceSize.height: 20
+ fillMode: Image.PreserveAspectFit
+
+ smooth: true
+ antialiasing: true
+ asynchronous: true
+ }
+
+ contentItem: Text {
+ text: treeDelegate.fileName
+ color: Colors.text
+ }
+
+ background: Rectangle {
+ color: (treeDelegate.index === fileSystemTreeView.lastIndex)
+ ? Colors.selection
+ : (hoverHandler.hovered ? Colors.active : "transparent")
+ }
+
+ // We color the directory icons with this MultiEffect, where we overlay
+ // the colorization color ontop of the SVG icons.
+ MultiEffect {
+ id: iconOverlay
+
+ anchors.fill: directoryIcon
+ source: directoryIcon
+ colorization: 1.0
+ brightness: 1.0
+ colorizationColor: {
+ const isFile = treeDelegate.index === fileSystemTreeView.lastIndex
+ && !treeDelegate.hasChildren;
+ if (isFile)
+ return Qt.lighter(Colors.folder, 3)
+
+ const isExpandedFolder = treeDelegate.expanded && treeDelegate.hasChildren;
+ if (isExpandedFolder)
+ return Colors.color2
+ else
+ return Colors.folder
+ }
+ }
+
+ HoverHandler {
+ id: hoverHandler
+ }
+
+ TapHandler {
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onSingleTapped: (eventPoint, button) => {
+ switch (button) {
+ case Qt.LeftButton:
+ fileSystemTreeView.toggleExpanded(treeDelegate.row)
+ fileSystemTreeView.lastIndex = treeDelegate.index
+ // If this model item doesn't have children, it means it's
+ // representing a file.
+ if (!treeDelegate.hasChildren)
+ root.fileClicked(treeDelegate.filePath)
+ break;
+ case Qt.RightButton:
+ if (treeDelegate.hasChildren)
+ contextMenu.popup();
+ break;
+ }
+ }
+ }
+
+ MyMenu {
+ id: contextMenu
+ Action {
+ text: qsTr("Set as root index")
+ onTriggered: {
+ fileSystemTreeView.rootIndex = fileSystemTreeView.index(treeDelegate.row, 0)
+ }
+ }
+ Action {
+ text: qsTr("Reset root index")
+ onTriggered: fileSystemTreeView.rootIndex = undefined
+ }
+ }
+ }
+
+ // Provide our own custom ScrollIndicator for the TreeView.
+ ScrollIndicator.vertical: ScrollIndicator {
+ active: true
+ implicitWidth: 15
+
+ contentItem: Rectangle {
+ implicitWidth: 6
+ implicitHeight: 6
+
+ color: Colors.color1
+ opacity: fileSystemTreeView.movingVertically ? 0.5 : 0.0
+
+ Behavior on opacity {
+ OpacityAnimator {
+ duration: 500
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenu.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenu.qml
new file mode 100644
index 000000000..1f1d30c56
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenu.qml
@@ -0,0 +1,45 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Basic
+import FileSystemModule
+
+Menu {
+ id: root
+
+ delegate: MenuItem {
+ id: menuItem
+ contentItem: Item {
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+
+ text: menuItem.text
+ color: enabled ? Colors.text : Colors.disabledText
+ }
+ Rectangle {
+ id: indicator
+
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ width: 6
+ height: parent.height
+
+ visible: menuItem.highlighted
+ color: Colors.color2
+ }
+ }
+ background: Rectangle {
+ implicitWidth: 210
+ implicitHeight: 35
+ color: menuItem.highlighted ? Colors.active : "transparent"
+ }
+ }
+ background: Rectangle {
+ implicitWidth: 210
+ implicitHeight: 35
+ color: Colors.surface2
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenuBar.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenuBar.qml
new file mode 100644
index 000000000..4874a2c03
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/MyMenuBar.qml
@@ -0,0 +1,177 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls.Basic
+import FileSystemModule
+
+// The MenuBar also serves as a controller for our window as we don't use any decorations.
+MenuBar {
+ id: root
+
+ required property ApplicationWindow dragWindow
+ property alias infoText: windowInfo.text
+
+ // Customization of the top level menus inside the MenuBar
+ delegate: MenuBarItem {
+ id: menuBarItem
+
+ contentItem: Text {
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+
+ text: menuBarItem.text
+ font: menuBarItem.font
+ elide: Text.ElideRight
+ color: menuBarItem.highlighted ? Colors.textFile : Colors.text
+ opacity: enabled ? 1.0 : 0.3
+ }
+
+ background: Rectangle {
+ id: background
+
+ color: menuBarItem.highlighted ? Colors.selection : "transparent"
+ Rectangle {
+ id: indicator
+
+ width: 0; height: 3
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+
+ color: Colors.color1
+ states: State {
+ name: "active"
+ when: menuBarItem.highlighted
+ PropertyChanges {
+ indicator.width: background.width - 2
+ }
+ }
+ transitions: Transition {
+ NumberAnimation {
+ properties: "width"
+ duration: 175
+ }
+ }
+ }
+ }
+ }
+ // We use the contentItem property as a place to attach our window decorations. Beneath
+ // the usual menu entries within a MenuBar, it includes a centered information text, along
+ // with the minimize, maximize, and close buttons.
+ contentItem: RowLayout {
+ id: windowBar
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ spacing: root.spacing
+ Repeater {
+ id: menuBarItems
+
+ Layout.alignment: Qt.AlignLeft
+ model: root.contentModel
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Text {
+ id: windowInfo
+
+ width: parent.width; height: parent.height
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ leftPadding: windowActions.width
+ color: Colors.text
+ clip: true
+ }
+ }
+
+ RowLayout {
+ id: windowActions
+
+ Layout.alignment: Qt.AlignRight
+ Layout.fillHeight: true
+
+ spacing: 0
+
+ component InteractionButton: Rectangle {
+ id: interactionButton
+
+ signal action()
+ property alias hovered: hoverHandler.hovered
+
+ Layout.fillHeight: true
+ Layout.preferredWidth: height
+
+ color: hovered ? Colors.background : "transparent"
+ HoverHandler {
+ id: hoverHandler
+ }
+ TapHandler {
+ id: tapHandler
+ onTapped: interactionButton.action()
+ }
+ }
+
+ InteractionButton {
+ id: minimize
+
+ onAction: root.dragWindow.showMinimized()
+ Rectangle {
+ anchors.centerIn: parent
+ color: parent.hovered ? Colors.iconIndicator : Colors.icon
+ height: 2
+ width: parent.height - 14
+ }
+ }
+
+ InteractionButton {
+ id: maximize
+
+ onAction: root.dragWindow.showMaximized()
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: 7
+ border.color: parent.hovered ? Colors.iconIndicator : Colors.icon
+ border.width: 2
+ color: "transparent"
+ }
+ }
+
+ InteractionButton {
+ id: close
+
+ color: hovered ? "#ec4143" : "transparent"
+ onAction: root.dragWindow.close()
+ Rectangle {
+ anchors.centerIn: parent
+ width: parent.height - 8; height: 2
+
+ rotation: 45
+ antialiasing: true
+ transformOrigin: Item.Center
+ color: parent.hovered ? Colors.iconIndicator : Colors.icon
+
+ Rectangle {
+ anchors.centerIn: parent
+ width: parent.height
+ height: parent.width
+
+ antialiasing: true
+ color: parent.color
+ }
+ }
+ }
+ }
+ }
+
+ background: Rectangle {
+ color: Colors.surface2
+ // Make the empty space drag the specified root window.
+ WindowDragHandler {
+ dragWindow: root.dragWindow
+ }
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ResizeButton.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ResizeButton.qml
new file mode 100644
index 000000000..0df65bf82
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/ResizeButton.qml
@@ -0,0 +1,23 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick.Controls
+import FileSystemModule
+
+Button {
+ required property ApplicationWindow resizeWindow
+
+ icon.width: 20; icon.height: 20
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ rightPadding: 3
+ bottomPadding: 3
+
+ icon.source: "../icons/resize.svg"
+ icon.color: hovered ? Colors.iconIndicator : Colors.icon
+
+ background: null
+ checkable: false
+ display: AbstractButton.IconOnly
+ onPressed: resizeWindow.startSystemResize(Qt.BottomEdge | Qt.RightEdge)
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Sidebar.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Sidebar.qml
new file mode 100644
index 000000000..04880a55d
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/Sidebar.qml
@@ -0,0 +1,146 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls.Basic
+import FileSystemModule
+
+Rectangle {
+ id: root
+
+ property alias currentTabIndex: topBar.currentIndex
+ required property ApplicationWindow dragWindow
+ readonly property int tabBarSpacing: 10
+
+ color: Colors.surface2
+
+ component SidebarEntry: Button {
+ id: sidebarButton
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+
+ icon.color: down || checked ? Colors.iconIndicator : Colors.icon
+ icon.width: 27
+ icon.height: 27
+
+ topPadding: 0
+ rightPadding: 0
+ bottomPadding: 0
+ leftPadding: 0
+ background: null
+
+ Rectangle {
+ id: indicator
+
+ anchors.verticalCenter: parent.verticalCenter
+ x: 2
+ width: 4
+ height: sidebarButton.icon.height * 1.2
+
+ visible: sidebarButton.checked
+ color: Colors.color1
+ }
+ }
+
+ // TabBar is designed to be horizontal, whereas we need a vertical bar.
+ // We can easily achieve that by using a Container.
+ component TabBar: Container {
+ id: tabBarComponent
+
+ Layout.fillWidth: true
+ // ButtonGroup ensures that only one button can be checked at a time.
+ ButtonGroup {
+ buttons: tabBarComponent.contentChildren
+
+ // We have to manage the currentIndex ourselves, which we do by setting it to the index
+ // of the currently checked button. We use setCurrentIndex instead of setting the
+ // currentIndex property to avoid breaking bindings. See "Managing the Current Index"
+ // in Container's documentation for more information.
+ onCheckedButtonChanged: tabBarComponent.setCurrentIndex(
+ Math.max(0, buttons.indexOf(checkedButton)))
+ }
+
+ contentItem: ColumnLayout {
+ spacing: tabBarComponent.spacing
+ Repeater {
+ model: tabBarComponent.contentModel
+ }
+ }
+ }
+
+ ColumnLayout {
+ anchors.fill: root
+ anchors.topMargin: root.tabBarSpacing
+ anchors.bottomMargin: root.tabBarSpacing
+
+ spacing: root.tabBarSpacing
+ TabBar {
+ id: topBar
+
+ spacing: root.tabBarSpacing
+ // Shows help text when clicked.
+ SidebarEntry {
+ id: infoTab
+ icon.source: "../icons/light_bulb.svg"
+ checkable: true
+ checked: true
+ }
+
+ // Shows the file system when clicked.
+ SidebarEntry {
+ id: filesystemTab
+
+ icon.source: "../icons/read.svg"
+ checkable: true
+ }
+
+ // Shows the scheme switcher
+ SidebarEntry {
+ icon.source: "../icons/leaf.svg"
+ checkable: true
+
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+
+ // This item acts as a spacer to expand between the checkable and non-checkable buttons.
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ // Make the empty space drag our main window.
+ WindowDragHandler {
+ dragWindow: root.dragWindow
+ }
+ }
+
+ TabBar {
+ id: bottomBar
+
+ spacing: root.tabBarSpacing
+ // Opens the Qt website in the system's web browser.
+ SidebarEntry {
+ id: qtWebsiteButton
+ icon.source: "../icons/globe.svg"
+ checkable: false
+ onClicked: Qt.openUrlExternally("https://www.qt.io/")
+ }
+
+ // Opens the About Qt Window.
+ SidebarEntry {
+ id: aboutQtButton
+
+ icon.source: "../icons/info_sign.svg"
+ checkable: false
+ onClicked: aboutQtWindow.visible = !aboutQtWindow.visible
+ }
+ }
+ }
+
+ About {
+ id: aboutQtWindow
+ visible: false
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/WindowDragHandler.qml b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/WindowDragHandler.qml
new file mode 100644
index 000000000..0e140aca3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qml/WindowDragHandler.qml
@@ -0,0 +1,16 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+
+// Allows dragging the window when placed on an unused section of the UI.
+DragHandler {
+
+ required property ApplicationWindow dragWindow
+
+ target: null
+ onActiveChanged: {
+ if (active) dragWindow.startSystemMove()
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qmldir b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qmldir
new file mode 100644
index 000000000..e9c99b07b
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/FileSystemModule/qmldir
@@ -0,0 +1,11 @@
+module FileSystemModule
+Main 1.0 Main.qml
+About 1.0 qml/About.qml
+Editor 1.0 qml/Editor.qml
+MyMenu 1.0 qml/MyMenu.qml
+Sidebar 1.0 qml/Sidebar.qml
+MyMenuBar 1.0 qml/MyMenuBar.qml
+ColorScheme 1.0 qml/ColorScheme.qml
+ResizeButton 1.0 qml/ResizeButton.qml
+FileSystemView 1.0 qml/FileSystemView.qml
+WindowDragHandler 1.0 qml/WindowDragHandler.qml
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/editormodels.py b/sources/pyside6/doc/tutorials/extendedexplorer/editormodels.py
new file mode 100644
index 000000000..688147726
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/editormodels.py
@@ -0,0 +1,116 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtWidgets import QFileSystemModel
+from PySide6.QtQuick import QQuickTextDocument
+from PySide6.QtQml import QmlElement, QmlSingleton
+from PySide6.QtCore import (Qt, QDir, QAbstractListModel, Slot, QFile, QTextStream,
+ QMimeDatabase, QFileInfo, QStandardPaths, QModelIndex,
+ Signal, Property)
+
+QML_IMPORT_NAME = "FileSystemModule"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+@QmlSingleton
+class FileSystemModel(QFileSystemModel):
+
+ rootIndexChanged = Signal()
+
+ def getDefaultRootDir():
+ return QStandardPaths.writableLocation(QStandardPaths.StandardLocation.HomeLocation)
+
+ def __init__(self, parent=None):
+ super().__init__(parent=parent)
+ self.mRootIndex = QModelIndex()
+ self.mDb = QMimeDatabase()
+ self.setFilter(QDir.Filter.AllEntries | QDir.Filter.Hidden | QDir.Filter.NoDotAndDotDot)
+ self.setInitialDirectory()
+
+ # check for the correct mime type and then read the file.
+ # returns the text file's content or an error message on failure
+ @Slot(str, result=str)
+ def readFile(self, path):
+ if path == "":
+ return ""
+
+ file = QFile(path)
+
+ mime = self.mDb.mimeTypeForFile(QFileInfo(file))
+ if ('text' in mime.comment().lower()
+ or any('text' in s.lower() for s in mime.parentMimeTypes())):
+ if file.open(QFile.OpenModeFlag.ReadOnly | QFile.OpenModeFlag.Text):
+ stream = QTextStream(file).readAll()
+ file.close()
+ return stream
+ else:
+ return self.tr("Error opening the file!")
+ return self.tr("File type not supported!")
+
+ @Slot(QQuickTextDocument, int, result=int)
+ def currentLineNumber(self, textDocument, cursorPosition):
+ td = textDocument.textDocument()
+ tb = td.findBlock(cursorPosition)
+ return tb.blockNumber()
+
+ def setInitialDirectory(self, path=getDefaultRootDir()):
+ dir = QDir(path)
+ if dir.makeAbsolute():
+ self.setRootPath(dir.path())
+ else:
+ self.setRootPath(self.getDefaultRootDir())
+ self.setRootIndex(self.index(dir.path()))
+
+ # we only need one column in this example
+ def columnCount(self, parent):
+ return 1
+
+ @Property(QModelIndex, notify=rootIndexChanged)
+ def rootIndex(self):
+ return self.mRootIndex
+
+ def setRootIndex(self, index):
+ if (index == self.mRootIndex):
+ return
+ self.mRootIndex = index
+ self.rootIndexChanged.emit()
+
+
+@QmlElement
+class LineNumberModel(QAbstractListModel):
+
+ lineCountChanged = Signal()
+
+ def __init__(self, parent=None):
+ self.mLineCount = 0
+ super().__init__(parent=parent)
+
+ @Property(int, notify=lineCountChanged)
+ def lineCount(self):
+ return self.mLineCount
+
+ @lineCount.setter
+ def lineCount(self, n):
+ if n < 0:
+ print("lineCount must be greater then zero")
+ return
+ if self.mLineCount == n:
+ return
+
+ if self.mLineCount < n:
+ self.beginInsertRows(QModelIndex(), self.mLineCount, n - 1)
+ self.mLineCount = n
+ self.endInsertRows()
+ else:
+ self.beginRemoveRows(QModelIndex(), n, self.mLineCount - 1)
+ self.mLineCount = n
+ self.endRemoveRows()
+
+ def rowCount(self, parent):
+ return self.mLineCount
+
+ def data(self, index, role):
+ if not self.checkIndex(index) or role != Qt.ItemDataRole.DisplayRole:
+ return
+ return index.row()
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md b/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md
new file mode 100644
index 000000000..0ac7bec18
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md
@@ -0,0 +1,210 @@
+# Extending the file system explorer example
+
+This tutorial shows how to extend the
+[Filesystem Explorer Example](filesystemexplorer_example)
+by adding a simple scheme manager. This feature will allow you to switch color
+schemes during the application's runtime. The color schemes will be declared in
+JSON format and made available through a custom Python-QML plugin.
+
+![Extended Explorer GIF](resources/extendedexplorer.gif)
+
+## Defining the color schemes
+
+To define your color scheme, you can use the same color names as the original
+example, so you don't have to rename every occurrence. The original colors are
+defined in the `Colors.qml` file as follows:
+
+```{literalinclude} resources/Colors.qml
+---
+language: QML
+caption: true
+linenos: true
+lines: 7-22
+---
+```
+
+The `schemes.json` file holds the color schemes. To start implementing this, you
+can use the [Catppuccin](https://github.com/catppuccin/catppuccin) scheme.
+
+```{literalinclude} schemes.json
+---json
+caption: true
+linenos: true
+start-at: "Catppuccin"
+end-at: "},"
+---
+```
+
+In addition to the "Catppuccin" color scheme, four other color schemes got
+implemented: Nordic, One Dark, Gruvbox, and Solarized. However, feel free to get
+creative and experiment with **your** schemes.
+
+To define a new color scheme, copy the structure from above and provide your
+color values
+
+## Implement the scheme manager
+
+After defining the color schemes, you can implement the actual scheme manager.
+The manager will read the `schemes.json` file and provide QML bindings to switch
+between schemes during runtime.
+
+To implement the scheme manager, create a Python-QML plugin that exposes the
+`SchemeManager` object to QML. This object will have methods to load the color
+schemes from the `schemes.json` file and switch between them.
+
+Create a new Python file called `schememanager.py` in your project directory. In
+this file, define the **SchemeManager** class:
+
+```{literalinclude} scheme_manager.py
+---
+language: python
+caption: true
+linenos: true
+start-at: "QML_IMPORT_NAME"
+end-at: "class SchemeManager"
+---
+```
+
+To integrate smoothly into the already existing code, attach the SchemeManager
+to the same QML module that's already present with
+`QML_IMPORT_NAME = "FileSystemModule"`. Additionally, use the`@QmlNamedElement`
+decorator to smoothly transition to using the custom plugin instead of the
+`Colors.qml` file. With these changes, we can avoid editing all previous
+assignments like:
+
+```QML
+import FileSystemModule
+...
+Rectangle {
+ color: Colors.background
+}
+```
+
+The constructor reads the `schemes.json` file once upon application start and
+then calls the `setTheme` member function.
+
+```{literalinclude} scheme_manager.py
+---
+language: python
+caption: true
+linenos: true
+lines: 18-24
+---
+```
+
+By adding the `SchemeManager` as a callable QML element named **Colors** to the
+FileSystemModule, the class is now accessible in the code without the need to
+import it each time or edit previous assignments. This, in turn, will streamline
+the workflow.
+
+After defining the schemes in the JSON format and making the `SchemeManager`
+class a callable element from QML under the name **Colors**, there are two
+remaining steps to fully integrate the new scheme manager in the example.
+
+The **first step** is to create a function in the `SchemeManager` class that
+loads a color scheme from the JSON file. The **second step** is to make the
+individual colors available in QML with the *same name* as used before with the
+syntax `Colors.<previousName>` as assignable properties.
+
+
+```{literalinclude} scheme_manager.py
+---
+language: python
+caption: true
+linenos: true
+lines: 26-31
+---
+```
+
+The `setScheme` method is responsible for switching between color schemes. To
+make this method accessible in QML, use the `@Slot(str)` decorator and specify
+that it takes a string as its input parameter. In this method, we populate a
+dictionary with the color values from the JSON file.
+
+> Note: For simplicity reasons no other error checking is performed.
+> You would probably want to validate the keys contained in the json.
+
+```{literalinclude} scheme_manager.py
+---
+language: python
+caption: true
+linenos: true
+start-at: "@Property(QColor"
+end-at: "return"
+---
+```
+
+To make the color property assignable in QML, use the `@Property` decorator.
+We simply return the corresponding color value from the dictionary for each
+property. This process is repeated for all other colors that are used in the
+application.
+At this point the application should start with the colors provided by the
+active scheme in the constructor.
+
+## Add the scheme switching to QML
+
+To visualize the current scheme and enable interactive scheme switching, start
+by adding a new entry to the `Sidebar.qml` file.
+
+```{literalinclude} FileSystemModule/qml/Sidebar.qml
+---
+language: QML
+caption: true
+linenos: true
+lines: 99-105
+---
+```
+
+To update the main content area of the application to display the `ColorScheme`,
+the logic that checks the active index from the Sidebar buttons needs to be
+modified. The necessary changes will be made to the Main.qml file:
+
+```{literalinclude} FileSystemModule/Main.qml
+---
+language: QML
+caption: true
+linenos: true
+lines: 170-187
+---
+```
+
+In addition, change the behavior of the application so that there are two
+`StackLayouts`: one for the resizable navigation and one for the main content
+area where we display our color scheme switching functionality. These changes
+will also be made to the Main.qml file.
+
+```{literalinclude} FileSystemModule/Main.qml
+---
+language: QML
+caption: true
+linenos: true
+lines: 147-150
+---
+```
+
+To complete our implementation, the `ColorScheme.qml` file needs to be created.
+The implementation is straightforward and follows the same principles as in the
+original example. If anything is unclear, please refer to the documentation
+provided there. To display all colors and scheme names, use a `Repeater`. The
+model for the Repeater is provided by our `scheme_manager.py`file as a
+`QStringList`.
+
+```{literalinclude} FileSystemModule/qml/ColorScheme.qml
+---
+language: QML
+caption: true
+linenos: true
+lines: 97-111
+---
+```
+
+When examining the code in more detail, you will notice that there are different
+ways to retrieve the models. The `getKeys()` method is defined as a **Slot** and
+therefore requires parentheses when called. On the other hand, the `currentColors`
+model is defined as a **property** and is therefore assigned as a property in QML.
+The reason for this is to receive notifications when the color scheme is switched
+so that the colors displayed in the application can be updated. The keys for the
+color schemes are loaded only once at application startup and do not rely on any
+notifications.
+
+![Extended Explorer GIF](resources/colorscheme.png)
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.pyproject b/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.pyproject
new file mode 100644
index 000000000..77a3969ae
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.pyproject
@@ -0,0 +1,31 @@
+{
+ "files": [
+ "main.py",
+ "editormodels.py",
+ "scheme_manager.py",
+ "schemes.json",
+ "FileSystemModule/qmldir",
+ "FileSystemModule/app.qrc",
+ "FileSystemModule/icons.qrc",
+ "FileSystemModule/Main.qml",
+ "FileSystemModule/qml/About.qml",
+ "FileSystemModule/qml/ColorScheme.qml",
+ "FileSystemModule/qml/Editor.qml",
+ "FileSystemModule/qml/FileSystemView.qml",
+ "FileSystemModule/qml/MyMenu.qml",
+ "FileSystemModule/qml/MyMenuBar.qml",
+ "FileSystemModule/qml/ResizeButton.qml",
+ "FileSystemModule/qml/Sidebar.qml",
+ "FileSystemModule/qml/WindowDragHandler.qml",
+ "FileSystemModule/icons/app_icon.svg",
+ "FileSystemModule/icons/folder_closed.svg",
+ "FileSystemModule/icons/folder_open.svg",
+ "FileSystemModule/icons/generic_file.svg",
+ "FileSystemModule/icons/globe.svg",
+ "FileSystemModule/icons/info_sign.svg",
+ "FileSystemModule/icons/light_bulb.svg",
+ "FileSystemModule/icons/qt_logo.svg",
+ "FileSystemModule/icons/read.svg",
+ "FileSystemModule/icons/resize.svg"
+ ]
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/main.py b/sources/pyside6/doc/tutorials/extendedexplorer/main.py
new file mode 100644
index 000000000..f1e6e7d93
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/main.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""
+This example shows how to customize Qt Quick Controls by implementing a simple filesystem explorer.
+"""
+
+# Compile both resource files app.qrc and icons.qrc and include them here if you wish
+# to load them from the resource system. Currently, all resources are loaded locally
+# import FileSystemModule.rc_icons
+# import FileSystemModule.rc_app
+
+from scheme_manager import SchemeManager
+from editormodels import FileSystemModel
+import PySide6
+from PySide6.QtGui import QGuiApplication, QIcon
+from PySide6.QtQml import QQmlApplicationEngine
+from PySide6.QtCore import QCommandLineParser
+
+import sys
+
+if __name__ == '__main__':
+ app = QGuiApplication(sys.argv)
+ app.setOrganizationName("QtProject")
+ app.setApplicationName("File System Explorer")
+ app.setApplicationVersion(PySide6.__version__)
+ app.setWindowIcon(QIcon("FileSystemModule/icons/app_icon.svg"))
+
+ parser = QCommandLineParser()
+ parser.setApplicationDescription("Qt Filesystemexplorer Example")
+ parser.addHelpOption()
+ parser.addVersionOption()
+ parser.addPositionalArgument("", "Initial directory", "[path]")
+ parser.process(app)
+ args = parser.positionalArguments()
+
+ engine = QQmlApplicationEngine()
+ # Include the path of this file to search for the 'qmldir' module
+ engine.addImportPath(sys.path[0])
+
+ engine.loadFromModule("FileSystemModule", "Main")
+
+ if not engine.rootObjects():
+ sys.exit(-1)
+
+ if (len(args) == 1):
+ fsm = engine.singletonInstance("FileSystemModule", "FileSystemModel")
+ fsm.setInitialDirectory(args[0])
+
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/resources/Colors.qml b/sources/pyside6/doc/tutorials/extendedexplorer/resources/Colors.qml
new file mode 100644
index 000000000..280f89286
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/resources/Colors.qml
@@ -0,0 +1,22 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+pragma Singleton
+import QtQuick
+
+QtObject {
+ readonly property color background: "#23272E"
+ readonly property color surface1: "#1E2227"
+ readonly property color surface2: "#090A0C"
+ readonly property color text: "#ABB2BF"
+ readonly property color textFile: "#C5CAD3"
+ readonly property color disabledText: "#454D5F"
+ readonly property color selection: "#2C313A"
+ readonly property color active: "#23272E"
+ readonly property color inactive: "#3E4452"
+ readonly property color folder: "#3D4451"
+ readonly property color icon: "#3D4451"
+ readonly property color iconIndicator: "#E5C07B"
+ readonly property color color1: "#E06B74"
+ readonly property color color2: "#62AEEF"
+}
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/resources/colorscheme.png b/sources/pyside6/doc/tutorials/extendedexplorer/resources/colorscheme.png
new file mode 100644
index 000000000..410538ca3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/resources/colorscheme.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.gif b/sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.gif
new file mode 100644
index 000000000..9e59f64aa
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.gif
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.webp b/sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.webp
new file mode 100644
index 000000000..79a14f34c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/resources/extendedexplorer.webp
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/scheme_manager.py b/sources/pyside6/doc/tutorials/extendedexplorer/scheme_manager.py
new file mode 100644
index 000000000..8d732093c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/scheme_manager.py
@@ -0,0 +1,97 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import json
+from pathlib import Path
+from PySide6.QtCore import Slot, QObject, Property, Signal
+from PySide6.QtGui import QColor
+from PySide6.QtQml import QmlNamedElement, QmlSingleton
+
+QML_IMPORT_NAME = "FileSystemModule"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlNamedElement("Colors")
+@QmlSingleton
+class SchemeManager(QObject):
+
+ schemeChanged = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent=parent)
+ with open(Path(__file__).parent / "schemes.json", 'r') as f:
+ self.m_schemes = json.load(f)
+ self.m_activeScheme = {}
+ self.m_activeSchemeName = "Catppuccin"
+ self.setScheme(self.m_activeSchemeName)
+
+ @Slot(str)
+ def setScheme(self, theme):
+ for k, v in self.m_schemes[theme].items():
+ self.m_activeScheme[k] = QColor.fromString(v)
+ self.m_activeSchemeName = theme
+ self.schemeChanged.emit()
+
+ @Slot(result='QStringList')
+ def getKeys(self):
+ return self.m_schemes.keys()
+
+ @Property('QStringList', notify=schemeChanged)
+ def currentColors(self):
+ return self.m_schemes[self.m_activeSchemeName].values()
+
+ @Property(QColor, notify=schemeChanged)
+ def background(self):
+ return self.m_activeScheme["background"]
+
+ @Property(QColor, notify=schemeChanged)
+ def surface1(self):
+ return self.m_activeScheme["surface1"]
+
+ @Property(QColor, notify=schemeChanged)
+ def surface2(self):
+ return self.m_activeScheme["surface2"]
+
+ @Property(QColor, notify=schemeChanged)
+ def text(self):
+ return self.m_activeScheme["text"]
+
+ @Property(QColor, notify=schemeChanged)
+ def textFile(self):
+ return self.m_activeScheme["textFile"]
+
+ @Property(QColor, notify=schemeChanged)
+ def disabledText(self):
+ return self.m_activeScheme["disabledText"]
+
+ @Property(QColor, notify=schemeChanged)
+ def selection(self):
+ return self.m_activeScheme["selection"]
+
+ @Property(QColor, notify=schemeChanged)
+ def active(self):
+ return self.m_activeScheme["active"]
+
+ @Property(QColor, notify=schemeChanged)
+ def inactive(self):
+ return self.m_activeScheme["inactive"]
+
+ @Property(QColor, notify=schemeChanged)
+ def folder(self):
+ return self.m_activeScheme["folder"]
+
+ @Property(QColor, notify=schemeChanged)
+ def icon(self):
+ return self.m_activeScheme["icon"]
+
+ @Property(QColor, notify=schemeChanged)
+ def iconIndicator(self):
+ return self.m_activeScheme["iconIndicator"]
+
+ @Property(QColor, notify=schemeChanged)
+ def color1(self):
+ return self.m_activeScheme["color1"]
+
+ @Property(QColor, notify=schemeChanged)
+ def color2(self):
+ return self.m_activeScheme["color2"]
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/schemes.json b/sources/pyside6/doc/tutorials/extendedexplorer/schemes.json
new file mode 100644
index 000000000..e4f2d8c81
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/extendedexplorer/schemes.json
@@ -0,0 +1,82 @@
+{
+ "Catppuccin": {
+ "background": "#1E1E2E",
+ "surface1": "#181825",
+ "surface2": "#11111B",
+ "text": "#CDD6F4",
+ "textFile": "#CDD6F4",
+ "disabledText": "#363659",
+ "selection": "#45475A",
+ "active": "#1E1E2E",
+ "inactive": "#6C7086",
+ "folder": "#6C7086",
+ "icon": "#6C7086",
+ "iconIndicator": "#FFCC66",
+ "color1": "#CBA6F7",
+ "color2": "#89DCEB"
+ },
+ "Nordic": {
+ "background": "#2E3440",
+ "surface1": "#2B2F3A",
+ "surface2": "#262A35",
+ "text": "#D8DEE9",
+ "textFile": "#D8DEE9",
+ "disabledText": "#4D556A",
+ "selection": "#495468",
+ "active": "#2E3440",
+ "inactive": "#555B6A",
+ "folder": "#495468",
+ "icon": "#495468",
+ "iconIndicator": "#FFC40D",
+ "color1": "#81B6C6",
+ "color2": "#5E81AC"
+ },
+ "One Dark": {
+ "background": "#23272E",
+ "surface1": "#1E2227",
+ "surface2": "#090A0C",
+ "text": "#ABB2BF",
+ "textFile": "#C5CAD3",
+ "disabledText": "#2B303B",
+ "selection": "#2C313A",
+ "active": "#23272E",
+ "inactive": "#3E4452",
+ "folder": "#3D4451",
+ "icon": "#3D4451",
+ "iconIndicator": "#E5C07B",
+ "color1": "#E06B74",
+ "color2": "#62AEEF"
+ },
+ "Gruvbox": {
+ "background": "#292828",
+ "surface1": "#171819",
+ "surface2": "#090A0C",
+ "text": "#D4BE98",
+ "textFile": "#E1D2B7",
+ "disabledText": "#2C313A",
+ "selection": "#333130",
+ "active": "#292828",
+ "inactive": "#383737",
+ "folder": "#383737",
+ "icon": "#383737",
+ "iconIndicator": "#FFCC66",
+ "color1": "#A7B464",
+ "color2": "#D3869B"
+ },
+ "Solarized": {
+ "background": "#FDF6E3",
+ "surface1": "#EEE8D5",
+ "surface2": "#DDD6C1",
+ "text": "#6D6D6D",
+ "textFile": "#333333",
+ "disabledText": "#ADADAD",
+ "selection": "#D1CBB8",
+ "active": "#FDF6E3",
+ "inactive": "#8C8364",
+ "folder": "#5F5944",
+ "icon": "#5F5944",
+ "iconIndicator": "#002B36",
+ "color1": "#B58900",
+ "color2": "#6B9E75"
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/index.rst b/sources/pyside6/doc/tutorials/index.rst
new file mode 100644
index 000000000..8a69a3c6f
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/index.rst
@@ -0,0 +1,206 @@
+Tutorials
+=========
+
+A collection of tutorials with walkthrough guides are
+provided with |project| to help new users get started.
+
+Some of these documents were ported from C++ to Python and cover a range of
+topics, from basic use of widgets to step-by-step tutorials that show how an
+application is put together.
+
+Qt Widgets: Basic tutorials
+---------------------------
+
+If you want to see the available widgets in action, you can check the
+`Qt Widget Gallery <https://doc.qt.io/qt-6/gallery.html>`_ to learn their
+names and how they look like.
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: Basic Widget
+ :class-item: cover-img
+ :link: basictutorial/widgets.html
+ :img-top: basictutorial/widgets.png
+
+ Your first QtWidgets Application
+
+ .. grid-item-card:: Basic Button
+ :class-item: cover-img
+ :link: basictutorial/clickablebutton.html
+ :img-top: basictutorial/clickablebutton.png
+
+ Using a Simple Button
+
+ .. grid-item-card:: Basic Connections
+ :class-item: cover-img
+ :link: basictutorial/signals_and_slots.html
+ :img-top: basictutorial/signals_slots.png
+
+ Signals and Slots
+
+ .. grid-item-card:: Basic Dialog
+ :class-item: cover-img
+ :link: basictutorial/dialog.html
+ :img-top: basictutorial/dialog.png
+
+ Creating a Dialog Application
+
+ .. grid-item-card:: Basic Table
+ :class-item: cover-img
+ :link: basictutorial/tablewidget.html
+ :img-top: basictutorial/tablewidget.png
+
+ Displaying Data Using a Table Widget
+
+ .. grid-item-card:: Basic Tree
+ :class-item: cover-img
+ :link: basictutorial/treewidget.html
+ :img-top: basictutorial/treewidget.png
+
+ Displaying Data Using a Tree Widget
+
+ .. grid-item-card:: Basic ``ui`` files
+ :class-item: cover-img
+ :link: basictutorial/uifiles.html
+ :img-top: basictutorial/uifiles.png
+
+ Using .ui files from Designer or QtCreator with QUiLoader and pyside6-uic
+
+ .. grid-item-card:: Basic ``qrc`` files
+ :class-item: cover-img
+ :link: basictutorial/qrcfiles.html
+ :img-top: basictutorial/player-new.png
+
+ Using .qrc Files (pyside6-rcc)
+
+ .. grid-item-card:: Basic Translations
+ :class-item: cover-img
+ :link: basictutorial/translations.html
+ :img-top: basictutorial/translations.png
+
+ Translating Applications
+
+ .. grid-item-card:: Basic Widget Style
+ :class-item: cover-img
+ :link: basictutorial/widgetstyling.html
+ :img-top: basictutorial/widgetstyling-yes.png
+
+ Styling the Widgets Application
+
+.. toctree::
+ :hidden:
+
+ basictutorial/widgets.rst
+ basictutorial/clickablebutton.rst
+ basictutorial/signals_and_slots.rst
+ basictutorial/dialog.rst
+ basictutorial/tablewidget.rst
+ basictutorial/treewidget.rst
+ basictutorial/uifiles.rst
+ basictutorial/qrcfiles.rst
+ basictutorial/translations.rst
+ basictutorial/widgetstyling.rst
+
+
+Quick/QML: Basic tutorials
+--------------------------
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: Basic Quick
+ :class-item: cover-img
+ :link: basictutorial/qml.html
+ :img-top: basictutorial/greenapplication.png
+
+ Your First QtQuick/QML Application
+
+ .. grid-item-card:: Basic QML Integration
+ :class-item: cover-img
+ :link: qmlintegration/qmlintegration.html
+ :img-top: qmlintegration/textproperties_material.png
+
+ Python-QML integration
+
+ .. grid-item-card:: QML Application
+ :class-item: cover-img
+ :link: qmlapp/qmlapplication.html
+ :img-top: qmlapp/qmlapplication.png
+
+ QML Application Tutorial (QtCreator)
+
+ .. grid-item-card:: Advanced QML Integration
+ :class-item: cover-img
+ :link: qmlsqlintegration/qmlsqlintegration.html
+ :img-top: qmlsqlintegration/example_list_view.png
+
+ QML, SQL and PySide Integration Tutorial
+
+ .. grid-item-card:: Extended Explorer
+ :class-item: cover-img
+ :link: extendedexplorer/extendedexplorer.html
+ :img-top: extendedexplorer/resources/extendedexplorer.webp
+
+ Extending an Qt Quick Controls example
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+ basictutorial/qml.rst
+ qmlintegration/qmlintegration.rst
+ qmlapp/qmlapplication.rst
+ qmlsqlintegration/qmlsqlintegration.rst
+ extendedexplorer/extendedexplorer.md
+
+General Applications
+--------------------
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: Data Visualization
+ :class-item: cover-img
+ :link: datavisualize/index.html
+ :img-top: datavisualize/images/datavisualization_app.png
+
+ Data Visualization Tool
+
+ .. grid-item-card:: Expenses Application
+ :class-item: cover-img
+ :link: expenses/expenses.html
+ :img-top: expenses/expenses_tool.png
+
+ Expenses administration tool
+
+.. toctree::
+ :hidden:
+
+ datavisualize/index.rst
+ expenses/expenses.rst
+
+Qt Overviews
+------------
+
+.. toctree::
+ :maxdepth: 1
+
+ ../overviews/overviews-main.rst
+
+C++ and Python
+--------------
+
+.. toctree::
+ :maxdepth: 1
+
+ portingguide/index.rst
+
+Debug a PySide6 Application
+---------------------------
+.. toctree::
+ :maxdepth: 1
+
+ debugging/mixed_debugging.rst
+ debugging/qml_debugging.rst
+
diff --git a/sources/pyside6/doc/tutorials/modelviewprogramming/qlistview-dnd.py b/sources/pyside6/doc/tutorials/modelviewprogramming/qlistview-dnd.py
new file mode 100644
index 000000000..3a37cc0f3
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/modelviewprogramming/qlistview-dnd.py
@@ -0,0 +1,137 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtWidgets import (QAbstractItemView, QApplication, QMainWindow,
+ QListView)
+from PySide6.QtCore import (QByteArray, QDataStream, QIODevice, QMimeData,
+ QModelIndex, QStringListModel, Qt)
+
+
+class DragDropListModel(QStringListModel):
+ """A simple model that uses a QStringList as its data source."""
+
+ def __init__(self, strings, parent=None):
+ super().__init__(strings, parent)
+
+#! [0]
+
+ def canDropMimeData(self, data, action, row, column, parent):
+ if not data.hasFormat("application/vnd.text.list"):
+ return False
+
+ if column > 0:
+ return False
+
+ return True
+#! [0]
+#! [1]
+ def dropMimeData(self, data, action, row, column, parent):
+ if not self.canDropMimeData(data, action, row, column, parent):
+ return False
+
+ if action == Qt.IgnoreAction:
+ return True
+#! [1]
+
+#! [2]
+ begin_row = 0
+
+ if row != -1:
+ begin_row = row
+#! [2] #! [3]
+ elif parent.isValid():
+ begin_row = parent.row()
+#! [3] #! [4]
+ else:
+ begin_row = self.rowCount(QModelIndex())
+#! [4]
+
+#! [5]
+ encoded_data = data.data("application/vnd.text.list")
+ stream = QDataStream(encoded_data, QIODevice.ReadOnly)
+ new_items = []
+ while not stream.atEnd():
+ new_items.append(stream.readQString())
+#! [5]
+
+#! [6]
+ self.insertRows(begin_row, len(new_items), QModelIndex())
+ for text in new_items:
+ idx = self.index(begin_row, 0, QModelIndex())
+ self.setData(idx, text)
+ begin_row += 1
+
+ return True
+#! [6]
+
+#! [7]
+ def flags(self, index):
+ default_flags = super().flags(index)
+ if index.isValid():
+ return Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled | default_flags
+ return Qt.ItemIsDropEnabled | default_flags
+#! [7]
+
+#! [8]
+ def mimeData(self, indexes):
+ mime_data = QMimeData()
+ encoded_data = QByteArray()
+ stream = QDataStream(encoded_data, QIODevice.WriteOnly)
+ for index in indexes:
+ if index.isValid():
+ text = self.data(index, Qt.DisplayRole)
+ stream.writeQString(text)
+
+ mime_data.setData("application/vnd.text.list", encoded_data)
+ return mime_data
+#! [8]
+
+#! [9]
+ def mimeTypes(self):
+ return ["application/vnd.text.list"]
+#! [9]
+
+#! [10]
+ def supportedDropActions(self):
+ return Qt.CopyAction | Qt.MoveAction
+#! [10]
+
+
+class MainWindow(QMainWindow):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ file_menu = self.menuBar().addMenu("&File")
+ quit_action = file_menu.addAction("E&xit")
+ quit_action.setShortcut("Ctrl+Q")
+
+#! [mainwindow0]
+ self._list_view = QListView(self)
+ self._list_view.setSelectionMode(QAbstractItemView.ExtendedSelection)
+ self._list_view.setDragEnabled(True)
+ self._list_view.setAcceptDrops(True)
+ self._list_view.setDropIndicatorShown(True)
+#! [mainwindow0]
+
+ quit_action.triggered.connect(self.close)
+
+ self.setup_list_items()
+
+ self.setCentralWidget(self._list_view)
+ self.setWindowTitle("List View")
+
+ def setup_list_items(self):
+ items = ["Oak", "Fir", "Pine", "Birch", "Hazel", "Redwood", "Sycamore",
+ "Chestnut", "Mahogany"]
+ model = DragDropListModel(items, self)
+ self._list_view.setModel(model)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ window = MainWindow()
+ window.show()
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/modelviewprogramming/simplemodel-use.py b/sources/pyside6/doc/tutorials/modelviewprogramming/simplemodel-use.py
new file mode 100644
index 000000000..1bacfd829
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/modelviewprogramming/simplemodel-use.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtWidgets import (QApplication, QFileSystemModel, QLabel,
+ QVBoxLayout, QWidget)
+from PySide6.QtGui import QPalette
+from PySide6.QtCore import QDir, Qt
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ window = QWidget()
+ layout = QVBoxLayout(window)
+ title = QLabel("Some items from the directory model", window)
+ title.setBackgroundRole(QPalette.Base)
+ title.setMargin(8)
+ layout.addWidget(title)
+
+#! [0]
+ model = QFileSystemModel()
+ model.setRootPath(QDir.currentPath())
+
+ def on_directory_loaded(directory):
+ parent_index = model.index(directory)
+ num_rows = model.rowCount(parent_index)
+#! [1]
+ for row in range(num_rows):
+ index = model.index(row, 0, parent_index)
+#! [1]
+#! [2]
+ text = model.data(index, Qt.DisplayRole)
+#! [2]
+ label = QLabel(text, window)
+ layout.addWidget(label)
+
+ model.directoryLoaded.connect(on_directory_loaded)
+#! [0]
+
+ window.setWindowTitle("A simple model example")
+ window.show()
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/modelviewprogramming/stringlistmodel.py b/sources/pyside6/doc/tutorials/modelviewprogramming/stringlistmodel.py
new file mode 100644
index 000000000..2c8493aa9
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/modelviewprogramming/stringlistmodel.py
@@ -0,0 +1,124 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtWidgets import (QApplication, QListView)
+from PySide6.QtCore import QAbstractListModel, QStringListModel, QModelIndex, Qt
+
+
+#! [0]
+class StringListModel(QAbstractListModel):
+ def __init__(self, strings, parent=None):
+ super().__init__(parent)
+ self._strings = strings
+
+#! [0]
+ def rowCount(self, parent=QModelIndex()):
+ """Returns the number of items in the string list as the number of rows
+ in the model."""
+ return len(self._strings)
+#! [0]
+
+#! [1]
+ def data(self, index, role):
+ """Returns an appropriate value for the requested data.
+ If the view requests an invalid index, an invalid variant is returned.
+ Any valid index that corresponds to a string in the list causes that
+ string to be returned."""
+ row = index.row()
+ if not index.isValid() or row >= len(self._strings):
+ return None
+ if role != Qt.DisplayRole and role != Qt.EditRole:
+ return None
+ return self._strings[row]
+#! [1]
+
+#! [2]
+ def headerData(self, section, orientation, role=Qt.DisplayRole):
+ """Returns the appropriate header string depending on the orientation of
+ the header and the section. If anything other than the display role is
+ requested, we return an invalid variant."""
+ if role != Qt.DisplayRole:
+ return None
+ if orientation == Qt.Horizontal:
+ return f"Column {section}"
+ return f"Row {section}"
+#! [2]
+
+#! [3]
+ def flags(self, index):
+ """Returns an appropriate value for the item's flags. Valid items are
+ enabled, selectable, and editable."""
+
+ if not index.isValid():
+ return Qt.ItemIsEnabled
+ return super().flags(index) | Qt.ItemIsEditable
+#! [3]
+
+ #! [4]
+ def setData(self, index, value, role=Qt.EditRole):
+ """Changes an item in the string list, but only if the following conditions
+ are met:
+
+ # The index supplied is valid.
+ # The index corresponds to an item to be shown in a view.
+ # The role associated with editing text is specified.
+
+ The dataChanged() signal is emitted if the item is changed."""
+
+ if index.isValid() and role == Qt.EditRole:
+ self._strings[index.row()] = value
+ self.dataChanged.emit(index, index, {role})
+ return True
+#! [4] #! [5]
+ return False
+#! [5]
+
+#! [6]
+ def insertRows(self, position, rows, parent):
+ """Inserts a number of rows into the model at the specified position."""
+ self.beginInsertRows(QModelIndex(), position, position + rows - 1)
+ for row in range(rows):
+ self._strings.insert(position, "")
+ self.endInsertRows()
+ return True
+#! [6] #! [7]
+#! [7]
+
+#! [8]
+ def removeRows(self, position, rows, parent):
+ """Removes a number of rows from the model at the specified position."""
+ self.beginRemoveRows(QModelIndex(), position, position + rows - 1)
+ for row in range(rows):
+ del self._strings[position]
+ self.endRemoveRows()
+ return True
+#! [8] #! [9]
+#! [9]
+
+
+#! [main0]
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+#! [main1]
+ numbers = ["One", "Two", "Three", "Four", "Five"]
+ model = StringListModel(numbers)
+#! [main0] #! [main1] #! [main2] #! [main3]
+ view = QListView()
+#! [main2]
+ view.setWindowTitle("View onto a string list model")
+#! [main4]
+ view.setModel(model)
+#! [main3] #! [main4]
+
+ model.insertRows(5, 7, QModelIndex())
+ for row in range(5, 12):
+ index = model.index(row, 0, QModelIndex())
+ model.setData(index, f"{row+1}")
+
+#! [main5]
+ view.show()
+ sys.exit(app.exec())
+#! [main5]
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst b/sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst
new file mode 100644
index 000000000..87fb97660
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/chapter1.rst
@@ -0,0 +1,89 @@
+Chapter 1: ``initDb.h`` to ``createDb.py``
+*******************************************
+
+To begin with, port the C++ code that creates an SQLite
+database and tables, and adds data to them. In this case,
+all C++ code related to this lives in ``initdb.h``. The
+code in this header file is divided into following parts:
+
+* ``initDb`` - Creates a db and the necessary tables
+* ``addBooks`` - Adds data to the **books** table.
+* ``addAuthor`` - Adds data to the **authors** table.
+* ``addGenre`` - Adds data to the **genres** table.
+
+To start with, add these following ``import`` statements at
+the beginning of ``createdb.py``:
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 3-5
+
+The ``initDb`` function does most of the work needed to
+set up the database, but it depends on the ``addAuthor``,
+``addGenre``, and ``addBook`` helper functions to populate
+the tables. Port these helper functions first. Here is how
+the C++ and Python versions of these functions look like:
+
+C++ version
+-----------
+
+.. literalinclude:: initdb.h
+ :language: c++
+ :linenos:
+ :lines: 9-33
+
+Python version
+--------------
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 7-28
+
+Now that the helper functions are in place, port ``initDb``.
+Here is how the C++ and Python versions of this function
+looks like:
+
+C++ version (initDb)
+--------------------
+
+.. literalinclude:: initdb.h
+ :language: c++
+ :linenos:
+ :lines: 35-112
+
+Python version (init_db)
+------------------------
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 28-
+
+.. note:: The Python version uses the ``check`` function to
+ execute the SQL statements instead of the ``if...else``
+ block like in the C++ version. Although both are valid
+ approaches, the earlier one produces code that looks
+ cleaner and shorter.
+
+Your Python code to set up the database is ready now. To
+test it, add the following code to ``main.py`` and run it:
+
+.. literalinclude:: main.py
+ :language: python
+ :linenos:
+ :lines: 3-
+
+Use the following command from the prompt to run:
+
+.. code-block:: bash
+
+ python main.py
+
+Your table will look like this:
+
+.. image:: images/chapter1_books.png
+
+Try modifying the SQL statment in ``main.py`` to get data
+from the ``genres`` or ``authors`` table.
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py b/sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py
new file mode 100644
index 000000000..da7d201a8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/createdb.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from datetime import date
+
+
+def add_book(q, title, year, authorId, genreId, rating):
+ q.addBindValue(title)
+ q.addBindValue(year)
+ q.addBindValue(authorId)
+ q.addBindValue(genreId)
+ q.addBindValue(rating)
+ q.exec_()
+
+
+def add_genre(q, name):
+ q.addBindValue(name)
+ q.exec_()
+ return q.lastInsertId()
+
+
+def add_author(q, name, birthdate):
+ q.addBindValue(name)
+ q.addBindValue(str(birthdate))
+ q.exec_()
+ return q.lastInsertId()
+
+BOOKS_SQL = """
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ """
+AUTHORS_SQL = """
+ create table authors(id integer primary key, name varchar, birthdate text)
+ """
+GENRES_SQL = """
+ create table genres(id integer primary key, name varchar)
+ """
+INSERT_AUTHOR_SQL = """
+ insert into authors(name, birthdate) values(?, ?)
+ """
+INSERT_GENRE_SQL = """
+ insert into genres(name) values(?)
+ """
+INSERT_BOOK_SQL = """
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ """
+
+def init_db():
+ """
+ init_db()
+ Initializes the database.
+ If tables "books" and "authors" are already in the database, do nothing.
+ Return value: None or raises ValueError
+ The error value is the QtSql error instance.
+ """
+ def check(func, *args):
+ if not func(*args):
+ raise ValueError(func.__self__.lastError())
+ db = QSqlDatabase.addDatabase("QSQLITE")
+ db.setDatabaseName(":memory:")
+
+ check(db.open)
+
+ q = QSqlQuery()
+ check(q.exec_, BOOKS_SQL)
+ check(q.exec_, AUTHORS_SQL)
+ check(q.exec_, GENRES_SQL)
+ check(q.prepare, INSERT_AUTHOR_SQL)
+
+ asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1))
+ greeneId = add_author(q, "Graham Greene", date(1904, 10, 2))
+ pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28))
+
+ check(q.prepare,INSERT_GENRE_SQL)
+ sfiction = add_genre(q, "Science Fiction")
+ fiction = add_genre(q, "Fiction")
+ fantasy = add_genre(q, "Fantasy")
+
+ check(q.prepare,INSERT_BOOK_SQL)
+ add_book(q, "Foundation", 1951, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4)
+ add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3)
+ add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4)
+ add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3)
+ add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3)
+ add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4)
+ add_book(q, "The Third Man", 1950, greeneId, fiction, 5)
+ add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4)
+ add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3)
+ add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3)
+ add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3)
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.png b/sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.png
new file mode 100644
index 000000000..164674220
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/images/chapter1_books.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h b/sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h
new file mode 100644
index 000000000..5596defc0
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/initdb.h
@@ -0,0 +1,113 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef INITDB_H
+#define INITDB_H
+
+#include <QtSql>
+
+void addBook(QSqlQuery &q, const QString &title, int year, const QVariant &authorId,
+ const QVariant &genreId, int rating)
+{
+ q.addBindValue(title);
+ q.addBindValue(year);
+ q.addBindValue(authorId);
+ q.addBindValue(genreId);
+ q.addBindValue(rating);
+ q.exec();
+}
+
+QVariant addGenre(QSqlQuery &q, const QString &name)
+{
+ q.addBindValue(name);
+ q.exec();
+ return q.lastInsertId();
+}
+
+QVariant addAuthor(QSqlQuery &q, const QString &name, const QDate &birthdate)
+{
+ q.addBindValue(name);
+ q.addBindValue(birthdate);
+ q.exec();
+ return q.lastInsertId();
+}
+
+const auto BOOKS_SQL = QLatin1String(R"(
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ )");
+
+const auto AUTHORS_SQL = QLatin1String(R"(
+ create table authors(id integer primary key, name varchar, birthdate date)
+ )");
+
+const auto GENRES_SQL = QLatin1String(R"(
+ create table genres(id integer primary key, name varchar)
+ )");
+
+const auto INSERT_AUTHOR_SQL = QLatin1String(R"(
+ insert into authors(name, birthdate) values(?, ?)
+ )");
+
+const auto INSERT_BOOK_SQL = QLatin1String(R"(
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ )");
+
+const auto INSERT_GENRE_SQL = QLatin1String(R"(
+ insert into genres(name) values(?)
+ )");
+
+QSqlError initDb()
+{
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+ db.setDatabaseName(":memory:");
+
+ if (!db.open())
+ return db.lastError();
+
+ QStringList tables = db.tables();
+ if (tables.contains("books", Qt::CaseInsensitive)
+ && tables.contains("authors", Qt::CaseInsensitive))
+ return QSqlError();
+
+ QSqlQuery q;
+ if (!q.exec(BOOKS_SQL))
+ return q.lastError();
+ if (!q.exec(AUTHORS_SQL))
+ return q.lastError();
+ if (!q.exec(GENRES_SQL))
+ return q.lastError();
+
+ if (!q.prepare(INSERT_AUTHOR_SQL))
+ return q.lastError();
+ QVariant asimovId = addAuthor(q, QLatin1String("Isaac Asimov"), QDate(1920, 2, 1));
+ QVariant greeneId = addAuthor(q, QLatin1String("Graham Greene"), QDate(1904, 10, 2));
+ QVariant pratchettId = addAuthor(q, QLatin1String("Terry Pratchett"), QDate(1948, 4, 28));
+
+ if (!q.prepare(INSERT_GENRE_SQL))
+ return q.lastError();
+ QVariant sfiction = addGenre(q, QLatin1String("Science Fiction"));
+ QVariant fiction = addGenre(q, QLatin1String("Fiction"));
+ QVariant fantasy = addGenre(q, QLatin1String("Fantasy"));
+
+ if (!q.prepare(INSERT_BOOK_SQL))
+ return q.lastError();
+ addBook(q, QLatin1String("Foundation"), 1951, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Empire"), 1952, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Second Foundation"), 1953, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation's Edge"), 1982, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Earth"), 1986, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Prelude to Foundation"), 1988, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Forward the Foundation"), 1993, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("The Power and the Glory"), 1940, greeneId, fiction, 4);
+ addBook(q, QLatin1String("The Third Man"), 1950, greeneId, fiction, 5);
+ addBook(q, QLatin1String("Our Man in Havana"), 1958, greeneId, fiction, 4);
+ addBook(q, QLatin1String("Guards! Guards!"), 1989, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Night Watch"), 2002, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Going Postal"), 2004, pratchettId, fantasy, 3);
+
+ return QSqlError();
+}
+
+#endif
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter1/main.py b/sources/pyside6/doc/tutorials/portingguide/chapter1/main.py
new file mode 100644
index 000000000..c1293bcbd
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter1/main.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtSql import QSqlQueryModel
+from PySide6.QtWidgets import QTableView, QApplication
+
+import createdb
+
+if __name__ == "__main__":
+ app = QApplication()
+ createdb.init_db()
+
+ model = QSqlQueryModel()
+ model.setQuery("select * from books")
+
+ table_view = QTableView()
+ table_view.setModel(model)
+ table_view.resize(800, 600)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.cpp b/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.cpp
new file mode 100644
index 000000000..3d246667b
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.cpp
@@ -0,0 +1,96 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "bookdelegate.h"
+
+#include <QtWidgets>
+
+BookDelegate::BookDelegate(QObject *parent)
+ : QSqlRelationalDelegate(parent), star(QPixmap(":images/star.png"))
+{
+}
+
+void BookDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() != 5) {
+ QStyleOptionViewItem opt = option;
+ // Since we draw the grid ourselves:
+ opt.rect.adjust(0, 0, -1, -1);
+ QSqlRelationalDelegate::paint(painter, opt, index);
+ } else {
+ const QAbstractItemModel *model = index.model();
+ QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ?
+ (option.state & QStyle::State_Active) ?
+ QPalette::Normal :
+ QPalette::Inactive :
+ QPalette::Disabled;
+
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(
+ option.rect,
+ option.palette.color(cg, QPalette::Highlight));
+
+ int rating = model->data(index, Qt::DisplayRole).toInt();
+ int width = star.width();
+ int height = star.height();
+ int x = option.rect.x();
+ int y = option.rect.y() + (option.rect.height() / 2) - (height / 2);
+ for (int i = 0; i < rating; ++i) {
+ painter->drawPixmap(x, y, star);
+ x += width;
+ }
+ // Since we draw the grid ourselves:
+ drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1));
+ }
+
+ QPen pen = painter->pen();
+ painter->setPen(option.palette.color(QPalette::Mid));
+ painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
+ painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
+ painter->setPen(pen);
+}
+
+QSize BookDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() == 5)
+ return QSize(5 * star.width(), star.height()) + QSize(1, 1);
+ // Since we draw the grid ourselves:
+ return QSqlRelationalDelegate::sizeHint(option, index) + QSize(1, 1);
+}
+
+bool BookDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index)
+{
+ if (index.column() != 5)
+ return QSqlRelationalDelegate::editorEvent(event, model, option, index);
+
+ if (event->type() == QEvent::MouseButtonPress) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ int stars = qBound(0, int(0.7 + qreal(mouseEvent->pos().x()
+ - option.rect.x()) / star.width()), 5);
+ model->setData(index, QVariant(stars));
+ // So that the selection can change:
+ return false;
+ }
+
+ return true;
+}
+
+QWidget *BookDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() != 4)
+ return QSqlRelationalDelegate::createEditor(parent, option, index);
+
+ // For editing the year, return a spinbox with a range from -1000 to 2100.
+ QSpinBox *sb = new QSpinBox(parent);
+ sb->setFrame(false);
+ sb->setMaximum(2100);
+ sb->setMinimum(-1000);
+
+ return sb;
+}
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.h b/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.h
new file mode 100644
index 000000000..d0b157b39
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef BOOKDELEGATE_H
+#define BOOKDELEGATE_H
+
+#include <QModelIndex>
+#include <QPixmap>
+#include <QSize>
+#include <QSqlRelationalDelegate>
+
+QT_FORWARD_DECLARE_CLASS(QPainter)
+
+class BookDelegate : public QSqlRelationalDelegate
+{
+public:
+ BookDelegate(QObject *parent);
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) override;
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+private:
+ QPixmap star;
+};
+
+#endif
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.py b/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.py
new file mode 100644
index 000000000..2c2b80157
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/bookdelegate.py
@@ -0,0 +1,101 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import copy
+import os
+from pathlib import Path
+
+from PySide6.QtSql import QSqlRelationalDelegate
+from PySide6.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate,
+ QStyle, QStyleOptionViewItem)
+from PySide6.QtGui import QMouseEvent, QPixmap, QPalette, QImage
+from PySide6.QtCore import QEvent, QSize, Qt, QUrl
+
+
+class BookDelegate(QSqlRelationalDelegate):
+ """Books delegate to rate the books"""
+
+ def __init__(self, parent=None):
+ QSqlRelationalDelegate.__init__(self, parent)
+ star_png = Path(__file__).parent / "images" / "star.png"
+ self.star = QPixmap(star_png)
+
+ def paint(self, painter, option, index):
+ """ Paint the items in the table.
+
+ If the item referred to by <index> is a StarRating, we
+ handle the painting ourselves. For the other items, we
+ let the base class handle the painting as usual.
+
+ In a polished application, we'd use a better check than
+ the column number to find out if we needed to paint the
+ stars, but it works for the purposes of this example.
+ """
+ if index.column() != 5:
+ # Since we draw the grid ourselves:
+ opt = copy.copy(option)
+ opt.rect = option.rect.adjusted(0, 0, -1, -1)
+ QSqlRelationalDelegate.paint(self, painter, opt, index)
+ else:
+ model = index.model()
+ if option.state & QStyle.State_Enabled:
+ if option.state & QStyle.State_Active:
+ color_group = QPalette.Normal
+ else:
+ color_group = QPalette.Inactive
+ else:
+ color_group = QPalette.Disabled
+
+ if option.state & QStyle.State_Selected:
+ painter.fillRect(option.rect,
+ option.palette.color(color_group, QPalette.Highlight))
+ rating = model.data(index, Qt.DisplayRole)
+ width = self.star.width()
+ height = self.star.height()
+ x = option.rect.x()
+ y = option.rect.y() + (option.rect.height() / 2) - (height / 2)
+ for i in range(rating):
+ painter.drawPixmap(x, y, self.star)
+ x += width
+
+ # Since we draw the grid ourselves:
+ self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1))
+
+ pen = painter.pen()
+ painter.setPen(option.palette.color(QPalette.Mid))
+ painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
+ painter.drawLine(option.rect.topRight(), option.rect.bottomRight())
+ painter.setPen(pen)
+
+ def sizeHint(self, option, index):
+ """ Returns the size needed to display the item in a QSize object. """
+ if index.column() == 5:
+ size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1)
+ return size_hint
+ # Since we draw the grid ourselves:
+ return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1)
+
+ def editorEvent(self, event, model, option, index):
+ if index.column() != 5:
+ return False
+
+ if event.type() == QEvent.MouseButtonPress:
+ mouse_pos = event.pos()
+ new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width())
+ stars = max(0, min(new_stars, 5))
+ model.setData(index, stars)
+ # So that the selection can change
+ return False
+
+ return True
+
+ def createEditor(self, parent, option, index):
+ if index.column() != 4:
+ return QSqlRelationalDelegate.createEditor(self, parent, option, index)
+
+ # For editing the year, return a spinbox with a range from -1000 to 2100.
+ spinbox = QSpinBox(parent)
+ spinbox.setFrame(False)
+ spinbox.setMaximum(2100)
+ spinbox.setMinimum(-1000)
+ return spinbox
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/chapter2.rst b/sources/pyside6/doc/tutorials/portingguide/chapter2/chapter2.rst
new file mode 100644
index 000000000..83ba3357b
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/chapter2.rst
@@ -0,0 +1,93 @@
+Chapter 2: ``bookdelegate.cpp`` to ``bookdelegate.py``
+*******************************************************
+
+Now that your database is in place, port the C++ code for the
+``BookDelegate`` class. This class offers a delegate to present
+and edit the data in a ``QTableView``. It inherits
+``QSqlRelationalDelegate`` interface, which offers features
+specific for handling relational databases, such as a combobox
+editor for foreign key fields. To begin with, create
+``bookdelegate.py`` and add the following imports to it:
+
+.. literalinclude:: bookdelegate.py
+ :language: python
+ :linenos:
+ :lines: 3-10
+
+After the necessary ``import`` statements, port the
+constructor code for the ``BookDelegate`` class. Both
+the C++ and Python versions of this code initialize a
+``QSqlRelationalDelegate`` and ``QPixmap`` instance.
+Here is how they look:
+
+C++ version
+-------------
+
+.. literalinclude:: bookdelegate.cpp
+ :language: c++
+ :linenos:
+ :lines: 17-22
+
+Python version
+---------------
+
+.. literalinclude:: bookdelegate.py
+ :language: python
+ :linenos:
+ :lines: 10-17
+
+.. note:: The Python version loads the ``QPixmap`` using
+ the absolute path of ``star.png`` in the local
+ filesystem.
+
+As the default functionality offered by the
+``QSqlRelationalDelegate`` is not enough to present
+the books data, you must reimplement a few functions.
+For example, painting stars to represent the rating for
+each book in the table. Here is how the reimplemented
+code looks like:
+
+C++ version (bookdelegate)
+--------------------------
+
+.. literalinclude:: bookdelegate.cpp
+ :language: c++
+ :linenos:
+ :lines: 22-
+
+Python version (bookdelegate)
+-----------------------------
+
+.. literalinclude:: bookdelegate.py
+ :language: python
+ :linenos:
+ :lines: 18-
+
+Now that the delegate is in place, run the following
+``main.py`` to see how the data is presented:
+
+.. literalinclude:: main.py
+ :language: python
+ :linenos:
+ :lines: 3-
+
+Here is how the application will look when you run it:
+
+.. image:: images/chapter2_books.png
+ :alt: Books table data
+
+The only difference you'll notice now in comparison to
+:doc:`chapter 1 <../chapter1/chapter1>` is that the
+``rating`` column looks different.
+
+Try improving the table even further by adding these
+features:
+
+* Title for each column
+* SQL relation for the ``author_id`` and ``genre_id`` columns
+* Set a title to the window
+
+With these features, this is how your table will look like:
+
+.. image:: images/chapter2_books_with_relation.png
+ :alt: Books table with SQL relation
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/createdb.py b/sources/pyside6/doc/tutorials/portingguide/chapter2/createdb.py
new file mode 100644
index 000000000..da7d201a8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/createdb.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from datetime import date
+
+
+def add_book(q, title, year, authorId, genreId, rating):
+ q.addBindValue(title)
+ q.addBindValue(year)
+ q.addBindValue(authorId)
+ q.addBindValue(genreId)
+ q.addBindValue(rating)
+ q.exec_()
+
+
+def add_genre(q, name):
+ q.addBindValue(name)
+ q.exec_()
+ return q.lastInsertId()
+
+
+def add_author(q, name, birthdate):
+ q.addBindValue(name)
+ q.addBindValue(str(birthdate))
+ q.exec_()
+ return q.lastInsertId()
+
+BOOKS_SQL = """
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ """
+AUTHORS_SQL = """
+ create table authors(id integer primary key, name varchar, birthdate text)
+ """
+GENRES_SQL = """
+ create table genres(id integer primary key, name varchar)
+ """
+INSERT_AUTHOR_SQL = """
+ insert into authors(name, birthdate) values(?, ?)
+ """
+INSERT_GENRE_SQL = """
+ insert into genres(name) values(?)
+ """
+INSERT_BOOK_SQL = """
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ """
+
+def init_db():
+ """
+ init_db()
+ Initializes the database.
+ If tables "books" and "authors" are already in the database, do nothing.
+ Return value: None or raises ValueError
+ The error value is the QtSql error instance.
+ """
+ def check(func, *args):
+ if not func(*args):
+ raise ValueError(func.__self__.lastError())
+ db = QSqlDatabase.addDatabase("QSQLITE")
+ db.setDatabaseName(":memory:")
+
+ check(db.open)
+
+ q = QSqlQuery()
+ check(q.exec_, BOOKS_SQL)
+ check(q.exec_, AUTHORS_SQL)
+ check(q.exec_, GENRES_SQL)
+ check(q.prepare, INSERT_AUTHOR_SQL)
+
+ asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1))
+ greeneId = add_author(q, "Graham Greene", date(1904, 10, 2))
+ pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28))
+
+ check(q.prepare,INSERT_GENRE_SQL)
+ sfiction = add_genre(q, "Science Fiction")
+ fiction = add_genre(q, "Fiction")
+ fantasy = add_genre(q, "Fantasy")
+
+ check(q.prepare,INSERT_BOOK_SQL)
+ add_book(q, "Foundation", 1951, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4)
+ add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3)
+ add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4)
+ add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3)
+ add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3)
+ add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4)
+ add_book(q, "The Third Man", 1950, greeneId, fiction, 5)
+ add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4)
+ add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3)
+ add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3)
+ add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3)
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books.png b/sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books.png
new file mode 100644
index 000000000..e456b7d8f
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png b/sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png
new file mode 100644
index 000000000..82a5f449c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/images/star.png b/sources/pyside6/doc/tutorials/portingguide/chapter2/images/star.png
new file mode 100644
index 000000000..87f4464bd
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/images/star.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter2/main.py b/sources/pyside6/doc/tutorials/portingguide/chapter2/main.py
new file mode 100644
index 000000000..3cc55fa46
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter2/main.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import Qt
+from PySide6.QtSql import QSqlQueryModel
+from PySide6.QtWidgets import QTableView, QApplication
+
+import createdb
+from bookdelegate import BookDelegate
+
+if __name__ == "__main__":
+ app = QApplication()
+ createdb.init_db()
+
+ model = QSqlQueryModel()
+ model.setQuery("select title, author, genre, year, rating from books")
+
+ table = QTableView()
+ table.setModel(model)
+ table.setItemDelegate(BookDelegate())
+ table.resize(800, 600)
+ table.show()
+
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate-old.py b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate-old.py
new file mode 100644
index 000000000..b3187e054
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate-old.py
@@ -0,0 +1,101 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import copy
+import os
+from pathlib import Path
+
+from PySide6.QtSql import QSqlRelationalDelegate
+from PySide6.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate,
+ QStyle, QStyleOptionViewItem)
+from PySide6.QtGui import QMouseEvent, QPixmap, QPalette, QImage
+from PySide6.QtCore import QEvent, QSize, Qt, QUrl
+
+
+class BookDelegate(QSqlRelationalDelegate):
+ """Books delegate to rate the books"""
+
+ def __init__(self, star_png, parent=None):
+ QSqlRelationalDelegate.__init__(self, parent)
+ star_png = Path(__file__).parent / "images" / "star.png"
+ self.star = QPixmap(star_png)
+
+ def paint(self, painter, option, index):
+ """ Paint the items in the table.
+
+ If the item referred to by <index> is a StarRating, we
+ handle the painting ourselves. For the other items, we
+ let the base class handle the painting as usual.
+
+ In a polished application, we'd use a better check than
+ the column number to find out if we needed to paint the
+ stars, but it works for the purposes of this example.
+ """
+ if index.column() != 5:
+ # Since we draw the grid ourselves:
+ opt = copy.copy(option)
+ opt.rect = option.rect.adjusted(0, 0, -1, -1)
+ QSqlRelationalDelegate.paint(self, painter, opt, index)
+ else:
+ model = index.model()
+ if option.state & QStyle.State_Enabled:
+ if option.state & QStyle.State_Active:
+ color_group = QPalette.Normal
+ else:
+ color_group = QPalette.Inactive
+ else:
+ color_group = QPalette.Disabled
+
+ if option.state & QStyle.State_Selected:
+ painter.fillRect(option.rect,
+ option.palette.color(color_group, QPalette.Highlight))
+ rating = model.data(index, Qt.DisplayRole)
+ width = self.star.width()
+ height = self.star.height()
+ x = option.rect.x()
+ y = option.rect.y() + (option.rect.height() / 2) - (height / 2)
+ for i in range(rating):
+ painter.drawPixmap(x, y, self.star)
+ x += width
+
+ # Since we draw the grid ourselves:
+ self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1))
+
+ pen = painter.pen()
+ painter.setPen(option.palette.color(QPalette.Mid))
+ painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
+ painter.drawLine(option.rect.topRight(), option.rect.bottomRight())
+ painter.setPen(pen)
+
+ def sizeHint(self, option, index):
+ """ Returns the size needed to display the item in a QSize object. """
+ if index.column() == 5:
+ size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1)
+ return size_hint
+ # Since we draw the grid ourselves:
+ return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1)
+
+ def editorEvent(self, event, model, option, index):
+ if index.column() != 5:
+ return False
+
+ if event.type() == QEvent.MouseButtonPress:
+ mouse_pos = event.pos()
+ new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width())
+ stars = max(0, min(new_stars, 5))
+ model.setData(index, stars)
+ # So that the selection can change
+ return False
+
+ return True
+
+ def createEditor(self, parent, option, index):
+ if index.column() != 4:
+ return QSqlRelationalDelegate.createEditor(self, parent, option, index)
+
+ # For editing the year, return a spinbox with a range from -1000 to 2100.
+ spinbox = QSpinBox(parent)
+ spinbox.setFrame(False)
+ spinbox.setMaximum(2100)
+ spinbox.setMinimum(-1000)
+ return spinbox
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate.py b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate.py
new file mode 100644
index 000000000..145d6b73e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookdelegate.py
@@ -0,0 +1,96 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import copy, os
+from PySide6.QtSql import QSqlRelationalDelegate
+from PySide6.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate,
+ QStyle, QStyleOptionViewItem)
+from PySide6.QtGui import QMouseEvent, QPixmap, QPalette, QImage
+from PySide6.QtCore import QEvent, QSize, Qt, QUrl
+
+class BookDelegate(QSqlRelationalDelegate):
+ """Books delegate to rate the books"""
+
+ def __init__(self, star_png, parent=None):
+ QSqlRelationalDelegate.__init__(self, parent)
+ self.star = QPixmap(":/images/star.png")
+
+ def paint(self, painter, option, index):
+ """ Paint the items in the table.
+
+ If the item referred to by <index> is a StarRating, we
+ handle the painting ourselves. For the other items, we
+ let the base class handle the painting as usual.
+
+ In a polished application, we'd use a better check than
+ the column number to find out if we needed to paint the
+ stars, but it works for the purposes of this example.
+ """
+ if index.column() != 5:
+ # Since we draw the grid ourselves:
+ opt = copy.copy(option)
+ opt.rect = option.rect.adjusted(0, 0, -1, -1)
+ QSqlRelationalDelegate.paint(self, painter, opt, index)
+ else:
+ model = index.model()
+ if option.state & QStyle.State_Enabled:
+ if option.state & QStyle.State_Active:
+ color_group = QPalette.Normal
+ else:
+ color_group = QPalette.Inactive
+ else:
+ color_group = QPalette.Disabled
+
+ if option.state & QStyle.State_Selected:
+ painter.fillRect(option.rect,
+ option.palette.color(color_group, QPalette.Highlight))
+ rating = model.data(index, Qt.DisplayRole)
+ width = self.star.width()
+ height = self.star.height()
+ x = option.rect.x()
+ y = option.rect.y() + (option.rect.height() / 2) - (height / 2)
+ for i in range(rating):
+ painter.drawPixmap(x, y, self.star)
+ x += width
+
+ # Since we draw the grid ourselves:
+ self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1))
+
+ pen = painter.pen()
+ painter.setPen(option.palette.color(QPalette.Mid))
+ painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
+ painter.drawLine(option.rect.topRight(), option.rect.bottomRight())
+ painter.setPen(pen)
+
+ def sizeHint(self, option, index):
+ """ Returns the size needed to display the item in a QSize object. """
+ if index.column() == 5:
+ size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1)
+ return size_hint
+ # Since we draw the grid ourselves:
+ return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1)
+
+ def editorEvent(self, event, model, option, index):
+ if index.column() != 5:
+ return False
+
+ if event.type() == QEvent.MouseButtonPress:
+ mouse_pos = event.pos()
+ new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width())
+ stars = max(0, min(new_stars, 5))
+ model.setData(index, stars)
+ # So that the selection can change
+ return False
+
+ return True
+
+ def createEditor(self, parent, option, index):
+ if index.column() != 4:
+ return QSqlRelationalDelegate.createEditor(self, parent, option, index)
+
+ # For editing the year, return a spinbox with a range from -1000 to 2100.
+ spinbox = QSpinBox(parent)
+ spinbox.setFrame(False)
+ spinbox.setMaximum(2100)
+ spinbox.setMinimum(-1000)
+ return spinbox
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/books.qrc b/sources/pyside6/doc/tutorials/portingguide/chapter3/books.qrc
new file mode 100644
index 000000000..d6ad21337
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/books.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/star.png</file>
+</qresource>
+</RCC>
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.cpp b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.cpp
new file mode 100644
index 000000000..6ec1b9e19
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.cpp
@@ -0,0 +1,124 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "bookwindow.h"
+#include "bookdelegate.h"
+#include "initdb.h"
+
+#include <QtSql>
+
+BookWindow::BookWindow()
+{
+ ui.setupUi(this);
+
+ if (!QSqlDatabase::drivers().contains("QSQLITE"))
+ QMessageBox::critical(
+ this,
+ "Unable to load database",
+ "This demo needs the SQLITE driver"
+ );
+
+ // Initialize the database:
+ QSqlError err = initDb();
+ if (err.type() != QSqlError::NoError) {
+ showError(err);
+ return;
+ }
+
+ // Create the data model:
+ model = new QSqlRelationalTableModel(ui.bookTable);
+ model->setEditStrategy(QSqlTableModel::OnManualSubmit);
+ model->setTable("books");
+
+ // Remember the indexes of the columns:
+ authorIdx = model->fieldIndex("author");
+ genreIdx = model->fieldIndex("genre");
+
+ // Set the relations to the other database tables:
+ model->setRelation(authorIdx, QSqlRelation("authors", "id", "name"));
+ model->setRelation(genreIdx, QSqlRelation("genres", "id", "name"));
+
+ // Set the localized header captions:
+ model->setHeaderData(authorIdx, Qt::Horizontal, tr("Author Name"));
+ model->setHeaderData(genreIdx, Qt::Horizontal, tr("Genre"));
+ model->setHeaderData(model->fieldIndex("title"),
+ Qt::Horizontal, tr("Title"));
+ model->setHeaderData(model->fieldIndex("year"), Qt::Horizontal, tr("Year"));
+ model->setHeaderData(model->fieldIndex("rating"),
+ Qt::Horizontal, tr("Rating"));
+
+ // Populate the model:
+ if (!model->select()) {
+ showError(model->lastError());
+ return;
+ }
+
+ // Set the model and hide the ID column:
+ ui.bookTable->setModel(model);
+ ui.bookTable->setItemDelegate(new BookDelegate(ui.bookTable));
+ ui.bookTable->setColumnHidden(model->fieldIndex("id"), true);
+ ui.bookTable->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // Initialize the Author combo box:
+ ui.authorEdit->setModel(model->relationModel(authorIdx));
+ ui.authorEdit->setModelColumn(
+ model->relationModel(authorIdx)->fieldIndex("name"));
+
+ ui.genreEdit->setModel(model->relationModel(genreIdx));
+ ui.genreEdit->setModelColumn(
+ model->relationModel(genreIdx)->fieldIndex("name"));
+
+ // Lock and prohibit resizing of the width of the rating column:
+ ui.bookTable->horizontalHeader()->setSectionResizeMode(
+ model->fieldIndex("rating"),
+ QHeaderView::ResizeToContents);
+
+ QDataWidgetMapper *mapper = new QDataWidgetMapper(this);
+ mapper->setModel(model);
+ mapper->setItemDelegate(new BookDelegate(this));
+ mapper->addMapping(ui.titleEdit, model->fieldIndex("title"));
+ mapper->addMapping(ui.yearEdit, model->fieldIndex("year"));
+ mapper->addMapping(ui.authorEdit, authorIdx);
+ mapper->addMapping(ui.genreEdit, genreIdx);
+ mapper->addMapping(ui.ratingEdit, model->fieldIndex("rating"));
+
+ connect(ui.bookTable->selectionModel(),
+ &QItemSelectionModel::currentRowChanged,
+ mapper,
+ &QDataWidgetMapper::setCurrentModelIndex
+ );
+
+ ui.bookTable->setCurrentIndex(model->index(0, 0));
+ createMenuBar();
+}
+
+void BookWindow::showError(const QSqlError &err)
+{
+ QMessageBox::critical(this, "Unable to initialize Database",
+ "Error initializing database: " + err.text());
+}
+
+void BookWindow::createMenuBar()
+{
+ QAction *quitAction = new QAction(tr("&Quit"), this);
+ QAction *aboutAction = new QAction(tr("&About"), this);
+ QAction *aboutQtAction = new QAction(tr("&About Qt"), this);
+
+ QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+ fileMenu->addAction(quitAction);
+
+ QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+ helpMenu->addAction(aboutAction);
+ helpMenu->addAction(aboutQtAction);
+
+ connect(quitAction, &QAction::triggered, this, &BookWindow::close);
+ connect(aboutAction, &QAction::triggered, this, &BookWindow::about);
+ connect(aboutQtAction, &QAction::triggered, qApp, &QApplication::aboutQt);
+}
+
+void BookWindow::about()
+{
+ QMessageBox::about(this, tr("About Books"),
+ tr("<p>The <b>Books</b> example shows how to use Qt SQL classes "
+ "with a model/view framework."));
+}
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.py b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.py
new file mode 100644
index 000000000..bb033c6d2
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.py
@@ -0,0 +1,99 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtGui import QAction
+from PySide6.QtWidgets import (QAbstractItemView, QDataWidgetMapper,
+ QHeaderView, QMainWindow, QMessageBox)
+from PySide6.QtGui import QKeySequence
+from PySide6.QtSql import (QSqlRelation, QSqlRelationalTableModel, QSqlTableModel,
+ QSqlError)
+from PySide6.QtCore import QAbstractItemModel, QObject, QSize, Qt, Slot
+import createdb
+from ui_bookwindow import Ui_BookWindow
+from bookdelegate import BookDelegate
+
+
+class BookWindow(QMainWindow, Ui_BookWindow):
+ # """A window to show the books available"""
+
+ def __init__(self):
+ QMainWindow.__init__(self)
+ self.setupUi(self)
+
+ #Initialize db
+ createdb.init_db()
+
+ model = QSqlRelationalTableModel(self.bookTable)
+ model.setEditStrategy(QSqlTableModel.OnManualSubmit)
+ model.setTable("books")
+
+ # Remember the indexes of the columns:
+ author_idx = model.fieldIndex("author")
+ genre_idx = model.fieldIndex("genre")
+
+ # Set the relations to the other database tables:
+ model.setRelation(author_idx, QSqlRelation("authors", "id", "name"))
+ model.setRelation(genre_idx, QSqlRelation("genres", "id", "name"))
+
+ # Set the localized header captions:
+ model.setHeaderData(author_idx, Qt.Horizontal, self.tr("Author Name"))
+ model.setHeaderData(genre_idx, Qt.Horizontal, self.tr("Genre"))
+ model.setHeaderData(model.fieldIndex("title"), Qt.Horizontal, self.tr("Title"))
+ model.setHeaderData(model.fieldIndex("year"), Qt.Horizontal, self.tr("Year"))
+ model.setHeaderData(model.fieldIndex("rating"), Qt.Horizontal, self.tr("Rating"))
+
+ if not model.select():
+ print(model.lastError())
+
+ # Set the model and hide the ID column:
+ self.bookTable.setModel(model)
+ self.bookTable.setItemDelegate(BookDelegate(self.bookTable))
+ self.bookTable.setColumnHidden(model.fieldIndex("id"), True)
+ self.bookTable.setSelectionMode(QAbstractItemView.SingleSelection)
+
+ # Initialize the Author combo box:
+ self.authorEdit.setModel(model.relationModel(author_idx))
+ self.authorEdit.setModelColumn(model.relationModel(author_idx).fieldIndex("name"))
+
+ self.genreEdit.setModel(model.relationModel(genre_idx))
+ self.genreEdit.setModelColumn(model.relationModel(genre_idx).fieldIndex("name"))
+
+ # Lock and prohibit resizing of the width of the rating column:
+ self.bookTable.horizontalHeader().setSectionResizeMode(model.fieldIndex("rating"),
+ QHeaderView.ResizeToContents)
+
+ mapper = QDataWidgetMapper(self)
+ mapper.setModel(model)
+ mapper.setItemDelegate(BookDelegate(self))
+ mapper.addMapping(self.titleEdit, model.fieldIndex("title"))
+ mapper.addMapping(self.yearEdit, model.fieldIndex("year"))
+ mapper.addMapping(self.authorEdit, author_idx)
+ mapper.addMapping(self.genreEdit, genre_idx)
+ mapper.addMapping(self.ratingEdit, model.fieldIndex("rating"))
+
+ selection_model = self.bookTable.selectionModel()
+ selection_model.currentRowChanged.connect(mapper.setCurrentModelIndex)
+
+ self.bookTable.setCurrentIndex(model.index(0, 0))
+ self.create_menubar()
+
+ def showError(err):
+ QMessageBox.critical(self, "Unable to initialize Database",
+ "Error initializing database: " + err.text())
+
+ def create_menubar(self):
+ file_menu = self.menuBar().addMenu(self.tr("&File"))
+ quit_action = file_menu.addAction(self.tr("&Quit"))
+ quit_action.triggered.connect(qApp.quit)
+
+ help_menu = self.menuBar().addMenu(self.tr("&Help"))
+ about_action = help_menu.addAction(self.tr("&About"))
+ about_action.setShortcut(QKeySequence.HelpContents)
+ about_action.triggered.connect(self.about)
+ aboutQt_action = help_menu.addAction("&About Qt")
+ aboutQt_action.triggered.connect(qApp.aboutQt)
+
+ def about(self):
+ QMessageBox.about(self, self.tr("About Books"),
+ self.tr("<p>The <b>Books</b> example shows how to use Qt SQL classes "
+ "with a model/view framework."))
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.ui b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.ui
new file mode 100644
index 000000000..e1668288f
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/bookwindow.ui
@@ -0,0 +1,149 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>BookWindow</class>
+ <widget class="QMainWindow" name="BookWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>601</width>
+ <height>420</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Books</string>
+ </property>
+ <widget class="QWidget" name="centralWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Books</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTableView" name="bookTable" >
+ <property name="selectionBehavior" >
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Details</string>
+ </property>
+ <layout class="QFormLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>&lt;b>Title:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="titleEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2_2_2_2" >
+ <property name="text" >
+ <string>&lt;b>Author: &lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="authorEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>&lt;b>Genre:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QComboBox" name="genreEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>&lt;b>Year:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSpinBox" name="yearEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="prefix" >
+ <string/>
+ </property>
+ <property name="maximum" >
+ <number>2100</number>
+ </property>
+ <property name="minimum" >
+ <number>-1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>&lt;b>Rating:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QSpinBox" name="ratingEdit" >
+ <property name="maximum" >
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <tabstops>
+ <tabstop>bookTable</tabstop>
+ <tabstop>titleEdit</tabstop>
+ <tabstop>authorEdit</tabstop>
+ <tabstop>genreEdit</tabstop>
+ <tabstop>yearEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/chapter3.rst b/sources/pyside6/doc/tutorials/portingguide/chapter3/chapter3.rst
new file mode 100644
index 000000000..98d4d3982
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/chapter3.rst
@@ -0,0 +1,121 @@
+Chapter 3: Port ``bookdwindow.cpp`` to ``bookwindow.py``
+*********************************************************
+
+After the bookdelegate, port the C++ code for the
+``BookWindow`` class. It offers a QMainWindow, containing a
+``QTableView`` to present the books data, and a **Details**
+section with a set of input fields to edit the selected row
+in the table. To begin with, create the ``bookwindow.py``
+and add the following imports to it:
+
+.. literalinclude:: bookwindow.py
+ :language: python
+ :linenos:
+ :lines: 3-16
+
+.. note:: The imports include the ``BookDelegate`` you
+ ported earlier and the ``Ui_BookWindow``. The pyside-uic
+ tool generates the ``ui_bookwindow`` Python code based
+ on the ``bookwindow.ui`` XML file.
+
+To generate this Python code, run the following command on the
+prompt:
+
+.. code-block:: bash
+
+ pyside6-uic bookwindow.ui -o ui_bookwindow.py
+
+Try porting the remaining code now. To begin with, here is
+how both the versions of the constructor code looks:
+
+C++ version
+------------
+
+.. literalinclude:: bookwindow.cpp
+ :language: c++
+ :linenos:
+ :lines: 20-103
+
+Python version
+---------------
+
+.. literalinclude:: bookwindow.py
+ :language: python
+ :linenos:
+ :lines: 16-79
+
+.. note:: The Python version of the ``BookWindow`` class
+ definition inherits from both ``QMainWindow`` and
+ ``Ui_BookWindow``, which is defined in the
+ ``ui_bookwindow.py`` file that you generated earlier.
+
+Here is how the rest of the code looks like:
+
+C++ version
+------------
+
+.. literalinclude:: bookwindow.cpp
+ :language: c++
+ :linenos:
+ :lines: 78-
+
+Python version
+---------------
+
+.. literalinclude:: bookwindow.py
+ :language: python
+ :linenos:
+ :lines: 80-
+
+Now that all the necessary pieces are in place, try to put
+them together in ``main.py``.
+
+.. literalinclude:: main.py
+ :language: python
+ :linenos:
+ :lines: 3-
+
+Try running this to see if you get the following output:
+
+.. image:: images/chapter3-books.png
+ :alt: BookWindow with a QTableView and a few input fields
+
+Now, if you look back at :doc:`chapter2 <../chapter2/chapter2>`,
+you'll notice that the ``bookdelegate.py`` loads the
+``star.png`` from the filesytem. Instead, you could add it
+to a ``qrc`` file, and load from it. The later approach is
+rececommended if your application is targeted for
+different platforms, as most of the popular platforms
+employ stricter file access policy these days.
+
+To add the ``star.png`` to a ``.qrc``, create a file called
+``books.qrc`` and the following XML content to it:
+
+.. literalinclude:: books.qrc
+ :linenos:
+
+This is a simple XML file defining a list all resources that
+your application needs. In this case, it is the ``star.png``
+image only.
+
+Now, run the ``pyside6-rcc`` tool on the ``books.qrc`` file
+to generate ``rc_books.py``.
+
+.. code-block:: bash
+
+ pyside6-rcc books.qrc -o rc_books.py
+
+Once you have the Python script generated, make the
+following changes to ``bookdelegate.py`` and ``main.py``:
+
+.. literalinclude:: bookdelegate.py
+ :diff: ../chapter2/bookdelegate.py
+
+.. literalinclude:: main.py
+ :diff: main-old.py
+
+Although there will be no noticeable difference in the UI
+after these changes, using a ``.qrc`` is a better approach.
+
+Now that you have successfully ported the SQL Books example,
+you know how easy it is. Try porting another C++ application.
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/createdb.py b/sources/pyside6/doc/tutorials/portingguide/chapter3/createdb.py
new file mode 100644
index 000000000..da7d201a8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/createdb.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from datetime import date
+
+
+def add_book(q, title, year, authorId, genreId, rating):
+ q.addBindValue(title)
+ q.addBindValue(year)
+ q.addBindValue(authorId)
+ q.addBindValue(genreId)
+ q.addBindValue(rating)
+ q.exec_()
+
+
+def add_genre(q, name):
+ q.addBindValue(name)
+ q.exec_()
+ return q.lastInsertId()
+
+
+def add_author(q, name, birthdate):
+ q.addBindValue(name)
+ q.addBindValue(str(birthdate))
+ q.exec_()
+ return q.lastInsertId()
+
+BOOKS_SQL = """
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ """
+AUTHORS_SQL = """
+ create table authors(id integer primary key, name varchar, birthdate text)
+ """
+GENRES_SQL = """
+ create table genres(id integer primary key, name varchar)
+ """
+INSERT_AUTHOR_SQL = """
+ insert into authors(name, birthdate) values(?, ?)
+ """
+INSERT_GENRE_SQL = """
+ insert into genres(name) values(?)
+ """
+INSERT_BOOK_SQL = """
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ """
+
+def init_db():
+ """
+ init_db()
+ Initializes the database.
+ If tables "books" and "authors" are already in the database, do nothing.
+ Return value: None or raises ValueError
+ The error value is the QtSql error instance.
+ """
+ def check(func, *args):
+ if not func(*args):
+ raise ValueError(func.__self__.lastError())
+ db = QSqlDatabase.addDatabase("QSQLITE")
+ db.setDatabaseName(":memory:")
+
+ check(db.open)
+
+ q = QSqlQuery()
+ check(q.exec_, BOOKS_SQL)
+ check(q.exec_, AUTHORS_SQL)
+ check(q.exec_, GENRES_SQL)
+ check(q.prepare, INSERT_AUTHOR_SQL)
+
+ asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1))
+ greeneId = add_author(q, "Graham Greene", date(1904, 10, 2))
+ pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28))
+
+ check(q.prepare,INSERT_GENRE_SQL)
+ sfiction = add_genre(q, "Science Fiction")
+ fiction = add_genre(q, "Fiction")
+ fantasy = add_genre(q, "Fantasy")
+
+ check(q.prepare,INSERT_BOOK_SQL)
+ add_book(q, "Foundation", 1951, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4)
+ add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3)
+ add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4)
+ add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3)
+ add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3)
+ add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4)
+ add_book(q, "The Third Man", 1950, greeneId, fiction, 5)
+ add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4)
+ add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3)
+ add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3)
+ add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3)
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/images/chapter3-books.png b/sources/pyside6/doc/tutorials/portingguide/chapter3/images/chapter3-books.png
new file mode 100644
index 000000000..952cb14e8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/images/chapter3-books.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/images/star.png b/sources/pyside6/doc/tutorials/portingguide/chapter3/images/star.png
new file mode 100644
index 000000000..87f4464bd
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/images/star.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/main-old.py b/sources/pyside6/doc/tutorials/portingguide/chapter3/main-old.py
new file mode 100644
index 000000000..164fc589a
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/main-old.py
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import QApplication
+from bookwindow import BookWindow
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ window = BookWindow()
+ window.resize(800, 600)
+ window.show()
+
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/portingguide/chapter3/main.py b/sources/pyside6/doc/tutorials/portingguide/chapter3/main.py
new file mode 100644
index 000000000..9a6575dc2
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/chapter3/main.py
@@ -0,0 +1,16 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from PySide6.QtWidgets import QApplication
+from bookwindow import BookWindow
+import rc_books
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ window = BookWindow()
+ window.resize(800, 600)
+ window.show()
+
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/portingguide/hello_world_ex.py b/sources/pyside6/doc/tutorials/portingguide/hello_world_ex.py
new file mode 100644
index 000000000..d67906fa7
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/hello_world_ex.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+import random
+
+from PySide6.QtWidgets import (QApplication, QLabel,
+ QPushButton, QVBoxLayout, QWidget)
+from PySide6.QtCore import Qt, Slot
+
+class MyWidget(QWidget):
+ def __init__(self):
+ super().__init__()
+
+ self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/portingguide/index.rst b/sources/pyside6/doc/tutorials/portingguide/index.rst
new file mode 100644
index 000000000..0b89c2ff8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/portingguide/index.rst
@@ -0,0 +1,194 @@
+Porting a C++ Application to Python
+*************************************
+
+Qt for Python lets you use Qt APIs in a Python application.
+So the next question is: What does it take to port an
+existing C++ application? Try porting a Qt C++ application
+to Python to understand this.
+
+Before you start, ensure that all the prerequisites for
+Qt for Python are met. See
+:doc:`Getting Started <../../gettingstarted/index>` for more
+information. In addition, familiarize yourself with the
+basic differences between Qt in C++ and in Python.
+
+Basic differences
+==================
+
+This section highlights some of the basic differences
+between C++ and Python, and how Qt differs between these
+two contexts.
+
+C++ vs Python
+--------------
+
+* In the interest of code reuse, both C++ and Python
+ provide ways for one file of code to use facilities
+ provided by another. In C++, this is done using the
+ ``#include`` directive to access the API definition of
+ the reused code. The Python equivalent is an ``import``
+ statement.
+* The constructor of a C++ class shares the name of its
+ class and automatically calls the constructor of any
+ base-classes (in a predefined order) before it runs.
+ In Python, the ``__init__()`` method is the constructor
+ of the class, and it can explicitly call base-class
+ constructors in any order.
+* C++ uses the keyword, ``this``, to implicitly refer to
+ the current object. In python, you need to explicitly
+ mention the current object as the first parameter
+ to each instance method of the class; it is conventionally
+ named ``self``.
+* And more importantly, forget about curly braces, {}, and
+ semi-colon, ;.
+* Precede variable definitions with the ``global`` keyword,
+ only if they need global scope.
+
+.. code:: python
+
+ var = None
+ def func(key, value = None):
+ """Does stuff with a key and an optional value.
+
+ If value is omitted or None, the value from func()'s
+ last call is reused.
+ """
+ global var
+ if value is None:
+ if var is None:
+ raise ValueError("Must pass a value on first call", key, value)
+ value = var
+ else:
+ var = value
+ doStuff(key, value)
+
+In this example, ``func()`` would treat ``var`` as a local
+name without the ``global`` statement. This would lead to
+a ``NameError`` in the ``value is None`` handling, on
+accessing ``var``. For more information about this, see
+`Python refernce documentation <python refdoc>`_.
+
+.. _python refdoc: https://docs.python.org/3/reference/simple_stmts.html#the-global-statement
+
+.. tip:: Python being an interpreted language, most often
+ the easiest way is to try your idea in the interperter.
+ You could call the ``help()`` function in the
+ interpreter on any built-in function or keyword in
+ Python. For example, a call to ``help(import)`` should
+ provide documentation about the ``import`` statment
+
+Last but not the least, try out a few examples to
+familiarize yourself with the Python coding style and
+follow the guidelines outlined in the
+`PEP8 - Style Guide <pep8>`_.
+
+.. _pep8: <https://www.python.org/dev/peps/pep-0008/#naming-conventions>
+
+.. code-block:: python
+
+ import sys
+
+ from PySide6.QtWidgets import QApplication, QLabel
+
+ app = QApplication(sys.argv)
+ label = QLabel("Hello World")
+ label.show()
+ sys.exit(app.exec())
+
+.. note:: Qt provides classes that are meant to manage
+ the application-specific requirements depending on
+ whether the application is console-only
+ (QCoreApplication), GUI with QtWidgets (QApplication),
+ or GUI without QtWidgets (QGuiApplication). These
+ classes load necessary plugins, such as the GUI
+ libraries required by an application. In this case, it is
+ QApplication that is initialized first as the application
+ has a GUI with QtWidgets.
+
+Qt in the C++ and Python context
+---------------------------------
+
+Qt behaves the same irrespective of whether it is used
+in a C++ or a Python application. Considering that C++
+and Python use different language semantics, some
+differences between the two variants of Qt are inevitable.
+Here are a few important ones that you must be aware of:
+
+* **Qt Properties**: ``Q_PROPERTY`` macros are used in C++ to add a
+ public member variable with getter and setter functions. Python's
+ alternative for this is the ``@property`` decorator before the
+ getter and setter function definitions.
+* **Qt Signals and Slots**: Qt offers a unique callback mechanism,
+ where a signal is emitted to notify the occurrence of an event, so
+ that slots connected to this signal can react to it. In C++,
+ the class definition must define the slots under the
+ ``public Q_SLOTS:`` and signals under ``Q_SIGNALS:``
+ access specifier. You connect these two using one of the
+ several variants of the QObject::connect() function. Python's
+ equivalent for this is the `@Slot`` decorator just before the
+ function definition. This is necessary to register the slots
+ with the QtMetaObject.
+* **QString, QVariant, and other types**
+
+ - Qt for Python does not provide access to QString and
+ QVariant. You must use Python's native types instead.
+ - QChar and QStringRef are represented as Python strings,
+ and QStringList is converted to a list of strings.
+ - QDate, QDateTime, QTime, and QUrl's __hash__() methods
+ return a string representation so that identical dates
+ (and identical date/times or times or URLs) have
+ identical hash values.
+ - QTextStream's bin(), hex(), and oct() functions are
+ renamed to bin_(), hex_(), and oct_() respectively. This
+ should avoid name conflicts with Python's built-in
+ functions.
+
+* **QByteArray**: A QByteArray is treated as a list of
+ bytes without encoding. Python 3 uses
+ "bytes". QString is represented as an encoded human readable string,
+ which means it is a "str".
+
+Here is the improved version of the Hello World example,
+demonstrating some of these differences:
+
+.. literalinclude:: hello_world_ex.py
+ :linenos:
+ :lines: 3-
+
+.. note:: The ``if`` block is just a good practice when
+ developing a Python application. It lets the Python file
+ behave differently depending on whether it is imported
+ as a module in another file or run directly. The
+ ``__name__`` variable will have different values in
+ these two scenarios. It is ``__main__`` when the file is
+ run directly, and the module's file name
+ (``hello_world_ex`` in this case) when imported as a
+ module. In the later case, everything defined in the
+ module except the ``if`` block is available to the
+ importing file.
+
+Notice that the QPushButton's ``clicked`` signal is
+connected to the ``magic`` function to randomly change the
+QLabel's ``text`` property. The `@Slot`` decorator marks
+the methods that are slots and informs the QtMetaObject about
+them.
+
+Porting a Qt C++ example
+=========================
+
+Qt offers several C++ examples to showcase its features and help
+beginners learn. You can try porting one of these C++ examples to
+Python. The
+`books SQL example <https://code.qt.io/cgit/qt/qtbase.git/tree/examples/sql/books>`_
+is a good starting point as it does not require you to write UI-specific code in
+Python, but can use its ``.ui`` file instead.
+
+The following chapters guides you through the porting process:
+
+.. toctree::
+ :glob:
+ :titlesonly:
+
+ chapter1/chapter1
+ chapter2/chapter2
+ chapter3/chapter3
diff --git a/sources/pyside6/doc/tutorials/qmlapp/logo.png b/sources/pyside6/doc/tutorials/qmlapp/logo.png
new file mode 100644
index 000000000..30c621c9c
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/logo.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlapp/main.py b/sources/pyside6/doc/tutorials/qmlapp/main.py
new file mode 100644
index 000000000..8b1b25440
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/main.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+import urllib.request
+import json
+from pathlib import Path
+
+from PySide6.QtQuick import QQuickView
+from PySide6.QtCore import QStringListModel, QUrl
+from PySide6.QtGui import QGuiApplication
+
+
+if __name__ == '__main__':
+
+ #get our data
+ url = "http://country.io/names.json"
+ response = urllib.request.urlopen(url)
+ data = json.loads(response.read().decode('utf-8'))
+
+ #Format and sort the data
+ data_list = list(data.values())
+ data_list.sort()
+
+ #Set up the application window
+ app = QGuiApplication(sys.argv)
+ view = QQuickView()
+ view.setResizeMode(QQuickView.SizeRootObjectToView)
+
+ #Expose the list to the Qml code
+ my_model = QStringListModel()
+ my_model.setStringList(data_list)
+ view.setInitialProperties({"myModel": my_model})
+
+ #Load the QML file
+ qml_file = Path(__file__).parent / "view.qml"
+ view.setSource(QUrl.fromLocalFile(qml_file.resolve()))
+
+ #Show the window
+ if view.status() == QQuickView.Error:
+ sys.exit(-1)
+ view.show()
+
+ #execute and cleanup
+ app.exec()
+ del view
diff --git a/sources/pyside6/doc/tutorials/qmlapp/newpyproject.png b/sources/pyside6/doc/tutorials/qmlapp/newpyproject.png
new file mode 100644
index 000000000..93968a52d
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/newpyproject.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlapp/projectsmode.png b/sources/pyside6/doc/tutorials/qmlapp/projectsmode.png
new file mode 100644
index 000000000..c66d88723
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/projectsmode.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlapp/pyprojname.png b/sources/pyside6/doc/tutorials/qmlapp/pyprojname.png
new file mode 100644
index 000000000..98328074d
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/pyprojname.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlapp/pyprojxplor.png b/sources/pyside6/doc/tutorials/qmlapp/pyprojxplor.png
new file mode 100644
index 000000000..e01e2ebeb
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/pyprojxplor.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.png b/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.png
new file mode 100644
index 000000000..ec0ad3dea
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst b/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst
new file mode 100644
index 000000000..c6d72e742
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst
@@ -0,0 +1,132 @@
+#########################
+QML Application Tutorial
+#########################
+
+This tutorial provides a quick walk-through of a python application
+that loads a QML file. QML is a declarative language that lets you
+design UIs faster than a traditional language, such as C++. The
+QtQml and QtQuick modules provides the necessary infrastructure for
+QML-based UIs.
+
+In this tutorial, you'll also learn how to provide data from Python
+as a QML initial property, which is then consumed by the ListView
+defined in the QML file.
+
+Before you begin, install the following prerequisites:
+
+* The `PySide6 <https://pypi.org/project/PySide6/>`_ Python packages.
+* *Qt Creator* from
+ `https://download.qt.io
+ <https://download.qt.io/snapshots/qtcreator/>`_.
+
+
+The following step-by-step instructions guide you through application
+development process using *Qt Creator*:
+
+#. Open *Qt Creator* and select **File > New File or Project..** menu item
+ to open following dialog:
+
+ .. image:: newpyproject.png
+
+#. Select **Qt for Python - Empty** from the list of application templates
+ and select **Choose**.
+
+ .. image:: pyprojname.png
+
+#. Give a **Name** to your project, choose its location in the
+ filesystem, and select **Finish** to create an empty ``main.py``
+ and ``main.pyproject``.
+
+ .. image:: pyprojxplor.png
+
+ This should create a ``main.py`` and ```main.pyproject`` files
+ for the project.
+
+#. Download :download:`view.qml<view.qml>` and :download:`logo.png <logo.png>`
+ and move them to your project folder.
+
+#. Double-click on ``main.pyproject`` to open it in edit mode, and append
+ ``view.qml`` and ``logo.png`` to the **files** list. This is how your
+ project file should look after this change:
+
+ .. code::
+
+ {
+ "files": ["main.py", "view.qml", "logo.png"]
+ }
+
+#. Now that you have the necessary bits for the application, import the
+ Python modules in your ``main.py``, and download country data and
+ format it:
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 3-23
+ :emphasize-lines: 7-9,14-17
+
+#. Now, set up the application window using
+ :ref:`PySide6.QtGui.QGuiApplication<qguiapplication>`, which manages the application-wide
+ settings.
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 3-28
+ :emphasize-lines: 23-25
+
+ .. note:: Setting the resize policy is important if you want the
+ root item to resize itself to fit the window or vice-a-versa.
+ Otherwise, the root item will retain its original size on
+ resizing the window.
+
+#. You can now expose the ``data_list`` variable as a QML initial
+ property, which will be consumed by the QML ListView item in ``view.qml``.
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 3-33
+ :emphasize-lines: 28-31
+
+#. Load the ``view.qml`` to the ``QQuickView`` and call ``show()`` to
+ display the application window.
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 3-42
+ :emphasize-lines: 33-40
+
+#. Finally, execute the application to start the event loop and clean up.
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 3-
+ :emphasize-lines: 42-44
+
+#. Your application is ready to be run now. Select **Projects** mode to
+ choose the Python version to run it.
+
+ .. image:: projectsmode.png
+
+Run the application by using the ``CTRL+R`` keyboard shortcut to see if it
+looks like this:
+
+.. image:: qmlapplication.png
+
+You could also watch the following video tutorial for guidance to develop
+this application:
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/JxfiUx60Mbg" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>
+
+********************
+Related information
+********************
+
+* `QML Reference <https://doc.qt.io/qt-5/qmlreference.html>`_
+* :doc:`../qmlintegration/qmlintegration`
diff --git a/sources/pyside6/doc/tutorials/qmlapp/view.qml b/sources/pyside6/doc/tutorials/qmlapp/view.qml
new file mode 100644
index 000000000..7f9b1d777
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlapp/view.qml
@@ -0,0 +1,56 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick 2.12
+import QtQuick.Controls 2.12
+
+Page {
+ width: 640
+ height: 480
+ required property var myModel
+
+ header: Label {
+ color: "#15af15"
+ text: qsTr("Where do people use Qt?")
+ font.pointSize: 17
+ font.bold: true
+ font.family: "Arial"
+ renderType: Text.NativeRendering
+ horizontalAlignment: Text.AlignHCenter
+ padding: 10
+ }
+ Rectangle {
+ id: root
+ width: parent.width
+ height: parent.height
+
+ Image {
+ id: image
+ fillMode: Image.PreserveAspectFit
+ anchors.centerIn: root
+ source: "./logo.png"
+ opacity: 0.5
+
+ }
+
+ ListView {
+ id: view
+ anchors.fill: root
+ anchors.margins: 25
+ model: myModel
+ delegate: Text {
+ anchors.leftMargin: 50
+ font.pointSize: 15
+ horizontalAlignment: Text.AlignHCenter
+ text: display
+ }
+ }
+ }
+ NumberAnimation {
+ id: anim
+ running: true
+ target: view
+ property: "contentY"
+ duration: 500
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/qmlintegration/main.py b/sources/pyside6/doc/tutorials/qmlintegration/main.py
new file mode 100644
index 000000000..0a751d7d1
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlintegration/main.py
@@ -0,0 +1,77 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from pathlib import Path
+
+from PySide6.QtCore import QObject, Slot
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import QQmlApplicationEngine, QmlElement
+from PySide6.QtQuickControls2 import QQuickStyle
+
+import style_rc
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "io.qt.textproperties"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class Bridge(QObject):
+
+ @Slot(str, result=str)
+ def getColor(self, s):
+ if s.lower() == "red":
+ return "#ef9a9a"
+ elif s.lower() == "green":
+ return "#a5d6a7"
+ elif s.lower() == "blue":
+ return "#90caf9"
+ else:
+ return "white"
+
+ @Slot(float, result=int)
+ def getSize(self, s):
+ size = int(s * 34)
+ if size <= 0:
+ return 1
+ else:
+ return size
+
+ @Slot(str, result=bool)
+ def getItalic(self, s):
+ if s.lower() == "italic":
+ return True
+ else:
+ return False
+
+ @Slot(str, result=bool)
+ def getBold(self, s):
+ if s.lower() == "bold":
+ return True
+ else:
+ return False
+
+ @Slot(str, result=bool)
+ def getUnderline(self, s):
+ if s.lower() == "underline":
+ return True
+ else:
+ return False
+
+
+if __name__ == '__main__':
+ app = QGuiApplication(sys.argv)
+ QQuickStyle.setStyle("Material")
+ engine = QQmlApplicationEngine()
+
+ # Get the path of the current directory, and then add the name
+ # of the QML file, to load it.
+ qml_file = Path(__file__).parent / 'view.qml'
+ engine.load(qml_file)
+
+ if not engine.rootObjects():
+ sys.exit(-1)
+
+ sys.exit(app.exec())
diff --git a/sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst b/sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst
new file mode 100644
index 000000000..ff6fe3e31
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst
@@ -0,0 +1,128 @@
+Python-QML integration
+======================
+
+This tutorial provides a quick walk-through of a python application that loads, and interacts with
+a QML file. QML is a declarative language that lets you design UIs faster than a traditional
+language, such as C++. The QtQml and QtQuick modules provides the necessary infrastructure for
+QML-based UIs.
+
+In this tutorial, you will learn how to integrate Python with a QML application.
+This mechanism will help us to understand how to use Python as a backend for certain
+signals from the UI elements in the QML interface. Additionally, you will learn how to provide
+a modern look to your QML application using one of the features from Qt Quick Controls 2.
+
+The tutorial is based on an application that allow you to set many text properties, like increasing
+the font size, changing the color, changing the style, and so on. Before you begin, install the
+`PySide6 <https://pypi.org/project/PySide6/>`_ Python packages.
+
+The following step-by-step process will guide you through the key elements of the QML based
+application and PySide6 integration:
+
+#. First, let's start with the following QML-based UI:
+
+ .. image:: textproperties_default.png
+
+ The design is based on a `GridLayout`, containing two `ColumnLayout`.
+ Inside the UI you will find many `RadioButton`, `Button`, and a `Slider`.
+
+#. With the QML file in place, you can load it from Python:
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 63-76
+ :emphasize-lines: 4,9
+
+ Notice that we only need a :code:`QQmlApplicationEngine` to
+ :code:`load` the QML file.
+
+#. Define the ``Bridge`` class, containing all the logic for the element
+ that will be register in QML:
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 14-54
+ :emphasize-lines: 3,4,7
+
+ Notice that the registration happens thanks to the :code:`QmlElement`
+ decorator, that underneath uses the reference to the :code:`Bridge`
+ class and the variables :code:`QML_IMPORT_NAME` and
+ :code:`QML_IMPORT_MAJOR_VERSION`.
+
+#. Now, go back to the QML file and connect the signals to the slots defined in the ``Bridge`` class:
+
+ .. code:: js
+
+ Bridge {
+ id: bridge
+ }
+
+ Inside the :code:`ApplicationWindow` we declare a component
+ with the same name as the Python class, and provide an :code:`id:`.
+ This :code:`id` will help you to get a reference to the element
+ that was registered from Python.
+
+ .. literalinclude:: view.qml
+ :linenos:
+ :lines: 45-55
+ :emphasize-lines: 6-8
+
+ The properties *Italic*, *Bold*, and *Underline* are mutually
+ exclusive, this means only one can be active at any time.
+ To achieve this each time we select one of these options, we
+ check the three properties via the QML element property as you can
+ see in the above snippet.
+ Only one of the three will return *True*, while the other two
+ will return *False*, that is how we make sure only one is being
+ applied to the text.
+
+#. Each slot verifies if the selected option contains the text associated
+ to the property:
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 42-47
+ :emphasize-lines: 4,6
+
+ Returning *True* or *False* allows you to activate and deactivate
+ the properties of the QML UI elements.
+
+ It is also possible to return other values that are not *Boolean*,
+ like the slot in charge of returning the font size:
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 34-39
+
+#. Now, for changing the look of our application, you have two options:
+
+ 1. Use the command line: execute the python file adding the option, ``--style``::
+
+ python main.py --style material
+
+ 2. Use a ``qtquickcontrols2.conf`` file:
+
+ .. literalinclude:: qtquickcontrols2.conf
+ :linenos:
+
+ Then add it to your ``.qrc`` file:
+
+ .. literalinclude:: style.qrc
+ :linenos:
+
+ Generate the *rc* file running, ``pyside6-rcc style.qrc -o style_rc.py``
+ And finally import it from your ``main.py`` script.
+
+ .. literalinclude:: main.py
+ :linenos:
+ :lines: 4-12
+ :emphasize-lines: 9
+
+ You can read more about this configuration file
+ `here <https://doc.qt.io/qt-5/qtquickcontrols2-configuration.html>`_.
+
+ The final look of your application will be:
+
+ .. image:: textproperties_material.png
+
+You can :download:`view.qml <view.qml>` and
+:download:`main.py <main.py>` to try this example.
diff --git a/sources/pyside6/doc/tutorials/qmlintegration/qtquickcontrols2.conf b/sources/pyside6/doc/tutorials/qmlintegration/qtquickcontrols2.conf
new file mode 100644
index 000000000..850646021
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlintegration/qtquickcontrols2.conf
@@ -0,0 +1,10 @@
+[Controls]
+Style=Material
+
+[Universal]
+Theme=System
+Accent=Red
+
+[Material]
+Theme=Dark
+Accent=Red
diff --git a/sources/pyside6/doc/tutorials/qmlintegration/style.qrc b/sources/pyside6/doc/tutorials/qmlintegration/style.qrc
new file mode 100644
index 000000000..e313f5ed6
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlintegration/style.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+ <file>qtquickcontrols2.conf</file>
+</qresource>
+</RCC>
diff --git a/sources/pyside6/doc/tutorials/qmlintegration/textproperties_default.png b/sources/pyside6/doc/tutorials/qmlintegration/textproperties_default.png
new file mode 100644
index 000000000..cfeac9368
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlintegration/textproperties_default.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlintegration/textproperties_material.png b/sources/pyside6/doc/tutorials/qmlintegration/textproperties_material.png
new file mode 100644
index 000000000..47866c10e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlintegration/textproperties_material.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlintegration/view.qml b/sources/pyside6/doc/tutorials/qmlintegration/view.qml
new file mode 100644
index 000000000..635603fac
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlintegration/view.qml
@@ -0,0 +1,160 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.11
+import QtQuick.Controls 2.1
+import QtQuick.Window 2.1
+import QtQuick.Controls.Material 2.1
+
+import io.qt.textproperties 1.0
+
+ApplicationWindow {
+ id: page
+ width: 800
+ height: 400
+ visible: true
+ Material.theme: Material.Dark
+ Material.accent: Material.Red
+
+ Bridge {
+ id: bridge
+ }
+
+ GridLayout {
+ id: grid
+ columns: 2
+ rows: 3
+
+ ColumnLayout {
+ spacing: 2
+ Layout.columnSpan: 1
+ Layout.preferredWidth: 400
+
+ Text {
+ id: leftlabel
+ Layout.alignment: Qt.AlignHCenter
+ color: "white"
+ font.pointSize: 16
+ text: "Qt for Python"
+ Layout.preferredHeight: 100
+ Material.accent: Material.Green
+ }
+
+ RadioButton {
+ id: italic
+ Layout.alignment: Qt.AlignLeft
+ text: "Italic"
+ onToggled: {
+ leftlabel.font.italic = bridge.getItalic(italic.text)
+ leftlabel.font.bold = bridge.getBold(italic.text)
+ leftlabel.font.underline = bridge.getUnderline(italic.text)
+
+ }
+ }
+ RadioButton {
+ id: bold
+ Layout.alignment: Qt.AlignLeft
+ text: "Bold"
+ onToggled: {
+ leftlabel.font.italic = bridge.getItalic(bold.text)
+ leftlabel.font.bold = bridge.getBold(bold.text)
+ leftlabel.font.underline = bridge.getUnderline(bold.text)
+ }
+ }
+ RadioButton {
+ id: underline
+ Layout.alignment: Qt.AlignLeft
+ text: "Underline"
+ onToggled: {
+ leftlabel.font.italic = bridge.getItalic(underline.text)
+ leftlabel.font.bold = bridge.getBold(underline.text)
+ leftlabel.font.underline = bridge.getUnderline(underline.text)
+ }
+ }
+ RadioButton {
+ id: noneradio
+ Layout.alignment: Qt.AlignLeft
+ text: "None"
+ checked: true
+ onToggled: {
+ leftlabel.font.italic = bridge.getItalic(noneradio.text)
+ leftlabel.font.bold = bridge.getBold(noneradio.text)
+ leftlabel.font.underline = bridge.getUnderline(noneradio.text)
+ }
+ }
+ }
+
+ ColumnLayout {
+ id: rightcolumn
+ spacing: 2
+ Layout.columnSpan: 1
+ Layout.preferredWidth: 400
+ Layout.preferredHeight: 400
+ Layout.fillWidth: true
+
+ RowLayout {
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+
+
+ Button {
+ id: red
+ text: "Red"
+ highlighted: true
+ Material.accent: Material.Red
+ onClicked: {
+ leftlabel.color = bridge.getColor(red.text)
+ }
+ }
+ Button {
+ id: green
+ text: "Green"
+ highlighted: true
+ Material.accent: Material.Green
+ onClicked: {
+ leftlabel.color = bridge.getColor(green.text)
+ }
+ }
+ Button {
+ id: blue
+ text: "Blue"
+ highlighted: true
+ Material.accent: Material.Blue
+ onClicked: {
+ leftlabel.color = bridge.getColor(blue.text)
+ }
+ }
+ Button {
+ id: nonebutton
+ text: "None"
+ highlighted: true
+ Material.accent: Material.BlueGrey
+ onClicked: {
+ leftlabel.color = bridge.getColor(nonebutton.text)
+ }
+ }
+ }
+ RowLayout {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ Text {
+ id: rightlabel
+ color: "white"
+ Layout.alignment: Qt.AlignLeft
+ text: "Font size"
+ Material.accent: Material.White
+ }
+ Slider {
+ width: rightcolumn.width*0.6
+ Layout.alignment: Qt.AlignRight
+ id: slider
+ value: 0.5
+ onValueChanged: {
+ leftlabel.font.pointSize = bridge.getSize(value)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml b/sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml
new file mode 100644
index 000000000..da58ae9b2
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml
@@ -0,0 +1,98 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import ChatModel
+
+ApplicationWindow {
+ id: window
+ title: qsTr("Chat")
+ width: 640
+ height: 960
+ visible: true
+
+ SqlConversationModel {
+ id: chat_model
+ }
+
+ ColumnLayout {
+ anchors.fill: window
+
+ ListView {
+ id: listView
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.margins: pane.leftPadding + messageField.leftPadding
+ displayMarginBeginning: 40
+ displayMarginEnd: 40
+ verticalLayoutDirection: ListView.BottomToTop
+ spacing: 12
+ model: chat_model
+ delegate: Column {
+ anchors.right: sentByMe ? listView.contentItem.right : undefined
+ spacing: 6
+
+ readonly property bool sentByMe: model.recipient !== "Me"
+ Row {
+ id: messageRow
+ spacing: 6
+ anchors.right: sentByMe ? parent.right : undefined
+
+ Rectangle {
+ width: Math.min(messageText.implicitWidth + 24,
+ listView.width - (!sentByMe ? messageRow.spacing : 0))
+ height: messageText.implicitHeight + 24
+ radius: 15
+ color: sentByMe ? "lightgrey" : "steelblue"
+
+ Label {
+ id: messageText
+ text: model.message
+ color: sentByMe ? "black" : "white"
+ anchors.fill: parent
+ anchors.margins: 12
+ wrapMode: Label.Wrap
+ }
+ }
+ }
+
+ Label {
+ id: timestampText
+ text: Qt.formatDateTime(model.timestamp, "d MMM hh:mm")
+ color: "lightgrey"
+ anchors.right: sentByMe ? parent.right : undefined
+ }
+ }
+
+ ScrollBar.vertical: ScrollBar {}
+ }
+
+ Pane {
+ id: pane
+ Layout.fillWidth: true
+
+ RowLayout {
+ width: parent.width
+
+ TextArea {
+ id: messageField
+ Layout.fillWidth: true
+ placeholderText: qsTr("Compose message")
+ wrapMode: TextArea.Wrap
+ }
+
+ Button {
+ id: sendButton
+ text: qsTr("Send")
+ enabled: messageField.length > 0
+ onClicked: {
+ listView.model.send_message("machine", messageField.text, "Me");
+ messageField.text = "";
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/example_list_view.png b/sources/pyside6/doc/tutorials/qmlsqlintegration/example_list_view.png
new file mode 100644
index 000000000..a0c189665
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/example_list_view.png
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/main.py b/sources/pyside6/doc/tutorials/qmlsqlintegration/main.py
new file mode 100644
index 000000000..314fd5aa5
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/main.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import sys
+import logging
+
+from PySide6.QtCore import QDir, QFile, QUrl
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import QQmlApplicationEngine
+from PySide6.QtSql import QSqlDatabase
+
+# We import the file just to trigger the QmlElement type registration.
+import sqlDialog
+
+logging.basicConfig(filename="chat.log", level=logging.DEBUG)
+logger = logging.getLogger("logger")
+
+
+def connectToDatabase():
+ database = QSqlDatabase.database()
+ if not database.isValid():
+ database = QSqlDatabase.addDatabase("QSQLITE")
+ if not database.isValid():
+ logger.error("Cannot add database")
+
+ write_dir = QDir("")
+ if not write_dir.mkpath("."):
+ logger.error("Failed to create writable directory")
+
+ # Ensure that we have a writable location on all devices.
+ abs_path = write_dir.absolutePath()
+ filename = f"{abs_path}/chat-database.sqlite3"
+
+ # When using the SQLite driver, open() will create the SQLite
+ # database if it doesn't exist.
+ database.setDatabaseName(filename)
+ if not database.open():
+ logger.error("Cannot open database")
+ QFile.remove(filename)
+
+
+if __name__ == "__main__":
+ app = QGuiApplication()
+ connectToDatabase()
+
+ engine = QQmlApplicationEngine()
+ engine.load(QUrl("chat.qml"))
+
+ if not engine.rootObjects():
+ sys.exit(-1)
+
+ app.exec()
diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst b/sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst
new file mode 100644
index 000000000..eee3f807e
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst
@@ -0,0 +1,232 @@
+QML, SQL and PySide Integration Tutorial
+########################################
+
+This tutorial is very similar to the `Qt Chat Tutorial`_ one but it focuses on explaining how to
+integrate a SQL database into a PySide6 application using QML for its UI.
+
+.. _`Qt Chat Tutorial`: https://doc.qt.io/qt-6/qtquickcontrols-chattutorial-example.html
+
+sqlDialog.py
+------------
+
+We import the pertinent libraries to our program, define a global variable that hold the
+name of our table, and define the global function ``createTable()`` that creates a new table if it
+doesn't already exist.
+The database contains a single line to mock the beginning of a conversation.
+
+.. literalinclude:: sqlDialog.py
+ :linenos:
+ :lines: 4-43
+
+The ``SqlConversationModel`` class offers the read-only data model required for the non-editable
+contacts list. It derives from the :ref:`QSqlQueryModel` class, which is the logical choice for
+this use case.
+Then, we proceed to create the table, set its name to the one defined previously with the
+:meth:`~.QSqlTableModel.setTable` method.
+We add the necessary attributes to the table, to have a program that reflects the idea
+of a chat application.
+
+.. literalinclude:: sqlDialog.py
+ :linenos:
+ :lines: 47-59
+
+In ``setRecipient()``, you set a filter over the returned results from the database, and
+emit a signal every time the recipient of the message changes.
+
+.. literalinclude:: sqlDialog.py
+ :linenos:
+ :lines: 61-70
+
+The ``data()`` function falls back to ``QSqlTableModel``'s implementation if the role is not a
+custom user role.
+If you get a user role, we can subtract :meth:`~.QtCore.Qt.UserRole` from it to get the index of
+that field, and then use that index to find the value to be returned.
+
+.. literalinclude:: sqlDialog.py
+ :linenos:
+ :lines: 72-79
+
+
+In ``roleNames()``, we return a Python dictionary with our custom role and role names as key-values
+pairs, so we can use these roles in QML.
+Alternatively, it can be useful to declare an Enum to hold all of the role values.
+Note that ``names`` has to be a hash to be used as a dictionary key,
+and that's why we're using the ``hash`` function.
+
+.. literalinclude:: sqlDialog.py
+ :linenos:
+ :lines: 81-95
+
+The ``send_message()`` function uses the given recipient and message to insert a new record into
+the database.
+Using :meth:`~.QSqlTableModel.OnManualSubmit` requires you to also call ``submitAll()``,
+since all the changes will be cached in the model until you do so.
+
+.. literalinclude:: sqlDialog.py
+ :linenos:
+ :lines: 97-116
+
+chat.qml
+--------
+
+Let's look at the ``chat.qml`` file.
+
+.. literalinclude:: chat.qml
+ :linenos:
+ :lines: 4-6
+
+First, import the Qt Quick module.
+This gives us access to graphical primitives such as Item, Rectangle, Text, and so on.
+For a full list of types, see the `Qt Quick QML Types`_ documentation.
+We then add QtQuick.Layouts import, which we'll cover shortly.
+
+Next, import the Qt Quick Controls module.
+Among other things, this provides access to ``ApplicationWindow``, which replaces the existing
+root type, Window:
+
+Let's step through the ``chat.qml`` file.
+
+.. literalinclude:: chat.qml
+ :linenos:
+ :lines: 9-14
+
+``ApplicationWindow`` is a Window with some added convenience for creating a header and a footer.
+It also provides the foundation for popups and supports some basic styling, such as the background
+color.
+
+There are three properties that are almost always set when using ApplicationWindow: ``width``,
+``height``, and ``visible``.
+Once we've set these, we have a properly sized, empty window ready to be filled with content.
+
+Because we are exposing the :code:`SqlConversationModel` class to QML, we will
+declare a component to access it:
+
+.. literalinclude:: chat.qml
+ :linenos:
+ :lines: 16-18
+
+There are two ways of laying out items in QML: `Item Positioners`_ and `Qt Quick Layouts`_.
+
+- Item positioners (`Row`_, `Column`_, and so on) are useful for situations where the size of items
+ is known or fixed, and all that is required is to neatly position them in a certain formation.
+- The layouts in Qt Quick Layouts can both position and resize items, making them well suited for
+ resizable user interfaces.
+ Below, we use `ColumnLayout`_ to vertically lay out a `ListView`_ and a `Pane`_.
+
+ .. literalinclude:: chat.qml
+ :linenos:
+ :lines: 20-23
+
+ .. literalinclude:: chat.qml
+ :linenos:
+ :lines: 72-74
+
+Pane is basically a rectangle whose color comes from the application's style.
+It's similar to `Frame`_, but it has no stroke around its border.
+
+Items that are direct children of a layout have various `attached properties`_ available to them.
+We use `Layout.fillWidth`_ and `Layout.fillHeight`_ on the `ListView`_ to ensure that it takes as
+much space within the `ColumnLayout`_ as it can, and the same is done for the Pane.
+As `ColumnLayout`_ is a vertical layout, there aren't any items to the left or right of each child,
+so this results in each item consuming the entire width of the layout.
+
+On the other hand, the `Layout.fillHeight`_ statement in the `ListView`_ enables it to occupy the
+remaining space that is left after accommodating the Pane.
+
+.. _Item Positioners: https://doc.qt.io/qt-5/qtquick-positioning-layouts.html
+.. _Qt Quick Layouts: https://doc.qt.io/qt-5/qtquicklayouts-index.html
+.. _Row: https://doc.qt.io/qt-5/qml-qtquick-row.html
+.. _Column: https://doc.qt.io/qt-5/qml-qtquick-column.html
+.. _ColumnLayout: https://doc.qt.io/qt-5/qml-qtquick-layouts-columnlayout.html
+.. _ListView: https://doc.qt.io/qt-5/qml-qtquick-listview.html
+.. _Pane: https://doc.qt.io/qt-5/qml-qtquick-controls2-pane.html
+.. _Frame: https://doc.qt.io/qt-5/qml-qtquick-controls2-frame.html
+.. _attached properties: https://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html
+.. _Layout.fillWidth: https://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html#fillWidth-attached-prop
+.. _Layout.fillHeight: https://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html#fillHeight-attached-prop
+.. _Qt Quick QML Types: https://doc.qt.io/qt-5/qtquick-qmlmodule.html
+
+Let's look at the ``Listview`` in detail:
+
+.. literalinclude:: chat.qml
+ :linenos:
+ :lines: 23-70
+
+After filling the ``width`` and ``height`` of its parent, we also set some margins on the view.
+
+Next, we set `displayMarginBeginning`_ and `displayMarginEnd`_.
+These properties ensure that the delegates outside the view don't disappear when you
+scroll at the edges of the view.
+To get a better understanding, consider commenting out the properties and then rerun your code.
+Now watch what happens when you scroll the view.
+
+We then flip the vertical direction of the view, so that first items are at the bottom.
+
+Additionally, messages sent by the contact should be distinguished from those sent by a contact.
+For now, when a message is sent by you, we set a ``sentByMe`` property, to alternate between
+different contacts.
+Using this property, we distinguish between different contacts in two ways:
+
+* Messages sent by the contact are aligned to the right side of the screen by setting
+ ``anchors.right`` to ``parent.right``.
+* We change the color of the rectangle depending on the contact.
+ Since we don't want to display dark text on a dark background, and vice versa, we also set the
+ text color depending on who the contact is.
+
+At the bottom of the screen, we place a `TextArea`_ item to allow multi-line text input, and a
+button to send the message.
+We use Pane to cover the area under these two items:
+
+.. literalinclude:: chat.qml
+ :linenos:
+ :lines: 72-96
+
+The `TextArea`_ should fill the available width of the screen.
+We assign some placeholder text to provide a visual cue to the contact as to where they should begin
+typing.
+The text within the input area is wrapped to ensure that it does not go outside of the screen.
+
+Lastly, we have a button that allows us to call the ``send_message`` method we defined on
+``sqlDialog.py``, since we're just having a mock up example here and there is only one possible
+recipient and one possible sender for this conversation we're just using strings here.
+
+.. _displayMarginBeginning: https://doc.qt.io/qt-5/qml-qtquick-listview.html#displayMarginBeginning-prop
+.. _displayMarginEnd: https://doc.qt.io/qt-5/qml-qtquick-listview.html#displayMarginEnd-prop
+.. _TextArea: https://doc.qt.io/qt-5/qml-qtquick-controls2-textarea.html
+
+
+main.py
+-------
+
+We use ``logging`` instead of Python's ``print()``, because it provides a better way to control the
+messages levels that our application will generate (errors, warnings, and information messages).
+
+.. literalinclude:: main.py
+ :linenos:
+ :lines: 4-16
+
+``connectToDatabase()`` creates a connection with the SQLite database, creating the actual file
+if it doesn't already exist.
+
+.. literalinclude:: main.py
+ :linenos:
+ :lines: 19-39
+
+A few interesting things happen in the ``main`` function:
+
+- Declaring a :ref:`QGuiApplication`.
+ You should use a :ref:`QGuiApplication` instead of :ref:`QApplication` because we're not
+ using the **QtWidgets** module.
+- Connecting to the database,
+- Declaring a :ref:`QQmlApplicationEngine`.
+ This allows you to access the QML Elements to connect Python
+ and QML from the conversation model we built on ``sqlDialog.py``.
+- Loading the ``.qml`` file that defines the UI.
+
+Finally, the Qt application runs, and your program starts.
+
+.. literalinclude:: main.py
+ :linenos:
+ :lines: 42-52
+
+.. image:: example_list_view.png
diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py b/sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py
new file mode 100644
index 000000000..d728aee59
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py
@@ -0,0 +1,116 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import datetime
+import logging
+
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlRecord, QSqlTableModel
+from PySide6.QtQml import QmlElement
+
+table_name = "Conversations"
+QML_IMPORT_NAME = "ChatModel"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+def createTable():
+ if table_name in QSqlDatabase.database().tables():
+ return
+
+ query = QSqlQuery()
+ if not query.exec_(
+ """
+ CREATE TABLE IF NOT EXISTS 'Conversations' (
+ 'author' TEXT NOT NULL,
+ 'recipient' TEXT NOT NULL,
+ 'timestamp' TEXT NOT NULL,
+ 'message' TEXT NOT NULL,
+ FOREIGN KEY('author') REFERENCES Contacts ( name ),
+ FOREIGN KEY('recipient') REFERENCES Contacts ( name )
+ )
+ """
+ ):
+ logging.error("Failed to query database")
+
+ # This adds the first message from the Bot
+ # and further development is required to make it interactive.
+ query.exec_(
+ """
+ INSERT INTO Conversations VALUES(
+ 'machine', 'Me', '2019-01-07T14:36:06', 'Hello!'
+ )
+ """
+ )
+ logging.info(query)
+
+
+@QmlElement
+class SqlConversationModel(QSqlTableModel):
+ def __init__(self, parent=None):
+ super(SqlConversationModel, self).__init__(parent)
+
+ createTable()
+ self.setTable(table_name)
+ self.setSort(2, Qt.DescendingOrder)
+ self.setEditStrategy(QSqlTableModel.OnManualSubmit)
+ self.recipient = ""
+
+ self.select()
+ logging.debug("Table was loaded successfully.")
+
+ def setRecipient(self, recipient):
+ if recipient == self.recipient:
+ pass
+
+ self.recipient = recipient
+
+ filter_str = (f"(recipient = '{self.recipient}' AND author = 'Me') OR "
+ f"(recipient = 'Me' AND author='{self.recipient}')")
+ self.setFilter(filter_str)
+ self.select()
+
+ def data(self, index, role):
+ if role < Qt.UserRole:
+ return QSqlTableModel.data(self, index, role)
+
+ sql_record = QSqlRecord()
+ sql_record = self.record(index.row())
+
+ return sql_record.value(role - Qt.UserRole)
+
+ def roleNames(self):
+ """Converts dict to hash because that's the result expected
+ by QSqlTableModel"""
+ names = {}
+ author = "author".encode()
+ recipient = "recipient".encode()
+ timestamp = "timestamp".encode()
+ message = "message".encode()
+
+ names[hash(Qt.UserRole)] = author
+ names[hash(Qt.UserRole + 1)] = recipient
+ names[hash(Qt.UserRole + 2)] = timestamp
+ names[hash(Qt.UserRole + 3)] = message
+
+ return names
+
+ # This is a workaround because PySide doesn't provide Q_INVOKABLE
+ # So we declare this as a Slot to be able to call it from QML
+ @Slot(str, str, str)
+ def send_message(self, recipient, message, author):
+ timestamp = datetime.datetime.now()
+
+ new_record = self.record()
+ new_record.setValue("author", author)
+ new_record.setValue("recipient", recipient)
+ new_record.setValue("timestamp", str(timestamp))
+ new_record.setValue("message", message)
+
+ logging.debug(f'Message: "{message}" \n Received by: "{recipient}"')
+
+ if not self.insertRecord(self.rowCount(), new_record):
+ logging.error("Failed to send message: {self.lastError().text()}")
+ return
+
+ self.submitAll()
+ self.select()
diff --git a/sources/pyside6/doc/typesystem_doc.xml.in b/sources/pyside6/doc/typesystem_doc.xml.in
new file mode 100644
index 000000000..86a4d0eae
--- /dev/null
+++ b/sources/pyside6/doc/typesystem_doc.xml.in
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!--
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+-->
+<typesystem package="PySide">
+ <suppress-warning text="File containing conversion code for *" />
+ <suppress-warning text="File for inject code not exist: *" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix4x3, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix4x3.xml" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix3x4, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix3x4.xml" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix2x3, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix2x3.xml" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix4x2, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix4x2.xml" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix3x3, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix3x3.xml" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix2x2, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix2x2.xml" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix3x2, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix3x2.xml" />
+ <suppress-warning text="Can't find qdoc3 file for class QMatrix2x4, tried: /home/hugo/src/pyside/build/doc/qdoc3-output/qmatrix2x4.xml" />
+<!-- Modules to be appended -->
diff --git a/sources/pyside6/doc/videos.rst b/sources/pyside6/doc/videos.rst
new file mode 100644
index 000000000..919c9ff38
--- /dev/null
+++ b/sources/pyside6/doc/videos.rst
@@ -0,0 +1,155 @@
+.. _video-gallery:
+
+Videos
+======
+
+Tutorials
+---------
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: Resources overview
+ :img-top: https://img.youtube.com/vi/sywLvidNkbw/mqdefault.jpg
+ :link: https://www.youtube.com/embed/sywLvidNkbw
+
+ .. grid-item-card:: Repository overview
+ :img-top: https://img.youtube.com/vi/RP0K1B7fqMs/mqdefault.jpg
+ :link: https://www.youtube.com/embed/RP0K1B7fqMs
+
+ .. grid-item-card:: Shiboken overview
+ :img-top: https://img.youtube.com/vi/RUwV_sx_gBM/mqdefault.jpg
+ :link: https://www.youtube.com/embed/RUwV_sx_gBM
+
+ .. grid-item-card:: Tutorial
+ :img-top: https://img.youtube.com/vi/Cqo0-EQmy1Q/mqdefault.jpg
+ :link: https://www.youtube.com/embed/Cqo0-EQmy1Q
+
+ How to create a simple Qt Widgets app with PySide6
+
+ .. grid-item-card:: Tutorial
+ :img-top: https://img.youtube.com/vi/JxfiUx60Mbg/mqdefault.jpg
+ :link: https://www.youtube.com/embed/JxfiUx60Mbg
+
+ Making a QML Application in Python
+
+ .. grid-item-card:: Tutorial
+ :img-top: https://img.youtube.com/vi/i-utZN_NP6c/mqdefault.jpg
+ :link: https://www.youtube.com/embed/i-utZN_NP6c
+
+ How to install PySide6 on a new virtual environment
+
+
+Community events
+----------------
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: Akademy 2021
+ :img-top: https://img.youtube.com/vi/Ftm68AzYvr8/mqdefault.jpg
+ :link: https://www.youtube.com/embed/Ftm68AzYvr8
+
+ Qt for Python
+
+Webinars
+--------
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: Online Webinar
+ :img-top: https://img.youtube.com/vi/eqHveQ5JTZU/mqdefault.jpg
+ :link: https://www.youtube.com/embed/eqHveQ5JTZU
+
+ How your Python projects can benefit from Qt
+
+ .. grid-item-card:: Online Webinar
+ :img-top: https://img.youtube.com/vi/wOMlDutOWXI/mqdefault.jpg
+ :link: https://www.youtube.com/embed/wOMlDutOWXI
+
+ Interoperability of Python and C++ using Shiboken
+
+ .. grid-item-card:: Online Webinar
+ :img-top: https://img.youtube.com/vi/HDBjmSiOBxY/mqdefault.jpg
+ :link: https://www.youtube.com/embed/HDBjmSiOBxY
+
+ Developing your first Qt for Python application
+
+ .. grid-item-card:: Online Webinar
+ :img-top: https://img.youtube.com/vi/wKqLaNqxgas/mqdefault.jpg
+ :link: https://www.youtube.com/embed/wKqLaNqxgas
+
+ Creating user interfaces with Qt for Python
+
+Conferences
+-----------
+
+.. grid:: 1 3 3 3
+ :gutter: 2
+
+ .. grid-item-card:: PyConES 2023
+ :img-top: https://img.youtube.com/vi/XuqdTvisqkQ/mqdefault.jpg
+ :link: https://www.youtube.com/embed/XuqdTvisqkQ
+
+ Asynchronous programming with asyncio and Qt
+
+ .. grid-item-card:: QtWS 2022
+ :img-top: https://img.youtube.com/vi/8wcdN1Iw1Uk/mqdefault.jpg
+ :link: https://www.youtube.com/embed/8wcdN1Iw1Uk
+
+ 5 Reasons Why You Should Use the Latest Qt for Python
+
+ .. grid-item-card:: QtDeCon 2022
+ :img-top: https://img.youtube.com/vi/ZUNg19OlDeE/mqdefault.jpg
+ :link: https://www.youtube.com/embed/ZUNg19OlDeE
+
+ Hybrid Qt Development: Boosting Your Projects with Python
+
+ .. grid-item-card:: QtWS 2021
+ :img-top: https://img.youtube.com/vi/SylgpRc-Lrg/mqdefault.jpg
+ :link: https://www.youtube.com/embed/SylgpRc-Lrg
+
+ Hybrid Qt Development: boosting Projects with Python
+
+ .. grid-item-card:: QtWS 2020
+ :img-top: https://img.youtube.com/vi/Vb1dbLQafyM/mqdefault.jpg
+ :link: https://www.youtube.com/embed/Vb1dbLQafyM
+
+ Prototypes to Hybrid Applications
+
+ .. grid-item-card:: QtWS 2019
+ :img-top: https://img.youtube.com/vi/mAfEVPgHRt8/mqdefault.jpg
+ :link: https://www.youtube.com/embed/mAfEVPgHRt8
+
+ Using Shiboken to Enhance Application
+
+ .. grid-item-card:: QtWS 2019
+ :img-top: https://img.youtube.com/vi/214TWASZVgA/mqdefault.jpg
+ :link: https://www.youtube.com/embed/214TWASZVgA
+
+ Intro to Qt for Python
+
+ .. grid-item-card:: QtWS 2019
+ :img-top: https://img.youtube.com/vi/XmY-tWTi9gY/mqdefault.jpg
+ :link: https://www.youtube.com/embed/XmY-tWTi9gY
+
+ Using C++ project in Python
+
+ .. grid-item-card:: QtWS 2019
+ :img-top: https://img.youtube.com/vi/rRDoToEOlbY/mqdefault.jpg
+ :link: https://www.youtube.com/embed/rRDoToEOlbY
+
+ Using Qt for Python for embedded system development
+
+ .. grid-item-card:: QtWS 2018
+ :img-top: https://img.youtube.com/vi/IhxZ99usPqY/mqdefault.jpg
+ :link: https://www.youtube.com/embed/IhxZ99usPqY
+
+ Qt for Python in 20 min
+
+ .. grid-item-card:: QtWS 2017
+ :img-top: https://img.youtube.com/vi/Sb4FV6SdHHQ/mqdefault.jpg
+ :link: https://www.youtube.com/embed/Sb4FV6SdHHQ
+
+ A walk to PySide
diff --git a/sources/pyside6/libpyside/CMakeLists.txt b/sources/pyside6/libpyside/CMakeLists.txt
new file mode 100644
index 000000000..ebfe123dd
--- /dev/null
+++ b/sources/pyside6/libpyside/CMakeLists.txt
@@ -0,0 +1,194 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(libpyside)
+
+set(libpyside_libraries Qt::Core Qt::CorePrivate)
+
+set(CMAKE_AUTOMOC ON)
+
+set(libpyside_HEADERS # installed below
+ class_property.h
+ dynamicqmetaobject.h
+ feature_select.h
+ globalreceiverv2.h
+ pysideclassdecorator_p.h
+ pysideclassinfo.h
+ pysideclassinfo_p.h
+ pysidecleanup.h
+ pyside.h
+ pysideinit.h
+ pysidelogging_p.h
+ pysidemacros.h
+ pysidemetafunction.h
+ pysidemetafunction_p.h
+ pysidemetatype.h
+ pyside_numpy.h
+ pyside_p.h
+ pysideproperty.h
+ pysideproperty_p.h
+ pysideqapp.h
+ pysideqenum.h
+ pysideqhash.h
+ pysideqmetatype.h
+ pysideqobject.h
+ pysideqslotobject_p.h
+ pysidesignal.h
+ pysidesignal_p.h
+ pysideslot_p.h
+ pysidestaticstrings.h
+ pysideutils.h
+ pysideweakref.h
+ qobjectconnect.h
+ signalmanager.h
+)
+
+set(libpyside_SRC
+ class_property.cpp
+ dynamicqmetaobject.cpp
+ feature_select.cpp
+ signalmanager.cpp
+ globalreceiverv2.cpp
+ pysideclassdecorator.cpp
+ pysideclassinfo.cpp
+ pysideqenum.cpp
+ pysideqslotobject_p.cpp
+ pysidemetafunction.cpp
+ pysidesignal.cpp
+ pysideslot.cpp
+ pysideproperty.cpp
+ pysideweakref.cpp
+ pyside.cpp
+ pyside_numpy.cpp
+ pysidestaticstrings.cpp
+ qobjectconnect.cpp
+ ${libpyside_HEADERS}
+)
+
+qt6_add_resources(libpyside_SRC libpyside.qrc)
+
+# Add python files to project explorer in Qt Creator, when opening the CMakeLists.txt as a project,
+# so you can look up python files with the Locator.
+macro(add_other_files)
+ foreach(_it ${ARGN})
+ if(NOT IS_DIRECTORY ${_it})
+ get_filename_component(name ${_it} NAME)
+ if(NOT ${_it} MATCHES "^/\\\\..*$;~$")
+ set_source_files_properties(${_it} PROPERTIES HEADER_FILE_ONLY TRUE)
+ endif()
+ endif()
+ endforeach()
+endmacro()
+
+# Test files.
+file(GLOB_RECURSE pyside_folder_py_files "../*.py")
+
+# Mostly for setup.py.
+file(GLOB setup_folder_py_files "../../../*.py")
+
+set(other_files ${pyside_folder_py_files} ${setup_folder_py_files})
+add_other_files(${other_files})
+
+add_library(pyside6 SHARED ${libpyside_SRC} ${other_files})
+add_library(PySide6::pyside6 ALIAS pyside6)
+
+#does nothing if QFP_NO_OVERRIDE_OPTIMIZATION_FLAGS (no-size-optimization) flag is not set
+append_size_optimization_flags(pyside6)
+
+target_include_directories(pyside6 PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ $<INSTALL_INTERFACE:include/PySide6>
+)
+
+target_compile_definitions(pyside6 PRIVATE -DQT_LEAN_HEADERS=1 -DQT_NO_KEYWORDS=1)
+
+target_link_libraries(pyside6
+ PRIVATE Shiboken6::libshiboken ${libpyside_libraries})
+
+set_target_properties(pyside6 PROPERTIES
+ VERSION ${BINDING_API_VERSION}
+ SOVERSION "${PYSIDE_SO_VERSION}"
+ OUTPUT_NAME "pyside6${pyside6_SUFFIX}${SHIBOKEN_PYTHON_SHARED_LIBRARY_SUFFIX}"
+ DEFINE_SYMBOL BUILD_LIBPYSIDE)
+
+set_property(TARGET pyside6 PROPERTY CXX_STANDARD 17)
+
+if(PYSIDE_QT_CONF_PREFIX)
+ set_property(SOURCE pyside.cpp
+ APPEND
+ PROPERTY COMPILE_DEFINITIONS
+ PYSIDE_QT_CONF_PREFIX=${PYSIDE_QT_CONF_PREFIX})
+endif()
+
+#
+# install stuff
+#
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_DEBUG_POSTFIX})
+else()
+ set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_RELEASE_POSTFIX})
+endif()
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_TO_ASCII")
+
+qfp_strip_library("pyside6")
+
+# create pkg-config file
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/pyside6.pc.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/pyside6${pyside6_SUFFIX}.pc" @ONLY)
+
+# for creating cmake-config files
+include(CMakePackageConfigHelpers)
+
+# Build-tree / super project package config file.
+set(PYSIDE_PYTHONPATH "${pysidebindings_BINARY_DIR}/PySide6")
+set(PYSIDE_TYPESYSTEMS "${pysidebindings_SOURCE_DIR}/PySide6/templates/")
+set(PYSIDE_GLUE "${pysidebindings_SOURCE_DIR}/PySide6/glue")
+
+configure_package_config_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/PySide6Config-spec.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/PySide6Config${SHIBOKEN_PYTHON_CONFIG_SUFFIX}.cmake"
+ INSTALL_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}"
+ PATH_VARS PYSIDE_PYTHONPATH PYSIDE_TYPESYSTEMS PYSIDE_GLUE
+ INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
+)
+
+set(PYSIDE_PYTHONPATH "${PYTHON_SITE_PACKAGES}/PySide6")
+set(PYSIDE_TYPESYSTEMS "${CMAKE_INSTALL_PREFIX}/share/PySide6${pyside6_SUFFIX}/typesystems")
+set(PYSIDE_GLUE "${CMAKE_INSTALL_PREFIX}/share/PySide6${pyside6_SUFFIX}/glue")
+
+# Install-tree / relocatable package config file.
+configure_package_config_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/PySide6Config-spec.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/install/PySide6Config${SHIBOKEN_PYTHON_CONFIG_SUFFIX}.cmake"
+ INSTALL_DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6"
+ PATH_VARS PYSIDE_PYTHONPATH PYSIDE_TYPESYSTEMS PYSIDE_GLUE
+)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/PySide6Config.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/PySide6Config.cmake" @ONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/PySide6ConfigVersion.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/PySide6ConfigVersion.cmake" @ONLY)
+
+install(FILES ${libpyside_HEADERS}
+ DESTINATION include/${BINDING_NAME}${pyside6_SUFFIX})
+
+install(TARGETS pyside6 EXPORT PySide6Targets
+ LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
+ ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
+ RUNTIME DESTINATION bin)
+install(EXPORT PySide6Targets NAMESPACE PySide6::
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pyside6${pyside6_SUFFIX}.pc"
+ DESTINATION "${LIB_INSTALL_DIR}/pkgconfig")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/PySide6Config.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/install/PySide6Config${SHIBOKEN_PYTHON_CONFIG_SUFFIX}.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/PySide6ConfigVersion.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6")
diff --git a/sources/pyside6/libpyside/PySide6Config-spec.cmake.in b/sources/pyside6/libpyside/PySide6Config-spec.cmake.in
new file mode 100644
index 000000000..fd3de1e75
--- /dev/null
+++ b/sources/pyside6/libpyside/PySide6Config-spec.cmake.in
@@ -0,0 +1,16 @@
+# PYSIDE_PYTHONPATH - Path to where the PySide6 Python module files could be found
+# PYSIDE_TYPESYSTEMS - Type system files that should be used by other bindings extending PySide6
+# PYSIDE_GLUE - Path to module glue files.
+
+@PACKAGE_INIT@
+
+# Import targets only when using an installed PySide6 config file (so not during a regular
+# PySide6 build, or during a super project build).
+if (NOT TARGET PySide6::pyside6)
+ include("${CMAKE_CURRENT_LIST_DIR}/PySide6Targets.cmake")
+endif()
+
+# Set relocatable variables.
+set_and_check(PYSIDE_PYTHONPATH "@PACKAGE_PYSIDE_PYTHONPATH@")
+set_and_check(PYSIDE_TYPESYSTEMS "@PACKAGE_PYSIDE_TYPESYSTEMS@")
+set_and_check(PYSIDE_GLUE "@PACKAGE_PYSIDE_GLUE@")
diff --git a/sources/pyside6/libpyside/PySide6Config.cmake.in b/sources/pyside6/libpyside/PySide6Config.cmake.in
new file mode 100644
index 000000000..037a5c44f
--- /dev/null
+++ b/sources/pyside6/libpyside/PySide6Config.cmake.in
@@ -0,0 +1,5 @@
+if (NOT PYTHON_CONFIG_SUFFIX)
+ message(STATUS "PySide6Config: Using default python: @SHIBOKEN_PYTHON_CONFIG_SUFFIX@")
+ SET(PYTHON_CONFIG_SUFFIX @SHIBOKEN_PYTHON_CONFIG_SUFFIX@)
+endif()
+include(${CMAKE_CURRENT_LIST_DIR}/PySide6Config${PYTHON_CONFIG_SUFFIX}.cmake)
diff --git a/sources/pyside6/libpyside/PySide6ConfigVersion.cmake.in b/sources/pyside6/libpyside/PySide6ConfigVersion.cmake.in
new file mode 100644
index 000000000..f5073ce08
--- /dev/null
+++ b/sources/pyside6/libpyside/PySide6ConfigVersion.cmake.in
@@ -0,0 +1,10 @@
+set(PACKAGE_VERSION @BINDING_API_VERSION@)
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+endif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
diff --git a/sources/pyside6/libpyside/class_property.cpp b/sources/pyside6/libpyside/class_property.cpp
new file mode 100644
index 000000000..2bed97ef5
--- /dev/null
+++ b/sources/pyside6/libpyside/class_property.cpp
@@ -0,0 +1,178 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "class_property.h"
+#include "pysidestaticstrings.h"
+#include "feature_select.h"
+
+#include <pep384ext.h>
+#include <shiboken.h>
+#include <sbkstaticstrings.h>
+
+extern "C" {
+
+/*
+ * A `classproperty` is the same as a `property` but the `__get__()` and `__set__()`
+ * methods are modified to always use the object class instead of a concrete instance.
+ *
+ * Note: A "static property" as it is often called does not exist per se.
+ * Static methods do not receive anything when created. Static methods which
+ * should participate in a property must be turned into class methods, before.
+ * See function `createProperty` in `feature_select.cpp`.
+ */
+
+// `class_property.__get__()`: Always pass the class instead of the instance.
+static PyObject *PyClassProperty_descr_get(PyObject *self, PyObject * /*ob*/, PyObject *cls)
+{
+ return PepExt_Type_GetDescrGetSlot(&PyProperty_Type)(self, cls, cls);
+}
+
+// `class_property.__set__()`: Just like the above `__get__()`.
+static int PyClassProperty_descr_set(PyObject *self, PyObject *obj, PyObject *value)
+{
+ PyObject *cls = PyType_Check(obj) ? obj : reinterpret_cast<PyObject *>(Py_TYPE(obj));
+ return PepExt_Type_GetDescrSetSlot(&PyProperty_Type)(self, cls, value);
+}
+
+// PYSIDE-2230: Why is this metaclass necessary?
+//
+// The problem is that the property object already exists as a Python
+// object. We derive a subclass for class properties, without
+// repeating everything but just by adding something to support
+// the class-ness.
+//
+// But this Python property has as metaclass `type` which is incompatible
+// now with SbkObjectType, which generates physically larger types that
+// are incompatible with properties by using PEP 697.
+// Adding a compatible metaclass that is unrelated to `SbkObjectType`
+// is the correct solution. Re-using `SbkObjectType` was actually an abuse,
+// since Python properties are in no way PySide objects.
+
+static PyTypeObject *createClassPropertyTypeType()
+{
+ PyType_Slot PyClassPropertyType_Type_slots[] = {
+ {Py_tp_base, static_cast<void *>(&PyType_Type)},
+ {Py_tp_alloc, reinterpret_cast<void *>(PyType_GenericAlloc)},
+ {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PyClassPropertyType_Type_spec = {
+ "1:Shiboken.ClassPropertyType",
+ 0,
+ 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_TYPE_SUBCLASS,
+ PyClassPropertyType_Type_slots,
+ };
+
+ return SbkType_FromSpec(&PyClassPropertyType_Type_spec);
+}
+
+PyTypeObject *PyClassPropertyType_TypeF()
+{
+ static auto *type = createClassPropertyTypeType();
+ return type;
+}
+
+// The property `__doc__` default does not work for class properties
+// because PyProperty_Type.tp_init thinks this is a subclass which needs PyObject_SetAttr.
+// We call `__init__` while pretending to be a PyProperty_Type instance.
+static int PyClassProperty_tp_init(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ auto hold = Py_TYPE(self);
+ self->ob_type = &PyProperty_Type;
+ auto ret = PepExt_Type_GetInitSlot(&PyProperty_Type)(self, args, kwargs);
+ self->ob_type = hold;
+ return ret;
+}
+
+static PyTypeObject *createPyClassPropertyType()
+{
+ PyType_Slot PyClassProperty_slots[] = {
+ {Py_tp_getset, reinterpret_cast<void *>(PyProperty_Type.tp_getset)}, // will be set below
+ {Py_tp_base, reinterpret_cast<void *>(&PyProperty_Type)},
+ {Py_tp_descr_get, reinterpret_cast<void *>(PyClassProperty_descr_get)},
+ {Py_tp_descr_set, reinterpret_cast<void *>(PyClassProperty_descr_set)},
+ {Py_tp_init, reinterpret_cast<void *>(PyClassProperty_tp_init)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PyClassProperty_spec = {
+ "2:PySide6.QtCore.PyClassProperty",
+ sizeof(propertyobject),
+ 0,
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
+ PyClassProperty_slots,
+ };
+
+ if (_PepRuntimeVersion() >= 0x030A00)
+ PyClassProperty_spec.basicsize = sizeof(propertyobject310);
+ return SbkType_FromSpecWithMeta(&PyClassProperty_spec, PyClassPropertyType_TypeF());
+}
+
+PyTypeObject *PyClassProperty_TypeF()
+{
+ static auto *type = createPyClassPropertyType();
+ return type;
+}
+
+/*
+ * Types with class properties need to handle `Type.class_prop = x` in a specific way.
+ * By default, Python replaces the `class_property` itself, but for wrapped C++ types
+ * we need to call `class_property.__set__()` in order to propagate the new value to
+ * the underlying C++ data structure.
+ */
+static int SbkObjectType_meta_setattro(PyObject *obj, PyObject *name, PyObject *value)
+{
+ // Use `_PepType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw
+ // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`).
+ auto type = reinterpret_cast<PyTypeObject *>(obj);
+ PySide::Feature::Select(type);
+ PyObject *descr = _PepType_Lookup(type, name);
+
+ // The following assignment combinations are possible:
+ // 1. `Type.class_prop = value` --> descr_set: `Type.class_prop.__set__(value)`
+ // 2. `Type.class_prop = other_class_prop` --> setattro: replace existing `class_prop`
+ // 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment
+ const auto class_prop = reinterpret_cast<PyObject *>(PyClassProperty_TypeF());
+ const auto call_descr_set = descr && PyObject_IsInstance(descr, class_prop)
+ && !PyObject_IsInstance(value, class_prop);
+ if (call_descr_set) {
+ // Call `class_property.__set__()` instead of replacing the `class_property`.
+ return PepExt_Type_GetDescrSetSlot(Py_TYPE(descr))(descr, obj, value);
+ } // Replace existing attribute.
+ return PepExt_Type_GetSetAttroSlot(&PyType_Type)(obj, name, value);
+}
+
+} // extern "C"
+
+/*
+ * These functions are added to the SbkObjectType_TypeF() dynamically.
+ */
+namespace PySide::ClassProperty {
+
+static const char *PyClassProperty_SignatureStrings[] = {
+ "PySide6.QtCore.PyClassProperty(cls,"
+ "fget:typing.Optional[typing.Callable[[typing.Any],typing.Any]]=None,"
+ "fset:typing.Optional[typing.Callable[[typing.Any,typing.Any],None]]=None,"
+ "fdel:typing.Optional[typing.Callable[[typing.Any],None]]=None,"
+ "doc:typing.Optional[str]=None)",
+ "PySide6.QtCore.PyClassProperty.getter(cls,fget:typing.Callable[[typing.Any],typing.Any])->PySide6.QtCore.PyClassProperty",
+ "PySide6.QtCore.PyClassProperty.setter(cls,fset:typing.Callable[[typing.Any,typing.Any],None])->PySide6.QtCore.PyClassProperty",
+ "PySide6.QtCore.PyClassProperty.deleter(cls,fdel:typing.Callable[[typing.Any],None])->PySide6.QtCore.PyClassProperty",
+ nullptr}; // Sentinel
+
+void init(PyObject *module)
+{
+ PyTypeObject *type = SbkObjectType_TypeF();
+ type->tp_setattro = SbkObjectType_meta_setattro;
+
+ if (InitSignatureStrings(PyClassProperty_TypeF(), PyClassProperty_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PyClassProperty_TypeF());
+ auto classproptype = reinterpret_cast<PyObject *>(PyClassProperty_TypeF());
+ PyModule_AddObject(module, "PyClassProperty", classproptype);
+}
+
+} // namespace PySide::ClassProperty
diff --git a/sources/pyside6/libpyside/class_property.h b/sources/pyside6/libpyside/class_property.h
new file mode 100644
index 000000000..f2ed29f1f
--- /dev/null
+++ b/sources/pyside6/libpyside/class_property.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef CLASS_PROPERTY_H
+#define CLASS_PROPERTY_H
+
+#include "pysidemacros.h"
+#include <sbkpython.h>
+
+extern "C" {
+
+struct propertyobject {
+ PyObject_HEAD
+ PyObject *prop_get;
+ PyObject *prop_set;
+ PyObject *prop_del;
+ PyObject *prop_doc;
+ int getter_doc;
+};
+
+struct propertyobject310 {
+ PyObject_HEAD
+ PyObject *prop_get;
+ PyObject *prop_set;
+ PyObject *prop_del;
+ PyObject *prop_doc;
+ // Note: This is a problem with Limited API: We have no direct access.
+ // You need to pick it from runtime info.
+ PyObject *prop_name;
+ int getter_doc;
+};
+
+PYSIDE_API PyTypeObject *PyClassProperty_TypeF();
+
+} // extern "C"
+
+namespace PySide::ClassProperty {
+
+PYSIDE_API void init(PyObject *module);
+
+} // namespace PySide::ClassProperty
+
+#endif // CLASS_PROPERTY_H
diff --git a/sources/pyside6/libpyside/dynamicqmetaobject.cpp b/sources/pyside6/libpyside/dynamicqmetaobject.cpp
new file mode 100644
index 000000000..048001f81
--- /dev/null
+++ b/sources/pyside6/libpyside/dynamicqmetaobject.cpp
@@ -0,0 +1,675 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "dynamicqmetaobject.h"
+#include "pysideqobject.h"
+#include "pysidesignal.h"
+#include "pysidesignal_p.h"
+#include "pysideproperty.h"
+#include "pysideproperty_p.h"
+#include "pysideslot_p.h"
+#include "pysideqenum.h"
+#include "pyside_p.h"
+#include "pysidestaticstrings.h"
+
+#include <shiboken.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QList>
+#include <private/qmetaobjectbuilder_p.h>
+
+#include <cstring>
+#include <vector>
+
+using namespace Qt::StringLiterals;
+
+using namespace PySide;
+
+// MetaObjectBuilder: Provides the QMetaObject's returned by
+// QObject::metaObject() for PySide6 objects. There are several
+// scenarios to consider:
+// 1) A plain Qt class (say QTimer) is instantiated. In that case,
+// return the base meta object until a modification is made by
+// adding methods, properties or class info (cf qmetaobject_test.py).
+// In that case, instantiate a QMetaObjectBuilder inheriting the
+// base meta meta object, add the method and return the result
+// of QMetaObjectBuilder::toMetaObject() (with dirty handling should
+// further modifications be made).
+// 2) A Python class inheriting a Qt class is instantiated. For this,
+// instantiate a QMetaObjectBuilder and add the methods/properties
+// found by inspecting the Python class.
+
+class MetaObjectBuilderPrivate
+{
+public:
+ using MetaObjects = std::vector<const QMetaObject *>;
+
+ QMetaObjectBuilder *ensureBuilder();
+ void parsePythonType(PyTypeObject *type);
+ int indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const;
+ int indexOfProperty(const QByteArray &name) const;
+ int addSlot(const QByteArray &signature);
+ int addSlot(const QByteArray &signature, const QByteArray &type,
+ const QByteArray &tag = {});
+ int addSignal(const QByteArray &signature);
+ void removeMethod(QMetaMethod::MethodType mtype, int index);
+ int getPropertyNotifyId(PySideProperty *property) const;
+ int addProperty(const QByteArray &property, PyObject *data);
+ void addInfo(const QByteArray &key, const QByteArray &value);
+ void addInfo(const QMap<QByteArray, QByteArray> &info);
+ void addEnumerator(const char *name, bool flag, bool scoped,
+ const MetaObjectBuilder::EnumValues &entries);
+ void removeProperty(int index);
+ const QMetaObject *update();
+
+ QMetaObjectBuilder *m_builder = nullptr;
+
+ const QMetaObject *m_baseObject = nullptr;
+ MetaObjects m_cachedMetaObjects;
+ bool m_dirty = true;
+
+private:
+ QMetaPropertyBuilder
+ createProperty(PySideProperty *property, const QByteArray &propertyName);
+};
+
+QMetaObjectBuilder *MetaObjectBuilderPrivate::ensureBuilder()
+{
+ if (!m_builder) {
+ m_builder = new QMetaObjectBuilder();
+ m_builder->setClassName(m_baseObject->className());
+ m_builder->setSuperClass(m_baseObject);
+ }
+ return m_builder;
+}
+
+MetaObjectBuilder::MetaObjectBuilder(const char *className, const QMetaObject *metaObject) :
+ m_d(new MetaObjectBuilderPrivate)
+{
+ m_d->m_baseObject = metaObject;
+ m_d->m_builder = new QMetaObjectBuilder();
+ m_d->m_builder->setClassName(className);
+ m_d->m_builder->setSuperClass(metaObject);
+ m_d->m_builder->setClassName(className);
+}
+
+MetaObjectBuilder::MetaObjectBuilder(PyTypeObject *type, const QMetaObject *metaObject)
+ : m_d(new MetaObjectBuilderPrivate)
+{
+ m_d->m_baseObject = metaObject;
+ const char *className = type->tp_name;
+ if (const char *lastDot = strrchr(type->tp_name, '.'))
+ className = lastDot + 1;
+ // Different names indicate a Python class inheriting a Qt class.
+ // Parse the type.
+ if (strcmp(className, metaObject->className()) != 0) {
+ m_d->m_builder = new QMetaObjectBuilder();
+ m_d->m_builder->setClassName(className);
+ m_d->m_builder->setSuperClass(metaObject);
+ m_d->parsePythonType(type);
+ }
+}
+
+MetaObjectBuilder::~MetaObjectBuilder()
+{
+ for (auto *metaObject : m_d->m_cachedMetaObjects)
+ free(const_cast<QMetaObject*>(metaObject));
+ delete m_d->m_builder;
+ delete m_d;
+}
+
+int MetaObjectBuilderPrivate::indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const
+{
+ int result = -1;
+ if (m_builder) {
+ switch (mtype) {
+ case QMetaMethod::Signal:
+ result = m_builder->indexOfSignal(signature);
+ break;
+ case QMetaMethod::Slot:
+ result = m_builder->indexOfSlot(signature);
+ break;
+ case QMetaMethod::Constructor:
+ result = m_builder->indexOfConstructor(signature);
+ break;
+ case QMetaMethod::Method:
+ result = m_builder->indexOfMethod(signature);
+ break;
+ }
+ if (result >= 0)
+ return result + m_baseObject->methodCount();
+ }
+ switch (mtype) {
+ case QMetaMethod::Signal:
+ result = m_baseObject->indexOfSignal(signature);
+ break;
+ case QMetaMethod::Slot:
+ result = m_baseObject->indexOfSlot(signature);
+ break;
+ case QMetaMethod::Constructor:
+ result = m_baseObject->indexOfConstructor(signature);
+ break;
+ case QMetaMethod::Method:
+ result = m_baseObject->indexOfMethod(signature);
+ break;
+ }
+ return result;
+}
+
+int MetaObjectBuilder::indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const
+{
+ return m_d->indexOfMethod(mtype, signature);
+}
+
+int MetaObjectBuilderPrivate::indexOfProperty(const QByteArray &name) const
+{
+ if (m_builder) {
+ const int result = m_builder->indexOfProperty(name);
+ if (result >= 0)
+ return m_baseObject->propertyCount() + result;
+ }
+ return m_baseObject->indexOfProperty(name);
+}
+
+int MetaObjectBuilder::indexOfProperty(const QByteArray &name) const
+{
+ return m_d->indexOfProperty(name);
+}
+
+static bool checkMethodSignature(const QByteArray &signature)
+{
+ // Common mistake not to add parentheses to the signature.
+ const auto openParen = signature.indexOf('(');
+ const auto closingParen = signature.lastIndexOf(')');
+ const bool ok = openParen != -1 && closingParen != -1 && openParen < closingParen;
+ if (!ok) {
+ const QByteArray message =
+ "MetaObjectBuilder::addMethod: Invalid method signature provided for \""
+ + signature + '"';
+ PyErr_WarnEx(PyExc_RuntimeWarning, message.constData(), 0);
+ }
+ return ok;
+}
+
+int MetaObjectBuilderPrivate::addSlot(const QByteArray &signature)
+{
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ return m_baseObject->methodCount()
+ + ensureBuilder()->addSlot(signature).index();
+}
+
+int MetaObjectBuilder::addSlot(const char *signature)
+{
+ return m_d->addSlot(signature);
+}
+
+int MetaObjectBuilderPrivate::addSlot(const QByteArray &signature,
+ const QByteArray &type,
+ const QByteArray &tag)
+{
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ QMetaMethodBuilder methodBuilder = ensureBuilder()->addSlot(signature);
+ if (!type.isEmpty() && type != "void"_ba)
+ methodBuilder.setReturnType(type);
+ if (!tag.isEmpty())
+ methodBuilder.setTag(tag);
+ return m_baseObject->methodCount() + methodBuilder.index();
+}
+
+int MetaObjectBuilder::addSlot(const char *signature, const char *type)
+{
+ return m_d->addSlot(signature, type);
+}
+
+int MetaObjectBuilderPrivate::addSignal(const QByteArray &signature)
+{
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ return m_baseObject->methodCount()
+ + ensureBuilder()->addSignal(signature).index();
+}
+
+int MetaObjectBuilder::addSignal(const char *signature)
+{
+ return m_d->addSignal(signature);
+}
+
+void MetaObjectBuilderPrivate::removeMethod(QMetaMethod::MethodType mtype,
+ int index)
+{
+ index -= m_baseObject->methodCount();
+ auto builder = ensureBuilder();
+ Q_ASSERT(index >= 0 && index < builder->methodCount());
+ switch (mtype) {
+ case QMetaMethod::Constructor:
+ builder->removeConstructor(index);
+ break;
+ default:
+ builder->removeMethod(index);
+ break;
+ }
+ m_dirty = true;
+}
+
+void MetaObjectBuilder::removeMethod(QMetaMethod::MethodType mtype, int index)
+{
+ m_d->removeMethod(mtype, index);
+}
+
+int MetaObjectBuilderPrivate::getPropertyNotifyId(PySideProperty *property) const
+{
+ int notifyId = -1;
+ if (property->d->notify) {
+ if (const char *signalNotify = PySide::Property::getNotifyName(property))
+ notifyId = indexOfMethod(QMetaMethod::Signal, signalNotify);
+ }
+ return notifyId;
+}
+
+QMetaPropertyBuilder
+ MetaObjectBuilderPrivate::createProperty(PySideProperty *property,
+ const QByteArray &propertyName)
+{
+ int propertyNotifyId = getPropertyNotifyId(property);
+ if (propertyNotifyId >= 0)
+ propertyNotifyId -= m_baseObject->methodCount();
+
+ // For QObject-derived Python types, retrieve the meta type registered
+ // by name from the qmlRegisterType, if there is one. This is required for
+ // grouped QML properties to work.
+ auto *builder = ensureBuilder();
+ auto *typeObject = Property::getTypeObject(property);
+ if (typeObject != nullptr && PyType_Check(typeObject)) {
+ auto *pyTypeObject = reinterpret_cast<PyTypeObject *>(typeObject);
+ if (qstrncmp(pyTypeObject->tp_name, "PySide", 6) != 0
+ && PySide::isQObjectDerived(pyTypeObject, false)) {
+ const QByteArray pyType(pyTypeObject->tp_name);
+ const auto metaType = QMetaType::fromName(pyType + '*');
+ if (metaType.isValid()) {
+ return builder->addProperty(propertyName, pyType,
+ metaType, propertyNotifyId);
+ }
+ }
+ }
+ return builder->addProperty(propertyName, property->d->typeName,
+ propertyNotifyId);
+}
+
+int MetaObjectBuilderPrivate::addProperty(const QByteArray &propertyName,
+ PyObject *data)
+{
+ int index = indexOfProperty(propertyName);
+ if (index != -1)
+ return index;
+
+ auto *property = reinterpret_cast<PySideProperty *>(data);
+ auto newProperty = createProperty(property, propertyName);
+
+ // Adding property attributes
+ newProperty.setReadable(PySide::Property::isReadable(property));
+ newProperty.setWritable(PySide::Property::isWritable(property));
+ newProperty.setResettable(PySide::Property::hasReset(property));
+ newProperty.setDesignable(PySide::Property::isDesignable(property));
+ newProperty.setScriptable(PySide::Property::isScriptable(property));
+ newProperty.setStored(PySide::Property::isStored(property));
+ newProperty.setUser(PySide::Property::isUser(property));
+ newProperty.setConstant(PySide::Property::isConstant(property));
+ newProperty.setFinal(PySide::Property::isFinal(property));
+
+ index = newProperty.index() + m_baseObject->propertyCount();
+ m_dirty = true;
+ return index;
+}
+
+int MetaObjectBuilder::addProperty(const char *property, PyObject *data)
+{
+ return m_d->addProperty(property, data);
+}
+
+void MetaObjectBuilderPrivate::addInfo(const QByteArray &key,
+ const QByteArray &value)
+{
+ ensureBuilder()->addClassInfo(key, value);
+ m_dirty = true;
+}
+
+void MetaObjectBuilder::addInfo(const char *key, const char *value)
+{
+ m_d->addInfo(key, value);
+}
+
+void MetaObjectBuilderPrivate::addInfo(const QMap<QByteArray, QByteArray> &info)
+{
+ auto builder = ensureBuilder();
+ for (auto i = info.constBegin(), end = info.constEnd(); i != end; ++i)
+ builder->addClassInfo(i.key(), i.value());
+ m_dirty = true;
+}
+
+void MetaObjectBuilder::addInfo(const QMap<QByteArray, QByteArray> &info)
+{
+ m_d->addInfo(info);
+}
+
+void MetaObjectBuilder::addEnumerator(const char *name, bool flag, bool scoped,
+ const EnumValues &entries)
+{
+ m_d->addEnumerator(name, flag, scoped, entries);
+}
+
+void MetaObjectBuilderPrivate::addEnumerator(const char *name, bool flag, bool scoped,
+ const MetaObjectBuilder::EnumValues &entries)
+{
+ auto builder = ensureBuilder();
+ int have_already = builder->indexOfEnumerator(name);
+ if (have_already >= 0)
+ builder->removeEnumerator(have_already);
+ auto enumbuilder = builder->addEnumerator(name);
+ enumbuilder.setIsFlag(flag);
+ enumbuilder.setIsScoped(scoped);
+
+ for (const auto &item : entries)
+ enumbuilder.addKey(item.first, item.second);
+ m_dirty = true;
+}
+
+void MetaObjectBuilderPrivate::removeProperty(int index)
+{
+ index -= m_baseObject->propertyCount();
+ auto builder = ensureBuilder();
+ Q_ASSERT(index >= 0 && index < builder->propertyCount());
+ builder->removeProperty(index);
+ m_dirty = true;
+}
+
+void MetaObjectBuilder::removeProperty(int index)
+{
+ m_d->removeProperty(index);
+}
+
+// PYSIDE-315: Instead of sorting the items and maybe breaking indices, we
+// ensure that the signals and slots are sorted by the improved
+// parsePythonType() (signals must go before slots). The order can only
+// become distorted if the class is modified after creation. In that
+// case, we give a warning.
+
+static QString msgMethodSortOrder(const QMetaObject *mo, int offendingIndex)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "\n\n*** Sort Warning ***\nSignals and slots in QMetaObject '"
+ << mo->className()
+ << "' are not ordered correctly, this may lead to issues.\n";
+ const int methodOffset = mo->methodOffset();
+ for (int m = methodOffset, methodCount = mo->methodCount(); m < methodCount; ++m) {
+ const auto method = mo->method(m);
+ str << (m - methodOffset + 1) << (m > offendingIndex ? '!' : ' ')
+ << (method.methodType() == QMetaMethod::Signal ? " Signal " : " Slot ")
+ << method.methodSignature() << '\n';
+ }
+ return result;
+}
+
+static void checkMethodOrder(const QMetaObject *metaObject)
+{
+ const int lastMethod = metaObject->methodCount() - 1;
+ for (int m = metaObject->methodOffset(); m < lastMethod; ++m) {
+ if (metaObject->method(m).methodType() == QMetaMethod::Slot
+ && metaObject->method(m + 1).methodType() == QMetaMethod::Signal) {
+ const auto message = msgMethodSortOrder(metaObject, m);
+ PyErr_WarnEx(PyExc_RuntimeWarning, qPrintable(message), 0);
+ // Prevent a warning from being turned into an error. We cannot easily unwind.
+ PyErr_Clear();
+ break;
+ }
+ }
+}
+
+const QMetaObject *MetaObjectBuilderPrivate::update()
+{
+ if (!m_builder)
+ return m_baseObject;
+ if (m_cachedMetaObjects.empty() || m_dirty) {
+ // PYSIDE-803: The dirty branch needs to be protected by the GIL.
+ // This was moved from SignalManager::retrieveMetaObject to here,
+ // which is only the update in "return builder->update()".
+ Shiboken::GilState gil;
+ m_cachedMetaObjects.push_back(m_builder->toMetaObject());
+ checkMethodOrder(m_cachedMetaObjects.back());
+ m_dirty = false;
+ }
+ return m_cachedMetaObjects.back();
+}
+
+const QMetaObject *MetaObjectBuilder::update()
+{
+ return m_d->update();
+}
+
+static void formatEnum(QTextStream &str, const QMetaEnum &e)
+{
+ str << '"' << e.name() << "\" {";
+ for (int k = 0, cnt = e.keyCount(); k < cnt; ++k) {
+ if (k)
+ str << ", ";
+ str << e.key(k);
+ }
+ str << "}";
+}
+
+static void formatProperty(QTextStream &str, const QMetaProperty &p)
+{
+ str << '"' << p.name() << "\", " << p.typeName();
+ if (p.isWritable())
+ str << " [writeable]";
+ if (p.isResettable())
+ str << " [resettable]";
+ if (p.isConstant())
+ str << " [constant]";
+ if (p.isFinal())
+ str << " [final]";
+ if (p.isDesignable())
+ str << " [designable]";
+ auto sig = p.notifySignal();
+ if (sig.isValid())
+ str << ", notify=" << sig.name();
+}
+
+static void formatMethod(QTextStream &str, const QMetaMethod &m)
+{
+ str << "type=";
+ switch (m.methodType()) {
+ case QMetaMethod::Method:
+ str << "Method";
+ break;
+ case QMetaMethod::Signal:
+ str << "Signal";
+ break;
+ case QMetaMethod::Slot:
+ str << "Slot";
+ break;
+ case QMetaMethod::Constructor:
+ str << "Constructor";
+ break;
+ }
+
+ str << ", signature="
+ << m.methodSignature();
+ const QByteArrayList parms = m.parameterTypes();
+ if (!parms.isEmpty())
+ str << ", parameters=" << parms.join(", ");
+}
+
+QString MetaObjectBuilder::formatMetaObject(const QMetaObject *metaObject)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "PySide" << QT_VERSION_MAJOR << ".QtCore.QMetaObject(\""
+ << metaObject->className() << '"';
+ if (auto *s = metaObject->superClass())
+ str << " inherits \"" << s->className() << '"';
+ str << ":\n";
+
+ int offset = metaObject->enumeratorOffset();
+ int count = metaObject->enumeratorCount();
+ if (offset < count) {
+ str << "Enumerators:\n";
+ for (int e = offset; e < count; ++e) {
+ str << " #" << e << ' ';
+ formatEnum(str, metaObject->enumerator(e));
+ str << '\n';
+ }
+ }
+
+ offset = metaObject->propertyOffset();
+ count = metaObject->propertyCount();
+ if (offset < count) {
+ str << "Properties:\n";
+ for (int p = offset; p < count; ++p) {
+ str << " #" << p << ' ';
+ formatProperty(str, metaObject->property(p));
+ str << '\n';
+ }
+ }
+
+ offset = metaObject->methodOffset();
+ count = metaObject->methodCount();
+ if (offset < count) {
+ str << "Methods:\n";
+ for (int m = offset; m < count; ++m) {
+ str << " #" << m << ' ';
+ formatMethod(str, metaObject->method(m));
+ str << '\n';
+ }
+ }
+
+ str << ')';
+ return result;
+}
+
+using namespace Shiboken;
+
+void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
+{
+ // Get all non-QObject-derived base types in method resolution order, filtering out the types
+ // that can't have signals, slots or properties.
+ // This enforces registering of all signals and slots at type parsing time, and not later at
+ // signal connection time, thus making sure no method indices change which would break
+ // existing connections.
+ const PyObject *mro = type->tp_mro;
+ const Py_ssize_t basesCount = PyTuple_GET_SIZE(mro);
+
+ std::vector<PyTypeObject *> basesToCheck;
+ // Prepend the actual type that we are parsing.
+ basesToCheck.reserve(1u + basesCount);
+ basesToCheck.push_back(type);
+
+ auto sbkObjTypeF = SbkObject_TypeF();
+ auto baseObjType = reinterpret_cast<PyTypeObject *>(&PyBaseObject_Type);
+ for (Py_ssize_t i = 0; i < basesCount; ++i) {
+ auto baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
+ if (baseType != sbkObjTypeF && baseType != baseObjType
+ && !PySide::isQObjectDerived(baseType, false)) {
+ basesToCheck.push_back(baseType);
+ }
+ }
+
+ // PYSIDE-315: Handle all signals first, in all involved types.
+ // Leave the properties to be registered after signals because they may depend on
+ // notify signals.
+ for (PyTypeObject *baseType : basesToCheck) {
+ AutoDecRef tpDict(PepType_GetDict(baseType));
+ PyObject *attrs = tpDict.object();
+ PyObject *key = nullptr;
+ PyObject *value = nullptr;
+ Py_ssize_t pos = 0;
+
+ while (PyDict_Next(attrs, &pos, &key, &value)) {
+ if (Signal::checkType(value)) {
+ // Register signals.
+ auto *data = reinterpret_cast<PySideSignal *>(value)->data;
+ if (data->signalName.isEmpty())
+ data->signalName = String::toCString(key);
+ for (const auto &s : data->signatures) {
+ const auto sig = data->signalName + '(' + s.signature + ')';
+ if (m_baseObject->indexOfSignal(sig) == -1) {
+ // Registering the parameterNames to the QMetaObject (PYSIDE-634)
+ // from:
+ // Signal(..., arguments=['...', ...]
+ // the arguments are now on data-data->signalArguments
+ auto builder = m_builder->addSignal(sig);
+ if (!data->signalArguments.isEmpty())
+ builder.setParameterNames(data->signalArguments);
+ }
+ }
+ }
+ }
+ }
+
+ PyObject *slotAttrName = PySide::PySideMagicName::slot_list_attr();
+ // PYSIDE-315: Now take care of the rest.
+ // Signals and slots should be separated, unless the types are modified, later.
+ // We check for this using "is_sorted()". Sorting no longer happens at all.
+ for (PyTypeObject *baseType : basesToCheck) {
+ AutoDecRef tpDict(PepType_GetDict(baseType));
+ PyObject *attrs = tpDict.object();
+ PyObject *key = nullptr;
+ PyObject *value = nullptr;
+ Py_ssize_t pos = 0;
+
+ while (PyDict_Next(attrs, &pos, &key, &value)) {
+ if (Property::checkType(value)) {
+ const QByteArray name = String::toCString(key);
+ const int index = m_baseObject->indexOfProperty(name);
+ if (index == -1)
+ addProperty(name, value);
+ } else if (PepType_GetSlot(Py_TYPE(value), Py_tp_call) != nullptr) {
+ // PYSIDE-198: PyFunction_Check does not work with Nuitka.
+ // Register slots.
+ if (PyObject_HasAttr(value, slotAttrName)) {
+ auto *capsule = PyObject_GetAttr(value, slotAttrName);
+ const auto *entryList = PySide::Slot::dataListFromCapsule(capsule);
+ for (const auto &e : *entryList) {
+ if (m_baseObject->indexOfSlot(e.signature) == -1)
+ addSlot(e.signature, e.resultType, e.tag);
+ }
+ }
+ }
+ }
+ }
+ // PYSIDE-957: Collect the delayed QEnums
+ auto collectedEnums = PySide::QEnum::resolveDelayedQEnums(type);
+ for (PyObject *obEnumType : collectedEnums) {
+ bool isFlag = PySide::QEnum::isFlag(obEnumType);
+ AutoDecRef obName(PyObject_GetAttr(obEnumType, PyMagicName::name()));
+ // Everything has been checked already in resolveDelayedQEnums.
+ // Therefore, we don't need to error-check here again.
+ auto name = String::toCString(obName);
+ AutoDecRef members(PyObject_GetAttr(obEnumType, PyMagicName::members()));
+ AutoDecRef items(PyMapping_Items(members));
+ Py_ssize_t nr_items = PySequence_Length(items);
+
+ QList<std::pair<QByteArray, int> > entries;
+ for (Py_ssize_t idx = 0; idx < nr_items; ++idx) {
+ AutoDecRef item(PySequence_GetItem(items, idx));
+ AutoDecRef key(PySequence_GetItem(item, 0));
+ AutoDecRef member(PySequence_GetItem(item, 1));
+ AutoDecRef value(PyObject_GetAttr(member, Shiboken::PyName::value()));
+ auto ckey = String::toCString(key);
+ auto ivalue = PyLong_AsSsize_t(value);
+ entries.push_back(std::make_pair(ckey, int(ivalue)));
+ }
+ addEnumerator(name, isFlag, true, entries);
+ }
+}
diff --git a/sources/pyside6/libpyside/dynamicqmetaobject.h b/sources/pyside6/libpyside/dynamicqmetaobject.h
new file mode 100644
index 000000000..dd33f65f7
--- /dev/null
+++ b/sources/pyside6/libpyside/dynamicqmetaobject.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef DYNAMICQMETAOBJECT_H
+#define DYNAMICQMETAOBJECT_H
+
+#include <sbkpython.h>
+#include <pysidemacros.h>
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QMetaMethod>
+
+#include <utility>
+
+class MetaObjectBuilderPrivate;
+
+namespace PySide
+{
+
+class MetaObjectBuilder
+{
+ Q_DISABLE_COPY_MOVE(MetaObjectBuilder)
+public:
+ using EnumValue = std::pair<QByteArray, int>;
+ using EnumValues = QList<EnumValue>;
+
+ MetaObjectBuilder(const char *className, const QMetaObject *metaObject);
+
+ MetaObjectBuilder(PyTypeObject *type, const QMetaObject *metaObject);
+ ~MetaObjectBuilder();
+
+ int indexOfMethod(QMetaMethod::MethodType mtype, const QByteArray &signature) const;
+ int indexOfProperty(const QByteArray &name) const;
+ int addSlot(const char *signature);
+ int addSlot(const char *signature, const char *type);
+ int addSignal(const char *signature);
+ void removeMethod(QMetaMethod::MethodType mtype, int index);
+ int addProperty(const char *property, PyObject *data);
+ void addInfo(const char *key, const char *value);
+ void addInfo(const QMap<QByteArray, QByteArray> &info);
+ void addEnumerator(const char *name, bool flag,
+ bool scoped, const EnumValues &entries);
+ void removeProperty(int index);
+
+ const QMetaObject *update();
+
+ PYSIDE_API static QString formatMetaObject(const QMetaObject *metaObject);
+
+private:
+ MetaObjectBuilderPrivate *m_d;
+};
+
+}
+#endif
diff --git a/sources/pyside6/libpyside/feature_select.cpp b/sources/pyside6/libpyside/feature_select.cpp
new file mode 100644
index 000000000..cfd465267
--- /dev/null
+++ b/sources/pyside6/libpyside/feature_select.cpp
@@ -0,0 +1,798 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "feature_select.h"
+#include "pysidecleanup.h"
+#include "pysideqobject.h"
+#include "pysidestaticstrings.h"
+#include "class_property.h"
+
+#include <shiboken.h>
+#include <sbkfeature_base.h>
+#include <signature_p.h>
+
+#include <QtCore/QStringList>
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PYSIDE-1019: Support switchable extensions
+//
+// This functionality is no longer implemented in the signature module, since
+// the PyCFunction getsets do not have to be modified any longer.
+// Instead, we simply exchange the complete class dicts. This is done in the
+// basewrapper.cpp file and in every generated `tp_(get|set)attro`.
+//
+// This is the general framework of the switchable extensions.
+// A maximum of eight features is planned so far. This seems to be enough.
+// More features are possible, but then we must somehow register the
+// extra `select_id`s above 255.
+//
+
+/*****************************************************************************
+
+ How Does This Feature Selection Work?
+ -------------------------------------
+
+The basic idea is to replace the `tp_dict` of a QObject derived type.
+This way, we can replace the methods of the class in no time.
+
+The crucial point to understand is how the `tp_dict` is actually accessed:
+When you type "QObject.__dict__", the descriptor of `SbkObjectType_Type`
+is called. This descriptor is per default unassigned, so the base class
+PyType_Type provides the tp_getset method `type_dict`:
+
+ static PyObject *
+ type_dict(PyTypeObject *type, void *context)
+ {
+ if (type->tp_dict == NULL) {
+ Py_RETURN_NONE;
+ }
+ return PyDictProxy_New(type->tp_dict);
+ }
+
+In order to change that, we need to insert our own version into SbkObjectType:
+
+ static PyObject *Sbk_TypeGet___dict__(PyTypeObject *type, void *context)
+ {
+ auto dict = type->tp_dict;
+ if (dict == NULL)
+ Py_RETURN_NONE;
+ if (SelectFeatureSet != nullptr)
+ dict = SelectFeatureSet(type);
+ return PyDictProxy_New(dict);
+ }
+
+This way, the Python function `type_ready()` does not fill in the default,
+but uses our modified version. It a similar way, we overwrite type_getattro
+with our own version, again in SbkObjectType, replacing the default of
+PyType_Type.
+
+Now we can exchange the dict with a customized version.
+We have our own derived type `ChameleonDict` with additional attributes.
+These allow us to create a ring of dicts which can be rotated to the actual
+needed dict version:
+
+Every dict has a field `select_id` which is selected by the `from __feature__`
+import. The dicts are cyclic connected by the `dict_ring` field.
+
+When a class dict is required, now always `SelectFeatureSet` is called, which
+looks into the `__name__` attribute of the active module and decides which
+version of `tp_dict` is needed. Then the right dict is searched in the ring
+and created if not already there.
+
+Furthermore, we need to overwrite every `tp_(get|set)attro` with a version
+that switches dicts right before looking up methods.
+The dict changing must walk the whole `tp_mro` in order to change all names.
+
+This is everything that the following code does.
+
+*****************************************************************************/
+
+
+namespace PySide::Feature {
+
+using namespace Shiboken;
+
+using FeatureProc = bool(*)(PyTypeObject *type, PyObject *prev_dict, int id);
+
+static FeatureProc *featurePointer = nullptr;
+
+// Create a derived dict class
+static PyTypeObject *
+createDerivedDictType()
+{
+ // It is not easy to create a compatible dict object with the
+ // limited API. Easier is to use Python to create a derived
+ // type and to modify that a bit from the C code.
+ PyObject *ChameleonDict = PepRun_GetResult(R"CPP(if True:
+
+ class ChameleonDict(dict):
+ __slots__ = ("dict_ring", "select_id", "orig_dict")
+
+ result = ChameleonDict
+
+ )CPP");
+ return reinterpret_cast<PyTypeObject *>(ChameleonDict);
+}
+
+static PyTypeObject *new_dict_type = nullptr;
+
+static void ensureNewDictType()
+{
+ if (new_dict_type == nullptr) {
+ new_dict_type = createDerivedDictType();
+ if (new_dict_type == nullptr)
+ Py_FatalError("PySide6: Problem creating ChameleonDict");
+ }
+}
+
+static inline PyObject *nextInCircle(PyObject *dict)
+{
+ // returns a borrowed ref
+ AutoDecRef next_dict(PyObject_GetAttr(dict, PySideName::dict_ring()));
+ return next_dict;
+}
+
+static inline void setNextDict(PyObject *dict, PyObject *next_dict)
+{
+ PyObject_SetAttr(dict, PySideName::dict_ring(), next_dict);
+}
+
+static inline void setSelectId(PyObject *dict, int select_id)
+{
+ PyObject_SetAttr(dict, PySideName::select_id(), PyLong_FromLong(select_id));
+}
+
+static inline int getSelectId(PyObject *dict)
+{
+ auto *py_select_id = PyObject_GetAttr(dict, PyName::select_id());
+ if (py_select_id == nullptr) {
+ PyErr_Clear();
+ return 0;
+ }
+ int ret = PyLong_AsLong(py_select_id);
+ Py_DECREF(py_select_id);
+ return ret;
+}
+
+static bool replaceClassDict(PyTypeObject *type)
+{
+ /*
+ * Replace the type dict by the derived ChameleonDict.
+ * This is mandatory for all type dicts when they are touched.
+ */
+ ensureNewDictType();
+ AutoDecRef dict(PepType_GetDict(type));
+ auto *ob_ndt = reinterpret_cast<PyObject *>(new_dict_type);
+ auto *new_dict = PyObject_CallObject(ob_ndt, nullptr);
+ if (new_dict == nullptr || PyDict_Update(new_dict, dict) < 0)
+ return false;
+ // Insert the default id. Cannot fail for small numbers.
+ setSelectId(new_dict, 0);
+ // insert the dict into itself as ring
+ setNextDict(new_dict, new_dict);
+ // We have now an exact copy of the dict with a new type.
+ PepType_SetDict(type, new_dict);
+ // PYSIDE-2404: Retain the original dict for easy late init.
+ PyObject_SetAttr(new_dict, PySideName::orig_dict(), dict);
+ return true;
+}
+
+static bool addNewDict(PyTypeObject *type, int select_id)
+{
+ /*
+ * Add a new dict to the ring and set it as `type->tp_dict`.
+ * A 'false' return is fatal.
+ */
+ AutoDecRef dict(PepType_GetDict(type));
+ AutoDecRef orig_dict(PyObject_GetAttr(dict, PySideName::orig_dict()));
+ auto *ob_ndt = reinterpret_cast<PyObject *>(new_dict_type);
+ auto *new_dict = PyObject_CallObject(ob_ndt, nullptr);
+ if (new_dict == nullptr)
+ return false;
+ setSelectId(new_dict, select_id);
+ // insert the dict into the ring
+ auto next_dict = nextInCircle(dict);
+ setNextDict(dict, new_dict);
+ setNextDict(new_dict, next_dict);
+ PepType_SetDict(type, new_dict);
+ // PYSIDE-2404: Retain the original dict for easy late init.
+ PyObject_SetAttr(new_dict, PySideName::orig_dict(), orig_dict);
+ return true;
+}
+
+static inline bool moveToFeatureSet(PyTypeObject *type, int select_id)
+{
+ /*
+ * Rotate the ring to the given `select_id` and return `true`.
+ * If not found, stay at the current position and return `false`.
+ */
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *initial_dict = tpDict.object();
+ auto *dict = initial_dict;
+ do {
+ int current_id = getSelectId(dict);
+ // This works because small numbers are singleton objects.
+ if (current_id == select_id) {
+ PepType_SetDict(type, dict);
+ return true;
+ }
+ dict = nextInCircle(dict);
+ } while (dict != initial_dict);
+ PepType_SetDict(type, initial_dict);
+ return false;
+}
+
+static bool createNewFeatureSet(PyTypeObject *type, int select_id)
+{
+ /*
+ * Create a new feature set.
+ * A `false` return value is a fatal error.
+ *
+ * A FeatureProc sees an empty `type->tp_dict` and the previous dict
+ * content in `prev_dict`. It is responsible of filling `type->tp_dict`
+ * with modified content.
+ */
+
+ bool ok = moveToFeatureSet(type, 0);
+ Q_UNUSED(ok);
+ assert(ok);
+
+ AutoDecRef prev_dict(PepType_GetDict(type));
+ if (!addNewDict(type, select_id))
+ return false;
+ int id = select_id;
+ if (id == -1)
+ return false;
+ FeatureProc *proc = featurePointer;
+ for (int idx = id; *proc != nullptr; ++proc, idx >>= 1) {
+ if (idx & 1) {
+ // clear the tp_dict that will get new content
+ AutoDecRef tpDict(PepType_GetDict(type));
+ PyDict_Clear(tpDict);
+ // let the proc re-fill the tp_dict
+ if (!(*proc)(type, prev_dict, id))
+ return false;
+ // if there is still a step, prepare `prev_dict`
+ if (idx >> 1) {
+ prev_dict.reset(PyDict_Copy(tpDict.object()));
+ if (prev_dict.isNull())
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static inline void SelectFeatureSetSubtype(PyTypeObject *type, int select_id)
+{
+ /*
+ * This is the selector for one sublass. We need to call this for
+ * every subclass until no more subclasses or reaching the wanted id.
+ */
+ static const auto *pyTypeType_tp_dict = PepType_GetDict(&PyType_Type);
+ AutoDecRef tpDict(PepType_GetDict(type));
+ if (Py_TYPE(tpDict.object()) == Py_TYPE(pyTypeType_tp_dict)) {
+ // On first touch, we initialize the dynamic naming.
+ // The dict type will be replaced after the first call.
+ if (!replaceClassDict(type)) {
+ Py_FatalError("failed to replace class dict!");
+ return;
+ }
+ }
+ if (!moveToFeatureSet(type, select_id)) {
+ if (!createNewFeatureSet(type, select_id)) {
+ Py_FatalError("failed to create a new feature set!");
+ return;
+ }
+ }
+ }
+
+static PyObject *cached_globals{};
+static int last_select_id{};
+
+static inline int getFeatureSelectId()
+{
+ static auto *undef = PyLong_FromLong(-1);
+ static auto *feature_dict = GetFeatureDict();
+ // these things are all borrowed
+ auto *globals = PyEval_GetGlobals();
+ if (globals == nullptr
+ || globals == cached_globals)
+ return last_select_id;
+
+ auto *modname = PyDict_GetItem(globals, PyMagicName::name());
+ if (modname == nullptr)
+ return last_select_id;
+
+ auto *py_select_id = PyDict_GetItem(feature_dict, modname);
+ if (py_select_id == nullptr
+ || !PyLong_Check(py_select_id)
+ || py_select_id == undef)
+ return last_select_id;
+
+ cached_globals = globals;
+ last_select_id = PyLong_AsLong(py_select_id) & 0xff;
+ return last_select_id;
+}
+
+static inline void SelectFeatureSet(PyTypeObject *type)
+{
+ /*
+ * This is the main function of the module.
+ * The purpose of this function is to switch the dict of a class right
+ * before a (get|set)attro call is performed.
+ *
+ * Generated functions call this directly.
+ * Shiboken will assign it via a public hook of `basewrapper.cpp`.
+ */
+ static const auto *pyTypeType_tp_dict = PepType_GetDict(&PyType_Type);
+ AutoDecRef tpDict(PepType_GetDict(type));
+ if (Py_TYPE(tpDict.object()) == Py_TYPE(pyTypeType_tp_dict)) {
+ // We initialize the dynamic features by using our own dict type.
+ if (!replaceClassDict(type)) {
+ Py_FatalError("failed to replace class dict!");
+ return;
+ }
+ }
+
+ int select_id = getFeatureSelectId();
+ static int last_select_id{};
+ static PyTypeObject *last_type{};
+
+ // PYSIDE-2029: Implement a very simple but effective cache that cannot fail.
+ if (type == last_type && select_id == last_select_id)
+ return;
+ last_type = type;
+ last_select_id = select_id;
+
+ auto *mro = type->tp_mro;
+ Py_ssize_t idx, n = PyTuple_GET_SIZE(mro);
+ // We leave 'Shiboken.Object' and 'object' alone, therefore "n - 2".
+ for (idx = 0; idx < n - 2; idx++) {
+ auto *sub_type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ SelectFeatureSetSubtype(sub_type, select_id);
+ }
+ // PYSIDE-1436: Clear all caches for the type and subtypes.
+ PyType_Modified(type);
+}
+
+// For cppgenerator:
+void Select(PyObject *obj)
+{
+ if (featurePointer == nullptr)
+ return;
+ auto *type = Py_TYPE(obj);
+ SelectFeatureSet(type);
+}
+
+void Select(PyTypeObject *type)
+{
+ if (featurePointer != nullptr)
+ SelectFeatureSet(type);
+}
+
+static bool feature_01_addLowerNames(PyTypeObject *type, PyObject *prev_dict, int id);
+static bool feature_02_true_property(PyTypeObject *type, PyObject *prev_dict, int id);
+static bool feature_04_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int id);
+static bool feature_08_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int id);
+static bool feature_10_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int id);
+static bool feature_20_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int id);
+static bool feature_40_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int id);
+static bool feature_80_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int id);
+
+static FeatureProc featureProcArray[] = {
+ feature_01_addLowerNames,
+ feature_02_true_property,
+ feature_04_addDummyNames,
+ feature_08_addDummyNames,
+ feature_10_addDummyNames,
+ feature_20_addDummyNames,
+ feature_40_addDummyNames,
+ feature_80_addDummyNames,
+ nullptr
+};
+
+static bool patch_property_impl();
+static bool is_initialized = false;
+
+static void featureEnableCallback(bool enable)
+{
+ featurePointer = enable ? featureProcArray : nullptr;
+}
+
+void init()
+{
+ // This function can be called multiple times.
+ if (!is_initialized) {
+ featurePointer = featureProcArray;
+ initSelectableFeature(SelectFeatureSet);
+ setSelectableFeatureCallback(featureEnableCallback);
+ patch_property_impl();
+ is_initialized = true;
+ }
+ last_select_id = 0;
+ // Reset the cache. This is called at any "from __feature__ import".
+ cached_globals = nullptr;
+}
+
+void Enable(bool enable)
+{
+ if (!is_initialized)
+ return;
+ featurePointer = enable ? featureProcArray : nullptr;
+ initSelectableFeature(enable ? SelectFeatureSet : nullptr);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PYSIDE-1019: Support switchable extensions
+//
+// Feature 0x01: Allow snake_case instead of camelCase
+//
+// This functionality is no longer implemented in the signature module, since
+// the PyCFunction getsets do not have to be modified any longer.
+// Instead, we simply exchange the complete class dicts. This is done in the
+// basewrapper.cpp file.
+//
+
+static PyObject *methodWithNewName(PyTypeObject *type,
+ PyMethodDef *meth,
+ const char *new_name)
+{
+ /*
+ * Create a method with a lower case name.
+ */
+ auto *obtype = reinterpret_cast<PyObject *>(type);
+ int len = strlen(new_name);
+ auto name = new char[len + 1];
+ strcpy(name, new_name);
+ auto new_meth = new PyMethodDef;
+ new_meth->ml_name = name;
+ new_meth->ml_meth = meth->ml_meth;
+ new_meth->ml_flags = meth->ml_flags;
+ new_meth->ml_doc = meth->ml_doc;
+ PyObject *descr = nullptr;
+ if (new_meth->ml_flags & METH_STATIC) {
+ AutoDecRef cfunc(PyCFunction_NewEx(new_meth, obtype, nullptr));
+ if (cfunc.isNull())
+ return nullptr;
+ descr = PyStaticMethod_New(cfunc);
+ }
+ else {
+ descr = PyDescr_NewMethod(type, new_meth);
+ }
+ return descr;
+}
+
+static bool feature_01_addLowerNames(PyTypeObject *type, PyObject *prev_dict, int /* id */)
+{
+ PyMethodDef *meth = type->tp_methods;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ PyObject *lower_dict = tpDict.object();
+
+ // PYSIDE-1702: A user-defined class in Python has no internal method list.
+ // We are not going to change anything.
+ if (!meth)
+ return PyDict_Update(lower_dict, prev_dict) >= 0;
+
+ /*
+ * Add objects with lower names to `type->tp_dict` from 'prev_dict`.
+ */
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+
+ // We first copy the things over which will not be changed:
+ while (PyDict_Next(prev_dict, &pos, &key, &value)) {
+ if (Py_TYPE(value) != PepMethodDescr_TypePtr
+ && Py_TYPE(value) != PepStaticMethod_TypePtr) {
+ if (PyDict_SetItem(lower_dict, key, value))
+ return false;
+ continue;
+ }
+ }
+
+ // Then we walk over the tp_methods to get all methods and insert
+ // them with changed names.
+
+ for (; meth != nullptr && meth->ml_name != nullptr; ++meth) {
+ const char *name = String::toCString(String::getSnakeCaseName(meth->ml_name, true));
+ AutoDecRef new_method(methodWithNewName(type, meth, name));
+ if (new_method.isNull())
+ return false;
+ if (PyDict_SetItemString(lower_dict, name, new_method) < 0)
+ return false;
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PYSIDE-1019: Support switchable extensions
+//
+// Feature 0x02: Use true properties instead of getters and setters
+//
+
+// This is the Python 2 version for inspection of m_ml, only.
+// The actual Python 3 version is larget.
+
+struct PyCFunctionObject {
+ PyObject_HEAD
+ PyMethodDef *m_ml; /* Description of the C function to call */
+ PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
+ PyObject *m_module; /* The __module__ attribute, can be anything */
+};
+
+static PyObject *modifyStaticToClassMethod(PyTypeObject *type, PyObject *sm)
+{
+ AutoDecRef func_ob(PyObject_GetAttr(sm, PyMagicName::func()));
+ if (func_ob.isNull())
+ return nullptr;
+ auto *func = reinterpret_cast<PyCFunctionObject *>(func_ob.object());
+ auto *new_func = new PyMethodDef;
+ new_func->ml_name = func->m_ml->ml_name;
+ new_func->ml_meth = func->m_ml->ml_meth;
+ new_func->ml_flags = (func->m_ml->ml_flags & ~METH_STATIC) | METH_CLASS;
+ new_func->ml_doc = func->m_ml->ml_doc;
+ PyCFunction_NewEx(new_func, nullptr, nullptr);
+ return PyDescr_NewClassMethod(type, new_func);
+}
+
+static PyObject *createProperty(PyTypeObject *type, PyObject *getter, PyObject *setter)
+{
+ assert(getter != nullptr);
+ if (setter == nullptr)
+ setter = Py_None;
+ auto *ptype = &PyProperty_Type;
+ if (Py_TYPE(getter) == PepStaticMethod_TypePtr) {
+ ptype = PyClassProperty_TypeF();
+ getter = modifyStaticToClassMethod(type, getter);
+ if (setter != Py_None)
+ setter = modifyStaticToClassMethod(type, setter);
+ }
+ auto *obtype = reinterpret_cast<PyObject *>(ptype);
+ PyObject *prop = PyObject_CallFunctionObjArgs(obtype, getter, setter, nullptr);
+ return prop;
+}
+
+static const QByteArrayList parseFields(const char *propStr, bool *stdWrite)
+{
+ /*
+ * Break the string into subfields at ':' and add defaults.
+ */
+ if (stdWrite)
+ *stdWrite = true;
+ QByteArray s = QByteArray(propStr);
+ auto list = s.split(u':');
+ assert(list.size() == 2 || list.size() == 3);
+ auto name = list[0];
+ auto read = list[1];
+ if (read.isEmpty())
+ list[1] = name;
+ if (list.size() == 2)
+ return list;
+ auto write = list[2];
+ if (stdWrite)
+ *stdWrite = write.isEmpty();
+ if (write.isEmpty()) {
+ list[2] = "set" + name;
+ list[2][3] = std::toupper(list[2][3]);
+ }
+ return list;
+}
+
+static PyObject *make_snake_case(const QByteArray &s, bool lower)
+{
+ if (s.isNull())
+ return nullptr;
+ return String::getSnakeCaseName(s.constData(), lower);
+}
+
+PyObject *adjustPropertyName(PyObject *dict, PyObject *name)
+{
+ // PYSIDE-1670: If this is a function with multiple arity or with
+ // parameters, we use a mangled name for the property.
+ PyObject *existing = PyDict_GetItem(dict, name); // borrowed
+ if (existing) {
+ Shiboken::AutoDecRef sig(get_signature_intern(existing, nullptr));
+ if (sig.object()) {
+ bool name_clash = false;
+ if (PyList_CheckExact(sig)) {
+ name_clash = true;
+ } else {
+ Shiboken::AutoDecRef params(PyObject_GetAttr(sig, PySideName::parameters()));
+ // Are there parameters except self or cls?
+ if (PyObject_Size(params.object()) > 1)
+ name_clash = true;
+ }
+ if (name_clash) {
+ // PyPy has no PyUnicode_AppendAndDel function, yet
+ Shiboken::AutoDecRef hold(name);
+ Shiboken::AutoDecRef under(Py_BuildValue("s", "_"));
+ name = PyUnicode_Concat(hold, under);
+ }
+ }
+ }
+ return name;
+}
+
+static QByteArrayList GetPropertyStringsMro(PyTypeObject *type)
+{
+ /*
+ * PYSIDE-2042: There are possibly more methods which should become properties,
+ * because the wrapping process does not obey inheritance.
+ * Therefore, we need to walk the mro to find property strings.
+ */
+ auto res = QByteArrayList();
+
+ PyObject *mro = type->tp_mro;
+ const Py_ssize_t n = PyTuple_GET_SIZE(mro);
+ // We leave 'Shiboken.Object' and 'object' alone, therefore "n - 2".
+ for (Py_ssize_t idx = 0; idx < n - 2; idx++) {
+ auto *subType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ auto props = SbkObjectType_GetPropertyStrings(subType);
+ if (props != nullptr)
+ for (; *props != nullptr; ++props)
+ res << QByteArray(*props);
+ }
+ return res;
+}
+
+static bool feature_02_true_property(PyTypeObject *type, PyObject *prev_dict, int id)
+{
+ /*
+ * Use the property info to create true Python property objects.
+ */
+
+ PyMethodDef *meth = type->tp_methods;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ PyObject *prop_dict = tpDict.object();
+
+ // The empty `tp_dict` gets populated by the previous dict.
+ if (PyDict_Update(prop_dict, prev_dict) < 0)
+ return false;
+
+ // PYSIDE-1702: A user-defined class in Python has no internal method list.
+ // We are not going to change anything.
+ if (!meth)
+ return true;
+
+ // For speed, we establish a helper dict that maps the removed property
+ // method names to property name.
+ PyObject *prop_methods = PyDict_GetItem(prop_dict, PyMagicName::property_methods());
+ if (prop_methods == nullptr) {
+ prop_methods = PyDict_New();
+ if (prop_methods == nullptr
+ || PyDict_SetItem(prop_dict, PyMagicName::property_methods(), prop_methods))
+ return false;
+ }
+ // We then replace methods by properties.
+ bool lower = (id & 0x01) != 0;
+ auto props = GetPropertyStringsMro(type);
+ if (props.isEmpty())
+ return true;
+
+ for (const auto &propStr : std::as_const(props)) {
+ bool isStdWrite;
+ auto fields = parseFields(propStr, &isStdWrite);
+ bool haveWrite = fields.size() == 3;
+ PyObject *name = make_snake_case(fields[0], lower);
+ PyObject *read = make_snake_case(fields[1], lower);
+ PyObject *write = haveWrite ? make_snake_case(fields[2], lower) : nullptr;
+ PyObject *getter = PyDict_GetItem(prev_dict, read);
+ if (getter == nullptr || !(Py_TYPE(getter) == PepMethodDescr_TypePtr ||
+ Py_TYPE(getter) == PepStaticMethod_TypePtr))
+ continue;
+ PyObject *setter = haveWrite ? PyDict_GetItem(prev_dict, write) : nullptr;
+
+ // PYSIDE-1670: If multiple arities exist as a property name, rename it.
+ name = adjustPropertyName(prop_dict, name);
+
+ AutoDecRef PyProperty(createProperty(type, getter, setter));
+ if (PyProperty.isNull())
+ return false;
+ if (PyDict_SetItem(prop_dict, name, PyProperty) < 0
+ || PyDict_SetItem(prop_methods, read, name) < 0
+ || (setter != nullptr && PyDict_SetItem(prop_methods, write, name) < 0))
+ return false;
+ if (fields[0] != fields[1] && PyDict_GetItem(prop_dict, read))
+ if (PyDict_DelItem(prop_dict, read) < 0)
+ return false;
+ // Theoretically, we need to check for multiple signatures to be exact.
+ // But we don't do so intentionally because it would be confusing.
+ if (haveWrite && PyDict_GetItem(prop_dict, write) && isStdWrite) {
+ if (PyDict_DelItem(prop_dict, write) < 0)
+ return false;
+ }
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// These are a number of patches to make Python's property object better
+// suitable for us.
+// We turn `__doc__` into a lazy attribute saving signature initialization.
+//
+// There is now also a class property implementation which inherits
+// from this one.
+//
+
+static PyObject *property_doc_get(PyObject *self, void *)
+{
+ auto *po = reinterpret_cast<propertyobject *>(self);
+
+ if (po->prop_doc != nullptr && po->prop_doc != Py_None) {
+ Py_INCREF(po->prop_doc);
+ return po->prop_doc;
+ }
+ if (po->prop_get) {
+ // PYSIDE-1019: Fetch the default `__doc__` from fget. We do it late.
+ auto *txt = PyObject_GetAttr(po->prop_get, PyMagicName::doc());
+ if (txt != nullptr) {
+ Py_INCREF(txt);
+ po->prop_doc = txt;
+ Py_INCREF(txt);
+ return txt;
+ }
+ PyErr_Clear();
+ }
+ Py_RETURN_NONE;
+}
+
+static int property_doc_set(PyObject *self, PyObject *value, void *)
+{
+ auto *po = reinterpret_cast<propertyobject *>(self);
+
+ Py_INCREF(value);
+ po->prop_doc = value;
+ return 0;
+}
+
+static PyGetSetDef property_getset[] = {
+ // This gets added to the existing getsets
+ {const_cast<char *>("__doc__"), property_doc_get, property_doc_set, nullptr, nullptr},
+ {nullptr, nullptr, nullptr, nullptr, nullptr}
+};
+
+static bool patch_property_impl()
+{
+ // Turn `__doc__` into a computed attribute without changing writability.
+ auto gsp = property_getset;
+ auto *type = &PyProperty_Type;
+ AutoDecRef dict(PepType_GetDict(type));
+ AutoDecRef descr(PyDescr_NewGetSet(type, gsp));
+ if (descr.isNull())
+ return false;
+ if (PyDict_SetItemString(dict.object(), gsp->name, descr) < 0)
+ return false;
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// PYSIDE-1019: Support switchable extensions
+//
+// Feature 0x04..0x80: A fake switchable option for testing
+//
+
+#define SIMILAR_FEATURE(xx) \
+static bool feature_##xx##_addDummyNames(PyTypeObject *type, PyObject *prev_dict, int /* id */) \
+{ \
+ AutoDecRef tpDict(PepType_GetDict(type)); \
+ PyObject *dict = tpDict.object(); \
+ if (PyDict_Update(dict, prev_dict) < 0) \
+ return false; \
+ if (PyDict_SetItemString(dict, "fake_feature_" #xx, Py_None) < 0) \
+ return false; \
+ return true; \
+}
+
+SIMILAR_FEATURE(04)
+SIMILAR_FEATURE(08)
+SIMILAR_FEATURE(10)
+SIMILAR_FEATURE(20)
+SIMILAR_FEATURE(40)
+SIMILAR_FEATURE(80)
+
+} // namespace PySide::Feature
diff --git a/sources/pyside6/libpyside/feature_select.h b/sources/pyside6/libpyside/feature_select.h
new file mode 100644
index 000000000..bf5a1b56b
--- /dev/null
+++ b/sources/pyside6/libpyside/feature_select.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef FEATURE_SELECT_H
+#define FEATURE_SELECT_H
+
+#include "pysidemacros.h"
+#include <sbkpython.h>
+
+namespace PySide::Feature {
+
+PYSIDE_API void init();
+PYSIDE_API void Select(PyObject *obj);
+PYSIDE_API void Select(PyTypeObject *type);
+PYSIDE_API void Enable(bool);
+
+} // namespace PySide::Feature
+
+#endif // FEATURE_SELECT_H
diff --git a/sources/pyside6/libpyside/globalreceiverv2.cpp b/sources/pyside6/libpyside/globalreceiverv2.cpp
new file mode 100644
index 000000000..2c75e39e1
--- /dev/null
+++ b/sources/pyside6/libpyside/globalreceiverv2.cpp
@@ -0,0 +1,322 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "globalreceiverv2.h"
+#include "pysideweakref.h"
+#include "pysidestaticstrings.h"
+#include "pysideutils.h"
+#include "signalmanager.h"
+
+#include <autodecref.h>
+#include <gilstate.h>
+#include <pep384ext.h>
+
+#include <QtCore/QMetaMethod>
+#include <QtCore/QSet>
+#include <QtCore/QDebug>
+
+#include <cstring>
+
+#define RECEIVER_DESTROYED_SLOT_NAME "__receiverDestroyed__(QObject*)"
+
+
+namespace PySide
+{
+
+class DynamicSlotDataV2
+{
+ Q_DISABLE_COPY_MOVE(DynamicSlotDataV2)
+ public:
+ DynamicSlotDataV2(PyObject *callback, GlobalReceiverV2 *parent);
+ ~DynamicSlotDataV2();
+
+ int addSlot(const char *signature);
+ int id(const char *signature) const;
+ PyObject *callback();
+ GlobalReceiverKey key() const { return {m_pythonSelf, m_callback}; }
+ void notify();
+
+ static void onCallbackDestroyed(void *data);
+ static GlobalReceiverKey key(PyObject *callback);
+
+ void formatDebug(QDebug &debug) const;
+
+ private:
+ bool m_isMethod;
+ PyObject *m_callback;
+ PyObject *m_pythonSelf = nullptr;
+ PyObject *m_pyClass = nullptr;
+ PyObject *m_weakRef = nullptr;
+ QMap<QByteArray, int> m_signatures;
+ GlobalReceiverV2 *m_parent;
+};
+
+void DynamicSlotDataV2::formatDebug(QDebug &debug) const
+{
+ debug << "method=" << m_isMethod << ", m_callback=" << m_callback;
+ if (m_callback != nullptr)
+ debug << '/' << Py_TYPE(m_callback)->tp_name;
+ debug << ", self=" << m_pythonSelf;
+ if (m_pythonSelf != nullptr)
+ debug << '/' << Py_TYPE(m_pythonSelf)->tp_name;
+ debug << ", m_pyClass=" << m_pyClass;
+ if (m_pyClass != nullptr)
+ debug << '/' << Py_TYPE(m_pyClass)->tp_name;
+ debug << ", signatures=" << m_signatures.keys();
+}
+
+QDebug operator<<(QDebug debug, const DynamicSlotDataV2 *d)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "DynamicSlotDataV2(";
+ if (d)
+ d->formatDebug(debug);
+ else
+ debug << '0';
+ debug << ')';
+ return debug;
+}
+
+using namespace PySide;
+
+DynamicSlotDataV2::DynamicSlotDataV2(PyObject *callback, GlobalReceiverV2 *parent) :
+ m_parent(parent)
+{
+ Shiboken::GilState gil;
+
+ if (PyMethod_Check(callback)) {
+ m_isMethod = true;
+ // To avoid increment instance reference keep the callback information
+ m_callback = PyMethod_GET_FUNCTION(callback);
+ Py_INCREF(m_callback);
+ m_pythonSelf = PyMethod_GET_SELF(callback);
+
+ //monitor class from method lifetime
+ m_weakRef = WeakRef::create(m_pythonSelf, DynamicSlotDataV2::onCallbackDestroyed, this);
+ } else if (PySide::isCompiledMethod(callback)) {
+ // PYSIDE-1523: PyMethod_Check is not accepting compiled form, we just go by attributes.
+ m_isMethod = true;
+
+ m_callback = PyObject_GetAttr(callback, PySide::PySideName::im_func());
+ Py_DECREF(m_callback);
+
+ m_pythonSelf = PyObject_GetAttr(callback, PySide::PySideName::im_self());
+ Py_DECREF(m_pythonSelf);
+
+ //monitor class from method lifetime
+ m_weakRef = WeakRef::create(m_pythonSelf, DynamicSlotDataV2::onCallbackDestroyed, this);
+ } else {
+ m_isMethod = false;
+
+ m_callback = callback;
+ Py_INCREF(m_callback);
+ }
+}
+
+GlobalReceiverKey DynamicSlotDataV2::key(PyObject *callback)
+{
+ Shiboken::GilState gil;
+ if (PyMethod_Check(callback)) {
+ // PYSIDE-1422: Avoid hash on self which might be unhashable.
+ return {PyMethod_GET_SELF(callback), PyMethod_GET_FUNCTION(callback)};
+ } else if (PySide::isCompiledMethod(callback)) {
+ // PYSIDE-1589: Fix for slots in compiled functions
+ Shiboken::AutoDecRef self(PyObject_GetAttr(callback, PySide::PySideName::im_self()));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(callback, PySide::PySideName::im_func()));
+ return {self, func};
+ }
+ return {nullptr, callback};
+}
+
+PyObject *DynamicSlotDataV2::callback()
+{
+ PyObject *callback = m_callback;
+
+ //create a callback based on method data
+ if (m_isMethod)
+ callback = PepExt_Type_CallDescrGet(m_callback, m_pythonSelf, nullptr);
+ else
+ Py_INCREF(callback);
+
+ return callback;
+}
+
+int DynamicSlotDataV2::id(const char *signature) const
+{
+ const auto it = m_signatures.constFind(signature);
+ return it != m_signatures.cend() ? it.value() : -1;
+}
+
+int DynamicSlotDataV2::addSlot(const char *signature)
+{
+ int index = id(signature);
+ if (index == -1)
+ index = m_signatures[signature] = m_parent->metaObjectBuilder().addSlot(signature);
+ return index;
+}
+
+void DynamicSlotDataV2::onCallbackDestroyed(void *data)
+{
+ auto self = reinterpret_cast<DynamicSlotDataV2 *>(data);
+ self->m_weakRef = nullptr;
+ Py_BEGIN_ALLOW_THREADS
+ SignalManager::instance().deleteGlobalReceiver(self->m_parent);
+ Py_END_ALLOW_THREADS
+}
+
+DynamicSlotDataV2::~DynamicSlotDataV2()
+{
+ Shiboken::GilState gil;
+
+ Py_XDECREF(m_weakRef);
+ m_weakRef = nullptr;
+
+ Py_DECREF(m_callback);
+}
+
+const char *GlobalReceiverV2::senderDynamicProperty = "_q_pyside_sender";
+
+GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, QObject *receiver) :
+ QObject(nullptr),
+ m_metaObject("__GlobalReceiver__", &QObject::staticMetaObject),
+ m_receiver(receiver)
+{
+ m_data = new DynamicSlotDataV2(callback, this);
+}
+
+GlobalReceiverV2::~GlobalReceiverV2()
+{
+ m_refs.clear();
+ // Remove itself from map.
+ // Suppress handling of destroyed() for objects whose last reference is contained inside
+ // the callback object that will now be deleted. The reference could be a default argument,
+ // a callback local variable, etc.
+ // The signal has to be suppressed because it would lead to the following situation:
+ // Callback is deleted, hence the last reference is decremented,
+ // leading to the object being deleted, which emits destroyed(), which would try to invoke
+ // the already deleted callback, and also try to delete the object again.
+ DynamicSlotDataV2 *data = m_data;
+ m_data = nullptr;
+ delete data;
+}
+
+int GlobalReceiverV2::addSlot(const char *signature)
+{
+ return m_data->addSlot(signature);
+}
+
+void GlobalReceiverV2::incRef(const QObject *link)
+{
+ Q_ASSERT(link);
+ m_refs.append(link);
+}
+
+void GlobalReceiverV2::decRef(const QObject *link)
+{
+ Q_ASSERT(link);
+ m_refs.removeOne(link);
+}
+
+void GlobalReceiverV2::notify()
+{
+ purgeDeletedSenders();
+}
+
+static bool isNull(const QPointer<const QObject> &p)
+{
+ return p.isNull();
+}
+
+void GlobalReceiverV2::purgeDeletedSenders()
+{
+ m_refs.erase(std::remove_if(m_refs.begin(), m_refs.end(), isNull), m_refs.end());
+}
+
+bool GlobalReceiverV2::isEmpty() const
+{
+ return std::all_of(m_refs.cbegin(), m_refs.cend(), isNull);
+}
+
+GlobalReceiverKey GlobalReceiverV2::key() const
+{
+ return m_data->key();
+}
+
+GlobalReceiverKey GlobalReceiverV2::key(PyObject *callback)
+{
+ return DynamicSlotDataV2::key(callback);
+}
+
+const QMetaObject *GlobalReceiverV2::metaObject() const
+{
+ return const_cast<GlobalReceiverV2 *>(this)->m_metaObject.update();
+}
+
+int GlobalReceiverV2::qt_metacall(QMetaObject::Call call, int id, void **args)
+{
+ Shiboken::GilState gil;
+ Q_ASSERT(call == QMetaObject::InvokeMetaMethod);
+ Q_ASSERT(id >= QObject::staticMetaObject.methodCount());
+
+ QMetaMethod slot = metaObject()->method(id);
+ Q_ASSERT(slot.methodType() == QMetaMethod::Slot);
+
+ if (!m_data) {
+ const QByteArray message = "PySide6 Warning: Skipping callback call "
+ + slot.methodSignature() + " because the callback object is being destructed.";
+ PyErr_WarnEx(PyExc_RuntimeWarning, message.constData(), 0);
+ return -1;
+ }
+
+ const bool setSenderDynamicProperty = !m_receiver.isNull();
+ if (setSenderDynamicProperty)
+ m_receiver->setProperty(senderDynamicProperty, QVariant::fromValue(sender()));
+
+ Shiboken::AutoDecRef callback(m_data->callback());
+ SignalManager::callPythonMetaMethod(slot, args, callback);
+
+ if (setSenderDynamicProperty)
+ m_receiver->setProperty(senderDynamicProperty, QVariant{});
+
+ // SignalManager::callPythonMetaMethod might have failed, in that case we have to print the
+ // error so it considered "handled".
+ if (PyErr_Occurred()) {
+ int reclimit = Py_GetRecursionLimit();
+ // Inspired by Python's errors.c: PyErr_GivenExceptionMatches() function.
+ // Temporarily bump the recursion limit, so that PyErr_Print will not raise a recursion
+ // error again. Don't do it when the limit is already insanely high, to avoid overflow.
+ if (reclimit < (1 << 30))
+ Py_SetRecursionLimit(reclimit + 5);
+ PyErr_Print();
+ Py_SetRecursionLimit(reclimit);
+ }
+
+ return -1;
+}
+
+void GlobalReceiverV2::formatDebug(QDebug &debug) const
+{
+ debug << "receiver=" << m_receiver << ", slot=" << m_data;
+ if (isEmpty())
+ debug << ", empty";
+ else
+ debug << ", refs=" << m_refs;
+};
+
+QDebug operator<<(QDebug debug, const GlobalReceiverV2 *g)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "GlobalReceiverV2(";
+ if (g)
+ g->formatDebug(debug);
+ else
+ debug << '0';
+ debug << ')';
+ return debug;
+}
+
+} // namespace PySide
diff --git a/sources/pyside6/libpyside/globalreceiverv2.h b/sources/pyside6/libpyside/globalreceiverv2.h
new file mode 100644
index 000000000..0e3bc562a
--- /dev/null
+++ b/sources/pyside6/libpyside/globalreceiverv2.h
@@ -0,0 +1,115 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef GLOBALRECEIVER_V2_H
+#define GLOBALRECEIVER_V2_H
+
+#include <sbkpython.h>
+
+#include "dynamicqmetaobject.h"
+
+#include <QtCore/QtCompare>
+#include <QtCore/QByteArray>
+#include <QtCore/QHashFunctions>
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtCore/QMap>
+
+#include <memory>
+
+QT_FORWARD_DECLARE_CLASS(QDebug);
+
+namespace PySide
+{
+
+class DynamicSlotDataV2;
+class GlobalReceiverV2;
+
+struct GlobalReceiverKey
+{
+ const PyObject *object;
+ const PyObject *method;
+
+ friend constexpr size_t qHash(GlobalReceiverKey k, size_t seed = 0) noexcept
+ {
+ return qHashMulti(seed, k.object, k.method);
+ }
+ friend constexpr bool comparesEqual(const GlobalReceiverKey &lhs,
+ const GlobalReceiverKey &rhs) noexcept
+ {
+ return lhs.object == rhs.object && lhs.method == rhs.method;
+ }
+ Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(GlobalReceiverKey)
+};
+
+/// A class used to link C++ Signals to non C++ slots (Python callbacks) by
+/// providing fake slots for QObject::connect().
+/// It keeps a Python callback and the list of QObject senders. It is stored
+/// in SignalManager by a hash of the Python callback.
+class GlobalReceiverV2 : public QObject
+{
+public:
+ Q_DISABLE_COPY_MOVE(GlobalReceiverV2)
+
+ /// Create a GlobalReceiver object that will call 'callback'
+ /// @param callback A Python callable object (can be a method or not)
+ explicit GlobalReceiverV2(PyObject *callback, QObject *receiver = nullptr);
+
+ ~GlobalReceiverV2() override;
+
+ /// Reimplemented function from QObject
+ int qt_metacall(QMetaObject::Call call, int id, void **args) override;
+ const QMetaObject *metaObject() const override;
+
+ /// Add a extra slot to this object
+ /// @param signature The signature of the slot to be added
+ /// @return The index of this slot on metaobject
+ int addSlot(const char *signature);
+
+ /// Notify to GlobalReceiver about when a new connection was made
+ void notify();
+
+ /// Used to increment the reference of the GlobalReceiver object
+ /// @param link This is a parameter used to link the ref to
+ /// some QObject life.
+ void incRef(const QObject *link);
+
+ /// Used to decrement the reference of the GlobalReceiver object.
+ /// @param link This is a parameter used to dismiss the link
+ /// ref to some QObject.
+ void decRef(const QObject *link);
+
+ /// Returns whether any senders are registered.
+ bool isEmpty() const;
+
+ /// Use to retrieve the unique hash of this GlobalReceiver object
+ /// @return hash key
+ GlobalReceiverKey key() const;
+
+ /// Use to retrieve the unique hash of the PyObject based on GlobalReceiver rules
+ /// @param callback The Python callable object used to calculate the id
+ /// @return hash key
+ static GlobalReceiverKey key(PyObject *callback);
+
+ const MetaObjectBuilder &metaObjectBuilder() const { return m_metaObject; }
+ MetaObjectBuilder &metaObjectBuilder() { return m_metaObject; }
+
+ static const char *senderDynamicProperty;
+
+ void formatDebug(QDebug &debug) const;
+
+private:
+ void purgeDeletedSenders();
+
+ MetaObjectBuilder m_metaObject;
+ DynamicSlotDataV2 *m_data;
+ using QObjectPointer = QPointer<const QObject>;
+ QList<QObjectPointer> m_refs;
+ QPointer<QObject> m_receiver;
+};
+
+QDebug operator<<(QDebug debug, const GlobalReceiverV2 *g);
+
+}
+
+#endif
diff --git a/sources/pyside6/libpyside/libpyside.qrc b/sources/pyside6/libpyside/libpyside.qrc
new file mode 100644
index 000000000..1e652eb4c
--- /dev/null
+++ b/sources/pyside6/libpyside/libpyside.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qt-project.org/logos">
+ <file alias="pysidelogo.png">../doc/_static/qtforpython.png</file>
+ </qresource>
+</RCC>
diff --git a/sources/pyside6/libpyside/pyside.cpp b/sources/pyside6/libpyside/pyside.cpp
new file mode 100644
index 000000000..9e12e3cd7
--- /dev/null
+++ b/sources/pyside6/libpyside/pyside.cpp
@@ -0,0 +1,1215 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pyside.h"
+#include "pysideinit.h"
+#include "pysidecleanup.h"
+#include "pysidemetatype.h"
+#include "pysideqapp.h"
+#include "pysideqobject.h"
+#include "pysideutils.h"
+#include "pyside_p.h"
+#include "signalmanager.h"
+#include "pysideclassinfo_p.h"
+#include "pysideproperty_p.h"
+#include "class_property.h"
+#include "pysideproperty.h"
+#include "pysidesignal.h"
+#include "pysidesignal_p.h"
+#include "pysidestaticstrings.h"
+#include "pysideslot_p.h"
+#include "pysidemetafunction_p.h"
+#include "pysidemetafunction.h"
+#include "dynamicqmetaobject.h"
+#include "feature_select.h"
+#include "pysidelogging_p.h"
+
+#include <autodecref.h>
+#include <basewrapper.h>
+#include <bindingmanager.h>
+#include <gilstate.h>
+#include <sbkconverter.h>
+#include <sbkstring.h>
+#include <sbkstaticstrings.h>
+#include <sbkfeature_base.h>
+#include <sbkmodule.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QMetaMethod>
+#include <QtCore/QMutex>
+#include <QtCore/QStack>
+#include <QtCore/QThread>
+#include <QtCore/private/qobject_p.h>
+
+#include <algorithm>
+#include <cstring>
+#include <cctype>
+#include <memory>
+#include <optional>
+#include <typeinfo>
+
+using namespace Qt::StringLiterals;
+
+static QStack<PySide::CleanupFunction> cleanupFunctionList;
+static void *qobjectNextAddr;
+
+QT_BEGIN_NAMESPACE
+extern bool qRegisterResourceData(int, const unsigned char *, const unsigned char *,
+ const unsigned char *);
+QT_END_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcPySide, "qt.pyside.libpyside", QtCriticalMsg)
+
+static QObjectData *qt_object_private(const QObject *o)
+{
+ class FriendlyQObject : public QObject {
+ public:
+ using QObject::d_ptr;
+ };
+ return static_cast<const FriendlyQObject *>(o)->d_ptr.data();
+}
+
+static bool hasDynamicMetaObject(const QObject *o)
+{
+ return qt_object_private(o)->metaObject != nullptr;
+}
+
+namespace PySide
+{
+
+void init(PyObject *module)
+{
+ qobjectNextAddr = nullptr;
+ ClassInfo::init(module);
+ Signal::init(module);
+ Slot::init(module);
+ Property::init(module);
+ ClassProperty::init(module);
+ MetaFunction::init(module);
+ // Init signal manager, so it will register some meta types used by QVariant.
+ SignalManager::instance();
+ initQApp();
+}
+
+static const QByteArray _sigWithMangledName(const QByteArray &signature, bool mangle)
+{
+ if (!mangle)
+ return signature;
+ auto bracePos = signature.indexOf('(');
+ auto limit = bracePos >= 0 ? bracePos : signature.size();
+ if (limit < 3)
+ return signature;
+ QByteArray result;
+ result.reserve(signature.size() + 4);
+ for (auto i = 0; i < limit; ++i) {
+ const char c = signature.at(i);
+ if (std::isupper(c)) {
+ if (i > 0) {
+ if (std::isupper(signature.at(i - 1)))
+ return signature; // Give up at consecutive upper chars
+ result.append('_');
+ }
+ result.append(std::tolower(c));
+ } else {
+ result.append(c);
+ }
+ }
+ // Copy the rest after the opening brace (if any)
+ result.append(signature.mid(limit));
+ return result;
+}
+
+static const QByteArray _sigWithOrigName(const QByteArray &signature, bool mangle)
+{
+ if (!mangle)
+ return signature;
+ auto bracePos = signature.indexOf('(');
+ auto limit = bracePos >= 0 ? bracePos : signature.size();
+ QByteArray result;
+ result.reserve(signature.size());
+ for (auto i = 0; i < limit; ++i) {
+ const char c = signature.at(i);
+ if (std::isupper(c)) {
+ if (i > 0) {
+ if (std::isupper(signature.at(i - 1)))
+ return signature; // Give up at consecutive upper chars
+ return QByteArray{}; // Error, this was not converted!
+ }
+ }
+ if (std::islower(c) && i > 0 && signature.at(i - 1) == '_') {
+ result.chop(1);
+ result.append(std::toupper(c));
+ } else {
+ result.append(c);
+ }
+ }
+ // Copy the rest after the opening brace (if any)
+ result.append(signature.mid(limit));
+ return result;
+}
+
+/*****************************************************************************
+ *
+ * How do we find a property?
+ * --------------------------
+ *
+ * There are methods which are truly parts of properties, and there are
+ * other property-like methods which are not. True properties can be
+ * found by inspecting `SbkObjectType_GetPropertyStrings(type)`.
+ *
+ * Pseudo-properties have only a getter and a setter, and we must assume that
+ * the name of the getter is the property name, and the name of the setter
+ * is the uppercase of the getter with "set" prepended.
+ *
+ * We first walk the mro and search the property name and get the setter
+ * name. If that doesn't work, we use the heuristics for the setter.
+ * We then do the final mro lookup.
+ *
+ * Note that the true property lists have the original names, while the
+ * dict entries in the mro are already mangled.
+ */
+
+static const QByteArrayList parseFields(const char *propStr, int flags, bool *stdWrite)
+{
+ /*
+ * Break the string into subfields at ':' and add defaults.
+ */
+ if (stdWrite)
+ *stdWrite = true;
+ QByteArray s = QByteArray(propStr);
+ auto list = s.split(':');
+ assert(list.size() == 2 || list.size() == 3);
+ auto name = list[0];
+ auto read = list[1];
+ if (read.isEmpty())
+ list[1] = name;
+ if (list.size() == 2)
+ return list;
+ auto write = list[2];
+ if (stdWrite)
+ *stdWrite = write.isEmpty();
+ if (write.isEmpty()) {
+ auto snake_flag = flags & 0x01;
+ if (snake_flag) {
+ list[2] = ("set_") + name;
+ } else {
+ list[2] = QByteArray("set") + name;
+ list[2][3] = std::toupper(list[2][3]);
+ }
+ }
+ return list;
+}
+
+static QByteArrayList _SbkType_LookupProperty(PyTypeObject *type,
+ const QByteArray &name, int flags)
+{
+ /*
+ * Looks up a property and returns all fields.
+ */
+ int snake_flag = flags & 0x01;
+ QByteArray origName(_sigWithOrigName(name, snake_flag));
+ if (origName.isEmpty())
+ return QByteArrayList{};
+ PyObject *mro = type->tp_mro;
+ auto n = PyTuple_GET_SIZE(mro);
+ auto len = std::strlen(origName);
+ for (Py_ssize_t idx = 0; idx < n; idx++) {
+ PyTypeObject *base = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ if (!SbkObjectType_Check(base))
+ continue;
+ auto props = SbkObjectType_GetPropertyStrings(base);
+ if (props == nullptr || *props == nullptr)
+ continue;
+ for (; *props != nullptr; ++props) {
+ QByteArray propStr(*props);
+ if (std::strncmp(propStr, origName, len) == 0) {
+ if (propStr[len] != ':')
+ continue;
+ // We found the property. Return the parsed fields.
+ propStr = _sigWithMangledName(propStr, snake_flag);
+ return parseFields(propStr, flags, nullptr);
+ }
+ }
+ }
+ return QByteArrayList{};
+}
+
+static QByteArrayList _SbkType_FakeProperty(const QByteArray &name, int flags)
+{
+ /*
+ * Handle a pseudo.property and return all fields.
+ */
+ int snake_flag = flags & 0x01;
+ QByteArray propStr(name);
+ propStr += "::";
+ propStr = _sigWithMangledName(propStr, snake_flag);
+ return parseFields(propStr, snake_flag, nullptr);
+}
+
+static bool _setProperty(PyObject *qObj, PyObject *name, PyObject *value, bool *accept)
+{
+ using Shiboken::AutoDecRef;
+
+ QByteArray propName(Shiboken::String::toCString(name));
+ auto type = Py_TYPE(qObj);
+ int flags = currentSelectId(type);
+ int prop_flag = flags & 0x02;
+ auto found = false;
+ QByteArray getterName{}, setterName{};
+
+ auto fields = _SbkType_LookupProperty(type, propName, flags);
+ if (!fields.isEmpty()) {
+ found = true;
+ bool haveWrite = fields.size() == 3;
+ if (!haveWrite)
+ return false;
+ } else {
+ fields = _SbkType_FakeProperty(propName, flags);
+ }
+
+ propName = fields[0];
+ getterName = fields[1];
+ setterName = fields[2];
+
+ // PYSIDE-1702: We do not use getattr, since that could trigger an action
+ // if we have a true property. Better to look inside the mro.
+ // That should return a descriptor or a property.
+ PyObject *look{};
+
+ if (found && prop_flag) {
+ // We have a property, and true_property is active.
+ // There must be a property object and we use it's fset.
+ AutoDecRef pyPropName(Shiboken::String::fromCString(propName.constData()));
+ look = _PepType_Lookup(Py_TYPE(qObj), pyPropName);
+ } else {
+ // We have a pseudo property or true_property is off, looking for a setter.
+ AutoDecRef pySetterName(Shiboken::String::fromCString(setterName.constData()));
+ look = _PepType_Lookup(Py_TYPE(qObj), pySetterName);
+ }
+
+ if (look) {
+ AutoDecRef propSetter{};
+ static PyObject *magicGet = Shiboken::PyMagicName::get();
+ if (found && prop_flag) {
+ // the indirection of the setter descriptor in a true property
+ AutoDecRef descr(PyObject_GetAttr(look, PySideName::fset()));
+ propSetter.reset(PyObject_CallMethodObjArgs(descr, magicGet, qObj, nullptr));
+ } else {
+ // look is already the descriptor
+ propSetter.reset(PyObject_CallMethodObjArgs(look, magicGet, qObj, nullptr));
+ }
+ *accept = true;
+ AutoDecRef args(PyTuple_Pack(1, value));
+ AutoDecRef retval(PyObject_CallObject(propSetter, args));
+ if (retval.isNull())
+ return false;
+ } else {
+ PyErr_Clear();
+ AutoDecRef attr(PyObject_GenericGetAttr(qObj, name));
+ if (PySide::Property::checkType(attr)) {
+ *accept = true;
+ if (PySide::Property::setValue(reinterpret_cast<PySideProperty *>(
+ attr.object()), qObj, value) < 0)
+ return false;
+ }
+ }
+ return true;
+}
+
+// PYSIDE-2329: Search a signal by name (Note: QMetaObject::indexOfSignal()
+// searches by signature).
+static std::optional<QMetaMethod> findSignal(const QMetaObject *mo,
+ const QByteArray &name)
+{
+ const auto count = mo->methodCount();
+ for (int i = mo->methodOffset(); i < count; ++i) {
+ const auto method = mo->method(i);
+ if (method.methodType() == QMetaMethod::Signal && method.name() == name)
+ return method;
+ }
+ auto *base = mo->superClass();
+ return base != nullptr ? findSignal(base, name) : std::nullopt;
+}
+
+bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj,
+ PyObject *kwds, bool allowErrors)
+{
+
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ int flags = currentSelectId(Py_TYPE(qObj));
+ int snake_flag = flags & 0x01;
+
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ const QByteArray propName = Shiboken::String::toCString(key);
+ QByteArray unmangledName = _sigWithOrigName(propName, snake_flag);
+ bool accept = false;
+ // PYSIDE-1705: Make sure that un-mangled names are not recognized in snake_case mode.
+ if (!unmangledName.isEmpty()) {
+ if (metaObj->indexOfProperty(unmangledName) != -1) {
+ if (!_setProperty(qObj, key, value, &accept))
+ return false;
+ } else {
+ const auto methodO = findSignal(metaObj, propName);
+ if (methodO.has_value()) {
+ const auto signature = "2"_ba + methodO->methodSignature();
+ accept = true;
+ if (!PySide::Signal::connect(qObj, signature, value))
+ return false;
+ }
+ }
+ if (!accept) {
+ // PYSIDE-1019: Allow any existing attribute in the constructor.
+ if (!_setProperty(qObj, key, value, &accept))
+ return false;
+ }
+ }
+ if (allowErrors) {
+ PyErr_Clear();
+ continue;
+ }
+ if (!accept) {
+ PyErr_Format(PyExc_AttributeError, "'%s' is not a Qt property or a signal",
+ propName.constData());
+ return false;
+ }
+ }
+ return true;
+}
+
+void registerCleanupFunction(CleanupFunction func)
+{
+ cleanupFunctionList.push(func);
+}
+
+void runCleanupFunctions()
+{
+ while (!cleanupFunctionList.isEmpty()) {
+ CleanupFunction f = cleanupFunctionList.pop();
+ f();
+ }
+}
+
+static void destructionVisitor(SbkObject *pyObj, void *data)
+{
+ auto realData = reinterpret_cast<void **>(data);
+ auto pyQApp = reinterpret_cast<SbkObject *>(realData[0]);
+ auto pyQObjectType = reinterpret_cast<PyTypeObject *>(realData[1]);
+
+ if (pyObj != pyQApp && PyObject_TypeCheck(pyObj, pyQObjectType)) {
+ if (Shiboken::Object::hasOwnership(pyObj) && Shiboken::Object::isValid(pyObj, false)) {
+ Shiboken::Object::setValidCpp(pyObj, false);
+
+ Py_BEGIN_ALLOW_THREADS
+ Shiboken::callCppDestructor<QObject>(Shiboken::Object::cppPointer(pyObj, pyQObjectType));
+ Py_END_ALLOW_THREADS
+ }
+ }
+
+};
+
+void destroyQCoreApplication()
+{
+ QCoreApplication *app = QCoreApplication::instance();
+ if (!app)
+ return;
+ SignalManager::instance().clear();
+
+ Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+ SbkObject *pyQApp = bm.retrieveWrapper(app);
+ PyTypeObject *pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
+ assert(pyQObjectType);
+
+ void *data[2] = {pyQApp, pyQObjectType};
+ bm.visitAllPyObjects(&destructionVisitor, &data);
+
+ // in the end destroy app
+ // Allow threads because the destructor calls
+ // QThreadPool::globalInstance().waitForDone() which may deadlock on the GIL
+ // if there is a worker working with python objects.
+ Py_BEGIN_ALLOW_THREADS
+ delete app;
+ Py_END_ALLOW_THREADS
+ // PYSIDE-571: make sure to create a singleton deleted qApp.
+ Py_DECREF(MakeQAppWrapper(nullptr));
+}
+
+std::size_t getSizeOfQObject(PyTypeObject *type)
+{
+ return retrieveTypeUserData(type)->cppObjSize;
+}
+
+void initDynamicMetaObject(PyTypeObject *type, const QMetaObject *base, std::size_t cppObjSize)
+{
+ //create DynamicMetaObject based on python type
+ auto userData = new TypeUserData(reinterpret_cast<PyTypeObject *>(type), base, cppObjSize);
+ userData->mo.update();
+ Shiboken::ObjectType::setTypeUserData(type, userData, Shiboken::callCppDestructor<TypeUserData>);
+
+ //initialize staticQMetaObject property
+ void *metaObjectPtr = const_cast<QMetaObject *>(userData->mo.update());
+ static SbkConverter *converter = Shiboken::Conversions::getConverter("QMetaObject");
+ if (!converter)
+ return;
+ Shiboken::AutoDecRef pyMetaObject(Shiboken::Conversions::pointerToPython(converter, metaObjectPtr));
+ PyObject_SetAttr(reinterpret_cast<PyObject *>(type),
+ Shiboken::PyName::qtStaticMetaObject(), pyMetaObject);
+}
+
+TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj)
+{
+ if (!SbkObjectType_Check(pyTypeObj))
+ return nullptr;
+ return reinterpret_cast<TypeUserData *>(Shiboken::ObjectType::getTypeUserData(pyTypeObj));
+}
+
+TypeUserData *retrieveTypeUserData(PyObject *pyObj)
+{
+ auto pyTypeObj = PyType_Check(pyObj)
+ ? reinterpret_cast<PyTypeObject *>(pyObj) : Py_TYPE(pyObj);
+ return retrieveTypeUserData(pyTypeObj);
+}
+
+const QMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj)
+{
+ TypeUserData *userData = retrieveTypeUserData(pyTypeObj);
+ return userData ? userData->mo.update() : nullptr;
+}
+
+const QMetaObject *retrieveMetaObject(PyObject *pyObj)
+{
+ auto pyTypeObj = PyType_Check(pyObj)
+ ? reinterpret_cast<PyTypeObject *>(pyObj) : Py_TYPE(pyObj);
+ return retrieveMetaObject(pyTypeObj);
+}
+
+void initQObjectSubType(PyTypeObject *type, PyObject *args, PyObject * /* kwds */)
+{
+ PyTypeObject *qObjType = Shiboken::Conversions::getPythonTypeObject("QObject*");
+
+ PyObject *bases = PyTuple_GET_ITEM(args, 1);
+ int numBases = PyTuple_GET_SIZE(bases);
+
+ TypeUserData *userData = nullptr;
+
+ for (int i = 0; i < numBases; ++i) {
+ auto base = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(bases, i));
+ if (PyType_IsSubtype(base, qObjType)) {
+ userData = retrieveTypeUserData(base);
+ break;
+ }
+ }
+ if (!userData) {
+ const char *className = Shiboken::String::toCString(PyTuple_GET_ITEM(args, 0));
+ qWarning("Sub class of QObject not inheriting QObject!? Crash will happen when using %s.",
+ className);
+ return;
+ }
+ // PYSIDE-1463: Don't change feature selection durin subtype initialization.
+ // This behavior is observed with PySide 6.
+ PySide::Feature::Enable(false);
+ initDynamicMetaObject(type, userData->mo.update(), userData->cppObjSize);
+ PySide::Feature::Enable(true);
+}
+
+void initQApp()
+{
+ /*
+ * qApp will not be initialized when embedding is active.
+ * That means that qApp exists already when PySide is initialized.
+ * We could solve that by creating a qApp variable, but in embedded
+ * mode, we also have the effect that the first assignment to qApp
+ * is persistent! Therefore, we can never be sure to have created
+ * qApp late enough to get the right type for the instance.
+ *
+ * I would appreciate very much if someone could explain or even fix
+ * this issue. It exists only when a pre-existing application exists.
+ */
+ if (!qApp)
+ Py_DECREF(MakeQAppWrapper(nullptr));
+
+ // PYSIDE-1470: Register a function to destroy an application from shiboken.
+ setDestroyQApplication(destroyQCoreApplication);
+}
+
+PyObject *getHiddenDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name)
+{
+ using Shiboken::AutoDecRef;
+
+ // PYSIDE-68-bis: This getattr finds signals early by `signalDescrGet`.
+ PyObject *attr = PyObject_GenericGetAttr(self, name);
+ if (!Shiboken::Object::isValid(reinterpret_cast<SbkObject *>(self), false))
+ return attr;
+
+ if (attr && Property::checkType(attr)) {
+ PyObject *value = Property::getValue(reinterpret_cast<PySideProperty *>(attr), self);
+ Py_DECREF(attr);
+ if (!value)
+ return nullptr;
+ attr = value;
+ }
+
+ // Search on metaobject (avoid internal attributes started with '__')
+ if (!attr) {
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback); // This was omitted for a loong time.
+
+ int flags = currentSelectId(Py_TYPE(self));
+ int snake_flag = flags & 0x01;
+ int propFlag = flags & 0x02;
+
+ if (propFlag) {
+ // PYSIDE-1889: If we have actually a Python property, return f(get|set|del).
+ // Do not store this attribute in the instance dict, because this
+ // would create confusion with overload.
+ // Note: before implementing this property handling, the meta function code
+ // below created meta functions which was quite wrong.
+ auto *subdict = _PepType_Lookup(Py_TYPE(self), PySideMagicName::property_methods());
+ PyObject *propName = PyDict_GetItem(subdict, name);
+ if (propName) {
+ // We really have a property name and need to fetch the fget or fset function.
+ static PyObject *const _fget = Shiboken::String::createStaticString("fget");
+ static PyObject *const _fset = Shiboken::String::createStaticString("fset");
+ static PyObject *const _fdel = Shiboken::String::createStaticString("fdel");
+ static PyObject *const arr[3] = {_fget, _fset, _fdel};
+ auto prop = _PepType_Lookup(Py_TYPE(self), propName);
+ for (int idx = 0; idx < 3; ++idx) {
+ auto *trial = arr[idx];
+ auto *res = PyObject_GetAttr(prop, trial);
+ if (res) {
+ AutoDecRef elemName(PyObject_GetAttr(res, PySideMagicName::name()));
+ // Note: This comparison works because of interned strings.
+ if (elemName == name)
+ return res;
+ Py_DECREF(res);
+ }
+ PyErr_Clear();
+ }
+ }
+ }
+
+ const char *cname = Shiboken::String::toCString(name);
+ uint cnameLen = qstrlen(cname);
+ if (std::strncmp("__", cname, 2) != 0) {
+ const QMetaObject *metaObject = cppSelf->metaObject();
+ QList<QMetaMethod> signalList;
+ // Caution: This inserts a meta function or a signal into the instance dict.
+ for (int i=0, imax = metaObject->methodCount(); i < imax; i++) {
+ QMetaMethod method = metaObject->method(i);
+ // PYSIDE-1753: Snake case names must be renamed here too, or they will be
+ // found unexpectedly when forgetting to rename them.
+ auto origSignature = method.methodSignature();
+ // Currently, we rename only methods but no signals. This might change.
+ bool use_lower = snake_flag and method.methodType() != QMetaMethod::Signal;
+ const QByteArray methSig_ = _sigWithMangledName(origSignature, use_lower);
+ const char *methSig = methSig_.constData();
+ bool methMatch = std::strncmp(cname, methSig, cnameLen) == 0
+ && methSig[cnameLen] == '(';
+ if (methMatch) {
+ if (method.methodType() == QMetaMethod::Signal) {
+ signalList.append(method);
+ } else {
+ PySideMetaFunction *func = MetaFunction::newObject(cppSelf, i);
+ if (func) {
+ PyObject *result = reinterpret_cast<PyObject *>(func);
+ PyObject_SetAttr(self, name, result);
+ return result;
+ }
+ }
+ }
+ }
+ if (!signalList.isEmpty()) {
+ PyObject *pySignal = reinterpret_cast<PyObject *>(
+ Signal::newObjectFromMethod(self, signalList));
+ PyObject_SetAttr(self, name, pySignal);
+ return pySignal;
+ }
+ }
+ PyErr_Restore(type, value, traceback);
+ }
+ return attr;
+}
+
+bool inherits(PyTypeObject *objType, const char *class_name)
+{
+ if (strcmp(objType->tp_name, class_name) == 0)
+ return true;
+
+ PyTypeObject *base = objType->tp_base;
+ if (base == nullptr)
+ return false;
+
+ return inherits(base, class_name);
+}
+
+QMutex &nextQObjectMemoryAddrMutex()
+{
+ static QMutex mutex;
+ return mutex;
+}
+
+void *nextQObjectMemoryAddr()
+{
+ return qobjectNextAddr;
+}
+
+void setNextQObjectMemoryAddr(void *addr)
+{
+ qobjectNextAddr = addr;
+}
+
+} // namespace PySide
+
+// A std::shared_ptr is used with a deletion function to invalidate a pointer
+// when the property value is cleared. This should be a QSharedPointer with
+// a void *pointer, but that isn't allowed
+using any_t = char;
+Q_DECLARE_METATYPE(std::shared_ptr<any_t>);
+
+
+namespace PySide
+{
+
+static void invalidatePtr(any_t *object)
+{
+ // PYSIDE-2254: Guard against QObjects outliving Python, for example the
+ // adopted main thread as returned by QObjects::thread().
+ if (Py_IsInitialized() == 0)
+ return;
+
+ Shiboken::GilState state;
+
+ SbkObject *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(object);
+ if (wrapper != nullptr)
+ Shiboken::BindingManager::instance().releaseWrapper(wrapper);
+}
+
+static const char invalidatePropertyName[] = "_PySideInvalidatePtr";
+
+// PYSIDE-2749: Skip over internal QML classes and classes
+// with dynamic meta objects when looking for the best matching
+// type to avoid unnessarily triggering the lazy load mechanism
+// for classes that do not have a binding from things like eventFilter().
+static inline bool isInternalObject(const char *name)
+{
+ return std::strstr(name, "QMLTYPE") != nullptr || std::strstr(name, "QQmlPrivate") != nullptr;
+}
+
+static const QMetaObject *metaObjectCandidate(const QObject *o)
+{
+ auto *metaObject = o->metaObject();
+ // Skip QML helper types and Python objects
+ if (hasDynamicMetaObject(o)) {
+ if (auto *super = metaObject->superClass())
+ metaObject = super;
+ }
+ for (auto *candidate = metaObject; candidate != nullptr; candidate = candidate->superClass()) {
+ if (!isInternalObject(candidate->className())) {
+ metaObject = candidate;
+ break;
+ }
+ }
+ return metaObject;
+}
+
+// PYSIDE-1214, when creating new wrappers for classes inheriting QObject but
+// not exposed to Python, try to find the best-matching (most-derived) Qt
+// class by walking up the meta objects.
+static const char *typeName(const QObject *cppSelf)
+{
+ const char *typeName = typeid(*cppSelf).name();
+ if (!Shiboken::Conversions::getConverter(typeName)) {
+ auto *metaObject = metaObjectCandidate(cppSelf);
+ for (; metaObject != nullptr; metaObject = metaObject->superClass()) {
+ const char *name = metaObject->className();
+ if (Shiboken::Conversions::getConverter(name)) {
+ typeName = name;
+ break;
+ }
+ }
+ }
+ return typeName;
+}
+
+PyTypeObject *getTypeForQObject(const QObject *cppSelf)
+{
+ // First check if there are any instances of Python implementations
+ // inheriting a PySide class.
+ auto *existing = Shiboken::BindingManager::instance().retrieveWrapper(cppSelf);
+ if (existing != nullptr)
+ return reinterpret_cast<PyObject *>(existing)->ob_type;
+ // Find the best match (will return a PySide type)
+ auto *sbkObjectType = Shiboken::ObjectType::typeForTypeName(typeName(cppSelf));
+ if (sbkObjectType != nullptr)
+ return reinterpret_cast<PyTypeObject *>(sbkObjectType);
+ return nullptr;
+}
+
+PyObject *getWrapperForQObject(QObject *cppSelf, PyTypeObject *sbk_type)
+{
+ PyObject *pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppSelf));
+ if (pyOut) {
+ Py_INCREF(pyOut);
+ return pyOut;
+ }
+
+ // Setting the property will trigger an QEvent notification, which may call into
+ // code that creates the wrapper so only set the property if it isn't already
+ // set and check if it's created after the set call
+ QVariant existing = cppSelf->property(invalidatePropertyName);
+ if (!existing.isValid()) {
+ if (cppSelf->thread() == QThread::currentThread()) {
+ std::shared_ptr<any_t> shared_with_del(reinterpret_cast<any_t *>(cppSelf), invalidatePtr);
+ cppSelf->setProperty(invalidatePropertyName, QVariant::fromValue(shared_with_del));
+ }
+ pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppSelf));
+ if (pyOut) {
+ Py_INCREF(pyOut);
+ return pyOut;
+ }
+ }
+
+ pyOut = Shiboken::Object::newObjectWithHeuristics(sbk_type, cppSelf, false, typeName(cppSelf));
+
+ return pyOut;
+}
+
+QString pyUnicodeToQString(PyObject *str)
+{
+ Q_ASSERT(PyUnicode_Check(str) != 0);
+
+ const void *data = _PepUnicode_DATA(str);
+ const Py_ssize_t len = PyUnicode_GetLength(str);
+ switch (_PepUnicode_KIND(str)) {
+ case PepUnicode_1BYTE_KIND:
+ return QString::fromLatin1(reinterpret_cast<const char *>(data), len);
+ case PepUnicode_2BYTE_KIND:
+ return QString::fromUtf16(reinterpret_cast<const char16_t *>(data), len);
+ case PepUnicode_4BYTE_KIND:
+ break;
+ }
+ return QString::fromUcs4(reinterpret_cast<const char32_t *>(data), len);
+}
+
+PyObject *qStringToPyUnicode(QStringView s)
+{
+ const QByteArray ba = s.toUtf8();
+ return PyUnicode_FromStringAndSize(ba.constData(), ba.size());
+}
+
+// Inspired by Shiboken::String::toCString;
+QString pyStringToQString(PyObject *str)
+{
+ if (str == Py_None)
+ return QString();
+
+ if (PyUnicode_Check(str) != 0)
+ return pyUnicodeToQString(str);
+
+ if (PyBytes_Check(str)) {
+ const char *asciiBuffer = PyBytes_AS_STRING(str);
+ if (asciiBuffer)
+ return QString::fromLatin1(asciiBuffer);
+ }
+ return QString();
+}
+
+// PySide-1499: Provide an efficient, correct PathLike interface
+QString pyPathToQString(PyObject *path)
+{
+ // For empty constructors path can be nullptr
+ // fallback to an empty QString in that case.
+ if (!path)
+ return QString();
+
+ // str or bytes pass through
+ if (PyUnicode_Check(path) || PyBytes_Check(path))
+ return pyStringToQString(path);
+
+ // Let PyOS_FSPath do its work and then fix the result for Windows.
+ Shiboken::AutoDecRef strPath(PyOS_FSPath(path));
+ if (strPath.isNull())
+ return QString();
+ return QDir::fromNativeSeparators(pyStringToQString(strPath));
+}
+
+bool isCompiledMethod(PyObject *callback)
+{
+ return PyObject_HasAttr(callback, PySide::PySideName::im_func())
+ && PyObject_HasAttr(callback, PySide::PySideName::im_self())
+ && PyObject_HasAttr(callback, PySide::PySideMagicName::code());
+}
+
+static const unsigned char qt_resource_name[] = {
+ // qt
+ 0x0,0x2,
+ 0x0,0x0,0x7,0x84,
+ 0x0,0x71,
+ 0x0,0x74,
+ // etc
+ 0x0,0x3,
+ 0x0,0x0,0x6c,0xa3,
+ 0x0,0x65,
+ 0x0,0x74,0x0,0x63,
+ // qt.conf
+ 0x0,0x7,
+ 0x8,0x74,0xa6,0xa6,
+ 0x0,0x71,
+ 0x0,0x74,0x0,0x2e,0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x66
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+ // :/qt
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,
+ // :/qt/etc
+ 0x0,0x0,0x0,0xa,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,
+ // :/qt/etc/qt.conf
+ 0x0,0x0,0x0,0x16,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0
+};
+
+bool registerInternalQtConf()
+{
+ // Guard to ensure single registration.
+#ifdef PYSIDE_QT_CONF_PREFIX
+ static bool registrationAttempted = false;
+#else
+ static bool registrationAttempted = true;
+#endif
+ static bool isRegistered = false;
+ if (registrationAttempted)
+ return isRegistered;
+ registrationAttempted = true;
+
+ // Support PyInstaller case when a qt.conf file might be provided next to the generated
+ // PyInstaller executable.
+ // This will disable the internal qt.conf which points to the PySide6 subdirectory (due to the
+ // subdirectory not existing anymore).
+#ifndef PYPY_VERSION
+ QString executablePath = QString::fromWCharArray(Py_GetProgramFullPath());
+#else
+ // PYSIDE-535: FIXME: Add this function when available.
+ QString executablePath = QLatin1StringView("missing Py_GetProgramFullPath");
+#endif // PYPY_VERSION
+
+ QString appDirPath = QFileInfo(executablePath).absolutePath();
+
+ QString maybeQtConfPath = QDir(appDirPath).filePath(u"qt.conf"_s);
+ maybeQtConfPath = QDir::toNativeSeparators(maybeQtConfPath);
+ bool executableQtConfAvailable = QFileInfo::exists(maybeQtConfPath);
+
+ QString maybeQt6ConfPath = QDir(appDirPath).filePath(u"qt6.conf"_s);
+ maybeQt6ConfPath = QDir::toNativeSeparators(maybeQt6ConfPath);
+ bool executableQt6ConfAvailable = QFileInfo::exists(maybeQt6ConfPath);
+
+ // Allow disabling the usage of the internal qt.conf. This is necessary for tests to work,
+ // because tests are executed before the package is installed, and thus the Prefix specified
+ // in qt.conf would point to a not yet existing location.
+ bool disableInternalQtConf =
+ qEnvironmentVariableIntValue("PYSIDE_DISABLE_INTERNAL_QT_CONF") > 0;
+ bool runsInConda =
+ qEnvironmentVariableIsSet("CONDA_DEFAULT_ENV") || qEnvironmentVariableIsSet("CONDA_PREFIX");
+
+ if ((!runsInConda && (disableInternalQtConf || executableQtConfAvailable))
+ || (runsInConda && executableQt6ConfAvailable)) {
+ registrationAttempted = true;
+ return false;
+ }
+
+ PyObject *pysideModule = PyImport_ImportModule("PySide6");
+ if (!pysideModule)
+ return false;
+
+ // Querying __file__ should be done only for modules that have finished their initialization.
+ // Thus querying for the top-level PySide6 package works for us whenever any Qt-wrapped module
+ // is loaded.
+ PyObject *pysideInitFilePath = PyObject_GetAttr(pysideModule, Shiboken::PyMagicName::file());
+ Py_DECREF(pysideModule);
+ if (!pysideInitFilePath)
+ return false;
+
+ QString initPath = pyStringToQString(pysideInitFilePath);
+ Py_DECREF(pysideInitFilePath);
+ if (initPath.isEmpty())
+ return false;
+
+ // pysideDir - absolute path to the directory containing the init file, which also contains
+ // the rest of the PySide6 modules.
+ // prefixPath - absolute path to the directory containing the installed Qt (prefix).
+ QDir pysideDir = QFileInfo(QDir::fromNativeSeparators(initPath)).absoluteDir();
+ QString setupPrefix;
+#ifdef PYSIDE_QT_CONF_PREFIX
+ setupPrefix = QStringLiteral(PYSIDE_QT_CONF_PREFIX);
+#endif
+ const QByteArray prefixPath = pysideDir.absoluteFilePath(setupPrefix).toUtf8();
+
+ // rccData needs to be static, otherwise when it goes out of scope, the Qt resource system
+ // will point to invalid memory.
+ static QByteArray rccData = QByteArrayLiteral("[Paths]\nPrefix = ") + prefixPath + "\n";
+#ifdef Q_OS_WIN
+ // LibraryExecutables needs to point to Prefix instead of ./bin because we don't
+ // currently conform to the Qt default directory layout on Windows. This is necessary
+ // for QtWebEngineCore to find the location of QtWebEngineProcess.exe.
+ rccData += QByteArrayLiteral("LibraryExecutables = ") + prefixPath + "\n";
+#endif
+
+ // The RCC data structure expects a 4-byte size value representing the actual data.
+ qsizetype size = rccData.size();
+
+ for (int i = 0; i < 4; ++i) {
+ rccData.prepend((size & 0xff));
+ size >>= 8;
+ }
+
+ const int version = 0x01;
+ isRegistered = qRegisterResourceData(version, qt_resource_struct, qt_resource_name,
+ reinterpret_cast<const unsigned char *>(
+ rccData.constData()));
+
+ return isRegistered;
+}
+
+static PyTypeObject *qobjectType()
+{
+ static PyTypeObject * const result = Shiboken::Conversions::getPythonTypeObject("QObject*");
+ return result;
+}
+
+bool isQObjectDerived(PyTypeObject *pyType, bool raiseError)
+{
+ const bool result = PyType_IsSubtype(pyType, qobjectType());
+ if (!result && raiseError) {
+ PyErr_Format(PyExc_TypeError, "A type inherited from %s expected, got %s.",
+ qobjectType()->tp_name, pyType->tp_name);
+ }
+ return result;
+}
+
+QObject *convertToQObject(PyObject *object, bool raiseError)
+{
+ if (object == nullptr) {
+ if (raiseError)
+ PyErr_Format(PyExc_TypeError, "None passed for QObject");
+ return nullptr;
+ }
+
+ if (!isQObjectDerived(Py_TYPE(object), raiseError))
+ return nullptr;
+
+ auto *sbkObject = reinterpret_cast<SbkObject*>(object);
+ auto *ptr = Shiboken::Object::cppPointer(sbkObject, qobjectType());
+ if (ptr == nullptr) {
+ if (raiseError) {
+ PyErr_Format(PyExc_TypeError, "Conversion of %s to QObject failed.",
+ Py_TYPE(object)->tp_name);
+ }
+ return nullptr;
+ }
+ return reinterpret_cast<QObject*>(ptr);
+}
+
+QMetaType qMetaTypeFromPyType(PyTypeObject *pyType)
+{
+ if (Shiboken::String::checkType(pyType))
+ return QMetaType(QMetaType::QString);
+ if (pyType == &PyFloat_Type)
+ return QMetaType(QMetaType::Double);
+ if (pyType == &PyLong_Type)
+ return QMetaType(QMetaType::Int);
+ if (Shiboken::ObjectType::checkType(pyType))
+ return QMetaType::fromName(Shiboken::ObjectType::getOriginalName(pyType));
+ return QMetaType::fromName(pyType->tp_name);
+}
+
+debugPyTypeObject::debugPyTypeObject(const PyTypeObject *o) noexcept
+ : m_object(o)
+{
+}
+
+QDebug operator<<(QDebug debug, const debugPyTypeObject &o)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "PyTypeObject(";
+ if (o.m_object)
+ debug << '"' << o.m_object->tp_name << '"';
+ else
+ debug << '0';
+ debug << ')';
+ return debug;
+}
+
+static void formatPyObject(PyObject *obj, QDebug &debug);
+
+static void formatPySequence(PyObject *obj, QDebug &debug)
+{
+ const Py_ssize_t size = PySequence_Size(obj);
+ debug << size << " [";
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ if (i)
+ debug << ", ";
+ Shiboken::AutoDecRef item(PySequence_GetItem(obj, i));
+ formatPyObject(item.object(), debug);
+ }
+ debug << ']';
+}
+
+static void formatPyDict(PyObject *obj, QDebug &debug)
+{
+ PyObject *key;
+ PyObject *value;
+ Py_ssize_t pos = 0;
+ bool first = true;
+ debug << '{';
+ while (PyDict_Next(obj, &pos, &key, &value) != 0) {
+ if (first)
+ first = false;
+ else
+ debug << ", ";
+ formatPyObject(key, debug);
+ debug << '=';
+ formatPyObject(value, debug);
+ }
+ debug << '}';
+}
+
+static inline const char *pyTypeName(PyObject *obj)
+{
+ return Py_TYPE(obj)->tp_name;
+}
+
+static QString getQualName(PyObject *obj)
+{
+ Shiboken::AutoDecRef result(PyObject_GetAttr(obj, Shiboken::PyMagicName::qualname()));
+ return result.object() != nullptr
+ ? pyStringToQString(result.object()) : QString{};
+}
+
+static void formatPyFunction(PyObject *obj, QDebug &debug)
+{
+ debug << '"' << getQualName(obj) << "()\"";
+}
+
+static void formatPyMethod(PyObject *obj, QDebug &debug)
+{
+ if (auto *func = PyMethod_Function(obj))
+ formatPyFunction(func, debug);
+ debug << ", instance=" << PyMethod_Self(obj);
+}
+
+static void formatPyObjectValue(PyObject *obj, QDebug &debug)
+{
+ if (PyType_Check(obj) != 0)
+ debug << "type: \"" << pyTypeName(obj) << '"';
+ else if (PyLong_Check(obj) != 0) {
+ const auto llv = PyLong_AsLongLong(obj);
+ if (PyErr_Occurred() != PyExc_OverflowError) {
+ debug << llv;
+ } else {
+ PyErr_Clear();
+ debug << "0x" << Qt::hex << PyLong_AsUnsignedLongLong(obj) << Qt::dec;
+ }
+ } else if (PyFloat_Check(obj) != 0)
+ debug << PyFloat_AsDouble(obj);
+ else if (PyUnicode_Check(obj) != 0)
+ debug << '"' << pyStringToQString(obj) << '"';
+ else if (PyFunction_Check(obj) != 0)
+ formatPyFunction(obj, debug);
+ else if (PyMethod_Check(obj) != 0)
+ formatPyMethod(obj, debug);
+ else if (PySequence_Check(obj) != 0)
+ formatPySequence(obj, debug);
+ else if (PyDict_Check(obj) != 0)
+ formatPyDict(obj, debug);
+ else
+ debug << obj;
+}
+
+static void formatPyObject(PyObject *obj, QDebug &debug)
+{
+ if (obj == nullptr) {
+ debug << '0';
+ return;
+ }
+ if (obj == Py_None) {
+ debug << "None";
+ return;
+ }
+ if (obj == Py_True) {
+ debug << "True";
+ return;
+ }
+ if (obj == Py_False) {
+ debug << "False";
+ return;
+ }
+ if (PyType_Check(obj) == 0)
+ debug << pyTypeName(obj) << ": ";
+ formatPyObjectValue(obj, debug);
+}
+
+debugPyObject::debugPyObject(PyObject *o) noexcept : m_object(o)
+{
+}
+
+QDebug operator<<(QDebug debug, const debugPyObject &o)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "PyObject(";
+ formatPyObject(o.m_object, debug);
+ debug << ')';
+ return debug;
+}
+
+debugPyBuffer::debugPyBuffer(Py_buffer *b) noexcept : m_buffer(b)
+{
+}
+
+static void formatPy_ssizeArray(QDebug &debug, const char *name, const Py_ssize_t *array, int len)
+{
+ debug << ", " << name << '=';
+ if (array != nullptr) {
+ debug << '[';
+ for (int i = 0; i < len; ++i)
+ debug << array[i] << ' ';
+ debug << ']';
+ } else {
+ debug << '0';
+ }
+}
+
+PYSIDE_API QDebug operator<<(QDebug debug, const debugPyBuffer &b)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Py_buffer(";
+ if (b.m_buffer != nullptr) {
+ debug << "obj=" << b.m_buffer->obj
+ << ", buf=" << b.m_buffer->buf << ", len=" << b.m_buffer->len
+ << ", readonly=" << b.m_buffer->readonly
+ << ", itemsize=" << b.m_buffer->itemsize << ", format=";
+ if (b.m_buffer->format != nullptr)
+ debug << '"' << b.m_buffer->format << '"';
+ else
+ debug << '0';
+ debug << ", ndim=" << b.m_buffer->ndim;
+ formatPy_ssizeArray(debug, "shape", b.m_buffer->shape, b.m_buffer->ndim);
+ formatPy_ssizeArray(debug, "strides", b.m_buffer->strides, b.m_buffer->ndim);
+ formatPy_ssizeArray(debug, "suboffsets", b.m_buffer->suboffsets, b.m_buffer->ndim);
+ } else {
+ debug << '0';
+ }
+ debug << ')';
+ return debug;
+}
+
+} // namespace PySide
diff --git a/sources/pyside6/libpyside/pyside.h b/sources/pyside6/libpyside/pyside.h
new file mode 100644
index 000000000..c8793cbf0
--- /dev/null
+++ b/sources/pyside6/libpyside/pyside.h
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_H
+#define PYSIDE_H
+
+#include <sbkpython.h>
+
+#include <pysidemacros.h>
+
+#include "pysideinit.h"
+#include "pysideqapp.h"
+#include "pysideqobject.h"
+#include "pysideutils.h"
+
+#endif // PYSIDE_H
diff --git a/sources/pyside6/libpyside/pyside6.pc.in b/sources/pyside6/libpyside/pyside6.pc.in
new file mode 100644
index 000000000..394372539
--- /dev/null
+++ b/sources/pyside6/libpyside/pyside6.pc.in
@@ -0,0 +1,15 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@CMAKE_INSTALL_PREFIX@/include/PySide6@pyside6_SUFFIX@
+typesystemdir=@CMAKE_INSTALL_PREFIX@/share/PySide6@pyside6_SUFFIX@/typesystems
+gluedir=@CMAKE_INSTALL_PREFIX@/share/PySide6@pyside6_SUFFIX@/glue
+pythonpath=@PYTHON_SITE_PACKAGES@
+
+Name: PySide6@pyside6_SUFFIX@
+Description: Support library for Python bindings of Qt5-based libraries.
+Version: @BINDING_API_VERSION_FULL@
+Libs: -L${libdir} -lpyside6@pyside6_SUFFIX@@SHIBOKEN_PYTHON_CONFIG_SUFFIX@@LIBRARY_OUTPUT_SUFFIX@
+Cflags: -I${includedir}
+Requires: shiboken6
+
diff --git a/sources/pyside6/libpyside/pyside_numpy.cpp b/sources/pyside6/libpyside/pyside_numpy.cpp
new file mode 100644
index 000000000..5f43cc5ce
--- /dev/null
+++ b/sources/pyside6/libpyside/pyside_numpy.cpp
@@ -0,0 +1,98 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pyside_numpy.h"
+#include <sbknumpyview.h>
+
+// Convert X,Y of type T data to a list of points (QPoint, PointF)
+template <class T, class Point>
+static QList<Point>
+ xyDataToQPointHelper(const void *xData, const void *yData, qsizetype size)
+{
+ auto *x = reinterpret_cast<const T *>(xData);
+ auto *y = reinterpret_cast<const T *>(yData);
+ QList<Point> result;
+ result.reserve(size);
+ for (auto xEnd = x + size; x < xEnd; ++x, ++y)
+ result.append(Point(*x, *y));
+ return result;
+}
+
+// Convert X,Y of double/float type data to a list of QPoint (rounding)
+template <class T>
+static QList<QPoint>
+ xyFloatDataToQPointHelper(const void *xData, const void *yData, qsizetype size)
+{
+ auto *x = reinterpret_cast<const T *>(xData);
+ auto *y = reinterpret_cast<const T *>(yData);
+ QList<QPoint> result;
+ result.reserve(size);
+ for (auto xEnd = x + size; x < xEnd; ++x, ++y)
+ result.append(QPoint(qRound(*x), qRound(*y)));
+ return result;
+}
+
+namespace PySide::Numpy
+{
+
+QList<QPointF> xyDataToQPointFList(PyObject *pyXIn, PyObject *pyYIn)
+{
+ auto xv = Shiboken::Numpy::View::fromPyObject(pyXIn);
+ auto yv = Shiboken::Numpy::View::fromPyObject(pyYIn);
+ if (!xv.sameLayout(yv))
+ return {};
+ const qsizetype size = qMin(xv.dimensions[0], yv.dimensions[0]);
+ if (size == 0)
+ return {};
+ switch (xv.type) {
+ case Shiboken::Numpy::View::Int16:
+ return xyDataToQPointHelper<int16_t, QPointF>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Unsigned16:
+ return xyDataToQPointHelper<uint16_t, QPointF>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Int:
+ return xyDataToQPointHelper<int, QPointF>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Unsigned:
+ return xyDataToQPointHelper<unsigned, QPointF>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Int64:
+ return xyDataToQPointHelper<int64_t, QPointF>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Unsigned64:
+ return xyDataToQPointHelper<uint64_t, QPointF>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Float:
+ return xyDataToQPointHelper<float, QPointF>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Double:
+ break;
+ }
+ return xyDataToQPointHelper<double, QPointF>(xv.data, yv.data, size);
+}
+
+QList<QPoint> xyDataToQPointList(PyObject *pyXIn, PyObject *pyYIn)
+{
+ auto xv = Shiboken::Numpy::View::fromPyObject(pyXIn);
+ auto yv = Shiboken::Numpy::View::fromPyObject(pyYIn);
+ if (!xv.sameLayout(yv))
+ return {};
+ const qsizetype size = qMin(xv.dimensions[0], yv.dimensions[0]);
+ if (size == 0)
+ return {};
+ switch (xv.type) {
+ case Shiboken::Numpy::View::Int16:
+ return xyDataToQPointHelper<int16_t, QPoint>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Unsigned16:
+ return xyDataToQPointHelper<uint16_t, QPoint>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Int:
+ return xyDataToQPointHelper<int, QPoint>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Unsigned:
+ return xyDataToQPointHelper<unsigned, QPoint>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Int64:
+ return xyDataToQPointHelper<int64_t, QPoint>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Unsigned64:
+ return xyDataToQPointHelper<uint64_t, QPoint>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Float:
+ return xyFloatDataToQPointHelper<float>(xv.data, yv.data, size);
+ case Shiboken::Numpy::View::Double:
+ break;
+ }
+ return xyFloatDataToQPointHelper<double>(xv.data, yv.data, size);
+}
+
+} //namespace PySide::Numpy
diff --git a/sources/pyside6/libpyside/pyside_numpy.h b/sources/pyside6/libpyside/pyside_numpy.h
new file mode 100644
index 000000000..0925a6bd6
--- /dev/null
+++ b/sources/pyside6/libpyside/pyside_numpy.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_NUMPY_H
+#define PYSIDE_NUMPY_H
+
+#include <sbkpython.h>
+#include <sbknumpycheck.h>
+
+#include <pysidemacros.h>
+
+#include <QtCore/QList>
+#include <QtCore/QPoint>
+#include <QtCore/QPointF>
+
+namespace PySide::Numpy
+{
+
+/// Create a list of QPointF from 2 equally sized numpy array of x and y data
+/// (float,double).
+/// \param pyXIn X data array
+/// \param pyYIn Y data array
+/// \return List of QPointF
+
+PYSIDE_API QList<QPointF> xyDataToQPointFList(PyObject *pyXIn, PyObject *pyYIn);
+
+/// Create a list of QPoint from 2 equally sized numpy array of x and y data
+/// (int).
+/// \param pyXIn X data array
+/// \param pyYIn Y data array
+/// \return List of QPoint
+
+PYSIDE_API QList<QPoint> xyDataToQPointList(PyObject *pyXIn, PyObject *pyYIn);
+
+} //namespace PySide::Numpy
+
+#endif // PYSIDE_NUMPY_H
diff --git a/sources/pyside6/libpyside/pyside_p.h b/sources/pyside6/libpyside/pyside_p.h
new file mode 100644
index 000000000..b13c1829a
--- /dev/null
+++ b/sources/pyside6/libpyside/pyside_p.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_P_H
+#define PYSIDE_P_H
+
+#include <pysidemacros.h>
+
+#include <dynamicqmetaobject.h>
+
+namespace PySide
+{
+
+// Struct associated with QObject's via Shiboken::Object::getTypeUserData()
+struct TypeUserData
+{
+ explicit TypeUserData(PyTypeObject* type, const QMetaObject* metaobject, std::size_t size) :
+ mo(type, metaobject), cppObjSize(size) {}
+
+ MetaObjectBuilder mo;
+ std::size_t cppObjSize;
+};
+
+TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj);
+TypeUserData *retrieveTypeUserData(PyObject *pyObj);
+// For QML
+PYSIDE_API const QMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj);
+PYSIDE_API const QMetaObject *retrieveMetaObject(PyObject *pyObj);
+
+} //namespace PySide
+
+#endif // PYSIDE_P_H
diff --git a/sources/pyside6/libpyside/pysideclassdecorator.cpp b/sources/pyside6/libpyside/pysideclassdecorator.cpp
new file mode 100644
index 000000000..ec69c5fe7
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideclassdecorator.cpp
@@ -0,0 +1,103 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <sbkpython.h>
+
+#include "pysideclassdecorator_p.h"
+#include "pysideqobject.h"
+
+#include <basewrapper.h>
+#include <sbkstring.h>
+
+namespace PySide::ClassDecorator {
+
+DecoratorPrivate::DecoratorPrivate() noexcept = default;
+DecoratorPrivate::~DecoratorPrivate() = default;
+
+DecoratorPrivate *DecoratorPrivate::getPrivate(PyObject *o)
+{
+ auto *decorator = reinterpret_cast<PySideClassDecorator *>(o);
+ return decorator->d;
+}
+
+PyObject *DecoratorPrivate::tp_call_check(PyObject *args, CheckMode checkMode) const
+{
+ if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator takes exactly 1 positional argument (%zd given)",
+ name(), PyTuple_Size(args));
+ return nullptr;
+ }
+
+ PyObject *arg = PyTuple_GetItem(args, 0);
+
+ // This will sometimes segfault if you mistakenly use it on a function declaration
+ if (!PyType_Check(arg)) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator can only be used on class declarations", name());
+ return nullptr;
+ }
+
+ auto type = reinterpret_cast<PyTypeObject *>(arg);
+
+ if (checkMode != CheckMode::None && !Shiboken::ObjectType::checkType(type)) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator can only be used on wrapped types.", name());
+ return nullptr;
+ }
+
+ if (checkMode == CheckMode::QObjectType && !isQObjectDerived(type, false)) {
+ PyErr_Format(PyExc_TypeError,
+ "The %s decorator can only be used on QObject-derived types.", name());
+ return nullptr;
+ }
+
+ return arg;
+}
+
+int StringDecoratorPrivate::convertToString(PyObject *self, PyObject *args)
+{
+ int result = -1;
+ if (PyTuple_Size(args) == 1) {
+ PyObject *arg = PyTuple_GET_ITEM(args, 0);
+ if (PyUnicode_Check(arg)) {
+ auto *pData = DecoratorPrivate::get<StringDecoratorPrivate>(self);
+ result = 0;
+ pData->m_string.assign(Shiboken::String::toCString(arg));
+ }
+ }
+ return result;
+}
+
+int StringDecoratorPrivate::tp_init(PyObject *self, PyObject *args, PyObject *)
+{
+ const int result = convertToString(self, args);
+ if (result != 0)
+ PyErr_Format(PyExc_TypeError, "%s takes a single string argument.", name());
+ return result;
+}
+
+int TypeDecoratorPrivate::tp_init(PyObject *self, PyObject *args, PyObject *)
+{
+ const int result = convertToType(self, args);
+ if (result != 0)
+ PyErr_Format(PyExc_TypeError, "%s takes a single type argument.", name());
+ return result;
+}
+
+int TypeDecoratorPrivate::convertToType(PyObject *self, PyObject *args)
+{
+ int result = -1;
+ const auto argsCount = PyTuple_Size(args);
+ if (argsCount == 1) {
+ PyObject *arg = PyTuple_GET_ITEM(args, 0);
+ if (PyType_Check(arg)) {
+ result = 0;
+ auto *pData = DecoratorPrivate::get<TypeDecoratorPrivate>(self);
+ pData->m_type = reinterpret_cast<PyTypeObject *>(arg);
+ }
+ }
+ return result;
+}
+
+} // namespace PySide::ClassDecorator
diff --git a/sources/pyside6/libpyside/pysideclassdecorator_p.h b/sources/pyside6/libpyside/pysideclassdecorator_p.h
new file mode 100644
index 000000000..6068f6a2e
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideclassdecorator_p.h
@@ -0,0 +1,164 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef CLASSDECORATOR_P_H
+#define CLASSDECORATOR_P_H
+
+#include <pysidemacros.h>
+
+#include <sbkpython.h>
+#include <pep384ext.h>
+
+#include <QtCore/QByteArray>
+
+#include <array>
+#include <string>
+
+/// Helpers for class decorators with parameters
+namespace PySide::ClassDecorator {
+
+/// Base class for private objects of class decorators with parameters
+class PYSIDE_API DecoratorPrivate
+{
+public:
+ Q_DISABLE_COPY_MOVE(DecoratorPrivate)
+
+ virtual ~DecoratorPrivate();
+
+ /// Virtual function which is passed the decorated class type
+ /// \param args Decorated class type argument
+ /// \return class with reference count increased if the call was successful,
+ /// else nullptr
+ virtual PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) = 0;
+
+ /// Virtual function which is passed the decorator parameters
+ /// \param args Decorator arguments
+ /// \return 0 if the parameters are correct
+ virtual int tp_init(PyObject *self, PyObject *args, PyObject *kwds) = 0;
+ virtual const char *name() const = 0;
+
+ /// Helper that returns DecoratorPrivate instance from a PyObject
+ template <class DerivedPrivate>
+ static DerivedPrivate *get(PyObject *o)
+ { return static_cast<DerivedPrivate *>(DecoratorPrivate::getPrivate(o)); }
+
+protected:
+ /// Check mode for the arguments of the call operator
+ enum class CheckMode { None, WrappedType, QObjectType };
+
+ DecoratorPrivate() noexcept;
+ static DecoratorPrivate *getPrivate(PyObject *o);
+
+ /// Helper for checking the arguments of the call operator
+ /// \param args Arguments
+ /// \param checkMode Type check mode
+ /// \return The type object extracted from args tuple (borrowed reference)
+ /// if the argument is a matching type
+ PyObject *tp_call_check(PyObject *args,
+ CheckMode checkMode = CheckMode::QObjectType) const;
+};
+
+/// Base class for private objects of class decorator with a string parameter
+class PYSIDE_API StringDecoratorPrivate : public DecoratorPrivate
+{
+public:
+ /// Init function that retrieves the string parameter using convertToString()
+ int tp_init(PyObject *self, PyObject *args, PyObject *kwds) override;
+
+ QByteArray string() const { return m_string; }
+
+protected:
+ /// Helper function that retrieves the string parameter
+ /// \param self self
+ /// \param args Arguments
+ /// \return 0 if the parameter is correct, else -1 (for tp_init())
+ int convertToString(PyObject *self, PyObject *args);
+
+private:
+ QByteArray m_string;
+};
+
+/// Base class for private objects of class decorator with a type parameter
+class PYSIDE_API TypeDecoratorPrivate : public DecoratorPrivate
+{
+public:
+ /// Init function that retrieves the type parameter using convertToType()
+ int tp_init(PyObject *self, PyObject *args, PyObject *kwds) override;
+
+ PyTypeObject *type() const { return m_type; }
+
+protected:
+ /// Helper function that retrieves the type parameter
+ /// \param self self
+ /// \param args Arguments
+ /// \return 0 if the parameter is correct, else -1 (for tp_init())
+ int convertToType(PyObject *self, PyObject *args);
+
+private:
+ PyTypeObject *m_type = nullptr;
+};
+
+} // namespace PySide::ClassDecorator
+
+extern "C"
+{
+LIBSHIBOKEN_API void Sbk_object_dealloc(PyObject *self);
+
+/// Python type for class decorators with DecoratorPrivate
+struct PYSIDE_API PySideClassDecorator
+{
+ PyObject_HEAD
+ PySide::ClassDecorator::DecoratorPrivate *d;
+};
+};
+
+namespace PySide::ClassDecorator {
+
+/// Helper template providing the methods (slots) for class decorators
+template <class DecoratorPrivate>
+struct Methods
+{
+ static PyObject *tp_new(PyTypeObject *subtype)
+ {
+ auto *result = PepExt_TypeCallAlloc<PySideClassDecorator>(subtype, 0);
+ result->d = new DecoratorPrivate;
+ return reinterpret_cast<PyObject *>(result);
+ }
+
+ static void tp_free(void *self)
+ {
+ auto pySelf = reinterpret_cast<PyObject *>(self);
+ auto decorator = reinterpret_cast<PySideClassDecorator *>(self);
+ delete decorator->d;
+ PepExt_TypeCallFree(Py_TYPE(pySelf)->tp_base, self);
+ }
+
+ static PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwds)
+ {
+ auto *decorator = reinterpret_cast<PySideClassDecorator *>(self);
+ return decorator->d->tp_call(self, args, kwds);
+ }
+
+ static int tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+ {
+ auto *decorator = reinterpret_cast<PySideClassDecorator *>(self);
+ return decorator->d->tp_init(self, args, kwds);
+ }
+
+ using TypeSlots = std::array<PyType_Slot, 6>;
+
+ static TypeSlots typeSlots()
+ {
+ return { {{Py_tp_call, reinterpret_cast<void *>(tp_call)},
+ {Py_tp_init, reinterpret_cast<void *>(tp_init)},
+ {Py_tp_new, reinterpret_cast<void *>(tp_new)},
+ {Py_tp_free, reinterpret_cast<void *>(tp_free)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {0, nullptr}}
+ };
+ }
+};
+
+} // namespace PySide::ClassDecorator
+
+#endif // CLASSDECORATOR_P_H
diff --git a/sources/pyside6/libpyside/pysideclassinfo.cpp b/sources/pyside6/libpyside/pysideclassinfo.cpp
new file mode 100644
index 000000000..698cb1c76
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideclassinfo.cpp
@@ -0,0 +1,158 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <sbkpython.h>
+
+#include "pysideclassinfo.h"
+#include "pyside_p.h"
+#include "pysideclassinfo_p.h"
+#include "dynamicqmetaobject.h"
+
+#include <shiboken.h>
+#include <signature.h>
+
+extern "C"
+{
+
+static PyTypeObject *createClassInfoType()
+{
+ auto typeSlots =
+ PySide::ClassDecorator::Methods<PySide::ClassInfo::ClassInfoPrivate>::typeSlots();
+
+ PyType_Spec PySideClassInfoType_spec = {
+ "2:PySide6.QtCore.ClassInfo",
+ sizeof(PySideClassDecorator),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ typeSlots.data()};
+ return SbkType_FromSpec(&PySideClassInfoType_spec);
+};
+
+PyTypeObject *PySideClassInfo_TypeF(void)
+{
+ static auto *type = createClassInfoType();
+ return type;
+}
+
+} // extern "C"
+
+namespace PySide::ClassInfo {
+
+const char *ClassInfoPrivate::name() const
+{
+ return "ClassInfo";
+}
+
+PyObject *ClassInfoPrivate::tp_call(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PyObject *klass = tp_call_check(args, CheckMode::QObjectType);
+ if (klass == nullptr)
+ return nullptr;
+
+ auto *pData = DecoratorPrivate::get<ClassInfoPrivate>(self);
+
+ if (pData->m_alreadyWrapped)
+ return PyErr_Format(PyExc_TypeError, "This instance of ClassInfo() was already used to wrap an object");
+
+ PyTypeObject *klassType = reinterpret_cast<PyTypeObject *>(klass);
+ if (!PySide::ClassInfo::setClassInfo(klassType, pData->m_data))
+ return PyErr_Format(PyExc_TypeError, "This decorator can only be used on classes that are subclasses of QObject");
+
+ pData->m_alreadyWrapped = true;
+
+ Py_INCREF(klass);
+ return klass;
+}
+
+int ClassInfoPrivate::tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *infoDict = nullptr;
+ auto size = PyTuple_Size(args);
+ if (size == 1 && kwds == nullptr) {
+ PyObject *tmp = PyTuple_GET_ITEM(args, 0);
+ if (PyDict_Check(tmp))
+ infoDict = tmp;
+ } else if (size == 0 && kwds && PyDict_Check(kwds)) {
+ infoDict = kwds;
+ }
+
+ if (infoDict == nullptr) {
+ PyErr_Format(PyExc_TypeError, "ClassInfo() takes either keyword argument(s) or "
+ "a single dictionary argument");
+ return -1;
+ }
+
+ auto *pData = DecoratorPrivate::get<ClassInfoPrivate>(self);
+
+ PyObject *key{};
+ PyObject *value{};
+ Py_ssize_t pos = 0;
+
+ // PyDict_Next causes a segfault if kwds is empty
+ if (PyDict_Size(infoDict) > 0) {
+ while (PyDict_Next(infoDict, &pos, &key, &value)) {
+ if (Shiboken::String::check(key) && Shiboken::String::check(value)) {
+ ClassInfo info{Shiboken::String::toCString(key),
+ Shiboken::String::toCString(value)};
+ pData->m_data.append(info);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "All keys and values provided to ClassInfo() "
+ "must be strings");
+ return -1;
+ }
+ }
+ }
+
+ return PyErr_Occurred() != nullptr ? -1 : 0;
+}
+
+static const char *ClassInfo_SignatureStrings[] = {
+ "PySide6.QtCore.ClassInfo(self,**info:typing.Dict[str,str])",
+ nullptr}; // Sentinel
+
+void init(PyObject *module)
+{
+ if (InitSignatureStrings(PySideClassInfo_TypeF(), ClassInfo_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideClassInfo_TypeF());
+ PyModule_AddObject(module, "ClassInfo", reinterpret_cast<PyObject *>(PySideClassInfo_TypeF()));
+}
+
+bool checkType(PyObject *pyObj)
+{
+ return pyObj != nullptr
+ && PyType_IsSubtype(Py_TYPE(pyObj), PySideClassInfo_TypeF()) != 0;
+}
+
+ClassInfoList getClassInfoList(PyObject *decorator)
+{
+ auto *pData = PySide::ClassDecorator::DecoratorPrivate::get<ClassInfoPrivate>(decorator);
+ return pData->m_data;
+}
+
+bool setClassInfo(PyTypeObject *type, const QByteArray &key,
+ const QByteArray &value)
+{
+ auto *userData = PySide::retrieveTypeUserData(type);
+ const bool result = userData != nullptr;
+ if (result) {
+ PySide::MetaObjectBuilder &mo = userData->mo;
+ mo.addInfo(key, value);
+ }
+ return result;
+}
+
+bool setClassInfo(PyTypeObject *type, const ClassInfoList &list)
+{
+ auto *userData = PySide::retrieveTypeUserData(type);
+ const bool result = userData != nullptr;
+ if (result) {
+ PySide::MetaObjectBuilder &mo = userData->mo;
+ for (const auto &info : list)
+ mo.addInfo(info.key.constData(), info.value.constData());
+ }
+ return result;
+}
+
+} //namespace PySide::ClassInfo
diff --git a/sources/pyside6/libpyside/pysideclassinfo.h b/sources/pyside6/libpyside/pysideclassinfo.h
new file mode 100644
index 000000000..e04865829
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideclassinfo.h
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_CLASSINFO_H
+#define PYSIDE_CLASSINFO_H
+
+#include <pysidemacros.h>
+
+#include <sbkpython.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+
+namespace PySide::ClassInfo {
+
+struct ClassInfo
+{
+ QByteArray key;
+ QByteArray value;
+};
+
+using ClassInfoList = QList<ClassInfo>;
+
+PYSIDE_API bool checkType(PyObject* pyObj);
+PYSIDE_API ClassInfoList getClassInfoList(PyObject *decorator);
+
+PYSIDE_API bool setClassInfo(PyTypeObject *type, const QByteArray &key,
+ const QByteArray &value);
+PYSIDE_API bool setClassInfo(PyTypeObject *type, const ClassInfoList &list);
+
+} // namespace PySide::ClassInfo
+
+#endif
diff --git a/sources/pyside6/libpyside/pysideclassinfo_p.h b/sources/pyside6/libpyside/pysideclassinfo_p.h
new file mode 100644
index 000000000..4ef456f76
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideclassinfo_p.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_CLASSINFO_P_H
+#define PYSIDE_CLASSINFO_P_H
+
+#include <sbkpython.h>
+
+#include "pysideclassdecorator_p.h"
+#include "pysideclassinfo.h"
+
+#include <QtCore/QMetaObject>
+
+struct PySideClassInfo;
+
+extern "C"
+{
+extern PYSIDE_API PyTypeObject *PySideClassInfo_TypeF(void);
+
+} // extern "C"
+
+namespace PySide::ClassInfo {
+
+class ClassInfoPrivate : public PySide::ClassDecorator::DecoratorPrivate
+{
+public:
+ PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) override;
+ int tp_init(PyObject *self, PyObject *args, PyObject *kwds) override;
+ const char *name() const override;
+
+ ClassInfoList m_data;
+ bool m_alreadyWrapped = false;
+};
+
+/**
+ * Init PySide QProperty support system
+ */
+void init(PyObject* module);
+
+
+} // namespace PySide::ClassInfo
+
+#endif
diff --git a/sources/pyside6/libpyside/pysidecleanup.h b/sources/pyside6/libpyside/pysidecleanup.h
new file mode 100644
index 000000000..cc5bbb0e6
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidecleanup.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDECLEANUP_H
+#define PYSIDECLEANUP_H
+
+#include <pysidemacros.h>
+
+namespace PySide
+{
+
+using CleanupFunction = void(*)();
+
+/// Register a function to be called before python dies
+PYSIDE_API void registerCleanupFunction(CleanupFunction func);
+PYSIDE_API void runCleanupFunctions();
+
+} //namespace PySide
+
+#endif // PYSIDECLEANUP_H
diff --git a/sources/pyside6/libpyside/pysideinit.h b/sources/pyside6/libpyside/pysideinit.h
new file mode 100644
index 000000000..c623a0d27
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideinit.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEINIT_H
+#define PYSIDEINIT_H
+
+#include <sbkpython.h>
+
+#include <pysidemacros.h>
+
+namespace PySide
+{
+
+PYSIDE_API void init(PyObject *module);
+
+/// Registers a dynamic "qt.conf" file with the Qt resource system.
+///
+/// This is used in a standalone build, to inform QLibraryInfo of the Qt prefix
+/// (where Qt libraries are installed) so that plugins can be successfully loaded.
+///
+/// This is also used if PySide runs from inside a conda environment to solve
+/// conflicts with the qt.conf installed by Anaconda Qt packages.
+PYSIDE_API bool registerInternalQtConf();
+
+} //namespace PySide
+
+#endif // PYSIDEINIT_H
diff --git a/sources/pyside6/libpyside/pysidelogging_p.h b/sources/pyside6/libpyside/pysidelogging_p.h
new file mode 100644
index 000000000..bf167264d
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidelogging_p.h
@@ -0,0 +1,11 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_LOGGING_P_H
+#define PYSIDE_LOGGING_P_H
+
+#include <QtCore/QLoggingCategory>
+
+Q_DECLARE_LOGGING_CATEGORY(lcPySide)
+
+#endif // PYSIDE_LOGGING_P_H
diff --git a/sources/pyside6/libpyside/pysidemacros.h b/sources/pyside6/libpyside/pysidemacros.h
new file mode 100644
index 000000000..46f64b4ed
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidemacros.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEMACROS_H
+#define PYSIDEMACROS_H
+
+#include <shibokenmacros.h>
+
+#define PYSIDE_EXPORT LIBSHIBOKEN_EXPORT
+#define PYSIDE_IMPORT LIBSHIBOKEN_IMPORT
+
+#ifdef BUILD_LIBPYSIDE
+# define PYSIDE_API PYSIDE_EXPORT
+#else
+# define PYSIDE_API PYSIDE_IMPORT
+#endif
+
+#endif // PYSIDEMACROS_H
diff --git a/sources/pyside6/libpyside/pysidemetafunction.cpp b/sources/pyside6/libpyside/pysidemetafunction.cpp
new file mode 100644
index 000000000..e8173b97d
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidemetafunction.cpp
@@ -0,0 +1,197 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysidemetafunction.h"
+#include "pysidemetafunction_p.h"
+
+#include <shiboken.h>
+#include <signature.h>
+
+#include <QtCore/QMetaMethod>
+
+extern "C"
+{
+
+struct PySideMetaFunctionPrivate
+{
+ QObject *qobject;
+ int methodIndex;
+};
+
+//methods
+static void functionFree(void *);
+static PyObject *functionCall(PyObject *, PyObject *, PyObject *);
+
+static PyTypeObject *createMetaFunctionType()
+{
+ PyType_Slot PySideMetaFunctionType_slots[] = {
+ {Py_tp_call, reinterpret_cast<void *>(functionCall)},
+ {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)},
+ {Py_tp_free, reinterpret_cast<void *>(functionFree)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PySideMetaFunctionType_spec = {
+ "2:PySide6.QtCore.MetaFunction",
+ sizeof(PySideMetaFunction),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ PySideMetaFunctionType_slots,
+ };
+
+ return SbkType_FromSpec(&PySideMetaFunctionType_spec);
+}
+
+PyTypeObject *PySideMetaFunction_TypeF(void)
+{
+ static auto *type = createMetaFunctionType();
+ return type;
+}
+
+void functionFree(void *self)
+{
+ PySideMetaFunction *function = reinterpret_cast<PySideMetaFunction *>(self);
+ delete function->d;
+}
+
+PyObject *functionCall(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PySideMetaFunction *function = reinterpret_cast<PySideMetaFunction *>(self);
+
+ PyObject *retVal;
+ if (!PySide::MetaFunction::call(function->d->qobject, function->d->methodIndex, args, &retVal))
+ return nullptr;
+ return retVal;
+}
+
+} // extern "C"
+
+namespace PySide::MetaFunction {
+
+static const char *MetaFunction_SignatureStrings[] = {
+ "PySide6.QtCore.MetaFunction.__call__(self,*args:typing.Any)->typing.Any",
+ nullptr}; // Sentinel
+
+void init(PyObject *module)
+{
+ if (InitSignatureStrings(PySideMetaFunction_TypeF(), MetaFunction_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideMetaFunction_TypeF());
+ PyModule_AddObject(module, "MetaFunction", reinterpret_cast<PyObject *>(PySideMetaFunction_TypeF()));
+}
+
+PySideMetaFunction *newObject(QObject *source, int methodIndex)
+{
+ if (methodIndex >= source->metaObject()->methodCount())
+ return nullptr;
+
+ QMetaMethod method = source->metaObject()->method(methodIndex);
+ if ((method.methodType() == QMetaMethod::Slot) ||
+ (method.methodType() == QMetaMethod::Method)) {
+ PySideMetaFunction *function = PyObject_New(PySideMetaFunction, PySideMetaFunction_TypeF());
+ function->d = new PySideMetaFunctionPrivate();
+ function->d->qobject = source;
+ function->d->methodIndex = methodIndex;
+ return function;
+ }
+ return nullptr;
+}
+
+bool call(QObject *self, int methodIndex, PyObject *args, PyObject **retVal)
+{
+
+ QMetaMethod method = self->metaObject()->method(methodIndex);
+ QList<QByteArray> argTypes = method.parameterTypes();
+
+ // args given plus return type
+ Shiboken::AutoDecRef sequence(PySequence_Fast(args, nullptr));
+ qsizetype numArgs = PySequence_Fast_GET_SIZE(sequence.object()) + 1;
+
+ if (numArgs - 1 > argTypes.size()) {
+ PyErr_Format(PyExc_TypeError, "%s only accepts %d argument(s), %d given!",
+ method.methodSignature().constData(),
+ argTypes.size(), numArgs - 1);
+ return false;
+ }
+
+ if (numArgs - 1 < argTypes.size()) {
+ PyErr_Format(PyExc_TypeError, "%s needs %d argument(s), %d given!",
+ method.methodSignature().constData(),
+ argTypes.size(), numArgs - 1);
+ return false;
+ }
+
+ QVariant *methValues = new QVariant[numArgs];
+ void **methArgs = new void *[numArgs];
+
+ // Prepare room for return type
+ const char *returnType = method.typeName();
+ if (returnType && std::strcmp("void", returnType))
+ argTypes.prepend(returnType);
+ else
+ argTypes.prepend(QByteArray());
+
+ int i = 0;
+ for (; i < numArgs; ++i) {
+ const QByteArray &typeName = argTypes.at(i);
+ // This must happen only when the method hasn't return type.
+ if (typeName.isEmpty()) {
+ methArgs[i] = nullptr;
+ continue;
+ }
+
+ Shiboken::Conversions::SpecificConverter converter(typeName);
+ if (converter) {
+ QMetaType metaType = QMetaType::fromName(typeName);
+ if (!Shiboken::Conversions::pythonTypeIsObjectType(converter)) {
+ if (!metaType.isValid()) {
+ PyErr_Format(PyExc_TypeError, "Value types used on meta functions (including signals) need to be "
+ "registered on meta type: %s", typeName.data());
+ break;
+ }
+ methValues[i] = QVariant(metaType);
+ }
+ methArgs[i] = methValues[i].data();
+ if (i == 0) // Don't do this for return type
+ continue;
+ if (metaType.id() == QMetaType::QString) {
+ QString tmp;
+ converter.toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i - 1), &tmp);
+ methValues[i] = tmp;
+ } else {
+ converter.toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i - 1), methArgs[i]);
+ }
+ } else {
+ PyErr_Format(PyExc_TypeError, "Unknown type used to call meta function (that may be a signal): %s", argTypes[i].constData());
+ break;
+ }
+ }
+
+ bool ok = i == numArgs;
+ if (ok) {
+ Py_BEGIN_ALLOW_THREADS
+ QMetaObject::metacall(self, QMetaObject::InvokeMetaMethod, method.methodIndex(), methArgs);
+ Py_END_ALLOW_THREADS
+
+ if (retVal) {
+ if (methArgs[0]) {
+ static SbkConverter *qVariantTypeConverter = Shiboken::Conversions::getConverter("QVariant");
+ Q_ASSERT(qVariantTypeConverter);
+ *retVal = Shiboken::Conversions::copyToPython(qVariantTypeConverter, &methValues[0]);
+ } else {
+ *retVal = Py_None;
+ Py_INCREF(*retVal);
+ }
+ }
+ }
+
+ delete[] methArgs;
+ delete[] methValues;
+
+ return ok;
+}
+
+} //namespace PySide::MetaFunction
+
diff --git a/sources/pyside6/libpyside/pysidemetafunction.h b/sources/pyside6/libpyside/pysidemetafunction.h
new file mode 100644
index 000000000..26a2cfd68
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidemetafunction.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_METAFUNCTION_H
+#define PYSIDE_METAFUNCTION_H
+
+#include <pysidemacros.h>
+
+#include <sbkpython.h>
+
+#include <QtCore/QObject>
+
+extern "C"
+{
+ extern PYSIDE_API PyTypeObject *PySideMetaFunction_TypeF(void);
+
+ struct PySideMetaFunctionPrivate;
+ struct PYSIDE_API PySideMetaFunction
+ {
+ PyObject_HEAD
+ PySideMetaFunctionPrivate *d;
+ };
+}; //extern "C"
+
+namespace PySide::MetaFunction {
+
+/**
+ * This function creates a MetaFunction object
+ *
+ * @param obj the QObject witch this fuction is part of
+ * @param methodIndex The index of this function on MetaObject
+ * @return Return a new reference of PySideMetaFunction
+ **/
+PYSIDE_API PySideMetaFunction *newObject(QObject *obj, int methodIndex);
+
+} //namespace PySide::MetaFunction
+
+#endif
diff --git a/sources/pyside6/libpyside/pysidemetafunction_p.h b/sources/pyside6/libpyside/pysidemetafunction_p.h
new file mode 100644
index 000000000..0207ec3a2
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidemetafunction_p.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_METAFUNCTION_P_H
+#define PYSIDE_METAFUNCTION_P_H
+
+#include <sbkpython.h>
+
+#include <QtCore/qtconfigmacros.h>
+
+QT_BEGIN_NAMESPACE
+class QObject;
+QT_END_NAMESPACE
+
+namespace PySide::MetaFunction {
+
+ void init(PyObject *module);
+ /**
+ * Does a Qt metacall on a QObject
+ */
+ bool call(QObject *self, int methodIndex, PyObject *args, PyObject **retVal = nullptr);
+
+} //namespace PySide::MetaFunction
+
+#endif
diff --git a/sources/pyside6/libpyside/pysidemetatype.h b/sources/pyside6/libpyside/pysidemetatype.h
new file mode 100644
index 000000000..85e70f7c9
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidemetatype.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEMETATYPE_H
+#define PYSIDEMETATYPE_H
+
+#include <sbkpython.h>
+
+#include <pysidemacros.h>
+
+#include <QtCore/qtconfigmacros.h>
+
+QT_FORWARD_DECLARE_CLASS(QMetaType)
+
+namespace PySide
+{
+
+/// Returns the QMetaType matching a PyTypeObject
+/// \param
+/// \param type TypeObject
+/// \return QMetaType
+PYSIDE_API QMetaType qMetaTypeFromPyType(PyTypeObject *type);
+
+} //namespace PySide
+
+#endif // PYSIDEMETATYPE_H
diff --git a/sources/pyside6/libpyside/pysideproperty.cpp b/sources/pyside6/libpyside/pysideproperty.cpp
new file mode 100644
index 000000000..3720815db
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideproperty.cpp
@@ -0,0 +1,600 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <sbkpython.h>
+#include "pysideproperty.h"
+#include "pysideproperty_p.h"
+#include "pysidesignal.h"
+#include "pysidesignal_p.h"
+
+#include <shiboken.h>
+#include <pep384ext.h>
+#include <signature.h>
+
+using namespace Shiboken;
+
+extern "C"
+{
+
+static PyObject *qpropertyTpNew(PyTypeObject *subtype, PyObject *args, PyObject *kwds);
+static int qpropertyTpInit(PyObject *, PyObject *, PyObject *);
+static void qpropertyDeAlloc(PyObject *self);
+
+//methods
+static PyObject *qPropertyGetter(PyObject *, PyObject *);
+static PyObject *qPropertySetter(PyObject *, PyObject *);
+static PyObject *qPropertyResetter(PyObject *, PyObject *);
+static PyObject *qPropertyDeleter(PyObject *, PyObject *);
+static PyObject *qPropertyCall(PyObject *, PyObject *, PyObject *);
+static int qpropertyTraverse(PyObject *self, visitproc visit, void *arg);
+static int qpropertyClear(PyObject *self);
+
+// Attributes
+static PyObject *qPropertyDocGet(PyObject *, void *);
+static int qPropertyDocSet(PyObject *, PyObject *, void *);
+static PyObject *qProperty_fget(PyObject *, void *);
+static PyObject *qProperty_fset(PyObject *, void *);
+static PyObject *qProperty_freset(PyObject *, void *);
+static PyObject *qProperty_fdel(PyObject *, void *);
+
+static PyMethodDef PySidePropertyMethods[] = {
+ {"getter", reinterpret_cast<PyCFunction>(qPropertyGetter), METH_O, nullptr},
+ {"setter", reinterpret_cast<PyCFunction>(qPropertySetter), METH_O, nullptr},
+ {"resetter", reinterpret_cast<PyCFunction>(qPropertyResetter), METH_O, nullptr},
+ {"deleter", reinterpret_cast<PyCFunction>(qPropertyDeleter), METH_O, nullptr},
+ // Synonyms from Qt
+ {"read", reinterpret_cast<PyCFunction>(qPropertyGetter), METH_O, nullptr},
+ {"write", reinterpret_cast<PyCFunction>(qPropertySetter), METH_O, nullptr},
+ {nullptr, nullptr, 0, nullptr}
+};
+
+static PyGetSetDef PySidePropertyType_getset[] = {
+ // Note: we could not use `PyMemberDef` like Python's properties,
+ // because of the indirection of PySidePropertyPrivate.
+ {const_cast<char *>("fget"), qProperty_fget, nullptr, nullptr, nullptr},
+ {const_cast<char *>("fset"), qProperty_fset, nullptr, nullptr, nullptr},
+ {const_cast<char *>("freset"), qProperty_freset, nullptr, nullptr, nullptr},
+ {const_cast<char *>("fdel"), qProperty_fdel, nullptr, nullptr, nullptr},
+ {const_cast<char *>("__doc__"), qPropertyDocGet, qPropertyDocSet, nullptr, nullptr},
+ {nullptr, nullptr, nullptr, nullptr, nullptr}
+};
+
+static PyTypeObject *createPropertyType()
+{
+ PyType_Slot PySidePropertyType_slots[] = {
+ {Py_tp_dealloc, reinterpret_cast<void *>(qpropertyDeAlloc)},
+ {Py_tp_call, reinterpret_cast<void *>(qPropertyCall)},
+ {Py_tp_traverse, reinterpret_cast<void *>(qpropertyTraverse)},
+ {Py_tp_clear, reinterpret_cast<void *>(qpropertyClear)},
+ {Py_tp_methods, reinterpret_cast<void *>(PySidePropertyMethods)},
+ {Py_tp_init, reinterpret_cast<void *>(qpropertyTpInit)},
+ {Py_tp_new, reinterpret_cast<void *>(qpropertyTpNew)},
+ {Py_tp_getset, PySidePropertyType_getset},
+ {Py_tp_del, reinterpret_cast<void *>(PyObject_GC_Del)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PySidePropertyType_spec = {
+ "2:PySide6.QtCore.Property",
+ sizeof(PySideProperty),
+ 0,
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_BASETYPE,
+ PySidePropertyType_slots,
+ };
+
+ return SbkType_FromSpec(&PySidePropertyType_spec);
+}
+
+PyTypeObject *PySideProperty_TypeF(void)
+{
+ static auto *type = createPropertyType();
+ return type;
+}
+
+PySidePropertyPrivate::PySidePropertyPrivate() noexcept = default;
+PySidePropertyPrivate::~PySidePropertyPrivate() = default;
+
+PyObject *PySidePropertyPrivate::getValue(PyObject *source)
+{
+ if (fget) {
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ Py_INCREF(source);
+ PyTuple_SET_ITEM(args, 0, source);
+ return PyObject_CallObject(fget, args);
+ }
+ return nullptr;
+}
+
+int PySidePropertyPrivate::setValue(PyObject *source, PyObject *value)
+{
+ if (fset && value) {
+ Shiboken::AutoDecRef args(PyTuple_New(2));
+ PyTuple_SET_ITEM(args, 0, source);
+ PyTuple_SET_ITEM(args, 1, value);
+ Py_INCREF(source);
+ Py_INCREF(value);
+ Shiboken::AutoDecRef result(PyObject_CallObject(fset, args));
+ return (result.isNull() ? -1 : 0);
+ }
+ if (fdel) {
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTuple_SET_ITEM(args, 0, source);
+ Py_INCREF(source);
+ Shiboken::AutoDecRef result(PyObject_CallObject(fdel, args));
+ return (result.isNull() ? -1 : 0);
+ }
+ PyErr_SetString(PyExc_AttributeError, "Attribute is read only");
+ return -1;
+}
+
+int PySidePropertyPrivate::reset(PyObject *source)
+{
+ if (freset) {
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ Py_INCREF(source);
+ PyTuple_SET_ITEM(args, 0, source);
+ Shiboken::AutoDecRef result(PyObject_CallObject(freset, args));
+ return (result.isNull() ? -1 : 0);
+ }
+ return -1;
+}
+
+void PySidePropertyPrivate::metaCall(PyObject *source, QMetaObject::Call call, void **args)
+{
+ switch (call) {
+ case QMetaObject::ReadProperty: {
+ AutoDecRef value(getValue(source));
+ auto *obValue = value.object();
+ if (obValue) {
+ Conversions::SpecificConverter converter(typeName);
+ if (converter) {
+ converter.toCpp(obValue, args[0]);
+ } else {
+ // PYSIDE-2160: Report an unknown type name to the caller `qtPropertyMetacall`.
+ PyErr_SetObject(PyExc_StopIteration, obValue);
+ }
+ }
+ }
+ break;
+
+ case QMetaObject::WriteProperty: {
+ Conversions::SpecificConverter converter(typeName);
+ if (converter) {
+ AutoDecRef value(converter.toPython(args[0]));
+ setValue(source, value);
+ } else {
+ // PYSIDE-2160: Report an unknown type name to the caller `qtPropertyMetacall`.
+ PyErr_SetNone(PyExc_StopIteration);
+ }
+ }
+ break;
+
+ case QMetaObject::ResetProperty:
+ reset(source);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static PyObject *qpropertyTpNew(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */)
+{
+ auto *me = PepExt_TypeCallAlloc<PySideProperty>(subtype, 0);
+ me->d = new PySidePropertyPrivate;
+ return reinterpret_cast<PyObject *>(me);
+}
+
+static int qpropertyTpInit(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *type{};
+ auto data = reinterpret_cast<PySideProperty *>(self);
+ PySidePropertyPrivate *pData = data->d;
+
+ static const char *kwlist[] = {"type", "fget", "fset", "freset", "fdel", "doc", "notify",
+ "designable", "scriptable", "stored",
+ "user", "constant", "final", nullptr};
+ char *doc{};
+
+ Py_CLEAR(pData->pyTypeObject);
+ Py_CLEAR(pData->fget);
+ Py_CLEAR(pData->fset);
+ Py_CLEAR(pData->freset);
+ Py_CLEAR(pData->fdel);
+ Py_CLEAR(pData->notify);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds,
+ "O|OOOOsObbbbbb:QtCore.Property",
+ const_cast<char **>(kwlist),
+ /*OO*/ &type, &(pData->fget),
+ /*OOO*/ &(pData->fset), &(pData->freset), &(pData->fdel),
+ /*s*/ &doc,
+ /*O*/ &(pData->notify),
+ /*bbb*/ &(pData->designable), &(pData->scriptable), &(pData->stored),
+ /*bbb*/ &(pData->user), &(pData->constant), &(pData->final))) {
+ return -1;
+ }
+
+ // PYSIDE-1019: Fetching the default `__doc__` from fget would fail for inherited functions
+ // because we don't initialize the mro with signatures (and we will not!).
+ // But it is efficient and in-time to do that on demand in qPropertyDocGet.
+ pData->getter_doc = false;
+ if (doc)
+ pData->doc = doc;
+ else
+ pData->doc.clear();
+
+ pData->pyTypeObject = type;
+ Py_XINCREF(pData->pyTypeObject);
+ pData->typeName = PySide::Signal::getTypeName(type);
+
+ if (pData->typeName.isEmpty())
+ PyErr_SetString(PyExc_TypeError, "Invalid property type or type name.");
+ else if (pData->constant && ((pData->fset && pData->fset != Py_None)
+ || (pData->notify && pData->notify != Py_None)))
+ PyErr_SetString(PyExc_TypeError, "A constant property cannot have a WRITE method or a "
+ "NOTIFY signal.");
+ if (!PyErr_Occurred()) {
+ Py_XINCREF(pData->fget);
+ Py_XINCREF(pData->fset);
+ Py_XINCREF(pData->freset);
+ Py_XINCREF(pData->fdel);
+ Py_XINCREF(pData->notify);
+ return 0;
+ }
+ pData->fget = nullptr;
+ pData->fset = nullptr;
+ pData->freset = nullptr;
+ pData->fdel = nullptr;
+ pData->notify = nullptr;
+ return -1;
+}
+
+static void qpropertyDeAlloc(PyObject *self)
+{
+ qpropertyClear(self);
+ if (PepRuntime_38_flag) {
+ // PYSIDE-939: Handling references correctly.
+ // This was not needed before Python 3.8 (Python issue 35810)
+ Py_DECREF(Py_TYPE(self));
+ }
+ PyObject_GC_UnTrack(self);
+ PepExt_TypeCallFree(self);
+}
+
+// Create a copy of the property to prevent the @property.setter from modifying
+// the property in place and avoid strange side effects in derived classes
+// (cf https://bugs.python.org/issue1620).
+static PyObject *
+_property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *reset, PyObject *del)
+{
+ auto *pold = reinterpret_cast<PySideProperty *>(old);
+ PySidePropertyPrivate *pData = pold->d;
+
+ AutoDecRef type(PyObject_Type(old));
+ QByteArray doc{};
+ if (type.isNull())
+ return nullptr;
+
+ if (get == nullptr || get == Py_None) {
+ Py_XDECREF(get);
+ get = pData->fget ? pData->fget : Py_None;
+ }
+ if (set == nullptr || set == Py_None) {
+ Py_XDECREF(set);
+ set = pData->fset ? pData->fset : Py_None;
+ }
+ if (reset == nullptr || reset == Py_None) {
+ Py_XDECREF(reset);
+ reset = pData->freset ? pData->freset : Py_None;
+ }
+ if (del == nullptr || del == Py_None) {
+ Py_XDECREF(del);
+ del = pData->fdel ? pData->fdel : Py_None;
+ }
+ // make _init use __doc__ from getter
+ if ((pData->getter_doc && get != Py_None) || pData->doc.isEmpty())
+ doc.clear();
+ else
+ doc = pData->doc;
+
+ auto notify = pData->notify ? pData->notify : Py_None;
+
+ PyObject *obNew = PyObject_CallFunction(type, const_cast<char *>("OOOOOsO" "bbb" "bbb"),
+ pData->pyTypeObject, get, set, reset, del, doc.data(), notify,
+ pData->designable, pData->scriptable, pData->stored,
+ pData->user, pData->constant, pData->final);
+
+ return obNew;
+}
+
+static PyObject *qPropertyGetter(PyObject *self, PyObject *getter)
+{
+ return _property_copy(self, getter, nullptr, nullptr, nullptr);
+}
+
+static PyObject *qPropertySetter(PyObject *self, PyObject *setter)
+{
+ return _property_copy(self, nullptr, setter, nullptr, nullptr);
+}
+
+static PyObject *qPropertyResetter(PyObject *self, PyObject *resetter)
+{
+ return _property_copy(self, nullptr, nullptr, resetter, nullptr);
+}
+
+static PyObject *qPropertyDeleter(PyObject *self, PyObject *deleter)
+{
+ return _property_copy(self, nullptr, nullptr, nullptr, deleter);
+}
+
+static PyObject *qPropertyCall(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PyObject *getter = PyTuple_GetItem(args, 0);
+ return _property_copy(self, getter, nullptr, nullptr, nullptr);
+}
+
+// PYSIDE-1019: Provide the same getters as Pythons `PyProperty`.
+
+static PyObject *qProperty_fget(PyObject *self, void *)
+{
+ auto func = reinterpret_cast<PySideProperty *>(self)->d->fget;
+ auto ret = func != nullptr ? func : Py_None;
+ Py_INCREF(ret);
+ return ret;
+}
+
+static PyObject *qProperty_fset(PyObject *self, void *)
+{
+ auto func = reinterpret_cast<PySideProperty *>(self)->d->fset;
+ auto ret = func != nullptr ? func : Py_None;
+ Py_INCREF(ret);
+ return ret;
+}
+
+static PyObject *qProperty_freset(PyObject *self, void *)
+{
+ auto func = reinterpret_cast<PySideProperty *>(self)->d->freset;
+ auto ret = func != nullptr ? func : Py_None;
+ Py_INCREF(ret);
+ return ret;
+}
+
+static PyObject *qProperty_fdel(PyObject *self, void *)
+{
+ auto func = reinterpret_cast<PySideProperty *>(self)->d->fdel;
+ auto ret = func != nullptr ? func : Py_None;
+ Py_INCREF(ret);
+ return ret;
+}
+
+static PyObject *qPropertyDocGet(PyObject *self, void *)
+{
+ auto data = reinterpret_cast<PySideProperty *>(self);
+ PySidePropertyPrivate *pData = data->d;
+
+ QByteArray doc(pData->doc);
+ if (!doc.isEmpty())
+ return PyUnicode_FromString(doc);
+ if (pData->fget != nullptr) {
+ // PYSIDE-1019: Fetch the default `__doc__` from fget. We do it late.
+ AutoDecRef get_doc(PyObject_GetAttr(pData->fget, PyMagicName::doc()));
+ if (!get_doc.isNull() && get_doc.object() != Py_None) {
+ pData->doc = String::toCString(get_doc);
+ pData->getter_doc = true;
+ if (Py_TYPE(self) == PySideProperty_TypeF())
+ return qPropertyDocGet(self, nullptr);
+ /*
+ * If this is a property subclass, put __doc__ in dict of the
+ * subclass instance instead, otherwise it gets shadowed by
+ * __doc__ in the class's dict.
+ */
+ auto get_doc_obj = get_doc.object();
+ int err = PyObject_SetAttr(self, PyMagicName::doc(), get_doc);
+ return err < 0 ? nullptr : (Py_INCREF(get_doc_obj), get_doc_obj);
+ }
+ PyErr_Clear();
+ }
+ Py_RETURN_NONE;
+}
+
+static int qPropertyDocSet(PyObject *self, PyObject *value, void *)
+{
+ auto data = reinterpret_cast<PySideProperty *>(self);
+ PySidePropertyPrivate *pData = data->d;
+
+ if (String::check(value)) {
+ pData->doc = String::toCString(value);
+ return 0;
+ }
+ PyErr_SetString(PyExc_TypeError, "String argument expected.");
+ return -1;
+}
+
+static int qpropertyTraverse(PyObject *self, visitproc visit, void *arg)
+{
+ PySidePropertyPrivate *data = reinterpret_cast<PySideProperty *>(self)->d;
+ if (!data)
+ return 0;
+
+ Py_VISIT(data->fget);
+ Py_VISIT(data->fset);
+ Py_VISIT(data->freset);
+ Py_VISIT(data->fdel);
+ Py_VISIT(data->notify);
+ Py_VISIT(data->pyTypeObject);
+ return 0;
+}
+
+static int qpropertyClear(PyObject *self)
+{
+ PySidePropertyPrivate *data = reinterpret_cast<PySideProperty *>(self)->d;
+ if (!data)
+ return 0;
+
+ Py_CLEAR(data->fget);
+ Py_CLEAR(data->fset);
+ Py_CLEAR(data->freset);
+ Py_CLEAR(data->fdel);
+ Py_CLEAR(data->notify);
+ Py_CLEAR(data->pyTypeObject);
+
+ delete data;
+ reinterpret_cast<PySideProperty *>(self)->d = nullptr;
+ return 0;
+}
+
+} // extern "C"
+
+static PyObject *getFromType(PyTypeObject *type, PyObject *name)
+{
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *attr = PyDict_GetItem(tpDict.object(), name);
+ if (!attr) {
+ PyObject *bases = type->tp_bases;
+ const Py_ssize_t size = PyTuple_GET_SIZE(bases);
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ PyObject *base = PyTuple_GET_ITEM(bases, i);
+ attr = getFromType(reinterpret_cast<PyTypeObject *>(base), name);
+ if (attr)
+ return attr;
+ }
+ }
+ return attr;
+}
+
+namespace PySide::Property {
+
+static const char *Property_SignatureStrings[] = {
+ "PySide6.QtCore.Property(self,type:type,fget:typing.Callable=None,fset:typing.Callable=None,"
+ "freset:typing.Callable=None,fdel:typing.Callable=None,doc:str=None,"
+ "notify:typing.Callable=None,designable:bool=True,scriptable:bool=True,"
+ "stored:bool=True,user:bool=False,constant:bool=False,final:bool=False)",
+ "PySide6.QtCore.Property.deleter(self,fdel:typing.Callable)->PySide6.QtCore.Property",
+ "PySide6.QtCore.Property.getter(self,fget:typing.Callable)->PySide6.QtCore.Property",
+ "PySide6.QtCore.Property.read(self,fget:typing.Callable)->PySide6.QtCore.Property",
+ "PySide6.QtCore.Property.setter(self,fset:typing.Callable)->PySide6.QtCore.Property",
+ "PySide6.QtCore.Property.write(self,fset:typing.Callable)->PySide6.QtCore.Property",
+ "PySide6.QtCore.Property.__call__(self, func:typing.Callable)->PySide6.QtCore.Property",
+ nullptr}; // Sentinel
+
+void init(PyObject *module)
+{
+ if (InitSignatureStrings(PySideProperty_TypeF(), Property_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideProperty_TypeF());
+ PyModule_AddObject(module, "Property", reinterpret_cast<PyObject *>(PySideProperty_TypeF()));
+}
+
+bool checkType(PyObject *pyObj)
+{
+ if (pyObj) {
+ return PyType_IsSubtype(Py_TYPE(pyObj), PySideProperty_TypeF());
+ }
+ return false;
+}
+
+PyObject *getValue(PySideProperty *self, PyObject *source)
+{
+ return self->d->getValue(source);
+}
+
+int setValue(PySideProperty *self, PyObject *source, PyObject *value)
+{
+ return self->d->setValue(source, value);
+}
+
+int reset(PySideProperty *self, PyObject *source)
+{
+ return self->d->reset(source);
+}
+
+const char *getTypeName(const PySideProperty *self)
+{
+ return self->d->typeName;
+}
+
+PySideProperty *getObject(PyObject *source, PyObject *name)
+{
+ PyObject *attr = nullptr;
+
+ attr = getFromType(Py_TYPE(source), name);
+ if (attr && checkType(attr)) {
+ Py_INCREF(attr);
+ return reinterpret_cast<PySideProperty *>(attr);
+ }
+
+ if (!attr)
+ PyErr_Clear(); //Clear possible error caused by PyObject_GenericGetAttr
+
+ return nullptr;
+}
+
+bool isReadable(const PySideProperty * /* self */)
+{
+ return true;
+}
+
+bool isWritable(const PySideProperty *self)
+{
+ return self->d->fset != nullptr;
+}
+
+bool hasReset(const PySideProperty *self)
+{
+ return self->d->freset != nullptr;
+}
+
+bool isDesignable(const PySideProperty *self)
+{
+ return self->d->designable;
+}
+
+bool isScriptable(const PySideProperty *self)
+{
+ return self->d->scriptable;
+}
+
+bool isStored(const PySideProperty *self)
+{
+ return self->d->stored;
+}
+
+bool isUser(const PySideProperty *self)
+{
+ return self->d->user;
+}
+
+bool isConstant(const PySideProperty *self)
+{
+ return self->d->constant;
+}
+
+bool isFinal(const PySideProperty *self)
+{
+ return self->d->final;
+}
+
+const char *getNotifyName(PySideProperty *self)
+{
+ if (self->d->notifySignature.isEmpty()) {
+ AutoDecRef str(PyObject_Str(self->d->notify));
+ self->d->notifySignature = Shiboken::String::toCString(str);
+ }
+
+ return self->d->notifySignature.isEmpty()
+ ? nullptr : self->d->notifySignature.constData();
+}
+
+void setTypeName(PySideProperty *self, const char *typeName)
+{
+ self->d->typeName = typeName;
+}
+
+PyObject *getTypeObject(const PySideProperty *self)
+{
+ return self->d->pyTypeObject;
+}
+
+} //namespace PySide::Property
diff --git a/sources/pyside6/libpyside/pysideproperty.h b/sources/pyside6/libpyside/pysideproperty.h
new file mode 100644
index 000000000..a572efe45
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideproperty.h
@@ -0,0 +1,73 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_PROPERTY_H
+#define PYSIDE_PROPERTY_H
+
+#include <pysidemacros.h>
+
+#include <sbkpython.h>
+
+#include <QtCore/QMetaObject>
+
+class PySidePropertyPrivate;
+
+extern "C"
+{
+ extern PYSIDE_API PyTypeObject *PySideProperty_TypeF(void);
+
+ struct PYSIDE_API PySideProperty
+ {
+ PyObject_HEAD
+ PySidePropertyPrivate* d;
+ };
+};
+
+namespace PySide::Property {
+
+PYSIDE_API bool checkType(PyObject *pyObj);
+
+/**
+ * This function call set property function and pass value as arg
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @param source The QObject witch has the property
+ * @param value The value to set in property
+ * @return Return 0 if ok or -1 if this function fail
+ **/
+PYSIDE_API int setValue(PySideProperty *self, PyObject *source, PyObject *value);
+
+/**
+ * This function call get property function
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @param source The QObject witch has the property
+ * @return Return the result of property get function or 0 if this fail
+ **/
+PYSIDE_API PyObject *getValue(PySideProperty *self, PyObject *source);
+
+/**
+ * This function return the notify name used on this property
+ *
+ * @param self The property object
+ * @return Return a const char with the notify name used
+ **/
+PYSIDE_API const char *getNotifyName(PySideProperty *self);
+
+
+/**
+ * This function search in the source object for desired property
+ *
+ * @param source The QObject object
+ * @param name The property name
+ * @return Return a new reference to property object
+ **/
+PYSIDE_API PySideProperty *getObject(PyObject *source, PyObject *name);
+
+PYSIDE_API void setTypeName(PySideProperty *self, const char *typeName);
+
+} //namespace PySide::Property
+
+#endif
diff --git a/sources/pyside6/libpyside/pysideproperty_p.h b/sources/pyside6/libpyside/pysideproperty_p.h
new file mode 100644
index 000000000..10cb3ce87
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideproperty_p.h
@@ -0,0 +1,169 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_QPROPERTY_P_H
+#define PYSIDE_QPROPERTY_P_H
+
+#include <sbkpython.h>
+
+#include "pysideproperty.h"
+#include <pysidemacros.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/qtclasshelpermacros.h>
+#include <QtCore/QMetaObject>
+
+struct PySideProperty;
+
+class PYSIDE_API PySidePropertyPrivate
+{
+public:
+
+ Q_DISABLE_COPY_MOVE(PySidePropertyPrivate)
+
+ PySidePropertyPrivate() noexcept;
+ virtual ~PySidePropertyPrivate();
+
+ virtual void metaCall(PyObject *source, QMetaObject::Call call, void **args);
+
+ PyObject *getValue(PyObject *source);
+ int setValue(PyObject *source, PyObject *value);
+ int reset(PyObject *source);
+
+ QByteArray typeName;
+ // Type object: A real PyTypeObject ("@Property(int)") or a string
+ // "@Property('QVariant')".
+ PyObject *pyTypeObject = nullptr;
+ PyObject *fget = nullptr;
+ PyObject *fset = nullptr;
+ PyObject *freset = nullptr;
+ PyObject *fdel = nullptr;
+ PyObject *notify = nullptr;
+ bool getter_doc = false;
+ QByteArray notifySignature;
+ QByteArray doc;
+ bool designable = true;
+ bool scriptable = true;
+ bool stored = true;
+ bool user = false;
+ bool constant = false;
+ bool final = false;
+};
+
+namespace PySide::Property {
+
+/**
+ * Init PySide QProperty support system
+ */
+void init(PyObject* module);
+
+/**
+ * This function call reset property function
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @param source The QObject witch has the property
+ * @return Return 0 if ok or -1 if this function fail
+ **/
+int reset(PySideProperty* self, PyObject* source);
+
+
+/**
+ * This function return the property type
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return the property type name
+ **/
+const char* getTypeName(const PySideProperty* self);
+
+/**
+ * This function check if property has read function
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isReadable(const PySideProperty* self);
+
+/**
+ * This function check if property has write function
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isWritable(const PySideProperty* self);
+
+/**
+ * This function check if property has reset function
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool hasReset(const PySideProperty* self);
+
+/**
+ * This function check if property has the flag DESIGNABLE setted
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isDesignable(const PySideProperty* self);
+
+/**
+ * This function check if property has the flag SCRIPTABLE setted
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isScriptable(const PySideProperty* self);
+
+/**
+ * This function check if property has the flag STORED setted
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isStored(const PySideProperty* self);
+
+/**
+ * This function check if property has the flag USER setted
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isUser(const PySideProperty* self);
+
+/**
+ * This function check if property has the flag CONSTANT setted
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isConstant(const PySideProperty* self);
+
+/**
+ * This function check if property has the flag FINAL setted
+ * This function does not check the property object type
+ *
+ * @param self The property object
+ * @return Return a boolean value
+ **/
+bool isFinal(const PySideProperty* self);
+
+/// This function returns the type object of the property. It is either a real
+/// PyTypeObject ("@Property(int)") or a string "@Property('QVariant')".
+/// @param self The property object
+/// @return type object
+PyObject *getTypeObject(const PySideProperty* self);
+
+} // namespace PySide::Property
+
+#endif
diff --git a/sources/pyside6/libpyside/pysideqapp.h b/sources/pyside6/libpyside/pysideqapp.h
new file mode 100644
index 000000000..5543d83d8
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqapp.h
@@ -0,0 +1,19 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQAPP_H
+#define PYSIDEQAPP_H
+
+#include <pysidemacros.h>
+
+namespace PySide
+{
+
+PYSIDE_API void initQApp();
+
+/// Destroy a QCoreApplication taking care of destroy all instances of QObject first.
+PYSIDE_API void destroyQCoreApplication();
+
+} //namespace PySide
+
+#endif // PYSIDEQPP_H
diff --git a/sources/pyside6/libpyside/pysideqenum.cpp b/sources/pyside6/libpyside/pysideqenum.cpp
new file mode 100644
index 000000000..c0479160f
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqenum.cpp
@@ -0,0 +1,197 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <shiboken.h>
+
+#include "pysideqenum.h"
+#include "dynamicqmetaobject.h"
+#include "pyside_p.h"
+
+
+///////////////////////////////////////////////////////////////
+//
+// PYSIDE-957: Create QEnum dynamically from Python Enum
+//
+//
+extern "C" {
+
+using namespace Shiboken;
+
+static PyObject *analyzePyEnum(PyObject *pyenum)
+{
+ /*
+ * This is the straight-forward implementation of QEnum/QFlag. It does no
+ * longer create an equivalent Qt enum but takes the Python enum as-is.
+ *
+ * It parses an Enum/Flag derived Python enum completely so that
+ * registering can be done without error checks. This would be impossible
+ * in MetaObjectBuilderPrivate::parsePythonType.
+ */
+ AutoDecRef members(PyObject_GetAttr(pyenum, Shiboken::PyMagicName::members()));
+ if (members.isNull())
+ return nullptr;
+ AutoDecRef items(PyMapping_Items(members));
+ if (items.isNull())
+ return nullptr;
+ int iflag = PySide::QEnum::isFlag(pyenum);
+ if (iflag < 0)
+ return nullptr;
+ Py_ssize_t nr_items = PySequence_Length(items);
+ if (nr_items < 0)
+ return nullptr;
+
+ for (Py_ssize_t idx = 0; idx < nr_items; ++idx) {
+ AutoDecRef item(PySequence_GetItem(items, idx));
+ if (item.isNull())
+ return nullptr;
+
+ // The item should be a 2-element sequence of the key name and an
+ // object containing the value.
+ AutoDecRef key(PySequence_GetItem(item, 0));
+ AutoDecRef member(PySequence_GetItem(item, 1));
+ if (key.isNull() || member.isNull())
+ return nullptr;
+ if (!Shiboken::String::check(key)) {
+ // '%.200s' is the safety stringbuffer size of most CPython functions.
+ PyErr_Format(PyExc_TypeError,
+ "QEnum expected a string mapping as __members__, got '%.200s'",
+ Py_TYPE(key)->tp_name);
+ return nullptr;
+ }
+
+ // Get the value.
+ AutoDecRef value(PyObject_GetAttr(member, Shiboken::PyName::value()));
+ if (value.isNull())
+ return nullptr;
+ if (!PyLong_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "QEnum expected an int value as '%.200s', got '%.200s'",
+ Shiboken::String::toCString(key), Py_TYPE(value)->tp_name);
+ return nullptr;
+ }
+ }
+ Py_RETURN_NONE;
+}
+
+static Py_ssize_t get_lineno()
+{
+ PyObject *frame = reinterpret_cast<PyObject *>(PyEval_GetFrame()); // borrowed ref
+ AutoDecRef ob_lineno(PyObject_GetAttr(frame, Shiboken::PyName::f_lineno()));
+ if (ob_lineno.isNull() || !PyLong_Check(ob_lineno))
+ return -1;
+ return PyLong_AsSsize_t(ob_lineno);
+}
+
+static bool is_module_code()
+{
+ PyObject *frame = reinterpret_cast<PyObject *>(PyEval_GetFrame()); // borrowed ref
+ AutoDecRef ob_code(PyObject_GetAttr(frame, Shiboken::PyName::f_code()));
+ if (ob_code.isNull())
+ return false;
+ AutoDecRef ob_name(PyObject_GetAttr(ob_code, Shiboken::PyName::co_name()));
+ if (ob_name.isNull())
+ return false;
+ const char *codename = Shiboken::String::toCString(ob_name);
+ return strcmp(codename, "<module>") == 0;
+}
+
+} // extern "C"
+
+namespace PySide::QEnum {
+
+static std::map<int, PyObject *> enumCollector;
+
+int isFlag(PyObject *obType)
+{
+ /*
+ * Find out if this is an Enum or a Flag derived class.
+ * It checks also if things come from the enum module and if it is
+ * an Enum or Flag class at all.
+ *
+ * The function is called in MetaObjectBuilderPrivate::parsePythonType
+ * again to obtain the flag value.
+ */
+ int res = enumIsFlag(obType);
+ if (res < 0) {
+ auto *type = reinterpret_cast<PyTypeObject *>(obType);
+ PyErr_Format(PyExc_TypeError, "type %.200s does not inherit from 'Enum' or 'Flag'",
+ type->tp_name);
+ return -1;
+ }
+ return bool(res);
+}
+
+PyObject *QEnumMacro(PyObject *pyenum, bool flag)
+{
+ /*
+ * This is the official interface of 'QEnum'. It first calls 'analyzePyEnum'.
+ * When called as toplevel enum, it simply returns after some checks.
+ * Otherwise, 'pyenum' is stored for later use by the meta class registation.
+ */
+ int computedFlag = isFlag(pyenum);
+ if (computedFlag < 0)
+ return nullptr;
+ if (bool(computedFlag) != flag) {
+ AutoDecRef name(PyObject_GetAttr(pyenum, PyMagicName::qualname()));
+ auto cname = String::toCString(name);
+ const char *e = "Enum";
+ const char *f = "Flag";
+ PyErr_Format(PyExc_TypeError, "expected '%s' but got '%s' (%.200s)",
+ flag ? f : e, flag ? e : f, cname);
+ return nullptr;
+ }
+ auto ok = analyzePyEnum(pyenum);
+ if (ok == nullptr)
+ return nullptr;
+ if (is_module_code()) {
+ // This is a toplevel enum which we resolve immediately.
+ Py_INCREF(pyenum);
+ return pyenum;
+ }
+
+ Py_ssize_t lineno = get_lineno();
+ if (lineno < 0)
+ return nullptr;
+ // Handle the rest via line number and the meta class.
+ Py_INCREF(pyenum);
+ Py_XDECREF(enumCollector[lineno]);
+ enumCollector[lineno] = pyenum;
+ Py_RETURN_NONE;
+}
+
+std::vector<PyObject *> resolveDelayedQEnums(PyTypeObject *containerType)
+{
+ /*
+ * This is the internal interface of 'QEnum'.
+ * It is called at the end of the meta class call 'SbkObjectType_tp_new' via
+ * MetaObjectBuilderPrivate::parsePythonType and resolves the collected
+ * Python Enum arguments. The result is then registered.
+ */
+ if (enumCollector.empty())
+ return {};
+ PyObject *obContainerType = reinterpret_cast<PyObject *>(containerType);
+ Py_ssize_t lineno = get_lineno();
+
+ std::vector<PyObject *> result;
+
+ auto it = enumCollector.begin();
+ while (it != enumCollector.end()) {
+ int nr = it->first;
+ PyObject *pyenum = it->second;
+ if (nr >= lineno) {
+ AutoDecRef name(PyObject_GetAttr(pyenum, PyMagicName::name()));
+ if (name.isNull() || PyObject_SetAttr(obContainerType, name, pyenum) < 0)
+ return {};
+ result.push_back(pyenum);
+ it = enumCollector.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ return result;
+}
+
+} // namespace Shiboken::Enum
+
+//
+///////////////////////////////////////////////////////////////
diff --git a/sources/pyside6/libpyside/pysideqenum.h b/sources/pyside6/libpyside/pysideqenum.h
new file mode 100644
index 000000000..c3483e63e
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqenum.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_QENUM_H
+#define PYSIDE_QENUM_H
+
+#include <pysidemacros.h>
+#include <vector>
+
+namespace PySide::QEnum {
+
+// PYSIDE-957: Support the QEnum macro
+PYSIDE_API PyObject *QEnumMacro(PyObject *, bool);
+PYSIDE_API int isFlag(PyObject *);
+PYSIDE_API std::vector<PyObject *> resolveDelayedQEnums(PyTypeObject *);
+PYSIDE_API void init();
+
+} // namespace PySide::QEnum
+
+#endif
diff --git a/sources/pyside6/libpyside/pysideqhash.h b/sources/pyside6/libpyside/pysideqhash.h
new file mode 100644
index 000000000..ae2d295f6
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqhash.h
@@ -0,0 +1,24 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQHASH_H
+#define PYSIDEQHASH_H
+
+#include <sbkpython.h>
+
+#include <QtCore/QHash>
+
+namespace PySide
+{
+
+/// Hash function used to enable hash on objects not supported by the native Qt
+/// library which have a toString() function.
+template<class T>
+[[deprecated]] inline Py_ssize_t hash(const T& value)
+{
+ return qHash(value.toString());
+}
+
+} //namespace PySide
+
+#endif // PYSIDEQHASH_H
diff --git a/sources/pyside6/libpyside/pysideqmetatype.h b/sources/pyside6/libpyside/pysideqmetatype.h
new file mode 100644
index 000000000..3782dc3bb
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqmetatype.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMETATYPE_H
+#define PYSIDEQMETATYPE_H
+
+#include <QtCore/QMetaType>
+
+namespace PySide
+{
+
+/// If the type \p T was registered on Qt meta type system with Q_DECLARE_METATYPE macro,
+/// this class will initialize the meta type.
+///
+/// Initialize a meta type means register it on Qt meta type system, Qt itself only do this
+/// on the first call of qMetaTypeId, and this is exactly what we do to init it. If we don't
+/// do that, calls to QMetaType::type("QMatrix2x2") could return zero, causing QVariant to
+/// not recognize some C++ types, like QMatrix2x2.
+
+template<typename T, bool OK = QMetaTypeId<T>::Defined >
+struct initQtMetaType {
+ initQtMetaType()
+ {
+ qMetaTypeId<T>();
+ }
+};
+
+// Template specialization to do nothing when the type wasn't registered on Qt meta type system.
+template<typename T>
+struct initQtMetaType<T, false> {
+};
+
+} //namespace PySide
+
+#endif // PYSIDEQMETATYPE_H
diff --git a/sources/pyside6/libpyside/pysideqobject.h b/sources/pyside6/libpyside/pysideqobject.h
new file mode 100644
index 000000000..f81c50399
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqobject.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQOBJECT_H
+#define PYSIDEQOBJECT_H
+
+#include <sbkpython.h>
+
+#include <pysidemacros.h>
+
+#include <QtCore/qtclasshelpermacros.h>
+
+#include <cstddef>
+
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_STRUCT(QMetaObject)
+QT_FORWARD_DECLARE_CLASS(QMutex)
+
+namespace PySide
+{
+
+/// Fill QObject properties and do signal connections using the values found in \p kwds dictionary.
+/// \param qObj PyObject fot the QObject.
+/// \param metaObj QMetaObject of \p qObj.
+/// \param kwds key->value dictonary.
+/// \return True if everything goes well, false with a Python error set otherwise.
+PYSIDE_API bool fillQtProperties(PyObject *qObj, const QMetaObject *metaObj,
+ PyObject *kwds, bool allowErrors);
+
+PYSIDE_API void initDynamicMetaObject(PyTypeObject *type, const QMetaObject *base,
+ std::size_t cppObjSize);
+PYSIDE_API void initQObjectSubType(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+/// Return the size in bytes of a type that inherits QObject.
+PYSIDE_API std::size_t getSizeOfQObject(PyTypeObject *type);
+
+/// Check if a PyTypeObject or its bases contains a QObject
+/// \param pyType is the PyTypeObject to check
+/// \param raiseError controls if a TypeError is raised when an object does not
+/// inherit QObject
+PYSIDE_API bool isQObjectDerived(PyTypeObject *pyType, bool raiseError);
+
+/// Convenience to convert a PyObject to QObject
+PYSIDE_API QObject *convertToQObject(PyObject *object, bool raiseError);
+
+/// Check for properties and signals registered on MetaObject and return these.
+/// Also handle Python properties when true_property was selected.
+/// \param cppSelf Is the QObject which contains the metaobject
+/// \param self Python object of cppSelf
+/// \param name Name of the argument which the function will try retrieve from MetaData
+/// \return The Python object which contains the Data obtained in metaObject or the Python
+/// method pulled out of a Python property.
+PYSIDE_API PyObject *getHiddenDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name);
+
+/// Mutex for accessing QObject memory helpers from multiple threads
+PYSIDE_API QMutex &nextQObjectMemoryAddrMutex();
+PYSIDE_API void *nextQObjectMemoryAddr();
+/// Set the address where to allocate the next QObject (for QML)
+PYSIDE_API void setNextQObjectMemoryAddr(void *addr);
+
+PYSIDE_API PyObject *getWrapperForQObject(QObject *cppSelf, PyTypeObject *sbk_type);
+
+/// Return the best-matching type for a QObject (Helper for QObject.findType())
+/// \param cppSelf QObject instance
+/// \return type object
+PYSIDE_API PyTypeObject *getTypeForQObject(const QObject *cppSelf);
+
+} //namespace PySide
+
+#endif // PYSIDEQOBJECT_H
diff --git a/sources/pyside6/libpyside/pysideqslotobject_p.cpp b/sources/pyside6/libpyside/pysideqslotobject_p.cpp
new file mode 100644
index 000000000..914be898a
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqslotobject_p.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqslotobject_p.h"
+
+#include <autodecref.h>
+#include <gilstate.h>
+
+namespace PySide
+{
+
+void PySideQSlotObject::impl(int which, QSlotObjectBase *this_, QObject *receiver,
+ void **args, bool *ret)
+{
+ auto self = static_cast<PySideQSlotObject *>(this_);
+ switch (which) {
+ case Destroy:
+ delete self;
+ break;
+ case Call:
+ {
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(0));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(self->callable, arglist));
+ break;
+ }
+ case Compare:
+ case NumOperations:
+ Q_UNUSED(receiver);
+ Q_UNUSED(args);
+ Q_UNUSED(ret);
+ break;
+ }
+}
+
+} // namespace PySide
diff --git a/sources/pyside6/libpyside/pysideqslotobject_p.h b/sources/pyside6/libpyside/pysideqslotobject_p.h
new file mode 100644
index 000000000..d7d258505
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideqslotobject_p.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQSLOTOBJECT_P_H
+#define PYSIDEQSLOTOBJECT_P_H
+
+#include "pysidemacros.h"
+#include <sbkpython.h>
+
+#include <QtCore/QObject>
+#include <QtCore/qobjectdefs.h>
+
+namespace PySide
+{
+
+class PySideQSlotObject : public QtPrivate::QSlotObjectBase
+{
+ PyObject *callable;
+
+ static void impl(int which, QSlotObjectBase *this_, QObject *receiver, void **args, bool *ret);
+
+public:
+ PySideQSlotObject(PyObject *callable) : QtPrivate::QSlotObjectBase(&impl), callable(callable)
+ {
+ Py_INCREF(callable);
+ }
+
+ ~PySideQSlotObject()
+ {
+ auto gstate = PyGILState_Ensure();
+ Py_DECREF(callable);
+ PyGILState_Release(gstate);
+ }
+};
+
+
+} // namespace PySide
+
+#endif // PYSIDEQSLOTOBJECT_P_H
diff --git a/sources/pyside6/libpyside/pysidesignal.cpp b/sources/pyside6/libpyside/pysidesignal.cpp
new file mode 100644
index 000000000..ed0cc5d0a
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidesignal.cpp
@@ -0,0 +1,1335 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <sbkpython.h>
+#include "pysidesignal.h"
+#include "pysidesignal_p.h"
+#include "pysideqobject.h"
+#include "pysideutils.h"
+#include "pysidestaticstrings.h"
+#include "pysideweakref.h"
+#include "signalmanager.h"
+
+#include <shiboken.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+#include <QtCore/QObject>
+#include <QtCore/QMetaMethod>
+#include <QtCore/QMetaObject>
+#include <pep384ext.h>
+#include <signature.h>
+
+#include <algorithm>
+#include <optional>
+#include <utility>
+#include <cstring>
+
+#define QT_SIGNAL_SENTINEL '2'
+
+using namespace Qt::StringLiterals;
+
+QDebug operator<<(QDebug debug, const PySideSignalData::Signature &s)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Signature(\"" << s.signature << '"';
+ if (s.attributes)
+ debug << ", attributes=" << s.attributes;
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const PySideSignalData &d)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "PySideSignalData(\"" << d.signalName << "\", "
+ << d.signatures;
+ if (!d.signalArguments.isEmpty())
+ debug << ", signalArguments=" << d.signalArguments;
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const PySideSignalInstancePrivate &d)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "PySideSignalInstancePrivate(\"" << d.signalName
+ << "\", \"" << d.signature << '"';
+ if (d.attributes)
+ debug << ", attributes=" << d.attributes;
+ if (d.homonymousMethod)
+ debug << ", homonymousMethod=" << d.homonymousMethod;
+ debug << ')';
+ return debug;
+}
+
+static bool connection_Check(PyObject *o)
+{
+ if (o == nullptr || o == Py_None)
+ return false;
+ static QByteArray typeName = QByteArrayLiteral("PySide")
+ + QByteArray::number(QT_VERSION_MAJOR)
+ + QByteArrayLiteral(".QtCore.QMetaObject.Connection");
+ return std::strcmp(o->ob_type->tp_name, typeName.constData()) == 0;
+}
+
+static std::optional<QByteArrayList> parseArgumentNames(PyObject *argArguments)
+{
+ QByteArrayList result;
+ if (argArguments == nullptr)
+ return result;
+ // Prevent a string from being split into a sequence of characters
+ if (PySequence_Check(argArguments) == 0 || PyUnicode_Check(argArguments) != 0)
+ return std::nullopt;
+ const Py_ssize_t argumentSize = PySequence_Size(argArguments);
+ result.reserve(argumentSize);
+ for (Py_ssize_t i = 0; i < argumentSize; ++i) {
+ Shiboken::AutoDecRef item(PySequence_GetItem(argArguments, i));
+ if (PyUnicode_Check(item.object()) == 0)
+ return std::nullopt;
+ Shiboken::AutoDecRef strObj(PyUnicode_AsUTF8String(item));
+ const char *s = PyBytes_AsString(strObj);
+ if (s == nullptr)
+ return std::nullopt;
+ result.append(QByteArray(s));
+ }
+ return result;
+}
+
+namespace PySide::Signal {
+ static QByteArray buildSignature(const QByteArray &, const QByteArray &);
+ static void instanceInitialize(PySideSignalInstance *, PyObject *, PySideSignal *, PyObject *, int);
+ static PySideSignalData::Signature parseSignature(PyObject *);
+ static PyObject *buildQtCompatible(const QByteArray &);
+} // PySide::Signal
+
+extern "C"
+{
+
+// Signal methods
+static int signalTpInit(PyObject *, PyObject *, PyObject *);
+static void signalFree(void *);
+static void signalInstanceFree(void *);
+static PyObject *signalGetItem(PyObject *self, PyObject *key);
+static PyObject *signalGetAttr(PyObject *self, PyObject *name);
+static PyObject *signalToString(PyObject *self);
+static PyObject *signalDescrGet(PyObject *self, PyObject *obj, PyObject *type);
+
+// Signal Instance methods
+static PyObject *signalInstanceConnect(PyObject *, PyObject *, PyObject *);
+static PyObject *signalInstanceDisconnect(PyObject *, PyObject *);
+static PyObject *signalInstanceEmit(PyObject *, PyObject *);
+static PyObject *signalInstanceGetItem(PyObject *, PyObject *);
+
+static PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw);
+static PyObject *signalCall(PyObject *, PyObject *, PyObject *);
+
+static PyObject *metaSignalCheck(PyObject *, PyObject *);
+
+
+static PyMethodDef MetaSignal_tp_methods[] = {
+ {"__instancecheck__", reinterpret_cast<PyCFunction>(metaSignalCheck),
+ METH_O|METH_STATIC, nullptr},
+ {nullptr, nullptr, 0, nullptr}
+};
+
+static PyTypeObject *createMetaSignalType()
+{
+ PyType_Slot PySideMetaSignalType_slots[] = {
+ {Py_tp_methods, reinterpret_cast<void *>(MetaSignal_tp_methods)},
+ {Py_tp_base, reinterpret_cast<void *>(&PyType_Type)},
+ {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PySideMetaSignalType_spec = {
+ "2:PySide6.QtCore.MetaSignal",
+ 0,
+ // sizeof(PyHeapTypeObject) is filled in by SbkType_FromSpec
+ // which calls PyType_Ready which calls inherit_special.
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ PySideMetaSignalType_slots,
+ };
+
+ return SbkType_FromSpec(&PySideMetaSignalType_spec);
+}
+
+static PyTypeObject *PySideMetaSignal_TypeF(void)
+{
+ static auto *type = createMetaSignalType();
+ return type;
+}
+
+static PyTypeObject *createSignalType()
+{
+ PyType_Slot PySideSignalType_slots[] = {
+ {Py_mp_subscript, reinterpret_cast<void *>(signalGetItem)},
+ {Py_tp_getattro, reinterpret_cast<void *>(signalGetAttr)},
+ {Py_tp_descr_get, reinterpret_cast<void *>(signalDescrGet)},
+ {Py_tp_call, reinterpret_cast<void *>(signalCall)},
+ {Py_tp_str, reinterpret_cast<void *>(signalToString)},
+ {Py_tp_init, reinterpret_cast<void *>(signalTpInit)},
+ {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)},
+ {Py_tp_free, reinterpret_cast<void *>(signalFree)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PySideSignalType_spec = {
+ "2:PySide6.QtCore.Signal",
+ sizeof(PySideSignal),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ PySideSignalType_slots,
+ };
+
+ return SbkType_FromSpecWithMeta(&PySideSignalType_spec, PySideMetaSignal_TypeF());
+}
+
+PyTypeObject *PySideSignal_TypeF(void)
+{
+ static auto *type = createSignalType();
+ return type;
+}
+
+static PyObject *signalInstanceRepr(PyObject *obSelf)
+{
+ auto *self = reinterpret_cast<PySideSignalInstance *>(obSelf);
+ auto *typeName = Py_TYPE(obSelf)->tp_name;
+ return Shiboken::String::fromFormat("<%s %s at %p>", typeName,
+ self->d ? self->d->signature.constData()
+ : "(no signature)", obSelf);
+}
+
+static PyMethodDef SignalInstance_methods[] = {
+ {"connect", reinterpret_cast<PyCFunction>(signalInstanceConnect),
+ METH_VARARGS|METH_KEYWORDS, nullptr},
+ {"disconnect", signalInstanceDisconnect, METH_VARARGS, nullptr},
+ {"emit", signalInstanceEmit, METH_VARARGS, nullptr},
+ {nullptr, nullptr, 0, nullptr} /* Sentinel */
+};
+
+static PyTypeObject *createSignalInstanceType()
+{
+ PyType_Slot PySideSignalInstanceType_slots[] = {
+ {Py_mp_subscript, reinterpret_cast<void *>(signalInstanceGetItem)},
+ {Py_tp_call, reinterpret_cast<void *>(signalInstanceCall)},
+ {Py_tp_methods, reinterpret_cast<void *>(SignalInstance_methods)},
+ {Py_tp_repr, reinterpret_cast<void *>(signalInstanceRepr)},
+ {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)},
+ {Py_tp_free, reinterpret_cast<void *>(signalInstanceFree)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PySideSignalInstanceType_spec = {
+ "2:PySide6.QtCore.SignalInstance",
+ sizeof(PySideSignalInstance),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ PySideSignalInstanceType_slots,
+ };
+
+ return SbkType_FromSpec(&PySideSignalInstanceType_spec);
+}
+
+PyTypeObject *PySideSignalInstance_TypeF(void)
+{
+ static auto *type = createSignalInstanceType();
+ return type;
+}
+
+static int signalTpInit(PyObject *obSelf, PyObject *args, PyObject *kwds)
+{
+ static PyObject * const emptyTuple = PyTuple_New(0);
+ static const char *kwlist[] = {"name", "arguments", nullptr};
+ char *argName = nullptr;
+ PyObject *argArguments = nullptr;
+
+ if (!PyArg_ParseTupleAndKeywords(emptyTuple, kwds,
+ "|sO:QtCore.Signal{name, arguments}",
+ const_cast<char **>(kwlist), &argName, &argArguments))
+ return -1;
+
+ bool tupledArgs = false;
+ PySideSignal *self = reinterpret_cast<PySideSignal *>(obSelf);
+ if (!self->data)
+ self->data = new PySideSignalData;
+ if (argName)
+ self->data->signalName = argName;
+
+ auto argumentNamesOpt = parseArgumentNames(argArguments);
+ if (!argumentNamesOpt.has_value()) {
+ PyErr_SetString(PyExc_TypeError, "'arguments' must be a sequence of strings.");
+ return -1;
+ }
+ self->data->signalArguments = argumentNamesOpt.value();
+
+ for (Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
+ PyObject *arg = PyTuple_GET_ITEM(args, i);
+ if (PySequence_Check(arg) && !Shiboken::String::check(arg) && !PyEnumMeta_Check(arg)) {
+ tupledArgs = true;
+ self->data->signatures.append(PySide::Signal::parseSignature(arg));
+ }
+ }
+
+ if (!tupledArgs)
+ self->data->signatures.append(PySide::Signal::parseSignature(args));
+
+ return 0;
+}
+
+static void signalFree(void *vself)
+{
+ auto pySelf = reinterpret_cast<PyObject *>(vself);
+ auto self = reinterpret_cast<PySideSignal *>(vself);
+ if (self->data) {
+ delete self->data;
+ self->data = nullptr;
+ }
+ Py_XDECREF(self->homonymousMethod);
+ self->homonymousMethod = nullptr;
+
+ PepExt_TypeCallFree(Py_TYPE(pySelf)->tp_base, self);
+}
+
+static PyObject *signalGetItem(PyObject *obSelf, PyObject *key)
+{
+ auto self = reinterpret_cast<PySideSignal *>(obSelf);
+ QByteArray sigKey;
+ if (key) {
+ sigKey = PySide::Signal::parseSignature(key).signature;
+ } else {
+ sigKey = self->data == nullptr || self->data->signatures.isEmpty()
+ ? PySide::Signal::voidType() : self->data->signatures.constFirst().signature;
+ }
+ auto sig = PySide::Signal::buildSignature(self->data->signalName, sigKey);
+ return Shiboken::String::fromCString(sig.constData());
+}
+
+static PyObject *signalToString(PyObject *obSelf)
+{
+ auto self = reinterpret_cast<PySideSignal *>(obSelf);
+ QByteArray result;
+ if (self->data == nullptr || self->data->signatures.isEmpty()) {
+ result = "<invalid>"_ba;
+ } else {
+ for (const auto &signature : std::as_const(self->data->signatures)) {
+ if (!result.isEmpty())
+ result += "; "_ba;
+ result += PySide::Signal::buildSignature(self->data->signalName,
+ signature.signature);
+ }
+ }
+ return Shiboken::String::fromCString(result.constData());
+}
+
+static PyObject *signalGetAttr(PyObject *obSelf, PyObject *name)
+{
+ auto self = reinterpret_cast<PySideSignal *>(obSelf);
+
+ if (PyUnicode_CompareWithASCIIString(name, "signatures") != 0)
+ return PyObject_GenericGetAttr(obSelf, name);
+
+ auto nelems = self->data->signatures.count();
+ PyObject *tuple = PyTuple_New(nelems);
+
+ for (Py_ssize_t idx = 0; idx < nelems; ++idx) {
+ QByteArray sigKey = self->data->signatures.at(idx).signature;
+ auto sig = PySide::Signal::buildSignature(self->data->signalName, sigKey);
+ PyObject *entry = Shiboken::String::fromCString(sig.constData());
+ PyTuple_SetItem(tuple, idx, entry);
+ }
+ return tuple;
+}
+
+static void signalInstanceFree(void *vself)
+{
+ auto pySelf = reinterpret_cast<PyObject *>(vself);
+ auto self = reinterpret_cast<PySideSignalInstance *>(vself);
+
+ PySideSignalInstancePrivate *dataPvt = self->d;
+ if (dataPvt) {
+ Py_XDECREF(dataPvt->homonymousMethod);
+
+ if (dataPvt->next) {
+ Py_DECREF(dataPvt->next);
+ dataPvt->next = nullptr;
+ }
+ delete dataPvt;
+ self->d = nullptr;
+ }
+ self->deleted = true;
+ PepExt_TypeCallFree(Py_TYPE(pySelf)->tp_base, self);
+}
+
+// PYSIDE-1523: PyFunction_Check is not accepting compiled functions and
+// PyMethod_Check is not allowing compiled methods, therefore also lookup
+// "im_func" and "__code__" attributes, we allow for that with a dedicated
+// function handling both.
+
+struct FunctionArgumentsResult
+{
+ PyObject *function = nullptr;
+ PepCodeObject *objCode = nullptr;
+ PyObject *functionName = nullptr;
+ bool isMethod = false;
+};
+
+static FunctionArgumentsResult extractFunctionArgumentsFromSlot(PyObject *slot)
+{
+ FunctionArgumentsResult ret;
+ ret.isMethod = PyMethod_Check(slot);
+ const bool isFunction = PyFunction_Check(slot);
+
+ if (ret.isMethod || isFunction) {
+ ret.function = ret.isMethod ? PyMethod_GET_FUNCTION(slot) : slot;
+ ret.objCode = reinterpret_cast<PepCodeObject *>(PyFunction_GET_CODE(ret.function));
+ ret.functionName = PepFunction_GetName(ret.function);
+
+ } else if (PySide::isCompiledMethod(slot)) {
+ // PYSIDE-1523: PyFunction_Check and PyMethod_Check are not accepting compiled forms, we
+ // just go by attributes.
+ ret.isMethod = true;
+
+ ret.function = PyObject_GetAttr(slot, PySide::PySideName::im_func());
+ // Not retaining a reference inline with what PyMethod_GET_FUNCTION does.
+ Py_DECREF(ret.function);
+
+ ret.functionName = PyObject_GetAttr(ret.function, PySide::PySideMagicName::name());
+ // Not retaining a reference inline with what PepFunction_GetName does.
+ Py_DECREF(ret.functionName);
+
+ ret.objCode = reinterpret_cast<PepCodeObject *>(
+ PyObject_GetAttr(ret.function, PySide::PySideMagicName::code()));
+ // Not retaining a reference inline with what PyFunction_GET_CODE does.
+ Py_XDECREF(ret.objCode);
+
+ // Should not happen, but lets handle it gracefully, maybe Nuitka one day
+ // makes these optional, or somebody defined a type named like it without
+ // it being actually being that.
+ if (ret.objCode == nullptr)
+ ret.function = nullptr;
+ } else if (strcmp(Py_TYPE(slot)->tp_name, "compiled_function") == 0) {
+ ret.isMethod = false;
+ ret.function = slot;
+
+ ret.functionName = PyObject_GetAttr(ret.function, PySide::PySideMagicName::name());
+ // Not retaining a reference inline with what PepFunction_GetName does.
+ Py_DECREF(ret.functionName);
+
+ ret.objCode = reinterpret_cast<PepCodeObject *>(
+ PyObject_GetAttr(ret.function, PySide::PySideMagicName::code()));
+ // Not retaining a reference inline with what PyFunction_GET_CODE does.
+ Py_XDECREF(ret.objCode);
+
+ // Should not happen, but lets handle it gracefully, maybe Nuitka one day
+ // makes these optional, or somebody defined a type named like it without
+ // it being actually being that.
+ if (ret.objCode == nullptr)
+ ret.function = nullptr;
+ }
+ // any other callback
+ return ret;
+}
+
+struct ArgCount
+{
+ int min;
+ int max;
+};
+
+// Return a pair of minimum / arg count "foo(p1, p2=0)" -> {1, 2}
+ArgCount argCount(const FunctionArgumentsResult &args)
+{
+ Q_ASSERT(args.objCode);
+ ArgCount result{-1, -1};
+ if ((PepCode_GET_FLAGS(args.objCode) & CO_VARARGS) == 0) {
+ result.min = result.max = PepCode_GET_ARGCOUNT(args.objCode);
+ if (args.function != nullptr) {
+ if (auto *defaultArgs = PepFunction_GetDefaults(args.function))
+ result.min -= PyTuple_Size(defaultArgs);
+ }
+ }
+ return result;
+}
+
+// Find Signal Instance for argument count.
+static PySideSignalInstance *findSignalInstance(PySideSignalInstance *source, int argCount)
+{
+ for (auto *si = source; si != nullptr; si = si->d->next) {
+ if (si->d->argCount == argCount)
+ return si;
+ }
+ return nullptr;
+}
+
+static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *slot = nullptr;
+ PyObject *type = nullptr;
+ static const char *kwlist[] = {"slot", "type", nullptr};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds,
+ "O|O:SignalInstance", const_cast<char **>(kwlist), &slot, &type))
+ return nullptr;
+
+ PySideSignalInstance *source = reinterpret_cast<PySideSignalInstance *>(self);
+ if (!source->d)
+ return PyErr_Format(PyExc_RuntimeError, "cannot connect uninitialized SignalInstance");
+ if (source->deleted)
+ return PyErr_Format(PyExc_RuntimeError, "Signal source has been deleted");
+
+ Shiboken::AutoDecRef pyArgs(PyList_New(0));
+
+ bool match = false;
+ if (Py_TYPE(slot) == PySideSignalInstance_TypeF()) {
+ PySideSignalInstance *sourceWalk = source;
+
+ //find best match
+ while (sourceWalk && !match) {
+ auto targetWalk = reinterpret_cast<PySideSignalInstance *>(slot);
+ while (targetWalk && !match) {
+ if (QMetaObject::checkConnectArgs(sourceWalk->d->signature,
+ targetWalk->d->signature)) {
+ PyList_Append(pyArgs, sourceWalk->d->source);
+ Shiboken::AutoDecRef sourceSignature(PySide::Signal::buildQtCompatible(sourceWalk->d->signature));
+ PyList_Append(pyArgs, sourceSignature);
+
+ PyList_Append(pyArgs, targetWalk->d->source);
+ Shiboken::AutoDecRef targetSignature(PySide::Signal::buildQtCompatible(targetWalk->d->signature));
+ PyList_Append(pyArgs, targetSignature);
+
+ match = true;
+ }
+ targetWalk = reinterpret_cast<PySideSignalInstance *>(targetWalk->d->next);
+ }
+ sourceWalk = reinterpret_cast<PySideSignalInstance *>(sourceWalk->d->next);
+ }
+ } else {
+ // Check signature of the slot (method or function) to match signal
+ const auto args = extractFunctionArgumentsFromSlot(slot);
+ PySideSignalInstance *matchedSlot = nullptr;
+
+ if (args.function != nullptr) {
+ auto slotArgRange = argCount(args);
+ if (args.isMethod) {
+ slotArgRange.min -= 1;
+ slotArgRange.max -= 1;
+ }
+
+ // Get signature args
+ // Iterate the possible types of connection for this signal and compare
+ // it with slot arguments
+ for (int slotArgs = slotArgRange.max;
+ slotArgs >= slotArgRange.min && matchedSlot == nullptr; --slotArgs) {
+ matchedSlot = findSignalInstance(source, slotArgs);
+ }
+ }
+
+ // Adding references to pyArgs
+ PyList_Append(pyArgs, source->d->source);
+
+ if (matchedSlot != nullptr) {
+ // If a slot matching the same number of arguments was found,
+ // include signature to the pyArgs
+ Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(matchedSlot->d->signature));
+ PyList_Append(pyArgs, signature);
+ } else {
+ // Try the first by default if the slot was not found
+ Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(source->d->signature));
+ PyList_Append(pyArgs, signature);
+ }
+ PyList_Append(pyArgs, slot);
+ match = true;
+ }
+
+ if (type)
+ PyList_Append(pyArgs, type);
+
+ if (match) {
+ Shiboken::AutoDecRef tupleArgs(PyList_AsTuple(pyArgs));
+ Shiboken::AutoDecRef pyMethod(PyObject_GetAttr(source->d->source,
+ PySide::PySideName::qtConnect()));
+ if (pyMethod.isNull()) // PYSIDE-79: check if pyMethod exists.
+ return PyErr_Format(PyExc_RuntimeError, "method 'connect' vanished!");
+ PyObject *result = PyObject_CallObject(pyMethod, tupleArgs);
+ if (connection_Check(result))
+ return result;
+ Py_XDECREF(result);
+ }
+ if (!PyErr_Occurred()) // PYSIDE-79: inverse the logic. A Null return needs an error.
+ PyErr_Format(PyExc_RuntimeError, "Failed to connect signal %s.",
+ source->d->signature.constData());
+ return nullptr;
+}
+
+static int argCountInSignature(const char *signature)
+{
+ return QByteArray(signature).count(",") + 1;
+}
+
+static PyObject *signalInstanceEmit(PyObject *self, PyObject *args)
+{
+ PySideSignalInstance *source = reinterpret_cast<PySideSignalInstance *>(self);
+ if (!source->d)
+ return PyErr_Format(PyExc_RuntimeError, "cannot emit uninitialized SignalInstance");
+
+ // PYSIDE-2201: Check if the object has vanished meanwhile.
+ // Tried to revive it without exception, but this gives problems.
+ if (source->deleted)
+ return PyErr_Format(PyExc_RuntimeError, "The SignalInstance object was already deleted");
+
+ Shiboken::AutoDecRef pyArgs(PyList_New(0));
+ int numArgsGiven = PySequence_Fast_GET_SIZE(args);
+ int numArgsInSignature = argCountInSignature(source->d->signature);
+
+ // If number of arguments given to emit is smaller than the first source signature expects,
+ // it is possible it's a case of emitting a signal with default parameters.
+ // Search through all the overloaded signals with the same name, and try to find a signature
+ // with the same number of arguments as given to emit, and is also marked as a cloned method
+ // (which in metaobject parlance means a signal with default parameters).
+ // @TODO: This should be improved to take into account argument types as well. The current
+ // assumption is there are no signals which are both overloaded on argument types and happen to
+ // have signatures with default parameters.
+ if (numArgsGiven < numArgsInSignature) {
+ PySideSignalInstance *possibleDefaultInstance = source;
+ while ((possibleDefaultInstance = possibleDefaultInstance->d->next)) {
+ if (possibleDefaultInstance->d->attributes & QMetaMethod::Cloned
+ && argCountInSignature(possibleDefaultInstance->d->signature) == numArgsGiven) {
+ source = possibleDefaultInstance;
+ break;
+ }
+ }
+ }
+ Shiboken::AutoDecRef sourceSignature(PySide::Signal::buildQtCompatible(source->d->signature));
+
+ PyList_Append(pyArgs, sourceSignature);
+ for (Py_ssize_t i = 0, max = PyTuple_Size(args); i < max; i++)
+ PyList_Append(pyArgs, PyTuple_GetItem(args, i));
+
+ Shiboken::AutoDecRef pyMethod(PyObject_GetAttr(source->d->source,
+ PySide::PySideName::qtEmit()));
+
+ Shiboken::AutoDecRef tupleArgs(PyList_AsTuple(pyArgs));
+ return PyObject_CallObject(pyMethod.object(), tupleArgs);
+}
+
+static PyObject *signalInstanceGetItem(PyObject *self, PyObject *key)
+{
+ auto *firstSignal = reinterpret_cast<PySideSignalInstance *>(self);
+ const auto &sigName = firstSignal->d->signalName;
+ const auto sigKey = PySide::Signal::parseSignature(key).signature;
+ const auto sig = PySide::Signal::buildSignature(sigName, sigKey);
+ for (auto *data = firstSignal; data != nullptr; data = data->d->next) {
+ if (data->d->signature == sig) {
+ PyObject *result = reinterpret_cast<PyObject *>(data);
+ Py_INCREF(result);
+ return result;
+ }
+ }
+
+ // Build error message with candidates
+ QByteArray message = "Signature \"" + sig + "\" not found for signal: \""
+ + sigName + "\". Available candidates: ";
+ for (auto *data = firstSignal; data != nullptr; data = data->d->next) {
+ if (data != firstSignal)
+ message += ", ";
+ message += '"' + data->d->signature + '"';
+ }
+
+ return PyErr_Format(PyExc_IndexError, message.constData());
+}
+
+static inline void warnDisconnectFailed(PyObject *aSlot, const QByteArray &signature)
+{
+ if (PyErr_Occurred() != nullptr) { // avoid "%S" invoking str() when an error is set.
+ PyObject *exc{}, *inst{}, *tb{};
+ PyErr_Fetch(&exc, &inst, &tb);
+ PyErr_WarnFormat(PyExc_RuntimeWarning, 0, "Failed to disconnect (%s) from signal \"%s\".",
+ Py_TYPE(aSlot)->tp_name, signature.constData());
+ PyErr_Restore(exc, inst, tb);
+ } else {
+ PyErr_WarnFormat(PyExc_RuntimeWarning, 0, "Failed to disconnect (%S) from signal \"%s\".",
+ aSlot, signature.constData());
+ }
+}
+
+static PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args)
+{
+ auto source = reinterpret_cast<PySideSignalInstance *>(self);
+ if (!source->d)
+ return PyErr_Format(PyExc_RuntimeError, "cannot disconnect uninitialized SignalInstance");
+
+ Shiboken::AutoDecRef pyArgs(PyList_New(0));
+
+ PyObject *slot = Py_None;
+ if (PyTuple_Check(args) && PyTuple_GET_SIZE(args))
+ slot = PyTuple_GET_ITEM(args, 0);
+
+ bool match = false;
+ if (Py_TYPE(slot) == PySideSignalInstance_TypeF()) {
+ PySideSignalInstance *target = reinterpret_cast<PySideSignalInstance *>(slot);
+ if (QMetaObject::checkConnectArgs(source->d->signature, target->d->signature)) {
+ PyList_Append(pyArgs, source->d->source);
+ Shiboken::AutoDecRef source_signature(PySide::Signal::buildQtCompatible(source->d->signature));
+ PyList_Append(pyArgs, source_signature);
+
+ PyList_Append(pyArgs, target->d->source);
+ Shiboken::AutoDecRef target_signature(PySide::Signal::buildQtCompatible(target->d->signature));
+ PyList_Append(pyArgs, target_signature);
+ match = true;
+ }
+ } else if (connection_Check(slot)) {
+ PyList_Append(pyArgs, slot);
+ match = true;
+ } else {
+ //try the first signature
+ PyList_Append(pyArgs, source->d->source);
+ Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(source->d->signature));
+ PyList_Append(pyArgs, signature);
+
+ // disconnect all, so we need to use the c++ signature disconnect(qobj, signal, 0, 0)
+ if (slot == Py_None)
+ PyList_Append(pyArgs, slot);
+ PyList_Append(pyArgs, slot);
+ match = true;
+ }
+
+ if (match) {
+ Shiboken::AutoDecRef tupleArgs(PyList_AsTuple(pyArgs));
+ Shiboken::AutoDecRef pyMethod(PyObject_GetAttr(source->d->source,
+ PySide::PySideName::qtDisconnect()));
+ PyObject *result = PyObject_CallObject(pyMethod, tupleArgs);
+ if (result != Py_True)
+ warnDisconnectFailed(slot, source->d->signature);
+ return result;
+ }
+
+ warnDisconnectFailed(slot, source->d->signature);
+ Py_RETURN_FALSE;
+}
+
+// PYSIDE-68: Supply the missing __get__ function
+static PyObject *signalDescrGet(PyObject *self, PyObject *obj, PyObject * /*type*/)
+{
+ auto signal = reinterpret_cast<PySideSignal *>(self);
+ // Return the unbound signal if there is nothing to bind it to.
+ if (obj == nullptr || obj == Py_None
+ || !PySide::isQObjectDerived(Py_TYPE(obj), true)) {
+ Py_INCREF(self);
+ return self;
+ }
+
+ // PYSIDE-68-bis: It is important to respect the already cached instance.
+ Shiboken::AutoDecRef name(Py_BuildValue("s", signal->data->signalName.data()));
+ auto *dict = SbkObject_GetDict_NoRef(obj);
+ auto *inst = PyDict_GetItem(dict, name);
+ if (inst) {
+ Py_INCREF(inst);
+ return inst;
+ }
+ inst = reinterpret_cast<PyObject *>(PySide::Signal::initialize(signal, name, obj));
+ PyObject_SetAttr(obj, name, inst);
+ return inst;
+}
+
+static PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw)
+{
+ auto signal = reinterpret_cast<PySideSignal *>(self);
+
+ // Native C++ signals can't be called like functions, thus we throw an exception.
+ // The only way calling a signal can succeed (the Python equivalent of C++'s operator() )
+ // is when a method with the same name as the signal is attached to an object.
+ // An example is QProcess::error() (don't check the docs, but the source code of qprocess.h).
+ if (!signal->homonymousMethod)
+ return PyErr_Format(PyExc_TypeError, "native Qt signal is not callable");
+
+ // Check if there exists a method with the same name as the signal, which is also a static
+ // method in C++ land.
+ Shiboken::AutoDecRef homonymousMethod(PepExt_Type_CallDescrGet(signal->homonymousMethod,
+ nullptr, nullptr));
+ if (PyCFunction_Check(homonymousMethod.object())
+ && (PyCFunction_GET_FLAGS(homonymousMethod.object()) & METH_STATIC))
+ return PyObject_Call(homonymousMethod, args, kw);
+
+ // Assumes homonymousMethod is not a static method.
+ ternaryfunc callFunc = PepExt_Type_GetCallSlot(Py_TYPE(signal->homonymousMethod));
+ return callFunc(homonymousMethod, args, kw);
+}
+
+// This function returns a borrowed reference.
+static inline PyObject *_getRealCallable(PyObject *func)
+{
+ static const auto *SignalType = PySideSignal_TypeF();
+ static const auto *SignalInstanceType = PySideSignalInstance_TypeF();
+
+ // If it is a signal, use the (maybe empty) homonymous method.
+ if (Py_TYPE(func) == SignalType) {
+ auto *signal = reinterpret_cast<PySideSignal *>(func);
+ return signal->homonymousMethod;
+ }
+ // If it is a signal instance, use the (maybe empty) homonymous method.
+ if (Py_TYPE(func) == SignalInstanceType) {
+ auto *signalInstance = reinterpret_cast<PySideSignalInstance *>(func);
+ return signalInstance->d->homonymousMethod;
+ }
+ return func;
+}
+
+// This function returns a borrowed reference.
+static PyObject *_getHomonymousMethod(PySideSignalInstance *inst)
+{
+ if (inst->d->homonymousMethod)
+ return inst->d->homonymousMethod;
+
+ // PYSIDE-1730: We are searching methods with the same name not only at the same place,
+ // but walk through the whole mro to find a hidden method with the same name.
+ auto signalName = inst->d->signalName;
+ Shiboken::AutoDecRef name(Shiboken::String::fromCString(signalName));
+ auto *mro = Py_TYPE(inst->d->source)->tp_mro;
+ const Py_ssize_t n = PyTuple_GET_SIZE(mro);
+
+ for (Py_ssize_t idx = 0; idx < n; idx++) {
+ auto *sub_type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ Shiboken::AutoDecRef tpDict(PepType_GetDict(sub_type));
+ auto *hom = PyDict_GetItem(tpDict, name);
+ PyObject *realFunc{};
+ if (hom && PyCallable_Check(hom) && (realFunc = _getRealCallable(hom)))
+ return realFunc;
+ }
+ return nullptr;
+}
+
+static PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw)
+{
+ auto *PySideSignal = reinterpret_cast<PySideSignalInstance *>(self);
+ auto *hom = _getHomonymousMethod(PySideSignal);
+ if (!hom) {
+ PyErr_Format(PyExc_TypeError, "native Qt signal instance '%s' is not callable",
+ PySideSignal->d->signalName.constData());
+ return nullptr;
+ }
+
+ Shiboken::AutoDecRef homonymousMethod(PepExt_Type_CallDescrGet(hom, PySideSignal->d->source,
+ nullptr));
+ return PyObject_Call(homonymousMethod, args, kw);
+}
+
+static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *arg)
+{
+ if (PyType_IsSubtype(Py_TYPE(arg), PySideSignalInstance_TypeF()))
+ Py_RETURN_TRUE;
+ Py_RETURN_FALSE;
+}
+
+} // extern "C"
+
+namespace PySide::Signal {
+
+static const char *MetaSignal_SignatureStrings[] = {
+ "PySide6.QtCore.MetaSignal.__instancecheck__(self,object:object)->bool",
+ nullptr}; // Sentinel
+
+static const char *Signal_SignatureStrings[] = {
+ "PySide6.QtCore.Signal(self,*types:type,name:str=nullptr,arguments:typing.List[str]=nullptr)",
+ "1:PySide6.QtCore.Signal.__get__(self,instance:None,owner:Optional[typing.Any])->"
+ "PySide6.QtCore.Signal",
+ "0:PySide6.QtCore.Signal.__get__(self,instance:PySide6.QtCore.QObject,"
+ "owner:Optional[typing.Any])->PySide6.QtCore.SignalInstance",
+ nullptr}; // Sentinel
+
+static const char *SignalInstance_SignatureStrings[] = {
+ "PySide6.QtCore.SignalInstance.connect(self,slot:object,"
+ "type:PySide6.QtCore.Qt.ConnectionType=PySide6.QtCore.Qt.ConnectionType.AutoConnection)"
+ "->PySide6.QtCore.QMetaObject.Connection",
+ "PySide6.QtCore.SignalInstance.disconnect(self,slot:object=nullptr)->bool",
+ "PySide6.QtCore.SignalInstance.emit(self,*args:typing.Any)",
+ nullptr}; // Sentinel
+
+void init(PyObject *module)
+{
+ if (InitSignatureStrings(PySideMetaSignal_TypeF(), MetaSignal_SignatureStrings) < 0)
+ return;
+ Py_INCREF(PySideMetaSignal_TypeF());
+ auto *obMetaSignal_Type = reinterpret_cast<PyObject *>(PySideMetaSignal_TypeF());
+ PyModule_AddObject(module, "MetaSignal", obMetaSignal_Type);
+
+ if (InitSignatureStrings(PySideSignal_TypeF(), Signal_SignatureStrings) < 0)
+ return;
+ Py_INCREF(PySideSignal_TypeF());
+ auto *obSignal_Type = reinterpret_cast<PyObject *>(PySideSignal_TypeF());
+ PyModule_AddObject(module, "Signal", obSignal_Type);
+
+ if (InitSignatureStrings(PySideSignalInstance_TypeF(), SignalInstance_SignatureStrings) < 0)
+ return;
+ Py_INCREF(PySideSignalInstance_TypeF());
+ auto *obSignalInstance_Type = reinterpret_cast<PyObject *>(PySideSignalInstance_TypeF());
+ PyModule_AddObject(module, "SignalInstance", obSignalInstance_Type);
+}
+
+bool checkType(PyObject *pyObj)
+{
+ if (pyObj)
+ return PyType_IsSubtype(Py_TYPE(pyObj), PySideSignal_TypeF());
+ return false;
+}
+
+bool checkInstanceType(PyObject *pyObj)
+{
+ return pyObj != nullptr
+ && PyType_IsSubtype(Py_TYPE(pyObj), PySideSignalInstance_TypeF()) != 0;
+}
+
+void updateSourceObject(PyObject *source)
+{
+ // TODO: Provide for actual upstream exception handling.
+ // For now we'll just return early to avoid further issues.
+
+ if (source == nullptr) // Bad input
+ return;
+
+ Shiboken::AutoDecRef mroIterator(PyObject_GetIter(source->ob_type->tp_mro));
+
+ if (mroIterator.isNull()) // Not iterable
+ return;
+
+ Shiboken::AutoDecRef mroItem{};
+ auto *dict = SbkObject_GetDict_NoRef(source);
+
+ // PYSIDE-1431: Walk the mro and update. But see PYSIDE-1751 below.
+ while ((mroItem.reset(PyIter_Next(mroIterator))), mroItem.object()) {
+ Py_ssize_t pos = 0;
+ PyObject *key, *value;
+ auto *type = reinterpret_cast<PyTypeObject *>(mroItem.object());
+ Shiboken::AutoDecRef tpDict(PepType_GetDict(type));
+ while (PyDict_Next(tpDict, &pos, &key, &value)) {
+ if (PyObject_TypeCheck(value, PySideSignal_TypeF())) {
+ // PYSIDE-1751: We only insert an instance into the instance dict, if a signal
+ // of the same name is in the mro. This is the equivalent action
+ // as PyObject_SetAttr, but filtered by existing signal names.
+ if (!PyDict_GetItem(dict, key)) {
+ auto *inst = PyObject_New(PySideSignalInstance, PySideSignalInstance_TypeF());
+ Shiboken::AutoDecRef signalInstance(reinterpret_cast<PyObject *>(inst));
+ auto *si = reinterpret_cast<PySideSignalInstance *>(signalInstance.object());
+ instanceInitialize(si, key, reinterpret_cast<PySideSignal *>(value),
+ source, 0);
+ if (PyDict_SetItem(dict, key, signalInstance) == -1)
+ return; // An error occurred while setting the attribute
+ }
+ }
+ }
+ }
+
+ if (PyErr_Occurred()) // An iteration error occurred
+ return;
+}
+
+QByteArray getTypeName(PyObject *obType)
+{
+ if (PyType_Check(obType)) {
+ auto *type = reinterpret_cast<PyTypeObject *>(obType);
+ if (PyType_IsSubtype(type, SbkObject_TypeF()))
+ return Shiboken::ObjectType::getOriginalName(type);
+ // Translate Python types to Qt names
+ if (Shiboken::String::checkType(type))
+ return QByteArrayLiteral("QString");
+ if (type == &PyLong_Type)
+ return QByteArrayLiteral("int");
+ if (type == &PyFloat_Type)
+ return QByteArrayLiteral("double");
+ if (type == &PyBool_Type)
+ return QByteArrayLiteral("bool");
+ if (type == &PyList_Type)
+ return QByteArrayLiteral("QVariantList");
+ if (type == &PyDict_Type)
+ return QByteArrayLiteral("QVariantMap");
+ return QByteArrayLiteral("PyObject");
+ }
+ if (obType == Py_None) // Must be checked before as Shiboken::String::check accepts Py_None
+ return voidType();
+ if (Shiboken::String::check(obType)) {
+ QByteArray result = Shiboken::String::toCString(obType);
+ if (result == "qreal")
+ result = sizeof(qreal) == sizeof(double) ? "double" : "float";
+ return result;
+ }
+ return QByteArray();
+}
+
+static QByteArray buildSignature(const QByteArray &name, const QByteArray &signature)
+{
+ return QMetaObject::normalizedSignature(name + '(' + signature + ')');
+}
+
+static PySideSignalData::Signature parseSignature(PyObject *args)
+{
+ PySideSignalData::Signature result{{}, QMetaMethod::Compatibility, 0};
+ if (args && (Shiboken::String::check(args) || !PyTuple_Check(args))) {
+ result.signature = getTypeName(args);
+ result.argCount = 1;
+ return result;
+ }
+
+ for (Py_ssize_t i = 0, i_max = PySequence_Size(args); i < i_max; i++) {
+ Shiboken::AutoDecRef arg(PySequence_GetItem(args, i));
+ const auto typeName = getTypeName(arg);
+ if (!typeName.isEmpty()) {
+ if (!result.signature.isEmpty())
+ result.signature += ',';
+ result.signature += typeName;
+ ++result.argCount;
+ }
+ }
+ return result;
+}
+
+static void sourceGone(void *data)
+{
+ auto *self = reinterpret_cast<PySideSignalInstance *>(data);
+ self->deleted = true;
+}
+
+static void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal *signal, PyObject *source, int index)
+{
+ self->d = new PySideSignalInstancePrivate;
+ self->deleted = false;
+ PySideSignalInstancePrivate *selfPvt = self->d;
+ selfPvt->next = nullptr;
+ if (signal->data->signalName.isEmpty())
+ signal->data->signalName = Shiboken::String::toCString(name);
+ selfPvt->signalName = signal->data->signalName;
+
+ selfPvt->source = source;
+ const auto &signature = signal->data->signatures.at(index);
+ selfPvt->signature = buildSignature(self->d->signalName, signature.signature);
+ selfPvt->argCount = signature.argCount;
+ selfPvt->attributes = signature.attributes;
+ selfPvt->homonymousMethod = nullptr;
+ if (signal->homonymousMethod) {
+ selfPvt->homonymousMethod = signal->homonymousMethod;
+ Py_INCREF(selfPvt->homonymousMethod);
+ }
+ // PYSIDE-2201: We have no reference to source. Let's take a weakref to get
+ // notified when source gets deleted.
+ PySide::WeakRef::create(source, sourceGone, self);
+
+ index++;
+
+ if (index < signal->data->signatures.size()) {
+ selfPvt->next = PyObject_New(PySideSignalInstance, PySideSignalInstance_TypeF());
+ instanceInitialize(selfPvt->next, name, signal, source, index);
+ }
+}
+
+PySideSignalInstance *initialize(PySideSignal *self, PyObject *name, PyObject *object)
+{
+ static PyTypeObject *pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
+ assert(pyQObjectType);
+
+ if (!PyObject_TypeCheck(object, pyQObjectType)) {
+ PyErr_Format(PyExc_TypeError, "%s cannot be converted to %s",
+ Py_TYPE(object)->tp_name, pyQObjectType->tp_name);
+ return nullptr;
+ }
+
+ PySideSignalInstance *instance = PyObject_New(PySideSignalInstance,
+ PySideSignalInstance_TypeF());
+ instanceInitialize(instance, name, self, object, 0);
+ auto sbkObj = reinterpret_cast<SbkObject *>(object);
+ if (!Shiboken::Object::wasCreatedByPython(sbkObj))
+ Py_INCREF(object); // PYSIDE-79: this flag was crucial for a wrapper call.
+ return instance;
+}
+
+bool connect(PyObject *source, const char *signal, PyObject *callback)
+{
+ Shiboken::AutoDecRef pyMethod(PyObject_GetAttr(source,
+ PySide::PySideName::qtConnect()));
+ if (pyMethod.isNull())
+ return false;
+
+ Shiboken::AutoDecRef pySignature(Shiboken::String::fromCString(signal));
+ Shiboken::AutoDecRef pyArgs(PyTuple_Pack(3, source, pySignature.object(), callback));
+ PyObject *result = PyObject_CallObject(pyMethod, pyArgs);
+ if (result == Py_False) {
+ PyErr_Format(PyExc_RuntimeError, "Failed to connect signal %s, to python callable object.", signal);
+ Py_DECREF(result);
+ result = nullptr;
+ }
+ return result;
+}
+
+PySideSignalInstance *newObjectFromMethod(PyObject *source, const QList<QMetaMethod>& methodList)
+{
+ PySideSignalInstance *root = nullptr;
+ PySideSignalInstance *previous = nullptr;
+ for (const QMetaMethod &m : methodList) {
+ PySideSignalInstance *item = PyObject_New(PySideSignalInstance, PySideSignalInstance_TypeF());
+ if (!root)
+ root = item;
+
+ if (previous)
+ previous->d->next = item;
+
+ item->d = new PySideSignalInstancePrivate;
+ item->deleted = false;
+ PySideSignalInstancePrivate *selfPvt = item->d;
+ selfPvt->source = source;
+ QByteArray cppName(m.methodSignature());
+ cppName.truncate(cppName.indexOf('('));
+ // separate SignalName
+ selfPvt->signalName = cppName;
+ selfPvt->signature = m.methodSignature();
+ selfPvt->argCount = int(m.parameterCount());
+ selfPvt->attributes = m.attributes();
+ selfPvt->homonymousMethod = nullptr;
+ selfPvt->next = nullptr;
+ }
+ return root;
+}
+
+static void _addSignalToWrapper(PyTypeObject *wrapperType, const char *signalName, PySideSignal *signal)
+{
+ Shiboken::AutoDecRef tpDict(PepType_GetDict(wrapperType));
+ auto typeDict = tpDict.object();
+ PyObject *homonymousMethod;
+ if ((homonymousMethod = PyDict_GetItemString(typeDict, signalName))) {
+ Py_INCREF(homonymousMethod);
+ signal->homonymousMethod = homonymousMethod;
+ }
+ PyDict_SetItemString(typeDict, signalName, reinterpret_cast<PyObject *>(signal));
+}
+
+// This function is used by qStableSort to promote empty signatures
+static bool compareSignals(const PySideSignalData::Signature &sig1,
+ const PySideSignalData::Signature &sig2)
+{
+ return sig1.signature.isEmpty() && !sig2.signature.isEmpty();
+}
+
+static PyObject *buildQtCompatible(const QByteArray &signature)
+{
+ const auto ba = QT_SIGNAL_SENTINEL + signature;
+ return Shiboken::String::fromStringAndSize(ba, ba.size());
+}
+
+void registerSignals(PyTypeObject *pyObj, const QMetaObject *metaObject)
+{
+ using Signature = PySideSignalData::Signature;
+ struct MetaSignal
+ {
+ QByteArray methodName;
+ QList<Signature> signatures;
+ };
+
+ QList<MetaSignal> signalsFound;
+ for (int i = metaObject->methodOffset(), max = metaObject->methodCount(); i < max; ++i) {
+ QMetaMethod method = metaObject->method(i);
+
+ if (method.methodType() == QMetaMethod::Signal) {
+ QByteArray methodName(method.methodSignature());
+ methodName.truncate(methodName.indexOf('('));
+ Signature signature{method.parameterTypes().join(','), {},
+ short(method.parameterCount())};
+ if (method.attributes() & QMetaMethod::Cloned)
+ signature.attributes = QMetaMethod::Cloned;
+ auto it = std::find_if(signalsFound.begin(), signalsFound.end(),
+ [methodName](const MetaSignal &ms)
+ { return ms.methodName == methodName; });
+ if (it != signalsFound.end())
+ it->signatures << signature;
+ else
+ signalsFound.append(MetaSignal{methodName, {signature}});
+ }
+ }
+
+ for (const auto &metaSignal : std::as_const(signalsFound)) {
+ PySideSignal *self = PyObject_New(PySideSignal, PySideSignal_TypeF());
+ self->data = new PySideSignalData;
+ self->data->signalName = metaSignal.methodName;
+ self->homonymousMethod = nullptr;
+
+ // Empty signatures comes first! So they will be the default signal signature
+ self->data->signatures = metaSignal.signatures;
+ std::stable_sort(self->data->signatures.begin(),
+ self->data->signatures.end(), &compareSignals);
+
+ _addSignalToWrapper(pyObj, metaSignal.methodName, self);
+ Py_DECREF(reinterpret_cast<PyObject *>(self));
+ }
+}
+
+PyObject *getObject(PySideSignalInstance *signal)
+{
+ return signal->d->source;
+}
+
+const char *getSignature(PySideSignalInstance *signal)
+{
+ return signal->d->signature;
+}
+
+EmitterData getEmitterData(PySideSignalInstance *signal)
+{
+ EmitterData result;
+ result.emitter = PySide::convertToQObject(getObject(signal), false);
+ if (result.emitter != nullptr) {
+ auto *mo = result.emitter->metaObject();
+ result.methodIndex = mo->indexOfMethod(getSignature(signal));
+ }
+ return result;
+}
+
+QByteArrayList getArgsFromSignature(const char *signature)
+{
+ QByteArray qsignature = QByteArray(signature).trimmed();
+ QByteArrayList result;
+
+ if (qsignature.contains("()") || qsignature.contains("(void)"))
+ return result;
+ if (qsignature.endsWith(')')) {
+ const auto paren = qsignature.indexOf('(');
+ if (paren >= 0) {
+ qsignature.chop(1);
+ qsignature.remove(0, paren + 1);
+ result = qsignature.split(u',');
+ for (auto &type : result)
+ type = type.trimmed();
+ }
+ }
+ return result;
+}
+
+QByteArray getCallbackSignature(const char *signal, QObject *receiver,
+ PyObject *callback, bool encodeName)
+{
+ QByteArray functionName;
+ qsizetype numArgs = -1;
+
+ const auto slotArgs = extractFunctionArgumentsFromSlot(callback);
+ qsizetype useSelf = slotArgs.isMethod ? 1 : 0;
+
+ if (slotArgs.function != nullptr) {
+ numArgs = argCount(slotArgs).max;
+#ifdef PYPY_VERSION
+ } else if (Py_TYPE(callback) == PepBuiltinMethod_TypePtr) {
+ // PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction.
+ Shiboken::AutoDecRef temp(PyObject_GetAttr(callback, Shiboken::PyMagicName::name()));
+ functionName = Shiboken::String::toCString(temp);
+ useSelf = true;
+
+ if (receiver) {
+ // Search for signature on metaobject
+ const QMetaObject *mo = receiver->metaObject();
+ QByteArray prefix(functionName);
+ prefix += '(';
+ for (int i = 0; i < mo->methodCount(); i++) {
+ QMetaMethod me = mo->method(i);
+ if ((strncmp(me.methodSignature(), prefix, prefix.size()) == 0) &&
+ QMetaObject::checkConnectArgs(signal, me.methodSignature())) {
+ numArgs = me.parameterTypes().size() + useSelf;
+ break;
+ }
+ }
+ }
+#endif
+ } else if (PyCFunction_Check(callback)) {
+ const PyCFunctionObject *funcObj = reinterpret_cast<const PyCFunctionObject *>(callback);
+ functionName = PepCFunction_GET_NAMESTR(funcObj);
+ useSelf = PyCFunction_GET_SELF(funcObj) != nullptr ? 1 : 0;
+ const int flags = PyCFunction_GET_FLAGS(funcObj);
+
+ if (receiver) {
+ // Search for signature on metaobject
+ const QMetaObject *mo = receiver->metaObject();
+ QByteArray prefix(functionName);
+ prefix += '(';
+ for (int i = 0, count = mo->methodCount(); i < count; ++i) {
+ QMetaMethod me = mo->method(i);
+ if ((strncmp(me.methodSignature(), prefix, prefix.size()) == 0) &&
+ QMetaObject::checkConnectArgs(signal, me.methodSignature())) {
+ numArgs = me.parameterTypes().size() + useSelf;
+ break;
+ }
+ }
+ }
+
+ if (numArgs == -1) {
+ if (flags & METH_VARARGS)
+ numArgs = -1;
+ else if (flags & METH_NOARGS)
+ numArgs = 0;
+ }
+ } else if (PyCallable_Check(callback)) {
+ functionName = "__callback" + QByteArray::number(quintptr(callback));
+ }
+
+ if (functionName.isEmpty() && slotArgs.functionName != nullptr)
+ functionName = Shiboken::String::toCString(slotArgs.functionName);
+ Q_ASSERT(!functionName.isEmpty());
+
+ if (functionName.startsWith('<') && functionName.endsWith('>')) { // fix "<lambda>"
+ functionName[0] = '_';
+ functionName[functionName.size() - 1] = '_';
+ }
+ QByteArray signature = encodeName ? codeCallbackName(callback, functionName) : functionName;
+ QByteArrayList args = getArgsFromSignature(signal);
+
+ signature.append(u'(');
+ if (numArgs != -1) {
+ while (!args.isEmpty() && (args.size() > (numArgs - useSelf)))
+ args.removeLast();
+ }
+ signature.append(args.join(','));
+ signature.append(')');
+
+ return signature;
+}
+
+bool isQtSignal(const char *signal)
+{
+ return (signal && signal[0] == QT_SIGNAL_SENTINEL);
+}
+
+bool checkQtSignal(const char *signal)
+{
+ if (!isQtSignal(signal)) {
+ PyErr_SetString(PyExc_TypeError, "Use the function PySide6.QtCore.SIGNAL on signals");
+ return false;
+ }
+ return true;
+}
+
+QByteArray codeCallbackName(PyObject *callback, const QByteArray &funcName)
+{
+ if (PyMethod_Check(callback)) {
+ PyObject *self = PyMethod_GET_SELF(callback);
+ PyObject *func = PyMethod_GET_FUNCTION(callback);
+ return funcName + QByteArray::number(quint64(self), 16) + QByteArray::number(quint64(func), 16);
+ }
+ // PYSIDE-1523: Handle the compiled case.
+ if (PySide::isCompiledMethod(callback)) {
+ // Not retaining references inline with what PyMethod_GET_(SELF|FUNC) does.
+ Shiboken::AutoDecRef self(PyObject_GetAttr(callback, PySide::PySideName::im_self()));
+ Shiboken::AutoDecRef func(PyObject_GetAttr(callback, PySide::PySideName::im_func()));
+ return funcName + QByteArray::number(quint64(self), 16) + QByteArray::number(quint64(func), 16);
+ }
+ return funcName + QByteArray::number(quint64(callback), 16);
+}
+
+QByteArray voidType()
+{
+ return QByteArrayLiteral("void");
+}
+
+} //namespace PySide::Signal
diff --git a/sources/pyside6/libpyside/pysidesignal.h b/sources/pyside6/libpyside/pysidesignal.h
new file mode 100644
index 000000000..7493f94b5
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidesignal.h
@@ -0,0 +1,152 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_SIGNAL_H
+#define PYSIDE_SIGNAL_H
+
+#include <pysidemacros.h>
+
+#include <sbkpython.h>
+#include <basewrapper.h>
+
+#include <QtCore/QList>
+#include <QtCore/QMetaMethod>
+
+QT_BEGIN_NAMESPACE
+struct QMetaObject;
+class QObject;
+QT_END_NAMESPACE
+
+extern "C"
+{
+ extern PYSIDE_API PyTypeObject *PySideSignal_TypeF(void);
+ extern PYSIDE_API PyTypeObject *PySideSignalInstance_TypeF(void);
+
+ // Internal object
+ struct PYSIDE_API PySideSignal;
+
+ struct PySideSignalInstancePrivate;
+ struct PYSIDE_API PySideSignalInstance
+ {
+ PyObject_HEAD
+ PySideSignalInstancePrivate *d;
+ bool deleted;
+ };
+}; // extern "C"
+
+namespace PySide::Signal {
+
+/**
+ * This function checks for the PySideSignal type.
+ *
+ * @param pyObj
+ * @return whether pyObj is a PySideSignal
+ **/
+PYSIDE_API bool checkType(PyObject *pyObj);
+
+/**
+ * This function checks for the PySideSignalInstanceType type.
+ *
+ * @param pyObj
+ * @return Whether pyObj is a PySideSignalInstance
+ **/
+PYSIDE_API bool checkInstanceType(PyObject *pyObj);
+
+/**
+ * Register all C++ signals of a QObject on Python type.
+ */
+PYSIDE_API void registerSignals(PyTypeObject *pyObj, const QMetaObject *metaObject);
+
+/**
+ * This function creates a Signal object which stays attached to QObject class based on a list of QMetaMethods
+ *
+ * @param source of the Signal to be registered on meta object
+ * @param methods a list of QMetaMethod wich contains the supported signature
+ * @return Return a new reference to PyObject* of type PySideSignal
+ **/
+PYSIDE_API PySideSignalInstance *newObjectFromMethod(PyObject *source, const QList<QMetaMethod> &methods);
+
+/**
+ * This function initializes the Signal object by creating a PySideSignalInstance
+ *
+ * @param self a Signal object used as base to PySideSignalInstance
+ * @param name the name to be used on PySideSignalInstance
+ * @param object the PyObject where the signal will be attached
+ * @return Return a new reference to PySideSignalInstance
+ **/
+PYSIDE_API PySideSignalInstance *initialize(PySideSignal *signal, PyObject *name, PyObject *object);
+
+/**
+ * This function is used to retrieve the object in which the signal is attached
+ *
+ * @param self The Signal object
+ * @return Return the internal reference to the parent object of the signal
+ **/
+PYSIDE_API PyObject *getObject(PySideSignalInstance *signal);
+
+/**
+ * This function is used to retrieve the signal signature
+ *
+ * @param self The Signal object
+ * @return Return the signal signature
+ **/
+PYSIDE_API const char *getSignature(PySideSignalInstance *signal);
+
+struct EmitterData
+{
+ QObject *emitter = nullptr;
+ int methodIndex = -1;
+};
+
+/// A convenience to retrieve the emitter data from a signal instance
+///
+/// @param signal The Signal object
+/// @return Data structure
+PYSIDE_API EmitterData getEmitterData(PySideSignalInstance *signal);
+
+/**
+ * This function is used to retrieve the signal signature
+ *
+ * @param self The Signal object
+ * @return Return the signal signature
+ **/
+PYSIDE_API void updateSourceObject(PyObject *source);
+
+/**
+ * This function verifies if the signature is a QtSignal base on SIGNAL flag
+ * @param signature The signal signature
+ * @return Return true if this is a Qt Signal, otherwise return false
+ **/
+PYSIDE_API bool isQtSignal(const char *signature);
+
+/**
+ * This function is similar to isQtSignal, however if it fails, it'll raise a Python error instead.
+ *
+ * @param signature The signal signature
+ * @return Return true if this is a Qt Signal, otherwise return false
+ **/
+PYSIDE_API bool checkQtSignal(const char *signature);
+
+/**
+ * This function is used to retrieve the signature base on Signal and receiver callback
+ * @param signature The signal signature
+ * @param receiver The QObject which will receive the signal
+ * @param callback Callback function which will connect to the signal
+ * @param encodeName Used to specify if the returned signature will be encoded with Qt signal/slot style
+ * @return Return the callback signature
+ **/
+PYSIDE_API QByteArray getCallbackSignature(const char *signal, QObject *receiver,
+ PyObject *callback, bool encodeName);
+
+/**
+ * This function parses the signature and then returns a list of argument types.
+ *
+ * @param signature The signal signature
+ * @return Return true if this is a Qt Signal, otherwise return false
+ * @todo replace return type by QList<QByteArray>
+ **/
+QByteArrayList getArgsFromSignature(const char *signature);
+
+} // namespace PySide::Signal
+
+#endif
diff --git a/sources/pyside6/libpyside/pysidesignal_p.h b/sources/pyside6/libpyside/pysidesignal_p.h
new file mode 100644
index 000000000..55a9a7a70
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidesignal_p.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDE_QSIGNAL_P_H
+#define PYSIDE_QSIGNAL_P_H
+
+#include <sbkpython.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+
+struct PySideSignalData
+{
+ struct Signature
+ {
+ QByteArray signature; // ','-separated list of parameter types
+ unsigned short attributes;
+ short argCount;
+ };
+
+ QByteArray signalName;
+ QList<Signature> signatures;
+ QByteArrayList signalArguments;
+};
+
+extern "C"
+{
+ extern PyTypeObject *PySideSignal_TypeF(void);
+
+ struct PySideSignal {
+ PyObject_HEAD
+ PySideSignalData *data;
+ PyObject *homonymousMethod;
+ };
+
+ struct PySideSignalInstance;
+}; //extern "C"
+
+struct PySideSignalInstancePrivate
+{
+ QByteArray signalName;
+ QByteArray signature;
+ PyObject *source = nullptr;
+ PyObject *homonymousMethod = nullptr;
+ PySideSignalInstance *next = nullptr;
+ unsigned short attributes = 0;
+ short argCount = 0;
+};
+
+namespace PySide::Signal {
+
+ void init(PyObject *module);
+ bool connect(PyObject *source, const char *signal, PyObject *callback);
+ QByteArray getTypeName(PyObject *);
+ QByteArray codeCallbackName(PyObject *callback, const QByteArray &funcName);
+ QByteArray voidType();
+
+} // namespace PySide::Signal
+
+#endif
diff --git a/sources/pyside6/libpyside/pysideslot.cpp b/sources/pyside6/libpyside/pysideslot.cpp
new file mode 100644
index 000000000..fa7e89f42
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideslot.cpp
@@ -0,0 +1,183 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysidesignal_p.h"
+#include "pysideslot_p.h"
+#include "pysidestaticstrings.h"
+
+#include <shiboken.h>
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QString>
+#include <signature.h>
+
+using namespace Shiboken;
+
+struct SlotData
+{
+ QByteArray name;
+ QByteArray args;
+ QByteArray resultType;
+ QByteArray tag; // QMetaMethod::tag()
+};
+
+struct PySideSlot
+{
+ PyObject_HEAD
+ SlotData *slotData;
+};
+
+extern "C"
+{
+
+static void slotDataListDestructor(PyObject *o)
+{
+ delete PySide::Slot::dataListFromCapsule(o);
+}
+
+static int slotTpInit(PyObject *, PyObject *, PyObject *);
+static PyObject *slotCall(PyObject *, PyObject *, PyObject *);
+
+// Class Definition -----------------------------------------------
+
+static PyTypeObject *createSlotType()
+{
+ PyType_Slot PySideSlotType_slots[] = {
+ {Py_tp_call, reinterpret_cast<void *>(slotCall)},
+ {Py_tp_init, reinterpret_cast<void *>(slotTpInit)},
+ {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PySideSlotType_spec = {
+ "2:PySide6.QtCore.Slot",
+ sizeof(PySideSlot),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ PySideSlotType_slots,
+ };
+
+ return SbkType_FromSpec(&PySideSlotType_spec);
+}
+
+static PyTypeObject *PySideSlot_TypeF()
+{
+ static auto *type = createSlotType();
+ return type;
+}
+
+int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
+{
+ static PyObject *emptyTuple = nullptr;
+ static const char *kwlist[] = {"name", "result", "tag", nullptr};
+ char *argName = nullptr;
+ PyObject *argResult = nullptr;
+ char *tag = nullptr;
+
+ if (emptyTuple == nullptr)
+ emptyTuple = PyTuple_New(0);
+
+ if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sOs:QtCore.Slot",
+ const_cast<char **>(kwlist),
+ &argName, &argResult, &tag)) {
+ return -1;
+ }
+
+ PySideSlot *data = reinterpret_cast<PySideSlot *>(self);
+ if (!data->slotData)
+ data->slotData = new SlotData;
+ for(Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
+ PyObject *argType = PyTuple_GET_ITEM(args, i);
+ const auto typeName = PySide::Signal::getTypeName(argType);
+ if (typeName.isEmpty()) {
+ PyErr_Format(PyExc_TypeError, "Unknown signal argument type: %s", Py_TYPE(argType)->tp_name);
+ return -1;
+ }
+ if (!data->slotData->args.isEmpty())
+ data->slotData->args += ',';
+ data->slotData->args += typeName;
+ }
+
+ if (argName)
+ data->slotData->name = argName;
+
+ if (tag)
+ data->slotData->tag = tag;
+
+ data->slotData->resultType = argResult
+ ? PySide::Signal::getTypeName(argResult) : PySide::Signal::voidType();
+
+ return 0;
+}
+
+PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PyObject *callback = nullptr;
+
+ if (!PyArg_UnpackTuple(args, "Slot.__call__", 1, 1, &callback))
+ return nullptr;
+ Py_INCREF(callback);
+
+ if (PyCallable_Check(callback)) {
+ PySideSlot *data = reinterpret_cast<PySideSlot *>(self);
+
+ if (!data->slotData)
+ data->slotData = new SlotData;
+
+ if (data->slotData->name.isEmpty()) {
+ // PYSIDE-198: Use PyObject_GetAttr instead of PepFunction_GetName to support Nuitka.
+ AutoDecRef funcName(PyObject_GetAttr(callback, PyMagicName::name()));
+ data->slotData->name = funcName.isNull() ? "<no name>" : String::toCString(funcName);
+ }
+ const QByteArray returnType = QMetaObject::normalizedType(data->slotData->resultType);
+ const QByteArray signature = data->slotData->name + '(' + data->slotData->args + ')';
+
+ PyObject *pySlotName = PySide::PySideMagicName::slot_list_attr();
+ PySide::Slot::DataList *entryList = nullptr;
+ if (PyObject_HasAttr(callback, pySlotName)) {
+ auto *capsule = PyObject_GetAttr(callback, pySlotName);
+ entryList = PySide::Slot::dataListFromCapsule(capsule);
+ } else {
+ entryList = new PySide::Slot::DataList{};
+ auto *capsule = PyCapsule_New(entryList, nullptr /* name */, slotDataListDestructor);
+ Py_INCREF(capsule);
+ PyObject_SetAttr(callback, pySlotName, capsule);
+ }
+ entryList->append({signature, returnType, data->slotData->tag});
+
+ //clear data
+ delete data->slotData;
+ data->slotData = nullptr;
+ }
+ return callback;
+}
+
+} // extern "C"
+
+namespace PySide::Slot {
+
+DataList *dataListFromCapsule(PyObject *capsule)
+{
+ if (capsule != nullptr && PyCapsule_CheckExact(capsule) != 0) {
+ if (void *v = PyCapsule_GetPointer(capsule, nullptr))
+ return reinterpret_cast<DataList *>(v);
+ }
+ return nullptr;
+}
+
+static const char *Slot_SignatureStrings[] = {
+ "PySide6.QtCore.Slot(self,*types:type,name:str=nullptr,result:type=nullptr)",
+ "PySide6.QtCore.Slot.__call__(self,function:typing.Callable)->typing.Any",
+ nullptr}; // Sentinel
+
+void init(PyObject *module)
+{
+ if (InitSignatureStrings(PySideSlot_TypeF(), Slot_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideSlot_TypeF());
+ PyModule_AddObject(module, "Slot", reinterpret_cast<PyObject *>(PySideSlot_TypeF()));
+}
+
+} // namespace PySide::Slot
diff --git a/sources/pyside6/libpyside/pysideslot_p.h b/sources/pyside6/libpyside/pysideslot_p.h
new file mode 100644
index 000000000..9852301ee
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideslot_p.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef PYSIDE_SLOT_P_H
+#define PYSIDE_SLOT_P_H
+
+#include <sbkpython.h>
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qlist.h>
+
+namespace PySide::Slot {
+
+struct Data {
+ QByteArray signature;
+ QByteArray resultType;
+ QByteArray tag; // QMetaMethod::tag()
+};
+
+// This list is set as an attribute named PySide::PySideMagicName::slot_list_attr()
+// by the decorator for usage by MetaObjectBuilder.
+using DataList = QList<Data>;
+
+DataList *dataListFromCapsule(PyObject *capsule);
+
+void init(PyObject* module);
+} // namespace PySide::Slot
+
+#endif // PYSIDE_SLOT_P_H
diff --git a/sources/pyside6/libpyside/pysidestaticstrings.cpp b/sources/pyside6/libpyside/pysidestaticstrings.cpp
new file mode 100644
index 000000000..3bddc84c2
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidestaticstrings.cpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysidestaticstrings.h"
+#include <sbkstring.h>
+
+#define STATIC_STRING_IMPL(funcName, value) \
+PyObject *funcName() \
+{ \
+ static PyObject *const s = Shiboken::String::createStaticString(value); \
+ return s; \
+}
+
+namespace PySide
+{
+namespace PySideName
+{
+STATIC_STRING_IMPL(qtConnect, "connect")
+STATIC_STRING_IMPL(qtDisconnect, "disconnect")
+STATIC_STRING_IMPL(qtEmit, "emit")
+STATIC_STRING_IMPL(dict_ring, "dict_ring")
+STATIC_STRING_IMPL(fset, "fset")
+STATIC_STRING_IMPL(im_func, "im_func")
+STATIC_STRING_IMPL(im_self, "im_self")
+STATIC_STRING_IMPL(name, "name")
+STATIC_STRING_IMPL(orig_dict, "orig_dict")
+STATIC_STRING_IMPL(parameters, "parameters")
+STATIC_STRING_IMPL(property, "property")
+STATIC_STRING_IMPL(select_id, "select_id")
+} // namespace PyName
+namespace PySideMagicName
+{
+STATIC_STRING_IMPL(code, "__code__")
+STATIC_STRING_IMPL(doc, "__doc__")
+STATIC_STRING_IMPL(func, "__func__")
+STATIC_STRING_IMPL(name, "__name__")
+STATIC_STRING_IMPL(property_methods, "__property_methods__")
+STATIC_STRING_IMPL(slot_list_attr, "_slots")
+} // namespace PyMagicName
+} // namespace PySide
diff --git a/sources/pyside6/libpyside/pysidestaticstrings.h b/sources/pyside6/libpyside/pysidestaticstrings.h
new file mode 100644
index 000000000..b4bc61800
--- /dev/null
+++ b/sources/pyside6/libpyside/pysidestaticstrings.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDESTRINGS_H
+#define PYSIDESTRINGS_H
+
+#include <sbkpython.h>
+#include <pysidemacros.h>
+
+namespace PySide
+{
+namespace PySideName
+{
+PYSIDE_API PyObject *qtConnect();
+PYSIDE_API PyObject *qtDisconnect();
+PYSIDE_API PyObject *qtEmit();
+PYSIDE_API PyObject *dict_ring();
+PYSIDE_API PyObject *fset();
+PYSIDE_API PyObject *im_func();
+PYSIDE_API PyObject *im_self();
+PYSIDE_API PyObject *name();
+PYSIDE_API PyObject *orig_dict();
+PYSIDE_API PyObject *parameters();
+PYSIDE_API PyObject *property();
+PYSIDE_API PyObject *select_id();
+} // namespace PyName
+namespace PySideMagicName
+{
+PYSIDE_API PyObject *code();
+PYSIDE_API PyObject *doc();
+PYSIDE_API PyObject *func();
+PYSIDE_API PyObject *name();
+PYSIDE_API PyObject *property_methods();
+PYSIDE_API PyObject *slot_list_attr();
+} // namespace PyMagicName
+} // namespace PySide
+
+#endif // PYSIDESTRINGS_H
diff --git a/sources/pyside6/libpyside/pysideutils.h b/sources/pyside6/libpyside/pysideutils.h
new file mode 100644
index 000000000..47c2f2c1b
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideutils.h
@@ -0,0 +1,69 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEUTILS_H
+#define PYSIDEUTILS_H
+
+#include <sbkpython.h>
+
+#include <pysidemacros.h>
+
+#include <QtCore/qtclasshelpermacros.h>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+QT_FORWARD_DECLARE_CLASS(QString)
+QT_FORWARD_DECLARE_CLASS(QStringView)
+
+namespace PySide
+{
+
+/// Check if self inherits from class_name
+/// \param self Python object
+/// \param class_name strict with the class name
+/// \return Returns true if self object inherits from class_name, otherwise returns false
+PYSIDE_API bool inherits(PyTypeObject *self, const char *class_name);
+
+/// Given A PyObject representing Unicode data, returns an equivalent QString.
+PYSIDE_API QString pyUnicodeToQString(PyObject *str);
+
+/// Given a QString, return the PyObject repeesenting Unicode data.
+PYSIDE_API PyObject *qStringToPyUnicode(QStringView s);
+
+/// Given A PyObject representing ASCII or Unicode data, returns an equivalent QString.
+PYSIDE_API QString pyStringToQString(PyObject *str);
+
+/// Provide an efficient, correct PathLike interface.
+PYSIDE_API QString pyPathToQString(PyObject *path);
+
+PYSIDE_API bool isCompiledMethod(PyObject *callback);
+
+struct debugPyTypeObject
+{
+ PYSIDE_API explicit debugPyTypeObject(const PyTypeObject *o) noexcept;
+
+ const PyTypeObject *m_object;
+};
+
+PYSIDE_API QDebug operator<<(QDebug debug, const debugPyTypeObject &o);
+
+struct debugPyObject
+{
+ PYSIDE_API explicit debugPyObject(PyObject *o) noexcept;
+
+ PyObject *m_object;
+};
+
+PYSIDE_API QDebug operator<<(QDebug debug, const debugPyObject &o);
+
+struct debugPyBuffer
+{
+ PYSIDE_API explicit debugPyBuffer(Py_buffer *b) noexcept;
+
+ Py_buffer *m_buffer;
+};
+
+PYSIDE_API QDebug operator<<(QDebug debug, const debugPyBuffer &b);
+
+} //namespace PySide
+
+#endif // PYSIDESTRING_H
diff --git a/sources/pyside6/libpyside/pysideweakref.cpp b/sources/pyside6/libpyside/pysideweakref.cpp
new file mode 100644
index 000000000..5f3ca59e4
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideweakref.cpp
@@ -0,0 +1,82 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideweakref.h"
+
+#include <sbkpython.h>
+#include <shiboken.h>
+
+struct PySideCallableObject {
+ PyObject_HEAD
+ /* Type-specific fields go here. */
+ PySideWeakRefFunction weakref_func;
+ void *user_data;
+};
+
+static PyObject *CallableObject_call(PyObject *callable_object, PyObject *args, PyObject *kw);
+
+static PyTypeObject *createCallableObjectType()
+{
+ PyType_Slot PySideCallableObjectType_slots[] = {
+ {Py_tp_call, reinterpret_cast<void *>(CallableObject_call)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PySideCallableObjectType_spec = {
+ "1:PySide.Callable",
+ sizeof(PySideCallableObject),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ PySideCallableObjectType_slots,
+ };
+
+ return SbkType_FromSpec(&PySideCallableObjectType_spec);
+}
+
+static PyTypeObject *PySideCallableObject_TypeF()
+{
+ static auto *type = createCallableObjectType();
+ return type;
+}
+
+static PyObject *CallableObject_call(PyObject *callable_object, PyObject *args, PyObject * /* kw */)
+{
+ PySideCallableObject *obj = reinterpret_cast<PySideCallableObject *>(callable_object);
+ obj->weakref_func(obj->user_data);
+
+ Py_XDECREF(PyTuple_GET_ITEM(args, 0)); //kill weak ref object
+ Py_RETURN_NONE;
+}
+
+namespace PySide::WeakRef {
+
+PyObject *create(PyObject *obj, PySideWeakRefFunction func, void *userData)
+{
+ if (obj == Py_None)
+ return nullptr;
+
+ auto *callableObject_Type = PySideCallableObject_TypeF();
+ auto *callableObject_PyObject = reinterpret_cast<PyObject *>(callableObject_Type);
+ if (callableObject_PyObject->ob_type == nullptr) {
+ callableObject_PyObject->ob_type = &PyType_Type;
+ PyType_Ready(callableObject_Type);
+ }
+
+ PyTypeObject *type = PySideCallableObject_TypeF();
+ PySideCallableObject *callable = PyObject_New(PySideCallableObject, type);
+ if (!callable || PyErr_Occurred())
+ return nullptr;
+
+ PyObject *weak = PyWeakref_NewRef(obj, reinterpret_cast<PyObject *>(callable));
+ if (!weak || PyErr_Occurred())
+ return nullptr;
+
+ callable->weakref_func = func;
+ callable->user_data = userData;
+ Py_DECREF(callable); // PYSIDE-79: after decref the callable is undefined (theoretically)
+
+ return reinterpret_cast<PyObject *>(weak);
+}
+
+} // namespace PySide::WeakRef
diff --git a/sources/pyside6/libpyside/pysideweakref.h b/sources/pyside6/libpyside/pysideweakref.h
new file mode 100644
index 000000000..e29c73455
--- /dev/null
+++ b/sources/pyside6/libpyside/pysideweakref.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef __PYSIDEWEAKREF__
+#define __PYSIDEWEAKREF__
+
+#include <pysidemacros.h>
+#include <sbkpython.h>
+
+using PySideWeakRefFunction = void (*)(void *userData);
+
+namespace PySide::WeakRef {
+
+PYSIDE_API PyObject* create(PyObject* ob, PySideWeakRefFunction func, void* userData);
+
+} // namespace PySide::WeakRef
+
+#endif
diff --git a/sources/pyside6/libpyside/qobjectconnect.cpp b/sources/pyside6/libpyside/qobjectconnect.cpp
new file mode 100644
index 000000000..3c5b75953
--- /dev/null
+++ b/sources/pyside6/libpyside/qobjectconnect.cpp
@@ -0,0 +1,336 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qobjectconnect.h"
+#include "pysideqobject.h"
+#include "pysideqslotobject_p.h"
+#include "pysidesignal.h"
+#include "pysideutils.h"
+#include "signalmanager.h"
+
+#include "shiboken.h"
+#include "basewrapper.h"
+#include "autodecref.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QMetaMethod>
+#include <QtCore/QObject>
+
+#include <QtCore/private/qobject_p.h>
+
+#include <string_view>
+
+static bool isMethodDecorator(PyObject *method, bool is_pymethod, PyObject *self)
+{
+ Shiboken::AutoDecRef methodName(PyObject_GetAttr(method, Shiboken::PyMagicName::name()));
+ if (!PyObject_HasAttr(self, methodName))
+ return true;
+ Shiboken::AutoDecRef otherMethod(PyObject_GetAttr(self, methodName));
+
+ // PYSIDE-1523: Each could be a compiled method or a normal method here, for the
+ // compiled ones we can use the attributes.
+ PyObject *function1;
+ if (PyMethod_Check(otherMethod.object())) {
+ function1 = PyMethod_GET_FUNCTION(otherMethod.object());
+ } else {
+ function1 = PyObject_GetAttr(otherMethod.object(), Shiboken::PyName::im_func());
+ if (function1 == nullptr)
+ return false;
+ Py_DECREF(function1);
+ // Not retaining a reference in line with what PyMethod_GET_FUNCTION does.
+ }
+
+ PyObject *function2;
+ if (is_pymethod) {
+ function2 = PyMethod_GET_FUNCTION(method);
+ } else {
+ function2 = PyObject_GetAttr(method, Shiboken::PyName::im_func());
+ Py_DECREF(function2);
+ // Not retaining a reference in line with what PyMethod_GET_FUNCTION does.
+ }
+
+ return function1 != function2;
+}
+
+struct GetReceiverResult
+{
+ QObject *receiver = nullptr;
+ PyObject *self = nullptr;
+ QByteArray callbackSig;
+ bool usingGlobalReceiver = false;
+ int slotIndex = -1;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const GetReceiverResult &r)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "GetReceiverResult(receiver=" << r.receiver << ", self=" << r.self
+ << ", sig=\"" << r.callbackSig << "\", slotIndex=" << r.slotIndex
+ << ", usingGlobalReceiver=" << r.usingGlobalReceiver << ')';
+ return d;
+}
+#endif // QT_NO_DEBUG_STREAM
+
+static const char *getQualifiedName(PyObject *ob)
+{
+ Shiboken::AutoDecRef qualNameP(PyObject_GetAttr(ob, Shiboken::PyMagicName::qualname()));
+ return qualNameP.isNull()
+ ? nullptr : Shiboken::String::toCString(qualNameP.object());
+}
+
+// Determine whether a method is declared in a class using qualified name lookup.
+static bool isDeclaredIn(PyObject *method, const char *className)
+{
+ bool result = false;
+ if (auto *qualifiedNameC = getQualifiedName(PyMethod_Function(method))) {
+ std::string_view qualifiedName(qualifiedNameC);
+ if (const auto dot = qualifiedName.rfind('.'); dot != std::string::npos)
+ result = qualifiedName.substr(0, dot) == className;
+ }
+ return result;
+}
+
+static GetReceiverResult getReceiver(QObject *source, const char *signal,
+ PyObject *callback)
+{
+ GetReceiverResult result;
+
+ bool forceGlobalReceiver = false;
+ if (PyMethod_Check(callback)) {
+ result.self = PyMethod_GET_SELF(callback);
+ result.receiver = PySide::convertToQObject(result.self, false);
+ forceGlobalReceiver = isMethodDecorator(callback, true, result.self);
+#ifdef PYPY_VERSION
+ } else if (Py_TYPE(callback) == PepBuiltinMethod_TypePtr) {
+ result.self = PyObject_GetAttrString(callback, "__self__");
+ Py_DECREF(result.self);
+ result.receiver = PySide::convertToQObject(result.self, false);
+#endif
+ } else if (PyCFunction_Check(callback)) {
+ result.self = PyCFunction_GET_SELF(callback);
+ result.receiver = PySide::convertToQObject(result.self, false);
+ } else if (PySide::isCompiledMethod(callback)) {
+ result.self = PyObject_GetAttr(callback, Shiboken::PyName::im_self());
+ Py_DECREF(result.self);
+ result.receiver = PySide::convertToQObject(result.self, false);
+ forceGlobalReceiver = isMethodDecorator(callback, false, result.self);
+ } else if (PyCallable_Check(callback)) {
+ // Ok, just a callable object
+ result.receiver = nullptr;
+ result.self = nullptr;
+ }
+
+ result.usingGlobalReceiver = !result.receiver || forceGlobalReceiver;
+
+ // Check if this callback is a overwrite of a non-virtual Qt slot (pre-Jira bug 1019).
+ // Make it possible to connect to a MyWidget.show() although QWidget.show()
+ // is a non-virtual slot which would be found by QMetaObject search.
+ // FIXME PYSIDE7: This is arguably a bit of a misguided "feature", remove?
+ if (!result.usingGlobalReceiver && result.receiver && result.self) {
+ result.callbackSig =
+ PySide::Signal::getCallbackSignature(signal, result.receiver, callback,
+ result.usingGlobalReceiver);
+ const QMetaObject *metaObject = result.receiver->metaObject();
+ result.slotIndex = metaObject->indexOfSlot(result.callbackSig.constData());
+ if (PyMethod_Check(callback) != 0 && result.slotIndex != -1
+ && result.slotIndex < metaObject->methodOffset()) {
+ // Find the class in which the slot is declared.
+ while (result.slotIndex < metaObject->methodOffset())
+ metaObject = metaObject->superClass();
+ // If the Python callback is not declared in the same class, assume it is
+ // a Python override. Resort to global receiver (PYSIDE-2418).
+ if (!isDeclaredIn(callback, metaObject->className()))
+ result.usingGlobalReceiver = true;
+ }
+ }
+
+ const auto receiverThread = result.receiver ? result.receiver->thread() : nullptr;
+
+ if (result.usingGlobalReceiver) {
+ PySide::SignalManager &signalManager = PySide::SignalManager::instance();
+ result.receiver = signalManager.globalReceiver(source, callback, result.receiver);
+ // PYSIDE-1354: Move the global receiver to the original receivers's thread
+ // so that autoconnections work correctly.
+ if (receiverThread && receiverThread != result.receiver->thread())
+ result.receiver->moveToThread(receiverThread);
+ result.callbackSig =
+ PySide::Signal::getCallbackSignature(signal, result.receiver, callback,
+ result.usingGlobalReceiver);
+ const QMetaObject *metaObject = result.receiver->metaObject();
+ result.slotIndex = metaObject->indexOfSlot(result.callbackSig.constData());
+ }
+
+ return result;
+}
+
+namespace PySide
+{
+class FriendlyQObject : public QObject // Make protected connectNotify() accessible.
+{
+public:
+ using QObject::connectNotify;
+ using QObject::disconnectNotify;
+};
+
+QMetaObject::Connection qobjectConnect(QObject *source, const char *signal,
+ QObject *receiver, const char *slot,
+ Qt::ConnectionType type)
+{
+ if (!signal || !slot || !PySide::Signal::checkQtSignal(signal))
+ return {};
+
+ if (!PySide::SignalManager::registerMetaMethod(source, signal + 1, QMetaMethod::Signal))
+ return {};
+
+ const auto methodType = PySide::Signal::isQtSignal(slot)
+ ? QMetaMethod::Signal : QMetaMethod::Slot;
+ PySide::SignalManager::registerMetaMethod(receiver, slot + 1, methodType);
+ return QObject::connect(source, signal, receiver, slot, type);
+}
+
+QMetaObject::Connection qobjectConnect(QObject *source, QMetaMethod signal,
+ QObject *receiver, QMetaMethod slot,
+ Qt::ConnectionType type)
+{
+ return qobjectConnect(source, signal.methodSignature().constData(),
+ receiver, slot.methodSignature().constData(), type);
+}
+
+QMetaObject::Connection qobjectConnectCallback(QObject *source, const char *signal,
+ PyObject *callback, Qt::ConnectionType type)
+{
+ if (!signal || !PySide::Signal::checkQtSignal(signal))
+ return {};
+
+ const int signalIndex =
+ PySide::SignalManager::registerMetaMethodGetIndex(source, signal + 1,
+ QMetaMethod::Signal);
+ if (signalIndex == -1)
+ return {};
+
+ // Extract receiver from callback
+ const GetReceiverResult receiver = getReceiver(source, signal + 1, callback);
+ if (receiver.receiver == nullptr && receiver.self == nullptr)
+ return {};
+
+ int slotIndex = receiver.slotIndex;
+
+ PySide::SignalManager &signalManager = PySide::SignalManager::instance();
+ if (slotIndex == -1) {
+ if (!receiver.usingGlobalReceiver && receiver.self
+ && !Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject *>(receiver.self))) {
+ qWarning("You can't add dynamic slots on an object originated from C++.");
+ if (receiver.usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver.receiver);
+
+ return {};
+ }
+
+ const char *slotSignature = receiver.callbackSig.constData();
+ slotIndex = receiver.usingGlobalReceiver
+ ? signalManager.globalReceiverSlotIndex(receiver.receiver, slotSignature)
+ : PySide::SignalManager::registerMetaMethodGetIndex(receiver.receiver, slotSignature,
+ QMetaMethod::Slot);
+
+ if (slotIndex == -1) {
+ if (receiver.usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver.receiver);
+
+ return {};
+ }
+ }
+
+ QMetaObject::Connection connection{};
+ Py_BEGIN_ALLOW_THREADS // PYSIDE-2367, prevent threading deadlocks with connectNotify()
+ connection = QMetaObject::connect(source, signalIndex, receiver.receiver, slotIndex, type);
+ Py_END_ALLOW_THREADS
+ if (!connection) {
+ if (receiver.usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver.receiver);
+ return {};
+ }
+
+ Q_ASSERT(receiver.receiver);
+ if (receiver.usingGlobalReceiver)
+ signalManager.notifyGlobalReceiver(receiver.receiver);
+
+ const QMetaMethod signalMethod = receiver.receiver->metaObject()->method(signalIndex);
+ static_cast<FriendlyQObject *>(source)->connectNotify(signalMethod);
+ return connection;
+}
+
+QMetaObject::Connection qobjectConnectCallback(QObject *source, const char *signal, QObject *context,
+ PyObject *callback, Qt::ConnectionType type)
+{
+ if (!signal || !PySide::Signal::checkQtSignal(signal))
+ return {};
+
+ const int signalIndex =
+ PySide::SignalManager::registerMetaMethodGetIndex(source, signal + 1,
+ QMetaMethod::Signal);
+ if (signalIndex == -1)
+ return {};
+
+ // Extract receiver from callback
+ const GetReceiverResult receiver = getReceiver(source, signal + 1, callback);
+ if (receiver.receiver == nullptr && receiver.self == nullptr)
+ return {};
+
+ PySide::SignalManager &signalManager = PySide::SignalManager::instance();
+
+ PySideQSlotObject *slotObject = new PySideQSlotObject(callback);
+
+ QMetaObject::Connection connection{};
+ Py_BEGIN_ALLOW_THREADS // PYSIDE-2367, prevent threading deadlocks with connectNotify()
+ connection = QObjectPrivate::connect(source, signalIndex, context, slotObject, type);
+ Py_END_ALLOW_THREADS
+ if (!connection) {
+ if (receiver.usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver.receiver);
+ return {};
+ }
+
+ Q_ASSERT(receiver.receiver);
+ if (receiver.usingGlobalReceiver)
+ signalManager.notifyGlobalReceiver(receiver.receiver);
+
+ const QMetaMethod signalMethod = receiver.receiver->metaObject()->method(signalIndex);
+ static_cast<FriendlyQObject *>(source)->connectNotify(signalMethod);
+ return connection;
+}
+
+bool qobjectDisconnectCallback(QObject *source, const char *signal, PyObject *callback)
+{
+ if (!PySide::Signal::checkQtSignal(signal))
+ return false;
+
+ // Extract receiver from callback
+ const GetReceiverResult receiver = getReceiver(nullptr, signal, callback);
+ if (receiver.receiver == nullptr && receiver.self == nullptr)
+ return false;
+
+ const int signalIndex = source->metaObject()->indexOfSignal(signal + 1);
+ const int slotIndex = receiver.slotIndex;
+
+ bool ok{};
+ Py_BEGIN_ALLOW_THREADS // PYSIDE-2367, prevent threading deadlocks with disconnectNotify()
+ ok = QMetaObject::disconnectOne(source, signalIndex, receiver.receiver, slotIndex);
+ Py_END_ALLOW_THREADS
+ if (!ok)
+ return false;
+
+ Q_ASSERT(receiver.receiver);
+ const QMetaMethod slotMethod = receiver.receiver->metaObject()->method(slotIndex);
+ static_cast<FriendlyQObject *>(source)->disconnectNotify(slotMethod);
+
+ if (receiver.usingGlobalReceiver) { // might delete the receiver
+ PySide::SignalManager &signalManager = PySide::SignalManager::instance();
+ signalManager.releaseGlobalReceiver(source, receiver.receiver);
+ }
+ return true;
+}
+
+} // namespace PySide
diff --git a/sources/pyside6/libpyside/qobjectconnect.h b/sources/pyside6/libpyside/qobjectconnect.h
new file mode 100644
index 000000000..c99b8006e
--- /dev/null
+++ b/sources/pyside6/libpyside/qobjectconnect.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QOBJECTCONNECT_H
+#define QOBJECTCONNECT_H
+
+#include "pysidemacros.h"
+
+#include <sbkpython.h>
+
+#include <QtCore/QMetaObject>
+
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_CLASS(QMetaMethod)
+
+namespace PySide
+{
+
+/// Helpers for QObject::connect(): Make a string-based connection
+PYSIDE_API QMetaObject::Connection
+ qobjectConnect(QObject *source, const char *signal,
+ QObject *receiver, const char *slot,
+ Qt::ConnectionType type);
+
+/// Helpers for QObject::connect(): Make a connection based on QMetaMethod
+PYSIDE_API QMetaObject::Connection
+ qobjectConnect(QObject *source, QMetaMethod signal,
+ QObject *receiver, QMetaMethod slot,
+ Qt::ConnectionType type);
+
+/// Helpers for QObject::connect(): Make a connection to a Python callback
+PYSIDE_API QMetaObject::Connection
+ qobjectConnectCallback(QObject *source, const char *signal,
+ PyObject *callback, Qt::ConnectionType type);
+
+/// Helpers for QObject::connect(): Make a connection to a Python callback and a context object
+PYSIDE_API QMetaObject::Connection
+ qobjectConnectCallback(QObject *source, const char *signal, QObject *context,
+ PyObject *callback, Qt::ConnectionType type);
+
+/// Helpers for QObject::disconnect(): Disconnect a Python callback
+PYSIDE_API bool qobjectDisconnectCallback(QObject *source, const char *signal,
+ PyObject *callback);
+
+} // namespace PySide
+
+#endif // QOBJECTCONNECT_H
diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp
new file mode 100644
index 000000000..f4c2bbf43
--- /dev/null
+++ b/sources/pyside6/libpyside/signalmanager.cpp
@@ -0,0 +1,815 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "signalmanager.h"
+#include "pysidesignal.h"
+#include "pysidelogging_p.h"
+#include "pysideproperty.h"
+#include "pysideproperty_p.h"
+#include "pysidecleanup.h"
+#include "pyside_p.h"
+#include "dynamicqmetaobject.h"
+#include "pysidemetafunction_p.h"
+#include "pysidestaticstrings.h"
+
+#include <autodecref.h>
+#include <basewrapper.h>
+#include <bindingmanager.h>
+#include <gilstate.h>
+#include <sbkconverter.h>
+#include <sbkstring.h>
+#include <sbkstaticstrings.h>
+#include <sbkerrors.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QByteArrayView>
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QTimerEvent>
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+
+using namespace Qt::StringLiterals;
+
+#if QSLOT_CODE != 1 || QSIGNAL_CODE != 2
+#error QSLOT_CODE and/or QSIGNAL_CODE changed! change the hardcoded stuff to the correct value!
+#endif
+#define PYSIDE_SLOT '1'
+#define PYSIDE_SIGNAL '2'
+#include "globalreceiverv2.h"
+
+static PyObject *metaObjectAttr = nullptr;
+static PyObject *parseArguments(const QMetaMethod &method, void **args);
+
+static bool qAppRunning = false;
+
+static void destroyMetaObject(PyObject *obj)
+{
+ void *ptr = PyCapsule_GetPointer(obj, nullptr);
+ auto meta = reinterpret_cast<PySide::MetaObjectBuilder *>(ptr);
+ SbkObject *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(meta);
+ if (wrapper)
+ Shiboken::BindingManager::instance().releaseWrapper(wrapper);
+ delete meta;
+}
+
+static const char *metaCallName(QMetaObject::Call call)
+{
+ static const QHash<QMetaObject::Call, const char *> mapping = {
+ {QMetaObject::InvokeMetaMethod, "InvokeMetaMethod"},
+ {QMetaObject::ReadProperty, "ReadProperty"},
+ {QMetaObject::WriteProperty, "WriteProperty"},
+ {QMetaObject::ResetProperty, "ResetProperty"},
+ {QMetaObject::CreateInstance, "CreateInstance"},
+ {QMetaObject::IndexOfMethod, "IndexOfMethod"},
+ {QMetaObject::RegisterPropertyMetaType, "RegisterPropertyMetaType"},
+ {QMetaObject::RegisterMethodArgumentMetaType, "RegisterMethodArgumentMetaType"},
+ {QMetaObject::BindableProperty, "BindableProperty"},
+ {QMetaObject::CustomCall, "CustomCall"}
+ };
+ auto it = mapping.constFind(call);
+ return it != mapping.constEnd() ? it.value() : "<Unknown>";
+}
+
+static QByteArray methodSignature(const QMetaMethod &method)
+{
+ QByteArray result;
+ if (auto *t = method.typeName()) {
+ result += t;
+ result += ' ';
+ }
+ result += method.methodSignature();
+ return result;
+}
+
+static QByteArray msgCannotConvertParameter(const QMetaMethod &method, qsizetype p)
+{
+ return "Cannot call meta function \""_ba + methodSignature(method)
+ + "\" because parameter " + QByteArray::number(p) + " of type \""_ba
+ + method.parameterTypeName(p) + "\" cannot be converted."_ba;
+}
+
+static QByteArray msgCannotConvertReturn(const QMetaMethod &method)
+{
+ return "The return value of \""_ba + methodSignature(method) + "\" cannot be converted."_ba;
+}
+
+namespace PySide {
+
+PyObjectWrapper::PyObjectWrapper()
+ :m_me(Py_None)
+{
+ // PYSIDE-813: When PYSIDE-164 was solved by adding some thread allowance,
+ // this code was no longer protected. It was hard to find this connection.
+ // See the website https://bugreports.qt.io/browse/PYSIDE-813 for details.
+ Shiboken::GilState gil;
+ Py_XINCREF(m_me);
+}
+
+PyObjectWrapper::PyObjectWrapper(PyObject *me)
+ : m_me(me)
+{
+ Shiboken::GilState gil;
+ Py_XINCREF(m_me);
+}
+
+PyObjectWrapper::PyObjectWrapper(const PyObjectWrapper &other)
+ : m_me(other.m_me)
+{
+ Shiboken::GilState gil;
+ Py_XINCREF(m_me);
+}
+
+PyObjectWrapper::~PyObjectWrapper()
+{
+ // Check that Python is still initialized as sometimes this is called by a static destructor
+ // after Python interpeter is shutdown.
+ if (!Py_IsInitialized())
+ return;
+
+ Shiboken::GilState gil;
+ Py_XDECREF(m_me);
+}
+
+void PyObjectWrapper::reset(PyObject *o)
+{
+ Shiboken::GilState gil;
+ Py_XINCREF(o);
+ Py_XDECREF(m_me);
+ m_me = o;
+}
+
+PyObjectWrapper &PyObjectWrapper::operator=(const PySide::PyObjectWrapper &other)
+{
+ if (this != &other)
+ reset(other.m_me);
+ return *this;
+}
+
+PyObjectWrapper::operator PyObject *() const
+{
+ return m_me;
+}
+
+
+int PyObjectWrapper::toInt() const
+{
+ // hold the GIL
+ Shiboken::GilState state;
+ return Shiboken::Enum::check(m_me) ? Shiboken::Enum::getValue(m_me) : -1;
+}
+
+QDataStream &operator<<(QDataStream &out, const PyObjectWrapper &myObj)
+{
+ if (Py_IsInitialized() == 0) {
+ qWarning() << "Stream operator for PyObject called without python interpreter.";
+ return out;
+ }
+
+ static PyObject *reduce_func = nullptr;
+
+ Shiboken::GilState gil;
+ if (!reduce_func) {
+ Shiboken::AutoDecRef pickleModule(PyImport_ImportModule("pickle"));
+ reduce_func = PyObject_GetAttr(pickleModule, Shiboken::PyName::dumps());
+ }
+ PyObject *pyObj = myObj;
+ Shiboken::AutoDecRef repr(PyObject_CallFunctionObjArgs(reduce_func, pyObj, nullptr));
+ if (repr.object()) {
+ const char *buff = nullptr;
+ Py_ssize_t size = 0;
+ if (PyBytes_Check(repr.object())) {
+ buff = PyBytes_AS_STRING(repr.object());
+ size = PyBytes_GET_SIZE(repr.object());
+ } else if (Shiboken::String::check(repr.object())) {
+ buff = Shiboken::String::toCString(repr.object());
+ size = Shiboken::String::len(repr.object());
+ }
+ QByteArray data(buff, size);
+ out << data;
+ }
+ return out;
+}
+
+QDataStream &operator>>(QDataStream &in, PyObjectWrapper &myObj)
+{
+ if (Py_IsInitialized() == 0) {
+ qWarning() << "Stream operator for PyObject called without python interpreter.";
+ return in;
+ }
+
+ static PyObject *eval_func = nullptr;
+
+ Shiboken::GilState gil;
+ if (!eval_func) {
+ Shiboken::AutoDecRef pickleModule(PyImport_ImportModule("pickle"));
+ eval_func = PyObject_GetAttr(pickleModule, Shiboken::PyName::loads());
+ }
+
+ QByteArray repr;
+ in >> repr;
+ Shiboken::AutoDecRef pyCode(PyBytes_FromStringAndSize(repr.data(), repr.size()));
+ Shiboken::AutoDecRef value(PyObject_CallFunctionObjArgs(eval_func, pyCode.object(), 0));
+ if (!value.object())
+ value.reset(Py_None);
+ myObj.reset(value);
+ return in;
+}
+
+};
+
+namespace PySide {
+using GlobalReceiverV2Ptr = std::shared_ptr<GlobalReceiverV2>;
+using GlobalReceiverV2Map = QHash<PySide::GlobalReceiverKey, GlobalReceiverV2Ptr>;
+}
+
+using namespace PySide;
+
+// Listen for destroy() of main thread objects and ensure cleanup
+class SignalManagerDestroyListener : public QObject
+{
+ Q_OBJECT
+public:
+ Q_DISABLE_COPY_MOVE(SignalManagerDestroyListener)
+
+ using QObject::QObject;
+
+public Q_SLOTS:
+ void destroyNotify(const QObject *);
+
+protected:
+ void timerEvent(QTimerEvent *event) override;
+
+private:
+ int m_timerId = -1;
+};
+
+void SignalManagerDestroyListener::destroyNotify(const QObject *)
+{
+ if (qAppRunning && m_timerId == -1)
+ m_timerId = startTimer(0);
+}
+
+void SignalManagerDestroyListener::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_timerId) {
+ killTimer(std::exchange(m_timerId, -1));
+ SignalManager::instance().purgeEmptyGlobalReceivers();
+ }
+}
+
+struct SignalManager::SignalManagerPrivate
+{
+ Q_DISABLE_COPY_MOVE(SignalManagerPrivate)
+
+ SignalManagerPrivate() noexcept = default;
+ ~SignalManagerPrivate() { clear(); }
+
+ void deleteGlobalReceiver(const QObject *gr);
+ void clear();
+ void purgeEmptyGlobalReceivers();
+
+ GlobalReceiverV2Map m_globalReceivers;
+ static SignalManager::QmlMetaCallErrorHandler m_qmlMetaCallErrorHandler;
+
+ static void handleMetaCallError(QObject *object, int *result);
+ static int qtPropertyMetacall(QObject *object, QMetaObject::Call call,
+ int id, void **args);
+ static int qtMethodMetacall(QObject *object, int id, void **args);
+
+ QPointer<SignalManagerDestroyListener> m_listener;
+};
+
+SignalManager::QmlMetaCallErrorHandler
+ SignalManager::SignalManagerPrivate::m_qmlMetaCallErrorHandler = nullptr;
+
+static void clearSignalManager()
+{
+ PySide::SignalManager::instance().clear();
+}
+
+static void PyObject_PythonToCpp_PyObject_PTR(PyObject *pyIn, void *cppOut)
+{
+ *reinterpret_cast<PyObject **>(cppOut) = pyIn;
+}
+static PythonToCppFunc is_PyObject_PythonToCpp_PyObject_PTR_Convertible(PyObject * /* pyIn */)
+{
+ return PyObject_PythonToCpp_PyObject_PTR;
+}
+static PyObject *PyObject_PTR_CppToPython_PyObject(const void *cppIn)
+{
+ auto pyOut = reinterpret_cast<PyObject *>(const_cast<void *>(cppIn));
+ if (pyOut)
+ Py_INCREF(pyOut);
+ return pyOut;
+}
+
+SignalManager::SignalManager() : m_d(new SignalManagerPrivate)
+{
+ // Register Qt primitive typedefs used on signals.
+ using namespace Shiboken;
+
+ // Register PyObject type to use in queued signal and slot connections
+ qRegisterMetaType<PyObjectWrapper>("PyObject");
+ // Register QVariant(enum) conversion to QVariant(int)
+ QMetaType::registerConverter<PyObjectWrapper, int>(&PyObjectWrapper::toInt);
+
+ SbkConverter *converter = Shiboken::Conversions::createConverter(&PyBaseObject_Type, nullptr);
+ Shiboken::Conversions::setCppPointerToPythonFunction(converter, PyObject_PTR_CppToPython_PyObject);
+ Shiboken::Conversions::setPythonToCppPointerFunctions(converter, PyObject_PythonToCpp_PyObject_PTR, is_PyObject_PythonToCpp_PyObject_PTR_Convertible);
+ Shiboken::Conversions::registerConverterName(converter, "PyObject");
+ Shiboken::Conversions::registerConverterName(converter, "object");
+ Shiboken::Conversions::registerConverterName(converter, "PyObjectWrapper");
+ Shiboken::Conversions::registerConverterName(converter, "PySide::PyObjectWrapper");
+
+ PySide::registerCleanupFunction(clearSignalManager);
+
+ if (!metaObjectAttr)
+ metaObjectAttr = Shiboken::String::fromCString("__METAOBJECT__");
+}
+
+void SignalManager::clear()
+{
+ m_d->clear();
+}
+
+SignalManager::~SignalManager()
+{
+ delete m_d;
+}
+
+SignalManager &SignalManager::instance()
+{
+ static SignalManager me;
+ return me;
+}
+
+void SignalManager::setQmlMetaCallErrorHandler(QmlMetaCallErrorHandler handler)
+{
+ SignalManagerPrivate::m_qmlMetaCallErrorHandler = handler;
+}
+
+static void qAppAboutToQuit()
+{
+ qAppRunning = false;
+ SignalManager::instance().purgeEmptyGlobalReceivers();
+}
+
+static bool isInMainThread(const QObject *o)
+{
+ if (o->isWidgetType() || o->isWindowType() || o->isQuickItemType())
+ return true;
+ auto *app = QCoreApplication::instance();
+ return app != nullptr && app->thread() == o->thread();
+}
+
+QObject *SignalManager::globalReceiver(QObject *sender, PyObject *callback, QObject *receiver)
+{
+ if (m_d->m_listener.isNull() && !QCoreApplication::closingDown()) {
+ if (auto *app = QCoreApplication::instance()) {
+ // The signal manager potentially outlives QCoreApplication, ensure deletion
+ m_d->m_listener = new SignalManagerDestroyListener(app);
+ m_d->m_listener->setObjectName("qt_pyside_signalmanagerdestroylistener");
+ QObject::connect(app, &QCoreApplication::aboutToQuit, qAppAboutToQuit);
+ qAppRunning = true;
+ }
+ }
+
+ auto &globalReceivers = m_d->m_globalReceivers;
+ const GlobalReceiverKey key = GlobalReceiverV2::key(callback);
+ auto it = globalReceivers.find(key);
+ if (it == globalReceivers.end()) {
+ auto gr = std::make_shared<GlobalReceiverV2>(callback, receiver);
+ it = globalReceivers.insert(key, gr);
+ }
+
+ if (sender != nullptr) {
+ it.value()->incRef(sender); // create a link reference
+
+ // For main thread-objects, add a notification for destroy (PYSIDE-2646, 2141)
+ if (qAppRunning && !m_d->m_listener.isNull() && isInMainThread(sender)) {
+ QObject::connect(sender, &QObject::destroyed,
+ m_d->m_listener, &SignalManagerDestroyListener::destroyNotify,
+ Qt::UniqueConnection);
+ }
+ }
+
+ return it.value().get();
+}
+
+void SignalManager::purgeEmptyGlobalReceivers()
+{
+ m_d->purgeEmptyGlobalReceivers();
+}
+
+void SignalManager::notifyGlobalReceiver(QObject *receiver)
+{
+ reinterpret_cast<GlobalReceiverV2 *>(receiver)->notify();
+ purgeEmptyGlobalReceivers();
+}
+
+void SignalManager::releaseGlobalReceiver(const QObject *source, QObject *receiver)
+{
+ auto gr = static_cast<GlobalReceiverV2 *>(receiver);
+ gr->decRef(source);
+ if (gr->isEmpty())
+ m_d->deleteGlobalReceiver(gr);
+}
+
+void SignalManager::deleteGlobalReceiver(const QObject *gr)
+{
+ SignalManager::instance().m_d->deleteGlobalReceiver(gr);
+}
+
+void SignalManager::SignalManagerPrivate::deleteGlobalReceiver(const QObject *gr)
+{
+ for (auto it = m_globalReceivers.begin(), end = m_globalReceivers.end(); it != end; ++it) {
+ if (it.value().get() == gr) {
+ m_globalReceivers.erase(it);
+ break;
+ }
+ }
+}
+
+void SignalManager::SignalManagerPrivate::clear()
+{
+ // Delete receivers by always retrieving the current first element,
+ // because deleting a receiver can indirectly delete another one
+ // via ~DynamicSlotDataV2(). Using ~QHash/clear() could cause an
+ // iterator invalidation, and thus undefined behavior.
+ while (!m_globalReceivers.isEmpty())
+ m_globalReceivers.erase(m_globalReceivers.cbegin());
+}
+
+static bool isEmptyGlobalReceiver(const GlobalReceiverV2Ptr &g)
+{
+ return g->isEmpty();
+}
+
+void SignalManager::SignalManagerPrivate::purgeEmptyGlobalReceivers()
+{
+ // Delete repetitively (see comment in clear()).
+ while (true) {
+ auto it = std::find_if(m_globalReceivers.cbegin(), m_globalReceivers.cend(),
+ isEmptyGlobalReceiver);
+ if (it == m_globalReceivers.cend())
+ break;
+ m_globalReceivers.erase(it);
+ }
+}
+
+int SignalManager::globalReceiverSlotIndex(QObject *receiver, const char *signature) const
+{
+ return static_cast<GlobalReceiverV2 *>(receiver)->addSlot(signature);
+}
+
+bool SignalManager::emitSignal(QObject *source, const char *signal, PyObject *args)
+{
+ if (!Signal::checkQtSignal(signal))
+ return false;
+ signal++;
+
+ int signalIndex = source->metaObject()->indexOfSignal(signal);
+ return signalIndex != -1 && MetaFunction::call(source, signalIndex, args);
+}
+
+// Handle errors from meta calls. Requires GIL and PyErr_Occurred()
+void SignalManager::SignalManagerPrivate::handleMetaCallError(QObject *object, int *result)
+{
+ // Bubbles Python exceptions up to the Javascript engine, if called from one
+ if (m_qmlMetaCallErrorHandler) {
+ auto idOpt = m_qmlMetaCallErrorHandler(object);
+ if (idOpt.has_value())
+ *result = idOpt.value();
+ }
+
+ const int reclimit = Py_GetRecursionLimit();
+ // Inspired by Python's errors.c: PyErr_GivenExceptionMatches() function.
+ // Temporarily bump the recursion limit, so that PyErr_Print will not raise a recursion
+ // error again. Don't do it when the limit is already insanely high, to avoid overflow.
+ if (reclimit < (1 << 30))
+ Py_SetRecursionLimit(reclimit + 5);
+ PyErr_Print();
+ Py_SetRecursionLimit(reclimit);
+}
+
+// Handler for QMetaObject::ReadProperty/WriteProperty/ResetProperty:
+int SignalManager::SignalManagerPrivate::qtPropertyMetacall(QObject *object,
+ QMetaObject::Call call,
+ int id, void **args)
+{
+ const QMetaObject *metaObject = object->metaObject();
+ int result = id - metaObject->propertyCount();
+
+ const QMetaProperty mp = metaObject->property(id);
+
+ qCDebug(lcPySide).noquote().nospace() << __FUNCTION__
+ << ' ' << metaCallName(call) << " #" << id << ' ' << mp.typeName()
+ << "/\"" << mp.name() << "\" " << object;
+
+ if (!mp.isValid())
+ return result;
+
+ Shiboken::GilState gil;
+ auto *pySbkSelf = Shiboken::BindingManager::instance().retrieveWrapper(object);
+ Q_ASSERT(pySbkSelf);
+ auto *pySelf = reinterpret_cast<PyObject *>(pySbkSelf);
+ Shiboken::AutoDecRef pp_name(Shiboken::String::fromCString(mp.name()));
+ PySideProperty *pp = Property::getObject(pySelf, pp_name);
+ if (!pp) {
+ qWarning("Invalid property: %s.", mp.name());
+ return false;
+ }
+ pp->d->metaCall(pySelf, call, args);
+ Py_DECREF(pp);
+ if (PyErr_Occurred()) {
+ // PYSIDE-2160: An unknown type was reported. Indicated by StopIteration.
+ if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
+ PyObject *excType, *excValue, *excTraceback;
+ PyErr_Fetch(&excType, &excValue, &excTraceback);
+ bool ign = call == QMetaObject::WriteProperty;
+ PyErr_WarnFormat(PyExc_RuntimeWarning, 0,
+ ign ? "Unknown property type '%s' of QObject '%s' used in fset"
+ : "Unknown property type '%s' of QObject '%s' used in fget with %R",
+ pp->d->typeName.constData(), metaObject->className(), excValue);
+ if (PyErr_Occurred())
+ Shiboken::Errors::storeErrorOrPrint();
+ Py_DECREF(excType);
+ Py_DECREF(excValue);
+ Py_XDECREF(excTraceback);
+ return result;
+ }
+
+ qWarning().noquote().nospace()
+ << "An error occurred executing the property metacall " << call
+ << " on property \"" << mp.name() << "\" of " << object;
+ handleMetaCallError(object, &result);
+ }
+ return result;
+}
+
+// Handler for QMetaObject::InvokeMetaMethod
+int SignalManager::SignalManagerPrivate::qtMethodMetacall(QObject *object,
+ int id, void **args)
+{
+ const QMetaObject *metaObject = object->metaObject();
+ const QMetaMethod method = metaObject->method(id);
+ int result = id - metaObject->methodCount();
+
+ std::unique_ptr<Shiboken::GilState> gil;
+
+ qCDebug(lcPySide).noquote().nospace() << __FUNCTION__ << " #" << id
+ << " \"" << method.methodSignature() << '"';
+
+ if (method.methodType() == QMetaMethod::Signal) {
+ // emit python signal
+ QMetaObject::activate(object, id, args);
+ } else {
+ gil.reset(new Shiboken::GilState);
+ auto *pySbkSelf = Shiboken::BindingManager::instance().retrieveWrapper(object);
+ Q_ASSERT(pySbkSelf);
+ auto *pySelf = reinterpret_cast<PyObject *>(pySbkSelf);
+ QByteArray methodName = method.methodSignature();
+ methodName.truncate(methodName.indexOf('('));
+ Shiboken::AutoDecRef pyMethod(PyObject_GetAttrString(pySelf, methodName));
+ if (pyMethod.isNull()) {
+ PyErr_Format(PyExc_AttributeError, "Slot '%s::%s' not found.",
+ metaObject->className(), method.methodSignature().constData());
+ } else {
+ SignalManager::callPythonMetaMethod(method, args, pyMethod);
+ }
+ }
+ // WARNING Isn't safe to call any metaObject and/or object methods beyond this point
+ // because the object can be deleted inside the called slot.
+
+ if (gil.get() == nullptr)
+ gil.reset(new Shiboken::GilState);
+
+ if (PyErr_Occurred())
+ handleMetaCallError(object, &result);
+
+ return result;
+}
+
+int SignalManager::qt_metacall(QObject *object, QMetaObject::Call call, int id, void **args)
+{
+ switch (call) {
+ case QMetaObject::ReadProperty:
+ case QMetaObject::WriteProperty:
+ case QMetaObject::ResetProperty:
+ id = SignalManagerPrivate::qtPropertyMetacall(object, call, id, args);
+ break;
+ case QMetaObject::RegisterPropertyMetaType:
+ case QMetaObject::BindableProperty:
+ id -= object->metaObject()->propertyCount();
+ break;
+ case QMetaObject::InvokeMetaMethod:
+ id = SignalManagerPrivate::qtMethodMetacall(object, id, args);
+ break;
+ case QMetaObject::CreateInstance:
+ case QMetaObject::IndexOfMethod:
+ case QMetaObject::RegisterMethodArgumentMetaType:
+ case QMetaObject::CustomCall:
+ qCDebug(lcPySide).noquote().nospace() << __FUNCTION__ << ' '
+ << metaCallName(call) << " #" << id << ' ' << object;
+ id -= object->metaObject()->methodCount();
+ break;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
+ case QMetaObject::ConstructInPlace:
+ break;
+#endif
+ }
+ return id;
+}
+
+int SignalManager::callPythonMetaMethod(const QMetaMethod &method, void **args, PyObject *pyMethod)
+{
+ Q_ASSERT(pyMethod);
+
+ Shiboken::GilState gil;
+ PyObject *pyArguments = parseArguments(method, args);
+
+ if (pyArguments) {
+ QScopedPointer<Shiboken::Conversions::SpecificConverter> retConverter;
+ const char *returnType = method.typeName();
+ if (returnType != nullptr && returnType[0] != 0 && std::strcmp("void", returnType) != 0) {
+ retConverter.reset(new Shiboken::Conversions::SpecificConverter(returnType));
+ if (!retConverter->isValid()) {
+ PyErr_SetString(PyExc_RuntimeError, msgCannotConvertReturn(method).constData());
+ return -1;
+ }
+ }
+
+ Shiboken::AutoDecRef retval(PyObject_CallObject(pyMethod, pyArguments));
+
+ Py_DECREF(pyArguments);
+
+ if (!retval.isNull() && retval != Py_None && !PyErr_Occurred() && retConverter)
+ retConverter->toCpp(retval, args[0]);
+ }
+
+ return -1;
+}
+
+bool SignalManager::registerMetaMethod(QObject *source, const char *signature, QMetaMethod::MethodType type)
+{
+ int ret = registerMetaMethodGetIndex(source, signature, type);
+ return (ret != -1);
+}
+
+static MetaObjectBuilder *metaBuilderFromDict(PyObject *dict)
+{
+ // PYSIDE-803: The dict in this function is the ob_dict of an SbkObject.
+ // The "metaObjectAttr" entry is only handled in this file. There is no
+ // way in this function to involve the interpreter. Therefore, we need
+ // no GIL.
+ // Note that "SignalManager::registerMetaMethodGetIndex" has write actions
+ // that might involve the interpreter, but in that context the GIL is held.
+ if (!dict || !PyDict_Contains(dict, metaObjectAttr))
+ return nullptr;
+
+ // PYSIDE-813: The above assumption is not true in debug mode:
+ // PyDict_GetItem would touch PyThreadState_GET and the global error state.
+ // PyDict_GetItemWithError instead can work without GIL.
+ PyObject *pyBuilder = PyDict_GetItemWithError(dict, metaObjectAttr);
+ return reinterpret_cast<MetaObjectBuilder *>(PyCapsule_GetPointer(pyBuilder, nullptr));
+}
+
+// Helper to format a method signature "foo(QString)" into
+// Slot decorator "@Slot(str)"
+
+struct slotSignature
+{
+ explicit slotSignature(const char *signature) : m_signature(signature) {}
+
+ const char *m_signature;
+};
+
+QDebug operator<<(QDebug debug, const slotSignature &sig)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "@Slot(";
+ QByteArrayView signature(sig.m_signature);
+ const auto len = signature.size();
+ auto pos = signature.indexOf('(');
+ if (pos != -1 && pos < len - 2) {
+ ++pos;
+ while (true) {
+ auto nextPos = signature.indexOf(',', pos);
+ if (nextPos == -1)
+ nextPos = len - 1;
+ const QByteArrayView parameter = signature.sliced(pos, nextPos - pos);
+ if (parameter == "QString") {
+ debug << "str";
+ } else if (parameter == "double") {
+ debug << "float";
+ } else {
+ const bool hasDelimiter = parameter.contains("::");
+ if (hasDelimiter)
+ debug << '"';
+ if (!hasDelimiter && parameter.endsWith('*'))
+ debug << parameter.first(parameter.size() - 1);
+ else
+ debug << parameter;
+ if (hasDelimiter)
+ debug << '"';
+ }
+ pos = nextPos + 1;
+ if (pos >= len)
+ break;
+ debug << ',';
+ }
+ }
+ debug << ')';
+ return debug;
+}
+
+int SignalManager::registerMetaMethodGetIndex(QObject *source, const char *signature, QMetaMethod::MethodType type)
+{
+ if (!source) {
+ qWarning("SignalManager::registerMetaMethodGetIndex(\"%s\") called with source=nullptr.",
+ signature);
+ return -1;
+ }
+ const QMetaObject *metaObject = source->metaObject();
+ int methodIndex = metaObject->indexOfMethod(signature);
+ // Create the dynamic signal is needed
+ if (methodIndex == -1) {
+ SbkObject *self = Shiboken::BindingManager::instance().retrieveWrapper(source);
+ if (!Shiboken::Object::hasCppWrapper(self)) {
+ qWarning().noquote().nospace() << __FUNCTION__
+ << ": Cannot add dynamic method \"" << signature << "\" (" << type
+ << ") to " << source << ": No Wrapper found.";
+ return -1;
+ }
+ auto *pySelf = reinterpret_cast<PyObject *>(self);
+ auto *dict = SbkObject_GetDict_NoRef(pySelf);
+ MetaObjectBuilder *dmo = metaBuilderFromDict(dict);
+
+ // Create a instance meta object
+ if (!dmo) {
+ dmo = new MetaObjectBuilder(Py_TYPE(pySelf), metaObject);
+ PyObject *pyDmo = PyCapsule_New(dmo, nullptr, destroyMetaObject);
+ PyObject_SetAttr(pySelf, metaObjectAttr, pyDmo);
+ Py_DECREF(pyDmo);
+ }
+
+ if (type == QMetaMethod::Slot) {
+ qCWarning(lcPySide).noquote().nospace()
+ << "Warning: Registering dynamic slot \""
+ << signature << "\" on \"" << source->metaObject()->className()
+ << "\". Consider annotating with " << slotSignature(signature);
+ }
+
+ return type == QMetaMethod::Signal
+ ? dmo->addSignal(signature) : dmo->addSlot(signature);
+ }
+ return methodIndex;
+}
+
+const QMetaObject *SignalManager::retrieveMetaObject(PyObject *self)
+{
+ // PYSIDE-803: Avoid the GIL in SignalManager::retrieveMetaObject
+ // This function had the GIL. We do not use the GIL unless we have to.
+ // metaBuilderFromDict accesses a Python dict, but in that context there
+ // is no way to reach the interpreter, see "metaBuilderFromDict".
+ //
+ // The update function is MetaObjectBuilderPrivate::update in
+ // dynamicmetaobject.c . That function now uses the GIL when the
+ // m_dirty flag is set.
+ Q_ASSERT(self);
+
+ auto *ob_dict = SbkObject_GetDict_NoRef(self);
+ MetaObjectBuilder *builder = metaBuilderFromDict(ob_dict);
+ if (!builder)
+ builder = &(retrieveTypeUserData(self)->mo);
+
+ return builder->update();
+}
+
+static PyObject *parseArguments(const QMetaMethod &method, void **args)
+{
+ const auto &paramTypes = method.parameterTypes();
+ const qsizetype argsSize = paramTypes.size();
+ PyObject *preparedArgs = PyTuple_New(argsSize);
+
+ for (qsizetype i = 0; i < argsSize; ++i) {
+ void *data = args[i+1];
+ auto param = paramTypes.at(i);
+ Shiboken::Conversions::SpecificConverter converter(param.constData());
+ if (!converter) {
+ PyErr_SetString(PyExc_TypeError, msgCannotConvertParameter(method, i).constData());
+ Py_DECREF(preparedArgs);
+ return nullptr;
+ }
+ PyTuple_SET_ITEM(preparedArgs, i, converter.toPython(data));
+ }
+ return preparedArgs;
+}
+
+#include "signalmanager.moc"
diff --git a/sources/pyside6/libpyside/signalmanager.h b/sources/pyside6/libpyside/signalmanager.h
new file mode 100644
index 000000000..397700df1
--- /dev/null
+++ b/sources/pyside6/libpyside/signalmanager.h
@@ -0,0 +1,100 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef SIGNALMANAGER_H
+#define SIGNALMANAGER_H
+
+#include "pysidemacros.h"
+
+#include <sbkpython.h>
+#include <shibokenmacros.h>
+
+#include <QtCore/QMetaMethod>
+
+#include <optional>
+
+QT_FORWARD_DECLARE_CLASS(QDataStream)
+
+namespace PySide
+{
+
+/// Thin wrapper for PyObject which increases the reference count at the constructor but *NOT* at destructor.
+class PYSIDE_API PyObjectWrapper
+{
+public:
+ PyObjectWrapper(PyObjectWrapper&&) = delete;
+ PyObjectWrapper& operator=(PyObjectWrapper &&) = delete;
+
+ PyObjectWrapper();
+ explicit PyObjectWrapper(PyObject* me);
+ PyObjectWrapper(const PyObjectWrapper &other);
+ PyObjectWrapper& operator=(const PyObjectWrapper &other);
+
+ void reset(PyObject *o);
+
+ ~PyObjectWrapper();
+ operator PyObject*() const;
+
+ // FIXME: To be removed in Qt7
+ // This was done to make QAbstractItemModel::data() work without explicit conversion of
+ // QVariant(PyObjectWrapper) to QVariant(int). This works because QAbstractItemModel::data()
+ // inturn calls legacyEnumValueFromModelData(const QVariant &data). But this function will
+ // be removed in Qt7.
+ // The proper fix would be to associate PyObjectWrapper to the corresponding C++ Enum.
+ int toInt() const;
+
+private:
+ PyObject* m_me;
+};
+
+PYSIDE_API QDataStream &operator<<(QDataStream& out, const PyObjectWrapper& myObj);
+PYSIDE_API QDataStream &operator>>(QDataStream& in, PyObjectWrapper& myObj);
+
+class PYSIDE_API SignalManager
+{
+public:
+ Q_DISABLE_COPY_MOVE(SignalManager)
+
+ using QmlMetaCallErrorHandler = std::optional<int>(*)(QObject *object);
+
+ static SignalManager& instance();
+
+ static void setQmlMetaCallErrorHandler(QmlMetaCallErrorHandler handler);
+
+ QObject* globalReceiver(QObject *sender, PyObject *callback, QObject *receiver = nullptr);
+ void releaseGlobalReceiver(const QObject* sender, QObject* receiver);
+ int globalReceiverSlotIndex(QObject* sender, const char* slotSignature) const;
+ void notifyGlobalReceiver(QObject* receiver);
+
+ bool emitSignal(QObject* source, const char* signal, PyObject* args);
+ static int qt_metacall(QObject* object, QMetaObject::Call call, int id, void** args);
+
+ // Used to register a new signal/slot on QMetaobject of source.
+ static bool registerMetaMethod(QObject* source, const char* signature, QMetaMethod::MethodType type);
+ static int registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type);
+
+ // used to discovery metaobject
+ static const QMetaObject* retrieveMetaObject(PyObject* self);
+
+ // Disconnect all signals managed by Globalreceiver
+ void clear();
+ void purgeEmptyGlobalReceivers();
+
+ // Utility function to call a python method usign args received in qt_metacall
+ static int callPythonMetaMethod(const QMetaMethod& method, void** args, PyObject* obj);
+
+ static void deleteGlobalReceiver(const QObject *globalReceiver);
+
+private:
+ struct SignalManagerPrivate;
+ SignalManagerPrivate* m_d;
+
+ SignalManager();
+ ~SignalManager();
+};
+
+}
+
+Q_DECLARE_METATYPE(PySide::PyObjectWrapper)
+
+#endif
diff --git a/sources/pyside6/libpysideqml/CMakeLists.txt b/sources/pyside6/libpysideqml/CMakeLists.txt
new file mode 100644
index 000000000..1af8c02cf
--- /dev/null
+++ b/sources/pyside6/libpysideqml/CMakeLists.txt
@@ -0,0 +1,115 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+set(libpysideqml_libraries Qt::Core Qt::CorePrivate Qt::Qml Qt::QmlPrivate)
+
+set(libpysideqml_HEADERS # installed below
+ pysideqmlattached.h
+ pysideqmlattached_p.h
+ pysideqmlextended_p.h
+ pysideqmlforeign_p.h
+ pysideqml.h
+ pysideqmllistproperty_p.h
+ pysideqmlmacros.h
+ pysideqmlmetacallerror_p.h
+ pysideqmlnamedelement_p.h
+ pysideqmlregistertype.h
+ pysideqmlregistertype_p.h
+ pysideqmltypeinfo_p.h
+ pysideqmluncreatable.h
+)
+
+set(libpysideqml_SRC
+ pysideqml.cpp
+ pysideqmlattached.cpp
+ pysideqmlforeign.cpp
+ pysideqmlextended.cpp
+ pysideqmlregistertype.cpp
+ pysideqmlmetacallerror.cpp
+ pysideqmllistproperty.cpp
+ pysideqmlnamedelement.cpp
+ pysideqmluncreatable.cpp
+ pysideqmltypeinfo.cpp
+ ${libpysideqml_HEADERS}
+)
+
+# Hack for // https://github.com/python/cpython/issues/86286 causes issues
+set_source_files_properties(
+ pysideqmlmetacallerror.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON
+)
+
+add_library(pyside6qml SHARED ${libpysideqml_SRC} ${other_files})
+add_library(PySide6::pyside6qml ALIAS pyside6qml)
+
+target_include_directories(pyside6qml PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ $<INSTALL_INTERFACE:include/PySide6Qml>
+)
+
+target_compile_definitions(pyside6qml PRIVATE -DQT_LEAN_HEADERS=1 -DQT_NO_KEYWORDS=1)
+
+target_link_libraries(pyside6qml
+ PRIVATE PySide6::pyside6 Shiboken6::libshiboken ${libpysideqml_libraries})
+
+set_target_properties(pyside6qml PROPERTIES
+ VERSION ${BINDING_API_VERSION}
+ SOVERSION "${PYSIDE_SO_VERSION}"
+ OUTPUT_NAME "pyside6qml${pyside6_SUFFIX}${SHIBOKEN_PYTHON_SHARED_LIBRARY_SUFFIX}"
+ DEFINE_SYMBOL BUILD_LIBPYSIDEQML)
+
+target_compile_definitions(pyside6qml PRIVATE -DQT_LEAN_HEADERS=1)
+
+set_property(TARGET pyside6qml PROPERTY CXX_STANDARD 17)
+
+if(PYSIDE_QT_CONF_PREFIX)
+ set_property(SOURCE pysideqml.cpp
+ APPEND
+ PROPERTY COMPILE_DEFINITIONS
+ PYSIDE_QT_CONF_PREFIX=${PYSIDE_QT_CONF_PREFIX})
+endif()
+
+#
+# install stuff
+#
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_DEBUG_POSTFIX})
+else()
+ set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_RELEASE_POSTFIX})
+endif()
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_TO_ASCII")
+
+qfp_strip_library("pyside6qml")
+
+# Install-tree / relocatable package config file.
+configure_package_config_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/PySide6QmlConfig-spec.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/install/PySide6QmlConfig${SHIBOKEN_PYTHON_CONFIG_SUFFIX}.cmake"
+ INSTALL_DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6Qml"
+)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/PySide6QmlConfig.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/PySide6QmlConfig.cmake" @ONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/PySide6QmlConfigVersion.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/PySide6QmlConfigVersion.cmake" @ONLY)
+
+install(FILES ${libpysideqml_HEADERS}
+ DESTINATION include/${BINDING_NAME}${pyside6qml_SUFFIX})
+
+install(TARGETS pyside6qml EXPORT PySide6QmlTargets
+ LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
+ ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
+ RUNTIME DESTINATION bin)
+install(EXPORT PySide6QmlTargets NAMESPACE PySide6Qml::
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6Qml")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/PySide6QmlConfig.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6Qml")
+
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/install/PySide6QmlConfig${SHIBOKEN_PYTHON_CONFIG_SUFFIX}.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6Qml")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/PySide6QmlConfigVersion.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/PySide6Qml")
diff --git a/sources/pyside6/libpysideqml/PySide6QmlConfig-spec.cmake.in b/sources/pyside6/libpysideqml/PySide6QmlConfig-spec.cmake.in
new file mode 100644
index 000000000..36eb4123a
--- /dev/null
+++ b/sources/pyside6/libpysideqml/PySide6QmlConfig-spec.cmake.in
@@ -0,0 +1,7 @@
+@PACKAGE_INIT@
+
+# Import targets only when using an installed PySide6 config file (so not during a regular
+# PySide6 build, or during a super project build).
+if (NOT TARGET PySide6::pyside6qml)
+ include("${CMAKE_CURRENT_LIST_DIR}/PySide6QmlTargets.cmake")
+endif()
diff --git a/sources/pyside6/libpysideqml/PySide6QmlConfig.cmake.in b/sources/pyside6/libpysideqml/PySide6QmlConfig.cmake.in
new file mode 100644
index 000000000..dab0a6b13
--- /dev/null
+++ b/sources/pyside6/libpysideqml/PySide6QmlConfig.cmake.in
@@ -0,0 +1,5 @@
+if (NOT PYTHON_CONFIG_SUFFIX)
+ message(STATUS "PySide6QmlConfig: Using default python: @SHIBOKEN_PYTHON_CONFIG_SUFFIX@")
+ SET(PYTHON_CONFIG_SUFFIX @SHIBOKEN_PYTHON_CONFIG_SUFFIX@)
+endif()
+include(${CMAKE_CURRENT_LIST_DIR}/PySide6QmlConfig${PYTHON_CONFIG_SUFFIX}.cmake)
diff --git a/sources/pyside6/libpysideqml/PySide6QmlConfigVersion.cmake.in b/sources/pyside6/libpysideqml/PySide6QmlConfigVersion.cmake.in
new file mode 100644
index 000000000..f5073ce08
--- /dev/null
+++ b/sources/pyside6/libpysideqml/PySide6QmlConfigVersion.cmake.in
@@ -0,0 +1,10 @@
+set(PACKAGE_VERSION @BINDING_API_VERSION@)
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}")
+endif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
diff --git a/sources/pyside6/libpysideqml/pysideqml.cpp b/sources/pyside6/libpysideqml/pysideqml.cpp
new file mode 100644
index 000000000..3fe673fdf
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqml.cpp
@@ -0,0 +1,35 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqml.h"
+#include "pysideqmllistproperty_p.h"
+#include "pysideqmlattached_p.h"
+#include "pysideqmlextended_p.h"
+#include "pysideqmlforeign_p.h"
+#include "pysideqmlnamedelement_p.h"
+#include "pysideqmluncreatable.h"
+#include "pysideqmlmetacallerror_p.h"
+
+#include <QtQml/QQmlPropertyMap>
+#include <QtQml/QQmlComponent>
+
+#include <signalmanager.h>
+
+namespace PySide::Qml
+{
+
+void init(PyObject *module)
+{
+ initQtQmlListProperty(module);
+ initQmlAttached(module);
+ initQmlForeign(module);
+ initQmlExtended(module);
+ initQmlNamedElement(module);
+ initQmlUncreatable(module);
+ PySide::SignalManager::setQmlMetaCallErrorHandler(PySide::Qml::qmlMetaCallErrorHandler);
+
+ qRegisterMetaType<QQmlPropertyMap *>(); // PYSIDE-1845, QQmlPropertyMap * properties
+ qRegisterMetaType<QQmlComponent *>(); // PYSIDE-2415, QQmlComponent * properties
+}
+
+} //namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqml.h b/sources/pyside6/libpysideqml/pysideqml.h
new file mode 100644
index 000000000..d975bcf97
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqml.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQML_H
+#define PYSIDEQML_H
+
+#include "pysideqmlmacros.h"
+
+#include <sbkpython.h>
+
+namespace PySide::Qml
+{
+
+PYSIDEQML_API void init(PyObject *module);
+
+} //namespace PySide::Qml
+
+#endif // PYSIDEQML_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlattached.cpp b/sources/pyside6/libpysideqml/pysideqmlattached.cpp
new file mode 100644
index 000000000..d484257e2
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlattached.cpp
@@ -0,0 +1,216 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmlattached.h"
+#include "pysideqmlattached_p.h"
+#include "pysideqmltypeinfo_p.h"
+#include "pysideqmlregistertype_p.h"
+
+#include <signalmanager.h>
+#include <pyside_p.h>
+#include <pysideclassdecorator_p.h>
+
+#include <shiboken.h>
+#include <signature.h>
+#include <sbkstring.h>
+
+#include <QtQml/qqml.h>
+
+#include <algorithm>
+
+// The QmlAttached decorator modifies QmlElement to register an attached property
+// type. Due to the (reverse) execution order of decorators, it needs to follow
+// QmlElement.
+class PySideQmlAttachedPrivate : public PySide::ClassDecorator::TypeDecoratorPrivate
+{
+public:
+ PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) override;
+ const char *name() const override;
+};
+
+// The call operator is passed the class type and registers the type
+// in QmlTypeInfo.
+PyObject *PySideQmlAttachedPrivate::tp_call(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PyObject *klass = tp_call_check(args, CheckMode::WrappedType);
+ if (klass == nullptr)
+ return nullptr;
+
+ auto *data = DecoratorPrivate::get<PySideQmlAttachedPrivate>(self);
+ PySide::Qml::ensureQmlTypeInfo(klass)->attachedType = data->type();
+
+ Py_INCREF(klass);
+ return klass;
+}
+
+const char *PySideQmlAttachedPrivate::name() const
+{
+ return "QmlAttached";
+}
+
+extern "C" {
+
+static PyTypeObject *createPySideQmlAttachedType(void)
+{
+ auto typeSlots =
+ PySide::ClassDecorator::Methods<PySideQmlAttachedPrivate>::typeSlots();
+
+ PyType_Spec PySideQmlAttachedType_spec = {
+ "2:PySide6.QtCore.qmlAttached",
+ sizeof(PySideClassDecorator),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ typeSlots.data()
+ };
+ return SbkType_FromSpec(&PySideQmlAttachedType_spec);
+}
+
+PyTypeObject *PySideQmlAttached_TypeF(void)
+{
+ static auto *type = createPySideQmlAttachedType();
+ return type;
+}
+
+} // extern "C"
+
+static const char *qmlAttached_SignatureStrings[] = {
+ "PySide6.QtQml.QmlAttached(self,type:type)",
+ nullptr // Sentinel
+};
+
+namespace PySide::Qml {
+
+static QObject *attachedFactoryHelper(PyTypeObject *attachingType, QObject *o)
+{
+ // Call static qmlAttachedProperties() on type. If there is an error
+ // and nullptr is returned, a crash occurs. So, errors should at least be
+ // printed.
+
+ Shiboken::GilState gilState;
+ Shiboken::Conversions::SpecificConverter converter("QObject");
+ Q_ASSERT(converter);
+
+ static const char methodName[] = "qmlAttachedProperties";
+ static PyObject *const pyMethodName = Shiboken::String::createStaticString(methodName);
+ PyObject *attachingTypeObj = reinterpret_cast<PyObject *>(attachingType);
+ Shiboken::AutoDecRef pyResult(PyObject_CallMethodObjArgs(attachingTypeObj, pyMethodName,
+ attachingTypeObj /* self */,
+ converter.toPython(&o),
+ nullptr));
+ if (pyResult.isNull() || PyErr_Occurred()) {
+ PyErr_Print();
+ return nullptr;
+ }
+
+ if (PyType_IsSubtype(pyResult->ob_type, qObjectType()) == 0) {
+ qWarning("QmlAttached: Attached objects must inherit QObject, got %s.",
+ pyResult->ob_type->tp_name);
+ return nullptr;
+ }
+
+ QObject *result = nullptr;
+ converter.toCpp(pyResult.object(), &result);
+ return result;
+}
+
+// Since the required attached factory signature does not have a void *user
+// parameter to store the attaching type, we employ a template trick, storing
+// the attaching types in an array and create non-type-template (int) functions
+// taking the array index as template parameter.
+// We initialize the attachedFactories array with factory functions
+// accessing the attachingTypes[N] using template metaprogramming.
+
+enum { MAX_ATTACHING_TYPES = 50};
+
+using AttachedFactory = QObject *(*)(QObject *);
+
+static int nextAttachingType = 0;
+static PyTypeObject *attachingTypes[MAX_ATTACHING_TYPES];
+static AttachedFactory attachedFactories[MAX_ATTACHING_TYPES];
+
+template <int N>
+static QObject *attachedFactory(QObject *o)
+{
+ return attachedFactoryHelper(attachingTypes[N], o);
+}
+
+template<int N>
+struct AttachedFactoryInitializerBase
+{
+};
+
+template<int N>
+struct AttachedFactoryInitializer : AttachedFactoryInitializerBase<N>
+{
+ static void init()
+ {
+ attachedFactories[N] = attachedFactory<N>;
+ AttachedFactoryInitializer<N-1>::init();
+ }
+};
+
+template<>
+struct AttachedFactoryInitializer<0> : AttachedFactoryInitializerBase<0>
+{
+ static void init()
+ {
+ attachedFactories[0] = attachedFactory<0>;
+ }
+};
+
+void initQmlAttached(PyObject *module)
+{
+ std::fill(attachingTypes, attachingTypes + MAX_ATTACHING_TYPES, nullptr);
+ AttachedFactoryInitializer<MAX_ATTACHING_TYPES - 1>::init();
+
+ if (InitSignatureStrings(PySideQmlAttached_TypeF(), qmlAttached_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideQmlAttached_TypeF());
+ PyModule_AddObject(module, "QmlAttached",
+ reinterpret_cast<PyObject *>(PySideQmlAttached_TypeF()));
+}
+
+PySide::Qml::QmlExtensionInfo qmlAttachedInfo(PyTypeObject *t,
+ const std::shared_ptr<QmlTypeInfo> &info)
+{
+ PySide::Qml::QmlExtensionInfo result{nullptr, nullptr};
+ if (!info || info->attachedType == nullptr)
+ return result;
+
+ auto *name = reinterpret_cast<PyTypeObject *>(t)->tp_name;
+ if (nextAttachingType >= MAX_ATTACHING_TYPES) {
+ qWarning("Unable to initialize attached type \"%s\": "
+ "The limit %d of attached types has been reached.",
+ name, MAX_ATTACHING_TYPES);
+ return result;
+ }
+
+ result.metaObject = PySide::retrieveMetaObject(info->attachedType);
+ if (result.metaObject == nullptr) {
+ qWarning("Unable to retrieve meta object for %s", name);
+ return result;
+ }
+
+ attachingTypes[nextAttachingType] = t;
+ result.factory = attachedFactories[nextAttachingType];
+ ++nextAttachingType;
+
+ return result;
+}
+
+QObject *qmlAttachedPropertiesObject(PyObject *typeObject, QObject *obj, bool create)
+{
+ auto *type = reinterpret_cast<PyTypeObject *>(typeObject);
+ auto *end = attachingTypes + nextAttachingType;
+ auto *typePtr = std::find(attachingTypes, end, type);
+ if (typePtr == end) {
+ qWarning("%s: Attaching type \"%s\" not found.", __FUNCTION__, type->tp_name);
+ return nullptr;
+ }
+
+ auto func = attachedFactories[std::uintptr_t(typePtr - attachingTypes)];
+ return ::qmlAttachedPropertiesObject(obj, func, create);
+}
+
+} // namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqmlattached.h b/sources/pyside6/libpysideqml/pysideqmlattached.h
new file mode 100644
index 000000000..96f788268
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlattached.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLATTACHED_H
+#define PYSIDEQMLATTACHED_H
+
+#include <sbkpython.h>
+
+#include "pysideqmlmacros.h"
+
+#include <QtCore/qtconfigmacros.h>
+
+QT_FORWARD_DECLARE_CLASS(QObject)
+
+namespace PySide::Qml
+{
+
+/// PySide implementation of qmlAttachedPropertiesObject<T> function.
+/// \param typeObject attaching type
+/// \param obj attachee
+/// \param create Whether to create the Attachment object
+/// \return Attachment object instance
+PYSIDEQML_API QObject *qmlAttachedPropertiesObject(PyObject *typeObject, QObject *obj,
+ bool create = true);
+
+} // namespace PySide::Qml
+
+#endif // PYSIDEQMLATTACHED_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlattached_p.h b/sources/pyside6/libpysideqml/pysideqmlattached_p.h
new file mode 100644
index 000000000..7c8a47fb8
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlattached_p.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLATTACHED_P_H
+#define PYSIDEQMLATTACHED_P_H
+
+#include <sbkpython.h>
+
+#include <memory>
+
+namespace PySide::Qml {
+struct QmlExtensionInfo;
+struct QmlTypeInfo;
+
+void initQmlAttached(PyObject *module);
+
+PySide::Qml::QmlExtensionInfo qmlAttachedInfo(PyTypeObject *t,
+ const std::shared_ptr<QmlTypeInfo> &info);
+} // namespace PySide::Qml
+
+#endif // PYSIDEQMLATTACHED_P_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlextended.cpp b/sources/pyside6/libpysideqml/pysideqmlextended.cpp
new file mode 100644
index 000000000..23543d589
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlextended.cpp
@@ -0,0 +1,145 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmlextended_p.h"
+#include "pysideqmltypeinfo_p.h"
+#include "pysideqmlregistertype_p.h"
+
+#include <pyside_p.h>
+#include <pysideclassdecorator_p.h>
+
+#include <shiboken.h>
+#include <signature.h>
+#include <sbkstring.h>
+
+#include <QtQml/qqml.h>
+
+// The QmlExtended decorator modifies QmlElement to register an extension.
+// Due to the (reverse) execution order of decorators, it needs to follow
+// QmlElement.
+class PySideQmlExtendedPrivate : public PySide::ClassDecorator::TypeDecoratorPrivate
+{
+public:
+ PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) override;
+ const char *name() const override;
+};
+
+// The call operator is passed the class type and registers the type
+// in QmlTypeInfo.
+PyObject *PySideQmlExtendedPrivate::tp_call(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PyObject *klass = tp_call_check(args, CheckMode::WrappedType);
+ if (klass == nullptr)
+ return nullptr;
+
+ auto *data = DecoratorPrivate::get<PySideQmlExtendedPrivate>(self);
+ PySide::Qml::ensureQmlTypeInfo(klass)->extensionType = data->type();
+
+ Py_INCREF(klass);
+ return klass;
+}
+
+const char *PySideQmlExtendedPrivate::name() const
+{
+ return "QmlExtended";
+}
+
+extern "C" {
+
+static PyTypeObject *createPySideQmlExtendedType(void)
+{
+ auto typeSlots =
+ PySide::ClassDecorator::Methods<PySideQmlExtendedPrivate>::typeSlots();
+
+ PyType_Spec PySideQmlExtendedType_spec = {
+ "2:PySide6.QtCore.qmlExtended",
+ sizeof(PySideClassDecorator),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ typeSlots.data()
+ };
+ return SbkType_FromSpec(&PySideQmlExtendedType_spec);
+}
+
+PyTypeObject *PySideQmlExtended_TypeF(void)
+{
+ static auto *type = createPySideQmlExtendedType();
+ return type;
+}
+
+} // extern "C"
+
+static const char *qmlExtended_SignatureStrings[] = {
+ "PySide6.QtQml.QmlExtended(self,type:type)",
+ nullptr // Sentinel
+};
+
+namespace PySide::Qml {
+
+static QObject *extensionFactory(QObject *o)
+{
+ Shiboken::GilState gilState;
+ Shiboken::Conversions::SpecificConverter converter("QObject");
+ Q_ASSERT(converter);
+ PyObject *pyObj = converter.toPython(&o);
+ Q_ASSERT(pyObj);
+
+ // Search for the extension type and create an instance by invoking
+ // the call operator on type with the parent parameter.
+ // If there is an error and nullptr is returned, a crash occurs,
+ // so, errors should at least be printed.
+
+ auto *pyObjType = Py_TYPE(pyObj);
+ const auto info = qmlTypeInfo(reinterpret_cast<PyObject *>(pyObjType));
+ if (!info || info->extensionType == nullptr) {
+ qWarning("QmlExtended: Cannot find extension of %s.", pyObjType->tp_name);
+ return nullptr;
+ }
+
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTuple_SET_ITEM(args.object(), 0, pyObj);
+ auto *extensionTypeObj = reinterpret_cast<PyObject *>(info->extensionType);
+ Shiboken::AutoDecRef pyResult(PyObject_Call(extensionTypeObj, args, nullptr));
+ if (pyResult.isNull() || PyErr_Occurred()) {
+ PyErr_Print();
+ return nullptr;
+ }
+
+ if (PyType_IsSubtype(pyResult->ob_type, qObjectType()) == 0) {
+ qWarning("QmlExtended: Extension objects must inherit QObject, got %s.",
+ pyResult->ob_type->tp_name);
+ return nullptr;
+ }
+
+ QObject *result = nullptr;
+ converter.toCpp(pyResult.object(), &result);
+ return result;
+}
+
+void initQmlExtended(PyObject *module)
+{
+ if (InitSignatureStrings(PySideQmlExtended_TypeF(), qmlExtended_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideQmlExtended_TypeF());
+ PyModule_AddObject(module, "QmlExtended",
+ reinterpret_cast<PyObject *>(PySideQmlExtended_TypeF()));
+}
+
+PySide::Qml::QmlExtensionInfo qmlExtendedInfo(PyObject *t,
+ const std::shared_ptr<QmlTypeInfo> &info)
+{
+ PySide::Qml::QmlExtensionInfo result{nullptr, nullptr};
+ if (info && info->extensionType) {
+ result.metaObject = PySide::retrieveMetaObject(info->extensionType);
+ if (result.metaObject) {
+ result.factory = extensionFactory;
+ } else {
+ qWarning("Unable to retrieve meta object for %s",
+ reinterpret_cast<PyTypeObject *>(t)->tp_name);
+ }
+ }
+ return result;
+}
+
+} // namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqmlextended_p.h b/sources/pyside6/libpysideqml/pysideqmlextended_p.h
new file mode 100644
index 000000000..17d6dae64
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlextended_p.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLEXTENDED_P_H
+#define PYSIDEQMLEXTENDED_P_H
+
+#include <sbkpython.h>
+
+#include <memory>
+
+namespace PySide::Qml {
+struct QmlExtensionInfo;
+struct QmlTypeInfo;
+
+void initQmlExtended(PyObject *module);
+
+PySide::Qml::QmlExtensionInfo qmlExtendedInfo(PyObject *t,
+ const std::shared_ptr<QmlTypeInfo> &info);
+} // namespace PySide::Qml
+
+#endif // PYSIDEQMLEXTENDED_P_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlforeign.cpp b/sources/pyside6/libpysideqml/pysideqmlforeign.cpp
new file mode 100644
index 000000000..18d39d121
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlforeign.cpp
@@ -0,0 +1,92 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmlforeign_p.h"
+#include "pysideqmltypeinfo_p.h"
+
+#include <signalmanager.h>
+#include <pysideclassdecorator_p.h>
+
+#include <shiboken.h>
+#include <signature.h>
+#include <sbkstring.h>
+
+#include <QtCore/QDebug>
+
+// The QmlForeign decorator modifies QmlElement to create a different type
+// QmlElement.
+class PySideQmlForeignPrivate : public PySide::ClassDecorator::TypeDecoratorPrivate
+{
+public:
+ PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) override;
+ const char *name() const override;
+};
+
+// The call operator is passed the class type and registers the type
+// in QmlTypeInfo.
+PyObject *PySideQmlForeignPrivate::tp_call(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PyObject *klass = tp_call_check(args, CheckMode::WrappedType);
+ if (klass == nullptr)
+ return nullptr;
+
+ auto *data = DecoratorPrivate::get<PySideQmlForeignPrivate>(self);
+ const auto info = PySide::Qml::ensureQmlTypeInfo(klass);
+ info->foreignType = data->type();
+ // Insert an alias to be used by the factory functions of Decorators like
+ // @QmlExtended and @QmlAttached.
+ auto *foreignObj = reinterpret_cast<const PyObject *>(info->foreignType);
+ PySide::Qml::insertQmlTypeInfoAlias(foreignObj, info);
+
+ Py_INCREF(klass);
+ return klass;
+}
+
+const char *PySideQmlForeignPrivate::name() const
+{
+ return "QmlForeign";
+}
+
+extern "C" {
+
+static PyTypeObject *createPySideQmlForeignType(void)
+{
+ auto typeSlots =
+ PySide::ClassDecorator::Methods<PySideQmlForeignPrivate>::typeSlots();
+
+ PyType_Spec PySideQmlForeignType_spec = {
+ "2:PySide6.QtCore.qmlForeign",
+ sizeof(PySideClassDecorator),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ typeSlots.data()
+ };
+ return SbkType_FromSpec(&PySideQmlForeignType_spec);
+}
+
+PyTypeObject *PySideQmlForeign_TypeF(void)
+{
+ static auto *type = createPySideQmlForeignType();
+ return type;
+}
+
+} // extern "C"
+
+static const char *qmlForeign_SignatureStrings[] = {
+ "PySide6.QtQml.QmlForeign(self,type:type)",
+ nullptr // Sentinel
+};
+
+namespace PySide::Qml {
+
+void initQmlForeign(PyObject *module)
+{
+ if (InitSignatureStrings(PySideQmlForeign_TypeF(), qmlForeign_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideQmlForeign_TypeF());
+ PyModule_AddObject(module, "QmlForeign",
+ reinterpret_cast<PyObject *>(PySideQmlForeign_TypeF()));
+}
+
+} // namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqmlforeign_p.h b/sources/pyside6/libpysideqml/pysideqmlforeign_p.h
new file mode 100644
index 000000000..85688aab0
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlforeign_p.h
@@ -0,0 +1,17 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLFOREIGN_P_H
+#define PYSIDEQMLFOREIGN_P_H
+
+#include <sbkpython.h>
+
+namespace PySide::Qml {
+struct QmlExtensionInfo;
+struct QmlTypeInfo;
+
+void initQmlForeign(PyObject *module);
+
+} // namespace PySide::Qml
+
+#endif // PYSIDEQMLFOREIGN_P_H
diff --git a/sources/pyside6/libpysideqml/pysideqmllistproperty.cpp b/sources/pyside6/libpysideqml/pysideqmllistproperty.cpp
new file mode 100644
index 000000000..75bb5af96
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmllistproperty.cpp
@@ -0,0 +1,307 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmllistproperty_p.h"
+#include "pysideqmlregistertype_p.h"
+
+#include <shiboken.h>
+#include <pep384ext.h>
+#include <signature.h>
+
+#include <pysideproperty.h>
+#include <pysideproperty_p.h>
+
+#include <QtCore/QObject>
+#include <QtQml/QQmlListProperty>
+
+// This is the user data we store in the property.
+class QmlListPropertyPrivate : public PySidePropertyPrivate
+{
+public:
+ void metaCall(PyObject *source, QMetaObject::Call call, void **args) override;
+
+ PyTypeObject *type = nullptr;
+ PyObject *append = nullptr;
+ PyObject *count = nullptr;
+ PyObject *at = nullptr;
+ PyObject *clear = nullptr;
+ PyObject *replace = nullptr;
+ PyObject *removeLast = nullptr;
+};
+
+extern "C"
+{
+
+static PyObject *propList_tp_new(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */)
+{
+ auto *me = PepExt_TypeCallAlloc<PySideProperty>(subtype, 0);
+ me->d = new QmlListPropertyPrivate;
+ return reinterpret_cast<PyObject *>(me);
+}
+
+static int propListTpInit(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"type", "append", "count", "at", "clear",
+ "replace", "removeLast",
+ "doc", "notify", // PySideProperty
+ "designable", "scriptable", "stored",
+ "user", "constant", "final",
+ nullptr};
+ PySideProperty *pySelf = reinterpret_cast<PySideProperty *>(self);
+
+ auto *data = static_cast<QmlListPropertyPrivate *>(pySelf->d);
+
+ char *doc{};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds,
+ "O|OOOOOOsObbbbbb:QtQml.ListProperty",
+ const_cast<char **>(kwlist),
+ &data->type,
+ &data->append,
+ &data->count,
+ &data->at,
+ &data->clear,
+ &data->replace,
+ &data->removeLast,
+ /*s*/ &doc,
+ /*O*/ &(data->notify), // PySideProperty
+ /*bbb*/ &(data->designable),
+ &(data->scriptable),
+ &(data->stored),
+ /*bbb*/ &(data->user),
+ &(data->constant),
+ &(data->final))) {
+ return -1;
+ }
+
+ if (doc)
+ data->doc = doc;
+ else
+ data->doc.clear();
+
+ PyTypeObject *qobjectType = qObjectType();
+
+ if (!PySequence_Contains(data->type->tp_mro, reinterpret_cast<PyObject *>(qobjectType))) {
+ PyErr_Format(PyExc_TypeError, "A type inherited from %s expected, got %s.",
+ qobjectType->tp_name, data->type->tp_name);
+ return -1;
+ }
+
+ if ((data->append && data->append != Py_None && !PyCallable_Check(data->append)) ||
+ (data->count && data->count != Py_None && !PyCallable_Check(data->count)) ||
+ (data->at && data->at != Py_None && !PyCallable_Check(data->at)) ||
+ (data->clear && data->clear != Py_None && !PyCallable_Check(data->clear)) ||
+ (data->replace && data->replace != Py_None && !PyCallable_Check(data->replace)) ||
+ (data->removeLast && data->removeLast != Py_None && !PyCallable_Check(data->removeLast))) {
+ PyErr_Format(PyExc_TypeError, "Non-callable parameter given");
+ return -1;
+ }
+
+ data->typeName = QByteArrayLiteral("QQmlListProperty<QObject>");
+
+ return 0;
+}
+
+static PyTypeObject *createPropertyListType()
+{
+ PyType_Slot PropertyListType_slots[] = {
+ {Py_tp_new, reinterpret_cast<void *>(propList_tp_new)},
+ {Py_tp_init, reinterpret_cast<void *>(propListTpInit)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PropertyListType_spec = {
+ "2:PySide6.QtQml.ListProperty",
+ sizeof(PySideProperty),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ PropertyListType_slots,
+ };
+
+ Shiboken::AutoDecRef bases(Py_BuildValue("(O)", PySideProperty_TypeF()));
+ return SbkType_FromSpecWithBases(&PropertyListType_spec, bases.object());
+}
+
+PyTypeObject *PropertyList_TypeF(void)
+{
+ // PYSIDE-2230: This was a wrong replacement by static AutoDecref.
+ // Never do that, deletes things way too late.
+ static PyTypeObject *type = createPropertyListType();
+ return type;
+}
+
+} // extern "C"
+
+// Implementation of QQmlListProperty<T>::AppendFunction callback
+void propListAppender(QQmlListProperty<QObject> *propList, QObject *item)
+{
+ Shiboken::GilState state;
+
+ Shiboken::AutoDecRef args(PyTuple_New(2));
+ PyTypeObject *qobjectType = qObjectType();
+ PyTuple_SET_ITEM(args, 0,
+ Shiboken::Conversions::pointerToPython(qobjectType, propList->object));
+ PyTuple_SET_ITEM(args, 1,
+ Shiboken::Conversions::pointerToPython(qobjectType, item));
+
+ auto *data = reinterpret_cast<QmlListPropertyPrivate *>(propList->data);
+ Shiboken::AutoDecRef retVal(PyObject_CallObject(data->append, args));
+
+ if (PyErr_Occurred())
+ PyErr_Print();
+}
+
+// Implementation of QQmlListProperty<T>::CountFunction callback
+qsizetype propListCount(QQmlListProperty<QObject> *propList)
+{
+ Shiboken::GilState state;
+
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTuple_SET_ITEM(args, 0,
+ Shiboken::Conversions::pointerToPython(qObjectType(), propList->object));
+
+ auto *data = reinterpret_cast<QmlListPropertyPrivate *>(propList->data);
+ Shiboken::AutoDecRef retVal(PyObject_CallObject(data->count, args));
+
+ // Check return type
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ return 0;
+ }
+
+ qsizetype cppResult = 0;
+ auto *converter = Shiboken::Conversions::PrimitiveTypeConverter<qsizetype>();
+ if (auto *pythonToCpp = Shiboken::Conversions::isPythonToCppConvertible(converter, retVal))
+ pythonToCpp(retVal, &cppResult);
+ return cppResult;
+}
+
+// Implementation of QQmlListProperty<T>::AtFunction callback
+QObject *propListAt(QQmlListProperty<QObject> *propList, qsizetype index)
+{
+ Shiboken::GilState state;
+
+ Shiboken::AutoDecRef args(PyTuple_New(2));
+ PyTypeObject *qobjectType = qObjectType();
+ PyTuple_SET_ITEM(args, 0,
+ Shiboken::Conversions::pointerToPython(qobjectType, propList->object));
+ auto *converter = Shiboken::Conversions::PrimitiveTypeConverter<qsizetype>();
+ PyTuple_SET_ITEM(args, 1,
+ Shiboken::Conversions::copyToPython(converter, &index));
+
+ auto *data = reinterpret_cast<QmlListPropertyPrivate *>(propList->data);
+ Shiboken::AutoDecRef retVal(PyObject_CallObject(data->at, args));
+
+ QObject *result = 0;
+ if (PyErr_Occurred())
+ PyErr_Print();
+ else if (PyType_IsSubtype(Py_TYPE(retVal), data->type))
+ Shiboken::Conversions::pythonToCppPointer(qobjectType, retVal, &result);
+ return result;
+}
+
+// Implementation of QQmlListProperty<T>::ClearFunction callback
+void propListClear(QQmlListProperty<QObject> * propList)
+{
+ Shiboken::GilState state;
+
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTypeObject *qobjectType = qObjectType();
+ PyTuple_SET_ITEM(args, 0,
+ Shiboken::Conversions::pointerToPython(qobjectType, propList->object));
+
+ auto *data = reinterpret_cast<QmlListPropertyPrivate *>(propList->data);
+ Shiboken::AutoDecRef retVal(PyObject_CallObject(data->clear, args));
+
+ if (PyErr_Occurred())
+ PyErr_Print();
+}
+
+// Implementation of QQmlListProperty<T>::ReplaceFunction callback
+void propListReplace(QQmlListProperty<QObject> *propList, qsizetype index, QObject *value)
+{
+ Shiboken::GilState state;
+
+ Shiboken::AutoDecRef args(PyTuple_New(3));
+ PyTypeObject *qobjectType = qObjectType();
+ PyTuple_SET_ITEM(args, 0,
+ Shiboken::Conversions::pointerToPython(qobjectType, propList->object));
+ auto *converter = Shiboken::Conversions::PrimitiveTypeConverter<qsizetype>();
+ PyTuple_SET_ITEM(args, 1,
+ Shiboken::Conversions::copyToPython(converter, &index));
+ PyTuple_SET_ITEM(args, 2,
+ Shiboken::Conversions::pointerToPython(qobjectType, value));
+
+ auto *data = reinterpret_cast<QmlListPropertyPrivate *>(propList->data);
+ Shiboken::AutoDecRef retVal(PyObject_CallObject(data->replace, args));
+
+ if (PyErr_Occurred())
+ PyErr_Print();
+}
+
+// Implementation of QQmlListProperty<T>::RemoveLastFunction callback
+void propListRemoveLast(QQmlListProperty<QObject> *propList)
+{
+ Shiboken::GilState state;
+
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTypeObject *qobjectType = qObjectType();
+ PyTuple_SET_ITEM(args, 0,
+ Shiboken::Conversions::pointerToPython(qobjectType, propList->object));
+
+ auto *data = reinterpret_cast<QmlListPropertyPrivate *>(propList->data);
+ Shiboken::AutoDecRef retVal(PyObject_CallObject(data->removeLast, args));
+
+ if (PyErr_Occurred())
+ PyErr_Print();
+}
+
+// qt_metacall specialization for ListProperties
+void QmlListPropertyPrivate::metaCall(PyObject *source, QMetaObject::Call call, void **args)
+{
+ if (call != QMetaObject::ReadProperty)
+ return;
+
+ QObject *qobj;
+ PyTypeObject *qobjectType = qObjectType();
+ Shiboken::Conversions::pythonToCppPointer(qobjectType, source, &qobj);
+ QQmlListProperty<QObject> declProp(
+ qobj, this,
+ append && append != Py_None ? &propListAppender : nullptr,
+ count && count != Py_None ? &propListCount : nullptr,
+ at && at != Py_None ? &propListAt : nullptr,
+ clear && clear != Py_None ? &propListClear : nullptr,
+ replace && replace != Py_None ? &propListReplace : nullptr,
+ removeLast && removeLast != Py_None ? &propListRemoveLast : nullptr);
+
+ // Copy the data to the memory location requested by the meta call
+ void *v = args[0];
+ *reinterpret_cast<QQmlListProperty<QObject> *>(v) = declProp;
+}
+
+static const char *PropertyList_SignatureStrings[] = {
+ "PySide6.QtQml.ListProperty(self,type:type,append:typing.Callable,"
+ "at:typing.Callable=None,clear:typing.Callable=None,count:typing.Callable=None)",
+ nullptr // Sentinel
+};
+
+namespace PySide::Qml {
+
+void initQtQmlListProperty(PyObject *module)
+{
+ // Export QmlListProperty type
+ if (InitSignatureStrings(PropertyList_TypeF(), PropertyList_SignatureStrings) < 0) {
+ PyErr_Print();
+ qWarning() << "Error initializing PropertyList type.";
+ return;
+ }
+
+ // Register QQmlListProperty metatype for use in QML
+ qRegisterMetaType<QQmlListProperty<QObject>>();
+
+ Py_INCREF(reinterpret_cast<PyObject *>(PropertyList_TypeF()));
+ PyModule_AddObject(module, PepType_GetNameStr(PropertyList_TypeF()),
+ reinterpret_cast<PyObject *>(PropertyList_TypeF()));
+}
+
+} // namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqmllistproperty_p.h b/sources/pyside6/libpysideqml/pysideqmllistproperty_p.h
new file mode 100644
index 000000000..c00ffbf5b
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmllistproperty_p.h
@@ -0,0 +1,13 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLLISTPROPERTY_H
+#define PYSIDEQMLLISTPROPERTY_H
+
+#include <sbkpython.h>
+
+namespace PySide::Qml {
+void initQtQmlListProperty(PyObject *module);
+}
+
+#endif // PYSIDEQMLLISTPROPERTY_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlmacros.h b/sources/pyside6/libpysideqml/pysideqmlmacros.h
new file mode 100644
index 000000000..e9f24d269
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlmacros.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLMACROS_H
+#define PYSIDEQMLMACROS_H
+
+#include <shibokenmacros.h>
+
+#define PYSIDEQML_EXPORT LIBSHIBOKEN_EXPORT
+#define PYSIDEQML_IMPORT LIBSHIBOKEN_IMPORT
+
+#ifdef BUILD_LIBPYSIDEQML
+# define PYSIDEQML_API PYSIDEQML_EXPORT
+#else
+# define PYSIDEQML_API PYSIDEQML_IMPORT
+#endif
+
+#endif // PYSIDEQMLMACROS_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlmetacallerror.cpp b/sources/pyside6/libpysideqml/pysideqmlmetacallerror.cpp
new file mode 100644
index 000000000..63cefedb5
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlmetacallerror.cpp
@@ -0,0 +1,67 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmlmetacallerror_p.h"
+
+#include <sbkpython.h>
+#include <sbkstring.h>
+#include <autodecref.h>
+
+// Remove deprecated MACRO of copysign for MSVC #86286
+// https://github.com/python/cpython/issues/86286
+#ifdef copysign
+# undef copysign
+#endif
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlListProperty>
+
+#if __has_include (<private/qv4engine_p.h>)
+# define QML_PRIVATE_API_SUPPORT
+# include <private/qv4engine_p.h>
+# include <private/qv4context_p.h>
+# include <private/qqmldata_p.h>
+#endif
+
+namespace PySide::Qml {
+
+std::optional<int> qmlMetaCallErrorHandler(QObject *object)
+{
+#ifdef QML_PRIVATE_API_SUPPORT
+ // This JS engine grabber based off of Qt 5.5's `qjsEngine` function
+ QQmlData *data = QQmlData::get(object, false);
+ if (!data || data->jsWrapper.isNullOrUndefined())
+ return {};
+
+ QV4::ExecutionEngine *engine = data->jsWrapper.engine();
+ if (engine->currentStackFrame == nullptr)
+ return {};
+
+ PyObject *errType, *errValue, *errTraceback;
+ PyErr_Fetch(&errType, &errValue, &errTraceback);
+ // PYSIDE-464: The error is only valid before PyErr_Restore,
+ // PYSIDE-464: therefore we take local copies.
+ Shiboken::AutoDecRef objStr(PyObject_Str(errValue));
+ const QString errString = QString::fromUtf8(Shiboken::String::toCString(objStr));
+ const bool isSyntaxError = errType == PyExc_SyntaxError;
+ const bool isTypeError = errType == PyExc_TypeError;
+ PyErr_Restore(errType, errValue, errTraceback);
+
+ PyErr_Print(); // Note: PyErr_Print clears the error.
+
+ if (isSyntaxError)
+ return engine->throwSyntaxError(errString);
+ if (isTypeError)
+ return engine->throwTypeError(errString);
+ return engine->throwError(errString);
+#else
+ Q_UNUSED(object);
+ qWarning("libpyside6qml was built without QML private API support, error handling will not work.");
+ return {};
+#endif // QML_PRIVATE_API_SUPPORT
+}
+
+} // namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqmlmetacallerror_p.h b/sources/pyside6/libpysideqml/pysideqmlmetacallerror_p.h
new file mode 100644
index 000000000..fcbb6395d
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlmetacallerror_p.h
@@ -0,0 +1,21 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLMETACALLERROR_P_H
+#define PYSIDEQMLMETACALLERROR_P_H
+
+#include <optional>
+
+#include <QtCore/qtclasshelpermacros.h>
+
+QT_FORWARD_DECLARE_CLASS(QObject)
+
+namespace PySide::Qml {
+
+// Helper for SignalManager::qt_metacall():
+// Bubbles Python exceptions up to the Javascript engine, if called from one
+std::optional<int> qmlMetaCallErrorHandler(QObject *object);
+
+} // namespace PySide::Qml
+
+#endif // PYSIDEQMLMETACALLERROR_P_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlnamedelement.cpp b/sources/pyside6/libpysideqml/pysideqmlnamedelement.cpp
new file mode 100644
index 000000000..faf3e4116
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlnamedelement.cpp
@@ -0,0 +1,74 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmlnamedelement_p.h"
+#include <pysideclassdecorator_p.h>
+#include <pysideqmlregistertype_p.h>
+
+#include <shiboken.h>
+#include <signature.h>
+
+class PySideQmlNamedElementPrivate : public PySide::ClassDecorator::StringDecoratorPrivate
+{
+public:
+ PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) override;
+ const char *name() const override;
+};
+
+const char *PySideQmlNamedElementPrivate::name() const
+{
+ return "QmlNamedElement";
+}
+
+// The call operator is passed the class type and registers the type
+PyObject *PySideQmlNamedElementPrivate::tp_call(PyObject *self, PyObject *args, PyObject *)
+{
+ PyObject *klass = tp_call_check(args, CheckMode::WrappedType);
+ if (klass == nullptr)
+ return nullptr;
+
+ auto *data = DecoratorPrivate::get<PySideQmlNamedElementPrivate>(self);
+ auto *result = PySide::Qml::qmlNamedElementMacro(klass, data->string());
+ Py_XINCREF(result);
+ return result;
+}
+
+extern "C" {
+
+PyTypeObject *createPySideQmlNamedElementType(void)
+{
+ auto typeSlots =
+ PySide::ClassDecorator::Methods<PySideQmlNamedElementPrivate>::typeSlots();
+
+ PyType_Spec PySideQmlNamedElementType_spec = {
+ "2:PySide6.QtCore.qmlNamedElement",
+ sizeof(PySideClassDecorator),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ typeSlots.data()
+ };
+ return SbkType_FromSpec(&PySideQmlNamedElementType_spec);
+}
+
+PyTypeObject *PySideQmlNamedElement_TypeF(void)
+{
+ static auto *type = createPySideQmlNamedElementType();
+ return type;
+}
+
+} // extern "C"
+
+static const char *qmlNamedElement_SignatureStrings[] = {
+ "PySide6.QtQml.QmlNamedElement(self,reason:str)",
+ nullptr // Sentinel
+};
+
+void initQmlNamedElement(PyObject *module)
+{
+ if (InitSignatureStrings(PySideQmlNamedElement_TypeF(), qmlNamedElement_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideQmlNamedElement_TypeF());
+ PyModule_AddObject(module, "QmlNamedElement",
+ reinterpret_cast<PyObject *>(PySideQmlNamedElement_TypeF()));
+}
diff --git a/sources/pyside6/libpysideqml/pysideqmlnamedelement_p.h b/sources/pyside6/libpysideqml/pysideqmlnamedelement_p.h
new file mode 100644
index 000000000..4a4575de2
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlnamedelement_p.h
@@ -0,0 +1,11 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLNAMEDELEMENT_P_H
+#define PYSIDEQMLNAMEDELEMENT_P_H
+
+#include <sbkpython.h>
+
+void initQmlNamedElement(PyObject *module);
+
+#endif // PYSIDEQMLNAMEDELEMENT_P_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp b/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp
new file mode 100644
index 000000000..4ccd459d5
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlregistertype.cpp
@@ -0,0 +1,757 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmlregistertype.h"
+#include "pysideqmlregistertype_p.h"
+#include "pysideqmltypeinfo_p.h"
+#include "pysideqmlattached_p.h"
+#include "pysideqmlextended_p.h"
+#include "pysideqmluncreatable.h"
+
+#include <limits>
+#include <optional>
+
+// shiboken
+#include <shiboken.h>
+#include <sbkstring.h>
+
+// pyside
+#include <pyside.h>
+#include <pysideqobject.h>
+#include <pysideclassinfo.h>
+#include <pyside_p.h>
+
+#include <QtCore/QMutex>
+#include <QtCore/QTypeRevision>
+
+#include <QtQml/qqml.h>
+#include <QtQml/QJSValue>
+#include <QtQml/QQmlListProperty>
+#include <private/qqmlmetatype_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+
+#include <memory>
+
+using namespace Qt::StringLiterals;
+
+static PySide::Qml::QuickRegisterItemFunction quickRegisterItemFunction = nullptr;
+
+static const auto qmlElementKey = "QML.Element"_ba;
+
+static void createInto(void *memory, void *type)
+{
+ QMutexLocker locker(&PySide::nextQObjectMemoryAddrMutex());
+ PySide::setNextQObjectMemoryAddr(memory);
+ Shiboken::GilState state;
+ PyObject *obj = PyObject_CallObject(reinterpret_cast<PyObject *>(type), 0);
+ if (!obj || PyErr_Occurred())
+ PyErr_Print();
+ PySide::setNextQObjectMemoryAddr(nullptr);
+}
+
+PyTypeObject *qObjectType()
+{
+ static PyTypeObject *const result =
+ Shiboken::Conversions::getPythonTypeObject("QObject*");
+ assert(result);
+ return result;
+}
+
+static PyTypeObject *qQmlEngineType()
+{
+ static PyTypeObject *const result =
+ Shiboken::Conversions::getPythonTypeObject("QQmlEngine*");
+ assert(result);
+ return result;
+}
+
+static PyTypeObject *qQJSValueType()
+{
+ static PyTypeObject *const result =
+ Shiboken::Conversions::getPythonTypeObject("QJSValue*");
+ assert(result);
+ return result;
+}
+
+// Check if o inherits from baseClass
+static bool inheritsFrom(const QMetaObject *o, const char *baseClass)
+{
+ for (auto *base = o->superClass(); base ; base = base->superClass()) {
+ if (qstrcmp(base->className(), baseClass) == 0)
+ return true;
+ }
+ return false;
+}
+
+// Check if o inherits from QPyQmlPropertyValueSource.
+static inline bool isQmlPropertyValueSource(const QMetaObject *o)
+{
+ return inheritsFrom(o, "QPyQmlPropertyValueSource");
+}
+
+// Check if o inherits from QQmlParserStatus.
+static inline bool isQmlParserStatus(const QMetaObject *o)
+{
+ return inheritsFrom(o, "QPyQmlParserStatus");
+}
+
+static QByteArray getGlobalString(const char *name)
+{
+ PyObject *globalVar = PyDict_GetItemString(PyEval_GetGlobals(), name);
+
+ if (globalVar == nullptr || PyUnicode_Check(globalVar) == 0)
+ return {};
+
+ const char *stringValue = _PepUnicode_AsString(globalVar);
+ return stringValue != nullptr ? QByteArray(stringValue) : QByteArray{};
+}
+
+static int getGlobalInt(const char *name)
+{
+ PyObject *globalVar = PyDict_GetItemString(PyEval_GetGlobals(), name);
+
+ if (globalVar == nullptr || PyLong_Check(globalVar) == 0)
+ return -1;
+
+ long value = PyLong_AsLong(globalVar);
+
+ if (value > std::numeric_limits<int>::max() || value < std::numeric_limits<int>::min())
+ return -1;
+
+ return value;
+}
+
+struct ImportData
+{
+ QByteArray importName;
+ int majorVersion = 0;
+ int minorVersion = 0;
+
+ QTypeRevision toTypeRevision() const;
+};
+
+QTypeRevision ImportData::toTypeRevision() const
+{
+ return QTypeRevision::fromVersion(majorVersion, minorVersion);
+}
+
+std::optional<ImportData> getGlobalImportData(const char *decoratorName)
+{
+ ImportData result{getGlobalString("QML_IMPORT_NAME"),
+ getGlobalInt("QML_IMPORT_MAJOR_VERSION"),
+ getGlobalInt("QML_IMPORT_MINOR_VERSION")};
+
+ if (result.importName.isEmpty()) {
+ PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_NAME in order to use %s.",
+ decoratorName);
+ return {};
+ }
+
+ if (result.majorVersion == -1) {
+ PyErr_Format(PyExc_TypeError, "You need specify QML_IMPORT_MAJOR_VERSION in order to use %s.",
+ decoratorName);
+ return {};
+ }
+
+ // Specifying a minor version is optional
+ if (result.minorVersion == -1)
+ result.minorVersion = 0;
+ return result;
+}
+
+static PyTypeObject *checkTypeObject(PyObject *pyObj, const char *what)
+{
+ if (PyType_Check(pyObj) == 0) {
+ PyErr_Format(PyExc_TypeError, "%s can only be used for classes.", what);
+ return nullptr;
+ }
+ return reinterpret_cast<PyTypeObject *>(pyObj);
+}
+
+static bool setClassInfo(PyTypeObject *type, const QByteArray &key, const QByteArray &value)
+{
+ if (!PySide::ClassInfo::setClassInfo(type, key, value)) {
+ PyErr_Format(PyExc_TypeError, "Setting class info \"%s\" to \"%s\" on \"%s\" failed.",
+ key.constData(), value.constData(), type->tp_name);
+ return false;
+ }
+ return true;
+}
+
+static inline bool setSingletonClassInfo(PyTypeObject *type)
+{
+ return setClassInfo(type, "QML.Singleton"_ba, "true"_ba);
+}
+
+static QQmlCustomParser *defaultCustomParserFactory()
+{
+ return nullptr;
+}
+
+namespace PySide::Qml {
+
+// Modern (6.7) type registration using RegisterTypeAndRevisions
+// and information set to QMetaClassInfo.
+static int qmlRegisterType(PyObject *pyObj,
+ const ImportData &importData,
+ const QMetaObject *metaObject,
+ const QMetaObject *classInfoMetaObject = nullptr)
+{
+ PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj);
+
+ if (classInfoMetaObject == nullptr)
+ classInfoMetaObject = metaObject;
+
+ // Register as simple QObject rather than Qt Quick item.
+ // Incref the type object, don't worry about decref'ing it because
+ // there's no way to unregister a QML type.
+ Py_INCREF(pyObj);
+
+ const QByteArray typeName(pyObjType->tp_name);
+ QByteArray ptrType = typeName + '*';
+ QByteArray listType = QByteArrayLiteral("QQmlListProperty<") + typeName + '>';
+ const auto typeId = QMetaType(new QQmlMetaTypeInterface(ptrType));
+ const auto listId = QMetaType(new QQmlListMetaTypeInterface(listType, typeId.iface()));
+ const int objectSize = static_cast<int>(PySide::getSizeOfQObject(reinterpret_cast<PyTypeObject *>(pyObj)));
+
+ const auto typeInfo = qmlTypeInfo(pyObj);
+ const auto attachedInfo = qmlAttachedInfo(pyObjType, typeInfo);
+ const auto extendedInfo = qmlExtendedInfo(pyObj, typeInfo);
+
+ QList<int> ids;
+ QQmlPrivate::RegisterTypeAndRevisions type {
+ QQmlPrivate::RegisterType::StructVersion::Base, // structVersion
+ typeId, listId, objectSize,
+ createInto, // create
+ pyObj, // userdata
+ nullptr, // createValueType (Remove in Qt 7)
+ importData.importName.constData(),
+ importData.toTypeRevision(), // version
+ metaObject,
+ classInfoMetaObject,
+ attachedInfo.factory, // attachedPropertiesFunction
+ attachedInfo.metaObject, // attachedPropertiesMetaObject
+ 0, 0, 0, // parserStatusCast, valueSourceCast, valueInterceptorCast
+ extendedInfo.factory, // extensionObjectCreate
+ extendedInfo.metaObject, // extensionMetaObject
+ defaultCustomParserFactory, // customParser
+ &ids, // qmlTypeIds
+ 0, // finalizerCast
+ false, // forceAnonymous
+ {} // listMetaSequence
+ };
+
+ // Allow registering Qt Quick items.
+ const bool isQuickType = quickRegisterItemFunction && quickRegisterItemFunction(pyObj, &type);
+
+ if (!isQuickType) { // values filled by the Quick registration
+ // QPyQmlParserStatus inherits QObject, QQmlParserStatus, so,
+ // it is found behind the QObject.
+ type.parserStatusCast = isQmlParserStatus(metaObject)
+ ? int(sizeof(QObject))
+ : QQmlPrivate::StaticCastSelector<QObject, QQmlParserStatus>::cast();
+ // Similar for QPyQmlPropertyValueSource
+ type.valueSourceCast = isQmlPropertyValueSource(metaObject)
+ ? int(sizeof(QObject))
+ : QQmlPrivate::StaticCastSelector<QObject, QQmlPropertyValueSource>::cast();
+ type.valueInterceptorCast =
+ QQmlPrivate::StaticCastSelector<QObject, QQmlPropertyValueInterceptor>::cast();
+ }
+
+ QQmlPrivate::qmlregister(QQmlPrivate::TypeAndRevisionsRegistration, &type);
+ const int qmlTypeId = ids.value(0, -1);
+ if (qmlTypeId == -1) {
+ PyErr_Format(PyExc_TypeError, "QML meta type registration of \"%s\" failed.",
+ typeName.constData());
+ }
+ return qmlTypeId;
+}
+
+static int qmlRegisterType(PyObject *pyObj, PyObject *pyClassInfoObj,
+ const ImportData &importData)
+{
+ PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj);
+ if (!isQObjectDerived(pyObjType, true))
+ return -1;
+
+ const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType);
+ Q_ASSERT(metaObject);
+ const QMetaObject *classInfoMetaObject = pyObj == pyClassInfoObj
+ ? metaObject : PySide::retrieveMetaObject(pyClassInfoObj);
+ return qmlRegisterType(pyObj, importData, metaObject, classInfoMetaObject);
+}
+
+// Legacy (pre 6.7) compatibility helper for the free register functions.
+int qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int versionMinor,
+ const char *qmlName, const char *noCreationReason,
+ bool creatable)
+{
+ auto *type = checkTypeObject(pyObj, "qmlRegisterType()");
+ if (type == nullptr || !PySide::isQObjectDerived(type, true))
+ return -1;
+
+ const QMetaObject *metaObject = PySide::retrieveMetaObject(type);
+ Q_ASSERT(metaObject);
+
+ // PYSIDE-2709: Use a separate QMetaObject for the class information
+ // as modifying metaObject breaks inheritance.
+ QMetaObjectBuilder classInfobuilder(&QObject::staticMetaObject);
+ classInfobuilder.addClassInfo(qmlElementKey, qmlName);
+ if (!creatable)
+ setUncreatableClassInfo(&classInfobuilder, noCreationReason);
+ auto *classInfoMetaObject = classInfobuilder.toMetaObject();
+
+ const int qmlTypeId = qmlRegisterType(pyObj, {uri, versionMajor, versionMinor},
+ metaObject, classInfoMetaObject);
+ free(classInfoMetaObject);
+ return qmlTypeId;
+}
+
+// Singleton helpers
+
+// Check the arguments of a singleton callback (C++: "QJSValue cb(QQmlEngine *, QJSEngine *)",
+// but we drop the QJSEngine since it will be the same as QQmlEngine when the latter exists.
+static bool checkSingletonCallback(PyObject *callback)
+{
+ if (callback == nullptr) {
+ PyErr_SetString(PyExc_TypeError, "No callback specified.");
+ return false;
+ }
+ if (PyCallable_Check(callback) == 0) {
+ PyErr_Format(PyExc_TypeError, "Invalid callback specified (%S).", callback);
+ return false;
+ }
+ Shiboken::AutoDecRef funcCode(PyObject_GetAttrString(callback, "__code__"));
+ if (funcCode.isNull()) {
+ PyErr_Format(PyExc_TypeError, "Cannot retrieve code of callback (%S).", callback);
+ return false;
+ }
+ Shiboken::AutoDecRef argCountAttr(PyObject_GetAttrString(funcCode, "co_argcount"));
+ const int argCount = PyLong_AsLong(argCountAttr.object());
+ if (argCount != 1) {
+ PyErr_Format(PyExc_TypeError, "Callback (%S) has %d parameter(s), expected one.",
+ callback, argCount);
+ return false;
+ }
+
+ return true;
+}
+
+// Shared data of a singleton creation callback which dereferences an object on
+// destruction.
+class SingletonQObjectCreationSharedData
+{
+public:
+ Q_DISABLE_COPY_MOVE(SingletonQObjectCreationSharedData)
+
+ SingletonQObjectCreationSharedData(PyObject *cb, PyObject *ref = nullptr) noexcept :
+ callable(cb), reference(ref)
+ {
+ Py_XINCREF(ref);
+ }
+
+ // FIXME: Currently, the QML registration data are in global static variables
+ // and thus cleaned up after Python terminates. Once they are cleaned up
+ // by the QML engine, the code can be activated for proper cleanup of the references.
+ ~SingletonQObjectCreationSharedData()
+#if 0 //
+ ~SingletonQObjectCreationSharedData()
+ {
+ if (reference != nullptr) {
+ Shiboken::GilState gil;
+ Py_DECREF(reference);
+ }
+ }
+#else
+ = default;
+#endif
+
+ PyObject *callable{}; // Callback, static method or type object to be invoked.
+ PyObject *reference{}; // Object to dereference when going out scope
+};
+
+// Base class for QML singleton creation callbacks with helper for error checking.
+class SingletonQObjectCreationBase
+{
+protected:
+ explicit SingletonQObjectCreationBase(PyObject *cb, PyObject *ref = nullptr) :
+ m_data(std::make_shared<SingletonQObjectCreationSharedData>(cb, ref))
+ {
+ }
+
+ static QObject *handleReturnValue(PyObject *retVal);
+
+ std::shared_ptr<SingletonQObjectCreationSharedData> data() const { return m_data; }
+
+private:
+ std::shared_ptr<SingletonQObjectCreationSharedData> m_data;
+};
+
+QObject *SingletonQObjectCreationBase::handleReturnValue(PyObject *retVal)
+{
+ using Shiboken::Conversions::isPythonToCppPointerConvertible;
+ // Make sure the callback returns something we can convert, else the entire application will crash.
+ if (retVal == nullptr) {
+ PyErr_Format(PyExc_TypeError, "Callback returns 0 value.");
+ return nullptr;
+ }
+ if (isPythonToCppPointerConvertible(qObjectType(), retVal) == nullptr) {
+ PyErr_Format(PyExc_TypeError, "Callback returns invalid value (%S).", retVal);
+ return nullptr;
+ }
+
+ QObject *obj = nullptr;
+ Shiboken::Conversions::pythonToCppPointer(qObjectType(), retVal, &obj);
+ return obj;
+}
+
+// QML singleton creation callback by invoking a type object
+class SingletonQObjectFromTypeCreation : public SingletonQObjectCreationBase
+{
+public:
+ explicit SingletonQObjectFromTypeCreation(PyObject *typeObj) :
+ SingletonQObjectCreationBase(typeObj, typeObj) {}
+
+ QObject *operator ()(QQmlEngine *, QJSEngine *) const
+ {
+ Shiboken::GilState gil;
+ Shiboken::AutoDecRef args(PyTuple_New(0));
+ PyObject *retVal = PyObject_CallObject(data()->callable, args);
+ QObject *result = handleReturnValue(retVal);
+ if (result == nullptr)
+ Py_XDECREF(retVal);
+ return result;
+ }
+};
+
+// QML singleton creation by invoking a callback, passing QQmlEngine. Keeps a
+// references to the the callback.
+class SingletonQObjectCallbackCreation : public SingletonQObjectCreationBase
+{
+public:
+ explicit SingletonQObjectCallbackCreation(PyObject *callback) :
+ SingletonQObjectCreationBase(callback, callback) {}
+ explicit SingletonQObjectCallbackCreation(PyObject *callback, PyObject *ref) :
+ SingletonQObjectCreationBase(callback, ref) {}
+
+ QObject *operator ()(QQmlEngine *engine, QJSEngine *) const
+ {
+ Shiboken::GilState gil;
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTuple_SET_ITEM(args, 0,
+ Shiboken::Conversions::pointerToPython(qQmlEngineType(), engine));
+ PyObject *retVal = PyObject_CallObject(data()->callable, args);
+ QObject *result = handleReturnValue(retVal);
+ if (result == nullptr)
+ Py_XDECREF(retVal);
+ return result;
+ }
+};
+
+using SingletonQObjectCreation = std::function<QObject*(QQmlEngine *, QJSEngine *)>;
+
+// Modern (6.7) singleton type registration using RegisterSingletonTypeAndRevisions
+// and information set to QMetaClassInfo (QObject only pending QTBUG-110467).
+static int qmlRegisterSingletonTypeV2(PyObject *pyObj, PyObject *pyClassInfoObj,
+ const ImportData &importData,
+ const SingletonQObjectCreation &callback)
+{
+ PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj);
+ if (!isQObjectDerived(pyObjType, true))
+ return -1;
+
+ const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType);
+ Q_ASSERT(metaObject);
+ const QMetaObject *classInfoMetaObject = pyObj == pyClassInfoObj
+ ? metaObject : PySide::retrieveMetaObject(pyClassInfoObj);
+
+ QList<int> ids;
+ QQmlPrivate::RegisterSingletonTypeAndRevisions type {
+ QQmlPrivate::RegisterType::StructVersion::Base, // structVersion
+ importData.importName.constData(),
+ importData.toTypeRevision(), // version
+ callback, // qObjectApi,
+ metaObject,
+ classInfoMetaObject,
+ QMetaType(QMetaType::QObjectStar), // typeId
+ nullptr, // extensionMetaObject
+ nullptr, // extensionObjectCreate
+ &ids
+ };
+
+ QQmlPrivate::qmlregister(QQmlPrivate::SingletonAndRevisionsRegistration, &type);
+ const int qmlTypeId = ids.value(0, -1);
+ if (qmlTypeId == -1) {
+ PyErr_Format(PyExc_TypeError, "Singleton QML meta type registration of \"%s\" failed.",
+ pyObjType->tp_name);
+ }
+ return qmlTypeId;
+}
+
+// Legacy (pre 6.7) singleton type registration using RegisterSingletonType
+// for QObject and value types. Still used by qmlRegisterSingletonType()
+// for the hypothetical case of a value type.
+static int qmlRegisterSingletonType(PyObject *pyObj, const ImportData &importData,
+ const char *qmlName, PyObject *callback,
+ bool isQObject, bool hasCallback)
+{
+ if (hasCallback && !checkSingletonCallback(callback))
+ return -1;
+
+ const QMetaObject *metaObject = nullptr;
+
+ if (isQObject) {
+ PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj);
+
+ if (!isQObjectDerived(pyObjType, true))
+ return -1;
+
+ metaObject = PySide::retrieveMetaObject(pyObjType);
+ Q_ASSERT(metaObject);
+ }
+
+ QQmlPrivate::RegisterSingletonType type {
+ QQmlPrivate::RegisterType::StructVersion::Base, // structVersion
+ importData.importName.constData(),
+ importData.toTypeRevision(), // version
+ qmlName, // typeName
+ {}, // scriptApi
+ {}, // qObjectApi
+ metaObject, // instanceMetaObject
+ {}, // typeId
+ nullptr, // extensionMetaObject
+ nullptr, // extensionObjectCreate
+ {} // revision
+ };
+
+ if (isQObject) {
+ // FIXME: Fix this to assign new type ids each time.
+ type.typeId = QMetaType(QMetaType::QObjectStar);
+
+ if (hasCallback)
+ type.qObjectApi = SingletonQObjectCallbackCreation(callback);
+ else
+ type.qObjectApi = SingletonQObjectFromTypeCreation(pyObj);
+ } else {
+ type.scriptApi =
+ [callback](QQmlEngine *engine, QJSEngine *) -> QJSValue {
+ using namespace Shiboken;
+
+ Shiboken::GilState gil;
+ AutoDecRef args(PyTuple_New(1));
+
+ PyTuple_SET_ITEM(args, 0, Conversions::pointerToPython(
+ qQmlEngineType(), engine));
+
+ AutoDecRef retVal(PyObject_CallObject(callback, args));
+
+ PyTypeObject *qjsvalueType = qQJSValueType();
+
+ // Make sure the callback returns something we can convert, else the entire application will crash.
+ if (retVal.isNull() ||
+ Conversions::isPythonToCppPointerConvertible(qjsvalueType, retVal) == nullptr) {
+ PyErr_Format(PyExc_TypeError, "Callback returns invalid value.");
+ return QJSValue(QJSValue::UndefinedValue);
+ }
+
+ QJSValue *val = nullptr;
+ Conversions::pythonToCppPointer(qjsvalueType, retVal, &val);
+
+ Py_INCREF(retVal);
+
+ return *val;
+ };
+ }
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &type);
+}
+
+// Legacy (pre 6.7) compatibility helper for the free register functions.
+int qmlRegisterSingletonType(PyObject *pyObj,const char *uri,
+ int versionMajor, int versionMinor, const char *qmlName,
+ PyObject *callback, bool isQObject, bool hasCallback)
+{
+ return qmlRegisterSingletonType(pyObj, {uri, versionMajor, versionMinor}, qmlName,
+ callback, isQObject, hasCallback);
+}
+
+// Modern (6.7) singleton instance registration using RegisterSingletonTypeAndRevisions
+// and information set to QMetaClassInfo (QObject only).
+static int qmlRegisterSingletonInstance(PyObject *pyObj, const ImportData &importData,
+ PyObject *instanceObject)
+{
+ using namespace Shiboken;
+
+ // Check if the Python Type inherit from QObject
+ PyTypeObject *pyObjType = reinterpret_cast<PyTypeObject *>(pyObj);
+
+ if (!isQObjectDerived(pyObjType, true))
+ return -1;
+
+ // Convert the instanceObject (PyObject) into a QObject
+ QObject *instanceQObject = PySide::convertToQObject(instanceObject, true);
+ if (instanceQObject == nullptr)
+ return -1;
+
+ // Create Singleton Functor to pass the QObject to the Type registration step
+ // similarly to the case when we have a callback
+ QQmlPrivate::SingletonInstanceFunctor registrationFunctor;
+ registrationFunctor.m_object = instanceQObject;
+
+ const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType);
+ Q_ASSERT(metaObject);
+
+ QList<int> ids;
+ QQmlPrivate::RegisterSingletonTypeAndRevisions type {
+ QQmlPrivate::RegisterType::StructVersion::Base, // structVersion
+ importData.importName.constData(),
+ importData.toTypeRevision(), // version
+ registrationFunctor, // qObjectApi,
+ metaObject,
+ metaObject, // classInfoMetaObject
+ QMetaType(QMetaType::QObjectStar), // typeId
+ nullptr, // extensionMetaObject
+ nullptr, // extensionObjectCreate
+ &ids
+ };
+
+ QQmlPrivate::qmlregister(QQmlPrivate::SingletonAndRevisionsRegistration, &type);
+ return ids.value(0, -1);
+}
+
+// Legacy (pre 6.7) compatibility helper for the free register functions.
+int qmlRegisterSingletonInstance(PyObject *pyObj, const char *uri, int versionMajor,
+ int versionMinor, const char *qmlName,
+ PyObject *instanceObject)
+{
+ auto *type = checkTypeObject(pyObj, "qmlRegisterSingletonInstance()");
+ if (type == nullptr || !setClassInfo(type, qmlElementKey, qmlName)
+ || !setSingletonClassInfo(type)) {
+ return -1;
+ }
+ return qmlRegisterSingletonInstance(pyObj, {uri, versionMajor, versionMinor},
+ instanceObject);
+}
+
+} // namespace PySide::Qml
+
+enum class RegisterMode {
+ Normal,
+ Singleton
+};
+
+namespace PySide::Qml {
+
+// Check for a static create() method on a decorated singleton.
+// Might set a Python error if the check fails.
+static std::optional<SingletonQObjectCreation>
+ singletonCreateMethod(PyTypeObject *pyObjType)
+{
+ Shiboken::AutoDecRef tpDict(PepType_GetDict(pyObjType));
+ auto *create = PyDict_GetItemString(tpDict.object(), "create");
+ // Method decorated by "@staticmethod"
+ if (create == nullptr || std::strcmp(Py_TYPE(create)->tp_name, "staticmethod") != 0)
+ return std::nullopt;
+ // 3.10: "__wrapped__"
+ Shiboken::AutoDecRef function(PyObject_GetAttrString(create, "__func__"));
+ if (function.isNull()) {
+ PyErr_Format(PyExc_TypeError, "Cannot retrieve function of callback (%S).",
+ create);
+ return std::nullopt;
+ }
+ if (!checkSingletonCallback(function.object()))
+ return std::nullopt;
+ // Reference to the type needs to be kept.
+ return SingletonQObjectCallbackCreation(function.object(),
+ reinterpret_cast<PyObject *>(pyObjType));
+}
+
+PyObject *qmlElementMacro(PyObject *pyObj, const char *decoratorName,
+ const QByteArray &typeName)
+{
+ auto *pyObjType = checkTypeObject(pyObj, decoratorName);
+ if (pyObjType == nullptr)
+ return nullptr;
+
+ if (!PySide::isQObjectDerived(pyObjType, false)) {
+ PyErr_Format(PyExc_TypeError,
+ "%s can only be used with classes inherited from QObject, got %s.",
+ decoratorName, pyObjType->tp_name);
+ return nullptr;
+ }
+
+ if (!setClassInfo(pyObjType, qmlElementKey, typeName))
+ return nullptr;
+
+ RegisterMode mode = RegisterMode::Normal;
+ const auto info = PySide::Qml::qmlTypeInfo(pyObj);
+ auto *registerObject = pyObj;
+ if (info) {
+ if (info->flags.testFlag(PySide::Qml::QmlTypeFlag::Singleton)) {
+ mode = RegisterMode::Singleton;
+ setSingletonClassInfo(pyObjType);
+ }
+ if (info->foreignType)
+ registerObject = reinterpret_cast<PyObject *>(info->foreignType);
+ }
+
+ const auto importDataO = getGlobalImportData(decoratorName);
+ if (!importDataO.has_value())
+ return nullptr;
+ const auto importData = importDataO.value();
+
+ int result{};
+ if (mode == RegisterMode::Singleton) {
+ auto singletonCreateMethodO = singletonCreateMethod(pyObjType);
+ if (!singletonCreateMethodO.has_value()) {
+ if (PyErr_Occurred() != nullptr)
+ return nullptr;
+ singletonCreateMethodO = SingletonQObjectFromTypeCreation(pyObj);
+ }
+ result = PySide::Qml::qmlRegisterSingletonTypeV2(registerObject, pyObj, importData,
+ singletonCreateMethodO.value());
+ } else {
+ result = PySide::Qml::qmlRegisterType(registerObject, pyObj, importData);
+ }
+ if (result == -1) {
+ PyErr_Format(PyExc_TypeError, "%s: Failed to register type %s.",
+ decoratorName, pyObjType->tp_name);
+ return nullptr;
+ }
+
+ return pyObj;
+}
+
+PyObject *qmlElementMacro(PyObject *pyObj)
+{
+ return qmlElementMacro(pyObj, "QmlElement", "auto"_ba);
+}
+
+PyObject *qmlNamedElementMacro(PyObject *pyObj, const QByteArray &typeName)
+{
+ return qmlElementMacro(pyObj, "QmlNamedElement", typeName);
+}
+
+PyObject *qmlAnonymousMacro(PyObject *pyObj)
+{
+ return qmlElementMacro(pyObj, "QmlAnonymous", "anonymous"_ba);
+}
+
+PyObject *qmlSingletonMacro(PyObject *pyObj)
+{
+ PySide::Qml::ensureQmlTypeInfo(pyObj)->flags.setFlag(PySide::Qml::QmlTypeFlag::Singleton);
+ Py_INCREF(pyObj);
+ return pyObj;
+}
+
+QuickRegisterItemFunction getQuickRegisterItemFunction()
+{
+ return quickRegisterItemFunction;
+}
+
+void setQuickRegisterItemFunction(QuickRegisterItemFunction function)
+{
+ quickRegisterItemFunction = function;
+}
+
+} // namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqmlregistertype.h b/sources/pyside6/libpysideqml/pysideqmlregistertype.h
new file mode 100644
index 000000000..859172322
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlregistertype.h
@@ -0,0 +1,99 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLREGISTERTYPE_H
+#define PYSIDEQMLREGISTERTYPE_H
+
+#include "pysideqmlmacros.h"
+
+#include <sbkpython.h>
+#include <QtCore/qtconfigmacros.h>
+
+QT_BEGIN_NAMESPACE
+namespace QQmlPrivate
+{
+struct RegisterTypeAndRevisions;
+}
+QT_END_NAMESPACE
+
+namespace PySide::Qml
+{
+
+/**
+ * PySide implementation of qmlRegisterType<T> function.
+ *
+ * This is a helper for the legacy free qmlRegisterType*() type functions.
+ * Decorators should be used instead.
+ *
+ * \param pyObj Python type to be registered.
+ * \param uri QML element uri.
+ * \param versionMajor QML component major version.
+ * \param versionMinor QML component minor version.
+ * \param qmlName QML element name
+ * \return the metatype id of the registered type.
+ */
+PYSIDEQML_API int qmlRegisterType(PyObject *pyObj, const char *uri,
+ int versionMajor, int versionMinor,
+ const char *qmlName, const char *noCreationReason = nullptr,
+ bool creatable = true);
+
+/**
+ * PySide implementation of qmlRegisterSingletonType<T> function.
+ *
+ * This is a helper for the legacy free qmlRegisterSingletonType<T> type function.
+ * Decorators should be used instead.
+ *
+ * \param pyObj Python type to be registered.
+ * \param uri QML element uri.
+ * \param versionMajor QML component major version.
+ * \param versionMinor QML component minor version.
+ * \param qmlName QML element name
+ * \param callback Registration callback
+ * \return the metatype id of the registered type.
+ */
+PYSIDEQML_API int qmlRegisterSingletonType(PyObject *pyObj,const char *uri,
+ int versionMajor, int versionMinor, const char *qmlName,
+ PyObject *callback, bool isQObject, bool hasCallback);
+
+/**
+ * PySide implementation of qmlRegisterSingletonInstance<T> function.
+ *
+ * \param pyObj Python type to be registered.
+ * \param uri QML element uri.
+ * \param versionMajor QML component major version.
+ * \param versionMinor QML component minor version.
+ * \param qmlName QML element name
+ * \param instanceObject singleton object to be registered.
+ * \return the metatype id of the registered type.
+ */
+PYSIDEQML_API int qmlRegisterSingletonInstance(PyObject *pyObj, const char *uri,
+ int versionMajor, int versionMinor,
+ const char *qmlName, PyObject *instanceObject);
+
+/**
+ * PySide implementation of the QML_ELEMENT macro
+ *
+ * \param pyObj Python type to be registered
+ */
+PYSIDEQML_API PyObject *qmlElementMacro(PyObject *pyObj);
+
+/// PySide implementation of the QML_ANONYMOUS macro
+/// \param pyObj Python type to be registered
+PYSIDEQML_API PyObject *qmlAnonymousMacro(PyObject *pyObj);
+
+/// PySide implementation of the QML_SINGLETON macro
+/// \param pyObj Python type to be registered
+PYSIDEQML_API PyObject *qmlSingletonMacro(PyObject *pyObj);
+
+
+// Used by QtQuick module to fill the QQmlPrivate::RegisterType::parserStatusCast,
+// valueSourceCast and valueInterceptorCast fields with the correct values.
+using QuickRegisterItemFunction =
+ bool (*)(PyObject *pyObj, QT_PREPEND_NAMESPACE(QQmlPrivate::RegisterTypeAndRevisions) *);
+
+PYSIDEQML_API QuickRegisterItemFunction getQuickRegisterItemFunction();
+PYSIDEQML_API void setQuickRegisterItemFunction(QuickRegisterItemFunction function);
+
+} // namespace PySide::Qml
+
+#endif // PYSIDEQMLREGISTERTYPE_H
diff --git a/sources/pyside6/libpysideqml/pysideqmlregistertype_p.h b/sources/pyside6/libpysideqml/pysideqmlregistertype_p.h
new file mode 100644
index 000000000..f11f92241
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmlregistertype_p.h
@@ -0,0 +1,20 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLREGISTERTYPE_P_H
+#define PYSIDEQMLREGISTERTYPE_P_H
+
+#include <sbkpython.h>
+
+#include <QtCore/QByteArray>
+
+PyTypeObject *qObjectType();
+
+
+namespace PySide::Qml {
+
+PyObject *qmlNamedElementMacro(PyObject *pyObj, const QByteArray &typeName);
+
+}
+
+#endif // PYSIDEQMLREGISTERTYPE_P_H
diff --git a/sources/pyside6/libpysideqml/pysideqmltypeinfo.cpp b/sources/pyside6/libpysideqml/pysideqmltypeinfo.cpp
new file mode 100644
index 000000000..f369f7400
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmltypeinfo.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmltypeinfo_p.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+
+#include <algorithm>
+
+namespace PySide::Qml {
+
+using QmlTypeInfoHash = QHash<const PyObject *, QmlTypeInfoPtr>;
+
+Q_GLOBAL_STATIC(QmlTypeInfoHash, qmlTypeInfoHashStatic);
+
+QmlTypeInfoPtr ensureQmlTypeInfo(const PyObject *o)
+{
+ auto *hash = qmlTypeInfoHashStatic();
+ auto it = hash->find(o);
+ if (it == hash->end())
+ it = hash->insert(o, std::make_shared<QmlTypeInfo>());
+ return it.value();
+}
+
+void insertQmlTypeInfoAlias(const PyObject *o, const QmlTypeInfoPtr &value)
+{
+ qmlTypeInfoHashStatic()->insert(o, value);
+}
+
+QmlTypeInfoPtr qmlTypeInfo(const PyObject *o)
+{
+ auto *hash = qmlTypeInfoHashStatic();
+ auto it = hash->constFind(o);
+ return it != hash->cend() ? it.value() : QmlTypeInfoPtr{};
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const QmlTypeInfo &i)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "QmlTypeInfo(" << i.flags;
+ if (i.foreignType)
+ d << ", foreignType=" << i.foreignType->tp_name;
+ if (i.attachedType)
+ d << ", attachedType=" << i.attachedType->tp_name;
+ if (i.extensionType)
+ d << ", extensionType=" << i.extensionType->tp_name;
+ d << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const QmlExtensionInfo &e)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "QmlExtensionInfo(";
+ if (e.factory != nullptr && e.metaObject != nullptr)
+ d << '"' << e.metaObject->className() << "\", factory="
+ << reinterpret_cast<const void *>(e.factory);
+ d << ')';
+ return d;
+}
+
+#endif // QT_NO_DEBUG_STREAM
+
+} // namespace PySide::Qml
diff --git a/sources/pyside6/libpysideqml/pysideqmltypeinfo_p.h b/sources/pyside6/libpysideqml/pysideqmltypeinfo_p.h
new file mode 100644
index 000000000..112e127a7
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmltypeinfo_p.h
@@ -0,0 +1,59 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLTYPEINFO_P_H
+#define PYSIDEQMLTYPEINFO_P_H
+
+#include <sbkpython.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QFlags>
+
+#include <memory>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+QT_FORWARD_DECLARE_CLASS(QObject)
+QT_FORWARD_DECLARE_STRUCT(QMetaObject)
+
+namespace PySide::Qml {
+
+enum class QmlTypeFlag
+{
+ Singleton = 0x1
+};
+
+Q_DECLARE_FLAGS(QmlTypeFlags, QmlTypeFlag)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QmlTypeFlags)
+
+// Type information associated with QML type objects
+struct QmlTypeInfo
+{
+ QmlTypeFlags flags;
+ PyTypeObject *foreignType = nullptr;
+ PyTypeObject *attachedType = nullptr;
+ PyTypeObject *extensionType = nullptr;
+};
+
+using QmlTypeInfoPtr = std::shared_ptr<QmlTypeInfo>;
+
+QmlTypeInfoPtr ensureQmlTypeInfo(const PyObject *o);
+void insertQmlTypeInfoAlias(const PyObject *o, const QmlTypeInfoPtr &value);
+QmlTypeInfoPtr qmlTypeInfo(const PyObject *o);
+
+// Meta Object and factory function for QmlExtended/QmlAttached
+struct QmlExtensionInfo
+{
+ using Factory = QObject *(*)(QObject *);
+
+ Factory factory;
+ const QMetaObject *metaObject;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const QmlTypeInfo &);
+QDebug operator<<(QDebug d, const QmlExtensionInfo &);
+#endif
+
+} // namespace PySide::Qml
+
+#endif // PYSIDEQMLTYPEINFO_P_H
diff --git a/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp b/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp
new file mode 100644
index 000000000..7c0f6b8ff
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmluncreatable.cpp
@@ -0,0 +1,118 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "pysideqmluncreatable.h"
+#include <pysideclassdecorator_p.h>
+#include <pysideclassinfo.h>
+
+#include <shiboken.h>
+#include <signature.h>
+#include <sbkcppstring.h>
+
+#include <QtCore/qbytearray.h>
+#include <private/qmetaobjectbuilder_p.h>
+
+using namespace Qt::StringLiterals;
+
+class PySideQmlUncreatablePrivate : public PySide::ClassDecorator::StringDecoratorPrivate
+{
+public:
+ PyObject *tp_call(PyObject *self, PyObject *args, PyObject * /* kw */) override;
+ int tp_init(PyObject *self, PyObject *args, PyObject *kwds) override;
+ const char *name() const override;
+};
+
+const char *PySideQmlUncreatablePrivate::name() const
+{
+ return "QmlUncreatable";
+}
+
+// The call operator is passed the class type and registers the reason
+// in the uncreatableReasonMap()
+PyObject *PySideQmlUncreatablePrivate::tp_call(PyObject *self, PyObject *args, PyObject * /* kw */)
+{
+ PyObject *klass = tp_call_check(args, CheckMode::WrappedType);
+ if (klass== nullptr)
+ return nullptr;
+
+ auto *type = reinterpret_cast<PyTypeObject *>(klass);
+ auto *data = DecoratorPrivate::get<PySideQmlUncreatablePrivate>(self);
+ setUncreatableClassInfo(type, data->string());
+
+ Py_INCREF(klass);
+ return klass;
+}
+
+int PySideQmlUncreatablePrivate::tp_init(PyObject *self, PyObject *args, PyObject * /* kwds */)
+{
+ int result = -1;
+ const auto argsCount = PyTuple_Size(args);
+ if (argsCount == 0) {
+ result = 0; // QML-generated reason
+ } else if (argsCount == 1) {
+ PyObject *arg = PyTuple_GET_ITEM(args, 0);
+ result = arg == Py_None
+ ? 0 // QML-generated reason
+ : convertToString(self, args);
+ }
+
+ if (result != 0) {
+ PyErr_Format(PyExc_TypeError,
+ "QmlUncreatable() takes a single string argument or no argument");
+ }
+
+ return result;
+}
+
+extern "C" {
+
+PyTypeObject *createPySideQmlUncreatableType(void)
+{
+ auto typeSlots =
+ PySide::ClassDecorator::Methods<PySideQmlUncreatablePrivate>::typeSlots();
+
+ PyType_Spec PySideQmlUncreatableType_spec = {
+ "2:PySide6.QtCore.qmlUncreatable",
+ sizeof(PySideClassDecorator),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ typeSlots.data()
+ };
+ return SbkType_FromSpec(&PySideQmlUncreatableType_spec);
+}
+
+PyTypeObject *PySideQmlUncreatable_TypeF(void)
+{
+ static auto *type = createPySideQmlUncreatableType();
+ return type;
+}
+
+} // extern "C"
+
+static const char *qmlUncreatable_SignatureStrings[] = {
+ "PySide6.QtQml.QmlUncreatable(self,reason:str)",
+ nullptr // Sentinel
+};
+
+void initQmlUncreatable(PyObject *module)
+{
+ if (InitSignatureStrings(PySideQmlUncreatable_TypeF(), qmlUncreatable_SignatureStrings) < 0)
+ return;
+
+ Py_INCREF(PySideQmlUncreatable_TypeF());
+ PyModule_AddObject(module, "QmlUncreatable",
+ reinterpret_cast<PyObject *>(PySideQmlUncreatable_TypeF()));
+}
+
+void setUncreatableClassInfo(PyTypeObject *type, const QByteArray &reason)
+{
+ PySide::ClassInfo::setClassInfo(type, {
+ {"QML.Creatable"_ba, "false"_ba},
+ {"QML.UncreatableReason"_ba, reason} });
+}
+
+void setUncreatableClassInfo(QMetaObjectBuilder *builder, const QByteArray &reason)
+{
+ builder->addClassInfo("QML.Creatable", "false");
+ builder->addClassInfo("QML.UncreatableReason", reason);
+}
diff --git a/sources/pyside6/libpysideqml/pysideqmluncreatable.h b/sources/pyside6/libpysideqml/pysideqmluncreatable.h
new file mode 100644
index 000000000..8a8adb3c8
--- /dev/null
+++ b/sources/pyside6/libpysideqml/pysideqmluncreatable.h
@@ -0,0 +1,26 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYSIDEQMLUNCREATABLE_H
+#define PYSIDEQMLUNCREATABLE_H
+
+#include <sbkpython.h>
+
+#include <QtCore/QByteArray>
+
+QT_FORWARD_DECLARE_CLASS(QMetaObjectBuilder)
+
+// The QmlUncreatable decorator modifies QmlElement to register an uncreatable
+// type. Due to the (reverse) execution order of decorators, it needs to follow
+// QmlElement.
+extern "C"
+{
+ extern PyTypeObject *PySideQmlUncreatable_TypeF(void);
+}
+
+void initQmlUncreatable(PyObject *module);
+
+void setUncreatableClassInfo(PyTypeObject *type, const QByteArray &reason);
+void setUncreatableClassInfo(QMetaObjectBuilder *builder, const QByteArray &reason);
+
+#endif // PYSIDEQMLUNCREATABLE_H
diff --git a/sources/pyside6/plugins/designer/CMakeLists.txt b/sources/pyside6/plugins/designer/CMakeLists.txt
new file mode 100644
index 000000000..717652314
--- /dev/null
+++ b/sources/pyside6/plugins/designer/CMakeLists.txt
@@ -0,0 +1,59 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(PySidePlugin)
+
+# Note: At runtime, the dependency to the shiboken library is resolved
+# by the pyside_tool.py wrapper
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 COMPONENTS Core Gui Widgets UiPlugin)
+
+qt_add_plugin(PySidePlugin)
+
+target_sources(PySidePlugin PRIVATE
+ designercustomwidgets.cpp designercustomwidgets.h
+)
+
+# See libshiboken/CMakeLists.txt
+
+target_compile_definitions(PySidePlugin PRIVATE -DQT_NO_KEYWORDS=1)
+
+if(PYTHON_LIMITED_API)
+ target_compile_definitions(PySidePlugin PRIVATE "-DPy_LIMITED_API=0x03050000")
+endif()
+
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ if(PYTHON_WITH_DEBUG)
+ target_compile_definitions(PySidePlugin PRIVATE "-DPy_DEBUG")
+ endif()
+ if (PYTHON_WITH_COUNT_ALLOCS)
+ target_compile_definitions(PySidePlugin PRIVATE "-DCOUNT_ALLOCS")
+ endif()
+elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
+ target_compile_definitions(PySidePlugin PRIVATE "-DNDEBUG")
+endif()
+
+target_include_directories(PySidePlugin PRIVATE ../uitools)
+
+set_target_properties(PySidePlugin PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+get_property(SHIBOKEN_PYTHON_LIBRARIES GLOBAL PROPERTY shiboken_python_libraries)
+get_property(SHIBOKEN_PYTHON_INCLUDE_DIRS GLOBAL PROPERTY shiboken_python_include_dirs)
+
+target_include_directories(PySidePlugin PRIVATE ${SHIBOKEN_PYTHON_INCLUDE_DIRS})
+
+target_link_libraries(PySidePlugin PRIVATE
+ Qt::Core
+ Qt::Gui
+ Qt::UiPlugin
+ Qt::Widgets
+ ${SHIBOKEN_PYTHON_LIBRARIES})
+
+install(TARGETS PySidePlugin LIBRARY DESTINATION "${QT6_INSTALL_PLUGINS}/designer")
diff --git a/sources/pyside6/plugins/designer/designercustomwidgets.cpp b/sources/pyside6/plugins/designer/designercustomwidgets.cpp
new file mode 100644
index 000000000..d23156a9d
--- /dev/null
+++ b/sources/pyside6/plugins/designer/designercustomwidgets.cpp
@@ -0,0 +1,261 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#undef slots
+#include <Python.h> // Include before Qt headers due to 'slots' macro definition
+
+#include "designercustomwidgets.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfoList>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QOperatingSystemVersion>
+#include <QtCore/QTextStream>
+#include <QtCore/QVariant>
+
+#include <string_view>
+
+using namespace Qt::StringLiterals;
+
+Q_LOGGING_CATEGORY(lcPySidePlugin, "qt.pysideplugin")
+
+static const char pathVar[] = "PYSIDE_DESIGNER_PLUGINS";
+static const char pythonPathVar[] = "PYTHONPATH";
+
+// Find the static instance of 'QPyDesignerCustomWidgetCollection'
+// registered as a dynamic property of QCoreApplication.
+static QDesignerCustomWidgetCollectionInterface *findPyDesignerCustomWidgetCollection()
+{
+ static const char propertyName[] = "__qt_PySideCustomWidgetCollection";
+ if (auto *coreApp = QCoreApplication::instance()) {
+ const QVariant value = coreApp->property(propertyName);
+ if (value.isValid() && value.canConvert<void *>())
+ return reinterpret_cast<QDesignerCustomWidgetCollectionInterface *>(value.value<void *>());
+ }
+ return nullptr;
+}
+
+static QString pyStringToQString(PyObject *s)
+{
+ // PyUnicode_AsUTF8() is not available in the Limited API
+ if (PyObject *bytesStr = PyUnicode_AsEncodedString(s, "utf8", nullptr))
+ return QString::fromUtf8(PyBytes_AsString(bytesStr));
+ return {};
+}
+
+// Return str() of a Python object
+static QString pyStr(PyObject *o)
+{
+ PyObject *pstr = PyObject_Str(o);
+ return pstr != nullptr ? pyStringToQString(pstr) : QString();
+}
+
+static QString pyErrorMessage()
+{
+ QString result = "<error information not available>"_L1;
+ PyObject *ptype = {};
+ PyObject *pvalue = {};
+ PyObject *ptraceback = {};
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ if (pvalue != nullptr)
+ result = pyStr(pvalue);
+ PyErr_Restore(ptype, pvalue, ptraceback);
+ return result;
+}
+
+
+#ifdef Py_LIMITED_API
+// Provide PyRun_String() for limited API (see libshiboken/pep384impl.cpp)
+// Flags are ignored in these simple helpers.
+PyObject *PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
+{
+ PyObject *code = Py_CompileString(str, "pyscript", start);
+ PyObject *ret = nullptr;
+
+ if (code != nullptr) {
+ ret = PyEval_EvalCode(code, globals, locals);
+ }
+ Py_XDECREF(code);
+ return ret;
+}
+#endif // Py_LIMITED_API
+
+static bool runPyScript(const char *script, QString *errorMessage)
+{
+ PyObject *main = PyImport_AddModule("__main__");
+ if (main == nullptr) {
+ *errorMessage = "Internal error: Cannot retrieve __main__"_L1;
+ return false;
+ }
+ PyObject *globalDictionary = PyModule_GetDict(main);
+ PyObject *localDictionary = PyDict_New();
+ // Note: Limited API only has PyRun_String()
+ PyObject *result = PyRun_String(script, Py_file_input, globalDictionary, localDictionary);
+ const bool ok = result != nullptr;
+ Py_DECREF(localDictionary);
+ Py_XDECREF(result);
+ if (!ok) {
+ *errorMessage = pyErrorMessage();
+ PyErr_Clear();
+ }
+ return ok;
+}
+
+static bool runPyScriptFile(const QString &fileName, QString *errorMessage)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly| QIODevice::Text)) {
+ QTextStream(errorMessage) << "Cannot open "
+ << QDir::toNativeSeparators(fileName) << " for reading: "
+ << file.errorString();
+ return false;
+ }
+
+ const QByteArray script = file.readAll();
+ file.close();
+ const bool ok = runPyScript(script.constData(), errorMessage);
+ if (!ok && !errorMessage->isEmpty()) {
+ errorMessage->prepend("Error running "_L1 + fileName + ": "_L1);
+ }
+ return ok;
+}
+
+static void initVirtualEnvironment()
+{
+ static const char virtualEnvVar[] = "VIRTUAL_ENV";
+ // As of Python 3.8/Windows, Python is no longer able to run stand-alone in
+ // a virtualenv due to missing libraries. Add the path to the modules
+ // instead. macOS seems to be showing the same issues.
+
+ const auto os = QOperatingSystemVersion::currentType();
+
+ bool ok;
+ int majorVersion = qEnvironmentVariableIntValue("PY_MAJOR_VERSION", &ok);
+ int minorVersion = qEnvironmentVariableIntValue("PY_MINOR_VERSION", &ok);
+ if (!ok) {
+ majorVersion = PY_MAJOR_VERSION;
+ minorVersion = PY_MINOR_VERSION;
+ }
+
+ if (!qEnvironmentVariableIsSet(virtualEnvVar)
+ || (os != QOperatingSystemVersion::MacOS && os != QOperatingSystemVersion::Windows)
+ || (majorVersion == 3 && minorVersion < 8)) {
+ return;
+ }
+
+ const QByteArray virtualEnvPath = qgetenv(virtualEnvVar);
+ QByteArray pythonPath = qgetenv(pythonPathVar);
+ if (!pythonPath.isEmpty())
+ pythonPath.append(QDir::listSeparator().toLatin1());
+
+ switch (os) {
+ case QOperatingSystemVersion::Windows:
+ pythonPath.append(virtualEnvPath + R"(\Lib\site-packages)");
+ break;
+ case QOperatingSystemVersion::MacOS:
+ pythonPath.append(virtualEnvPath + "/lib/python"_ba +
+ QByteArray::number(majorVersion) + '.'
+ + QByteArray::number(minorVersion)
+ + "/site-packages"_ba);
+ break;
+ default:
+ break;
+ }
+
+ qputenv(pythonPathVar, pythonPath);
+}
+
+static void initPython()
+{
+ // Py_SetProgramName() is considered harmful, it can break virtualenv.
+ initVirtualEnvironment();
+
+ Py_Initialize();
+ qAddPostRoutine(Py_Finalize);
+}
+
+static bool withinQtDesigner = false;
+
+PyDesignerCustomWidgets::PyDesignerCustomWidgets(QObject *parent) : QObject(parent)
+{
+ qCDebug(lcPySidePlugin, "%s", __FUNCTION__);
+
+ withinQtDesigner = QCoreApplication::applicationName() == u"Designer"
+ && QCoreApplication::organizationName() == u"QtProject";
+
+ if (!qEnvironmentVariableIsSet(pathVar)) {
+ if (withinQtDesigner) {
+ qCWarning(lcPySidePlugin, "Environment variable %s is not set, bailing out.",
+ pathVar);
+ }
+ return;
+ }
+
+ QStringList pythonFiles;
+ const QString pathStr = qEnvironmentVariable(pathVar);
+ const QChar listSeparator = QDir::listSeparator();
+ const auto paths = pathStr.split(listSeparator);
+ const QStringList oldPythonPaths =
+ qEnvironmentVariable(pythonPathVar).split(listSeparator, Qt::SkipEmptyParts);
+ QStringList pythonPaths = oldPythonPaths;
+ // Scan for register*.py in the path
+ for (const auto &p : paths) {
+ QDir dir(p);
+ if (dir.exists()) {
+ const QFileInfoList matches =
+ dir.entryInfoList({u"register*.py"_s}, QDir::Files,
+ QDir::Name);
+ for (const auto &fi : matches)
+ pythonFiles.append(fi.absoluteFilePath());
+ if (!matches.isEmpty()) {
+ const QString dir =
+ QDir::toNativeSeparators(matches.constFirst().absolutePath());
+ if (!oldPythonPaths.contains(dir))
+ pythonPaths.append(dir);
+ }
+ } else {
+ qCWarning(lcPySidePlugin, "Directory '%s' as specified in %s does not exist.",
+ qPrintable(p), pathVar);
+ }
+ }
+ if (pythonFiles.isEmpty()) {
+ qCWarning(lcPySidePlugin, "No python files found in '%s'.", qPrintable(pathStr));
+ return;
+ }
+
+ // Make modules available by adding them to the path
+ if (pythonPaths != oldPythonPaths) {
+ const QByteArray value = pythonPaths.join(listSeparator).toLocal8Bit();
+ qCDebug(lcPySidePlugin) << "setting" << pythonPathVar << value;
+ qputenv(pythonPathVar, value);
+ }
+
+ // Might be initialized already, for example, when loaded from QUiLoader.
+ if (Py_IsInitialized() == 0)
+ initPython();
+
+ // Run all register*py files
+ QString errorMessage;
+ for (const auto &pythonFile : std::as_const(pythonFiles)) {
+ qCDebug(lcPySidePlugin) << "running" << pythonFile;
+ if (!runPyScriptFile(pythonFile, &errorMessage))
+ qCWarning(lcPySidePlugin, "%s", qPrintable(errorMessage));
+ }
+}
+
+PyDesignerCustomWidgets::~PyDesignerCustomWidgets()
+{
+ qCDebug(lcPySidePlugin, "%s", __FUNCTION__);
+}
+
+QList<QDesignerCustomWidgetInterface *> PyDesignerCustomWidgets::customWidgets() const
+{
+ if (auto *collection = findPyDesignerCustomWidgetCollection())
+ return collection->customWidgets();
+ if (withinQtDesigner)
+ qCWarning(lcPySidePlugin, "No instance of QPyDesignerCustomWidgetCollection was found.");
+ return {};
+}
diff --git a/sources/pyside6/plugins/designer/designercustomwidgets.h b/sources/pyside6/plugins/designer/designercustomwidgets.h
new file mode 100644
index 000000000..2f1db1f31
--- /dev/null
+++ b/sources/pyside6/plugins/designer/designercustomwidgets.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PY_DESIGNER_CUSTOM_WIDGETS_H_
+#define PY_DESIGNER_CUSTOM_WIDGETS_H_
+
+#include <QtUiPlugin/QDesignerCustomWidgetCollectionInterface>
+
+// A Qt Designer plugin proxying the QDesignerCustomWidgetCollectionInterface
+// instance set as as a dynamic property on QCoreApplication by the PySide6
+// Qt Designer module.
+class PyDesignerCustomWidgets: public QObject,
+ public QDesignerCustomWidgetCollectionInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.PySide.PyDesignerCustomWidgetsInterface")
+
+public:
+ Q_DISABLE_COPY_MOVE(PyDesignerCustomWidgets)
+
+ explicit PyDesignerCustomWidgets(QObject *parent = nullptr);
+ ~PyDesignerCustomWidgets() override;
+
+ QList<QDesignerCustomWidgetInterface *> customWidgets() const override;
+};
+
+#endif // PY_DESIGNER_CUSTOM_WIDGETS_H_
diff --git a/sources/pyside6/plugins/uitools/CMakeLists.txt b/sources/pyside6/plugins/uitools/CMakeLists.txt
new file mode 100644
index 000000000..06d0ae900
--- /dev/null
+++ b/sources/pyside6/plugins/uitools/CMakeLists.txt
@@ -0,0 +1,35 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(plugins)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 COMPONENTS Core Gui Widgets UiPlugin)
+
+set(ui_plugin_src
+ customwidgets.cpp customwidgets.h
+ customwidget.cpp customwidget.h
+)
+
+add_library(uiplugin STATIC ${ui_plugin_src})
+if(CMAKE_HOST_UNIX AND NOT CYGWIN)
+ add_definitions(-fPIC)
+endif()
+add_definitions(-DQT_STATICPLUGIN)
+
+set_property(TARGET pyside6 PROPERTY CXX_STANDARD 17)
+
+target_link_libraries(uiplugin
+ Qt::Core
+ Qt::Gui
+ Qt::UiPlugin
+ Qt::Widgets
+ Shiboken6::libshiboken)
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_DEBUG_POSTFIX})
+else()
+ set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_RELEASE_POSTFIX})
+endif()
diff --git a/sources/pyside6/plugins/uitools/customwidget.cpp b/sources/pyside6/plugins/uitools/customwidget.cpp
new file mode 100644
index 000000000..976754feb
--- /dev/null
+++ b/sources/pyside6/plugins/uitools/customwidget.cpp
@@ -0,0 +1,104 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "customwidget.h"
+#include <QtCore/qdebug.h>
+
+// Part of the static plugin linked to the QtUiLoader Python module,
+// allowing it to create a custom widget written in Python.
+PyCustomWidget::PyCustomWidget(PyObject *objectType) :
+ m_pyObject(objectType),
+ m_name(QString::fromUtf8(reinterpret_cast<PyTypeObject *>(objectType)->tp_name))
+{
+}
+
+bool PyCustomWidget::isContainer() const
+{
+ return false;
+}
+
+bool PyCustomWidget::isInitialized() const
+{
+ return m_initialized;
+}
+
+QIcon PyCustomWidget::icon() const
+{
+ return {};
+}
+
+QString PyCustomWidget::domXml() const
+{
+ return {};
+}
+
+QString PyCustomWidget::group() const
+{
+ return {};
+}
+
+QString PyCustomWidget::includeFile() const
+{
+ return {};
+}
+
+QString PyCustomWidget::name() const
+{
+ return m_name;
+}
+
+QString PyCustomWidget::toolTip() const
+{
+ return {};
+}
+
+QString PyCustomWidget::whatsThis() const
+{
+ return {};
+}
+
+// A copy of this code exists in PyDesignerCustomWidget::createWidget()
+// (see sources/pyside6/PySide6/QtDesigner/qpydesignercustomwidgetcollection.cpp).
+QWidget *PyCustomWidget::createWidget(QWidget *parent)
+{
+ // Create a python instance and return cpp object
+ PyObject *pyParent = nullptr;
+ bool unknownParent = false;
+ if (parent != nullptr) {
+ pyParent = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(parent));
+ if (pyParent != nullptr) {
+ Py_INCREF(pyParent);
+ } else {
+ static Shiboken::Conversions::SpecificConverter converter("QWidget*");
+ pyParent = converter.toPython(&parent);
+ unknownParent = true;
+ }
+ } else {
+ Py_INCREF(Py_None);
+ pyParent = Py_None;
+ }
+
+ Shiboken::AutoDecRef pyArgs(PyTuple_New(1));
+ PyTuple_SET_ITEM(pyArgs.object(), 0, pyParent); // tuple will keep pyParent reference
+
+ // Call python constructor
+ auto *result = reinterpret_cast<SbkObject *>(PyObject_CallObject(m_pyObject, pyArgs));
+ if (result == nullptr) {
+ qWarning("Unable to create a Python custom widget of type \"%s\".",
+ qPrintable(m_name));
+ PyErr_Print();
+ return nullptr;
+ }
+
+ if (unknownParent) // if parent does not exist in python, transfer the ownership to cpp
+ Shiboken::Object::releaseOwnership(result);
+ else
+ Shiboken::Object::setParent(pyParent, reinterpret_cast<PyObject *>(result));
+
+ return reinterpret_cast<QWidget *>(Shiboken::Object::cppPointer(result, Py_TYPE(result)));
+}
+
+void PyCustomWidget::initialize(QDesignerFormEditorInterface *)
+{
+ m_initialized = true;
+}
diff --git a/sources/pyside6/plugins/uitools/customwidget.h b/sources/pyside6/plugins/uitools/customwidget.h
new file mode 100644
index 000000000..52621f0bd
--- /dev/null
+++ b/sources/pyside6/plugins/uitools/customwidget.h
@@ -0,0 +1,37 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PY_CUSTOM_WIDGET_H_
+#define PY_CUSTOM_WIDGET_H_
+
+#include <shiboken.h>
+
+#include <QtUiPlugin/QDesignerCustomWidgetInterface>
+
+class PyCustomWidget: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+
+public:
+ explicit PyCustomWidget(PyObject *objectType);
+
+ bool isContainer() const override;
+ bool isInitialized() const override;
+ QIcon icon() const override;
+ QString domXml() const override;
+ QString group() const override;
+ QString includeFile() const override;
+ QString name() const override;
+ QString toolTip() const override;
+ QString whatsThis() const override;
+ QWidget *createWidget(QWidget *parent) override;
+ void initialize(QDesignerFormEditorInterface *core) override;
+
+private:
+ PyObject *m_pyObject = nullptr;
+ const QString m_name;
+ bool m_initialized = false;
+};
+
+#endif // PY_CUSTOM_WIDGET_H_
diff --git a/sources/pyside6/plugins/uitools/customwidgets.cpp b/sources/pyside6/plugins/uitools/customwidgets.cpp
new file mode 100644
index 000000000..93b6b4a10
--- /dev/null
+++ b/sources/pyside6/plugins/uitools/customwidgets.cpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "customwidgets.h"
+#include "customwidget.h"
+
+PyCustomWidgets::PyCustomWidgets(QObject *parent)
+ : QObject(parent)
+{
+}
+
+PyCustomWidgets::~PyCustomWidgets()
+{
+ qDeleteAll(m_widgets);
+}
+
+void PyCustomWidgets::registerWidgetType(PyObject *widget)
+{
+ m_widgets.append(new PyCustomWidget(widget));
+}
+
+QList<QDesignerCustomWidgetInterface *> PyCustomWidgets::customWidgets() const
+{
+ return m_widgets;
+}
diff --git a/sources/pyside6/plugins/uitools/customwidgets.h b/sources/pyside6/plugins/uitools/customwidgets.h
new file mode 100644
index 000000000..f67a0847d
--- /dev/null
+++ b/sources/pyside6/plugins/uitools/customwidgets.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PY_CUSTOM_WIDGETS_H_
+#define PY_CUSTOM_WIDGETS_H_
+
+#include <shiboken.h>
+
+#include <QtUiPlugin/QDesignerCustomWidgetInterface>
+
+#include <QtCore/qlist.h>
+
+// A static plugin linked to the QtUiLoader Python module
+class PyCustomWidgets: public QObject, public QDesignerCustomWidgetCollectionInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.PySide.PyCustomWidgetsInterface")
+
+public:
+ Q_DISABLE_COPY_MOVE(PyCustomWidgets)
+
+ explicit PyCustomWidgets(QObject *parent = nullptr);
+ ~PyCustomWidgets() override;
+
+ QList<QDesignerCustomWidgetInterface*> customWidgets() const override;
+
+ // Called from added function QUiLoader::registerCustomWidget()
+ void registerWidgetType(PyObject* widget);
+
+private:
+ QList<QDesignerCustomWidgetInterface *> m_widgets;
+};
+
+#endif
diff --git a/sources/pyside6/pyside_version.py b/sources/pyside6/pyside_version.py
new file mode 100644
index 000000000..bd78d3316
--- /dev/null
+++ b/sources/pyside6/pyside_version.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+major_version = "@pyside_MAJOR_VERSION@"
+minor_version = "@pyside_MINOR_VERSION@"
+patch_version = "@pyside_MICRO_VERSION@"
+
+# For example: "a", "b", "rc"
+# (which means "alpha", "beta", "release candidate").
+# An empty string means the generated package will be an official release.
+release_version_type = "@pyside_PRE_RELEASE_VERSION_TYPE@"
+
+# For example: "1", "2" (which means "beta1", "beta2", if type is "b").
+pre_release_version = "@pyside_PRE_RELEASE_VERSION@"
+
+if __name__ == '__main__':
+ # Used by CMake.
+ print(f'{major_version};{minor_version};{patch_version};'
+ f'{release_version_type};{pre_release_version}')
diff --git a/sources/pyside6/qtexampleicons/CMakeLists.txt b/sources/pyside6/qtexampleicons/CMakeLists.txt
new file mode 100644
index 000000000..1562f7b27
--- /dev/null
+++ b/sources/pyside6/qtexampleicons/CMakeLists.txt
@@ -0,0 +1,52 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+cmake_policy(VERSION 3.18)
+
+project(QtExampleIcons)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_AUTORCC ON)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 COMPONENTS ExampleIconsPrivate)
+
+add_library(QtExampleIcons MODULE module.c)
+
+# See libshiboken/CMakeLists.txt
+if(PYTHON_LIMITED_API)
+ target_compile_definitions(QtExampleIcons PRIVATE "-DPy_LIMITED_API=0x03050000")
+endif()
+
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ if(PYTHON_WITH_DEBUG)
+ target_compile_definitions(QtExampleIcons PRIVATE "-DPy_DEBUG")
+ endif()
+ if (PYTHON_WITH_COUNT_ALLOCS)
+ target_compile_definitions(QtExampleIcons PRIVATE "-DCOUNT_ALLOCS")
+ endif()
+elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
+ target_compile_definitions(QtExampleIcons PRIVATE "-DNDEBUG")
+endif()
+
+target_include_directories(QtExampleIcons PRIVATE ${SHIBOKEN_PYTHON_INCLUDE_DIRS})
+
+get_property(SHIBOKEN_PYTHON_LIBRARIES GLOBAL PROPERTY shiboken_python_libraries)
+
+target_link_libraries(QtExampleIcons PRIVATE
+ Qt::ExampleIconsPrivate
+ ${SHIBOKEN_PYTHON_LIBRARIES})
+
+set_target_properties(QtExampleIcons PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "QtExampleIcons${SHIBOKEN_PYTHON_EXTENSION_SUFFIX}"
+ LIBRARY_OUTPUT_DIRECTORY "${pyside6_BINARY_DIR}")
+
+if(WIN32)
+ set_property(TARGET QtExampleIcons PROPERTY SUFFIX ".pyd")
+endif()
+
+install(TARGETS QtExampleIcons LIBRARY DESTINATION "${PYTHON_SITE_PACKAGES}/PySide6")
diff --git a/sources/pyside6/qtexampleicons/module.c b/sources/pyside6/qtexampleicons/module.c
new file mode 100644
index 000000000..814204f1a
--- /dev/null
+++ b/sources/pyside6/qtexampleicons/module.c
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <Python.h>
+
+#if defined _WIN32
+# define MODULE_EXPORT __declspec(dllexport)
+#else
+# define MODULE_EXPORT __attribute__ ((visibility("default")))
+#endif
+
+static PyMethodDef QtExampleIconsMethods[] = {
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef moduleDef = {
+ /* m_base */ PyModuleDef_HEAD_INIT,
+ /* m_name */ "QtExampleIcons",
+ /* m_doc */ NULL,
+ /* m_size */ -1,
+ /* m_methods */ QtExampleIconsMethods,
+ /* m_reload */ NULL,
+ /* m_traverse */ NULL,
+ /* m_clear */ NULL,
+ /* m_free */ NULL
+};
+
+MODULE_EXPORT PyObject *PyInit_QtExampleIcons(void)
+{
+ return PyModule_Create(&moduleDef);
+}
+
+int main(int argc, char *argv[])
+{
+#ifndef PYPY_VERSION
+ Py_SetProgramName(L"module-test");
+ Py_Initialize();
+#endif
+ PyInit_QtExampleIcons();
+ return 0;
+}
diff --git a/sources/pyside6/tests/CMakeLists.txt b/sources/pyside6/tests/CMakeLists.txt
new file mode 100644
index 000000000..539e1aea8
--- /dev/null
+++ b/sources/pyside6/tests/CMakeLists.txt
@@ -0,0 +1,73 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(PYSIDE_IS_CROSS_BUILD)
+ # SHIBOKEN_PYTHON_INTERPRETER will be empty when cross-building.
+ message(WARNING
+ "Running tests when cross-compiling is not supported because it would require running "
+ "a target python interpreter which might have a different architecture than the host."
+ )
+endif()
+
+if(NOT CTEST_TESTING_TIMEOUT)
+ set(CTEST_TESTING_TIMEOUT 60)
+endif()
+
+# BUILD_DIR and QT_DIR are used by init_paths.py for setting
+# the path to the testbinding module
+get_filename_component(BUILD_DIR "${CMAKE_BINARY_DIR}" DIRECTORY)
+get_filename_component(BUILD_DIR "${CMAKE_BINARY_DIR}" DIRECTORY)
+set(QT_DIR "${QT6_INSTALL_PREFIX}")
+
+macro(TEST_QT_MODULE var name)
+ if(NOT DISABLE_${name} AND ${var})
+ add_subdirectory(${name})
+ endif()
+endmacro()
+
+macro(PYSIDE_TEST)
+ string(REGEX MATCH "/([^/]+)//?([^/]+)\\.py" foo "${CMAKE_CURRENT_SOURCE_DIR}/${ARGV0}" )
+ set(TEST_NAME "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}")
+ if (${ARGC} EQUAL 1)
+ set(EXPECT_TO_FAIL 0)
+ elseif(${ARGC} EQUAL 2)
+ set(EXPECT_TO_FAIL ${ARGV1})
+ else()
+ message(WARNING "Invalid call of macro PYSIDE_TEST")
+ endif()
+ set(TEST_CMD ${XVFB_EXEC} ${SHIBOKEN_PYTHON_INTERPRETER} "${CMAKE_CURRENT_SOURCE_DIR}/${ARGV0}")
+ add_test(${TEST_NAME} ${TEST_CMD})
+ # QT_NO_GLIB=1 is required to avoid crashes on CI RHEL 6.6 machines.
+ # See QTBUG-64716 for details.
+ set_tests_properties(${TEST_NAME} PROPERTIES
+ TIMEOUT ${CTEST_TESTING_TIMEOUT}
+ WILL_FAIL ${EXPECT_TO_FAIL}
+ ENVIRONMENT "BUILD_DIR=${BUILD_DIR};QT_DIR=${QT_DIR};PYSIDE_DISABLE_INTERNAL_QT_CONF=1;QT_NO_GLIB=1")
+endmacro()
+
+if (NOT DISABLE_QtCore AND NOT DISABLE_QtGui AND NOT DISABLE_QtWidgets)
+ add_subdirectory(pysidetest)
+endif()
+add_subdirectory(registry)
+add_subdirectory(signals)
+add_subdirectory(support)
+add_subdirectory(tools/metaobjectdump)
+add_subdirectory(tools/pyside6-deploy)
+
+if(UNIX AND NOT APPLE)
+ add_subdirectory(tools/pyside6-android-deploy)
+endif()
+
+if (NOT DISABLE_QtQuick)
+ add_subdirectory(tools/pyside6-qml)
+endif()
+
+foreach(shortname IN LISTS all_module_shortnames)
+ message(STATUS "preparing tests for module 'Qt${shortname}'")
+ TEST_QT_MODULE(Qt${QT_MAJOR_VERSION}${shortname}_FOUND Qt${shortname})
+endforeach()
+
+#platform specific
+if (ENABLE_MAC)
+ add_subdirectory(mac)
+endif ()
diff --git a/sources/pyside6/tests/Qt3DAnimation/CMakeLists.txt b/sources/pyside6/tests/Qt3DAnimation/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DAnimation/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/Qt3DCore/CMakeLists.txt b/sources/pyside6/tests/Qt3DCore/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DCore/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/Qt3DExtras/CMakeLists.txt b/sources/pyside6/tests/Qt3DExtras/CMakeLists.txt
new file mode 100644
index 000000000..5f8d2e77b
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DExtras/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(qt3dextras_test.py)
diff --git a/sources/pyside6/tests/Qt3DExtras/Qt3DExtras.pyproject b/sources/pyside6/tests/Qt3DExtras/Qt3DExtras.pyproject
new file mode 100644
index 000000000..4ac255226
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DExtras/Qt3DExtras.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["qt3dextras_test.py"]
+}
diff --git a/sources/pyside6/tests/Qt3DExtras/qt3dextras_test.py b/sources/pyside6/tests/Qt3DExtras/qt3dextras_test.py
new file mode 100644
index 000000000..23e2d6e7e
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DExtras/qt3dextras_test.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for Q3DExtras'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import (Property, QObject, QPropertyAnimation, QTimer, Signal, Slot)
+from PySide6.QtGui import (QGuiApplication, QMatrix4x4, QQuaternion, QVector3D, QWindow)
+from PySide6.Qt3DCore import (Qt3DCore)
+from PySide6.Qt3DRender import (Qt3DRender)
+from PySide6.Qt3DExtras import (Qt3DExtras)
+
+
+class OrbitTransformController(QObject):
+ def __init__(self, parent):
+ super().__init__(parent)
+ self._target = None
+ self._matrix = QMatrix4x4()
+ self._radius = 1
+ self._angle = 0
+
+ def setTarget(self, t):
+ self._target = t
+
+ def getTarget(self):
+ return self._target
+
+ def setRadius(self, radius):
+ if self._radius != radius:
+ self._radius = radius
+ self.updateMatrix()
+ self.radiusChanged.emit()
+
+ def getRadius(self):
+ return self._radius
+
+ def setAngle(self, angle):
+ if self._angle != angle:
+ self._angle = angle
+ self.updateMatrix()
+ self.angleChanged.emit()
+
+ def getAngle(self):
+ return self._angle
+
+ def updateMatrix(self):
+ self._matrix.setToIdentity()
+ self._matrix.rotate(self._angle, QVector3D(0, 1, 0))
+ self._matrix.translate(self._radius, 0, 0)
+ if self._target is not None:
+ self._target.setMatrix(self._matrix)
+
+ angleChanged = Signal()
+ radiusChanged = Signal()
+ angle = Property(float, getAngle, setAngle, notify=angleChanged)
+ radius = Property(float, getRadius, setRadius, notify=radiusChanged)
+
+
+class Window(Qt3DExtras.Qt3DWindow):
+ def __init__(self):
+ super().__init__()
+
+ # Camera
+ self.camera().lens().setPerspectiveProjection(45, 16 / 9, 0.1, 1000)
+ self.camera().setPosition(QVector3D(0, 0, 40))
+ self.camera().setViewCenter(QVector3D(0, 0, 0))
+
+ # For camera controls
+ self.createScene()
+ self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity)
+ self.camController.setLinearSpeed(50)
+ self.camController.setLookSpeed(180)
+ self.camController.setCamera(self.camera())
+
+ self.setRootEntity(self.rootEntity)
+
+ def createScene(self):
+ # Root entity
+ self.rootEntity = Qt3DCore.QEntity()
+
+ # Material
+ self.material = Qt3DExtras.QPhongMaterial(self.rootEntity)
+
+ # Torus
+ self.torusEntity = Qt3DCore.QEntity(self.rootEntity)
+ self.torusMesh = Qt3DExtras.QTorusMesh()
+ self.torusMesh.setRadius(5)
+ self.torusMesh.setMinorRadius(1)
+ self.torusMesh.setRings(100)
+ self.torusMesh.setSlices(20)
+
+ self.torusTransform = Qt3DCore.QTransform()
+ self.torusTransform.setScale3D(QVector3D(1.5, 1, 0.5))
+ self.torusTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45))
+
+ self.torusEntity.addComponent(self.torusMesh)
+ self.torusEntity.addComponent(self.torusTransform)
+ self.torusEntity.addComponent(self.material)
+
+ # Sphere
+ self.sphereEntity = Qt3DCore.QEntity(self.rootEntity)
+ self.sphereMesh = Qt3DExtras.QSphereMesh()
+ self.sphereMesh.setRadius(3)
+
+ self.sphereTransform = Qt3DCore.QTransform()
+ self.controller = OrbitTransformController(self.sphereTransform)
+ self.controller.setTarget(self.sphereTransform)
+ self.controller.setRadius(20)
+
+ self.sphereEntity.addComponent(self.sphereMesh)
+ self.sphereEntity.addComponent(self.sphereTransform)
+ self.sphereEntity.addComponent(self.material)
+
+
+class Qt3DExtrasTestCase(UsesQApplication):
+ '''Tests related to Q3DExtras'''
+
+ def test3DExtras(self):
+
+ window = Window()
+ window.show()
+ while not window.isExposed():
+ self.app.processEvents()
+ QTimer.singleShot(2000, self.app.quit)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/Qt3DInput/CMakeLists.txt b/sources/pyside6/tests/Qt3DInput/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DInput/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/Qt3DLogic/CMakeLists.txt b/sources/pyside6/tests/Qt3DLogic/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DLogic/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/Qt3DQuick/CMakeLists.txt b/sources/pyside6/tests/Qt3DQuick/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DQuick/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/Qt3DRender/CMakeLists.txt b/sources/pyside6/tests/Qt3DRender/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/Qt3DRender/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtAsyncio/CMakeLists.txt b/sources/pyside6/tests/QtAsyncio/CMakeLists.txt
new file mode 100644
index 000000000..935e0d90a
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/CMakeLists.txt
@@ -0,0 +1,2 @@
+PYSIDE_TEST(qasyncio_test.py)
+PYSIDE_TEST(qasyncio_test_chain.py)
diff --git a/sources/pyside6/tests/QtAsyncio/QtAsyncio.pyproject b/sources/pyside6/tests/QtAsyncio/QtAsyncio.pyproject
new file mode 100644
index 000000000..a36dcd5ad
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/QtAsyncio.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["qt_asyncio_test.py", "qt_asyncio_test_chain.py", "qt_asyncio_test_time.py"]
+}
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test.py
new file mode 100644
index 000000000..f3c971285
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import unittest
+import asyncio
+
+from PySide6.QtAsyncio import QAsyncioEventLoopPolicy
+
+
+class QAsyncioTestCase(unittest.TestCase):
+ async def sleep(self, output):
+ output += "Hello"
+ await asyncio.sleep(0.2)
+ output += "World"
+
+ async def gather(self, output):
+ await asyncio.gather(self.sleep(output), self.sleep(output), self.sleep(output))
+
+ def test_sleep(self):
+ outputs_expected = []
+ outputs_real = []
+
+ # Run the code without QAsyncioEventLoopPolicy
+ asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
+ asyncio.run(self.sleep(outputs_expected))
+
+ # Run the code with QAsyncioEventLoopPolicy and QtEventLoop
+ asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
+ asyncio.run(self.sleep(outputs_real))
+
+ self.assertEqual(outputs_expected, outputs_real)
+
+ def test_gather(self):
+ outputs_expected = []
+ outputs_real = []
+
+ # Run the code without QAsyncioEventLoopPolicy
+ asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
+ asyncio.run(self.gather(outputs_expected))
+
+ # Run the code with QAsyncioEventLoopPolicy and QtEventLoop
+ asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
+ asyncio.run(self.gather(outputs_real))
+
+ self.assertEqual(outputs_expected, outputs_real)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_task.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_task.py
new file mode 100644
index 000000000..7ef2bb90d
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_task.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import asyncio
+import unittest
+
+import PySide6.QtAsyncio as QtAsyncio
+
+
+class QAsyncioTestCaseCancelTask(unittest.TestCase):
+ # Taken from https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancel
+
+ async def cancel_me(self, output):
+ output += "(1) cancel_me(): before sleep"
+
+ try:
+ await asyncio.sleep(10)
+ except asyncio.CancelledError:
+ output += "(2) cancel_me(): cancel sleep"
+ raise
+ finally:
+ output += "(3) cancel_me(): after sleep"
+
+ async def main(self, output):
+ task = asyncio.create_task(self.cancel_me(output))
+ await asyncio.sleep(0.1)
+ task.cancel()
+ try:
+ await task
+ except asyncio.CancelledError:
+ output += "(4) main(): cancel_me is cancelled now"
+
+ def test_await_tasks(self):
+ output_expected = []
+ output_real = []
+
+ asyncio.run(self.main(output_expected))
+ QtAsyncio.run(self.main(output_real), keep_running=False)
+
+ self.assertEqual(output_real, output_expected)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_taskgroup.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_taskgroup.py
new file mode 100644
index 000000000..aa8ce4718
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test_cancel_taskgroup.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import asyncio
+import unittest
+
+import PySide6.QtAsyncio as QtAsyncio
+
+
+class QAsyncioTestCaseCancelTaskGroup(unittest.TestCase):
+ def setUp(self) -> None:
+ super().setUp()
+ # We only reach the end of the loop if the task is not cancelled.
+ self.loop_end_reached = False
+
+ async def raise_error(self):
+ raise RuntimeError
+
+ async def loop_short(self):
+ self._loop_end_reached = False
+ for _ in range(1000):
+ await asyncio.sleep(1e-3)
+ self._loop_end_reached = True
+
+ async def loop_shorter(self):
+ self._loop_end_reached = False
+ for _ in range(1000):
+ await asyncio.sleep(1e-4)
+ self._loop_end_reached = True
+
+ async def loop_the_shortest(self):
+ self._loop_end_reached = False
+ for _ in range(1000):
+ await asyncio.to_thread(lambda: None)
+ self._loop_end_reached = True
+
+ async def main(self, coro):
+ async with asyncio.TaskGroup() as tg:
+ tg.create_task(coro())
+ tg.create_task(self.raise_error())
+
+ def test_cancel_taskgroup(self):
+ coros = [self.loop_short, self.loop_shorter, self.loop_the_shortest]
+
+ for coro in coros:
+ try:
+ QtAsyncio.run(self.main(coro), keep_running=False)
+ except ExceptionGroup as e:
+ self.assertEqual(len(e.exceptions), 1)
+ self.assertIsInstance(e.exceptions[0], RuntimeError)
+ self.assertFalse(self._loop_end_reached)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test_chain.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test_chain.py
new file mode 100644
index 000000000..a0a949720
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test_chain.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import unittest
+import asyncio
+import random
+import time
+
+from PySide6.QtAsyncio import QAsyncioEventLoopPolicy
+
+
+class QAsyncioTestCaseChain(unittest.TestCase):
+
+ async def link(self, output, n, i):
+ t = random.randint(0, 5)
+ output += f"link {i}({n}): {t}s "
+ await asyncio.sleep(i)
+ result = f"result {n}-{i}"
+ output += f"link {i}({n}) finished with {result} "
+ return result
+
+ async def chain(self, output, n):
+ link1 = await self.link(output, n, 0.2)
+ link2 = await self.link(output, n, 0.5)
+ output += f"chain {n}: {link1} -> {link2} "
+
+ async def gather(self, output, *args):
+ await asyncio.gather(*(self.chain(output, n) for n in args))
+
+ def test_chain(self):
+ args = [1, 2, 3]
+
+ outputs_expected = []
+ outputs_real = []
+
+ # Run the code without QAsyncioEventLoopPolicy
+ random.seed(17)
+ asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
+ start = time.perf_counter()
+ asyncio.run(self.gather(outputs_expected, *args))
+ end_expected = time.perf_counter() - start
+
+ # Run the code with QAsyncioEventLoopPolicy and QtEventLoop
+ random.seed(17)
+ asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
+ start = time.perf_counter()
+ asyncio.run(self.gather(outputs_real, *args))
+ end_real = time.perf_counter() - start
+
+ self.assertEqual(outputs_expected, outputs_real)
+ self.assertAlmostEqual(end_expected, end_real, delta=0.5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test_executor.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test_executor.py
new file mode 100644
index 000000000..25e680b39
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test_executor.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import unittest
+import asyncio
+
+from concurrent.futures import ThreadPoolExecutor
+
+from PySide6.QtCore import QThread
+from PySide6.QtAsyncio import QAsyncioEventLoopPolicy
+
+
+class QAsyncioTestCaseExecutor(unittest.TestCase):
+ def setUp(self) -> None:
+ super().setUp()
+ self.executor_thread = None
+
+ def tearDown(self) -> None:
+ super().tearDown()
+
+ def blocking_function(self):
+ self.executor_thread = QThread.currentThread()
+ return 42
+
+ async def run_asyncio_executor(self):
+ main_thread = QThread.currentThread()
+ with ThreadPoolExecutor(max_workers=2) as executor:
+ result = await asyncio.get_running_loop().run_in_executor(
+ executor, self.blocking_function)
+
+ # Assert that we are back to the main thread.
+ self.assertEqual(QThread.currentThread(), main_thread)
+
+ # Assert that the blocking function was executed in a different thread.
+ self.assertNotEqual(self.executor_thread, main_thread)
+
+ self.assertEqual(result, 42)
+
+ def test_qasyncio_executor(self):
+ asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
+ asyncio.run(self.run_asyncio_executor())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test_queues.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test_queues.py
new file mode 100644
index 000000000..0bd98c361
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test_queues.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import unittest
+import asyncio
+import random
+import time
+
+from PySide6.QtAsyncio import QAsyncioEventLoopPolicy
+
+
+class QAsyncioTestCaseQueues(unittest.TestCase):
+
+ async def produce(self, output, queue):
+ for _ in range(random.randint(0, 2)):
+ await asyncio.sleep(random.random())
+ await queue.put(self.i)
+ output += f"{self.i} added to queue\n"
+ self.i += 1
+
+ async def consume(self, output, queue):
+ while True:
+ await asyncio.sleep(random.random())
+ i = await queue.get()
+ output += f"{i} pulled from queue\n"
+ queue.task_done()
+
+ async def main(self, output1, output2, num_producers, num_consumers):
+ self.i = 0
+ queue = asyncio.Queue()
+ producers = [
+ asyncio.create_task(self.produce(output1, queue)) for _ in range(num_producers)]
+ consumers = [
+ asyncio.create_task(self.consume(output2, queue)) for _ in range(num_consumers)]
+ await asyncio.gather(*producers)
+ await queue.join()
+ for consumer in consumers:
+ consumer.cancel()
+
+ def test_queues(self):
+ args = [(2, 3), (2, 1)]
+ for arg in args:
+ outputs_expected1 = []
+ outputs_expected2 = []
+ outputs_real1 = []
+ outputs_real2 = []
+
+ # Run the code without QAsyncioEventLoopPolicy
+ random.seed(17)
+ start = time.perf_counter()
+ asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
+ asyncio.run(self.main(outputs_expected1, outputs_expected2, *arg))
+ end_expected = time.perf_counter() - start
+
+ # Run the code with QAsyncioEventLoopPolicy and QtEventLoop
+ random.seed(17)
+ start = time.perf_counter()
+ asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
+ asyncio.run(self.main(outputs_real1, outputs_real2, *arg))
+ end_real = time.perf_counter() - start
+
+ self.assertEqual(outputs_expected1, outputs_real1)
+ self.assertEqual(outputs_expected2, outputs_real2)
+ self.assertAlmostEqual(end_expected, end_real, delta=1)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test_threadsafe.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test_threadsafe.py
new file mode 100644
index 000000000..5b52db239
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test_threadsafe.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import unittest
+import asyncio
+import threading
+import time
+
+from PySide6.QtAsyncio import QAsyncioEventLoopPolicy
+
+
+class QAsyncioTestCaseThreadsafe(unittest.TestCase):
+
+ def setUp(self) -> None:
+ super().setUp()
+ asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
+ self.loop_event = asyncio.Event()
+
+ def thread_target(self, is_threadsafe):
+ time.sleep(1)
+ if is_threadsafe:
+ # call_soon_threadsafe() wakes the loop that is in another thread, so the
+ # loop checks the event and will not hang.
+ asyncio.get_event_loop().call_soon_threadsafe(self.loop_event.set)
+ else:
+ # call_soon() does not wake the loop that is in another thread, and so the
+ # loop keeps waiting without checking the event and will hang.
+ asyncio.get_event_loop().call_soon(self.loop_event.set)
+
+ async def coro(self, is_threadsafe):
+ thread = threading.Thread(target=self.thread_target, args=(is_threadsafe,))
+ thread.start()
+
+ task = asyncio.create_task(self.loop_event.wait())
+
+ # The timeout is necessary because the loop will hang for the non-threadsafe case.
+ done, pending = await asyncio.wait([task], timeout=2)
+
+ thread.join()
+
+ if is_threadsafe:
+ self.assertEqual(len(done), 1)
+ self.assertEqual(len(pending), 0)
+ else:
+ self.assertEqual(len(done), 0)
+ self.assertEqual(len(pending), 1)
+
+ def test_not_threadsafe(self):
+ asyncio.run(self.coro(False))
+
+ def test_threadsafe(self):
+ asyncio.run(self.coro(True))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAsyncio/qasyncio_test_time.py b/sources/pyside6/tests/QtAsyncio/qasyncio_test_time.py
new file mode 100644
index 000000000..07a126644
--- /dev/null
+++ b/sources/pyside6/tests/QtAsyncio/qasyncio_test_time.py
@@ -0,0 +1,49 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtAsyncio'''
+
+import unittest
+import asyncio
+import datetime
+
+from PySide6.QtAsyncio import QAsyncioEventLoopPolicy
+
+
+class QAsyncioTestCaseTime(unittest.TestCase):
+
+ def setUp(self):
+ self.previous_time = None
+ self.exception = None
+
+ def display_date(self, end_time, loop):
+ if self.previous_time is not None:
+ try:
+ self.assertAlmostEqual(
+ (datetime.datetime.now() - self.previous_time).total_seconds(), 1, delta=0.1)
+ except AssertionError as e:
+ self.exception = e
+ self.previous_time = datetime.datetime.now()
+ if (loop.time() + 1.0) < end_time:
+ loop.call_later(1, self.display_date, end_time, loop)
+ else:
+ loop.stop()
+
+ def test_time(self):
+ asyncio.set_event_loop_policy(QAsyncioEventLoopPolicy())
+ loop = asyncio.new_event_loop()
+
+ end_time = loop.time() + 3.0
+ loop.call_soon(self.display_date, end_time, loop)
+
+ try:
+ loop.run_forever()
+ finally:
+ loop.close()
+
+ if self.exception is not None:
+ raise self.exception
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtAxContainer/CMakeLists.txt b/sources/pyside6/tests/QtAxContainer/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtAxContainer/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtBluetooth/CMakeLists.txt b/sources/pyside6/tests/QtBluetooth/CMakeLists.txt
new file mode 100644
index 000000000..a075c3c9b
--- /dev/null
+++ b/sources/pyside6/tests/QtBluetooth/CMakeLists.txt
@@ -0,0 +1,2 @@
+PYSIDE_TEST(localdevice.py)
+PYSIDE_TEST(lowenergy_characteristics.py)
diff --git a/sources/pyside6/tests/QtBluetooth/QtBluetooth.pyproject b/sources/pyside6/tests/QtBluetooth/QtBluetooth.pyproject
new file mode 100644
index 000000000..176b335e2
--- /dev/null
+++ b/sources/pyside6/tests/QtBluetooth/QtBluetooth.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["localdevice.py",
+ "lowenergy_characteristics.py"]
+}
diff --git a/sources/pyside6/tests/QtBluetooth/localdevice.py b/sources/pyside6/tests/QtBluetooth/localdevice.py
new file mode 100644
index 000000000..21801106f
--- /dev/null
+++ b/sources/pyside6/tests/QtBluetooth/localdevice.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QBluetoothLocalDevice'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtBluetooth import QBluetoothLocalDevice
+
+
+class QBluetoothLocalDeviceTest(unittest.TestCase):
+ def testInitialization(self):
+ device = QBluetoothLocalDevice()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtBluetooth/lowenergy_characteristics.py b/sources/pyside6/tests/QtBluetooth/lowenergy_characteristics.py
new file mode 100644
index 000000000..0f7298fec
--- /dev/null
+++ b/sources/pyside6/tests/QtBluetooth/lowenergy_characteristics.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QLowEnergyServiceData'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUuid
+from PySide6.QtBluetooth import (QBluetoothUuid, QLowEnergyServiceData,
+ QLowEnergyDescriptorData,
+ QLowEnergyCharacteristicData)
+
+
+class QLowEnergyCharacteristicsTest(unittest.TestCase):
+
+ def testCharacteristics(self):
+ uuid = QUuid("11111111-1111-1111-1111-111111111111")
+ self.assertFalse(uuid.isNull())
+
+ new_characteristic = QLowEnergyCharacteristicData()
+ bluetooth_uuid = QBluetoothUuid(uuid)
+ new_characteristic.setUuid(bluetooth_uuid)
+ new_characteristic.setValue(b"blabla")
+ new_characteristic.setValueLength(6, 20)
+
+ desc = QLowEnergyDescriptorData()
+ desc.setUuid(bluetooth_uuid)
+ desc.setValue(b"blabla")
+
+ new_characteristic.addDescriptor(desc)
+ self.assertTrue(new_characteristic.isValid())
+
+ data = QLowEnergyServiceData()
+ data.addCharacteristic(new_characteristic)
+
+ characteristics = data.characteristics()
+ self.assertEqual(len(characteristics), 1)
+
+ self.assertEqual(characteristics[0].uuid(), bluetooth_uuid)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCharts/CMakeLists.txt b/sources/pyside6/tests/QtCharts/CMakeLists.txt
new file mode 100644
index 000000000..4d031937a
--- /dev/null
+++ b/sources/pyside6/tests/QtCharts/CMakeLists.txt
@@ -0,0 +1,2 @@
+PYSIDE_TEST(qcharts_test.py)
+PYSIDE_TEST(qcharts_numpy_test.py)
diff --git a/sources/pyside6/tests/QtCharts/QtCharts.pyproject b/sources/pyside6/tests/QtCharts/QtCharts.pyproject
new file mode 100644
index 000000000..6f2bd66f2
--- /dev/null
+++ b/sources/pyside6/tests/QtCharts/QtCharts.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["qcharts_test.py"]
+}
diff --git a/sources/pyside6/tests/QtCharts/qcharts_numpy_test.py b/sources/pyside6/tests/QtCharts/qcharts_numpy_test.py
new file mode 100644
index 000000000..8154020c0
--- /dev/null
+++ b/sources/pyside6/tests/QtCharts/qcharts_numpy_test.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QCharts/numpy'''
+
+import os
+import sys
+import unittest
+try:
+ import numpy as np
+ HAVE_NUMPY = True
+except ModuleNotFoundError:
+ HAVE_NUMPY = False
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QCoreApplication
+from PySide6.QtCharts import QLineSeries
+
+
+class QChartsNumpyTestCase(UsesQApplication):
+ '''Tests related to QCharts/numpy'''
+
+ @unittest.skipUnless(HAVE_NUMPY, "requires numpy")
+ def test(self):
+ """PYSIDE-2313: Verify various types."""
+ line_series = QLineSeries()
+ data_types = [np.short, np.ushort, np.int32, np.uint32,
+ np.int64, np.uint64, np.float32, np.float64]
+ for dt in data_types:
+ print("Testing ", dt)
+ old_size = line_series.count()
+ x_arr = np.array([2], dtype=dt)
+ y_arr = np.array([3], dtype=dt)
+ line_series.appendNp(x_arr, y_arr)
+ size = line_series.count()
+ self.assertEqual(size, old_size + 1)
+ point = line_series.points()[size - 1]
+ self.assertEqual(point.x(), 2)
+ self.assertEqual(point.y(), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCharts/qcharts_test.py b/sources/pyside6/tests/QtCharts/qcharts_test.py
new file mode 100644
index 000000000..8d57c07eb
--- /dev/null
+++ b/sources/pyside6/tests/QtCharts/qcharts_test.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QCharts'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QRect, QSize, QTimer
+from PySide6.QtGui import QGuiApplication, QScreen
+from PySide6.QtCharts import QChart, QChartView, QPieSeries
+
+
+class QChartsTestCase(UsesQApplication):
+ '''Tests related to QCharts'''
+
+ def testCharts(self):
+ self.series = QPieSeries()
+ self.series.append("Jane", 1)
+ self.series.append("Joe", 2)
+ self.series.append("Andy", 3)
+ self.series.append("Barbara", 4)
+ self.series.append("Axel", 5)
+ slice = self.series.slices()[1]
+ slice.setExploded()
+ slice.setLabelVisible()
+ self.chart = QChart()
+ self.chart.addSeries(self.series)
+ chartView = QChartView(self.chart)
+ screenSize = QGuiApplication.primaryScreen().geometry().size()
+ chartView.resize(screenSize / 2)
+ chartView.show()
+ QTimer.singleShot(500, self.app.quit)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtConcurrent/CMakeLists.txt b/sources/pyside6/tests/QtConcurrent/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtConcurrent/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtCore/CMakeLists.txt b/sources/pyside6/tests/QtCore/CMakeLists.txt
new file mode 100644
index 000000000..f0228d943
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/CMakeLists.txt
@@ -0,0 +1,148 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(attr_cache_py3k.py)
+PYSIDE_TEST(bug_278_test.py)
+PYSIDE_TEST(bug_300_test.py)
+PYSIDE_TEST(bug_324.py)
+PYSIDE_TEST(bug_332.py)
+PYSIDE_TEST(bug_408.py)
+PYSIDE_TEST(bug_428.py)
+PYSIDE_TEST(bug_462.py)
+PYSIDE_TEST(bug_505.py)
+PYSIDE_TEST(bug_515.py)
+PYSIDE_TEST(bug_606.py)
+PYSIDE_TEST(bug_656.py)
+PYSIDE_TEST(bug_686.py)
+PYSIDE_TEST(bug_699.py)
+PYSIDE_TEST(bug_706.py)
+PYSIDE_TEST(bug_820.py)
+PYSIDE_TEST(bug_826.py)
+PYSIDE_TEST(bug_829.py)
+PYSIDE_TEST(bug_835.py)
+PYSIDE_TEST(bug_920.py)
+PYSIDE_TEST(bug_927.py)
+PYSIDE_TEST(bug_931.py)
+PYSIDE_TEST(bug_938.py)
+PYSIDE_TEST(bug_953.py)
+PYSIDE_TEST(bug_987.py)
+PYSIDE_TEST(bug_994.py)
+PYSIDE_TEST(bug_1019.py)
+PYSIDE_TEST(bug_1063.py)
+PYSIDE_TEST(bug_1069.py)
+PYSIDE_TEST(bug_1313.py)
+PYSIDE_TEST(bug_PYSIDE-41.py)
+PYSIDE_TEST(bug_PYSIDE-42.py)
+PYSIDE_TEST(bug_PYSIDE-164.py)
+PYSIDE_TEST(bug_PYSIDE-2745.py)
+PYSIDE_TEST(blocking_signals_test.py)
+PYSIDE_TEST(classinfo_test.py)
+PYSIDE_TEST(child_event_test.py)
+PYSIDE_TEST(deepcopy_test.py)
+PYSIDE_TEST(deletelater_test.py)
+PYSIDE_TEST(destroysignal_test.py)
+PYSIDE_TEST(duck_punching_test.py)
+PYSIDE_TEST(emoji_string_test.py)
+PYSIDE_TEST(errormessages_with_features_test.py)
+PYSIDE_TEST(feature_with_uic_test.py)
+PYSIDE_TEST(hash_test.py)
+PYSIDE_TEST(inherits_test.py)
+PYSIDE_TEST(max_signals.py)
+PYSIDE_TEST(missing_symbols_test.py)
+PYSIDE_TEST(mockclass_test.py)
+PYSIDE_TEST(multiple_feature_test.py)
+PYSIDE_TEST(python_conversion.py)
+PYSIDE_TEST(qabs_test.py)
+PYSIDE_TEST(qabstractitemmodel_test.py)
+PYSIDE_TEST(qanimationgroup_test.py)
+PYSIDE_TEST(qbitarray_test.py)
+PYSIDE_TEST(qbytearray_concatenation_operator_test.py)
+PYSIDE_TEST(qbytearray_operator_iadd_test.py)
+PYSIDE_TEST(qbytearray_operator_test.py)
+PYSIDE_TEST(qbytearray_test.py)
+PYSIDE_TEST(qcalendar_test.py)
+PYSIDE_TEST(qcbor_test.py)
+PYSIDE_TEST(qcollator_test.py)
+PYSIDE_TEST(qcommandlineparser_test.py)
+PYSIDE_TEST(qcoreapplication_argv_test.py)
+PYSIDE_TEST(qcoreapplication_instance_test.py)
+PYSIDE_TEST(qcoreapplication_test.py)
+PYSIDE_TEST(qdatastream_test.py)
+PYSIDE_TEST(qdatetime_test.py)
+PYSIDE_TEST(qdate_test.py)
+PYSIDE_TEST(qdir_test.py)
+PYSIDE_TEST(qeasingcurve_test.py)
+PYSIDE_TEST(qenum_test.py)
+PYSIDE_TEST(qevent_test.py)
+PYSIDE_TEST(qfileinfo_test.py)
+PYSIDE_TEST(qfile_test.py)
+PYSIDE_TEST(qfileread_test.py)
+PYSIDE_TEST(qflags_test.py)
+PYSIDE_TEST(qinstallmsghandler_test.py)
+PYSIDE_TEST(qjsondocument_test.py)
+PYSIDE_TEST(qlinef_test.py)
+PYSIDE_TEST(qlocale_test.py)
+PYSIDE_TEST(qlockfile_test.py)
+PYSIDE_TEST(qmessageauthenticationcode_test.py)
+PYSIDE_TEST(qmetaobject_test.py)
+PYSIDE_TEST(qmetatype_test.py)
+PYSIDE_TEST(qmimedatabase_test.py)
+PYSIDE_TEST(qmodelindex_internalpointer_test.py)
+PYSIDE_TEST(qobject_children_segfault_test.py)
+PYSIDE_TEST(qobject_connect_notify_test.py)
+PYSIDE_TEST(qobject_destructor.py)
+PYSIDE_TEST(qobject_event_filter_test.py)
+PYSIDE_TEST(qobject_inherits_test.py)
+PYSIDE_TEST(qobject_objectproperty_test.py)
+PYSIDE_TEST(qobject_parent_test.py)
+PYSIDE_TEST(qobject_property_test.py)
+PYSIDE_TEST(qobject_protected_methods_test.py)
+PYSIDE_TEST(qobject_test.py)
+PYSIDE_TEST(qobject_timer_event_test.py)
+PYSIDE_TEST(qobject_tr_as_instance_test.py)
+PYSIDE_TEST(qoperatingsystemversion_test.py)
+PYSIDE_TEST(qpoint_test.py)
+PYSIDE_TEST(qprocess_test.py)
+PYSIDE_TEST(qproperty_decorator.py)
+PYSIDE_TEST(qrect_test.py)
+PYSIDE_TEST(qregularexpression_test.py)
+PYSIDE_TEST(qresource_test.py)
+PYSIDE_TEST(qsettings_test.py)
+PYSIDE_TEST(qsize_test.py)
+PYSIDE_TEST(qslot_object_test.py)
+PYSIDE_TEST(qsocketnotifier_test.py)
+PYSIDE_TEST(qsrand_test.py)
+PYSIDE_TEST(qstandardpaths_test.py)
+PYSIDE_TEST(qstorageinfo_test.py)
+PYSIDE_TEST(qstring_test.py)
+PYSIDE_TEST(qsysinfo_test.py)
+PYSIDE_TEST(qtextstream_test.py)
+PYSIDE_TEST(qthread_prod_cons_test.py)
+PYSIDE_TEST(qthread_signal_test.py)
+PYSIDE_TEST(qthread_test.py)
+PYSIDE_TEST(qtimer_singleshot_test.py)
+PYSIDE_TEST(qtimer_timeout_test.py)
+PYSIDE_TEST(qtimezone_test.py)
+PYSIDE_TEST(qtnamespace_test.py)
+PYSIDE_TEST(qurl_test.py)
+PYSIDE_TEST(qurlquery_test.py)
+PYSIDE_TEST(quuid_test.py)
+PYSIDE_TEST(qversionnumber_test.py)
+PYSIDE_TEST(repr_test.py)
+PYSIDE_TEST(setprop_on_ctor_test.py)
+PYSIDE_TEST(signal_sender.py)
+PYSIDE_TEST(snake_prop_feature_test.py)
+PYSIDE_TEST(staticMetaObject_test.py)
+PYSIDE_TEST(static_method_test.py)
+PYSIDE_TEST(thread_signals_test.py)
+PYSIDE_TEST(tr_noop_test.py)
+PYSIDE_TEST(translation_test.py)
+PYSIDE_TEST(unaryoperator_test.py)
+PYSIDE_TEST(unicode_test.py)
+PYSIDE_TEST(versioninfo_test.py)
+PYSIDE_TEST(loggingcategorymacros_test.py)
+PYSIDE_TEST(qrunnable_test.py)
+
+if(X11)
+ PYSIDE_TEST(qhandle_test.py)
+endif()
diff --git a/sources/pyside6/tests/QtCore/QtCore.pyproject b/sources/pyside6/tests/QtCore/QtCore.pyproject
new file mode 100644
index 000000000..bd5951316
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/QtCore.pyproject
@@ -0,0 +1,148 @@
+{
+ "files": ["attr_cache_py3k.py",
+ "blocking_signals_test.py",
+ "bug_1019.py",
+ "bug_1063.py",
+ "bug_1069.py",
+ "bug_1313.py",
+ "bug_278_test.py",
+ "bug_300_test.py",
+ "bug_324.py",
+ "bug_332.py",
+ "bug_408.py",
+ "bug_428.py",
+ "bug_462.py",
+ "bug_505.py",
+ "bug_515.py",
+ "bug_606.py",
+ "bug_656.py",
+ "bug_686.py",
+ "bug_699.py",
+ "bug_706.py",
+ "bug_820.py",
+ "bug_826.py",
+ "bug_829.py",
+ "bug_835.py",
+ "bug_920.py",
+ "bug_927.py",
+ "bug_931.py",
+ "bug_938.py",
+ "bug_953.py",
+ "bug_987.py",
+ "bug_994.py",
+ "bug_PYSIDE-164.py",
+ "bug_PYSIDE-41.py",
+ "bug_PYSIDE-42.py",
+ "child_event_test.py",
+ "classinfo_test.py",
+ "deepcopy_test.py",
+ "deletelater_test.py",
+ "destroysignal_test.py",
+ "duck_punching_test.py",
+ "emoji_string_test.py",
+ "errormessages_with_features_test.py",
+ "feature_with_uic/window.py",
+ "feature_with_uic/window.ui",
+ "feature_with_uic_test.py",
+ "hash_test.py",
+ "inherits_test.py",
+ "loggingcategorymacros_test.py",
+ "max_signals.py",
+ "missing_symbols_test.py",
+ "mockclass_test.py",
+ "multiple_feature_test.py",
+ "python_conversion.py",
+ "qabs_test.py",
+ "qabstractitemmodel_test.py",
+ "qanimationgroup_test.py",
+ "qbitarray_test.py",
+ "qbytearray_concatenation_operator_test.py",
+ "qbytearray_operator_iadd_test.py",
+ "qbytearray_operator_test.py",
+ "qbytearray_test.py",
+ "qcalendar_test.py",
+ "qcbor_test.py",
+ "qcollator_test.py",
+ "qcommandlineparser_test.py",
+ "qcoreapplication_argv_test.py",
+ "qcoreapplication_instance_test.py",
+ "qcoreapplication_test.py",
+ "qdatastream_test.py",
+ "qdate_test.py",
+ "qdatetime_test.py",
+ "qdir_test.py",
+ "qeasingcurve_test.py",
+ "qenum_test.py",
+ "qevent_test.py",
+ "qfile_test.py",
+ "qfileinfo_test.py",
+ "qfileread_test.py",
+ "qflags_test.py",
+ "qhandle_test.py",
+ "qinstallmsghandler_test.py",
+ "qjsondocument_test.py",
+ "qlinef_test.py",
+ "qlocale_test.py",
+ "qlockfile_test.py",
+ "qmessageauthenticationcode_test.py",
+ "qmetaobject_test.py",
+ "qmetatype_test.py",
+ "qmimedatabase_test.py",
+ "qmodelindex_internalpointer_test.py",
+ "qobject_children_segfault_test.py",
+ "qobject_connect_notify_test.py",
+ "qobject_destructor.py",
+ "qobject_event_filter_test.py",
+ "qobject_inherits_test.py",
+ "qobject_objectproperty_test.py",
+ "qobject_parent_test.py",
+ "qobject_property_test.py",
+ "qobject_protected_methods_test.py",
+ "qobject_test.py",
+ "qobject_timer_event_test.py",
+ "qobject_tr_as_instance_test.py",
+ "qoperatingsystemversion_test.py",
+ "qpoint_test.py",
+ "qprocess_test.py",
+ "qproperty_decorator.py",
+ "qrandomgenerator_test.py",
+ "qrect_test.py",
+ "qregularexpression_test.py",
+ "qresource_test.py",
+ "qsettings_test.py",
+ "qsharedmemory_client.py",
+ "qsharedmemory_test.py",
+ "qsize_test.py",
+ "qslot_object_test.py",
+ "qsocketnotifier_test.py",
+ "qsrand_test.py",
+ "qstandardpaths_test.py",
+ "qstorageinfo_test.py",
+ "qstring_test.py",
+ "qsysinfo_test.py",
+ "qtextstream_test.py",
+ "qthread_prod_cons_test.py",
+ "qthread_signal_test.py",
+ "qthread_test.py",
+ "qtimer_singleshot_test.py",
+ "qtimer_timeout_test.py",
+ "qtimezone_test.py",
+ "qtnamespace_test.py",
+ "qurl_test.py",
+ "qurlquery_test.py",
+ "quuid_test.py",
+ "qversionnumber_test.py",
+ "repr_test.py",
+ "resources.qrc",
+ "resources_mc.py",
+ "setprop_on_ctor_test.py",
+ "snake_prop_feature_test.py",
+ "staticMetaObject_test.py",
+ "static_method_test.py",
+ "thread_signals_test.py",
+ "tr_noop_test.py",
+ "translation_test.py",
+ "unaryoperator_test.py",
+ "unicode_test.py",
+ "versioninfo_test.py"]
+}
diff --git a/sources/pyside6/tests/QtCore/attr_cache_py3k.py b/sources/pyside6/tests/QtCore/attr_cache_py3k.py
new file mode 100644
index 000000000..c82dbbea3
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/attr_cache_py3k.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+'''
+Unit tests for attribute cache in Python 3
+
+This is the original code from the bug report
+https://bugreports.qt.io/browse/PYSIDE-60
+'''
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QObject
+
+
+class A(QObject):
+ instance = 1
+
+ @classmethod
+ def test(cls):
+ cls.instance
+ cls.instance = cls()
+ assert "<__main__.A(0x" in repr(cls.__dict__['instance'])
+ assert "<__main__.A(0x" in repr(cls.instance)
+ assert "<__main__.A(0x" in repr(type.__getattribute__(cls, 'instance'))
+
+
+if __name__ == "__main__":
+ A.test()
diff --git a/sources/pyside6/tests/QtCore/blocking_signals_test.py b/sources/pyside6/tests/QtCore/blocking_signals_test.py
new file mode 100644
index 000000000..493abb071
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/blocking_signals_test.py
@@ -0,0 +1,154 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test case for QObject.signalsBlocked() and blockSignal()'''
+
+import gc
+import os
+import sys
+from tempfile import mkstemp
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, QFile, QSignalBlocker
+
+
+class Sender(QObject):
+ mysignal = Signal()
+ mysignal_int_int = Signal(int, int)
+
+
+class TestSignalsBlockedBasic(unittest.TestCase):
+ '''Basic test case for signalsBlocked'''
+
+ def testBasic(self):
+ '''QObject.signalsBlocked() and blockSignals()
+ The signals aren't blocked by default.
+ blockSignals returns the previous value'''
+ obj = QObject()
+ self.assertTrue(not obj.signalsBlocked())
+ self.assertTrue(not obj.blockSignals(True))
+ self.assertTrue(obj.signalsBlocked())
+ self.assertTrue(obj.blockSignals(False))
+ blocker = QSignalBlocker(obj)
+ self.assertTrue(obj.signalsBlocked())
+ blocker.unblock()
+ self.assertTrue(not obj.signalsBlocked())
+ blocker.reblock()
+ self.assertTrue(obj.signalsBlocked())
+ del blocker
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(not obj.signalsBlocked())
+
+ def testContext(self):
+ obj = QObject()
+ self.assertTrue(not obj.signalsBlocked())
+ with QSignalBlocker(obj):
+ self.assertTrue(obj.signalsBlocked())
+ self.assertTrue(not obj.signalsBlocked())
+
+ def testContextWithAs(self):
+ obj = QObject()
+ self.assertTrue(not obj.signalsBlocked())
+ with QSignalBlocker(obj) as blocker:
+ self.assertTrue(obj.signalsBlocked())
+ self.assertEqual(type(blocker), QSignalBlocker)
+ self.assertTrue(not obj.signalsBlocked())
+
+
+class TestSignalsBlocked(unittest.TestCase):
+ '''Test case to check if the signals are really blocked'''
+
+ def setUp(self):
+ # Set up the basic resources needed
+ self.obj = Sender()
+ self.args = tuple()
+ self.called = False
+
+ def tearDown(self):
+ # Delete used resources
+ del self.obj
+ del self.args
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def callback(self, *args):
+ # Default callback
+ if args == self.args:
+ self.called = True
+ else:
+ raise TypeError("Invalid arguments")
+
+ def testShortCircuitSignals(self):
+ # Blocking of Python short-circuit signals
+ self.obj.mysignal.connect(self.callback)
+
+ self.obj.mysignal.emit()
+ self.assertTrue(self.called)
+
+ self.called = False
+ self.obj.blockSignals(True)
+ self.obj.mysignal.emit()
+ self.assertTrue(not self.called)
+
+ def testPythonSignals(self):
+ # Blocking of Python typed signals
+
+ self.obj.mysignal_int_int.connect(self.callback)
+ self.args = (1, 3)
+
+ self.obj.mysignal_int_int.emit(*self.args)
+ self.assertTrue(self.called)
+
+ self.called = False
+ self.obj.blockSignals(True)
+ self.obj.mysignal_int_int.emit(*self.args)
+ self.assertTrue(not self.called)
+
+
+class TestQFileSignalBlocking(unittest.TestCase):
+ '''Test case for blocking the signal QIODevice.aboutToClose()'''
+
+ def setUp(self):
+ # Set up the needed resources - A temp file and a QFile
+ self.called = False
+ handle, self.filename = mkstemp()
+ os.close(handle)
+
+ self.qfile = QFile(self.filename)
+
+ def tearDown(self):
+ # Release acquired resources
+ os.remove(self.filename)
+ del self.qfile
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def callback(self):
+ # Default callback
+ self.called = True
+
+ def testAboutToCloseBlocking(self):
+ # QIODevice.aboutToClose() blocking
+
+ self.qfile.aboutToClose.connect(self.callback)
+
+ self.assertTrue(self.qfile.open(QFile.ReadOnly))
+ self.qfile.close()
+ self.assertTrue(self.called)
+
+ self.called = False
+ self.qfile.blockSignals(True)
+
+ self.assertTrue(self.qfile.open(QFile.ReadOnly))
+ self.qfile.close()
+ self.assertTrue(not self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_1019.py b/sources/pyside6/tests/QtCore/bug_1019.py
new file mode 100644
index 000000000..4a35956b1
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_1019.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QTimer, Slot
+
+
+class MyTimer (QTimer):
+ def __init__(self):
+ super().__init__()
+ self.startCalled = False
+
+ @Slot()
+ def slotUsedToIncreaseMethodOffset(self):
+ pass
+
+
+class MyTimer2 (MyTimer):
+
+ @Slot()
+ def slotUsedToIncreaseMethodOffset2(self):
+ pass
+
+ def start(self):
+ """ 'Overrides' non-virtual slot QTimer.start()."""
+ self.startCalled = True
+ QCoreApplication.instance().quit()
+
+
+class TestBug1019 (unittest.TestCase):
+ def testIt(self):
+ app = QCoreApplication([])
+ t = MyTimer2()
+ QTimer.singleShot(0, t.start)
+ app.exec()
+ self.assertTrue(t.startCalled)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_1063.py b/sources/pyside6/tests/QtCore/bug_1063.py
new file mode 100644
index 000000000..88c4bb51e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_1063.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' unit test for BUG #1063 '''
+
+import os
+import sys
+import tempfile
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QFile, QIODevice, QTextStream
+
+
+class QTextStreamTestCase(unittest.TestCase):
+ def setUp(self):
+ self.temp_file = tempfile.NamedTemporaryFile(delete=False)
+ self.temp_file.close()
+ self.f = QFile(self.temp_file.name)
+ self.f.open(QIODevice.WriteOnly)
+ self.strings = ('foo', 'bar')
+ self.stream = QTextStream(self.f)
+
+ def testIt(self):
+ for s in self.strings:
+ self.stream << s
+
+ self.f.close()
+
+ # make sure we didn't get an empty file
+ self.assertNotEqual(QFile(self.temp_file.name).size(), 0)
+
+ os.unlink(self.temp_file.name)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_1069.py b/sources/pyside6/tests/QtCore/bug_1069.py
new file mode 100644
index 000000000..760918cd9
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_1069.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' unit test for BUG #1069 '''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray, QDataStream, QIODevice
+
+
+class QDataStreamOpOverloadTestCase(unittest.TestCase):
+ def setUp(self):
+ self.ba = QByteArray()
+ self.stream = QDataStream(self.ba, QIODevice.WriteOnly)
+
+ def testIt(self):
+ self.stream << "hello"
+ ok = False
+ for c in self.ba:
+ if c != b'\x00':
+ ok = True
+ break
+
+ self.assertEqual(ok, True)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_1313.py b/sources/pyside6/tests/QtCore/bug_1313.py
new file mode 100644
index 000000000..ecc22c43b
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_1313.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' unit test for BUG #1313 '''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class MyQObject(QObject):
+ sig = Signal()
+
+
+demo_coroutine_definition_code = """
+async def demo_coroutine():
+ my_qobject = MyQObject()
+ my_qobject.sig.connect(lambda: None)
+"""
+
+
+exec(demo_coroutine_definition_code)
+
+
+class CoroutineRaisesStopIterationTestCase(unittest.TestCase):
+ def setUp(self):
+ self.coroutine = demo_coroutine()
+
+ def testCoroutine(self):
+ with self.assertRaises(StopIteration):
+ self.coroutine.send(None)
+
+
+def demo_generator():
+ my_qobject = MyQObject()
+ my_qobject.sig.connect(lambda: None)
+ return
+ yield # to make it a generator
+
+
+class GeneratorRaisesStopIterationTestCase(unittest.TestCase):
+ def setUp(self):
+ self.generator = demo_generator()
+
+ def testGenerator(self):
+ with self.assertRaises(StopIteration):
+ self.generator.send(None)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_278_test.py b/sources/pyside6/tests/QtCore/bug_278_test.py
new file mode 100644
index 000000000..8d2f4b47e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_278_test.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+def setValue(o):
+ values = ['Name']
+ o.setProperty('test1', values)
+
+
+class QQtVersionTest(unittest.TestCase):
+ '''Tests for QVariant conversion of QStringList'''
+
+ def testGet(self):
+ o = QObject()
+ setValue(o)
+ self.assertEqual(o.property('test1'), ['Name'])
+
+
+if __name__ == '__main__':
+ unittest.main()
+
+
diff --git a/sources/pyside6/tests/QtCore/bug_300_test.py b/sources/pyside6/tests/QtCore/bug_300_test.py
new file mode 100644
index 000000000..b9768bf9d
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_300_test.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QModelIndex, QStringListModel
+
+
+class TestQAbstractItemModelSignals(unittest.TestCase):
+ def sigCallback(self, index, r, c):
+ self._called = True
+
+ def testSignals(self):
+ self._called = False
+ m = QStringListModel()
+ m.rowsAboutToBeInserted[QModelIndex, int, int].connect(self.sigCallback)
+ m.insertRows(0, 3)
+ self.assertTrue(self._called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_324.py b/sources/pyside6/tests/QtCore/bug_324.py
new file mode 100644
index 000000000..0aa17c465
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_324.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 324: http://bugs.openbossa.org/show_bug.cgi?id=324'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QObject, Signal
+
+
+class QBug(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+ def check(self):
+ self.done.emit("abc")
+
+ done = Signal(str)
+
+
+class Bug324(unittest.TestCase):
+
+ def on_done(self, val):
+ self.value = val
+
+ def testBug(self):
+ app = QCoreApplication([])
+ bug = QBug()
+ self.value = ''
+ bug.done.connect(self.on_done)
+ bug.check()
+ self.assertEqual(self.value, 'abc')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_332.py b/sources/pyside6/tests/QtCore/bug_332.py
new file mode 100644
index 000000000..8d55bc87f
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_332.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QMutex
+
+
+class Lock(QMutex):
+ def tryLock(self, timeout=10):
+ return QMutex.tryLock(self, timeout)
+
+
+class TestBug(unittest.TestCase):
+
+ def testCase(self):
+ l = Lock()
+ l.tryLock() # this cause a assertion
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_408.py b/sources/pyside6/tests/QtCore/bug_408.py
new file mode 100644
index 000000000..30459172c
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_408.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QIODevice, QTextStream
+
+
+class MyDevice(QIODevice):
+ def __init__(self, txt):
+ super().__init__()
+ self.txt = txt
+ self.ptr = 0
+
+ def readData(self, size):
+ size = min(len(self.txt) - self.ptr, size)
+ retval = self.txt[self.ptr:size]
+ self.ptr += size
+ return retval
+
+
+class QIODeviceTest(unittest.TestCase):
+
+ def testIt(self):
+ device = MyDevice("hello world\nhello again")
+ device.open(QIODevice.ReadOnly)
+
+ s = QTextStream(device)
+ self.assertEqual(s.readLine(), "hello world")
+ self.assertEqual(s.readLine(), "hello again")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_428.py b/sources/pyside6/tests/QtCore/bug_428.py
new file mode 100644
index 000000000..8fb5d4827
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_428.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class MyBaseObject(QObject):
+ def __init__(self, number):
+ self.myMember = 'myMember' + number
+ super().__init__()
+
+
+class QObjectConstructorTest(unittest.TestCase):
+ def testBug(self):
+ for i in range(10):
+ number = str(i)
+ obj = MyBaseObject(number)
+ self.assertEqual(obj.myMember, 'myMember' + number)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_462.py b/sources/pyside6/tests/QtCore/bug_462.py
new file mode 100644
index 000000000..04a42fe08
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_462.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QCoreApplication, QEvent, QThread
+
+
+class MyEvent(QEvent):
+ def __init__(self, i):
+ print("TYPE:", type(QEvent.User))
+ super().__init__(QEvent.Type(QEvent.User))
+ self.i = i
+
+
+class MyThread (QThread):
+ def __init__(self, owner):
+ super().__init__()
+ self.owner = owner
+
+ def run(self):
+ for i in range(3):
+ e = MyEvent(i)
+ QCoreApplication.postEvent(self.owner, e)
+
+
+class MyBaseObject(QObject):
+ def __init__(self):
+ super().__init__()
+ self.events = []
+ self.t = MyThread(self)
+ self.t.start()
+
+ def customEvent(self, event):
+ self.events.append(event)
+ if len(self.events) == 3:
+ self.t.wait()
+ self.app.quit()
+
+
+class CheckForEventsTypes(unittest.TestCase):
+ def testTypes(self):
+ o = MyBaseObject()
+ o.app = QCoreApplication(sys.argv)
+ o.app.exec()
+ for e in o.events:
+ self.assertTrue(isinstance(e, MyEvent))
+ o.app = None
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_505.py b/sources/pyside6/tests/QtCore/bug_505.py
new file mode 100644
index 000000000..e8655a84e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_505.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class MyBaseObject(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+ self.setObjectName("PySide")
+
+ def __del__(self):
+ if self.objectName() != "PySide":
+ raise NameError('Fail')
+
+
+class CheckForEventsTypes(unittest.TestCase):
+ def testDelObject(self):
+ p = MyBaseObject()
+ o = MyBaseObject(p)
+ del o
+ del p
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_515.py b/sources/pyside6/tests/QtCore/bug_515.py
new file mode 100644
index 000000000..4e270a441
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_515.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+""" Unittest for bug #515 """
+""" http://bugs.openbossa.org/show_bug.cgi?id=515 """
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QCoreApplication, qAddPostRoutine
+
+
+callCleanup = False
+
+
+def _cleanup():
+ global callCleanup
+ callCleanup = True
+
+
+def _checkCleanup():
+ global callCleanup
+ assert (callCleanup)
+
+
+app = QCoreApplication([])
+qAddPostRoutine(_cleanup)
+qAddPostRoutine(_checkCleanup)
+del app
diff --git a/sources/pyside6/tests/QtCore/bug_606.py b/sources/pyside6/tests/QtCore/bug_606.py
new file mode 100644
index 000000000..4fed16b6e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_606.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+from PySide6.QtCore import QPoint, QPointF
+from PySide6.QtCore import QLine, QLineF
+from PySide6.QtCore import QSize, QSizeF
+
+
+class testCases(unittest.TestCase):
+ def testQPointToTuple(self):
+ p = QPoint(1, 2)
+ self.assertEqual((1, 2), p.toTuple())
+
+ def testQPointFToTuple(self):
+ p = QPointF(1, 2)
+ self.assertEqual((1, 2), p.toTuple())
+
+ def testQLineToTuple(self):
+ l = QLine(1, 2, 3, 4)
+ self.assertEqual((1, 2, 3, 4), l.toTuple())
+
+ def testQLineFToTuple(self):
+ l = QLineF(1, 2, 3, 4)
+ self.assertEqual((1, 2, 3, 4), l.toTuple())
+
+ def testQSizeToTuple(self):
+ s = QSize(1, 2)
+ self.assertEqual((1, 2), s.toTuple())
+
+ def testQSizeFToTuple(self):
+ s = QSizeF(1, 2)
+ self.assertEqual((1, 2), s.toTuple())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_656.py b/sources/pyside6/tests/QtCore/bug_656.py
new file mode 100644
index 000000000..066dc1a02
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_656.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QCoreApplication
+
+
+class CoreApp(QCoreApplication):
+ def __init__(self, *args):
+ super().__init__(*args)
+ # It shouldn't crash after the __init__ call
+
+
+import sys
+app = CoreApp(sys.argv)
diff --git a/sources/pyside6/tests/QtCore/bug_686.py b/sources/pyside6/tests/QtCore/bug_686.py
new file mode 100644
index 000000000..6425a4b86
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_686.py
@@ -0,0 +1,118 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QMutex, QMutexLocker, QReadLocker, QReadWriteLock,
+ QThread, QWriteLocker)
+
+
+class MyWriteThread(QThread):
+ def __init__(self, lock):
+ super().__init__()
+ self.lock = lock
+ self.started = False
+ self.canQuit = False
+
+ def run(self):
+ self.started = True
+ while not self.lock.tryLockForWrite():
+ pass
+ self.canQuit = True
+ self.lock.unlock()
+
+
+class MyReadThread(QThread):
+ def __init__(self, lock):
+ super().__init__()
+ self.lock = lock
+ self.started = False
+ self.canQuit = False
+
+ def run(self):
+ self.started = True
+ while not self.lock.tryLockForRead():
+ pass
+ self.canQuit = True
+ self.lock.unlock()
+
+
+class MyMutexedThread(QThread):
+ def __init__(self, mutex):
+ super().__init__()
+ self.mutex = mutex
+ self.started = False
+ self.canQuit = False
+
+ def run(self):
+ self.started = True
+ while not self.mutex.tryLock():
+ pass
+ self.mutex.unlock()
+ self.canQuit = True
+
+
+class TestQMutex (unittest.TestCase):
+
+ def testReadLocker(self):
+ lock = QReadWriteLock()
+ thread = MyWriteThread(lock)
+
+ with QReadLocker(lock):
+ thread.start()
+ while not thread.started:
+ QThread.msleep(10)
+ self.assertFalse(thread.canQuit)
+
+ self.assertTrue(thread.wait(2000))
+ self.assertTrue(thread.canQuit)
+
+ def testWriteLocker(self):
+ lock = QReadWriteLock()
+ thread = MyReadThread(lock)
+
+ with QWriteLocker(lock):
+ thread.start()
+ while not thread.started:
+ QThread.msleep(10)
+ self.assertFalse(thread.canQuit)
+
+ self.assertTrue(thread.wait(2000))
+ self.assertTrue(thread.canQuit)
+
+ def testMutexLocker(self):
+ mutex = QMutex()
+ thread = MyMutexedThread(mutex)
+
+ with QMutexLocker(mutex):
+ thread.start()
+ while not thread.started:
+ QThread.msleep(10)
+ self.assertFalse(thread.canQuit)
+
+ self.assertTrue(thread.wait(2000))
+ self.assertTrue(thread.canQuit)
+
+ def testWithAsLocker(self):
+ lock = QReadWriteLock()
+ with QReadLocker(lock) as locker:
+ self.assertTrue(isinstance(locker, QReadLocker))
+ with QWriteLocker(lock) as locker:
+ self.assertTrue(isinstance(locker, QWriteLocker))
+ mutex = QMutex()
+ with QMutexLocker(mutex) as locker:
+ self.assertTrue(isinstance(locker, QMutexLocker))
+ with self.assertRaises(TypeError):
+ with QMutexLocker(lock) as locker:
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_699.py b/sources/pyside6/tests/QtCore/bug_699.py
new file mode 100644
index 000000000..02da46ff1
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_699.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Property
+
+
+class TestBug699 (unittest.TestCase):
+
+ def defClass(self):
+ class Foo (QObject):
+ def foo(self):
+ pass
+
+ prop = Property(foo, foo)
+
+ def testIt(self):
+ self.assertRaises(TypeError, self.defClass)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_706.py b/sources/pyside6/tests/QtCore/bug_706.py
new file mode 100644
index 000000000..7db773240
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_706.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QAbstractListModel, QCoreApplication, QModelIndex
+
+
+class MyModel (QAbstractListModel):
+ def rowCount(self, parent=None):
+ return 3
+
+
+class TestBug706(unittest.TestCase):
+
+ def mySlot(self, idx, start, end):
+ self.start = start
+ self.end = end
+
+ def testIt(self):
+ self.start = None
+ self.end = None
+
+ app = QCoreApplication([])
+ model = MyModel()
+ model.columnsAboutToBeInserted.connect(self.mySlot)
+ model.columnsAboutToBeInserted.emit(QModelIndex(), 0, 1)
+ self.assertEqual(self.start, 0)
+ self.assertEqual(self.end, 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_820.py b/sources/pyside6/tests/QtCore/bug_820.py
new file mode 100644
index 000000000..ba0d33068
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_820.py
@@ -0,0 +1,82 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import functools
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Slot, Signal, SIGNAL
+
+
+def log_exception():
+ def log_exception_decorator(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwds):
+ try:
+ return func(*args, **kwds)
+ except Exception:
+ raise
+
+ return wrapper
+
+ return log_exception_decorator
+
+
+def log_exception2():
+ def log_exception_decorator(func):
+ def wrapper(*args, **kwds):
+ try:
+ return func(*args, **kwds)
+ except Exception:
+ raise
+
+ return wrapper
+
+ return log_exception_decorator
+
+
+class MyObject(QObject):
+
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+ self._mySlotcalled = False
+ self._mySlot2called = False
+
+ @Slot()
+ @log_exception()
+ def mySlot(self):
+ self._mySlotcalled = True
+
+ @Slot(name="mySlot2")
+ @log_exception2()
+ def mySlot2(self):
+ self._mySlot2called = True
+
+ def poke(self):
+ self.events.emit()
+
+ events = Signal()
+
+
+class SlotWithDecoratorTest(unittest.TestCase):
+ def testSlots(self):
+ o = MyObject()
+ self.assertTrue(o.metaObject().indexOfSlot("mySlot()") > 0)
+ self.assertTrue(o.metaObject().indexOfSlot("mySlot2()") > 0)
+
+ o.events.connect(o.mySlot)
+ o.events.connect(o.mySlot2)
+ o.poke()
+ self.assertTrue(o._mySlotcalled)
+ self.assertTrue(o._mySlot2called)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/bug_826.py b/sources/pyside6/tests/QtCore/bug_826.py
new file mode 100644
index 000000000..95edc0a7c
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_826.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QEvent, Qt
+import PySide6
+
+
+TEST_EVENT_TYPE = QEvent.Type(QEvent.registerEventType())
+
+
+class TestEvent(QEvent):
+ TestEventType = QEvent.Type(TEST_EVENT_TYPE)
+
+ def __init__(self, rand=0):
+ super().__init__(TestEvent.TestEventType)
+ self._rand = rand
+
+ def getRand(self):
+ return self._rand
+
+
+class TestEnums(unittest.TestCase):
+ def testUserTypesValues(self):
+ self.assertTrue(QEvent.User <= TestEvent.TestEventType <= QEvent.MaxUser)
+ self.assertTrue(QEvent.User <= TEST_EVENT_TYPE <= QEvent.MaxUser)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_829.py b/sources/pyside6/tests/QtCore/bug_829.py
new file mode 100644
index 000000000..9a57e0399
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_829.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# Copyright (C) 2011 Thomas Perl <thp.io/about>
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# Test case for PySide bug 829
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDir, QSettings, QTemporaryFile
+
+
+class QVariantConversions(unittest.TestCase):
+
+ _confFileName = None
+
+ def testDictionary(self):
+ confFile = QTemporaryFile(QDir.tempPath() + '/pysidebug829_XXXXXX.ini')
+ confFile.setAutoRemove(False)
+ self.assertTrue(confFile.open())
+ confFile.close()
+ self._confFileName = confFile.fileName()
+ del confFile
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ s = QSettings(self._confFileName, QSettings.IniFormat)
+ self.assertEqual(s.status(), QSettings.NoError)
+ # Save value
+ s.setValue('x', {1: 'a'})
+ s.sync()
+ self.assertEqual(s.status(), QSettings.NoError)
+ del s
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ # Restore value
+ s = QSettings(self._confFileName, QSettings.IniFormat)
+ self.assertEqual(s.status(), QSettings.NoError)
+ self.assertEqual(s.value('x'), {1: 'a'})
+
+ def __del__(self):
+ if self._confFileName is not None:
+ os.unlink(QDir.toNativeSeparators(self._confFileName))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_835.py b/sources/pyside6/tests/QtCore/bug_835.py
new file mode 100644
index 000000000..6d91b6e0a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_835.py
@@ -0,0 +1,80 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+get_counter = 0
+set_counter = 0
+
+
+class Descriptor(object):
+ def __get__(self, obj, owner):
+ global get_counter
+
+ if not obj:
+ return self
+
+ get_counter += 1
+ return obj.var
+
+ def __set__(self, obj, value):
+ global set_counter
+
+ set_counter += 1
+ obj.var = value
+
+
+class FooBar(QObject):
+ test = Descriptor()
+ var = 0
+
+
+class SetAndGetTestCases(unittest.TestCase):
+ def setUp(self):
+ global get_counter
+ global set_counter
+
+ get_counter = 0
+ set_counter = 0
+
+ def testSetMethod(self):
+ global get_counter
+ global set_counter
+
+ f = FooBar()
+
+ f.test = 1
+ self.assertEqual(get_counter, 0)
+ self.assertEqual(set_counter, 1)
+
+ get_counter = 0
+ set_counter = 0
+
+ def testGetMethod(self):
+ global get_counter
+ global set_counter
+
+ f = FooBar()
+ f.test = 1
+ set_counter = 0
+
+ ret = f.test
+ self.assertEqual(get_counter, 1)
+ self.assertEqual(set_counter, 0)
+
+ get_counter = 0
+ set_counter = 0
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_920.py b/sources/pyside6/tests/QtCore/bug_920.py
new file mode 100644
index 000000000..23c8d6201
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_920.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6.QtCore as QtCore
+
+
+class Signaller(QtCore.QObject):
+ s1 = QtCore.Signal()
+ s2 = QtCore.Signal()
+
+
+class TestBug920(unittest.TestCase):
+
+ def testIt(self):
+ s = Signaller()
+ s.s1.connect(self.onSignal)
+ s.s2.connect(self.onSignal)
+ self.assertTrue(s.s1.disconnect(self.onSignal))
+ self.assertTrue(s.s2.disconnect(self.onSignal))
+
+ def onSignal(self):
+ pass
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_927.py b/sources/pyside6/tests/QtCore/bug_927.py
new file mode 100644
index 000000000..c15a7014b
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_927.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import time
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QRunnable, QThread, QThreadPool
+
+
+thread_function_called = False
+
+
+class thread_function():
+ global thread_function_called
+ thread_function_called = True
+
+
+class Task(QRunnable):
+ def run(self):
+ QThread.msleep(100)
+
+
+class QThreadPoolTest(unittest.TestCase):
+ def testSlowJobs(self):
+ '''This used to cause a segfault due the ownership control on
+ globalInstance function'''
+ for i in range(3):
+ task = Task()
+ QThreadPool.globalInstance().start(task)
+ time.sleep(0.05)
+
+ self.assertTrue(QThreadPool.globalInstance().waitForDone())
+
+ def testCallable(self):
+ global thread_function_called
+ tp = QThreadPool.globalInstance()
+ tp.start(thread_function)
+ self.assertTrue(tp.waitForDone())
+ self.assertTrue(thread_function_called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_931.py b/sources/pyside6/tests/QtCore/bug_931.py
new file mode 100644
index 000000000..f233c2a26
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_931.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+o = QObject()
+
+
+class MyObject(QObject):
+ s = Signal(int)
+
+
+class CheckSignalType(unittest.TestCase):
+ def testSignal(self):
+ self.assertTrue(isinstance(QObject.destroyed, Signal))
+ self.assertEqual(type(QObject.destroyed), Signal)
+
+ self.assertEqual(type(o.destroyed).__name__, "SignalInstance")
+ self.assertNotEqual(type(o.destroyed), Signal)
+
+ self.assertTrue(isinstance(o.destroyed, Signal))
+ self.assertTrue(isinstance(MyObject.s, Signal))
+ self.assertFalse(isinstance(int, Signal))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_938.py b/sources/pyside6/tests/QtCore/bug_938.py
new file mode 100644
index 000000000..3aca25947
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_938.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QBuffer
+
+
+class TestBug938 (unittest.TestCase):
+
+ def testIt(self):
+ b = QBuffer()
+ b.open(QBuffer.WriteOnly)
+ b.write(bytes("\x0023\x005", "UTF-8"))
+ b.close()
+ self.assertEqual(b.buffer().size(), 5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_953.py b/sources/pyside6/tests/QtCore/bug_953.py
new file mode 100644
index 000000000..a9cacc97e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_953.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QCoreApplication, QObject, QTimer
+
+
+class Dispatcher(QObject):
+ _me = None
+
+ def __init__(self):
+ super().__init__()
+ self._me = self
+ QTimer.singleShot(0, self._finish)
+
+ def _finish(self):
+ del self._me # It can't crash here!
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ QTimer.singleShot(10, QCoreApplication.instance().quit)
+
+
+if __name__ == '__main__':
+ app = QCoreApplication([])
+ Dispatcher()
+ app.exec()
diff --git a/sources/pyside6/tests/QtCore/bug_987.py b/sources/pyside6/tests/QtCore/bug_987.py
new file mode 100644
index 000000000..a8c9799e0
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_987.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class TestBug987(unittest.TestCase):
+ def callback(self):
+ pass
+
+ def testInvalidDisconnection(self):
+ o = QObject()
+ self.assertFalse(o.destroyed.disconnect(self.callback))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_994.py b/sources/pyside6/tests/QtCore/bug_994.py
new file mode 100644
index 000000000..464fe3120
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_994.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QIODevice, QTextStream
+
+
+class MyIODevice (QIODevice):
+ def readData(self, amount):
+ return bytes("\0a" * int(amount / 2), "UTF-8")
+
+ def readLineData(self, maxSize):
+ return bytes("\0b" * 4, "UTF-8")
+
+ def atEnd(self):
+ return False
+
+
+class TestBug944 (unittest.TestCase):
+
+ def testIt(self):
+ device = MyIODevice()
+ device.open(QIODevice.ReadOnly)
+ s = QTextStream(device)
+ self.assertEqual(s.read(4), "\0a\0a")
+ self.assertEqual(device.readLine(), "\0b\0b\0b\0b")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_PYSIDE-164.py b/sources/pyside6/tests/QtCore/bug_PYSIDE-164.py
new file mode 100644
index 000000000..84859af84
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_PYSIDE-164.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QEventLoop, QObject, Qt, QThread, Signal
+
+
+class Emitter(QThread):
+
+ signal = Signal(int)
+
+ def __init__(self):
+ super().__init__()
+
+ def run(self):
+ print("Before emit.")
+ self.signal.emit(0)
+ print("After emit.")
+
+
+class Receiver(QObject):
+ def __init__(self, eventloop):
+ super().__init__()
+ self.eventloop = eventloop
+
+ def receive(self, number):
+ print(f"Received number: {number}")
+ self.eventloop.exit(0)
+
+
+class TestBugPYSIDE164(unittest.TestCase):
+
+ def testBlockingSignal(self):
+ app = QCoreApplication.instance() or QCoreApplication([]) # noqa: F841
+ eventloop = QEventLoop()
+ emitter = Emitter()
+ receiver = Receiver(eventloop)
+ emitter.signal.connect(receiver.receive, Qt.BlockingQueuedConnection)
+ emitter.start()
+ retval = eventloop.exec()
+ emitter.wait(2000)
+ self.assertEqual(retval, 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_PYSIDE-2745.py b/sources/pyside6/tests/QtCore/bug_PYSIDE-2745.py
new file mode 100644
index 000000000..3d6c603b7
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_PYSIDE-2745.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+
+from helper.usesqapplication import UsesQApplication
+
+
+class TestBugPYSIDE2745(UsesQApplication):
+
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self.counter = 0
+
+ def fail(self):
+ self.counter += 1
+ raise Exception()
+
+ def test_fail(self):
+ QTimer.singleShot(0, self.fail)
+ QTimer.singleShot(0, self.fail)
+ QTimer.singleShot(1, self.app.quit)
+ self.app.exec()
+ self.assertEqual(self.counter, 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_PYSIDE-41.py b/sources/pyside6/tests/QtCore/bug_PYSIDE-41.py
new file mode 100644
index 000000000..2830f8050
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_PYSIDE-41.py
@@ -0,0 +1,49 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPersistentModelIndex, QStringListModel
+
+
+class TestBugPYSIDE41(unittest.TestCase):
+
+ def testIt(self):
+
+ # list of single-character strings
+ strings = list('abcdefghijklmnopqrstuvwxyz')
+
+ model = QStringListModel(strings)
+
+ # Test hashing of both QModelIndex and QPersistentModelIndex
+ indexFunctions = []
+ indexFunctions.append(model.index)
+ indexFunctions.append(lambda i: QPersistentModelIndex(model.index(i)))
+
+ for indexFunction in indexFunctions:
+
+ # If two objects compare equal, their hashes MUST also be equal. (The
+ # reverse is not a requirement.)
+ for i, _ in enumerate(strings):
+ index1 = indexFunction(i)
+ index2 = indexFunction(i)
+ self.assertEqual(index1, index2)
+ self.assertEqual(hash(index1), hash(index2))
+
+ # Adding the full set of indexes to itself is a no-op.
+ allIndexes1 = set(indexFunction(i) for i, _ in enumerate(strings))
+ allIndexes2 = set(indexFunction(i) for i, _ in enumerate(strings))
+ allIndexesCombined = allIndexes1 & allIndexes2
+ self.assertEqual(allIndexes1, allIndexesCombined)
+ self.assertEqual(allIndexes2, allIndexesCombined)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/bug_PYSIDE-42.py b/sources/pyside6/tests/QtCore/bug_PYSIDE-42.py
new file mode 100644
index 000000000..b602b7569
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/bug_PYSIDE-42.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QFile, QObject
+
+
+class TestBugPYSIDE42 (unittest.TestCase):
+
+ def testIt(self):
+ obj1 = QFile()
+ obj2 = QObject()
+ hash1 = hash(obj1)
+ hash2 = hash(obj2)
+
+ self.assertNotEqual(hash1, hash2)
+ self.assertEqual(hash1, hash(obj1))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/child_event_test.py b/sources/pyside6/tests/QtCore/child_event_test.py
new file mode 100644
index 000000000..6b17ddc93
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/child_event_test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for QObject.childEvent and QTimer.childEvent overloading'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimer, QCoreApplication
+from helper.usesqapplication import UsesQApplication
+
+
+class ExtQObject(QObject):
+ def __init__(self):
+ super().__init__()
+ self.child_event_received = False
+
+ def childEvent(self, event):
+ QObject.childEvent(self, event)
+ self.child_event_received = True
+
+
+class ExtQTimer(QTimer):
+ def __init__(self):
+ super().__init__()
+ self.child_event_received = False
+
+ def childEvent(self, event):
+ QTimer.childEvent(self, event)
+ self.child_event_received = True
+
+
+class TestChildEvent(UsesQApplication):
+ '''Test case for QObject::childEvent and QTimer::childEvent'''
+
+ def setUp(self):
+ UsesQApplication.setUp(self)
+
+ def tearDown(self):
+ UsesQApplication.tearDown(self)
+
+ def testQObject(self):
+ parent = ExtQObject()
+ child = QObject()
+ child.setParent(parent)
+ self.assertTrue(parent.child_event_received)
+
+ def testQTimer(self):
+ parent = ExtQTimer()
+ child = QObject()
+ child.setParent(parent)
+ self.assertTrue(parent.child_event_received)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/classinfo_test.py b/sources/pyside6/tests/QtCore/classinfo_test.py
new file mode 100644
index 000000000..0b0a0b4b6
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/classinfo_test.py
@@ -0,0 +1,114 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import sys
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QCoreApplication, ClassInfo
+
+
+class TestClassInfo(unittest.TestCase):
+ def test_metadata(self):
+ @ClassInfo(author='pyside', url='http://www.pyside.org')
+ class MyObject(QObject):
+ pass
+
+ o = MyObject()
+ mo = o.metaObject()
+ self.assertEqual(mo.classInfoCount(), 2)
+
+ ci = mo.classInfo(0) # author
+ self.assertEqual(ci.name(), 'author')
+ self.assertEqual(ci.value(), 'pyside')
+
+ ci = mo.classInfo(1) # url
+ self.assertEqual(ci.name(), 'url')
+ self.assertEqual(ci.value(), 'http://www.pyside.org')
+
+ def test_dictionary(self):
+ @ClassInfo({'author': 'pyside', 'author company': 'The Qt Company'})
+ class MyObject(QObject):
+ pass
+
+ o = MyObject()
+ mo = o.metaObject()
+ self.assertEqual(mo.classInfoCount(), 2)
+
+ ci = mo.classInfo(0) # author
+ self.assertEqual(ci.name(), 'author')
+ self.assertEqual(ci.value(), 'pyside')
+
+ ci = mo.classInfo(1) # url
+ self.assertEqual(ci.name(), 'author company')
+ self.assertEqual(ci.value(), 'The Qt Company')
+
+ def test_verify_metadata_types(self):
+ valid_dict = {'123': '456'}
+
+ invalid_dict_1 = {'123': 456}
+ invalid_dict_2 = {123: 456}
+ invalid_dict_3 = {123: '456'}
+
+ ClassInfo(**valid_dict)
+
+ self.assertRaises(TypeError, ClassInfo, **invalid_dict_1)
+
+ # assertRaises only allows for string keywords, so a `try` must be used here.
+ try:
+ ClassInfo(**invalid_dict_2)
+ self.fail('ClassInfo() accepted invalid_dict_2!')
+ except TypeError:
+ pass
+
+ try:
+ ClassInfo(**invalid_dict_3)
+ self.fail('ClassInfo() accepted invalid_dict_3!')
+ except TypeError:
+ pass
+
+ def test_can_not_use_instance_twice(self):
+ decorator = ClassInfo(author='pyside', url='http://www.pyside.org')
+
+ @decorator
+ class MyObject1(QObject):
+ pass
+
+ class MyObject2(QObject):
+ pass
+
+ self.assertRaises(TypeError, decorator, MyObject2)
+
+ def test_can_only_be_used_on_qobjects(self):
+ def make_info():
+ return ClassInfo(author='pyside')
+
+ def test_function():
+ pass
+ self.assertRaises(TypeError, make_info(), test_function)
+
+ class NotAQObject(object):
+ pass
+ self.assertRaises(TypeError, make_info(), NotAQObject)
+
+ class QObjectSubclass(QObject):
+ pass
+ make_info()(QObjectSubclass)
+
+ class SubclassOfNativeQObjectSubclass(QCoreApplication):
+ pass
+ make_info()(SubclassOfNativeQObjectSubclass)
+
+ class SubclassOfPythonQObjectSubclass(QObjectSubclass):
+ pass
+ make_info()(SubclassOfPythonQObjectSubclass)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/deepcopy_test.py b/sources/pyside6/tests/QtCore/deepcopy_test.py
new file mode 100644
index 000000000..e130628e3
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/deepcopy_test.py
@@ -0,0 +1,102 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+from copy import deepcopy
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray, QDate, QDateTime, QTime, QLine, QLineF
+from PySide6.QtCore import Qt, QSize, QSizeF, QRect, QRectF, QDir, QPoint, QPointF
+try:
+ from PySide6.QtCore import QUuid
+ HAVE_Q = True
+except ImportError:
+ HAVE_Q = False
+
+
+class DeepCopyHelper:
+ def testCopy(self):
+ copy = deepcopy([self.original])[0]
+ self.assertTrue(copy is not self.original)
+ self.assertEqual(copy, self.original)
+
+
+class QByteArrayDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QByteArray(bytes('the quick brown fox jumps over the lazy dog', "UTF-8"))
+
+
+class QDateDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QDate(2010, 11, 22)
+
+
+class QTimeDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QTime(11, 37, 55, 692)
+
+
+class QDateTimeDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QDateTime(2010, 5, 18, 10, 24, 45, 223, Qt.LocalTime)
+
+
+class QSizeDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QSize(42, 190)
+
+
+class QSizeFDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QSizeF(42.7, 190.2)
+
+
+class QRectDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QRect(100, 200, 300, 400)
+
+
+class QRectFDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QRectF(100.33, 200.254, 300.321, 400.123)
+
+
+class QLineDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QLine(1, 2, 3, 4)
+
+
+class QLineFDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QLineF(1.1, 2.2, 3.3, 4.4)
+
+
+class QPointDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QPoint(1, 2)
+
+
+class QPointFDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QPointF(1.1, 2.2)
+
+
+class QDirDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QDir("./")
+
+
+class QUuiCopy(DeepCopyHelper, unittest.TestCase):
+ @unittest.skipUnless(HAVE_Q, "QUuid is currently not supported on this platform.")
+ def setUp(self):
+ self.original = QUuid("67C8770B-44F1-410A-AB9A-F9B5446F13EE")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/deletelater_test.py b/sources/pyside6/tests/QtCore/deletelater_test.py
new file mode 100644
index 000000000..0ee078428
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/deletelater_test.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QTimer.singleShot'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimer, QCoreApplication, SIGNAL
+from helper.usesqapplication import UsesQApplication
+
+
+class TestDeleteLater(UsesQApplication):
+ '''Test case for function DeleteLater'''
+
+ def testCase(self):
+ o = QObject()
+ o.deleteLater()
+ del o
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/destroysignal_test.py b/sources/pyside6/tests/QtCore/destroysignal_test.py
new file mode 100644
index 000000000..ad087b489
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/destroysignal_test.py
@@ -0,0 +1,78 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer, QObject, Signal
+
+
+class TestDestroySignal(unittest.TestCase):
+ def onObjectDestroyed(self, timer):
+ self.assertTrue(isinstance(timer, QObject))
+ self._destroyed = True
+
+ def testSignal(self):
+ self._destroyed = False
+ t = QTimer()
+ t.destroyed[QObject].connect(self.onObjectDestroyed)
+ del t
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
+ self.assertTrue(self._destroyed)
+
+ def testWithParent(self):
+ self._destroyed = False
+ p = QTimer()
+ t = QTimer(p)
+ t.destroyed[QObject].connect(self.onObjectDestroyed)
+ del p
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
+ self.assertTrue(self._destroyed)
+
+
+class Foo(QObject):
+ s = Signal(int)
+
+ def __init__(self):
+ QObject.__init__(self)
+ sys.stderr.write(f"__init__ {id(self):x}\n")
+
+ def __del__(self):
+ sys.stderr.write(f"__del__ {id(self):x}\n")
+
+ def send(self, i):
+ self.s.emit(i)
+
+
+# PYSIDE-2201/2328: This crashed until we introduced a weak reference.
+class TestDestroyNoConnect(unittest.TestCase):
+
+ def testSignalDestroyedMissingReference(self):
+ # This works since it has one reference more to Foo
+ Foo().send(43)
+ # This crashed because we have no reference in the signal.
+ with self.assertRaises(RuntimeError):
+ Foo().s.emit(44)
+
+ def testSignalDestroyedinConnect(self):
+ # PYSIDE-2328: Connect to signal of temporary
+ with self.assertRaises(RuntimeError):
+ Foo().s.connect(None)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/duck_punching_test.py b/sources/pyside6/tests/QtCore/duck_punching_test.py
new file mode 100644
index 000000000..145863c3e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/duck_punching_test.py
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for duck punching new implementations of C++ virtual methods into object instances.'''
+
+import gc
+import os
+import sys
+import types
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from helper.usesqapplication import UsesQApplication
+
+
+def MethodType(func, instance, instanceType):
+ return types.MethodType(func, instance)
+
+
+class Duck(QObject):
+ def __init__(self):
+ super().__init__()
+
+ def childEvent(self, event):
+ QObject.childEvent(self, event)
+
+
+class TestDuckPunchingOnQObjectInstance(UsesQApplication):
+ '''Test case for duck punching new implementations of C++ virtual methods into object instances.'''
+
+ def setUp(self):
+ # Acquire resources
+ self.duck_childEvent_called = False
+ UsesQApplication.setUp(self)
+
+ def tearDown(self):
+ # Release resources
+ del self.duck_childEvent_called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ def testChildEventMonkeyPatch(self):
+ # Test if the new childEvent injected on QObject instance is called from C++
+ parent = QObject()
+
+ def childEvent(obj, event):
+ self.duck_childEvent_called = True
+ parent.childEvent = MethodType(childEvent, parent, QObject)
+ child = QObject()
+ child.setParent(parent)
+ self.assertTrue(self.duck_childEvent_called)
+ # This is done to decrease the refcount of the vm object
+ # allowing the object wrapper to be deleted before the
+ # BindingManager. This is useful when compiling Shiboken
+ # for debug, since the BindingManager destructor has an
+ # assert that checks if the wrapper mapper is empty.
+ parent.childEvent = None
+
+ def testChildEventMonkeyPatchWithInheritance(self):
+ # Test if the new childEvent injected on a QObject's extension class instance is called from C++
+ parent = Duck()
+
+ def childEvent(obj, event):
+ QObject.childEvent(obj, event)
+ self.duck_childEvent_called = True
+ child = QObject()
+ child.setParent(parent)
+ parent.childEvent = MethodType(childEvent, parent, QObject)
+ child = QObject()
+ child.setParent(parent)
+ self.assertTrue(self.duck_childEvent_called)
+ # This is done to decrease the refcount of the vm object
+ # allowing the object wrapper to be deleted before the
+ # BindingManager. This is useful when compiling Shiboken
+ # for debug, since the BindingManager destructor has an
+ # assert that checks if the wrapper mapper is empty.
+ parent.childEvent = None
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/emoji_string_test.py b/sources/pyside6/tests/QtCore/emoji_string_test.py
new file mode 100644
index 000000000..78dee1893
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/emoji_string_test.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+emoji-string-test.py
+
+This is the original code from the bug report
+https://bugreports.qt.io/browse/PYSIDE-336
+
+The only changes are the emoji constant creation which avoids unicode in the
+source itself, utf8 encoding in line 1 and a short plausibility test to make
+it safely fail.
+"""
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QObject, Signal
+
+
+emoji_str = u'\U0001f632' + u' ' # "😲 "
+
+
+class TestStuff(QObject):
+ testsig = Signal(str)
+
+ def a_nop(self, sendMeAnEmoji):
+ print(sendMeAnEmoji)
+ return
+
+ def __init__(self):
+ super().__init__()
+ self.testsig.connect(self.a_nop)
+ self.testsig.emit(emoji_str)
+
+ def plausi(self):
+ # Python 2 may be built with UCS-2 or UCS-4 support.
+ # UCS-2 creates 2 surrogate code points. See
+ # https://stackoverflow.com/questions/30775689/python-length-of-unicode-string-confusion
+ assert len(emoji_str) == 2 if sys.maxunicode > 0xffff else 3
+
+
+if __name__ == "__main__":
+ mything = TestStuff()
+ mything.plausi()
diff --git a/sources/pyside6/tests/QtCore/errormessages_with_features_test.py b/sources/pyside6/tests/QtCore/errormessages_with_features_test.py
new file mode 100644
index 000000000..97c4f942e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/errormessages_with_features_test.py
@@ -0,0 +1,102 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6 import QtCore
+from PySide6.QtWidgets import QApplication, QLabel
+
+is_pypy = hasattr(sys, "pypy_version_info")
+if not is_pypy:
+ from PySide6.support import feature
+
+import inspect
+
+"""
+errormessages_with_features_test.py
+-----------------------------------
+
+When errors occur while features are switched, we must always produce a
+valid error message.
+
+This test is in its own file because combining it with
+"snake_prop_feature_test" gave strange interactions with the other tests.
+"""
+
+
+@unittest.skipIf(is_pypy, "__feature__ cannot yet be used with PyPy")
+class ErrormessagesWithFeatures(unittest.TestCase):
+ probe = "called with wrong argument types"
+
+ def setUp(self):
+ qApp or QApplication()
+ feature.reset()
+
+ def tearDown(self):
+ feature.reset()
+ qApp.shutdown()
+
+ def testCorrectErrorMessagesPlain(self):
+ with self.assertRaises(TypeError) as cm:
+ QLabel().setFont(42)
+ print("\n\n" + cm.exception.args[0])
+ self.assertTrue(self.probe in cm.exception.args[0])
+
+ def testCorrectErrorMessagesSnake(self):
+ from __feature__ import snake_case
+ with self.assertRaises(TypeError) as cm:
+ QLabel().set_font(42)
+ print("\n\n" + cm.exception.args[0])
+ self.assertTrue(self.probe in cm.exception.args[0])
+
+ def testCorrectErrorMessagesProp(self):
+ from __feature__ import true_property
+ with self.assertRaises(TypeError) as cm:
+ QLabel().font = 42
+ print("\n\n" + cm.exception.args[0])
+ self.assertTrue(self.probe in cm.exception.args[0])
+
+ def testCorrectErrorMessagesSnakeProp(self):
+ from __feature__ import snake_case, true_property
+ with self.assertRaises(TypeError) as cm:
+ QLabel().font = 42
+ print("\n\n" + cm.exception.args[0])
+ self.assertTrue(self.probe in cm.exception.args[0])
+
+ def testCorrectErrorMessagesClassProp(self):
+ from __feature__ import true_property
+ with self.assertRaises(TypeError) as cm:
+ QApplication.quitOnLastWindowClosed = object
+ print("\n\n" + cm.exception.args[0])
+ self.assertTrue(self.probe in cm.exception.args[0])
+ with self.assertRaises(TypeError) as cm:
+ qApp.quitOnLastWindowClosed = object
+ self.assertTrue(self.probe in cm.exception.args[0])
+
+ def testCorrectErrorMessagesClassSnakeProp(self):
+ from __feature__ import snake_case, true_property
+ with self.assertRaises(TypeError) as cm:
+ QApplication.quit_on_last_window_closed = object
+ print("\n\n" + cm.exception.args[0])
+ self.assertTrue(self.probe in cm.exception.args[0])
+ with self.assertRaises(TypeError) as cm:
+ qApp.quit_on_last_window_closed = object
+ self.assertTrue(self.probe in cm.exception.args[0])
+
+ def testDocIsWorking(self):
+ """
+ make sure that it does not crash when touched
+ """
+ inspect.getdoc(QApplication)
+ inspect.getdoc(QtCore)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/feature_with_uic/window.py b/sources/pyside6/tests/QtCore/feature_with_uic/window.py
new file mode 100644
index 000000000..c55bcaf92
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/feature_with_uic/window.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QHBoxLayout, QMainWindow, QMenuBar,
+ QPushButton, QSizePolicy, QStatusBar, QVBoxLayout,
+ QWidget)
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.resize(263, 196)
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.horizontalLayout = QHBoxLayout(self.centralwidget)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.verticalLayout = QVBoxLayout()
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.pushButton = QPushButton(self.centralwidget)
+ self.pushButton.setObjectName(u"pushButton")
+
+ self.verticalLayout.addWidget(self.pushButton)
+
+ self.horizontalLayout.addLayout(self.verticalLayout)
+
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QMenuBar(MainWindow)
+ self.menubar.setObjectName(u"menubar")
+ self.menubar.setGeometry(QRect(0, 0, 263, 23))
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QStatusBar(MainWindow)
+ self.statusbar.setObjectName(u"statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+
+ self.retranslateUi(MainWindow)
+ self.pushButton.clicked.connect(MainWindow.close)
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
+ self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
+ # retranslateUi
+
diff --git a/sources/pyside6/tests/QtCore/feature_with_uic/window.ui b/sources/pyside6/tests/QtCore/feature_with_uic/window.ui
new file mode 100644
index 000000000..0b85824ea
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/feature_with_uic/window.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>196</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>pushButton</sender>
+ <signal>clicked()</signal>
+ <receiver>MainWindow</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>131</x>
+ <y>97</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>131</x>
+ <y>97</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/sources/pyside6/tests/QtCore/feature_with_uic_test.py b/sources/pyside6/tests/QtCore/feature_with_uic_test.py
new file mode 100644
index 000000000..2ffc9970e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/feature_with_uic_test.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""
+feature_with_uic_test.py
+------------------------
+
+Check if feature switching works with a normal UIC file.
+This crashed due to callbacks into QApplication.
+
+PYSIDE-1626: Switch early in `BindingManager::getOverride`.
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import QCoreApplication, QLibraryInfo, qVersion
+from PySide6.QtWidgets import QApplication, QMainWindow
+
+# PYSIDE-535: We cannot use __feature__ in PyPy, yet
+try:
+ from __feature__ import snake_case
+
+ from feature_with_uic.window import Ui_MainWindow
+ have_feature = True
+except ImportError:
+ Ui_MainWindow = object
+ have_feature = False
+
+
+class MainWindow(QMainWindow, Ui_MainWindow):
+
+ def __init__(self) -> None:
+ super().__init__()
+ self.setupUi(self)
+
+
+@unittest.skipIf(hasattr(sys, "pypy_version_info"),
+ "__feature__ cannot yet be used with PyPy")
+class FeatureTest(UsesQApplication):
+
+ def testFeaturesWorkWithUIC(self):
+ window = MainWindow()
+ window.set_window_title(qVersion())
+ window.show()
+ while not window.window_handle().is_exposed():
+ QCoreApplication.process_events()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/hash_test.py b/sources/pyside6/tests/QtCore/hash_test.py
new file mode 100644
index 000000000..aee2f516c
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/hash_test.py
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDate, QDateTime, QTime, QUrl
+from PySide6.QtCore import QLine, QPoint, QRect, QSize
+
+
+URL = "https://qt.io/"
+
+
+class HashTest(unittest.TestCase):
+ def testInsert(self):
+ myHash = {}
+ qdate = QDate.currentDate()
+ qdatetime = QDateTime.currentDateTime()
+ qtime = QTime.currentTime()
+ qurl = QUrl(URL)
+ self.assertTrue(qurl.isValid())
+ qpoint = QPoint(12, 42)
+
+ myHash[qdate] = "QDate"
+ myHash[qdatetime] = "QDateTime"
+ myHash[qtime] = "QTime"
+ myHash[qurl] = "QUrl"
+ myHash[qpoint] = "QPoint"
+
+ self.assertEqual(myHash[qdate], "QDate")
+ self.assertEqual(myHash[qdatetime], "QDateTime")
+ self.assertEqual(myHash[qtime], "QTime")
+ self.assertEqual(myHash[qurl], "QUrl")
+ self.assertEqual(myHash[qpoint], "QPoint")
+
+ def testQPointHash(self):
+ p1 = QPoint(12, 34)
+ p2 = QPoint(12, 34)
+ self.assertFalse(p1 is p2)
+ self.assertEqual(p1, p2)
+ self.assertEqual(hash(p1), hash(p2))
+
+ def testQSizeHash(self):
+ s1 = QSize(12, 34)
+ s2 = QSize(12, 34)
+ self.assertFalse(s1 is s2)
+ self.assertEqual(s1, s2)
+ self.assertEqual(hash(s1), hash(s2))
+
+ def testQRectHash(self):
+ r1 = QRect(12, 34, 56, 78)
+ r2 = QRect(12, 34, 56, 78)
+ self.assertFalse(r1 is r2)
+ self.assertEqual(r1, r2)
+ self.assertEqual(hash(r1), hash(r2))
+
+ def testQLineHash(self):
+ l1 = QLine(12, 34, 56, 78)
+ l2 = QLine(12, 34, 56, 78)
+ self.assertFalse(l1 is l2)
+ self.assertEqual(l1, l2)
+ self.assertEqual(hash(l1), hash(l2))
+
+ def testQTimeHash(self):
+ t1 = QTime(5, 5, 5)
+ t2 = QTime(5, 5, 5)
+ self.assertFalse(t1 is t2)
+ self.assertEqual(t1, t2)
+ self.assertEqual(hash(t1), hash(t2))
+
+ def testQDateHash(self):
+ d1 = QDate(1968, 3, 9)
+ d2 = QDate(1968, 3, 9)
+ self.assertFalse(d1 is d2)
+ self.assertEqual(d1, d2)
+ self.assertEqual(hash(d1), hash(d2))
+
+ def testQDateTimeHash(self):
+ d1 = QDateTime(QDate(1968, 3, 9), QTime(5, 5, 5))
+ d2 = QDateTime(QDate(1968, 3, 9), QTime(5, 5, 5))
+ self.assertFalse(d1 is d2)
+ self.assertEqual(d1, d2)
+ self.assertEqual(hash(d1), hash(d2))
+
+ def testQUrlHash(self):
+ u1 = QUrl(URL)
+ u2 = QUrl(URL)
+ self.assertFalse(u1 is u2)
+ self.assertEqual(u1, u2)
+ self.assertEqual(hash(u1), hash(u2))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/inherits_test.py b/sources/pyside6/tests/QtCore/inherits_test.py
new file mode 100644
index 000000000..1422616d8
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/inherits_test.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class MyObject(QObject):
+ pass
+
+
+class MainTest(unittest.TestCase):
+ def testInherits(self):
+ o = MyObject()
+ mo = o.metaObject()
+ self.assertEqual(mo.className(), 'MyObject')
+ self.assertTrue(o.inherits('MyObject'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/loggingcategorymacros_test.py b/sources/pyside6/tests/QtCore/loggingcategorymacros_test.py
new file mode 100644
index 000000000..a808f0c3d
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/loggingcategorymacros_test.py
@@ -0,0 +1,84 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""Tests for category logging macros qCDebug, qCInfo, qCWarning, qCCritical"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QLoggingCategory, QtMsgType, qCDebug, qCWarning, qCInfo,
+ qCCritical, qInstallMessageHandler)
+
+param = None
+
+
+def handler(msgt, ctx, msg):
+ global param
+ param = ctx.category + ": " + msg.strip()
+
+
+class TestQLoggingCategory(unittest.TestCase):
+ def setUp(self) -> None:
+ super().setUp()
+ self.defaultCategory = QLoggingCategory("default")
+ self.debugCategory = QLoggingCategory("debug.log", QtMsgType.QtDebugMsg)
+ self.infoCategory = QLoggingCategory("info.log", QtMsgType.QtInfoMsg)
+ self.warningCategory = QLoggingCategory("warning.log", QtMsgType.QtWarningMsg)
+ self.criticalCategory = QLoggingCategory("critical.log", QtMsgType.QtCriticalMsg)
+ qInstallMessageHandler(handler)
+ self.no_devices = 2
+
+ def test_qCDebug(self):
+ qCDebug(self.defaultCategory, "no device")
+ self.assertEqual(param, "default: no device")
+ qCDebug(self.debugCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "debug.log: devices: 2")
+
+ # not updated because category is Info which is above Debug
+ # nothing will be printed here
+ qCDebug(self.infoCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "debug.log: devices: 2")
+
+ def test_qCInfo(self):
+ qCInfo(self.defaultCategory, "no device")
+ self.assertEqual(param, "default: no device")
+ qCInfo(self.debugCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "debug.log: devices: 2")
+ qCInfo(self.infoCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "info.log: devices: 2")
+
+ # not updated because category is Warning which is above Info
+ # nothing will be printed here
+ qCInfo(self.warningCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "info.log: devices: 2")
+
+ def test_qCWarning(self):
+ qCWarning(self.defaultCategory, "no device")
+ self.assertEqual(param, "default: no device")
+ qCWarning(self.debugCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "debug.log: devices: 2")
+ qCWarning(self.warningCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "warning.log: devices: 2")
+
+ # not updated because category is Critical which is above Warning
+ # nothing will be printed here
+ qCWarning(self.criticalCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "warning.log: devices: 2")
+
+ def test_qCritical(self):
+ qCCritical(self.defaultCategory, "no device")
+ self.assertEqual(param, "default: no device")
+ qCCritical(self.warningCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "warning.log: devices: 2")
+ qCCritical(self.criticalCategory, f"devices: {self.no_devices}")
+ self.assertEqual(param, "critical.log: devices: 2")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/max_signals.py b/sources/pyside6/tests/QtCore/max_signals.py
new file mode 100644
index 000000000..95952dfbf
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/max_signals.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, SIGNAL
+
+
+class MyObject(QObject):
+ pass
+
+
+class TestSignalLimitless(unittest.TestCase):
+ SIGNAL_MAX = 100
+
+ def test100DynamicSignals(self):
+
+ self.count = 0
+
+ def onSignal():
+ self.count += 1
+
+ # create 100 dynamic signals
+ o = MyObject()
+ for i in range(self.SIGNAL_MAX):
+ o.connect(SIGNAL(f'sig{i}()'), onSignal)
+
+ # check if the signals are valid
+ m = o.metaObject()
+ for i in range(self.SIGNAL_MAX):
+ self.assertTrue(m.indexOfSignal(f'sig{i}()') > 0)
+
+ # emit all 100 signals
+ for i in range(self.SIGNAL_MAX):
+ o.emit(SIGNAL(f'sig{i}()'))
+
+ self.assertEqual(self.count, self.SIGNAL_MAX)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/missing_symbols_test.py b/sources/pyside6/tests/QtCore/missing_symbols_test.py
new file mode 100644
index 000000000..7cf6d3e3e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/missing_symbols_test.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''(Very) Simple test case for missing names from QtCore'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6 import QtCore
+
+
+class MissingClasses(unittest.TestCase):
+
+ def testQSettings(self): # Bug 232
+ getattr(QtCore, 'QSettings')
+
+ def testQtTrNoop(self): # Bug 220
+ getattr(QtCore, 'QT_TR_NOOP')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/mockclass_test.py b/sources/pyside6/tests/QtCore/mockclass_test.py
new file mode 100644
index 000000000..c7e465b24
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/mockclass_test.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# Test case for PySide bug 634
+# http://bugs.pyside.org/show_bug.cgi?id=634
+# Marcus Lindblom <macke@yar.nu>; 2011-02-16
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication
+
+
+class Mock(object):
+ def __init__(self):
+ self.called = False
+ self.return_value = None
+
+ def __call__(self, *args, **kwargs):
+ self.called = True
+ return self.return_value
+
+
+class MockClassTest(unittest.TestCase):
+ def testMockQCoreApplication(self):
+ mock = Mock()
+ setattr(QCoreApplication, 'instance', mock)
+ QCoreApplication.instance()
+ self.assertTrue(mock.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/multiple_feature_test.py b/sources/pyside6/tests/QtCore/multiple_feature_test.py
new file mode 100644
index 000000000..0f51ace6b
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/multiple_feature_test.py
@@ -0,0 +1,116 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCborArray, QObject
+
+is_pypy = hasattr(sys, "pypy_version_info")
+if not is_pypy:
+ from PySide6.support import feature
+
+from textwrap import dedent
+
+"""
+multiple_feature_test.py
+------------------------
+
+This tests the selectable features in PySide.
+
+The first feature is `snake_case` instead of `camelCase`.
+There is much more to come.
+"""
+
+MethodDescriptorType = type(str.split)
+
+
+def xprint(*args, **kw):
+ if "-v" in sys.argv:
+ print(*args, **kw)
+
+
+@unittest.skipIf(is_pypy, "__feature__ cannot yet be used with PyPy")
+class FeaturesTest(unittest.TestCase):
+
+ def testAllFeatureCombinations(self):
+ """
+ Test for all 256 possible combinations of `__feature__` imports.
+ """
+
+ def tst_bit0(flag, self, bits):
+ if flag == 0:
+ QCborArray.isEmpty
+ QCborArray.__dict__["isEmpty"]
+ with self.assertRaises(AttributeError):
+ QCborArray.is_empty
+ with self.assertRaises(KeyError):
+ QCborArray.__dict__["is_empty"]
+ else:
+ QCborArray.is_empty
+ QCborArray.__dict__["is_empty"]
+ with self.assertRaises(AttributeError):
+ QCborArray.isEmpty
+ with self.assertRaises(KeyError):
+ QCborArray.__dict__["isEmpty"]
+
+ def tst_bit1(flag, self, bits):
+ getter_name = "object_name" if bits & 1 else "objectName"
+ setter_name = "set_object_name" if bits & 1 else "setObjectName"
+ thing = getattr(QObject, getter_name)
+ if flag:
+ self.assertEqual(type(thing), property)
+ with self.assertRaises(AttributeError):
+ getattr(QObject, setter_name)
+ else:
+ self.assertEqual(type(thing), MethodDescriptorType)
+ getattr(QObject, setter_name)
+
+ edict = {}
+ for bit in range(2, 8):
+ # We are cheating here, since the functions are in the globals.
+
+ bit_pow = 1 << bit
+ eval(compile(dedent(f"""
+
+ def tst_bit{bit}(flag, self, bits):
+ if flag == 0:
+ with self.assertRaises(AttributeError):
+ QCborArray.fake_feature_{bit_pow:02x}
+ with self.assertRaises(KeyError):
+ QCborArray.__dict__["fake_feature_{bit_pow:02x}"]
+ else:
+ QCborArray.fake_feature_{bit_pow:02x}
+ QCborArray.__dict__["fake_feature_{bit_pow:02x}"]
+
+ """), "<string>", "exec"), globals(), edict)
+ globals().update(edict)
+ feature_list = feature._really_all_feature_names
+ func_list = [tst_bit0, tst_bit1, tst_bit2, tst_bit3,
+ tst_bit4, tst_bit5, tst_bit6, tst_bit7]
+
+ for idx in range(0x100):
+ feature.reset()
+ config = f"feature_{idx:02x}"
+ xprint()
+ xprint(f"--- Feature Test Config `{config}` ---")
+ xprint("Imports:")
+ for bit in range(8):
+ if idx & 1 << bit:
+ cur_feature = feature_list[bit]
+ text = f"from __feature__ import {cur_feature}"
+ xprint(text)
+ eval(compile(text, "<string>", "exec"), globals(), edict)
+ for bit in range(8):
+ value = idx & 1 << bit
+ func_list[bit](value, self=self, bits=idx)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/python_conversion.py b/sources/pyside6/tests/QtCore/python_conversion.py
new file mode 100644
index 000000000..28a271b61
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/python_conversion.py
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QLineF'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import datetime
+
+from PySide6.QtCore import QTime, QDateTime, QDate
+
+
+class TestDateTimeConversions (unittest.TestCase):
+ def testQDate(self):
+ date = datetime.date(2010, 4, 23)
+ other = QDate(date)
+ self.assertEqual(date.year, other.year())
+ self.assertEqual(date.month, other.month())
+ self.assertEqual(date.day, other.day())
+
+ self.assertEqual(date, other.toPython())
+
+ def testQTime(self):
+ time = datetime.time(11, 14, 0, 1000)
+ other = QTime(time)
+ self.assertEqual(time.hour, other.hour())
+ self.assertEqual(time.minute, other.minute())
+ self.assertEqual(time.second, other.second())
+ self.assertEqual(time.microsecond / 1000, other.msec())
+
+ self.assertEqual(time, other.toPython())
+
+ def testQDateTime(self):
+ dateTime = datetime.datetime(2010, 4, 23, 11, 14, 0, 1000)
+ other = QDateTime(dateTime)
+
+ otherDate = other.date()
+ self.assertEqual(dateTime.year, otherDate.year())
+ self.assertEqual(dateTime.month, otherDate.month())
+ self.assertEqual(dateTime.day, otherDate.day())
+
+ otherTime = other.time()
+ self.assertEqual(dateTime.hour, otherTime.hour())
+ self.assertEqual(dateTime.minute, otherTime.minute())
+ self.assertEqual(dateTime.second, otherTime.second())
+ self.assertEqual(dateTime.microsecond / 1000, otherTime.msec())
+
+ self.assertEqual(dateTime, other.toPython())
+
+ def testQDateTime6arg(self):
+ dateTime = datetime.datetime(2010, 4, 23, 11, 14, 7)
+ other = QDateTime(dateTime)
+
+ otherDate = other.date()
+ self.assertEqual(dateTime.year, otherDate.year())
+ self.assertEqual(dateTime.month, otherDate.month())
+ self.assertEqual(dateTime.day, otherDate.day())
+
+ otherTime = other.time()
+ self.assertEqual(dateTime.hour, otherTime.hour())
+ self.assertEqual(dateTime.minute, otherTime.minute())
+ self.assertEqual(dateTime.second, otherTime.second())
+ self.assertEqual(dateTime.microsecond / 1000, otherTime.msec())
+
+ self.assertEqual(dateTime, other.toPython())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qabs_test.py b/sources/pyside6/tests/QtCore/qabs_test.py
new file mode 100644
index 000000000..2b22b1e17
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qabs_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import qAbs
+
+
+class QAbsTest(unittest.TestCase):
+ '''Tests for qAbs'''
+
+ def testBasic(self):
+ def check(x):
+ self.assertEqual(qAbs(x), abs(x))
+
+ check(0)
+ check(-10)
+ check(10)
+ check(10.5)
+ check(-10.5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qabstractitemmodel_test.py b/sources/pyside6/tests/QtCore/qabstractitemmodel_test.py
new file mode 100644
index 000000000..bb9a2222a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qabstractitemmodel_test.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QAbstractItemModel, QAbstractListModel,
+ QIdentityProxyModel, QObject, QPersistentModelIndex,
+ QStringListModel, Qt)
+
+
+class MyModel (QAbstractListModel):
+ pass
+
+
+class TestQModelIndexInternalPointer(unittest.TestCase):
+
+ def testInternalPointer(self):
+ m = MyModel()
+ foo = QObject()
+ idx = m.createIndex(0, 0, foo)
+ check = m.checkIndex(idx, QAbstractItemModel.CheckIndexOption.IndexIsValid
+ | QAbstractItemModel.CheckIndexOption.DoNotUseParent
+ | QAbstractItemModel.CheckIndexOption.ParentIsInvalid)
+ self.assertTrue(check)
+
+ def testPassQPersistentModelIndexAsQModelIndex(self):
+ # Related to bug #716
+ m = MyModel()
+ idx = QPersistentModelIndex()
+ m.span(idx)
+
+ def testQIdentityProxyModel(self):
+ sourceModel = QStringListModel(['item1', 'item2'])
+ sourceIndex = sourceModel.index(0, 0)
+ sourceData = str(sourceModel.data(sourceIndex, Qt.DisplayRole))
+ proxyModel = QIdentityProxyModel()
+ proxyModel.setSourceModel(sourceModel)
+ proxyIndex = proxyModel.mapFromSource(sourceIndex)
+ proxyData = str(proxyModel.data(proxyIndex, Qt.DisplayRole))
+ self.assertEqual(sourceData, proxyData)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qanimationgroup_test.py b/sources/pyside6/tests/QtCore/qanimationgroup_test.py
new file mode 100644
index 000000000..9b9b0e622
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qanimationgroup_test.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QParallelAnimationGroup, QSequentialAnimationGroup, QTimer
+
+
+class QAnimationGroupTest(unittest.TestCase):
+
+ def testBasic(self):
+ app = QCoreApplication([])
+
+ panim = QParallelAnimationGroup()
+ sanim = QSequentialAnimationGroup()
+ panim.addAnimation(sanim)
+
+ self.assertEqual(sanim.parent(), panim)
+
+ panim.clear()
+
+ self.assertRaises(RuntimeError, lambda: sanim.parent())
+
+ QTimer.singleShot(100, app.quit)
+ app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qbitarray_test.py b/sources/pyside6/tests/QtCore/qbitarray_test.py
new file mode 100644
index 000000000..70452eab1
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qbitarray_test.py
@@ -0,0 +1,134 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests if QBitArray class is iterable and also '~' (__invert__) and bitwise operators'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QBitArray
+
+
+def bool_list_from_qbitarray(qbitarray):
+ '''This function is used instead of a list comprehension because
+ the QBitArray is being tested also to check if it is providing
+ the iterable protocol.
+ '''
+ qbitarray_values = []
+ for i in range(qbitarray.size()):
+ qbitarray_values.append(qbitarray.at(i))
+ return qbitarray_values
+
+
+class QBitArrayIsIterableTest(unittest.TestCase):
+ '''Tests if QBitArray class is iterable and also '~' (__invert__) and bitwise operators'''
+
+ def setUp(self):
+ # Acquire resources
+ self.qbitarray = QBitArray(3)
+ self.qbitarray_values = [True, False, False]
+ # WARNING: do not pythonify the following loop
+ for i in range(len(self.qbitarray_values)):
+ self.qbitarray.setBit(i, self.qbitarray_values[i])
+
+ self.inverted_qbitarray_values = [not bit for bit in self.qbitarray_values]
+
+ self.other_qbitarray = QBitArray(3)
+ self.other_qbitarray_values = [True, True, False]
+ # WARNING: do not pythonify the following loop
+ for i in range(len(self.other_qbitarray_values)):
+ self.other_qbitarray.setBit(i, self.other_qbitarray_values[i])
+
+ def tearDown(self):
+ # Release resources
+ del self.qbitarray
+ del self.other_qbitarray
+ del self.qbitarray_values
+ del self.other_qbitarray_values
+ del self.inverted_qbitarray_values
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testQBitArrayIsIterable(self):
+ # Tests if QBitArray class is iterable
+ qbitarray_is_iterable = True
+ try:
+ bitarray = [bit for bit in self.qbitarray]
+ except:
+ qbitarray_is_iterable = False
+ self.assertTrue(qbitarray_is_iterable)
+
+ def testQBitArrayInvertOperator(self):
+ # Tests QBitArray '~' (__invert__) operator
+ inverted_qbitarray = ~self.qbitarray
+ # WARNING: do not pythonify the following loop, the
+ # iterability of QBitArray class is tested in another place
+ inverted_qbitarray_values = bool_list_from_qbitarray(inverted_qbitarray)
+ self.assertEqual(self.inverted_qbitarray_values, inverted_qbitarray_values)
+
+ def testQBitArrayOrBitwiseOperator(self):
+ # Tests QBitArray '|' (or) operator
+ has_or_bitwise_operator = True
+ ored_qbitarray, ored_bool_list = None, None
+ try:
+ ored_qbitarray = self.qbitarray | self.other_qbitarray
+ ored_bool_list = [b1 | b2 for b1, b2 in zip(self.qbitarray_values, self.other_qbitarray_values)]
+ except:
+ has_or_bitwise_operator = False
+ self.assertTrue(has_or_bitwise_operator)
+ self.assertEqual(bool_list_from_qbitarray(ored_qbitarray), ored_bool_list)
+
+ def testQBitArrayAndBitwiseOperator(self):
+ # Tests QBitArray '&' (and) operator
+ has_and_bitwise_operator = True
+ anded_qbitarray, anded_bool_list = None, None
+ try:
+ anded_qbitarray = self.qbitarray | self.other_qbitarray
+ anded_bool_list = [b1 | b2 for b1, b2 in zip(self.qbitarray_values, self.other_qbitarray_values)]
+ except:
+ has_and_bitwise_operator = False
+ self.assertTrue(has_and_bitwise_operator)
+ self.assertEqual(bool_list_from_qbitarray(anded_qbitarray), anded_bool_list)
+
+ def testQBitArrayXorBitwiseOperator(self):
+ # Tests QBitArray '^' (xor) operator
+ has_xor_bitwise_operator = True
+ xored_qbitarray, xored_bool_list = None, None
+ try:
+ xored_qbitarray = self.qbitarray | self.other_qbitarray
+ xored_bool_list = [b1 | b2 for b1, b2 in zip(self.qbitarray_values, self.other_qbitarray_values)]
+ except:
+ has_xor_bitwise_operator = False
+ self.assertTrue(has_xor_bitwise_operator)
+ self.assertEqual(bool_list_from_qbitarray(xored_qbitarray), xored_bool_list)
+
+
+class QBitArrayGetItemTest(unittest.TestCase):
+ '''Test case for []/__getitem__ operator'''
+
+ def create_bitarray(self, values):
+ '''helper function to create a bit array'''
+ obj = QBitArray(len(values))
+ for i, value in enumerate(values):
+ obj.setBit(i, value)
+ return obj
+
+ def testSequenceProtocol(self):
+ '''QBitArray sequence protocol'''
+ data = [True, False, True]
+ obj = self.create_bitarray(data)
+ for reference, value in zip(data, obj):
+ self.assertEqual(reference, value)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qbytearray_concatenation_operator_test.py b/sources/pyside6/tests/QtCore/qbytearray_concatenation_operator_test.py
new file mode 100644
index 000000000..aea9778d7
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qbytearray_concatenation_operator_test.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QByteArray concatenation with '+' operator'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray
+
+
+class QByteArrayConcatenationOperatorTest(unittest.TestCase):
+ '''Test cases for QByteArray concatenation with '+' operator'''
+
+ def testConcatQByteArrayAndPythonString(self):
+ # Test concatenation of a QByteArray with a Python bytes, in this order
+ qba = QByteArray(bytes('foo', "UTF-8"))
+ result = qba + bytes('\x00bar', "UTF-8")
+ self.assertEqual(type(result), QByteArray)
+ self.assertEqual(result, bytes('foo\x00bar', "UTF-8"))
+
+ def testConcatPythonStringAndQByteArray(self):
+ # Test concatenation of a Python bytes with a QByteArray, in this order
+ concat_python_string_add_qbytearray_worked = True
+ qba = QByteArray(bytes('foo', "UTF-8"))
+ result = bytes('bar\x00', "UTF-8") + qba
+ self.assertEqual(type(result), QByteArray)
+ self.assertEqual(result, bytes('bar\x00foo', "UTF-8"))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qbytearray_operator_iadd_test.py b/sources/pyside6/tests/QtCore/qbytearray_operator_iadd_test.py
new file mode 100644
index 000000000..a2201a716
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qbytearray_operator_iadd_test.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray
+from helper.docmodifier import DocModifier
+
+
+class BaseQByteArrayOperatorIAdd(object):
+ '''Base class for QByteArray += operator tests.
+
+ Implementing classes should inherit from unittest.TestCase and implement
+ setUp, setting self.obj and self.orig_obj to the target QByteArray and original
+ one, respectively'''
+
+ __metaclass__ = DocModifier
+
+ def testSingleString(self):
+ '''QByteArray += bytes of size 1'''
+ s = bytes('0', "UTF-8")
+ self.obj += s
+ self.assertEqual(self.obj, self.orig_obj + s)
+ self.assertEqual(self.obj.size(), self.orig_obj.size() + len(s))
+
+ def testString(self):
+ '''QByteArray += bytes of size > 1'''
+ s = bytearray(bytes('dummy', "UTF-8"))
+ self.obj += s # XXx iadd support abytearray
+ self.assertEqual(self.obj, self.orig_obj + s)
+ self.assertEqual(self.obj.size(), self.orig_obj.size() + len(s))
+
+ def testQByteArray(self):
+ '''QByteArray += QByteArray'''
+ s = QByteArray(bytes('array', "UTF-8"))
+ self.obj += s
+ self.assertEqual(self.obj, self.orig_obj + s)
+
+
+class NullQByteArrayOperatorIAdd(unittest.TestCase, BaseQByteArrayOperatorIAdd):
+ '''Test case for operator QByteArray += on null QByteArrays'''
+
+ doc_prefix = 'Null object'
+ doc_filter = lambda x: x.startswith('test')
+
+ def setUp(self):
+ self.obj = QByteArray()
+ self.orig_obj = QByteArray()
+
+
+class ValidQByteArrayOperatorIAdd(unittest.TestCase, BaseQByteArrayOperatorIAdd):
+ '''Test case for operator QByteArray += on valid QByteArrays'''
+
+ doc_prefix = 'Valid object'
+ doc_filter = lambda x: x.startswith('test')
+
+ def setUp(self):
+ self.obj = QByteArray(bytes('some byte array', "UTF-8"))
+ self.orig_obj = QByteArray(bytes('some byte array', "UTF-8"))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qbytearray_operator_test.py b/sources/pyside6/tests/QtCore/qbytearray_operator_test.py
new file mode 100644
index 000000000..0064e4dd6
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qbytearray_operator_test.py
@@ -0,0 +1,92 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QByteArray operators'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray
+
+
+class QByteArrayOperatorEqual(unittest.TestCase):
+ '''TestCase for operator QByteArray == QByteArray'''
+
+ def testDefault(self):
+ # QByteArray() == QByteArray()
+ obj1 = QByteArray()
+ obj2 = QByteArray()
+ self.assertEqual(obj1, obj2)
+
+ def testSimple(self):
+ # QByteArray(some_string) == QByteArray(some_string)
+ string = bytes('egg snakes', "UTF-8")
+ self.assertEqual(QByteArray(string), QByteArray(string))
+
+ def testPyString(self):
+ # QByteArray(string) == string
+ string = bytes('my test string', "UTF-8")
+ self.assertEqual(QByteArray(string), string)
+
+
+class QByteArrayOperatorAt(unittest.TestCase):
+ '''TestCase for operator QByteArray[]'''
+
+ def testInRange(self):
+ # QByteArray[x] where x is a valid index
+ string = 'abcdefgh'
+ obj = QByteArray(bytes(string, "UTF-8"))
+
+ for i in range(len(string)):
+ self.assertEqual(obj[i], bytes(string[i], "UTF-8"))
+
+ def testInRangeReverse(self):
+ # QByteArray[x] where x is a valid index (reverse order)
+ string = 'abcdefgh'
+ obj = QByteArray(bytes(string, "UTF-8"))
+
+ for i in range(len(string) - 1, 0, -1):
+ self.assertEqual(obj[i], bytes(string[i], "UTF-8"))
+
+ def testOutOfRange(self):
+ # QByteArray[x] where x is out of index
+ string = bytes('1234567', "UTF-8")
+ obj = QByteArray(string)
+ self.assertRaises(IndexError, lambda: obj[len(string)])
+
+ def testNullStrings(self):
+ ba = QByteArray(bytes('\x00', "UTF-8"))
+ self.assertEqual(ba.at(0), '\x00')
+ self.assertEqual(ba[0], bytes('\x00', "UTF-8"))
+
+
+class QByteArrayOperatorLen(unittest.TestCase):
+ '''Test case for __len__ operator of QByteArray'''
+
+ def testBasic(self):
+ '''QByteArray __len__'''
+ self.assertEqual(len(QByteArray()), 0)
+ self.assertEqual(len(QByteArray(bytes('', "UTF-8"))), 0)
+ self.assertEqual(len(QByteArray(bytes(' ', "UTF-8"))), 1)
+ self.assertEqual(len(QByteArray(bytes('yabadaba', "UTF-8"))), 8)
+
+
+class QByteArrayOperatorStr(unittest.TestCase):
+ '''Test case for __str__ operator of QByteArray'''
+
+ def testBasic(self):
+ '''QByteArray __str__'''
+ self.assertEqual(QByteArray().__str__(), str(b''))
+ self.assertEqual(QByteArray(bytes('', "UTF-8")).__str__(), str(b''))
+ self.assertEqual(QByteArray(bytes('aaa', "UTF-8")).__str__(), str(b'aaa'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qbytearray_test.py b/sources/pyside6/tests/QtCore/qbytearray_test.py
new file mode 100644
index 000000000..cb8f9a431
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qbytearray_test.py
@@ -0,0 +1,290 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QByteArray'''
+
+import ctypes
+import os
+import pickle
+import struct
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+
+from PySide6.QtCore import (QByteArray, QSettings, QObject, QDataStream,
+ QIODevice, qCompress, qUncompress)
+
+
+class QByteArrayTestToNumber(unittest.TestCase):
+ def testToNumberInt(self):
+ obj = QByteArray(bytes('37', "UTF8"))
+ self.assertEqual((37, True), obj.toInt())
+
+ def testToNumberUShort(self):
+ obj = QByteArray(bytes('37', "UTF8"))
+ self.assertEqual((37, True), obj.toUShort())
+
+ def testToNumberFloat(self):
+ obj = QByteArray(bytes('37.109', "UTF8"))
+ self.assertEqual((ctypes.c_float(37.109).value, True),
+ obj.toFloat())
+
+ def testToNumberDouble(self):
+ obj = QByteArray(bytes('37.109', "UTF8"))
+ self.assertEqual((ctypes.c_double(37.109).value, True),
+ obj.toDouble())
+
+ def testSetNum(self):
+ b = QByteArray()
+ b.setNum(int(-124124))
+ self.assertEqual(b, "-124124")
+ b = QByteArray()
+ b.setNum(-124124)
+ self.assertEqual(b, "-124124")
+ b = QByteArray()
+ b.setNum(-0.5)
+ self.assertEqual(b, "-0.5")
+
+ def testNumber(self):
+ b = QByteArray.number(int(-124124))
+ self.assertEqual(b, "-124124")
+ b = QByteArray.number(-124124)
+ self.assertEqual(b, "-124124")
+ b = QByteArray.number(-0.5)
+ self.assertEqual(b, "-0.5")
+
+ def testAppend(self):
+ b = QByteArray()
+ b.append(bytes("A", "UTF8"))
+ self.assertEqual(b.size(), 1)
+ b.append(bytes("AB", "UTF8"))
+ self.assertEqual(b.size(), 3)
+
+
+class QByteArraySplit(unittest.TestCase):
+ '''Test case for QByteArray.split'''
+
+ def testPathSeparator(self):
+ # QByteArray.split('/')
+ obj = QByteArray(bytes(unittest.__file__, "UTF8"))
+ self.assertEqual(obj.split('/'), unittest.__file__.split('/'))
+
+
+class QByteArrayData(unittest.TestCase):
+
+ '''Test case for QByteArray.data'''
+
+ def testData(self):
+ url = QByteArray(bytes("http://pyside.org", "UTF8"))
+ self.assertEqual(url.data(), bytes("http://pyside.org", "UTF8"))
+
+ def testDataWithZeros(self):
+ s1 = bytes("123\000321", "UTF8")
+ ba = QByteArray(s1)
+ s2 = ba.data()
+ self.assertEqual(s1, s2)
+ self.assertEqual(s1, ba)
+
+
+class QByteArrayOperatorAtSetter(unittest.TestCase):
+ '''Test case for operator QByteArray[] - __setitem__'''
+
+ def testSetterString(self):
+ '''QByteArray[x] = pythonstring'''
+ obj = QByteArray(bytes('123456', "UTF8"))
+ obj[1] = bytes('0', "UTF8")
+ self.assertEqual(obj, QByteArray(bytes('103456', "UTF8")))
+
+
+class QByteArrayOnQDataStream(unittest.TestCase):
+ '''
+ Bug PYSIDE-232
+ '''
+ def testIt(self):
+ a = QByteArray()
+ b = QDataStream(a, QIODevice.WriteOnly)
+ b.writeUInt16(5000)
+ # The __repr__ not suppose to crash anymore
+ self.assertNotEqual(repr(b), None)
+
+
+class TestBug664(unittest.TestCase):
+ '''
+ QByteArray.data() should return correct data
+ '''
+ def testIt(self):
+ a = QByteArray(bytes('hi 猫', "UTF-8"))
+ self.assertEqual(repr(a), "PySide6.QtCore.QByteArray(b'hi \\xe7\\x8c\\xab')")
+
+
+class QByteArrayOnQVariant(unittest.TestCase):
+ def testQByteArrayOnQVariant(self):
+ a = QSettings().value("some_prop", QByteArray())
+ self.assertEqual(type(a), QByteArray)
+
+
+class TestBug567(unittest.TestCase):
+ '''
+ QByteArray should support slices
+ '''
+ def testIt(self):
+ ba = QByteArray(bytes('1234567890', "UTF8"))
+ self.assertEqual(ba[2:4], '34')
+ self.assertEqual(ba[:4], '1234')
+ self.assertEqual(ba[4:], '567890')
+ self.assertEqual(len(ba[4:1]), 0)
+ self.assertEqual(ba[::-1], '0987654321')
+ self.assertEqual(ba[::2], '13579')
+ self.assertEqual(ba[::-2], '08642')
+ self.assertEqual(ba[2:8:3], '36')
+
+
+class TestPickler(unittest.TestCase):
+ def testIt(self):
+ ba = QByteArray(bytes("321\x00123", "UTF8"))
+ output = pickle.dumps(str(ba))
+ ba2 = pickle.loads(output)
+ self.assertEqual(str(ba), str(ba2))
+
+
+class QByteArrayBug720(unittest.TestCase):
+ def testIt(self):
+ ba = QByteArray(bytes("32\"1\x00123", "UTF8"))
+ self.assertEqual(str(ba), str(bytes("32\"1\x00123", "UTF-8")))
+ self.assertEqual(repr(ba), "PySide6.QtCore.QByteArray(b'32\"1\\x00123')")
+
+
+class QByteArrayImplicitConvert(unittest.TestCase):
+ def testString(self):
+ # No implicit conversions from QByteArray to python string
+ ba = QByteArray(bytes("object name", "UTF8"))
+ obj = QObject()
+ self.assertRaises(TypeError, obj.setObjectName, ba)
+
+
+class QByteArraySliceAssignment(unittest.TestCase):
+ def testIndexAssignment(self):
+ a = QByteArray(bytes('abc', "UTF8"))
+ a[0] = bytes('x', "UTF8")
+ self.assertEqual(a[0], bytes('x', "UTF8"))
+
+ def test_1():
+ a[0] = bytes('xy', "UTF8")
+ self.assertRaises(ValueError, test_1)
+
+ def testSliceAssignmentBytes(self):
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ b[2:8] = bytes('abcdef', "UTF8")
+ self.assertEqual(b[2:8], bytes('abcdef', "UTF8"))
+ # Delete behavior
+ b[2:8] = None
+ self.assertEqual(b, bytes('0189', "UTF8"))
+
+ # number of slots and number of values doesn't match
+ def test_2():
+ b[2:8:2] = bytes('', "UTF8")
+ self.assertRaises(ValueError, test_2)
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ # reverse slice
+ b[5:2:-1] = bytes('ABC', "UTF8")
+ self.assertEqual(b, bytes('012CBA6789', "UTF8"))
+ # step is not 1
+ b[2:9:3] = bytes('XYZ', "UTF8")
+ self.assertEqual(b, bytes('01XCBY67Z9', "UTF8"))
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ b[9:2:-3] = bytes('XYZ', "UTF8")
+ self.assertEqual(b, bytes('012Z45Y78X', "UTF8"))
+
+ def testSliceAssignmentQByteArray(self):
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ b[2:8] = QByteArray(bytes('abcdef', "UTF8"))
+ self.assertEqual(b[2:8], bytes('abcdef', "UTF8"))
+ # shrink
+ b[2:8] = QByteArray(bytes('aaa', "UTF8"))
+ self.assertEqual(b, bytes('01aaa89', "UTF8"))
+ # expand
+ b[2:5] = QByteArray(bytes('uvwxyz', "UTF8"))
+ self.assertEqual(b, bytes('01uvwxyz89', "UTF8"))
+ # Delete behavior
+ b[2:8] = QByteArray()
+ self.assertEqual(b, bytes('0189', "UTF8"))
+
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ # reverse assignment
+ b[5:2:-1] = QByteArray(bytes('ABC', "UTF8"))
+ self.assertEqual(b, bytes('012CBA6789', "UTF8"))
+ # step is not 1
+ b[2:9:3] = QByteArray(bytes('XYZ', "UTF8"))
+ self.assertEqual(b, bytes('01XCBY67Z9', "UTF8"))
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ b[9:2:-3] = QByteArray(bytes('XYZ', "UTF8"))
+ self.assertEqual(b, bytes('012Z45Y78X', "UTF8"))
+
+ def testSliceAssignmentByteArray(self):
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ # replace
+ b[2:8] = bytearray(bytes('abcdef', "UTF8"))
+ self.assertEqual(b[2:8], bytes('abcdef', "UTF8"))
+ # shrink
+ b[2:8] = bytearray(bytes('aaa', "UTF8"))
+ self.assertEqual(b, bytes('01aaa89', "UTF8"))
+ # expand
+ b[2:5] = bytearray(bytes('uvwxyz', "UTF8"))
+ self.assertEqual(b, bytes('01uvwxyz89', "UTF8"))
+ # Delete behavior
+ b[2:8] = bytearray(bytes('', "UTF8"))
+ self.assertEqual(b, bytes('0189', "UTF8"))
+
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ # reverse assignment
+ b[5:2:-1] = bytearray(bytes('ABC', "UTF8"))
+ self.assertEqual(b, bytes('012CBA6789', "UTF8"))
+ # step is not 1
+ b[2:9:3] = bytearray(bytes('XYZ', "UTF8"))
+ self.assertEqual(b, bytes('01XCBY67Z9', "UTF8"))
+ b = QByteArray(bytes('0123456789', "UTF8"))
+ b[9:2:-3] = bytearray(bytes('XYZ', "UTF8"))
+ self.assertEqual(b, bytes('012Z45Y78X', "UTF8"))
+
+ def testBufferProtocol(self):
+ orig_bytes = bytes('0123456789', "UTF8")
+ byte_array = QByteArray(orig_bytes)
+ actual_bytes = bytes(byte_array)
+ self.assertEqual(orig_bytes, actual_bytes)
+
+ def testUnpack(self):
+ b = QByteArray(b'\x19\x00\x00\x00\xc4\t\x00\x00')
+ t = struct.unpack('<ii', b)
+ self.assertEqual(len(t), 2)
+ self.assertEqual(t[0], 25)
+ self.assertEqual(t[1], 2500)
+
+
+class QCompressTest(unittest.TestCase):
+ def testQByteArrayCompression(self):
+ """Compress/uncompress a QByteArray."""
+ data = bytes(10 * 'long redundant sentence bla bla', "UTF8")
+ ba = QByteArray(data)
+ compressed = qCompress(ba)
+ self.assertTrue(len(compressed) < len(data))
+ uncompressed = qUncompress(compressed)
+ self.assertEqual(uncompressed, data)
+
+ def testBufferCompression(self):
+ """Compress/uncompress portions of bytes without converting to
+ QByteArray."""
+ data = bytes(10 * 'long redundant sentence bla bla', "UTF8")
+ used_len = int(len(data) / 2)
+ compressed = qCompress(data, used_len, -1)
+ self.assertTrue(len(compressed) < used_len)
+ uncompressed = qUncompress(compressed.data(), len(compressed))
+ self.assertEqual(uncompressed, data[:used_len])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qcalendar_test.py b/sources/pyside6/tests/QtCore/qcalendar_test.py
new file mode 100644
index 000000000..0137677f3
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qcalendar_test.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QCalendar (5.14)'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCalendar
+
+
+class TestQCalendar (unittest.TestCase):
+ def testCalendar(self):
+ calendar = QCalendar(QCalendar.System.Gregorian)
+ self.assertTrue(calendar.isGregorian())
+ self.assertEqual(calendar.name(), 'Gregorian')
+ self.assertFalse(calendar.hasYearZero())
+ self.assertEqual(calendar.monthsInYear(2019), 12)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qcbor_test.py b/sources/pyside6/tests/QtCore/qcbor_test.py
new file mode 100644
index 000000000..312c9e5c7
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qcbor_test.py
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QCbor'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QByteArray, QCborStreamReader, QCborStreamWriter,
+ QCborTag, QCborValue)
+
+
+class TestCbor(unittest.TestCase):
+ def testReader(self):
+ ba = QByteArray()
+ writer = QCborStreamWriter(ba)
+ writer.append(42)
+ del writer
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(not ba.isEmpty())
+ reader = QCborStreamReader(ba)
+ self.assertTrue(reader.hasNext())
+ value = reader.toInteger()
+ self.assertEqual(value, 42)
+
+ def testReader(self):
+ ba = QByteArray()
+ writer = QCborStreamWriter(ba)
+ writer.append("hello")
+ del writer
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(not ba.isEmpty())
+ reader = QCborStreamReader(ba)
+ self.assertTrue(reader.hasNext())
+ if (reader.isByteArray()): # Python 2
+ value = reader.readByteArray()
+ self.assertTrue(value)
+ self.assertEqual(value.data, "hello")
+ else:
+ self.assertTrue(reader.isString())
+ value = reader.readString()
+ self.assertTrue(value)
+ self.assertEqual(value.data, "hello")
+
+ def testValue(self):
+ value = QCborValue('hello')
+ self.assertTrue(value.isString())
+ self.assertEqual(value.toString(), 'hello')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qcollator_test.py b/sources/pyside6/tests/QtCore/qcollator_test.py
new file mode 100644
index 000000000..9d1052b24
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qcollator_test.py
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QCollator'''
+
+import ctypes
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCollator, QLocale, Qt
+
+
+class QCollatorTest(unittest.TestCase):
+ def testState(self):
+ c = QCollator()
+ c.setCaseSensitivity(Qt.CaseInsensitive)
+ c.setLocale(QLocale.German)
+
+ print("compare a and b:", c.compare("a", "b"))
+
+ self.assertEqual(c.caseSensitivity(), Qt.CaseInsensitive)
+ self.assertEqual(c.locale(), QLocale(QLocale.German))
+
+ c.setLocale(QLocale.French)
+ c.setNumericMode(True)
+ c.setIgnorePunctuation(True)
+ c.setLocale(QLocale.NorwegianBokmal)
+
+ self.assertEqual(c.caseSensitivity(), Qt.CaseInsensitive)
+ self.assertEqual(c.numericMode(), True)
+ self.assertEqual(c.ignorePunctuation(), True)
+ self.assertEqual(c.locale(), QLocale(QLocale.NorwegianBokmal))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qcommandlineparser_test.py b/sources/pyside6/tests/QtCore/qcommandlineparser_test.py
new file mode 100644
index 000000000..c562065ae
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qcommandlineparser_test.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QCommandLineParser and QCommandLineOption'''
+
+import ctypes
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QCommandLineOption, QCommandLineParser
+
+
+class QCommandLineParserTest(unittest.TestCase):
+ def testParser(self):
+ app = QCoreApplication([])
+
+ parser1 = QCommandLineParser()
+ self.assertEqual(parser1.parse(["QtCore_qcommandlineparser_test", "file.txt"]), True)
+ self.assertEqual(parser1.positionalArguments(), ["file.txt"])
+
+ parser2 = QCommandLineParser()
+ self.assertEqual(parser2.addOption(QCommandLineOption("b")), True)
+ self.assertEqual(parser2.parse(["QtCore_qcommandlineparser_test", "-b"]), True)
+ self.assertEqual(parser2.optionNames(), ["b"])
+ self.assertEqual(parser2.isSet("b"), True)
+ self.assertEqual(parser2.values("b"), [])
+ self.assertEqual(parser2.positionalArguments(), [])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qcoreapplication_argv_test.py b/sources/pyside6/tests/QtCore/qcoreapplication_argv_test.py
new file mode 100644
index 000000000..3c8500923
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qcoreapplication_argv_test.py
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication
+
+
+class TestQCoreApplication(unittest.TestCase):
+ def testConsoleEncoding(self):
+ """PYSIDE-1425, console encoding on Windows."""
+ arg0 = "Üllrich Ümläut"
+ app = QCoreApplication([arg0])
+ self.assertEqual(app.arguments()[0], arg0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qcoreapplication_instance_test.py b/sources/pyside6/tests/QtCore/qcoreapplication_instance_test.py
new file mode 100644
index 000000000..968765020
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qcoreapplication_instance_test.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QCoreApplication.instance static method'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication
+
+
+class QCoreApplicationInstanceTest(unittest.TestCase):
+ '''Test cases for QCoreApplication.instance static method'''
+
+ def testQCoreApplicationInstance(self):
+ # Tests QCoreApplication.instance()
+ self.assertEqual(QCoreApplication.instance(), None)
+ app = QCoreApplication([])
+ self.assertEqual(QCoreApplication.instance(), app)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qcoreapplication_test.py b/sources/pyside6/tests/QtCore/qcoreapplication_test.py
new file mode 100644
index 000000000..edd4dc8e2
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qcoreapplication_test.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication
+
+
+class TestQCoreApplication(unittest.TestCase):
+ def testNoArguments(self):
+ app = QCoreApplication()
+ self.assertIsInstance(app, QCoreApplication)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qdatastream_test.py b/sources/pyside6/tests/QtCore/qdatastream_test.py
new file mode 100644
index 000000000..517f466aa
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qdatastream_test.py
@@ -0,0 +1,326 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QDataStream'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+
+init_test_paths(False)
+
+from PySide6.QtCore import QBitArray, QByteArray, QIODevice, QDataStream, QDate, QTime, QDateTime
+
+
+def create_bitarray(string):
+ array = QBitArray(len(string))
+ for i, char in enumerate(string):
+ array.setBit(i, char != '0')
+ return array
+
+
+def serialize_bitarray(bit_array):
+ buffer = QByteArray()
+ stream = QDataStream(buffer, QIODevice.WriteOnly)
+ stream << bit_array
+ return buffer
+
+
+class QDataStreamWrite(unittest.TestCase):
+ '''Test case for QDatastream write* functions'''
+
+ def setUp(self):
+ self.ba = QByteArray()
+ self.read = QDataStream(self.ba, QIODevice.ReadOnly)
+ self.write = QDataStream(self.ba, QIODevice.WriteOnly)
+
+ def testWriteUInt8(self):
+ '''QDataStream.writeUInt8 (accepting str of size 1)'''
+ x = 0xFF
+ self.write.writeUInt8(x)
+ y = self.read.readUInt8()
+ self.assertEqual(x, y)
+
+ self.assertRaises(TypeError, self.write.writeUInt8, 'aaaaa')
+
+ def testWriteInt8(self):
+ '''QDataStream.writeInt8 (accepting str of size 1)'''
+ x = 65
+ self.write.writeInt8(chr(x))
+ y = self.read.readInt8()
+ self.assertEqual(x, y)
+
+ self.assertRaises(TypeError, self.write.writeInt8, 'aaaaa')
+
+ def testWriteUInt8Int(self):
+ '''QDataStream.writeUInt8 (accepting integer)'''
+ x = 0xFF
+ self.write.writeUInt8(x)
+ y = self.read.readUInt8()
+ self.assertEqual(x, y)
+
+ def testWriteInt8Int(self):
+ '''QDataStream.writeInt8 (accepting integer)'''
+ x = 65
+ self.write.writeInt8(x)
+ y = self.read.readInt8()
+ self.assertEqual(x, y)
+
+ def testWriteUInt16(self):
+ '''QDataStream.writeUInt16'''
+ x = 0x4423
+ self.write.writeUInt16(x)
+ y = int(self.read.readUInt16())
+ self.assertEqual(x, y)
+
+ def testWriteUInt32(self):
+ '''QDataStream.writeUInt32'''
+ x = 0xdeadbeef
+ self.write.writeUInt32(x)
+ y = int(self.read.readUInt32())
+ self.assertEqual(x, y)
+
+
+class QDataStreamShift(unittest.TestCase):
+ '''Test case for << and >> operators'''
+
+ def setUp(self):
+ self.ba = QByteArray()
+ self.stream = QDataStream(self.ba, QIODevice.WriteOnly)
+ self.read_stream = QDataStream(self.ba, QIODevice.ReadOnly)
+
+ def testQCharValid(self):
+ '''QDataStream <<>> QChar - valid'''
+ self.stream.writeQChar(42)
+
+ res = self.read_stream.readQChar()
+ self.assertEqual(res, chr(42))
+
+ def testQCharNull(self):
+ '''QDataStream <<>> QChar - null'''
+ self.stream.writeQChar(None)
+
+ res = self.read_stream.readQChar()
+ self.assertEqual(res, '\x00')
+
+ def testQByteArrayValid(self):
+ '''QDataStream <<>> QByteArray - valid'''
+ self.stream << QByteArray(bytes("hello", "UTF-8"))
+
+ res = QByteArray()
+
+ self.read_stream >> res
+ self.assertEqual(res, QByteArray(bytes("hello", "UTF-8")))
+
+ def testQByteArrayEmpty(self):
+ '''QDataStream <<>> QByteArray - empty'''
+ self.stream << QByteArray(bytes("", "UTF-8"))
+
+ res = QByteArray()
+
+ self.read_stream >> res
+ self.assertEqual(res, QByteArray(bytes("", "UTF-8")))
+ self.assertTrue(res.isEmpty())
+ self.assertFalse(res.isNull())
+
+ def testQByteArrayNull(self):
+ '''QDataStream <<>> QByteArray - null'''
+ self.stream << QByteArray()
+
+ res = QByteArray()
+
+ self.read_stream >> res
+ self.assertEqual(res, QByteArray())
+ self.assertTrue(res.isEmpty())
+ self.assertTrue(res.isNull())
+
+ def testQStringValid(self):
+ '''QDataStream <<>> QString - valid'''
+ self.stream.writeQString('Ka-boom')
+
+ res = self.read_stream.readQString()
+ self.assertEqual(res, 'Ka-boom')
+
+ def testQStringEmpty(self):
+ '''QDataStream <<>> QString - empty'''
+ self.stream.writeQString('')
+
+ res = self.read_stream.readQString()
+ self.assertEqual(res, '')
+
+ def testQStringNull(self):
+ '''QDataStream <<>> QString - null'''
+ self.stream.writeQString(None)
+
+ res = self.read_stream.readQString()
+ self.assertEqual(res, '')
+
+ def testQBitArrayNull(self):
+ '''QDataStream <<>> QBitArray - null'''
+ self.stream << QBitArray()
+
+ res = QBitArray()
+
+ self.read_stream >> res
+ self.assertEqual(res, QBitArray())
+
+ def testQBitArrayValid(self):
+ '''QDataStream <<>> QBitArray - valid'''
+ self.stream << create_bitarray('01010101')
+
+ res = QBitArray()
+
+ self.read_stream >> res
+ self.assertEqual(res, create_bitarray('01010101'))
+
+ def testQDateNull(self):
+ '''QDataStream <<>> QDate - null'''
+ self.stream << QDate()
+
+ res = QDate()
+
+ self.read_stream >> res
+ self.assertEqual(res, QDate())
+ self.assertFalse(res.isValid())
+ self.assertTrue(res.isNull())
+
+ def testQDateValid(self):
+ '''QDataStream <<>> QDate - valid'''
+ self.stream << QDate(2012, 12, 21)
+
+ res = QDate()
+
+ self.read_stream >> res
+ self.assertEqual(res, QDate(2012, 12, 21))
+ self.assertTrue(res.isValid())
+ self.assertFalse(res.isNull())
+
+ def testQTimeNull(self):
+ '''QDataStream <<>> QTime - null'''
+ self.stream << QTime()
+
+ res = QTime()
+
+ self.read_stream >> res
+ self.assertEqual(res, QTime())
+ self.assertFalse(res.isValid())
+ self.assertTrue(res.isNull())
+
+ def testQTimeValid(self):
+ '''QDataStream <<>> QTime - valid'''
+ self.stream << QTime(12, 12, 21)
+
+ res = QTime()
+
+ self.read_stream >> res
+ self.assertEqual(res, QTime(12, 12, 21))
+ self.assertTrue(res.isValid())
+ self.assertFalse(res.isNull())
+
+ def testQDateTimeNull(self):
+ '''QDataStream <<>> QDateTime - null'''
+
+ self.stream << QDateTime()
+
+ res = QDateTime()
+
+ self.read_stream >> res
+ self.assertEqual(res, QDateTime())
+ self.assertFalse(res.isValid())
+ self.assertTrue(res.isNull())
+
+ def testQDateTimeValid(self):
+ '''QDataStream <<>> QDateTime - valid'''
+ time = QTime(23, 23, 23)
+ date = QDate(2009, 1, 1)
+
+ self.stream << QDateTime(date, time)
+
+ res = QDateTime()
+
+ self.read_stream >> res
+ self.assertEqual(res, QDateTime(date, time))
+ self.assertTrue(res.isValid())
+ self.assertFalse(res.isNull())
+
+
+class QDataStreamShiftBitArray(unittest.TestCase):
+ def _check_bitarray(self, data_set):
+ '''Check the >> operator for the given data set'''
+
+ for data, expectedStatus, expectedString in data_set:
+ stream = QDataStream(data, QIODevice.ReadOnly)
+ string = QBitArray()
+ stream >> string
+
+ self.assertEqual(stream.status(), expectedStatus)
+ self.assertEqual(string.size(), expectedString.size())
+ self.assertEqual(string, expectedString)
+
+ def testOk(self):
+ '''QDataStream with valid QBitArray'''
+ test_set = [QBitArray()]
+ for i in range(1, 7):
+ test_set.append(create_bitarray(i * '1'))
+ for s in ['0111111', '0000000', '1001110']:
+ test_set.append(create_bitarray(s))
+
+ data = []
+ for expected in test_set:
+ data.append((serialize_bitarray(expected), QDataStream.Ok, expected))
+ self._check_bitarray(data)
+
+ def testPastEnd(self):
+ '''QDataStream >> QBitArray reading past the end of the data'''
+ serialized = serialize_bitarray(create_bitarray('1001110'))
+ serialized.resize(serialized.size() - 2)
+ self._check_bitarray([(serialized, QDataStream.ReadPastEnd, QBitArray())])
+
+
+class QDataStreamBuffer(unittest.TestCase):
+ def testRawData(self):
+ data = QDataStream()
+ self.assertEqual(data.readRawData(4), None)
+
+ ba = QByteArray()
+ data = QDataStream(ba, QIODevice.WriteOnly)
+ data.writeRawData('AB\x00C')
+ self.assertEqual(ba.data(), bytes('AB\x00C', "UTF-8"))
+
+ data = QDataStream(ba)
+ self.assertEqual(data.readRawData(4), bytes('AB\x00C', "UTF-8"))
+
+ def testRawDataBytes(self):
+ test_data = b'AB\0'
+ data = QDataStream()
+ ba = QByteArray()
+ data = QDataStream(ba, QIODevice.WriteOnly)
+ data.writeRawData(test_data)
+ self.assertEqual(ba.data(), test_data)
+ data = QDataStream(ba)
+ self.assertEqual(data.readRawData(3), test_data)
+
+ def testBytes(self):
+ dataOne = QDataStream()
+ self.assertEqual(dataOne.readBytes(4), None)
+
+ ba = QByteArray()
+ data = QDataStream(ba, QIODevice.WriteOnly)
+ # writeBytes() writes a quint32 containing the length of the data,
+ # followed by the data.
+ data.writeBytes(bytes('AB\x00C', 'UTF-8'))
+ self.assertEqual(ba.data(), bytes('\x00\x00\x00\x04AB\x00C', 'UTF-8'))
+
+ data = QDataStream(ba)
+ buffer = data.readBytes(4)
+ self.assertEqual(buffer, bytes('AB\x00C', 'UTF-8'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qdate_test.py b/sources/pyside6/tests/QtCore/qdate_test.py
new file mode 100644
index 000000000..611292227
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qdate_test.py
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QDate'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDate
+
+
+class TestQDate (unittest.TestCase):
+ def testGetDate(self):
+ date = QDate(2009, 22, 9)
+ tuple_ = date.getDate()
+ self.assertEqual(tuple, tuple_.__class__)
+ (y, m, d) = tuple_
+ self.assertEqual(date.year(), y)
+ self.assertEqual(date.month(), m)
+ self.assertEqual(date.day(), d)
+
+ def testGetWeekNumber(self):
+ date = QDate(2000, 1, 1)
+ tuple_ = date.weekNumber()
+ self.assertEqual(tuple, tuple_.__class__)
+ (week, yearNumber) = tuple_
+ self.assertEqual(week, 52)
+ self.assertEqual(yearNumber, 1999)
+
+ def testBooleanCast(self):
+ today = QDate.currentDate()
+ self.assertTrue(today)
+ nodate = QDate()
+ self.assertFalse(nodate)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qdatetime_test.py b/sources/pyside6/tests/QtCore/qdatetime_test.py
new file mode 100644
index 000000000..96e353112
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qdatetime_test.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import datetime
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDateTime, QDate, QTime
+
+
+class TestQDate (unittest.TestCase):
+ def testDateConversion(self):
+ dateTime = QDateTime(QDate(2011, 5, 17), QTime(11, 1, 14, 15))
+ dateTimePy = QDateTime(datetime.date(2011, 5, 17), datetime.time(11, 1, 14, 15000))
+ self.assertEqual(dateTime, dateTimePy)
+
+ def testDateTimeConversion(self):
+ dateTime = QDateTime(QDate(2011, 5, 17), QTime(11, 1, 14, 15))
+ dateTimePy = QDateTime(datetime.datetime(2011, 5, 17, 11, 1, 14, 15000))
+ self.assertEqual(dateTime, dateTimePy)
+
+ def testDateTimeNow(self):
+ py = datetime.datetime.now()
+ qt = QDateTime(py)
+ self.assertEqual(qt, py)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qdir_test.py b/sources/pyside6/tests/QtCore/qdir_test.py
new file mode 100644
index 000000000..702c7f13a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qdir_test.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDir
+
+
+class QDirTest(unittest.TestCase):
+ '''Test case for QDir'''
+
+ def testConstructor(self):
+ # Optional case without arguments is equivalent to the constructor
+ # QDir(const QString &path = QString())
+ a = QDir()
+
+ self.assertTrue(a.isReadable())
+ self.assertTrue(a.isRelative())
+
+ # Empty string
+ b = QDir("")
+ self.assertEqual(a, b)
+
+ # Empty Path
+ c = QDir(Path())
+ self.assertEqual(a, c)
+
+ self.assertEqual(b, c)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qeasingcurve_test.py b/sources/pyside6/tests/QtCore/qeasingcurve_test.py
new file mode 100644
index 000000000..b202dbefb
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qeasingcurve_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+import gc
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QEasingCurve
+
+
+def myFunction(progress):
+ if progress == 1.0:
+ return 100.0
+ else:
+ return -100.0
+
+
+class TestQEasingCurve(unittest.TestCase):
+ def testCustomType(self):
+ ec = QEasingCurve()
+ ec.setCustomType(myFunction)
+ self.assertEqual(ec.valueForProgress(1.0), 100.0)
+ self.assertEqual(ec.valueForProgress(0.5), -100.0)
+
+ def testObjectCleanup(self):
+ for i in range(100):
+ ec = QEasingCurve()
+ ec.setCustomType(myFunction)
+ self.assertEqual(ec.valueForProgress(1.0), 100.0)
+ self.assertEqual(ec.valueForProgress(0.5), -100.0)
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qenum_test.py b/sources/pyside6/tests/QtCore/qenum_test.py
new file mode 100644
index 000000000..45a8e9124
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qenum_test.py
@@ -0,0 +1,202 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QEnum and QFlags'''
+
+import gc
+import os
+import sys
+import pickle
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QIODevice, QObject, QEnum, QFlag
+
+
+class TestEnum(unittest.TestCase):
+ def testOperations(self):
+ k = Qt.Key.Key_1
+
+ # Integers
+ self.assertEqual(k + 2, 2 + k)
+ self.assertEqual(k - 2, -(2 - k))
+ self.assertEqual(k * 2, 2 * k)
+
+ @unittest.skipUnless(getattr(sys, "getobjects", None), "requires --with-trace-refs")
+ @unittest.skipUnless(getattr(sys, "gettotalrefcount", None), "requires --with-pydebug")
+ def testEnumNew_NoLeak(self):
+ gc.collect()
+ total = sys.gettotalrefcount()
+ for idx in range(1000):
+ ret = Qt.Key(42)
+
+ gc.collect()
+ delta = sys.gettotalrefcount() - total
+ print("delta total refcount =", delta)
+ if abs(delta) >= 10:
+ all = [(sys.getrefcount(x), x) for x in sys.getobjects(0)]
+ all.sort(key=lambda x: x[0], reverse=True)
+ for ob in all[:10]:
+ print(ob)
+ self.assertTrue(abs(delta) < 10)
+
+
+class TestQFlags(unittest.TestCase):
+
+ def testToItn(self):
+ om = QIODevice.NotOpen
+ omcmp = om.value
+
+ self.assertEqual(om, QIODevice.NotOpen)
+ self.assertTrue(omcmp == 0)
+
+ self.assertTrue(omcmp != QIODevice.ReadOnly)
+ self.assertTrue(omcmp != 1)
+
+ def testToIntInFunction(self):
+ om = QIODevice.WriteOnly
+ self.assertEqual(int(om.value), 2)
+
+ def testNonExtensibleEnums(self):
+ try:
+ om = QIODevice.OpenMode(QIODevice.WriteOnly)
+ self.assertFail()
+ except:
+ pass
+
+
+# PYSIDE-15: Pickling of enums
+class TestEnumPickling(unittest.TestCase):
+ def testPickleEnum(self):
+
+ # Pickling of enums with different depth works.
+ ret = pickle.loads(pickle.dumps(QIODevice.Append))
+ self.assertEqual(ret, QIODevice.Append)
+
+ ret = pickle.loads(pickle.dumps(Qt.Key.Key_Asterisk))
+ self.assertEqual(ret, Qt.Key.Key_Asterisk)
+ self.assertEqual(ret, Qt.Key(42))
+
+ # We can also pickle the whole enum class (built in):
+ ret = pickle.loads(pickle.dumps(QIODevice))
+
+ # This works also with nested classes for Python 3, after we
+ # introduced the correct __qualname__ attribute.
+
+ # Note: For Python 2, we would need quite strange patches.
+ func = lambda: pickle.loads(pickle.dumps(Qt.Key))
+ func()
+
+# PYSIDE-957: The QEnum macro
+
+
+try:
+ import enum
+ HAVE_ENUM = True
+except ImportError:
+ HAVE_ENUM = False
+ QEnum = QFlag = lambda x: x
+ import types
+
+ class Enum:
+ pass
+ enum = types.ModuleType("enum")
+ enum.Enum = enum.Flag = enum.IntEnum = enum.IntFlag = Enum
+ Enum.__module__ = "enum"
+ Enum.__members__ = {}
+ del Enum
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ enum.auto = lambda: 42
+
+HAVE_FLAG = hasattr(enum, "Flag")
+
+
+@QEnum
+class OuterEnum(enum.Enum):
+ A = 1
+ B = 2
+
+
+class SomeClass(QObject):
+
+ @QEnum
+ class SomeEnum(enum.Enum):
+ A = 1
+ B = 2
+ C = 3
+
+ @QEnum
+ class OtherEnum(enum.IntEnum):
+ A = 1
+ B = 2
+ C = 3
+
+ class InnerClass(QObject):
+
+ @QEnum
+ class InnerEnum(enum.Enum):
+ X = 42
+
+ class SomeEnum(enum.Enum):
+ A = 4
+ B = 5
+ C = 6
+
+ QEnum(SomeEnum) # works even without the decorator assignment
+
+
+class TestQEnumMacro(unittest.TestCase):
+ meta_name = "EnumType" if sys.version_info[:2] >= (3, 11) else "EnumMeta"
+
+ def testTopLevel(self):
+ self.assertEqual(type(OuterEnum).__name__, self.meta_name)
+ self.assertEqual(len(OuterEnum.__members__), 2)
+
+ def testSomeClass(self):
+ self.assertEqual(type(SomeClass.SomeEnum).__name__, self.meta_name)
+ self.assertEqual(len(SomeClass.SomeEnum.__members__), 3)
+ with self.assertRaises(TypeError):
+ int(SomeClass.SomeEnum.C) == 6
+ self.assertEqual(SomeClass.OtherEnum.C, 3)
+
+ @unittest.skipIf(sys.version_info[0] < 3, "we cannot support nested classes in Python 2")
+ def testInnerClass(self):
+ self.assertEqual(SomeClass.InnerClass.InnerEnum.__qualname__,
+ "SomeClass.InnerClass.InnerEnum")
+ with self.assertRaises(TypeError):
+ int(SomeClass.InnerClass.InnerEnum.X) == 42
+
+ @unittest.skipUnless(HAVE_FLAG, "some older Python versions have no 'Flag'")
+ def testEnumFlag(self):
+ with self.assertRaises(TypeError):
+ class WrongFlagForEnum(QObject):
+ @QEnum
+ class Bad(enum.Flag):
+ pass
+ with self.assertRaises(TypeError):
+ class WrongEnuForFlag(QObject):
+ @QFlag
+ class Bad(enum.Enum):
+ pass
+
+ def testIsRegistered(self):
+ mo = SomeClass.staticMetaObject
+ self.assertEqual(mo.enumeratorCount(), 2)
+ self.assertEqual(mo.enumerator(0).name(), "OtherEnum")
+ self.assertEqual(mo.enumerator(0).scope(), "SomeClass")
+ self.assertEqual(mo.enumerator(1).name(), "SomeEnum")
+ moi = SomeClass.InnerClass.staticMetaObject
+ self.assertEqual(moi.enumerator(0).name(), "InnerEnum")
+ ## Question: Should that scope not better be "SomeClass.InnerClass"?
+ ## But we have __qualname__ already:
+ self.assertEqual(moi.enumerator(0).scope(), "InnerClass")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qevent_test.py b/sources/pyside6/tests/QtCore/qevent_test.py
new file mode 100644
index 000000000..244a14f13
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qevent_test.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtCore.QEvent'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QEvent
+
+
+class QEventTypeFlag(unittest.TestCase):
+ '''Test case for usage of QEvent.Type flags'''
+
+ def testFlagAccess(self):
+ # QEvent.Type flags usage
+
+ event = QEvent(QEvent.Timer)
+ self.assertEqual(event.type(), QEvent.Timer)
+
+ event = QEvent(QEvent.Close)
+ self.assertEqual(event.type(), QEvent.Close)
+
+ event = QEvent(QEvent.IconTextChange)
+ self.assertEqual(event.type(), QEvent.IconTextChange)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qfile_test.py b/sources/pyside6/tests/QtCore/qfile_test.py
new file mode 100644
index 000000000..0af5c2650
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qfile_test.py
@@ -0,0 +1,85 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import tempfile
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDir, QFile, QIODevice, QSaveFile, QTemporaryDir
+
+
+class GetCharTest(unittest.TestCase):
+ '''Test case for QIODevice.getChar in QFile'''
+
+ def setUp(self):
+ '''Acquire resources'''
+ handle, self.filename = tempfile.mkstemp()
+ os.write(handle, bytes('a', "UTF-8"))
+ os.close(handle)
+
+ def tearDown(self):
+ '''release resources'''
+ os.remove(self.filename)
+
+ def testBasic(self):
+ '''QFile.getChar'''
+ obj = QFile(self.filename)
+ obj.open(QIODevice.ReadOnly)
+ try:
+ self.assertEqual(obj.getChar(), (True, 'a'))
+ self.assertFalse(obj.getChar()[0])
+ finally:
+ obj.close()
+
+ def testBug721(self):
+ obj = QFile(self.filename)
+ obj.open(QIODevice.ReadOnly)
+ try:
+ memory = obj.map(0, 1)
+ self.assertEqual(len(memory), 1)
+ self.assertEqual(memory[0], ord('a'))
+ # now memory points to wild bytes... :-)
+ # uncommenting this must cause a segfault.
+ # self.assertEqual(memory[0], 'a')
+ finally:
+ obj.unmap(memory)
+ obj.close()
+
+ def testQSaveFile(self):
+ dir = QTemporaryDir(QDir.tempPath() + "/XXXXXX.dir")
+ self.assertTrue(dir.isValid())
+ saveFile = QSaveFile(dir.path() + "/test.dat")
+ self.assertTrue(saveFile.open(QIODevice.WriteOnly))
+ saveFile.write(bytes("Test", "UTF-8"))
+ self.assertTrue(saveFile.commit())
+ self.assertTrue(os.path.exists(QDir.toNativeSeparators(saveFile.fileName())))
+
+
+class GetCharTestPath(GetCharTest):
+ # PYSIDE-1499: Do the same with Path objects
+
+ def setUp(self):
+ '''Acquire resources'''
+ handle, filename = tempfile.mkstemp()
+ self.filename = Path(filename)
+ os.write(handle, bytes('a', "UTF-8"))
+ os.close(handle)
+
+
+class DirPath(unittest.TestCase):
+ # PYSIDE-1499: Test QDir with Path objects
+ def testQDirPath(self):
+ test_path = Path("some") / "dir"
+ qdir1 = QDir(os.fspath(test_path))
+ qdir2 = QDir(test_path)
+ self.assertEqual(qdir1, qdir2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qfileinfo_test.py b/sources/pyside6/tests/QtCore/qfileinfo_test.py
new file mode 100644
index 000000000..dfdfd7fa2
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qfileinfo_test.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import tempfile
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QFile, QFileInfo
+
+
+class QFileConstructor(unittest.TestCase):
+ '''QFileInfo constructor with qfile'''
+
+ def testBasic(self):
+ '''QFileInfo(QFile)'''
+ obj = QFileInfo(QFile())
+
+ def testQFileInfoPath(self):
+ # PYSIDE-1499: Test QFileInfo with Path objects
+ test_path = Path("some") / "dir"
+ qinf1 = QFileInfo(os.fspath(test_path))
+ qinf2 = QFileInfo(test_path)
+ self.assertEqual(qinf1, qinf2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qfileread_test.py b/sources/pyside6/tests/QtCore/qfileread_test.py
new file mode 100644
index 000000000..c66a27f8a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qfileread_test.py
@@ -0,0 +1,66 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QIODevice, QTemporaryFile
+
+
+class FileChild1(QTemporaryFile):
+ pass
+
+
+class FileChild2(QTemporaryFile):
+ def readData(self, maxlen):
+ return super(FileChild2, self).readData(maxlen)
+
+ def readLineData(self, maxlen):
+ return super(FileChild2, self).readLineData(maxlen)
+
+
+class readDataTest(unittest.TestCase):
+ '''Test case for readData and readLineData'''
+
+ def setUp(self):
+ '''Acquire resources'''
+ self.filename1 = FileChild1()
+ self.assertTrue(self.filename1.open())
+ self.filename1.write(bytes('Test text for testing', "UTF-8"))
+
+ self.filename2 = FileChild2()
+ self.assertTrue(self.filename2.open())
+ self.filename2.write(bytes('Test text for testing', "UTF-8"))
+
+ def tearDown(self):
+ '''release resources'''
+ pass
+
+ def testBasic(self):
+ '''QTemporaryFile.read'''
+ self.filename1.seek(0)
+ s1 = self.filename1.read(50)
+ self.assertEqual(s1, 'Test text for testing')
+
+ def testBug40(self):
+ self.filename2.seek(0)
+ s2 = self.filename2.read(50)
+ self.assertEqual(s2, 'Test text for testing')
+
+ self.filename2.seek(0)
+ s2 = self.filename2.readLine(22)
+ self.assertEqual(s2, 'Test text for testing')
+
+ self.filename1.seek(0)
+ s1 = self.filename1.read(50)
+ self.assertEqual(s1, s2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qflags_test.py b/sources/pyside6/tests/QtCore/qflags_test.py
new file mode 100644
index 000000000..2a5306685
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qflags_test.py
@@ -0,0 +1,131 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QFlags'''
+
+import operator
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QTemporaryFile, QFile, QIODevice, QObject
+
+
+class QFlagTest(unittest.TestCase):
+ '''Test case for usage of flags'''
+
+ def testCallFunction(self):
+ f = QTemporaryFile()
+ self.assertTrue(f.open())
+ fileName = f.fileName()
+ f.close()
+
+ f = QFile(fileName)
+ self.assertEqual(f.open(QIODevice.Truncate | QIODevice.Text | QIODevice.ReadWrite), True)
+ om = f.openMode()
+ self.assertEqual(om & QIODevice.Truncate, QIODevice.Truncate)
+ self.assertEqual(om & QIODevice.Text, QIODevice.Text)
+ self.assertEqual(om & QIODevice.ReadWrite, QIODevice.ReadWrite)
+ self.assertTrue(om == QIODevice.Truncate | QIODevice.Text | QIODevice.ReadWrite)
+ f.close()
+
+
+class QFlagOperatorTest(unittest.TestCase):
+ '''Test case for operators in QFlags'''
+
+ def testInvert(self):
+ '''QFlags ~ (invert) operator'''
+ self.assertEqual(type(~QIODevice.ReadOnly), QIODevice.OpenMode)
+
+ def testOr(self):
+ '''QFlags | (or) operator'''
+ self.assertEqual(type(QIODevice.ReadOnly | QIODevice.WriteOnly), QIODevice.OpenMode)
+
+ def testAnd(self):
+ '''QFlags & (and) operator'''
+ self.assertEqual(type(QIODevice.ReadOnly & QIODevice.WriteOnly), QIODevice.OpenMode)
+
+ def testIOr(self):
+ '''QFlags |= (ior) operator'''
+ flag = Qt.WindowFlags()
+ self.assertTrue(Qt.Widget == 0)
+ self.assertFalse(flag & Qt.Widget)
+ result = flag & Qt.Widget
+ self.assertTrue(result == 0)
+ flag |= Qt.WindowMinimizeButtonHint
+ self.assertTrue(flag & Qt.WindowMinimizeButtonHint)
+
+ def testInvertOr(self):
+ '''QFlags ~ (invert) operator over the result of an | (or) operator'''
+ self.assertEqual(type(~(Qt.ItemIsSelectable | Qt.ItemIsEditable)), Qt.ItemFlags)
+
+ def testEqual(self):
+ '''QFlags == operator'''
+ flags = Qt.Window
+ flags |= Qt.WindowMinimizeButtonHint
+ flag_type = (flags & Qt.WindowType_Mask)
+ self.assertEqual(flag_type, Qt.Window)
+
+ self.assertEqual(Qt.KeyboardModifiers(Qt.ControlModifier), Qt.ControlModifier)
+
+ def testOperatorBetweenFlags(self):
+ '''QFlags & QFlags'''
+ flags = Qt.NoItemFlags | Qt.ItemIsUserCheckable
+ newflags = Qt.NoItemFlags | Qt.ItemIsUserCheckable
+ self.assertTrue(flags & newflags)
+
+ def testOperatorDifferentOrder(self):
+ '''Different ordering of arguments'''
+ flags = Qt.NoItemFlags | Qt.ItemIsUserCheckable
+ self.assertEqual(flags | Qt.ItemIsEnabled, Qt.ItemIsEnabled | flags)
+
+ def testEqualNonNumericalObject(self):
+ '''QFlags ==,!= non-numerical object '''
+ flags = Qt.NoItemFlags | Qt.ItemIsUserCheckable
+
+ self.assertTrue(flags != None) # noqa: E711
+ self.assertFalse(flags == None) # noqa: E711
+
+ self.assertTrue(flags != "tomato")
+ self.assertFalse(flags == "tomato")
+
+ with self.assertRaises(TypeError):
+ flags > None
+ with self.assertRaises(TypeError):
+ flags >= None
+ with self.assertRaises(TypeError):
+ flags < None
+ with self.assertRaises(TypeError):
+ flags <= None
+
+
+class QFlagsOnQVariant(unittest.TestCase):
+ def testQFlagsOnQVariant(self):
+ o = QObject()
+ o.setProperty("foo", QIODevice.ReadOnly | QIODevice.WriteOnly)
+ self.assertEqual(type(o.property("foo")), QIODevice.OpenMode)
+
+
+class QEnumFlagDefault(unittest.TestCase):
+ """
+ Check that old flag and enum syntax can be used.
+ The signatures of these surrogate functions intentionally do not exist
+ because people should learn to use the new Enums correctly.
+ """
+ def testOldQFlag(self):
+ self.assertEqual(Qt.AlignmentFlag(), Qt.AlignmentFlag(0))
+ oldFlag = Qt.Alignment()
+ oldEnum = Qt.AlignmentFlag()
+ self.assertEqual(type(oldFlag), Qt.Alignment)
+ self.assertEqual(type(oldEnum), Qt.AlignmentFlag)
+ self.assertEqual(type(oldFlag), type(oldEnum))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qhandle_test.py b/sources/pyside6/tests/QtCore/qhandle_test.py
new file mode 100644
index 000000000..e0f4f3f7a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qhandle_test.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QEnum and QFlags'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QThread, Qt
+
+
+class TestHANDLE(unittest.TestCase):
+ def testIntConversion(self):
+ i = 0
+ h = QThread.currentThreadId()
+ i = 0 + int(h)
+ self.assertEqual(i, int(h))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qinstallmsghandler_test.py b/sources/pyside6/tests/QtCore/qinstallmsghandler_test.py
new file mode 100644
index 000000000..9c5ae4370
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qinstallmsghandler_test.py
@@ -0,0 +1,76 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for qInstallMsgHandler'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QLibraryInfo, QtMsgType,
+ QMessageLogContext,
+ qCritical, qFormatLogMessage, qDebug,
+ qInstallMessageHandler, qWarning)
+
+
+param = []
+
+
+def handler(msgt, ctx, msg):
+ global param
+ param = [msgt, ctx, msg.strip()]
+
+
+def handleruseless(msgt, ctx, msg):
+ pass
+
+
+class QInstallMsgHandlerTest(unittest.TestCase):
+
+ def tearDown(self):
+ # Ensure that next test will have a clear environment
+ qInstallMessageHandler(None)
+
+ def testNone(self):
+ ret = qInstallMessageHandler(None)
+ self.assertEqual(ret, None)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRet(self):
+ ret = qInstallMessageHandler(None)
+ self.assertEqual(ret, None)
+ refcount = sys.getrefcount(handleruseless)
+ retNone = qInstallMessageHandler(handleruseless)
+ self.assertEqual(sys.getrefcount(handleruseless), refcount + 1)
+ rethandler = qInstallMessageHandler(None)
+ self.assertEqual(rethandler, handleruseless)
+ del rethandler
+ self.assertEqual(sys.getrefcount(handleruseless), refcount)
+
+ def testHandler(self):
+ rethandler = qInstallMessageHandler(handler)
+ if QLibraryInfo.isDebugBuild():
+ qDebug("Test Debug")
+ self.assertEqual(param[0], QtMsgType.QtDebugMsg)
+ self.assertEqual(param[2], "Test Debug")
+ qWarning("Test Warning")
+ self.assertEqual(param[0], QtMsgType.QtWarningMsg)
+ self.assertEqual(param[2], "Test Warning")
+ qCritical("Test Critical")
+ self.assertEqual(param[0], QtMsgType.QtCriticalMsg)
+ self.assertEqual(param[2], "Test Critical")
+
+ def testFormat(self):
+ ctx = QMessageLogContext()
+ s = qFormatLogMessage(QtMsgType.QtInfoMsg, ctx, 'bla')
+ self.assertTrue(s)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qiodevice_buffered_read_test.py b/sources/pyside6/tests/QtCore/qiodevice_buffered_read_test.py
new file mode 100644
index 000000000..ea735112a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qiodevice_buffered_read_test.py
@@ -0,0 +1,78 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for buffered read methods of QIODevice'''
+
+from PySide6.QtCore import QBuffer
+
+import enum
+import unittest
+
+
+class TestQIODeviceBufferedRead(unittest.TestCase):
+ class TestType(enum.Enum):
+ Read = enum.auto()
+ ReadLine = enum.auto()
+ Peek = enum.auto()
+
+ def setUp(self) -> None:
+ self.buffer = QBuffer()
+ self.text = "Tomato juice\nPotato salad\n"
+
+ self.assertTrue(
+ self.buffer.open(QBuffer.OpenModeFlag.ReadWrite), self.buffer.errorString())
+ self.assertGreaterEqual(
+ self.buffer.write(self.text.encode("utf-8")), 0, self.buffer.errorString())
+
+ self.buffer.seek(0)
+
+ def tearDown(self) -> None:
+ self.buffer.close()
+
+ def test_read(self) -> None:
+ response1 = self.buffer.read(1024).data().decode("utf-8")
+ self.assertEqual(response1, self.text)
+
+ self.buffer.seek(0)
+ response2 = bytearray(1024)
+ bytes_read = self.buffer.read(response2, 1024)
+
+ self.assertGreaterEqual(bytes_read, 0, self.buffer.errorString())
+ self.assertEqual(response2[:bytes_read].decode("utf-8"), response1)
+
+ def test_readLine(self) -> None:
+ response1 = self.buffer.readLine(1024).data().decode("utf-8")
+ # Only read until the first line (including the line break)
+ self.assertEqual(response1, self.text.split("\n", 1)[0] + "\n")
+
+ self.buffer.seek(0)
+ response2 = bytearray(1024)
+ bytes_read = self.buffer.readLine(response2, 1024)
+
+ self.assertGreaterEqual(bytes_read, 0, self.buffer.errorString())
+ self.assertEqual(response2[:bytes_read].decode("utf-8"), response1)
+
+ def test_peek(self) -> None:
+ response1 = self.buffer.peek(1024).data().decode("utf-8")
+ self.assertEqual(response1, self.text)
+
+ # Test that peek has no side effects
+ response_again1 = self.buffer.read(1024).data().decode("utf-8")
+ self.assertEqual(response_again1, response1)
+
+ self.buffer.seek(0)
+ response2 = bytearray(1024)
+ bytes_read = self.buffer.peek(response2, 1024)
+
+ self.assertGreaterEqual(bytes_read, 0, self.buffer.errorString())
+ self.assertEqual(response2[:bytes_read].decode("utf-8"), response1)
+
+ # Test that peek has no side effects
+ response_again2 = bytearray(1024)
+ bytes_read_again2 = self.buffer.read(response_again2, 1024)
+ self.assertEqual(bytes_read, bytes_read_again2)
+ self.assertEqual(response_again2, response2)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qiopipe_test.py b/sources/pyside6/tests/QtCore/qiopipe_test.py
new file mode 100644
index 000000000..53a6ba70a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qiopipe_test.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for the QIOPipe class'''
+
+from PySide6.QtCore import QIODevice, QIOPipe
+
+import unittest
+
+
+class QIOPipeTest(unittest.TestCase):
+ def setUp(self) -> None:
+ self.pipe = QIOPipe()
+ self.pipe.open(QIODevice.OpenModeFlag.ReadWrite)
+ return super().setUp()
+
+ def tearDown(self) -> None:
+ super().tearDown()
+
+ def ready_read_bytes_written(self):
+ received_data = self.pipe.end2().readAll().data()
+ self.assertEqual(received_data, self.data)
+
+ def test_readyRead(self):
+ self.data = b"Hello, World!"
+ self.pipe.end2().readyRead.connect(self.ready_read_bytes_written)
+ self.pipe.end1().write(self.data)
+
+ def test_bytesWritten(self):
+ self.data = b"Hello, World!"
+ self.pipe.end2().bytesWritten.connect(self.ready_read_bytes_written)
+ self.pipe.end1().write(self.data)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qjsondocument_test.py b/sources/pyside6/tests/QtCore/qjsondocument_test.py
new file mode 100644
index 000000000..a50f185ff
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qjsondocument_test.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QJsonDocument/nullptr_t'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QJsonDocument
+
+
+class QJsonDocumentTest(unittest.TestCase):
+
+ def testToVariant(self):
+ a = QJsonDocument.fromJson(b'{"test": null}')
+ self.assertIsInstance(a, QJsonDocument)
+ self.assertEqual(str(a.toVariant()), "{'test': None}")
+
+ b = QJsonDocument.fromJson(b'{"test": [null]}')
+ self.assertIsInstance(b, QJsonDocument)
+ self.assertEqual(str(b.toVariant()), "{'test': [None]}")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qlinef_test.py b/sources/pyside6/tests/QtCore/qlinef_test.py
new file mode 100644
index 000000000..90ae50159
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qlinef_test.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QLineF'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QLineF, QPointF
+
+
+class TestQLineF (unittest.TestCase):
+ def testIntersect(self):
+ l1 = QLineF(0, 0, 1, 0)
+ l2 = QLineF(1, -1, 1, 1)
+ tuple_ = l1.intersects(l2)
+ self.assertEqual(tuple, tuple_.__class__)
+ (value, p) = tuple_
+ self.assertEqual(QLineF.BoundedIntersection, value)
+ self.assertEqual(QPointF(1, 0), p)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qlocale_test.py b/sources/pyside6/tests/QtCore/qlocale_test.py
new file mode 100644
index 000000000..05b0d3219
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qlocale_test.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QLocale'''
+
+import ctypes
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QLocale
+
+
+class QLocaleTestToNumber(unittest.TestCase):
+ def testToNumberInt(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual((37, True), obj.toInt('37'))
+
+ def testToNumberFloat(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual((ctypes.c_float(37.109).value, True),
+ obj.toFloat('37.109'))
+
+ def testToNumberDouble(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual((ctypes.c_double(37.109).value, True),
+ obj.toDouble('37.109'))
+
+ def testToNumberShort(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual((ctypes.c_short(37).value, True),
+ obj.toShort('37'))
+
+ def testToNumberLong(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual((ctypes.c_long(37).value, True),
+ obj.toLong('37'))
+
+ def testToNumberULongLong(self):
+ obj = QLocale(QLocale.C)
+ self.assertEqual((ctypes.c_ulonglong(37).value, True),
+ obj.toULongLong('37'))
+
+ def testToNumberULongLongNegative(self):
+ obj = QLocale(QLocale.C)
+ self.assertTrue(not obj.toULongLong('-37')[1])
+
+ def testToCurrencyString(self):
+ """PYSIDE-2133, do not use int overload, dropping decimals."""
+ en_locale = QLocale("en_US")
+ value = en_locale.toCurrencyString(1234.56)
+ self.assertEqual(value, "$1,234.56")
+
+ def testToString(self):
+ """PYSIDE-2168, check negative values"""
+ en_locale = QLocale("en_US")
+ value = en_locale.toString(-4)
+ self.assertEqual(value, "-4")
+ # Verify that large types (long long/double) are used.
+ value = en_locale.toString(3000000000)
+ self.assertEqual(value, "3,000,000,000")
+ value = en_locale.toString(10e40)
+ self.assertEqual(value, "1E+41")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qlockfile_test.py b/sources/pyside6/tests/QtCore/qlockfile_test.py
new file mode 100644
index 000000000..6dca9235c
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qlockfile_test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QLockFile'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QDir, QLockFile, QCoreApplication
+
+
+class TestQMessageAuthenticationCode (unittest.TestCase):
+
+ def setUp(self):
+ pid = QCoreApplication.applicationPid()
+ self._fileName = f"{QDir.tempPath()}/pqlockfiletest{pid}.tmp"
+
+ def tearDown(self):
+ if (os.path.exists(self._fileName)):
+ os.remove(self._fileName)
+
+ def test(self):
+ # Merely exercise the API, no locking against another processes.
+ lockFile = QLockFile(self._fileName)
+ self.assertTrue(lockFile.lock())
+ self.assertTrue(lockFile.isLocked())
+ lock_info = lockFile.getLockInfo();
+ self.assertEqual(len(lock_info), 3)
+ self.assertEqual(lock_info[0], os.getpid())
+ lockFile.unlock()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qmessageauthenticationcode_test.py b/sources/pyside6/tests/QtCore/qmessageauthenticationcode_test.py
new file mode 100644
index 000000000..74e6bceb9
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qmessageauthenticationcode_test.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QMessageAuthenticationCode'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCryptographicHash, QMessageAuthenticationCode
+
+
+class TestQMessageAuthenticationCode (unittest.TestCase):
+ def test(self):
+ code = QMessageAuthenticationCode(QCryptographicHash.Sha1, bytes('bla', "UTF-8"))
+ result = code.result()
+ self.assertTrue(result.size() > 0)
+ print(result.toHex())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qmetaobject_test.py b/sources/pyside6/tests/QtCore/qmetaobject_test.py
new file mode 100644
index 000000000..4b3051711
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qmetaobject_test.py
@@ -0,0 +1,213 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests for static methos conflicts with class methods'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QCoreApplication, QFile, QMetaMethod, QMetaObject,
+ QObject, QModelIndex, QPoint, QTimer, QSemaphore,
+ QStringListModel, Qt, Signal, Slot,
+ SIGNAL, Q_ARG, Q_RETURN_ARG)
+
+
+class Foo(QFile):
+ pass
+
+
+class DynObject(QObject):
+ def slot(self):
+ pass
+
+
+class InvokeTester(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ @Slot(int, int, result=int)
+ def add(self, a, b):
+ return a + b
+
+ @Slot(str, str, result=str)
+ def concatenate(self, a, b):
+ return a + b
+
+ @Slot(QPoint, result=int)
+ def manhattan_length(self, point):
+ return abs(point.x()) + abs(point.y())
+
+ @Slot(QPoint, QPoint, result=QPoint)
+ def add_points(self, point1, point2):
+ return point1 + point2
+
+ @Slot(QObject, result=str)
+ def object_name(self, o):
+ return o.objectName()
+
+ @Slot(QObject, result=QObject)
+ def first_child(self, o):
+ return o.children()[0]
+
+
+class SemaphoreSender(QObject):
+ signal = Signal(QSemaphore)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.semaphore = QSemaphore()
+
+ def emitSignal(self):
+ self.signal.emit(self.semaphore)
+
+
+class SemaphoreReceiver(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.semaphore = None
+
+ @Slot(QSemaphore)
+ def receiverSlot(self, semaphore):
+ self.semaphore = semaphore
+
+
+class qmetaobject_test(unittest.TestCase):
+ """
+ def test_QMetaObject(self):
+ qobj = QObject()
+ qobj_metaobj = qobj.metaObject()
+ self.assertEqual(qobj_metaobj.className(), "QObject")
+
+ obj = QFile()
+ m = obj.metaObject()
+ self.assertEqual(m.className(), "QFile")
+ self.assertNotEqual(m.methodCount(), qobj_metaobj.methodCount())
+
+ obj = Foo()
+ m = obj.metaObject()
+ self.assertEqual(m.className(), "Foo")
+ f = QFile()
+ fm = f.metaObject()
+ self.assertEqual(m.methodCount(), fm.methodCount())
+ """
+
+ def test_DynamicSlotSignal(self):
+ o = DynObject()
+ o2 = QObject()
+
+ o.connect(o2, SIGNAL("bars()"), o.slot)
+ self.assertTrue(o2.metaObject().indexOfMethod("bars()") > -1)
+
+ # PYSIDE-784, plain Qt objects should not have intermediary
+ # metaObjects.
+ def test_PlainQObject(self):
+ timer = QTimer()
+ self.assertEqual(timer.metaObject().superClass().className(),
+ "QObject")
+
+ # PYSIDE-1827, slots with non-QObject object types should work
+ # (metatypes are registered)
+ def test_ObjectSlotSignal(self):
+ app = QCoreApplication() # noqa: F841
+ sender = SemaphoreSender()
+ receiver = SemaphoreReceiver()
+ sender.signal.connect(receiver.receiverSlot, Qt.QueuedConnection)
+ sender.emitSignal()
+ while not receiver.semaphore:
+ QCoreApplication.processEvents()
+ self.assertEqual(sender.semaphore, receiver.semaphore)
+
+ # PYSIDE-1898,
+ def test_Invoke(self):
+ tester = InvokeTester()
+
+ # Primitive types
+ sum = QMetaObject.invokeMethod(tester, "add", Q_RETURN_ARG(int),
+ Q_ARG(int, 2), Q_ARG(int, 3))
+ self.assertEqual(sum, 5)
+
+ # Same with QMetaMethod
+ mo = tester.metaObject()
+ method = mo.method(mo.indexOfMethod("add(int,int)"))
+ self.assertTrue(method.isValid())
+ sum = method.invoke(tester, Qt.ConnectionType.AutoConnection,
+ Q_RETURN_ARG(int), Q_ARG(int, 2), Q_ARG(int, 3))
+ self.assertEqual(sum, 5)
+ sum = method.invoke(tester, Q_RETURN_ARG(int), Q_ARG(int, 2),
+ Q_ARG(int, 3))
+ self.assertEqual(sum, 5)
+
+ concatenated = QMetaObject.invokeMethod(tester, "concatenate",
+ Q_RETURN_ARG(str),
+ Q_ARG(str, "bla"),
+ Q_ARG(str, "bla"))
+ self.assertEqual(concatenated, "blabla")
+
+ # Wrapped type as in-parameter
+ point = QPoint(10, 20)
+ len = QMetaObject.invokeMethod(tester, "manhattan_length",
+ Q_RETURN_ARG(int),
+ Q_ARG(QPoint, point))
+ self.assertEqual(len, point.manhattanLength())
+
+ # Wrapped type as result
+ point2 = QPoint(30, 30)
+ point3 = QMetaObject.invokeMethod(tester, "add_points",
+ Q_RETURN_ARG(QPoint),
+ Q_ARG(QPoint, point),
+ Q_ARG(QPoint, point2))
+ self.assertEqual(point + point2, point3)
+
+ # Pass an object
+ o = QObject()
+ o.setObjectName("Foo")
+ name = QMetaObject.invokeMethod(tester, "object_name",
+ Q_RETURN_ARG(str),
+ Q_ARG(QObject, o))
+ self.assertEqual(name, o.objectName())
+
+ # Return an object
+ child = QObject(o)
+ child.setObjectName("Child")
+ c = QMetaObject.invokeMethod(tester, "first_child",
+ Q_RETURN_ARG(QObject),
+ Q_ARG(QObject, o))
+ self.assertTrue(c)
+ self.assertEqual(c, child)
+
+ def test_InvokeTypeString(self):
+ strings = ["item1", "item2"]
+ model = QStringListModel(strings)
+ index = model.index(1, 0)
+ QMetaObject.invokeMethod(model, "setData",
+ Q_ARG(QModelIndex, index),
+ Q_ARG("QVariant", "bla"))
+ self.assertEqual(model.data(index), "bla")
+
+ # Same with QMetaMethod
+ mo = model.metaObject()
+ method = mo.method(mo.indexOfMethod("setData(QModelIndex,QVariant)"))
+ self.assertTrue(method.isValid())
+ method.invoke(model, Qt.ConnectionType.AutoConnection,
+ Q_ARG(QModelIndex, index), Q_ARG("QVariant", "blub"))
+ self.assertEqual(model.data(index), "blub")
+ method.invoke(model, Q_ARG(QModelIndex, index), Q_ARG("QVariant", "blip"))
+ self.assertEqual(model.data(index), "blip")
+
+ def test_QMetaMethod(self):
+ o = QObject()
+ m = QMetaMethod.fromSignal(o.destroyed)
+ self.assertTrue(m.isValid)
+ self.assertEqual(m.methodSignature(), b"destroyed()")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qmetatype_test.py b/sources/pyside6/tests/QtCore/qmetatype_test.py
new file mode 100644
index 000000000..f8e0ba1c0
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qmetatype_test.py
@@ -0,0 +1,43 @@
+#!/usr/bin/python
+# Copyright (C) 2022The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests for QMetaType'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QMetaType, QObject, QPoint)
+
+
+class qmetatype_test(unittest.TestCase):
+ def test_ObjectSlotSignal(self):
+ meta_type = QMetaType(int)
+ self.assertTrue(meta_type.isValid())
+ self.assertEqual(meta_type.name(), "int")
+
+ meta_type = QMetaType(str)
+ self.assertTrue(meta_type.isValid())
+ self.assertEqual(meta_type.name(), "QString")
+
+ meta_type = QMetaType(float)
+ self.assertTrue(meta_type.isValid())
+ self.assertEqual(meta_type.name(), "double")
+
+ meta_type = QMetaType(QPoint)
+ self.assertTrue(meta_type.isValid())
+ self.assertEqual(meta_type.name(), "QPoint")
+
+ meta_type = QMetaType(QObject)
+ self.assertTrue(meta_type.isValid())
+ self.assertEqual(meta_type.name(), "QObject*")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qmimedatabase_test.py b/sources/pyside6/tests/QtCore/qmimedatabase_test.py
new file mode 100644
index 000000000..6a63edb85
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qmimedatabase_test.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QMimeDatabase'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QMimeDatabase, QLocale
+
+
+class QMimeDatabaseTest(unittest.TestCase):
+ def testMimeTypeForName(self):
+ db = QMimeDatabase()
+
+ s0 = db.mimeTypeForName("application/x-zerosize")
+ self.assertTrue(s0.isValid())
+ self.assertEqual(s0.name(), "application/x-zerosize")
+ self.assertTrue(s0.comment())
+
+ s0Again = db.mimeTypeForName("application/x-zerosize")
+ self.assertEqual(s0Again.name(), s0.name())
+
+ s1 = db.mimeTypeForName("text/plain")
+ self.assertTrue(s1.isValid())
+ self.assertEqual(s1.name(), "text/plain")
+
+ krita = db.mimeTypeForName("application/x-krita")
+ self.assertTrue(krita.isValid())
+
+ rdf = db.mimeTypeForName("application/rdf+xml")
+ self.assertTrue(rdf.isValid())
+ self.assertEqual(rdf.name(), "application/rdf+xml")
+ self.assertTrue(rdf.comment())
+ if "en" in QLocale().name():
+ self.assertEqual(rdf.comment(), "RDF file")
+
+ bzip2 = db.mimeTypeForName("application/x-bzip2")
+ self.assertTrue(bzip2.isValid())
+ self.assertTrue(bzip2.comment())
+
+ defaultMime = db.mimeTypeForName("application/octet-stream")
+ self.assertTrue(defaultMime.isValid())
+ self.assertEqual(defaultMime.name(), "application/octet-stream")
+ self.assertTrue(defaultMime.isDefault())
+
+ doesNotExist = db.mimeTypeForName("foobar/x-doesnot-exist")
+ self.assertTrue(not doesNotExist.isValid())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qmodelindex_internalpointer_test.py b/sources/pyside6/tests/QtCore/qmodelindex_internalpointer_test.py
new file mode 100644
index 000000000..ec37ca6a0
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qmodelindex_internalpointer_test.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test case for QAbstractListModel.createIndex and QModelIndex.internalPointer'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QAbstractListModel, QObject
+
+
+class MyModel (QAbstractListModel):
+ pass
+
+
+class TestQModelIndexInternalPointer(unittest.TestCase):
+ ''' Test case for QAbstractListModel.createIndex and QModelIndex.internalPointer'''
+
+ def setUp(self):
+ # Acquire resources
+ self.model = MyModel()
+
+ def tearDown(self):
+ # Release resources
+ del self.model
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testInternalPointer(self):
+ # Test QAbstractListModel.createIndex and
+ # QModelIndex.internalPointer with regular Python objects
+ obj = QObject()
+ idx = self.model.createIndex(0, 0, "Hello")
+ i = idx.internalPointer()
+ self.assertEqual(i, "Hello")
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceCounting(self):
+ # Test reference counting when retrieving data with
+ # QModelIndex.internalPointer
+ o = [1, 2, 3]
+ o_refcnt = sys.getrefcount(o)
+ idx = self.model.createIndex(0, 0, o)
+ ptr = idx.internalPointer()
+ self.assertEqual(sys.getrefcount(o), o_refcnt + 1)
+
+ def testIndexForDefaultDataArg(self):
+ # Test QAbstractListModel.createIndex with a default
+ # value for data argument
+ idx = self.model.createIndex(0, 0)
+ self.assertEqual(None, idx.internalPointer())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qobject_children_segfault_test.py b/sources/pyside6/tests/QtCore/qobject_children_segfault_test.py
new file mode 100644
index 000000000..508526cca
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_children_segfault_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for parent-child relationship'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QCoreApplication
+
+
+class ChildrenCoreApplication(unittest.TestCase):
+ '''Test case for calling QObject.children after creating a QCoreApp'''
+
+ def testQCoreAppChildren(self):
+ # QObject.children() after creating a QCoreApplication
+ # Minimal test:
+ # 1- Create QCoreApp
+ # 2- Create parent and childrens
+ # 3- While keeping the children alive, call parent.children()
+ # 4- Delete parent
+ app = QCoreApplication([])
+ parent = QObject()
+ children = [QObject(parent) for x in range(25)]
+ # Uncomment the lines below to make the test pass
+ # del children
+ # del child2
+ del parent # XXX Segfaults here
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_connect_notify_test.py b/sources/pyside6/tests/QtCore/qobject_connect_notify_test.py
new file mode 100644
index 000000000..b3bfaf007
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_connect_notify_test.py
@@ -0,0 +1,99 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test case for QObject::connectNotify()'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, SIGNAL, SLOT
+from helper.usesqapplication import UsesQApplication
+
+
+def cute_slot():
+ pass
+
+
+class Obj(QObject):
+
+ foo = Signal()
+
+ def __init__(self):
+ super().__init__()
+ self.con_notified = False
+ self.dis_notified = False
+ self.signal = ""
+
+ def connectNotify(self, signal):
+ self.con_notified = True
+ self.signal = signal
+
+ def disconnectNotify(self, signal):
+ self.dis_notified = True
+
+ def reset(self):
+ self.con_notified = False
+ self.dis_notified = False
+
+
+class TestQObjectConnectNotify(UsesQApplication):
+ '''Test case for QObject::connectNotify'''
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self.called = False
+
+ def tearDown(self):
+ UsesQApplication.tearDown(self)
+
+ def testBasic(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.destroyed.connect(receiver.deleteLater)
+ self.assertTrue(sender.con_notified)
+ self.assertEqual(sender.signal.methodSignature(), "destroyed()")
+ self.assertTrue(sender.destroyed.disconnect(receiver.deleteLater))
+ self.assertTrue(sender.dis_notified)
+
+ def testBasicString(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.connect(SIGNAL("destroyed()"), receiver, SLOT("deleteLater()"))
+ self.assertTrue(sender.con_notified)
+ # When connecting to a regular slot, and not a python callback function, QObject::connect
+ # will use the non-cloned method signature, so connecting to destroyed() will actually
+ # connect to destroyed(QObject*).
+ self.assertEqual(sender.signal.methodSignature(), "destroyed(QObject*)")
+ self.assertTrue(sender.disconnect(SIGNAL("destroyed()"), receiver, SLOT("deleteLater()")))
+ self.assertTrue(sender.dis_notified)
+
+ def testPySignal(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.foo.connect(receiver.deleteLater)
+ self.assertTrue(sender.con_notified)
+ self.assertTrue(sender.foo.disconnect(receiver.deleteLater))
+ self.assertTrue(sender.dis_notified)
+
+ def testPySlots(self):
+ sender = Obj()
+ sender.destroyed.connect(cute_slot)
+ self.assertTrue(sender.con_notified)
+ self.assertTrue(sender.destroyed.disconnect(cute_slot))
+ self.assertTrue(sender.dis_notified)
+
+ def testpyAll(self):
+ sender = Obj()
+ sender.foo.connect(cute_slot)
+ self.assertTrue(sender.con_notified)
+ self.assertTrue(sender.foo.disconnect(cute_slot))
+ self.assertTrue(sender.dis_notified)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_destructor.py b/sources/pyside6/tests/QtCore/qobject_destructor.py
new file mode 100644
index 000000000..2b7b40f25
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_destructor.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class MyObject(QObject):
+ def __init__(self, other=None):
+ super().__init__(None)
+ self._o = other
+
+
+class TestDestructor(unittest.TestCase):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReference(self):
+ o = QObject()
+ m = MyObject(o)
+ self.assertEqual(sys.getrefcount(o), 3)
+ del m
+ self.assertEqual(sys.getrefcount(o), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_event_filter_test.py b/sources/pyside6/tests/QtCore/qobject_event_filter_test.py
new file mode 100644
index 000000000..ab7a1b6ad
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_event_filter_test.py
@@ -0,0 +1,150 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QObject.eventFilter'''
+
+import gc
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimerEvent
+
+from helper.usesqapplication import UsesQApplication
+
+
+class FilterObject(QObject):
+ '''Filter object for the basic test'''
+ def __init__(self, obj=None, event_type=None, *args):
+ # Creates a new filter object
+ QObject.__init__(self, *args)
+ self.obj = obj
+ self.event_type = event_type
+ self.events_handled = 0
+ self.events_bypassed = 0
+
+ def setTargetObject(self, obj):
+ # Sets the object that will be filtered
+ self.obj = obj
+
+ def eventFilter(self, obj, event):
+ '''Just checks if is the correct object and event type
+ incrementing counter until reaching the limit. After that it
+ stops filtering the events for the object.'''
+ if (self.obj == obj):
+ if isinstance(event, self.event_type) and self.events_handled < 5:
+ self.events_handled += 1
+ return True
+ else:
+ self.events_bypassed += 1
+ return False
+ else:
+ return QObject.eventFilter(self, obj, event)
+
+
+class FilteredObject(QObject):
+ '''Class that will be filtered. Quits the app after 5 timer events'''
+ def __init__(self, app, *args):
+ QObject.__init__(self, *args)
+ self.app = app
+ self.times_called = 0
+
+ def timerEvent(self, evt):
+ # Overridden method
+ self.times_called += 1
+
+ if self.times_called == 5:
+ self.app.quit()
+
+
+class PolymorphicIdFilterObject(QObject):
+ """PYSIDE-2675: Check whether QChildEvent.added() is accessible via PolymorphicId"""
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.added = False
+
+ def event(self, event):
+ self.added = event.added()
+ return False
+
+
+class TestQObjectEventFilterPython(UsesQApplication):
+ '''QObject.eventFilter - Reimplemented in python
+ Filters 5 TimerEvents and then bypasses the other events to the
+ timerEvent method. After 5 runs, the timerEvent method will ask
+ the core application to exit'''
+ def setUp(self):
+ # Acquire resources
+ UsesQApplication.setUp(self)
+ self.obj_filter = FilterObject(event_type=QTimerEvent)
+
+ def tearDown(self):
+ # Release resources
+ del self.obj_filter
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ def testEventFilter(self):
+ # QObject.eventFilter reimplemented in python
+ filtered = FilteredObject(self.app)
+ filtered.installEventFilter(self.obj_filter)
+ self.obj_filter.setTargetObject(filtered)
+
+ filtered.startTimer(0)
+
+ self.app.exec()
+
+ self.assertEqual(filtered.times_called, 5)
+ self.assertEqual(self.obj_filter.events_handled, 5)
+
+ def testPolymorphicId(self):
+ testObject = PolymorphicIdFilterObject()
+ t2 = QObject(testObject) # noqa: F841
+ self.assertTrue(testObject.added)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testInstallEventFilterRefCountAfterDelete(self):
+ '''Bug 910 - installEventFilter() increments reference count on target object
+ http://bugs.pyside.org/show_bug.cgi?id=910'''
+ obj = QObject()
+ filt = QObject()
+
+ self.assertEqual(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(filt), 2)
+ obj.installEventFilter(filt)
+ self.assertEqual(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(filt), 2)
+
+ wref = weakref.ref(obj)
+ del obj
+ self.assertEqual(wref(), None)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testInstallEventFilterRefCountAfterRemove(self):
+ # Bug 910
+ obj = QObject()
+ filt = QObject()
+
+ self.assertEqual(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(filt), 2)
+ obj.installEventFilter(filt)
+ self.assertEqual(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(filt), 2)
+ obj.removeEventFilter(filt)
+ self.assertEqual(sys.getrefcount(obj), 2)
+ self.assertEqual(sys.getrefcount(filt), 2)
+
+ wref = weakref.ref(obj)
+ del obj
+ self.assertEqual(wref(), None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_inherits_test.py b/sources/pyside6/tests/QtCore/qobject_inherits_test.py
new file mode 100644
index 000000000..0bd4fba75
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_inherits_test.py
@@ -0,0 +1,115 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QObject methods'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimer
+from PySide6.QtWidgets import QApplication, QLabel, QVBoxLayout
+
+is_alive = None
+
+
+class InheritsCase(unittest.TestCase):
+ '''Test case for QObject.inherits'''
+
+ def testCppInheritance(self):
+ # QObject.inherits() for c++ classes
+ # A class inherits itself
+ self.assertTrue(QObject().inherits('QObject'))
+
+ def testPythonInheritance(self):
+ # QObject.inherits() for python classes
+
+ class Dummy(QObject):
+ # Dummy class
+ pass
+
+ self.assertTrue(Dummy().inherits('QObject'))
+ self.assertTrue(Dummy().inherits('Dummy'))
+ self.assertTrue(not Dummy().inherits('FooBar'))
+
+ def testPythonMultiInheritance(self):
+ # QObject.inherits() for multiple inheritance
+ # QObject.inherits(classname) should fail if classname isn't a
+ # QObject subclass
+
+ class Parent(object):
+ # Dummy parent
+ pass
+
+ class Dummy(QObject, Parent):
+ # Dummy class
+ pass
+
+ self.assertTrue(Dummy().inherits('QObject'))
+ self.assertTrue(not Dummy().inherits('Parent'))
+
+ def testSetAttributeBeforeCallingInitOnQObjectDerived(self):
+ '''Test for bug #428.'''
+ class DerivedObject(QObject):
+ def __init__(self):
+ self.member = 'member'
+ super().__init__()
+ obj0 = DerivedObject()
+ # The second instantiation of DerivedObject will generate an exception
+ # that will not come to surface immediately.
+ obj1 = DerivedObject()
+ # The mere calling of the object method causes
+ # the exception to "reach the surface".
+ obj1.objectName()
+
+ def testMultipleInheritance(self):
+ def declareClass():
+ class Foo(object, QObject):
+ pass
+
+ self.assertRaises(TypeError, declareClass)
+
+ # PYSIDE-11:
+ # The takeOwnership() method was relying that the SbkObject
+ # had a converter, which it's not the case when multiple
+ # inheritance is used.
+ # The deleteLater() method uses the takeOwnership() to give
+ # control of the object to C++, so it can be remove once
+ # the destructor is called.
+ # The solution was to add a default case when the object
+ # is null under the pythonTypeIsValueType() method in shiboken.
+ def testDeleteMultipleInheritance(self):
+ app = QApplication(sys.argv)
+
+ class DerivedLabel(QLabel, QObject):
+ def __del__(self):
+ global is_alive
+ is_alive = False
+
+ global is_alive
+ child = DerivedLabel('Hello')
+ is_alive = True
+ parent = QVBoxLayout()
+ parent.addWidget(child)
+ parent.removeWidget(child)
+ child.deleteLater()
+ self.assertTrue(is_alive)
+ del child
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(is_alive)
+ QTimer.singleShot(100, app.quit)
+ app.exec()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertFalse(is_alive)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_objectproperty_test.py b/sources/pyside6/tests/QtCore/qobject_objectproperty_test.py
new file mode 100644
index 000000000..f1a4cb0b5
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_objectproperty_test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for the bug #378
+http://bugs.openbossa.org/show_bug.cgi?id=378
+'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class ExtQObject(QObject):
+ def __init__(self):
+ # "foobar" will become a object attribute that will not be
+ # listed on the among the type attributes. Thus for bug
+ # condition be correctly triggered the "foobar" attribute
+ # must not previously exist in the parent class.
+ self.foobar = None
+ # The parent __init__ method must be called after the
+ # definition of "self.foobar".
+ super().__init__()
+
+
+class TestBug378(unittest.TestCase):
+ '''Test case for the bug #378'''
+
+ def testBug378(self):
+ obj = ExtQObject()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qobject_parent_test.py b/sources/pyside6/tests/QtCore/qobject_parent_test.py
new file mode 100644
index 000000000..6265f77b1
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_parent_test.py
@@ -0,0 +1,335 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for parent-child relationship'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QRegularExpression, QTimer, Qt
+
+
+class TestObject1(QTimer):
+ def __init(self, parent):
+ super().__init__(parent)
+
+
+class TestObject2(TestObject1):
+ def __init(self, parent):
+ super().__init__(parent)
+
+
+class ParentRefCountCase(unittest.TestCase):
+ '''Test case for the refcount changes of setParent'''
+
+ def setUp(self):
+ # Acquire resources
+ self.parent = QObject()
+ self.child = QObject()
+
+ def tearDown(self):
+ # Release resources
+ del self.child
+ del self.parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testSetParent(self):
+ # QObject.setParent() refcount changes
+ self.assertEqual(sys.getrefcount(self.child), 2)
+ self.child.setParent(self.parent)
+ self.assertEqual(sys.getrefcount(self.child), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testSetParentTwice(self):
+ self.assertEqual(sys.getrefcount(self.child), 2)
+ self.child.setParent(self.parent)
+ self.assertEqual(sys.getrefcount(self.child), 3)
+ self.child.setParent(self.parent)
+ self.assertEqual(sys.getrefcount(self.child), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testConstructor(self):
+ # QObject(QObject) refcount changes
+ child = QObject(self.parent)
+ self.assertEqual(sys.getrefcount(child), 3)
+
+
+class ParentCase(unittest.TestCase):
+ '''Small collection of tests related to parent-child relationship'''
+
+ def testSetParent(self):
+ # QObject.setParent()
+ parent = QObject()
+ child = QObject()
+ child.setParent(parent)
+
+ self.assertEqual(parent, child.parent())
+
+ def testParentConstructor(self):
+ # QObject(parent)
+ parent = QObject()
+ child = QObject(parent)
+
+ self.assertEqual(parent, child.parent())
+
+ orig_repr = repr(child)
+ del child
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(orig_repr, repr(parent.children()[0]))
+
+ def testChildren(self):
+ # QObject.children()
+ parent = QObject()
+ children = [QObject(parent) for x in range(25)]
+
+ self.assertEqual(parent.children(), children)
+
+ def testFindChild(self):
+ # QObject.findChild() with all QObject
+ parent = QObject()
+ children = [QObject(parent) for i in range(20)]
+
+ for i, child in enumerate(children):
+ child.setObjectName(f'object{i}')
+
+ for i, child in enumerate(children):
+ self.assertEqual(child, parent.findChild(QObject, f'object{i}'))
+
+ def testFindChildOptions(self):
+ parent = QObject()
+ child = QObject(parent)
+ nested_child_name = 'nestedChild'
+ nested_child = QObject(child)
+ nested_child.setObjectName(nested_child_name)
+
+ search_result = parent.findChild(QObject, nested_child_name)
+ self.assertTrue(search_result)
+ search_result = parent.findChild(QObject, nested_child_name,
+ Qt.FindChildrenRecursively)
+ self.assertTrue(search_result)
+ search_result = parent.findChild(QObject, nested_child_name,
+ Qt.FindDirectChildrenOnly)
+ self.assertFalse(search_result)
+
+ search_results = parent.findChildren(QObject, nested_child_name)
+ self.assertEqual(len(search_results), 1)
+ search_result = parent.findChildren(QObject, nested_child_name,
+ Qt.FindChildrenRecursively)
+ self.assertEqual(len(search_results), 1)
+ search_results = parent.findChildren(QObject, nested_child_name,
+ Qt.FindDirectChildrenOnly)
+ self.assertEqual(len(search_results), 0)
+
+ def testFindChildWithoutName(self):
+ parent = QObject()
+ children = [QObject(parent) for i in range(20)]
+
+ for i, child in enumerate(children):
+ child.setObjectName(f'object{i}')
+
+ child = parent.findChild(QObject)
+ self.assertTrue(isinstance(child, QObject))
+
+ def testFindChildren(self):
+ # QObject.findChildren() with all QObject
+ parent = QObject()
+ target_name = 'foo'
+ children = [QTimer(parent) for i in range(20)]
+ children.extend([QObject(parent) for i in range(20)])
+
+ for i, child in enumerate(children):
+ if i % 5 == 0:
+ child.setObjectName(target_name)
+ else:
+ child.setObjectName(str(i))
+
+ # Emulates findChildren with the intended outcome
+ target_children = [x for x in children if x.objectName() == target_name]
+ test_children = parent.findChildren(QObject, target_name)
+ self.assertEqual(target_children, test_children)
+
+ # test findChildren default value
+ res = parent.findChildren(QTimer)
+ self.assertEqual(len(res), 20)
+
+ # test findChildren with a QRegularExpression
+ res = parent.findChildren(QObject, QRegularExpression("^fo+"))
+ self.assertEqual(res, test_children)
+
+ def testParentEquality(self):
+ # QObject.parent() == parent
+ parent = QObject()
+ child = QObject(parent)
+ self.assertEqual(parent, child.parent())
+
+ def testFindChildByType(self):
+ parent = QObject()
+ expected = TestObject2(parent)
+ actual = parent.findChild(TestObject2)
+ self.assertEqual(actual, expected)
+ actual = parent.findChild(TestObject1)
+ self.assertEqual(actual, expected)
+ actual = parent.findChild(QTimer)
+ self.assertEqual(actual, expected)
+
+ def testFindChildrenByType(self):
+ parent = QObject()
+ expected = [TestObject2(parent)]
+ actual = parent.findChildren(TestObject2)
+ self.assertEqual(actual, expected)
+ actual = parent.findChildren(TestObject1)
+ self.assertEqual(actual, expected)
+ actual = parent.findChildren(QTimer)
+ self.assertEqual(actual, expected)
+
+
+class TestParentOwnership(unittest.TestCase):
+ '''Test case for Parent/Child object ownership'''
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testParentDestructor(self):
+ parent = QObject()
+ self.assertEqual(sys.getrefcount(parent), 2)
+
+ child = QObject(parent)
+ self.assertEqual(sys.getrefcount(child), 3)
+ self.assertEqual(sys.getrefcount(parent), 2)
+
+ del parent
+ self.assertEqual(sys.getrefcount(child), 2)
+
+ # this will fail because parent deleted child cpp object
+ self.assertRaises(RuntimeError, lambda: child.objectName())
+
+ # test parent with multiples children
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testMultipleChildren(self):
+ o = QObject()
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ c = QObject(o)
+ self.assertEqual(sys.getrefcount(c), 3)
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ c2 = QObject(o)
+ self.assertEqual(sys.getrefcount(o), 2)
+ self.assertEqual(sys.getrefcount(c), 3)
+ self.assertEqual(sys.getrefcount(c2), 3)
+
+ del o
+ self.assertEqual(sys.getrefcount(c), 2)
+ self.assertEqual(sys.getrefcount(c2), 2)
+
+ # this will fail because parent deleted child cpp object
+ self.assertRaises(RuntimeError, lambda: c.objectName())
+ self.assertRaises(RuntimeError, lambda: c2.objectName())
+
+ # test recursive parent
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRecursiveParent(self):
+ o = QObject()
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ c = QObject(o)
+ self.assertEqual(sys.getrefcount(c), 3)
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ c2 = QObject(c)
+ self.assertEqual(sys.getrefcount(o), 2)
+ self.assertEqual(sys.getrefcount(c), 3)
+ self.assertEqual(sys.getrefcount(c2), 3)
+
+ del o
+ self.assertEqual(sys.getrefcount(c), 2)
+ self.assertEqual(sys.getrefcount(c2), 2)
+
+ # this will fail because parent deleted child cpp object
+ self.assertRaises(RuntimeError, lambda: c.objectName())
+ self.assertRaises(RuntimeError, lambda: c2.objectName())
+
+ # test parent transfer
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testParentTransfer(self):
+ o = QObject()
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ c = QObject()
+ self.assertEqual(sys.getrefcount(c), 2)
+
+ c.setParent(o)
+ self.assertEqual(sys.getrefcount(c), 3)
+
+ c.setParent(None)
+ self.assertEqual(sys.getrefcount(c), 2)
+
+ del c
+ del o
+
+
+class ExtQObject(QObject):
+ def __init__(self):
+ super().__init__()
+
+
+class ReparentingTest(unittest.TestCase):
+ '''Test cases for reparenting'''
+
+ def testParentedQObjectIdentity(self):
+ object_list = []
+ parent = QObject()
+ for i in range(3):
+ obj = QObject()
+ object_list.append(obj)
+ obj.setParent(parent)
+ for child in parent.children():
+ self.assertTrue(child in object_list)
+
+ def testParentedExtQObjectType(self):
+ object_list = []
+ parent = QObject()
+ for i in range(3):
+ obj = ExtQObject()
+ object_list.append(obj)
+ obj.setParent(parent)
+ for orig, child in zip(object_list, parent.children()):
+ self.assertEqual(type(orig), type(child))
+
+ def testReparentedQObjectIdentity(self):
+ object_list = []
+ old_parent = QObject()
+ new_parent = QObject()
+ for i in range(3):
+ obj = QObject()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for child in new_parent.children():
+ self.assertTrue(child in object_list)
+
+ def testReparentedExtQObjectType(self):
+ object_list = []
+ old_parent = QObject()
+ new_parent = QObject()
+ for i in range(3):
+ obj = ExtQObject()
+ object_list.append(obj)
+ obj.setParent(old_parent)
+ for obj in object_list:
+ obj.setParent(new_parent)
+ for orig, child in zip(object_list, new_parent.children()):
+ self.assertEqual(type(orig), type(child))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_property_test.py b/sources/pyside6/tests/QtCore/qobject_property_test.py
new file mode 100644
index 000000000..4efb25cb4
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_property_test.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QObject property and setProperty'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Property, Signal
+
+
+class MyObjectWithNotifyProperty(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+ self.p = 0
+
+ def readP(self):
+ return self.p
+
+ def writeP(self, v):
+ self.p = v
+ self.notifyP.emit()
+
+ notifyP = Signal()
+ myProperty = Property(int, readP, fset=writeP, notify=notifyP)
+
+
+class PropertyWithNotify(unittest.TestCase):
+ def called(self):
+ self.called_ = True
+
+ def testNotify(self):
+ self.called_ = False
+ obj = MyObjectWithNotifyProperty()
+ obj.notifyP.connect(self.called)
+ obj.myProperty = 10
+ self.assertTrue(self.called_)
+
+ def testHasProperty(self):
+ o = MyObjectWithNotifyProperty()
+ o.setProperty("myProperty", 10)
+ self.assertEqual(o.myProperty, 10)
+ self.assertEqual(o.property("myProperty"), 10)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_protected_methods_test.py b/sources/pyside6/tests/QtCore/qobject_protected_methods_test.py
new file mode 100644
index 000000000..926698b4b
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_protected_methods_test.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QObject protected methods'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QThread, SIGNAL
+
+
+class Dummy(QObject):
+ '''Dummy class'''
+ pass
+
+
+class QObjectReceivers(unittest.TestCase):
+ '''Test case for QObject.receivers()'''
+
+ def cb(self, *args):
+ # Dummy callback
+ pass
+
+ def testQObjectReceiversExtern(self):
+ # QObject.receivers() - Protected method external access
+
+ obj = Dummy()
+ self.assertEqual(obj.receivers(SIGNAL("destroyed()")), 0)
+
+ obj.destroyed.connect(self.cb)
+ self.assertEqual(obj.receivers(SIGNAL("destroyed()")), 1)
+
+ def testQThreadReceiversExtern(self):
+ # QThread.receivers() - Inherited protected method
+
+ obj = QThread()
+ self.assertEqual(obj.receivers(SIGNAL('destroyed()')), 0)
+ obj.destroyed.connect(self.cb)
+ self.assertEqual(obj.receivers(SIGNAL("destroyed()")), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_test.py b/sources/pyside6/tests/QtCore/qobject_test.py
new file mode 100644
index 000000000..ecfc3dff0
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_test.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QObject methods'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Slot, Qt
+
+
+class Obj(QObject):
+ signal = Signal()
+
+ def empty(self):
+ pass
+
+ def emitSignal(self):
+ self.signal.emit()
+
+
+class Receiver(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._count = 0
+
+ def count(self):
+ return self._count
+
+ @Slot()
+ def testSlot(self):
+ self._count += 1
+
+
+class ObjectNameCase(unittest.TestCase):
+ '''Tests related to QObject object name'''
+
+ def testSimple(self):
+ # QObject.objectName(string)
+ name = 'object1'
+ obj = QObject()
+ obj.setObjectName(name)
+
+ self.assertEqual(name, obj.objectName())
+
+ def testEmpty(self):
+ # QObject.objectName('')
+ name = ''
+ obj = QObject()
+ obj.setObjectName(name)
+
+ self.assertEqual(name, obj.objectName())
+
+ def testDefault(self):
+ # QObject.objectName() default
+ obj = QObject()
+ self.assertEqual('', obj.objectName())
+
+ def testUnicode(self):
+ name = 'não'
+ # FIXME Strange error on upstream when using equal(name, obj)
+ obj = QObject()
+ obj.setObjectName(name)
+ self.assertEqual(obj.objectName(), name)
+
+ def testUniqueConnection(self):
+ obj = Obj()
+ # On first connect, UniqueConnection returns True, and on the second
+ # it must return False, and not a RuntimeError (PYSIDE-34)
+ self.assertTrue(obj.signal.connect(obj.empty, Qt.UniqueConnection))
+ self.assertFalse(obj.signal.connect(obj.empty, Qt.UniqueConnection))
+
+ def testDisconnect(self):
+ obj = Obj()
+ receiver = Receiver()
+ conn_id = obj.signal.connect(receiver.testSlot)
+ self.assertTrue(conn_id)
+
+ obj.emitSignal()
+ self.assertEqual(receiver.count(), 1)
+
+ obj.signal.disconnect(conn_id)
+ obj.emitSignal()
+ self.assertEqual(receiver.count(), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_timer_event_test.py b/sources/pyside6/tests/QtCore/qobject_timer_event_test.py
new file mode 100644
index 000000000..9e657c27f
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_timer_event_test.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for QObject.timerEvent overloading'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QCoreApplication
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Dummy(QObject):
+
+ def __init__(self, app):
+ super().__init__()
+ self.times_called = 0
+ self.app = app
+
+ def timerEvent(self, event):
+ QObject.timerEvent(self, event)
+ event.accept()
+ self.times_called += 1
+
+ if self.times_called == 5:
+ self.app.exit(0)
+
+
+class QObjectTimerEvent(UsesQApplication):
+
+ def setUp(self):
+ # Acquire resources
+ super(QObjectTimerEvent, self).setUp()
+
+ def tearDown(self):
+ # Release resources
+ super(QObjectTimerEvent, self).tearDown()
+
+ def testTimerEvent(self):
+ # QObject.timerEvent overloading
+ obj = Dummy(self.app)
+ timer_id = obj.startTimer(200)
+ self.app.exec()
+ obj.killTimer(timer_id)
+ self.assertEqual(obj.times_called, 5)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qobject_tr_as_instance_test.py b/sources/pyside6/tests/QtCore/qobject_tr_as_instance_test.py
new file mode 100644
index 000000000..9123c5155
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qobject_tr_as_instance_test.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QObject's tr static methods.'''
+
+import gc
+import os
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+#from helper.usesqapplication import UsesQApplication
+
+
+class QObjectTrTest(unittest.TestCase):
+ '''Test case to check if QObject tr static methods could be treated as instance methods.'''
+
+ def setUp(self):
+ self.obj = QObject()
+
+ def tearDown(self):
+ del self.obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testTrCommonCase(self):
+ # Test common case for QObject.tr
+ invar1 = 'test1'
+ outvar1 = self.obj.tr(invar1)
+ invar2 = 'test2'
+ outvar2 = self.obj.tr(invar2, 'test comment')
+ self.assertEqual((invar1, invar2), (outvar1, outvar2))
+
+ def testTrAsInstanceMethod(self):
+ # Test QObject.tr as instance.
+ # PYSIDE-1252: This works now as a class method!
+ invar1 = 'test1'
+ outvar1 = QObject.tr(invar1)
+ invar2 = 'test2'
+ outvar2 = QObject.tr(invar2, 'test comment')
+ self.assertEqual((invar1, invar2), (outvar1, outvar2))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qoperatingsystemversion_test.py b/sources/pyside6/tests/QtCore/qoperatingsystemversion_test.py
new file mode 100644
index 000000000..d887029ac
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qoperatingsystemversion_test.py
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QOperatingSystemVersion
+
+
+class TestQOperatingSystemVersion(unittest.TestCase):
+ def test(self):
+ ov = QOperatingSystemVersion.current()
+ name = f"{ov.name()} v{ov.majorVersion()}.{ov.minorVersion()}.{ov.microVersion()}"
+ print(name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qpoint_test.py b/sources/pyside6/tests/QtCore/qpoint_test.py
new file mode 100644
index 000000000..b9d5afa37
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qpoint_test.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QPoint and QPointF'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPoint, QPointF
+
+
+class QPointTest(unittest.TestCase):
+
+ def testQPointCtor(self):
+ point = QPoint(QPoint(10, 20))
+
+
+class QPointFTest(unittest.TestCase):
+
+ def testQPointFCtor(self):
+ pointf = QPointF(QPoint(10, 20))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qprocess_test.py b/sources/pyside6/tests/QtCore/qprocess_test.py
new file mode 100644
index 000000000..ba4d29102
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qprocess_test.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QProcess'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QProcess
+
+
+class TestQProcess (unittest.TestCase):
+ def testStartDetached(self):
+ value, pid = QProcess.startDetached("dir", [], os.getcwd())
+ self.assertTrue(isinstance(value, bool))
+ self.assertTrue(isinstance(pid, int))
+
+ def testPid(self):
+ p = QProcess()
+ p.start("dir", [])
+ p.waitForStarted()
+ pid = p.processId()
+ # We can't test the pid method result because it returns 0 when the
+ # process isn't running
+ if p.state() == QProcess.Running:
+ self.assertNotEqual(pid, 0)
+ p.waitForFinished()
+ else:
+ print("PROCESS ALREADY DEAD :-/")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qproperty_decorator.py b/sources/pyside6/tests/QtCore/qproperty_decorator.py
new file mode 100644
index 000000000..19f2bd251
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qproperty_decorator.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Property
+
+
+class MyObject(QObject):
+ def __init__(self):
+ super().__init__()
+ self._value = None
+
+ @Property(int)
+ def value(self):
+ return self._value
+
+ @value.setter
+ # Note: The name of property and setter must be the same, because the
+ # object changes its identity all the time. `valueSet` no longer works.
+ def value(self, value):
+ self._value = value
+
+
+class PropertyTest(unittest.TestCase):
+ def destroyCB(self, obj):
+ self._obDestroyed = True
+
+ def testDecorator(self):
+ self._obDestroyed = False
+ o = MyObject()
+ weak = weakref.ref(o, self.destroyCB)
+ o.value = 10
+ self.assertEqual(o._value, 10)
+ self.assertEqual(o.value, 10)
+ del o
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
+ self.assertTrue(self._obDestroyed)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qrandomgenerator_test.py b/sources/pyside6/tests/QtCore/qrandomgenerator_test.py
new file mode 100644
index 000000000..c13a8b24a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qrandomgenerator_test.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QRandomGenerator, QRandomGenerator64
+
+
+class QRandomGeneratorTest(unittest.TestCase):
+ '''Test case for QRandomGenerator'''
+
+ def testGenerator(self):
+ self.assertTrue(QRandomGenerator.system())
+ self.assertTrue(QRandomGenerator.global_())
+ generator = QRandomGenerator()
+ r = generator.bounded(10, 20)
+ self.assertTrue(r >= 10)
+ self.assertTrue(r <= 20)
+
+ def testGenerator64(self):
+ generator = QRandomGenerator64()
+ r = generator.generate()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qrect_test.py b/sources/pyside6/tests/QtCore/qrect_test.py
new file mode 100644
index 000000000..8a14abc5a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qrect_test.py
@@ -0,0 +1,123 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QRect'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPoint, QRect, QRectF
+
+
+class RectConstructor(unittest.TestCase):
+
+ def testDefault(self):
+ # QRect()
+ obj = QRect()
+
+ self.assertTrue(obj.isNull())
+
+ def testConstructorQPoint(self):
+ topLeft = QPoint(3, 0)
+ bottomRight = QPoint(0, 3)
+
+ rect1 = QRect(topLeft, bottomRight)
+ rect2 = QRect(topLeft, bottomRight)
+
+ self.assertEqual(rect1, rect2)
+
+
+class RectOperator(unittest.TestCase):
+ '''Test case for QRect operators'''
+
+ def testEqual(self):
+ '''QRect == QRect
+ Note: operator == must be working as it's the main check
+ for correctness'''
+ rect1 = QRect()
+ rect2 = QRect()
+ self.assertEqual(rect1, rect2)
+
+ rect1 = QRect(0, 4, 100, 300)
+ rect2 = QRect(0, 4, 100, 300)
+ self.assertEqual(rect1, rect2)
+
+ def testNullRectIntersection(self):
+ # QRect & QRect for null rects
+ rect1 = QRect()
+ rect2 = QRect()
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, rect1)
+ self.assertEqual(rect3, rect2)
+
+ def testNoIntersect(self):
+ '''QRect & QRect for non-intersecting QRects
+ Non-intersecting QRects return a 'null' QRect for operator &'''
+ rect1 = QRect(10, 10, 5, 5)
+ rect2 = QRect(20, 20, 5, 5)
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, QRect())
+
+ def testIntersectPartial(self):
+ # QRect & QRect for partial intersections
+ rect1 = QRect(10, 10, 10, 10)
+ rect2 = QRect(15, 15, 10, 10)
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, QRect(15, 15, 5, 5))
+
+ def testIntersetEnclosed(self):
+ # QRect & QRect for a qrect inside another
+ rect1 = QRect(10, 10, 20, 20)
+ rect2 = QRect(15, 15, 5, 5)
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, rect2)
+
+ def testNullRectIntersectBounding(self):
+ # QRect | QRect for null rects
+ rect1 = QRect()
+ rect2 = QRect()
+ rect3 = rect1 & rect2
+ self.assertEqual(rect3, rect1)
+ self.assertEqual(rect3, rect2)
+
+ def testNoIntersectBounding(self):
+ '''QRect | QRect for non-intersecting QRects
+ Non-intersecting QRects return a greater QRect for operator |'''
+ rect1 = QRect(10, 10, 5, 5)
+ rect2 = QRect(20, 20, 5, 5)
+ rect3 = rect1 | rect2
+ self.assertEqual(rect3, QRect(10, 10, 15, 15))
+
+ def testBoundingPartialIntersection(self):
+ # QRect | QRect for partial intersections
+ rect1 = QRect(10, 10, 10, 10)
+ rect2 = QRect(15, 15, 10, 10)
+ rect3 = rect1 | rect2
+ self.assertEqual(rect3, QRect(10, 10, 15, 15))
+
+ def testBoundingEnclosed(self):
+ # QRect | QRect for a qrect inside another
+ rect1 = QRect(10, 10, 20, 20)
+ rect2 = QRect(15, 15, 5, 5)
+ rect3 = rect1 | rect2
+ self.assertEqual(rect3, rect1)
+
+ def testGetCoordsAndRect(self):
+ rect1 = QRect(1, 2, 3, 4)
+ self.assertEqual(rect1.getRect(), (1, 2, 3, 4))
+ self.assertEqual(rect1.getCoords(), (1, 2, 3, 5))
+
+ rect1 = QRectF(1, 2, 3, 4)
+ self.assertEqual(rect1.getRect(), (1, 2, 3, 4))
+ self.assertEqual(rect1.getCoords(), (1, 2, 4, 6))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qregularexpression_test.py b/sources/pyside6/tests/QtCore/qregularexpression_test.py
new file mode 100644
index 000000000..a88c2dc24
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qregularexpression_test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QRegularExpression'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QRegularExpression, QRegularExpressionMatch, QRegularExpressionMatchIterator
+
+
+class QRegularExpressionTest(unittest.TestCase):
+
+ def testMatch(self):
+ re = QRegularExpression('^.*(word2).*$')
+ self.assertTrue(re.isValid())
+ match = re.match('word1 word2 word3')
+ self.assertTrue(match.isValid())
+ self.assertEqual(match.captured(1), 'word2')
+ self.assertEqual(match.capturedView(1), 'word2')
+
+ def testMatchIterator(self):
+ re = QRegularExpression('(\w+)')
+ self.assertTrue(re.isValid())
+ count = 0
+ it = re.globalMatch('word1 word2 word3')
+ while it.hasNext():
+ it.next()
+ count = count + 1
+ self.assertEqual(count, 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qresource_test.py b/sources/pyside6/tests/QtCore/qresource_test.py
new file mode 100644
index 000000000..1cdd2c785
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qresource_test.py
@@ -0,0 +1,56 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QResource usage'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray, QFile, QIODevice
+import resources_mc
+
+
+class ResourcesUsage(unittest.TestCase):
+ '''Test case for resources usage'''
+
+ def testPhrase(self):
+ # Test loading of quote.txt resource
+ file = Path(__file__).resolve().parent / 'quoteEnUS.txt'
+ self.assertTrue(file.is_file())
+ orig = QByteArray(file.read_bytes())
+ # In case the file is checked out in 'crlf' mode, strip '\r'
+ # since we read binary.
+ if sys.platform == 'win32':
+ carriage_return = orig.indexOf('\r')
+ if carriage_return != -1:
+ orig.remove(carriage_return, 1)
+
+ f = QFile(':/quote.txt') # |QIODevice.Text
+ self.assertTrue(f.open(QIODevice.ReadOnly), f.errorString())
+ copy = f.readAll()
+ f.close()
+ self.assertEqual(orig, copy)
+
+ def testImage(self):
+ # Test loading of sample.png resource
+ file = Path(__file__).resolve().parent / 'sample.png'
+ self.assertTrue(file.is_file())
+ orig = file.read_bytes()
+
+ f = QFile(':/sample.png')
+ self.assertTrue(f.open(QIODevice.ReadOnly), f.errorString())
+ copy = f.readAll()
+ f.close()
+ self.assertEqual(len(orig), len(copy))
+ self.assertEqual(orig, copy)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qrunnable_test.py b/sources/pyside6/tests/QtCore/qrunnable_test.py
new file mode 100644
index 000000000..d52f50ce1
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qrunnable_test.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QRunnable'''
+
+import os
+import sys
+import unittest
+from io import StringIO
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QRunnable, QThreadPool, QThread, qDebug
+from helper.usesqapplication import UsesQApplication
+test_result = ""
+
+
+def check_test():
+ global test_result
+ test_result = "test works"
+
+
+class QRunnableTest(UsesQApplication):
+ def testCreateWithAutoDelete(self):
+ global test_result
+ test_result = "" # reset
+ runnable = QRunnable.create(check_test)
+ runnable.run()
+ self.assertEqual(test_result, "test works")
+
+ def testwithQThreadPool(self):
+ global test_result
+ test_result = "" # reset
+ runnable = QRunnable.create(check_test)
+ tp = QThreadPool.globalInstance()
+ tp.start(runnable)
+ self.assertTrue(tp.waitForDone())
+ self.assertEqual(test_result, "test works")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qsettings_test.ini b/sources/pyside6/tests/QtCore/qsettings_test.ini
new file mode 100644
index 000000000..f54ae0029
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsettings_test.ini
@@ -0,0 +1,4 @@
+[General]
+var1=a, b, c
+var2=a
+
diff --git a/sources/pyside6/tests/QtCore/qsettings_test.py b/sources/pyside6/tests/QtCore/qsettings_test.py
new file mode 100644
index 000000000..64ceffd70
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsettings_test.py
@@ -0,0 +1,130 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QDate'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDir, QSettings, QTemporaryDir, QByteArray
+
+
+class TestQSettings(unittest.TestCase):
+ def testConversions(self):
+ file = Path(__file__).resolve().parent / 'qsettings_test.ini'
+ self.assertTrue(file.is_file())
+ file_path = QDir.fromNativeSeparators(os.fspath(file))
+ settings = QSettings(file_path, QSettings.IniFormat)
+
+ r = settings.value('var1')
+ self.assertEqual(type(r), list)
+
+ r = settings.value('var2')
+ self.assertEqual(type(r), str)
+
+ r = settings.value('var2', type=list)
+ self.assertEqual(type(r), list)
+
+ # Test mixed conversions
+ ba = QByteArray("hello".encode("utf-8"))
+
+ r = settings.value("test", ba, type=QByteArray)
+ self.assertEqual(type(r), QByteArray)
+
+ r = settings.value("test", ba, type=str)
+ self.assertEqual(type(r), str)
+
+ # Test invalid conversions
+ with self.assertRaises(TypeError):
+ r = settings.value("test", ba, type=dict)
+
+ def testDefaultValueConversion(self):
+ temp_dir = QDir.tempPath()
+ dir = QTemporaryDir(f'{temp_dir}/qsettings_XXXXXX')
+ self.assertTrue(dir.isValid())
+ file_name = dir.filePath('foo.ini')
+ settings = QSettings(file_name, QSettings.IniFormat)
+ sample_list = ["a", "b"]
+ string_list_of_empty = [""]
+ settings.setValue('zero_value', 0)
+ settings.setValue('empty_list', [])
+ settings.setValue('some_strings', sample_list)
+ settings.setValue('string_list_of_empty', string_list_of_empty)
+ settings.setValue('bool1', False)
+ settings.setValue('bool2', True)
+ del settings
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ # Loading values already set
+ settings = QSettings(file_name, QSettings.IniFormat)
+
+ # Getting value that doesn't exist
+ r = settings.value("variable")
+ self.assertEqual(type(r), type(None))
+
+ r = settings.value("variable", type=list)
+ self.assertEqual(type(r), list)
+ self.assertEqual(len(r), 0)
+
+ # Handling zero value
+ r = settings.value('zero_value')
+ self.assertEqual(type(r), int)
+
+ r = settings.value('zero_value', type=int)
+ self.assertEqual(type(r), int)
+
+ # Empty list
+ r = settings.value('empty_list')
+ self.assertTrue(len(r) == 0)
+ self.assertEqual(type(r), list)
+
+ r = settings.value('empty_list', type=list)
+ self.assertTrue(len(r) == 0)
+ self.assertEqual(type(r), list)
+
+ r = settings.value('some_strings')
+ self.assertEqual(r, sample_list)
+
+ r = settings.value('some_strings', type=list)
+ self.assertEqual(r, sample_list)
+
+ r = settings.value('string_list_of_empty', type=list)
+ self.assertEqual(r, string_list_of_empty)
+
+ # Booleans
+ r = settings.value('bool1')
+ self.assertEqual(type(r), bool)
+
+ r = settings.value('bool2')
+ self.assertEqual(type(r), bool)
+
+ r = settings.value('bool1', type=bool)
+ self.assertEqual(type(r), bool)
+
+ r = settings.value('bool2', type=int)
+ self.assertEqual(type(r), int)
+
+ r = settings.value('bool2', type=bool)
+ self.assertEqual(type(r), bool)
+
+ # Not set variable, but with default value
+ r = settings.value('lala', 22, type=bytes)
+ self.assertEqual(type(r), bytes)
+
+ r = settings.value('lala', 22, type=int)
+ self.assertEqual(type(r), int)
+
+ r = settings.value('lala', 22, type=float)
+ self.assertEqual(type(r), float)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qsharedmemory_client.py b/sources/pyside6/tests/QtCore/qsharedmemory_client.py
new file mode 100644
index 000000000..d16c36da9
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsharedmemory_client.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Client for the unit test of QSharedMemory'''
+
+import sys
+
+from PySide6.QtCore import QSharedMemory
+
+
+def read_string(shared_memory):
+ """Read out a null-terminated string from the QSharedMemory"""
+ mv = memoryview(shared_memory.constData())
+ result = ''
+ for i in range(shared_memory.size()):
+ char = mv[i]
+ if not char:
+ break
+ result += chr(char)
+ return result
+
+
+if __name__ == '__main__':
+ if len(sys.argv) != 2:
+ print('Pass segment name', file=sys.stderr)
+ sys.exit(-1)
+ shared_memory = QSharedMemory(sys.argv[1])
+ if not shared_memory.attach(QSharedMemory.ReadOnly):
+ raise SystemError(f'attach to "{name}" failed')
+ if not shared_memory.lock():
+ raise SystemError(f'lock of "{name}" failed')
+ data = read_string(shared_memory)
+ shared_memory.unlock()
+ shared_memory.detach()
+ sys.stdout.write(data)
+ sys.exit(0)
diff --git a/sources/pyside6/tests/QtCore/qsharedmemory_test.py b/sources/pyside6/tests/QtCore/qsharedmemory_test.py
new file mode 100644
index 000000000..ed8a47939
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsharedmemory_test.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QSharedMemory'''
+
+import ctypes
+import os
+import subprocess
+import sys
+import unittest
+
+from pathlib import Path
+FILE = Path(__file__).resolve()
+sys.path.append(os.fspath(FILE.parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QSharedMemory, QRandomGenerator, qVersion
+from qsharedmemory_client import read_string
+
+
+TEST_STRING = 'ABCD'
+
+
+def run(cmd):
+ # FIXME Python 3.7: Use subprocess.run()
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False,
+ universal_newlines=True)
+ output, error = proc.communicate()
+ proc.wait()
+ return_code = proc.returncode
+ return (return_code, output, error)
+
+
+class QSharedMemoryTest(unittest.TestCase):
+
+ def setUp(self):
+ r = QRandomGenerator.global_().bounded(1000)
+ v = qVersion()
+ self._name = f"pyside{v}_test_{r}"
+ print(self._name)
+ self._shared_memory = QSharedMemory(self._name)
+
+ def tearDown(self):
+ if self._shared_memory.isAttached():
+ self._shared_memory.detach()
+
+ def test(self):
+ # Create and write
+ self.assertTrue(self._shared_memory.create(1024, QSharedMemory.ReadWrite))
+ self.assertTrue(self._shared_memory.lock())
+ mv = memoryview(self._shared_memory.data())
+ for idx, c in enumerate(TEST_STRING + chr(0)):
+ mv[idx] = ord(c)
+ mv = None
+ self.assertTrue(self._shared_memory.unlock())
+
+ # Read
+ self.assertTrue(self._shared_memory.lock())
+ self.assertEqual(read_string(self._shared_memory), TEST_STRING)
+ self.assertTrue(self._shared_memory.unlock())
+
+ # Run a subprocess and let it read
+ client = FILE.parent / 'qsharedmemory_client.py'
+ returncode, output, error = run([sys.executable, client, self._name])
+ if error:
+ print(error, file=sys.stderr)
+ self.assertEqual(returncode, 0)
+ self.assertEqual(output, TEST_STRING)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qsize_test.py b/sources/pyside6/tests/QtCore/qsize_test.py
new file mode 100644
index 000000000..bc324ba73
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsize_test.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QSize'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QSize
+
+
+class QSizeOperator(unittest.TestCase):
+ def testOperatorMultiply(self):
+ # QSize operator * float
+ # bug 131
+ a = QSize(1, 1)
+ x = a * 3.4
+ self.assertEqual(QSize(3, 3), x)
+
+ def testOperatorRevertedMultiply(self):
+ # QSize operator * float, reverted
+ # bug 132
+ a = QSize(1, 1)
+ x = 3.4 * a
+ self.assertEqual(QSize(3, 3), x)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qslot_object_test.py b/sources/pyside6/tests/QtCore/qslot_object_test.py
new file mode 100644
index 000000000..a95afb090
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qslot_object_test.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QObject, QTimer
+
+"""
+This is a simple slot test that was updated to use the qApp "macro".
+It is implicitly in builtins and does not need an import.
+"""
+
+
+class objTest(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self.ok = False
+
+ def slot(self):
+ self.ok = True
+ qApp.quit() # noqa: F821
+
+
+class slotTest(unittest.TestCase):
+ def quit_app(self):
+ qApp.quit() # noqa: F821
+
+ def testBasic(self):
+ timer = QTimer()
+ timer.setInterval(100)
+
+ my_obj = objTest()
+ timer.timeout.connect(my_obj.slot)
+ timer.start(100)
+
+ QTimer.singleShot(1000, self.quit_app)
+ qApp.exec() # noqa: F821
+
+ self.assertTrue(my_obj.ok)
+
+
+if __name__ == '__main__':
+ QCoreApplication()
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qsocketnotifier_test.py b/sources/pyside6/tests/QtCore/qsocketnotifier_test.py
new file mode 100644
index 000000000..2e812947c
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsocketnotifier_test.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QUuid'''
+
+import os
+import socket
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QSocketNotifier
+
+
+class QSocketNotifierTest(unittest.TestCase):
+ def testClass(self):
+ app = QCoreApplication([])
+ # socketpair is not available on Windows
+ if os.name != "nt":
+ w_sock, r_sock = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
+
+ self.assertIsInstance(r_sock.fileno(), int)
+
+ notifier = QSocketNotifier(r_sock.fileno(), QSocketNotifier.Read)
+
+ self.assertIsNotNone(notifier)
+
+ w_sock.close()
+ r_sock.close()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qsrand_test.py b/sources/pyside6/tests/QtCore/qsrand_test.py
new file mode 100644
index 000000000..fef44261b
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsrand_test.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QRandomGenerator
+
+
+class OverflowExceptionCollect(unittest.TestCase):
+ '''Test case for OverflowError exception during garbage collection. See bug #147'''
+
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
+ def testOverflow(self):
+ # NOTE: PyQt4 raises TypeError, but boost.python raises OverflowError
+ self.assertRaises(OverflowError, QRandomGenerator, 42415335332353253)
+ # should not abort if bug #147 is fixed
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qstandardpaths_test.py b/sources/pyside6/tests/QtCore/qstandardpaths_test.py
new file mode 100644
index 000000000..b8274769b
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qstandardpaths_test.py
@@ -0,0 +1,32 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QStandardPaths'''
+
+import ctypes
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QStandardPaths
+
+
+class QStandardPathsTest(unittest.TestCase):
+ def testTestModeEnabled(self):
+ print("QStandardPaths.isTestModeEnabled:", QStandardPaths.isTestModeEnabled())
+ sp = True
+ QStandardPaths.setTestModeEnabled(sp)
+ self.assertEqual(QStandardPaths.isTestModeEnabled(), sp)
+ sp = False
+ QStandardPaths.setTestModeEnabled(sp)
+ self.assertEqual(QStandardPaths.isTestModeEnabled(), sp)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qstorageinfo_test.py b/sources/pyside6/tests/QtCore/qstorageinfo_test.py
new file mode 100644
index 000000000..5869d9f00
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qstorageinfo_test.py
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QStorageInfo'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QStorageInfo
+
+
+class QandardPathsTest(unittest.TestCase):
+ def testQStorageInfo(self):
+ for v in QStorageInfo.mountedVolumes():
+ print(v.name(), v.rootPath(), v.device())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qstring_test.py b/sources/pyside6/tests/QtCore/qstring_test.py
new file mode 100644
index 000000000..d740eeeef
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qstring_test.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QString'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class QStringConstructor(unittest.TestCase):
+ '''Test case for QString constructors'''
+
+ def testQStringDefault(self):
+ obj = QObject()
+ obj.setObjectName('foo')
+ self.assertEqual(obj.objectName(), 'foo')
+ obj.setObjectName('áâãà')
+ self.assertEqual(obj.objectName(), 'áâãà')
+ obj.setObjectName('A\x00B')
+ self.assertEqual(obj.objectName(), 'A\x00B')
+ obj.setObjectName('ä\x00B')
+ self.assertEqual(obj.objectName(), 'ä\x00B')
+ obj.setObjectName(None)
+ self.assertEqual(obj.objectName(), '')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qsysinfo_test.py b/sources/pyside6/tests/QtCore/qsysinfo_test.py
new file mode 100644
index 000000000..602852fab
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qsysinfo_test.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QSysInfo
+
+
+class TestQSysInfo(unittest.TestCase):
+
+ def testEnumEndian(self):
+ self.assertEqual(QSysInfo.BigEndian.value, 0)
+ self.assertEqual(QSysInfo.LittleEndian.value, 1)
+ self.assertTrue(QSysInfo.ByteOrder.value > -1)
+
+ def testEnumSizes(self):
+ self.assertTrue(QSysInfo.WordSize.value > 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qtextstream_test.py b/sources/pyside6/tests/QtCore/qtextstream_test.py
new file mode 100644
index 000000000..d4ed94e14
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qtextstream_test.py
@@ -0,0 +1,92 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QTextStream'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray, QTextStream, QIODevice, QFile
+
+
+class QTextStreamShiftTest(unittest.TestCase):
+
+ def setUp(self):
+ self.ba = QByteArray()
+ self.read = QTextStream(self.ba, QIODevice.ReadOnly)
+ self.write = QTextStream(self.ba, QIODevice.WriteOnly)
+
+ def testNumber(self):
+ '''QTextStream << number'''
+
+ self.write << '4'
+ self.write.flush()
+ res = self.read.readLine()
+ self.assertTrue(isinstance(res, str))
+ self.assertEqual(res, '4')
+
+
+class QTextStreamGetSet(unittest.TestCase):
+
+ def setUp(self):
+ self.obj = QTextStream()
+
+ def testDevice(self):
+ '''QTextStream get/set Device'''
+ device = QFile()
+ self.obj.setDevice(device)
+ self.assertEqual(device, self.obj.device())
+ self.obj.setDevice(None)
+ self.assertEqual(None, self.obj.device())
+
+
+class QTextStreamInitialization(unittest.TestCase):
+
+ def testConstruction(self):
+ '''QTextStream construction'''
+ obj = QTextStream()
+
+ self.assertEqual(obj.device(), None)
+ self.assertEqual(obj.string(), None)
+
+ self.assertTrue(obj.atEnd())
+ self.assertEqual(obj.readAll(), '')
+
+
+class QTextStreamReadLinesFromDevice(unittest.TestCase):
+
+ def _check_data(self, data_set):
+
+ for data, lines in data_set:
+ stream = QTextStream(data)
+
+ res = []
+ while not stream.atEnd():
+ res.append(stream.readLine())
+
+ self.assertEqual(res, lines)
+
+ def testLatin1(self):
+ '''QTextStream readLine for simple Latin1 strings'''
+
+ data = []
+
+ data.append((QByteArray(), []))
+ data.append((QByteArray(bytes('\n', "UTF-8")), ['']))
+ data.append((QByteArray(bytes('\r\n', "UTF-8")), ['']))
+ data.append((QByteArray(bytes('ole', "UTF-8")), ['ole']))
+ data.append((QByteArray(bytes('ole\n', "UTF-8")), ['ole']))
+ data.append((QByteArray(bytes('ole\r\n', "UTF-8")), ['ole']))
+ data.append((QByteArray(bytes('ole\r\ndole\r\ndoffen', "UTF-8")), ['ole', 'dole', 'doffen']))
+
+ self._check_data(data)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qthread_prod_cons_test.py b/sources/pyside6/tests/QtCore/qthread_prod_cons_test.py
new file mode 100644
index 000000000..a179c936f
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qthread_prod_cons_test.py
@@ -0,0 +1,116 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Producer-Consumer test/example with QThread'''
+
+import gc
+import logging
+import os
+from random import random
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+logging.basicConfig(level=logging.WARNING)
+
+from PySide6.QtCore import QThread, QCoreApplication, QObject, SIGNAL
+
+
+class Bucket(QObject):
+ '''Dummy class to hold the produced values'''
+ def __init__(self, max_size=10, *args):
+ # Constructor which receives the max number of produced items
+ super().__init__(*args)
+ self.data = []
+ self.max_size = 10
+
+ def pop(self):
+ # Retrieves an item
+ return self.data.pop(0)
+
+ def push(self, data):
+ # Pushes an item
+ self.data.append(data)
+
+
+class Producer(QThread):
+ '''Producer thread'''
+
+ def __init__(self, bucket, *args):
+ # Constructor. Receives the bucket
+ super().__init__(*args)
+ self.runs = 0
+ self.bucket = bucket
+ self.production_list = []
+
+ def run(self):
+ # Produces at most bucket.max_size items
+ while self.runs < self.bucket.max_size:
+ value = int(random() * 10) % 10
+ self.bucket.push(value)
+ self.production_list.append(value)
+ logging.debug(f'PRODUCER - pushed {value}')
+ self.runs += 1
+ self.msleep(5)
+
+
+class Consumer(QThread):
+ '''Consumer thread'''
+ def __init__(self, bucket, *args):
+ # Constructor. Receives the bucket
+ super().__init__(*args)
+ self.runs = 0
+ self.bucket = bucket
+ self.consumption_list = []
+
+ def run(self):
+ # Consumes at most bucket.max_size items
+ while self.runs < self.bucket.max_size:
+ try:
+ value = self.bucket.pop()
+ self.consumption_list.append(value)
+ logging.debug(f'CONSUMER - got {value}')
+ self.runs += 1
+ except IndexError:
+ logging.debug('CONSUMER - empty bucket')
+ self.msleep(5)
+
+
+class ProducerConsumer(unittest.TestCase):
+ '''Basic test case for producer-consumer QThread'''
+
+ def setUp(self):
+ # Create fixtures
+ self.app = QCoreApplication([])
+
+ def tearDown(self):
+ # Destroy fixtures
+ del self.app
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testProdCon(self):
+ # QThread producer-consumer example
+ bucket = Bucket()
+ prod = Producer(bucket)
+ cons = Consumer(bucket)
+
+ cons.finished.connect(QCoreApplication.quit)
+ prod.start()
+ cons.start()
+
+ self.app.exec()
+
+ self.assertTrue(prod.wait(1000))
+ self.assertTrue(cons.wait(1000))
+
+ self.assertEqual(prod.production_list, cons.consumption_list)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qthread_signal_test.py b/sources/pyside6/tests/QtCore/qthread_signal_test.py
new file mode 100644
index 000000000..4e312dcc8
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qthread_signal_test.py
@@ -0,0 +1,71 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for connecting signals between threads'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QThread, QTimer, QObject, Signal, Slot, QCoreApplication
+
+
+class Source(QObject):
+ source = Signal()
+
+ def __init__(self, *args):
+ super().__init__(*args)
+
+ @Slot()
+ def emit_sig(self):
+ self.source.emit()
+
+
+class Target(QObject):
+ def __init__(self, *args):
+ super().__init__(*args)
+ self.called = False
+
+ @Slot()
+ def myslot(self):
+ self.called = True
+
+
+class ThreadJustConnects(QThread):
+ def __init__(self, source, *args):
+ super().__init__(*args)
+ self.source = source
+ self.target = Target()
+
+ def run(self):
+ self.source.source.connect(self.target.myslot)
+ self.source.source.connect(self.quit)
+ self.exec()
+
+
+class BasicConnection(unittest.TestCase):
+
+ def testEmitOutsideThread(self):
+ global thread_run
+
+ app = QCoreApplication([])
+ source = Source()
+ thread = ThreadJustConnects(source)
+
+ thread.finished.connect(QCoreApplication.quit)
+ thread.start()
+
+ QTimer.singleShot(50, source.emit_sig)
+ app.exec()
+ thread.wait()
+
+ self.assertTrue(thread.target.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qthread_test.py b/sources/pyside6/tests/QtCore/qthread_test.py
new file mode 100644
index 000000000..4d26e0597
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qthread_test.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QThread'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QThread, QCoreApplication, QObject, QTimer, Slot
+from PySide6.QtCore import QEventLoop
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Dummy(QThread):
+ '''Dummy thread'''
+ def __init__(self, *args):
+ super().__init__(*args)
+ self.called = False
+
+ def run(self):
+ # Start-quit sequence
+ self.qobj = QObject()
+ self.called = True
+
+
+class QThreadSimpleCase(UsesQApplication):
+
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self._started_called = False
+ self._finished_called = False
+ self.called = False
+
+ def testThread(self):
+ # Basic QThread test
+ obj = Dummy()
+ obj.start()
+ self.assertTrue(obj.wait(100))
+
+ self.assertTrue(obj.called)
+
+ @Slot()
+ def abort_application(self):
+ if self._thread.isRunning():
+ print("Warning: terminating thread", file=sys.stderr)
+ self._thread.terminate()
+ self.app.quit()
+
+ @Slot()
+ def finished(self):
+ self._finished_called = True
+
+ @Slot()
+ def started(self):
+ self._started_called = True
+
+ def testSignals(self):
+ # QThread.finished() (signal)
+ self._thread = Dummy()
+ self._thread.started.connect(self.started)
+ self._thread.finished.connect(self.finished)
+ self._thread.finished.connect(self.app.quit)
+
+ QTimer.singleShot(50, self._thread.start)
+ QTimer.singleShot(1000, self.abort_application)
+
+ self.app.exec()
+ if self._thread.isRunning():
+ self._thread.wait(100)
+
+ self.assertTrue(self._started_called)
+ self.assertTrue(self._finished_called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qtimer_singleshot_test.py b/sources/pyside6/tests/QtCore/qtimer_singleshot_test.py
new file mode 100644
index 000000000..2ccaa300e
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qtimer_singleshot_test.py
@@ -0,0 +1,195 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QTimer.singleShot'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QThread, QTimer, Signal, Slot, SLOT
+from helper.usesqapplication import UsesQApplication
+
+
+class WatchDog(QObject):
+ '''Exits the QCoreApplication main loop after sometime.'''
+
+ def __init__(self, watched):
+ super().__init__()
+ self.times_called = 0
+ self.watched = watched
+
+ def timerEvent(self, evt):
+ self.times_called += 1
+ if self.times_called == 20:
+ self.watched.exit_app_cb()
+
+
+class ThreadForContext(QThread):
+ def __init__(self):
+ super().__init__()
+ self.called = False
+ self.qthread = None
+ self.context = QObject()
+
+ def run(self):
+ self.called = True
+ self.qthread = QThread.currentThread()
+ self.exec()
+
+
+class TestSingleShot(UsesQApplication):
+ '''Test case for QTimer.singleShot'''
+
+ def setUp(self):
+ # Acquire resources
+ UsesQApplication.setUp(self)
+ self.watchdog = WatchDog(self)
+ self.called = False
+ self.qthread = None
+
+ def tearDown(self):
+ # Release resources
+ del self.watchdog
+ del self.called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ def callback(self):
+ self.called = True
+ self.qthread = QThread.currentThread()
+ self.qthread.exit()
+ self.app.quit()
+
+ def testSingleShot(self):
+ QTimer.singleShot(100, self.callback)
+ self.app.exec()
+ self.assertTrue(self.called)
+
+ def testSingleShotZero(self):
+ QTimer.singleShot(0, self.callback)
+ self.app.exec()
+ self.assertTrue(self.called)
+
+ def testSingleShotWithContext(self):
+ thread = ThreadForContext()
+ thread.start()
+ thread.context.moveToThread(thread)
+ QTimer.singleShot(100, thread.context, self.callback)
+ self.app.exec()
+ thread.wait()
+ self.assertTrue(self.called)
+ self.assertTrue(thread.called)
+ self.assertEqual(self.qthread, thread.qthread)
+
+ def testSingleShotWithContextZero(self):
+ thread = ThreadForContext()
+ thread.start()
+ thread.context.moveToThread(thread)
+ QTimer.singleShot(0, thread.context, self.callback)
+ self.app.exec()
+ thread.wait()
+ self.assertTrue(self.called)
+ self.assertTrue(thread.called)
+ self.assertEqual(self.qthread, thread.qthread)
+
+
+class TestSingleShotCallableObject(UsesQApplication):
+ '''Test case for QTimer.singleShot with callable inside an object'''
+
+ def setUp(self):
+ # Acquire resources
+ UsesQApplication.setUp(self)
+ self.watchdog = WatchDog(self)
+
+ def tearDown(self):
+ # Release resources
+ del self.watchdog
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ class CallbackObject(QObject):
+ def __init__(self, app) -> None:
+ super().__init__()
+ self.app = app
+
+ @Slot()
+ def func(self):
+ self.called = True
+ self.app.quit()
+
+ def testSingleShotWithObjectAndMember(self):
+ callback = self.CallbackObject(self.app)
+ QTimer.singleShot(100, callback, SLOT("func()"))
+ self.app.exec()
+ self.assertTrue(callback.called)
+
+ def testSingleShotWithObjectAndMemberZero(self):
+ callback = self.CallbackObject(self.app)
+ QTimer.singleShot(0, callback, SLOT("func()"))
+ self.app.exec()
+ self.assertTrue(callback.called)
+
+ def testSingleShotWithCallableInObject(self):
+ callback = self.CallbackObject(self.app)
+ QTimer.singleShot(100, callback.func)
+ self.app.exec()
+ self.assertTrue(callback.called)
+
+ def testSingleShotWithCallableInObjectZero(self):
+ callback = self.CallbackObject(self.app)
+ QTimer.singleShot(0, callback.func)
+ self.app.exec()
+ self.assertTrue(callback.called)
+
+
+class SigEmitter(QObject):
+
+ sig1 = Signal()
+
+
+class TestSingleShotSignal(UsesQApplication):
+ '''Test case for QTimer.singleShot connecting to signals'''
+
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self.watchdog = WatchDog(self)
+ self.called = False
+
+ def tearDown(self):
+ del self.watchdog
+ del self.called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ def callback(self):
+ self.called = True
+ self.app.quit()
+
+ def testSingleShotSignal(self):
+ emitter = SigEmitter()
+ emitter.sig1.connect(self.callback)
+ QTimer.singleShot(100, emitter.sig1)
+ self.app.exec()
+ self.assertTrue(self.called)
+
+ def testSingleShotSignalZero(self):
+ emitter = SigEmitter()
+ emitter.sig1.connect(self.callback)
+ QTimer.singleShot(0, emitter.sig1)
+ self.app.exec()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qtimer_timeout_test.py b/sources/pyside6/tests/QtCore/qtimer_timeout_test.py
new file mode 100644
index 000000000..70f151989
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qtimer_timeout_test.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for timeout() signals from QTimer object.'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimer, SIGNAL
+from helper.usesqapplication import UsesQApplication
+
+
+class WatchDog(QObject):
+ '''Exits the QCoreApplication main loop after sometime.'''
+
+ def __init__(self, watched):
+ super().__init__()
+ self.times_called = 0
+ self.watched = watched
+
+ def timerEvent(self, evt):
+ self.times_called += 1
+ if self.times_called == 20:
+ self.watched.exit_app_cb()
+
+
+class TestTimeoutSignal(UsesQApplication):
+ '''Test case to check if the signals are really being caught'''
+
+ def setUp(self):
+ # Acquire resources
+ super().setUp()
+ self.watchdog = WatchDog(self)
+ self.timer = QTimer()
+ self.called = False
+
+ def tearDown(self):
+ # Release resources
+ del self.watchdog
+ del self.timer
+ del self.called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super().tearDown()
+
+ def callback(self, *args):
+ # Default callback
+ self.called = True
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testTimeoutSignal(self):
+ # Test the QTimer timeout() signal
+ refCount = sys.getrefcount(self.timer)
+ self.timer.timeout.connect(self.callback)
+ self.timer.start(4)
+ self.watchdog.startTimer(10)
+
+ self.app.exec()
+
+ self.assertTrue(self.called)
+ self.assertEqual(sys.getrefcount(self.timer), refCount)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/qtimezone_test.py b/sources/pyside6/tests/QtCore/qtimezone_test.py
new file mode 100644
index 000000000..ad953f1cc
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qtimezone_test.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimeZone
+
+
+class TestQTimeZone (unittest.TestCase):
+ def testTimeZone(self):
+ id = bytes('Europe/Berlin', "UTF-8")
+ timeZone = QTimeZone(id)
+ self.assertTrue(timeZone.isValid())
+ self.assertEqual(timeZone.id(), id)
+ name = timeZone.displayName(QTimeZone.GenericTime, QTimeZone.DefaultName)
+ self.assertTrue(name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qtnamespace_test.py b/sources/pyside6/tests/QtCore/qtnamespace_test.py
new file mode 100644
index 000000000..c08c727ec
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qtnamespace_test.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test suite for QtCore.Qt namespace'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt
+
+
+class QtNamespace(unittest.TestCase):
+ '''Test case for accessing attributes from Qt namespace'''
+
+ def testBasic(self):
+ # Access to Qt namespace
+ getattr(Qt, 'Horizontal')
+ getattr(Qt, 'WindowMaximizeButtonHint')
+ self.assertTrue(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/quoteEnUS.txt b/sources/pyside6/tests/QtCore/quoteEnUS.txt
new file mode 100644
index 000000000..909b4fa17
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/quoteEnUS.txt
@@ -0,0 +1 @@
+Fine! Dishonor! Dishonor on you, dishonor on ya cow!
diff --git a/sources/pyside6/tests/QtCore/qurl_test.py b/sources/pyside6/tests/QtCore/qurl_test.py
new file mode 100644
index 000000000..df16c74e0
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qurl_test.py
@@ -0,0 +1,149 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test suite for QtCore.QUrl'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUrl
+from PySide6.QtCore import QUrlQuery
+
+
+class QUrlBasicConstructor(unittest.TestCase):
+ '''Tests the basic constructors'''
+
+ def testBasic(self):
+ # Default constructor for QUrl
+ url = QUrl()
+ self.assertEqual(url.toString(), "")
+
+ def testSetAttributes(self):
+ # Construct QUrl by set* methods
+ url = QUrl()
+
+ url.setScheme('ftp')
+ self.assertEqual(url.toString(), 'ftp:')
+
+ url.setHost('www.google.com')
+ self.assertEqual(url.toString(), 'ftp://www.google.com')
+
+ url.setPort(8080)
+ self.assertEqual(url.toString(), 'ftp://www.google.com:8080')
+
+ url.setPath('/mail/view')
+ self.assertEqual(url.toString(),
+ 'ftp://www.google.com:8080/mail/view')
+
+ url.setUserName('john')
+ self.assertEqual(url.toString(),
+ 'ftp://john@www.google.com:8080/mail/view')
+
+ url.setPassword('abc123')
+ self.assertEqual(url.toString(),
+ 'ftp://john:abc123@www.google.com:8080/mail/view')
+
+
+class QueryItemsTest(unittest.TestCase):
+ '''Test query item management'''
+
+ def testQueryItems(self):
+ url = QUrl('http://www.google.com/search?q=python&hl=en')
+ valid_data = [(('q'), ('python')), (('hl'), ('en'))]
+
+ self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data))
+
+ def testEncodedQueryItems(self):
+ url = QUrl('http://www.google.com/search?q=python&hl=en')
+ valid_data = [(('q'), ('python')), (('hl'), ('en'))]
+
+ self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data))
+
+ def testSetQueryItems(self):
+ urla = QUrl('http://www.google.com/search?q=python&hl=en')
+ urlb = QUrl('http://www.google.com/search')
+
+ urlb.setQuery(urla.query())
+
+ self.assertEqual(urla, urlb)
+
+ def testAddQueryItem(self):
+ url = QUrlQuery()
+ valid_data = [('hl', 'en'), ('user', 'konqui')]
+
+ url.addQueryItem(*valid_data[0])
+ self.assertEqual(url.queryItems()[0], valid_data[0])
+
+ url.addQueryItem(*valid_data[1])
+ self.assertEqual(sorted(url.queryItems()), sorted(valid_data))
+
+ def testAllQueryItemsValues(self):
+ url = QUrlQuery()
+ key = 'key'
+ valid_data = ['data', 'valid', 'test']
+
+ for i, data in enumerate(valid_data):
+ url.addQueryItem(key, data)
+ self.assertEqual(url.allQueryItemValues(key),
+ list(valid_data[:i + 1]))
+
+ def testPath(self):
+ url = QUrl("http://qt-project.org/images/ban/pgs_front.jpg")
+ self.assertEqual(url.path(), "/images/ban/pgs_front.jpg")
+
+# PYSIDE-345: No bindings for QUrlQuery
+
+
+class QueryItemsTest(unittest.TestCase):
+ '''Test query item management'''
+
+ def testQueryItems(self):
+ url = QUrl('http://www.google.com/search?q=python&hl=en')
+ valid_data = [(('q'), ('python')), (('hl'), ('en'))]
+
+ self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data))
+
+ def testEncodedQueryItems(self):
+ url = QUrl('http://www.google.com/search?q=python&hl=en')
+ valid_data = [(('q'), ('python')), (('hl'), ('en'))]
+
+ self.assertEqual(sorted(QUrlQuery(url.query()).queryItems()), sorted(valid_data))
+
+ def testSetQueryItems(self):
+ urla = QUrl('http://www.google.com/search?q=python&hl=en')
+ urlb = QUrl('http://www.google.com/search')
+
+ urlb.setQuery(urla.query())
+
+ self.assertEqual(urla, urlb)
+
+ def testAddQueryItem(self):
+ url = QUrlQuery()
+ valid_data = [('hl', 'en'), ('user', 'konqui')]
+
+ url.addQueryItem(*valid_data[0])
+ self.assertEqual(url.queryItems()[0], valid_data[0])
+
+ url.addQueryItem(*valid_data[1])
+ self.assertEqual(sorted(url.queryItems()), sorted(valid_data))
+
+ def testAllQueryItemsValues(self):
+ url = QUrlQuery()
+ key = 'key'
+ valid_data = ['data', 'valid', 'test']
+
+ for i, data in enumerate(valid_data):
+ url.addQueryItem(key, data)
+ self.assertEqual(url.allQueryItemValues(key),
+ list(valid_data[:i + 1]))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qurlquery_test.py b/sources/pyside6/tests/QtCore/qurlquery_test.py
new file mode 100644
index 000000000..36eb29475
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qurlquery_test.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QUrlQuery'''
+
+import ctypes
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUrlQuery
+
+
+class QUrlQueryTest(unittest.TestCase):
+ def testConstructing(self):
+ empty = QUrlQuery()
+ self.assertTrue(empty.isEmpty())
+
+ empty.clear()
+ self.assertTrue(empty.isEmpty())
+
+ def testAddRemove(self):
+ query = QUrlQuery()
+
+ query.addQueryItem("a", "b")
+ self.assertTrue(not query.isEmpty())
+ self.assertTrue(query.hasQueryItem("a"))
+ self.assertEqual(query.queryItemValue("a"), "b")
+ self.assertEqual(query.allQueryItemValues("a"), ["b"])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/quuid_test.py b/sources/pyside6/tests/QtCore/quuid_test.py
new file mode 100644
index 000000000..45c6fc89d
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/quuid_test.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QUuid'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUuid
+
+
+class QUuidTest(unittest.TestCase):
+ def testFromString(self):
+ uuidString = '{fc69b59e-cc34-4436-a43c-ee95d128b8c5}'
+# testing overload QUUid::fromString(QStringView)
+ uuid = QUuid.fromString(uuidString)
+ self.assertTrue(not uuid.isNull())
+ self.assertEqual(uuid.toString(), uuidString)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/qversionnumber_test.py b/sources/pyside6/tests/QtCore/qversionnumber_test.py
new file mode 100644
index 000000000..23f6ba639
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/qversionnumber_test.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QVersionNumber'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QVersionNumber
+
+
+class QVersionNumberTest(unittest.TestCase):
+ def testFromString(self):
+ versionString = '5.9.2'
+ version = QVersionNumber.fromString(versionString)
+ self.assertTrue(not version.isNull())
+ self.assertEqual(version.majorVersion(), 5)
+ self.assertEqual(version.minorVersion(), 9)
+ self.assertEqual(version.microVersion(), 2)
+ self.assertEqual(version.toString(), versionString)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/repr_test.py b/sources/pyside6/tests/QtCore/repr_test.py
new file mode 100644
index 000000000..87cceaa82
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/repr_test.py
@@ -0,0 +1,97 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+from PySide6.QtCore import QByteArray, QDate, QDateTime, QTime, QLine, QLineF
+from PySide6.QtCore import Qt, QSize, QSizeF, QRect, QRectF, QPoint, QPointF
+try:
+ from PySide6.QtCore import QUuid
+ HAVE_Q = True
+except ImportError:
+ HAVE_Q = False
+
+
+class ReprCopyHelper:
+ def testCopy(self):
+ copy = eval(self.original.__repr__())
+ self.assertTrue(copy is not self.original)
+ self.assertEqual(copy, self.original)
+
+
+class QByteArrayReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QByteArray(bytes('the quick brown fox jumps over the lazy dog', "UTF-8"))
+
+
+class QDateReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QDate(2010, 11, 22)
+
+
+class QTimeReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QTime(11, 37, 55, 692)
+
+
+class QDateTimeReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QDateTime(2010, 5, 18, 10, 24, 45, 223, Qt.LocalTime)
+
+
+class QSizeReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QSize(42, 190)
+
+
+class QSizeFReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QSizeF(42.7, 190.2)
+
+
+class QRectReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QRect(100, 200, 300, 400)
+
+
+class QRectFReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QRectF(100.33, 200.254, 300.321, 400.123)
+
+
+class QLineReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QLine(1, 2, 3, 4)
+
+
+class QLineFReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QLineF(1.1, 2.2, 3.3, 4.4)
+
+
+class QPointReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QPoint(1, 2)
+
+
+class QPointFReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QPointF(1.1, 2.2)
+
+
+class QUuiCopy(ReprCopyHelper, unittest.TestCase):
+ @unittest.skipUnless(HAVE_Q, "QUuid is currently not supported on this platform.")
+ def setUp(self):
+ self.original = QUuid("67C8770B-44F1-410A-AB9A-F9B5446F13EE")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/resources.qrc b/sources/pyside6/tests/QtCore/resources.qrc
new file mode 100644
index 000000000..0a0b03d40
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/resources.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="quote.txt">quoteEnUS.txt</file>
+ <file alias="sample.png">sample.png</file>
+ </qresource>
+</RCC>
+
diff --git a/sources/pyside6/tests/QtCore/resources_mc.py b/sources/pyside6/tests/QtCore/resources_mc.py
new file mode 100644
index 000000000..05766a22a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/resources_mc.py
@@ -0,0 +1,3547 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# Resource object code
+#
+# Created: Thu Feb 3 16:09:36 2011
+# by: The Resource Compiler for PySide (Qt v4.6.3)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PySide6 import QtCore
+
+qt_resource_data = b"""\
+\x00\x00\x00\x35\
+\x46\
+\x69\x6e\x65\x21\x20\x44\x69\x73\x68\x6f\x6e\x6f\x72\x21\x20\x44\
+\x69\x73\x68\x6f\x6e\x6f\x72\x20\x6f\x6e\x20\x79\x6f\x75\x2c\x20\
+\x64\x69\x73\x68\x6f\x6e\x6f\x72\x20\x6f\x6e\x20\x79\x61\x20\x63\
+\x6f\x77\x21\x0a\
+\x00\x00\xda\x88\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\xb1\x00\x00\x00\xd2\x08\x06\x00\x00\x00\x05\x49\x21\x31\
+\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
+\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\
+\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\
+\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xda\x03\x0a\
+\x0c\x02\x2e\xb0\x96\x99\x74\x00\x00\x00\x19\x74\x45\x58\x74\x43\
+\x6f\x6d\x6d\x65\x6e\x74\x00\x43\x72\x65\x61\x74\x65\x64\x20\x77\
+\x69\x74\x68\x20\x47\x49\x4d\x50\x57\x81\x0e\x17\x00\x00\x20\x00\
+\x49\x44\x41\x54\x78\xda\x94\xbd\xd9\xaf\x24\xd9\x7a\xdd\xf7\x8b\
+\x21\x33\x77\x44\xe4\x9c\xa7\xaa\xcf\xa9\xb1\xab\x87\x6b\xf2\x92\
+\xd4\x15\x49\x0b\x84\x64\xd9\x22\x64\x3f\xd8\x30\x0c\xd8\x8f\x34\
+\xfc\x68\x43\x7f\x8b\xfe\x04\x02\x06\xfc\x64\xbf\xd1\x06\x04\x13\
+\x7a\x30\x65\x59\x04\x4d\x03\xa4\x48\xba\x29\xf9\x72\xb8\xdd\x5d\
+\x55\x5d\xc3\x39\x75\xea\x9c\x9c\x23\xf6\xce\xcc\x18\xfc\xb0\x87\
+\x88\xc8\xcc\x6a\xd9\xd9\x68\x44\xce\x79\x2a\x73\xc5\x8a\xb5\xd7\
+\xb7\xbe\x2f\xbc\xdf\xff\x17\xbf\x57\x09\x00\x15\x82\xc8\x29\x89\
+\xb0\x97\x24\xaa\x90\x52\x51\x12\x91\x44\x95\xb9\x37\x42\x56\x1e\
+\x91\x97\x91\x4a\xcf\x3d\x27\x8a\x04\x12\x1a\xaf\xd6\xcf\x45\x54\
+\xa0\x3c\x7e\xfc\x22\xeb\xe7\x9b\xeb\xfa\xbd\xea\xdb\x08\x01\x4a\
+\x01\x11\x42\x54\x28\xe5\xe9\x2d\x20\xc0\xdd\x6e\x5e\xdc\x7d\x4a\
+\x02\x7d\x2a\xd1\x73\x8f\x79\x6a\x07\xa2\xa0\x22\xd6\xd7\x81\x24\
+\xdb\xe3\x8d\x87\xad\xf7\xc8\xe3\x12\x80\x30\xf3\xc9\xe3\x92\x30\
+\xf3\x09\x63\x81\x22\x43\x10\x03\x99\x79\x66\x6c\xfe\xce\x12\x94\
+\x5f\xbf\xc1\xd1\xed\x38\x28\xf4\xfb\x85\x11\x79\x2e\xf1\x37\x7d\
+\xb6\xb1\xe4\x61\x76\xe0\xf6\xe5\x82\xc3\x04\x46\xe3\x01\x00\x7d\
+\x42\xb6\xe4\x4c\xbd\x31\xd5\x70\xc3\xc6\xef\x33\x28\xb7\x78\xeb\
+\x01\xeb\x47\x01\x09\x3d\x52\x76\x24\xe8\x7f\x57\x90\x29\x3a\x71\
+\x0f\x45\xfd\x7d\x77\x85\x60\xaf\xd4\xc9\x37\x2e\x44\x81\x52\x01\
+\x82\x0a\x85\x87\xcc\x04\xdf\x7e\xbc\x67\x1c\x06\xfa\xfb\x99\x54\
+\xcc\x98\x50\x72\x4f\x12\x27\x88\x69\x42\x99\x15\x27\xef\xe3\xc7\
+\x41\xeb\xfe\xbd\x52\xc8\x4c\x00\x50\x72\x8f\xcf\x8c\x49\x2c\x29\
+\x45\x84\x1f\x07\x54\x9d\x11\xde\x61\xa5\x1f\xcf\x0a\x56\x73\xb8\
+\x5b\xbc\xa4\x5a\xae\x4f\xde\xdb\x1b\x0f\x19\x52\xf1\xd9\xe3\x11\
+\x4c\x1f\x52\x75\x46\x27\xcf\x79\xf4\xe8\x6b\x42\xfd\x63\x07\x20\
+\x72\x50\x01\xb0\xa7\x2b\xba\xec\x91\xec\xa5\x06\x88\xaf\x0e\x48\
+\x72\x03\x18\x0d\xea\x14\x8f\x3d\x12\x64\xc4\x1e\x40\xda\xfb\x61\
+\x8f\x44\x00\x25\x5e\x8d\x4f\xc0\x47\x52\x12\x31\x2c\x3d\xd6\x7e\
+\xe5\x6e\x83\x47\x15\x65\x78\xd2\xc3\x8f\xa0\x94\xfa\x47\x90\x91\
+\xa4\xb4\x3b\x8a\x52\x06\xd2\x12\x94\x05\xa9\xbe\x47\x99\x5d\x47\
+\x35\x76\x16\x0b\x68\x0d\xe4\x08\xa5\x4a\x03\x66\xe8\x09\xfd\xfc\
+\xca\x00\xaf\x12\x3d\xfa\xf3\x0d\x69\xdc\xa5\xf2\xf5\xeb\x06\xa5\
+\xc7\xc6\xaf\x18\x64\x3e\x79\x2c\xd0\x1f\x1a\x93\xc7\x10\x02\x82\
+\xb8\x01\xe4\x06\x58\x9b\x00\x06\x8a\x2a\x26\x40\x11\x67\x92\x2c\
+\x8e\xc8\x8a\x80\xa2\x27\x98\x50\xd6\xc0\xce\x24\x19\x53\x1e\xbe\
+\x80\x2d\x39\x7d\x42\xd4\x7c\x05\xd3\x11\x7d\x42\xf6\xd5\x16\x56\
+\x1e\x83\xd1\x96\xd5\x6a\x44\x39\xd8\x32\xe2\x82\x42\x1c\x10\xf8\
+\xa0\x34\x80\x01\x14\x1e\x5d\x21\xda\x80\xa5\xa2\x14\x91\x03\x73\
+\x57\x08\x94\x52\xee\x7e\x94\xe2\x2f\x6e\x7e\xce\x24\xeb\xc3\x64\
+\x48\x31\x9a\x10\x2c\x16\x94\x13\x0d\xc2\xae\xf8\x34\xfd\x34\x01\
+\x5c\x55\x63\xba\x62\x09\x68\x20\xfb\xcc\xea\xbf\xc9\x3e\x7f\x59\
+\x12\x24\xf5\x0e\xc0\xbc\x60\xbb\x08\x48\x3c\x48\xab\x09\x89\xb7\
+\x00\x20\x8d\xbb\x24\xcb\x35\x98\x1d\x1a\xc0\x3b\xac\x5a\x40\xf6\
+\x0e\x2b\x92\x7e\x07\xfd\x8d\x0b\xf3\x87\x88\x02\x44\x41\xa6\xe6\
+\x35\x9b\x01\x4a\xe4\x1a\xe8\xe6\xf6\x1e\xc9\x1e\x49\xd7\x80\xa7\
+\x4b\x64\x71\x85\xdf\x40\xed\xbe\x71\xbd\x06\x2c\x6c\xfd\xcc\xec\
+\xa9\x91\x7b\xcc\x93\xb1\x7e\x8e\xf4\xf0\x0d\xeb\x5b\x30\xa7\xd2\
+\x03\xa9\xdc\xbb\xc9\x06\x5f\xcb\x16\x9b\xd7\xcf\x50\xca\xd3\x47\
+\x81\x06\xb8\x85\xa8\xe8\x89\x88\x9d\x92\x20\x0a\xc7\xc0\x9e\xda\
+\xe9\x2f\x30\x38\xb8\x77\xdb\xf8\x15\xd1\x11\xb3\xb7\x18\x3a\x53\
+\xa7\x00\xb6\xc0\xed\x09\xb7\x0d\x76\x35\x80\x5b\xaf\xcf\x25\x59\
+\x11\x10\xb3\x26\x9c\x68\x60\x66\x0c\x99\x7a\x63\xba\x5e\x9f\x7c\
+\x9a\x68\x20\x37\x2e\x87\x95\xa7\x9f\x1f\xea\xf7\x4a\xf0\x89\x18\
+\x20\x44\x41\x11\x0b\x3a\x71\xef\x04\xc0\x80\x06\xea\x19\x66\xb6\
+\xc0\x96\x99\xe0\xe3\xdb\x1c\x80\x65\x5e\x10\xac\x34\x90\x3e\x96\
+\x17\x44\xb1\x3a\x01\xeb\xa7\x2e\x41\xb2\xd1\xdf\x7e\x56\xff\x0d\
+\xf6\xf5\x00\x45\x3a\x20\x48\x36\x54\x9d\x11\x65\x56\x50\xa4\x83\
+\xd6\xe3\x16\xc0\xcb\xaa\x20\xc9\xf6\xa4\x71\xb7\xf5\xfe\x16\xc0\
+\x96\xc9\x01\xd2\xed\x01\x3f\x57\x92\x03\x19\x76\xbb\xc9\x4b\x64\
+\xd8\x63\x93\x97\xe4\x4a\xb2\xc9\x4b\x0e\xee\x90\x69\x7e\x33\x15\
+\x9a\x43\xc7\xbe\x05\x5a\x0b\x72\xcb\x5b\xdd\x86\xb8\x28\x3f\x71\
+\xdd\x8f\x2a\x4a\x22\xfd\x3e\x91\xa8\x81\x6c\xbe\x78\xbb\xb5\xaf\
+\x29\xa5\x57\x33\xf5\xb1\xe4\x70\xd7\x23\x07\xe0\x63\x56\xf6\xcc\
+\xbf\x45\x19\x06\x06\xe8\x77\x05\x24\x29\x69\xd1\x31\xcc\x1c\x18\
+\x00\x1b\x90\x92\x91\xc7\x82\x4c\x1f\x73\xb4\x1c\x88\x85\x79\x9f\
+\x8c\xa2\x8a\xdb\x3f\xe6\x4e\x51\xf4\x04\x83\x3c\xa5\x9f\x45\x2d\
+\x70\x0f\x7b\x5d\x27\x27\xe2\xa0\x60\x3b\xd0\xe0\xf7\x37\x7d\xca\
+\xc1\x96\x65\xe5\xc3\xd8\x27\x9c\x8c\xc8\xa7\x89\xf9\xf4\x5a\xe2\
+\x6c\x07\x3e\x49\x6c\x8f\x44\x01\x3e\x29\x25\x09\x82\xaa\x75\x88\
+\xf7\xe3\xa0\x75\x88\x3f\xbe\xde\x7c\x7e\x3e\xd2\xdf\xe7\x22\xde\
+\x32\x0e\x03\x96\xb9\x06\xec\x67\x7e\xc5\xff\x9f\x4b\x91\x0e\xd8\
+\x2b\xd5\x02\xe6\xb9\xbf\xc1\x3b\xac\xf0\xe3\x80\x20\xd9\x38\xc0\
+\xa7\xd5\x84\x65\x55\xb0\xac\x0a\xc6\x5e\xe0\xe4\x5d\x4b\x5e\x18\
+\xf0\x1e\xcb\x0a\x1f\x40\xe5\xe6\x07\x31\xdb\x6a\xb5\x43\x76\x6f\
+\xc9\x52\xc3\x6b\xf7\x1e\x07\xb1\xa9\x59\x57\xe4\x0e\xa0\xea\x88\
+\x71\xbb\x47\xaa\xf8\xdf\x75\xb1\x80\x6c\x5e\xb7\x4c\xec\x47\x15\
+\xa5\x92\x24\x51\x85\x2f\x22\xf7\xce\xb5\x3e\xaf\xb9\x58\xfe\x88\
+\x0e\x3f\xa7\x97\x05\xe0\x91\x51\x88\x94\x8d\x5f\x69\x20\x43\x83\
+\x7d\x63\xc2\x4c\x19\x29\x11\x1b\x19\x12\xb6\x98\x16\xa0\xd3\x9b\
+\x12\xec\x94\xbb\xff\x18\xa8\x00\x59\x1c\x31\xec\x75\xb5\x84\x88\
+\x43\x26\x71\x5b\x72\x0c\x09\xf0\x1f\x7b\x84\x61\x84\xff\xd8\x63\
+\x1d\x7b\x24\x71\xc2\xe8\xf1\x23\xd4\x24\xc1\x9f\x14\x74\x27\x43\
+\xb6\x03\x9f\x69\xd8\x37\x47\x80\x94\xd5\xfa\xee\x93\x8c\xdb\xbc\
+\x58\x76\xb6\x5b\x61\x8e\xbc\x16\x58\xe1\xaa\x82\xcf\x87\x4c\xb2\
+\xbe\x03\x70\x1b\x24\xe9\x89\x0e\x3e\x77\xf1\xbc\x25\x9d\xde\x65\
+\x8b\x89\x9b\x92\xc6\x32\xb5\x05\x61\x91\x1a\xed\x3f\x29\x38\x70\
+\xe7\xc0\x6b\xc1\x9c\xc6\x5d\x56\xc5\x96\xdc\xdf\x9e\x30\xb1\x05\
+\x74\x52\x76\xf1\xe7\xb1\xbe\x21\xc3\x9e\x03\xef\x7d\x25\x51\xe9\
+\x73\x7d\x7f\xf7\x16\x6f\xd4\xc3\x33\xa0\xd8\x23\x41\x05\x7a\x2b\
+\x0a\xba\x44\x8e\x99\xed\xe3\x25\x91\xd6\xd2\x47\x2c\x7d\x0c\xc0\
+\x13\xc9\xd1\x7c\xcc\xcb\x5a\xbb\x43\xa9\x34\xc3\xfa\x51\x85\x3c\
+\x62\xbe\x7a\x39\x69\x24\x85\xf2\xea\x6d\x53\x52\x58\x80\x9a\x6d\
+\x45\x4c\xa0\x12\x06\xa5\xc7\x76\xaf\xa8\x44\x8f\x4c\x2f\x13\x90\
+\x4a\xb2\xf1\xab\xc6\xc2\x0d\x02\xe5\xd3\x31\x12\xa1\x29\x17\x8a\
+\x9e\xd0\x92\xe2\xdc\x4e\x3a\xd8\xd6\x6c\x1c\xd7\xdf\xd3\x64\x3a\
+\xe3\xb3\xe1\x8c\xd1\xf0\x82\x22\x16\x24\xf4\x98\x4d\x05\x13\x31\
+\x62\x22\x46\x88\x69\x42\x57\x08\x92\x38\x21\x89\x93\x13\xb0\x0a\
+\x62\x46\xc3\x36\x68\x7d\x25\x5b\x00\x6b\x5d\x37\x40\x14\x54\x2d\
+\xe9\xd3\x15\x82\x0f\xa5\xc7\x17\xd5\x80\x7c\x90\x30\x79\xe0\x9f\
+\x2c\x00\x7f\x4c\x07\x37\x3f\xa7\xaa\xc6\x1c\x76\x37\x6e\x51\xd7\
+\x94\x16\xcd\x1d\xcc\x02\xd0\x82\x7a\xbb\xa8\xc1\x0b\xb4\x98\xd8\
+\xf3\xe6\x84\x65\x9f\xd2\x5f\xb4\x64\x84\xdd\x01\x52\x7f\x8f\x2f\
+\x3e\xd6\xd4\xac\x1e\xac\x48\x6f\xbb\x04\xc9\x15\x22\x79\xcd\x32\
+\x1e\x9f\xa7\x4f\x51\x20\x54\x48\x97\x48\x83\x56\x74\xcc\xa2\x50\
+\x33\xb1\x05\xaf\x3a\xf3\xd2\x54\x1e\x39\x15\x91\xa8\xb7\x52\xd5\
+\xb7\x81\x2d\x9a\x85\x25\x90\x44\x42\xbb\x22\x44\x2d\x80\x47\x44\
+\x48\x64\x43\x54\x44\x48\x51\x19\x38\x37\x80\x2c\xaa\xda\xc5\x30\
+\x00\x2e\x44\xda\x62\xe2\x41\xe9\xe1\xa9\x82\x98\x2e\x91\xa8\x18\
+\x94\x9e\x63\xe1\x4e\x4f\xd0\x69\x68\x5d\x0b\x5a\xa7\x7f\xab\x98\
+\x49\xec\x33\xa1\x64\x81\xef\xd8\x36\x0c\x23\xfc\x49\xa1\xc1\x48\
+\x8f\x84\x1e\x13\x31\xd2\x32\x40\x44\x74\x85\xa0\x2b\x84\x5e\xfd\
+\xf7\x8b\x5a\x0a\x64\x6b\xf6\x4a\xb1\x5a\xdf\xb1\x79\xa7\x98\xe7\
+\x5b\xfa\x1b\xf3\x99\xf3\xa5\x01\x98\x80\x78\xe8\x40\x74\xcc\xc4\
+\x4d\xb0\xa5\x94\x27\x2e\x85\xd5\xc7\x0f\xfa\x4b\xe7\x4a\xe4\xe5\
+\xd4\x49\x8a\x7d\xfe\xf6\x64\xa1\xfa\x63\x8b\x3b\xcf\x5b\xb6\x34\
+\xbf\xd5\xc4\x4d\xe9\x52\x75\x46\x0e\x80\xe7\xdc\x06\x56\xa1\x03\
+\xf3\xb2\x2a\xa8\xd6\x93\x16\x13\xdb\xc5\x5d\x90\x6c\xdc\xe7\x86\
+\xcb\x78\xcc\xc4\x82\x2e\x7d\xce\xc5\x58\xb2\x38\x40\xb4\x7f\x48\
+\xd4\x91\xb0\x7f\xe8\x98\x7a\x00\xa0\x02\xba\xa2\x8b\x62\x6f\xd8\
+\x2e\xd0\xc7\xe6\xc6\x1e\x5b\x44\x15\x9e\x8c\xe9\x1e\x31\x6e\xd7\
+\x30\x69\x53\x42\x68\x17\x83\x1a\xc0\x66\x5b\x20\xe9\x13\x21\x1d\
+\xb0\x65\xad\x51\xab\x18\xe9\x65\x0e\xc0\xc7\xf6\x5c\xa4\x3c\x63\
+\xc9\x79\x2d\x69\xa1\x0c\x0b\x6b\xdd\x9e\x11\xa8\x84\xc8\x00\xde\
+\x31\xa4\x88\x0c\x30\x05\x01\x0a\xcf\x80\xf4\x90\x78\x3c\xac\x1a\
+\xd2\xa7\xf3\x04\xff\xb0\xa4\xec\x8c\x19\x1c\x24\x9b\x4e\x04\x87\
+\x25\xe5\xe8\x82\x27\x07\x49\xca\x8e\x72\x74\xc1\x2c\xa8\xce\xda\
+\x52\x30\x84\xac\x60\xaf\x94\x61\xbb\x21\x7e\x39\x39\x79\x6e\x18\
+\x46\x0c\x27\xda\x70\xc3\xab\xd9\x7e\xbf\xbd\xa5\xe4\x33\xba\xfd\
+\x05\x6c\x87\xf8\x86\x89\x89\xfb\x2d\x60\xed\x95\xa2\x10\x07\x22\
+\x06\xec\x51\x28\x3c\x07\xaa\xbd\x52\x74\x85\x60\x53\x44\x2c\xf3\
+\x3b\xc2\x4d\x4a\x10\x06\x5c\x4c\xc6\x6c\xbf\xff\x81\xd7\x6f\x97\
+\x84\xbf\x1e\x31\x11\x33\x67\xa5\x1d\x5b\x6a\xcd\x7f\x93\x9a\xa7\
+\xa4\x59\x0a\xa4\x5a\xe3\x4f\xee\x81\xc4\xd9\x6b\x7a\x61\xb7\x72\
+\xee\x84\x5b\xb0\xd2\x90\x45\xa3\xdc\x5d\x1d\x7b\x01\xde\x70\x01\
+\x8c\xf5\x77\x53\xb6\xdd\x89\xaa\x1a\x6b\x77\xe2\x59\xa4\x57\xe8\
+\x83\xd0\x67\xd2\x91\x6e\xdb\xbc\x0c\x42\x9f\x41\xe8\x23\x1a\x4e\
+\x46\x57\x74\xe9\x12\x39\x3b\xae\x7b\xc6\x69\x00\xa8\xa2\x0c\xdf\
+\x3c\xbe\x8f\x2a\xa7\xa1\xfd\xa8\x62\xdf\x94\x0f\x0d\x00\x97\xd2\
+\xd3\x00\x06\x22\xc3\xcc\xa9\xf4\x88\x3c\xfd\xfc\xc8\xab\xb0\x0a\
+\x39\x32\xff\x39\x96\x76\x87\x15\x0f\x41\xa6\xf7\x2f\x7c\xad\x89\
+\x0d\xa0\x2d\x13\xdb\x45\x5e\x24\x2a\x36\x7e\xe5\x3c\xe1\x09\x25\
+\xe3\x64\xc3\x70\xa2\xd9\xf5\x6a\x1a\xf2\xac\x17\x50\x4e\xa1\xec\
+\x8c\x29\xa7\x10\x07\x6b\x84\xf0\x99\x05\x15\x62\x9a\x30\x0b\x2a\
+\x26\x62\xc4\xe0\x20\xcd\xce\x30\xe2\xc1\xc0\x77\xcc\xea\x18\xb6\
+\xaf\xfd\xd0\xd2\x5f\xe0\xc7\x01\x62\x9a\x68\xe7\x27\xab\xef\xd7\
+\xd2\x63\x48\x21\x0e\x24\x71\x42\x11\x0b\xed\x3e\x3c\xaa\xdc\xf5\
+\x45\x19\x10\x64\x8a\xfd\x5d\x17\x5f\x49\x14\x9e\xf6\x87\xb3\xf5\
+\x09\x80\x03\xd5\x69\xb1\x70\xd3\x47\xde\x2b\xc5\xe0\x20\x19\x87\
+\x01\xf9\x20\x61\xbb\xd0\x7f\xc7\xe7\x5f\x3c\xe3\x65\x01\x7f\xfe\
+\xe7\x6f\xb9\xff\x6e\x89\x9a\xa7\xf8\xa4\xa8\x79\x4a\x31\x5f\x3a\
+\xf6\xf7\xe3\x00\x6f\x34\x85\xf9\x56\x1f\x31\x16\x01\xf3\x45\xc0\
+\xd8\x2b\x9d\x0c\xaa\xaa\xb1\x93\x0f\xe7\xd8\xb7\xc3\x05\xdb\xfd\
+\xde\x31\xb1\x05\xf0\xb2\x2a\x60\x51\x51\x6d\x47\x90\xad\x5b\x1e\
+\x33\x80\x3f\xf6\x49\xb7\x07\x2d\x00\xfd\x20\x01\x34\x80\xed\xed\
+\xc4\x93\x66\xd5\x18\x91\xab\x39\x21\x7d\x54\x83\x6d\xad\x96\x3d\
+\x5e\xc8\x95\x44\x54\x51\x46\xe9\x2c\xb3\x18\x90\x1a\xd4\xb2\x21\
+\x1f\xa4\xd2\xaf\x8d\xaa\x1f\x2d\x7f\x58\xa0\xa6\x46\x9c\xe8\x42\
+\xcb\xe9\x6b\x9a\xf7\x09\x7c\x14\x25\x8a\x58\xb3\x8e\x28\x50\xca\
+\xa3\x27\x22\x3c\x91\x39\x00\x6b\x9f\xb8\xf6\x85\x43\x2a\x2d\x13\
+\xa2\x10\xaf\x6a\xc8\x2c\x55\x32\x13\xa1\x96\xc7\xc1\x9a\x84\x29\
+\x25\x05\x1f\x45\x48\xe2\x57\x06\x80\x09\x92\x0d\x01\x7b\x20\xd1\
+\x2c\x87\x70\xee\x81\x64\x43\xc4\x00\x89\x07\x2c\x49\x08\x80\x35\
+\xc4\x43\x0d\xe4\xf9\x2d\xa8\x00\x21\x02\x4a\x0a\xe8\xaf\x09\x54\
+\x97\x94\x1d\x42\xf8\x04\xaa\x83\xa2\xa6\xb0\xd1\xf0\x82\x0e\x15\
+\x05\x70\xc8\x76\x04\x40\x11\x17\x28\x95\x50\x88\x0d\x81\xea\x18\
+\x1d\xdf\x39\xfb\xfd\x5a\x20\xdb\x62\x47\x31\x9a\xc0\xbd\x66\xc4\
+\xe5\xee\x9a\xe2\xb3\x2b\x7e\xf6\x1b\x3f\x43\xbe\x7a\xcd\xdb\xc5\
+\x9a\x3c\x2f\xf8\xea\xc1\x8c\x7c\xb1\xe4\xe5\xab\x1f\xe8\x7c\xbf\
+\xe6\x97\x7f\xf5\x21\x28\x78\x9b\xdd\xb1\xf9\x7e\xc3\xab\x97\xbf\
+\xa0\x3f\xb9\xe0\xf3\x17\xcf\xd9\x8e\xa7\x4c\xd0\x45\x8e\xaa\xaa\
+\xa5\x80\x95\x03\xf6\xfa\x87\xd2\xe3\xc0\x1d\x7d\x19\x43\x37\x87\
+\x51\x4e\x59\x6d\x59\xd2\xaf\x8f\xec\x71\x41\x27\x9e\xb5\x5e\x5b\
+\xa4\x03\x0e\xbb\xf7\x24\xfd\x8e\x06\xb1\x05\xac\x03\xa5\xbd\xad\
+\x02\x12\x21\x41\x44\x40\x61\xa4\x43\xe1\x00\x9c\x56\x8d\xe7\x36\
+\xfd\x60\x0b\xe0\x06\xa0\x01\x3a\x51\xc6\x41\x2a\x84\x01\xb2\x4f\
+\xd5\xf2\x85\x6d\xd5\xcf\x8f\xaa\x96\x71\x26\x91\x24\x51\xf4\x49\
+\x00\x9f\xfe\x40\x65\xcb\x5a\xb3\xd7\x2b\x2b\x29\x94\x44\x08\xed\
+\x4e\x48\x15\x13\x09\xcd\xc2\x21\x10\x1f\x2a\xaa\x78\xd5\x02\x71\
+\xbe\xde\xf0\x61\x0d\xa3\x61\x44\x21\xba\xa4\x99\xd6\x7e\x0f\xc2\
+\x0a\xca\x09\x29\x25\xb0\xb1\x4b\x57\x53\x45\xcb\x59\xd8\x4a\x20\
+\xf7\x28\x42\x02\x14\x59\x67\xc8\xe0\x70\x57\xaf\x17\x94\x22\x25\
+\x04\x42\xc8\x52\x56\x6b\x49\x18\x2a\x12\xa5\xdf\xc7\xee\x44\xed\
+\x23\x70\x0a\x24\x0e\x88\x6b\x34\xb9\x0c\xb3\x80\x22\xfe\x34\x70\
+\x8f\xdd\x82\x26\x98\x3f\xf3\x2b\x82\x30\x60\x39\x48\x58\xbe\x4b\
+\x11\xd3\x25\x0c\xe0\xf1\x6f\xfe\x1a\xf3\xfb\x35\xb3\xd5\x82\xbb\
+\xc5\x92\x8b\xc9\x98\xce\x62\xcd\xdd\x72\xc1\x9b\x77\x05\x30\xe1\
+\xf5\xea\x7b\xaa\x65\xc8\x7e\xf4\x80\x8b\xf1\x98\x8b\xc9\xf8\x93\
+\x8b\xb9\x26\x08\x83\x64\xc3\x67\x7e\x85\xe4\x82\x03\xcb\x9a\x89\
+\x8d\xa3\x58\x56\x5b\xaa\xf1\x8c\x73\xb5\x96\xc3\xee\x86\x34\x4b\
+\x35\x13\x77\x89\xd8\xab\xba\x4a\x67\x81\xbc\x57\xfb\x96\xce\x75\
+\xa5\xca\xc6\xe1\x3f\x91\xf2\x44\xf3\x5a\x3f\x57\xeb\x62\x08\xa4\
+\x47\x69\xc0\xad\x88\xe8\xe2\x81\x94\x4e\x3e\xf8\x8d\x85\x9c\x2b\
+\x63\x9b\xeb\xbe\xb9\x1e\x9d\x61\x5b\x0b\xee\xa8\xe1\x4e\xb4\xca\
+\xd1\xca\xab\x8b\x1c\xf8\xba\xb8\x41\xa6\xe5\x84\xa8\x1c\x1b\x6b\
+\x49\x11\xb9\xd2\x76\x10\x17\x44\xbd\x09\x4a\x95\x08\xa1\x8f\x4c\
+\x01\x11\xc5\xbb\x94\x70\xbc\x45\x70\xe1\x0e\xf7\x6c\xd7\xa4\xe6\
+\xcb\xd7\x40\xcb\x0d\xa0\xd1\xc0\xcc\x72\x88\x43\x03\x52\x48\xb3\
+\x14\x3f\xde\x91\x66\xf5\xe2\x47\xdb\x70\xfa\x79\xc4\x21\xa1\x71\
+\x32\x52\xeb\x6f\x1a\x47\xc3\x02\xda\x28\x65\xc0\xee\x20\x3d\x86\
+\x04\xac\x29\x28\xe2\xc2\x01\xbc\x59\x8e\xfe\x14\x13\x0b\x2a\xc7\
+\xc4\x51\xac\x28\x4a\xcd\xc6\x77\xcb\x05\x17\xff\x46\x4b\x8a\x7e\
+\xfa\x9a\x89\x0f\xc5\x63\xc1\x40\x1b\x7b\xfc\xf2\xaf\x3e\x44\x66\
+\xcf\xf8\x50\xea\xef\x77\xb6\x78\x00\x63\xf8\x7c\x32\x74\x00\x1e\
+\x4d\x6b\xdd\x1a\x24\x1b\x07\xda\xa6\x1c\xd0\xd2\x62\xce\x61\xb5\
+\xd4\x0c\xbc\x5a\x90\x45\x09\xfd\xf5\x18\x46\x39\xb3\xaa\xa0\xda\
+\x54\xe4\xfe\x96\x90\x87\xad\x85\x9d\x98\x42\xa7\x77\x59\x57\xec\
+\xba\xa2\x7b\x22\x0d\x9c\xe6\x6d\xdc\xa7\xce\xf9\xc0\x0d\x10\x36\
+\x75\x70\x20\x3d\x57\xc0\xd8\x9b\x6d\xb7\xc1\xba\xcd\xd7\x36\xfd\
+\x5f\xd9\xb8\x1e\xb5\x96\x6b\x5a\x4a\x70\x24\x33\xb0\x15\x2a\x03\
+\xdc\xf6\x4e\x57\x39\x37\xc5\x82\xba\x09\xe0\x8a\x18\xd1\x5c\xd1\
+\x2b\xc5\x26\x0b\x90\xbb\x05\x42\xf8\xba\x54\xdd\x94\x4a\xeb\x7a\
+\xa5\x9f\x66\x4b\x94\x52\xa8\xf9\x1e\xb9\x5b\x40\x96\xb3\xf5\x52\
+\x16\x59\xa9\xc1\x9b\x99\x05\x8a\xb9\xbe\x96\x5b\x88\x43\xfd\xb8\
+\x2d\xa1\x14\x0d\xbf\x35\xab\x17\x34\xe5\xa2\xed\xc3\xae\xe5\xf6\
+\x47\x59\xd5\x32\x71\x90\x05\x67\x01\x5c\x88\xc3\x89\x2b\x61\x4b\
+\xce\xda\xae\xab\xe8\x0a\xc1\x6c\x02\x83\x99\x96\x03\x87\xd5\x92\
+\x57\xdf\xff\xc0\xab\x05\x6c\x19\x93\xb2\x73\xef\xbb\xe9\xe8\xef\
+\x2c\x58\x2d\x90\xaf\x5e\xeb\x1d\x72\x90\x70\x31\x19\x73\x98\x8c\
+\x98\x4c\xd3\x56\x15\xaf\xcc\x0a\x67\xa7\x59\x67\x22\x48\x36\x94\
+\x4b\xfd\x5d\xac\xaa\x0a\x56\x21\xfe\x48\x2f\x6c\xcb\xa1\x26\x86\
+\x85\xaf\x8f\x86\x61\xd9\x3f\xa9\xd4\x55\x9d\xd1\x91\x26\x6e\x94\
+\x84\x9b\x8b\xb4\x63\x1f\x57\x57\xe2\x74\x2e\x42\x49\x45\x27\xaa\
+\x38\x48\x75\xe4\x4a\x68\xf6\xb5\x4c\x5b\x36\xae\xfb\x4d\x1b\xad\
+\x11\x2c\x6a\x32\x30\x47\xc0\x75\x60\x3d\x62\xe2\xda\x56\x13\x44\
+\x48\x04\xc2\x1d\x25\xd4\xa7\x02\x47\x8e\xa9\x33\x97\x9b\x50\x4a\
+\x22\x44\x44\x98\xf9\x60\x16\x76\x9b\x2c\x00\x16\xa4\x72\x07\xd9\
+\x54\x33\xe6\x7c\xc5\xbb\x65\xc9\x44\x7e\x64\xdb\xbf\x22\x3e\x54\
+\x06\x88\x3b\xf0\x04\x78\x8a\x78\xe5\x43\x08\x6b\x4f\xd5\xb9\x09\
+\x2f\x63\x58\x09\x5d\xd5\xcb\x72\x5b\x5f\xd2\x36\x5c\xaf\xcb\xda\
+\x53\x0c\xa3\x3e\x6b\xb9\x65\x68\xf3\x06\x93\x7b\x67\x51\x85\x59\
+\xc4\x30\xee\xff\x7f\xab\x98\x19\x26\x4e\x8e\xc4\xc7\x39\x79\x61\
+\xf3\x0c\x7a\xc1\xa7\xaf\x0f\x0e\x92\xd0\x17\x7c\x18\x4d\x18\xfe\
+\x6c\xc2\x37\x7f\xfe\x0d\x37\x7f\xfb\x1d\x00\x3f\x7d\xa8\xa9\xf5\
+\x62\x5c\x3b\x28\x77\xcb\x05\xe3\xa7\x4f\x18\xcc\x2e\xf8\xcc\xaf\
+\x0c\xfb\xae\xb4\x55\x58\x6a\x17\xc3\x3a\x1a\x96\x89\x2d\x98\x2d\
+\x90\xef\xbe\x5f\x3a\x57\xa2\x5c\x2d\xe8\xf3\x80\xb2\xb3\x87\x55\
+\x48\x39\x5c\xe2\x8d\x4a\xe0\x49\x4b\x8a\x34\xb5\x71\xd2\xef\x10\
+\x5a\xd0\xee\x39\x95\x06\x4e\x5a\x44\x15\x5d\xa9\x0b\x08\x5d\x0b\
+\x9d\x48\xa0\x9a\xbe\xae\x54\x1c\xa4\x87\x88\x2a\x0d\x77\x03\x52\
+\xcd\xce\xc2\x95\xa3\x6d\x65\x2e\x89\x04\xa9\xac\x8b\x1c\xf2\x18\
+\xbc\x55\x4c\xe4\x65\xad\x4c\x5b\x1b\xc0\xb5\x3f\x8c\x10\x67\x81\
+\xab\x8e\x00\x7c\x2c\x25\xdc\xfb\x29\x0f\xcf\x4f\xe9\x67\x09\x39\
+\x0a\x01\x7c\x54\x7a\xf7\x2e\x59\x72\xd8\xa4\xe0\x57\x78\xc5\x9c\
+\xc5\xed\x94\x22\x54\xed\x32\xbb\xf1\x52\x33\x51\x12\x28\x05\xf8\
+\xae\x10\x82\xd0\x80\x0d\xbc\x8c\x45\x15\x13\xec\x14\x0b\x63\xdb\
+\xad\x3d\x45\x51\xc5\x2c\xb2\x92\xc0\x33\xc0\x8e\x57\x90\xc1\x26\
+\x4c\x18\xe4\x69\xcd\xd2\x8d\x42\x89\x9f\x8d\x28\xe3\x15\x65\x67\
+\x0c\xc6\x0d\x19\x12\xb0\xce\xb4\x1f\x7d\x4e\x4a\x58\x4f\x58\xa7\
+\xd7\x54\xcb\x62\xf3\x95\x34\xe1\x28\x8f\xd1\x14\xba\xac\x51\xaa\
+\xe4\xef\xfc\xa3\x67\x8c\xdf\x3e\x61\xf9\xdd\x5b\xc6\x4f\x1f\x13\
+\x6e\x52\xc7\xba\x83\xd9\x05\x4f\x79\x6e\x4a\xd3\x95\x29\x35\x9b\
+\x85\xec\x76\xa8\x17\xa7\x8d\x94\x9b\x95\x14\x16\xbc\x45\x3a\xc0\
+\x1f\xfb\x5c\x4c\x0a\xde\x7c\xf8\x6b\x58\xc5\x64\x51\x42\x2c\x3f\
+\x92\x1d\x12\xe2\xe1\x12\xd6\x07\x2a\xff\xe2\x93\xba\xba\xea\x8c\
+\x1a\x9a\xb8\x01\xe4\x26\xa0\x1d\x78\xa5\x76\x85\x9b\x55\xb8\x52\
+\x7a\x0e\x94\x0a\x0c\x2b\x7b\x6e\xa1\x56\x1a\x4f\x58\x57\x1d\x6a\
+\xeb\xcc\x8f\x04\xbe\x94\x86\xcf\x9b\xa0\x6e\xfb\xb5\x78\x59\xcb\
+\xa9\x88\x1a\xce\x44\xdb\x1f\xe6\x4c\x04\xf4\x0c\x98\xcf\x00\xb8\
+\xa5\x8b\x55\x00\x5d\x1d\xb9\x54\x71\xd9\x08\xfa\xf8\x78\xc1\x80\
+\x70\xb1\x26\x1f\x02\x83\xda\x73\x0e\x33\x1f\x11\x0b\x17\x02\x2a\
+\xaa\x98\x40\x64\xa0\x34\x68\x8b\x5e\xac\x41\xdd\x03\x94\xcf\x20\
+\x48\xc9\x08\x08\xcc\xbf\xcd\x66\x2e\x26\xb1\xcf\x5a\xd6\xd2\x61\
+\x90\x14\x4c\xd2\x84\xfc\x53\xc5\x05\x53\x65\x1d\x1c\xa4\xa9\x88\
+\xa5\x4e\x52\x68\x4d\x5c\xeb\x68\x0b\x66\x6b\xb1\xd9\x20\x97\x95\
+\x19\x7b\x05\x5d\x11\xe9\x8a\x9e\x0a\xf0\x95\x24\xeb\x0c\x89\xc5\
+\x9a\x9f\x54\x4f\xf9\xc9\x17\x70\xff\xc5\x0b\xd6\xd5\x8a\x7c\xae\
+\x01\x35\x9b\x98\x52\xb5\x75\x4a\xa6\x38\x8a\x2a\x49\xa8\xaa\x31\
+\x9e\xb7\x3c\xf1\x96\xeb\x62\x48\xe0\x40\xf9\xa1\xf4\x28\xb2\x88\
+\x15\x15\x03\x99\x6a\x4d\x2c\x63\x4a\x99\xc2\xb0\x53\x07\xac\xce\
+\x64\x28\xbc\xc3\x4a\x97\x9d\x8f\x59\xb7\xbd\x72\x52\xee\x7e\x6d\
+\x87\x09\x2d\x3b\x4c\x50\xc7\x79\xbb\x86\x85\x5d\xde\xc1\xea\x61\
+\xf3\x7a\x11\x09\x84\x54\xee\xb1\xa8\xa1\xa3\x65\x83\x89\x9d\x94\
+\x30\x3f\xae\xb4\x8c\x6c\x41\xeb\x65\x48\xf3\x9f\xf3\x87\x95\xd2\
+\xc5\x8d\x63\x8b\xae\x51\xe4\xb0\x9f\x96\x37\xdc\x0a\x17\xc3\x24\
+\x76\xd7\x9b\xf9\x61\xfb\x3a\x1b\xf4\xc9\x5f\x0c\xa9\x82\xa9\xcb\
+\x16\xeb\xc7\x1a\x5f\xae\xf2\x5d\x39\xda\x7e\xe9\xc1\x4e\x11\x07\
+\x85\x03\xad\x8d\x61\x1e\x03\x78\x91\x95\x0c\x23\x2d\x19\x86\x95\
+\xc0\xab\x46\x2c\xf0\x5d\xe6\xb8\xa9\x9b\xfd\x6c\x84\x9f\x8d\x5c\
+\x49\x37\x8a\xef\x19\xd2\xd4\xd0\xc9\x09\x80\xcf\xbb\x13\x29\x89\
+\x0a\x11\x54\x8d\x50\x50\x0a\xa2\xe4\xc1\x21\x23\x62\x40\xb0\xbb\
+\x26\xf0\xde\x71\xe1\xad\xf8\x6a\x2f\xf9\xc9\x45\xc5\x2f\xf5\x33\
+\xfd\x78\xac\x18\x4d\x61\x38\x19\x9f\x94\xb6\x03\xef\xdd\x27\x3f\
+\xb7\x29\x2d\x9a\x21\xa3\xd1\x58\xef\x84\xb1\x4c\x29\xf9\x88\x3f\
+\x9a\x90\x1d\xba\xee\xbb\x3d\x97\x66\xab\x3a\x23\x5d\x76\xb6\xcc\
+\xeb\xd8\xf7\x48\x13\x1f\x87\x75\x2c\x38\x8b\x66\xe5\xcd\x80\xb2\
+\x4b\xa4\xb5\xaf\x88\xe8\x97\x71\xeb\xb1\xd2\x80\xce\x37\x1a\x98\
+\x23\x56\x6f\xb1\xaa\x97\x41\x15\x1b\x49\x51\xb5\x64\xc3\x89\x3f\
+\x7c\x9c\x9b\x68\x2c\x00\x2d\x5b\xdb\x05\x5d\xa0\x12\xc7\xc2\xde\
+\x51\x32\x0f\x60\xbb\x57\x28\x25\x1d\x50\x15\x31\x79\xa6\x1c\x90\
+\xbd\xf1\x90\x62\x90\x10\xc6\x25\x79\xe6\xbb\x14\x1b\xa2\xd4\x91\
+\x55\xfb\x85\xdb\x2f\x5d\x94\x64\x9d\xd3\x1d\xac\xa8\x62\x97\x27\
+\x5e\xcb\xad\x2e\x55\x67\xa5\x06\x34\x1a\xd4\xf6\x71\x1b\x22\x22\
+\xcb\xf1\x99\x69\x19\x61\x98\x38\x8a\x95\x73\x3a\x80\x86\x94\xc8\
+\x29\x3b\xe3\x23\x47\xa3\x1d\x06\x82\xd8\x2d\xec\xba\x42\x80\xf2\
+\xb5\x0f\x6d\xfe\x76\x5f\x69\x8f\xd7\x25\xe5\x6c\x9a\xb0\xb1\x18\
+\xf4\x95\x74\x59\x89\xbd\x52\x2d\x96\xf7\x49\x5d\xd1\xc5\xb2\xb1\
+\xbd\x7e\xbc\xc8\x6b\x16\x39\x36\xd5\x85\xbb\x1d\x77\xf6\x3f\x1a\
+\xc5\xb4\xdb\xb3\x9a\xd8\x8f\x2a\x94\x2d\x46\x9c\xa0\x46\xb3\xaf\
+\x27\xe3\xda\x03\x96\xed\x1d\x20\xf1\x32\xd6\xbe\xe7\xec\xb3\xd2\
+\xd9\x65\xed\xbc\xb0\x05\x78\xd3\xb1\x70\x4c\x6c\xca\xca\x2d\xb8\
+\x2a\x79\x26\xf0\x13\x9d\x08\x0a\x0d\x7c\x88\x84\xae\xcd\x09\x17\
+\x00\xca\xe8\xb5\x0a\x1d\x75\x97\x47\xbf\x2b\xd8\xfa\x29\x42\x44\
+\x48\xe5\x11\xc5\x25\x52\x49\xa2\xb8\x22\x37\x07\x68\x9d\x68\xcb\
+\x34\x58\xe3\x92\xdc\xb2\xbc\xf9\xe1\x85\xcd\x15\xdb\xc3\x9f\xbd\
+\xae\x7c\x17\xa0\x1f\xe4\xa9\x76\x25\x4c\xaa\x6d\x51\xc5\x2c\x4c\
+\x95\x70\x2d\x33\x26\x71\xdf\x69\xe0\x45\x56\x32\xc8\x53\x07\xe4\
+\x32\x5e\x39\x3d\xec\x67\x23\xd2\x78\x75\xe4\x1e\xef\xdc\xfd\xfe\
+\x61\x79\x96\x89\xf7\x4a\x91\xb2\x43\x66\x23\xee\xb3\x05\x33\x26\
+\xdc\xb3\x70\x5d\x1c\x92\x99\x0b\xef\x90\x65\xb5\xf7\x9d\xd5\x8c\
+\x5f\x4b\x17\xa3\xf7\x17\xef\xc8\x33\x9f\x65\x3e\x24\xdc\xdc\xd2\
+\x9f\x0c\xf9\xfa\x71\x8f\xa6\xc1\x7b\x5c\xaa\x76\x60\x36\x05\xca\
+\x55\x55\x31\xf0\xa0\x42\x67\xd9\xb7\x51\x46\xbc\x3e\xc0\xf8\x54\
+\x46\x1c\x83\x3a\x3c\xab\x21\x8d\x0c\x38\x66\x65\x5d\xc8\x88\x8c\
+\xcb\x60\x5d\x88\xca\xad\xc6\x6c\xf8\x27\x95\x6d\x5b\x4e\x44\x15\
+\xd8\x16\xa6\x33\x15\xba\xa8\xe1\x0b\x63\x98\x58\x36\x16\x70\xd1\
+\x89\x5f\xd1\xbe\x1e\xa4\x3e\x45\x22\x8d\xe7\x19\x6b\x29\x61\x74\
+\x70\x33\xb5\xe6\x18\x58\x05\xae\x72\x67\x3b\x3b\xb6\x4a\x01\x01\
+\x0a\x49\x64\x81\xec\x5e\x97\x91\xc7\x75\x2b\x92\x75\x34\x5c\x5b\
+\x92\x05\xaa\xf2\x81\x0c\xa1\xe2\x13\x1d\x67\x3b\x41\x28\xe2\xfa\
+\xc7\xdf\x29\xe7\x50\x60\x1d\x0c\xeb\x5c\x64\x39\x13\x80\x30\x3a\
+\xab\x87\xed\xd6\x7a\xc4\xc7\x8f\xdb\xd6\x25\xc7\xe0\x68\xc7\x63\
+\xbd\xe9\xb3\xdd\x5f\xa3\x78\x8b\x48\x07\xcc\x79\xa9\x19\x90\x0d\
+\x07\xee\xe8\x18\x49\x60\xf3\x0c\x1d\x2e\x38\xf0\x9a\x4e\x12\x41\
+\x9a\x40\x92\x9a\x0c\xf6\x15\xd3\x49\xa1\x8f\x18\x93\x0b\xfc\xde\
+\x88\xa7\xb1\x42\x66\x33\x3e\xbe\xfc\x86\x8f\x3c\xe7\xc1\x63\x23\
+\xad\xe2\xe1\x27\x43\xf5\x77\x8b\x25\xdb\xc5\x1d\xfd\xc9\x45\xeb\
+\xfe\xb8\xa9\x89\x8f\xd8\xfc\xb8\xb3\x23\xb4\xc0\xeb\x1c\x81\xd1\
+\x05\x76\x8c\xfd\xe6\xb6\x51\x45\x81\xc4\x23\xa6\x38\xb2\xd8\xdc\
+\x73\x84\x4e\x9a\xa9\xa3\x50\x8f\x05\x6a\xd4\xd0\xbb\x78\x19\x52\
+\x2a\x92\x48\x1c\x89\x04\xd9\x28\x33\x67\xed\x62\x88\x54\xf4\xcb\
+\x98\xad\x9f\xd1\x2f\x63\xca\x6a\x4b\x90\xf6\x51\x49\x0d\x9c\xc8\
+\x84\x7f\x44\xc3\x9d\xe8\x99\x9e\xb8\x4a\xf4\x4e\xe4\xc4\x09\x13\
+\x8b\x0a\xa9\x3c\x2a\x11\xe0\xa9\x82\x48\x64\xda\x86\x03\xfa\x24\
+\x90\x59\xfd\x9c\x81\x8a\x5d\x44\x53\x19\x50\x2b\xe5\x6b\x66\x36\
+\x92\x43\x58\xd6\xb6\x8f\x99\x85\xdf\xda\xfc\xdb\x16\xf8\x47\x6c\
+\x6c\xe4\xc6\x6e\xcf\xb0\xd7\xa5\x4a\xd2\x56\x15\xd1\xcf\x46\x44\
+\xf1\x3d\xeb\x46\x26\xb9\x20\x27\x25\xac\x01\x6c\x5e\x9f\x67\x2f\
+\x5d\x90\x3f\x8c\x25\xcf\x26\x0f\x5d\xae\x61\xd3\x79\xee\x02\x4c\
+\xb3\xe0\x19\x00\xf7\x85\xc7\xe0\xf0\xb0\xf1\xed\x3c\x44\x66\xc2\
+\x85\xe7\xa7\xfe\xe8\x24\x47\x6c\xfe\x71\x74\x7a\x63\xf2\xc5\x73\
+\xfc\xf9\x1b\x0e\xde\x63\x3a\x8f\x22\x5d\x5e\x27\x71\x0b\xbc\x63\
+\x40\xf7\x27\x17\x8e\x81\x87\x5e\xc9\xba\xf2\x09\xe3\x88\x78\x9d\
+\xe2\x0d\xe6\x28\x9e\x20\x3e\x91\x61\x66\xed\x69\x39\x21\x22\xa1\
+\xcb\xc1\x06\xcc\xbe\xd4\xdb\xbd\xd4\x8f\xf9\x52\xb6\xec\xb2\xc0\
+\x64\x1e\x8a\x06\xe0\xad\xee\xf5\x91\x94\x0a\xfc\x48\xcb\x05\xd1\
+\x14\x00\x86\x69\x2d\x18\x71\xcd\xa6\xfa\x59\x41\xea\xb3\xf6\x2b\
+\x92\x48\xd6\xcc\xac\xe6\x48\xd0\x1a\xdb\xd7\x00\x06\xd8\x26\x3a\
+\xb5\x5c\x50\x12\xa4\x7d\xca\x6a\xeb\x52\x6e\x51\x23\xbd\xa6\x0c\
+\x9b\xf6\x88\xd9\x71\x5e\x4e\xd8\x7e\xba\xfe\xa1\x64\x4b\x0d\x60\
+\xbd\x2d\x88\x44\x85\x52\x92\x64\x69\xbe\xfc\x81\x87\x17\x0c\x1a\
+\x7d\x76\x70\xd8\x29\x02\x51\x82\x52\x28\x15\x23\x0c\x58\x01\xa6\
+\x99\x47\x16\x57\x4e\xd3\x17\x76\xe1\xd7\x70\x60\x02\x2f\x63\x6d\
+\x16\x76\x64\xb9\x03\x35\xa2\x24\x3f\x48\xc2\x34\x69\x34\x9a\xe4\
+\x8e\x71\xf5\xdf\xbf\x65\xed\xf7\xcf\xba\x12\xf3\x6c\xce\xe2\xd5\
+\x86\xc9\xe7\xcf\xe8\x67\xe0\x4f\x6c\x61\x44\x7f\x8f\x63\x63\x44\
+\x0e\xe2\x94\x85\x79\xcb\x32\x97\x6c\x36\x7a\xa1\xb9\x04\x86\xcc\
+\x59\xe3\xb1\xfd\x3e\xa0\x3f\xd1\xa5\x66\xfd\x7b\xcf\x09\xe7\x26\
+\xa7\x3c\x1d\xd1\xf5\xfa\xc0\x9c\xed\xcb\x37\x7a\x31\x3c\x5d\xd2\
+\x7f\xb7\x25\xf9\x72\xd6\x62\x53\xbb\xd5\x72\xe0\xde\x01\x18\x60\
+\x5d\xf9\x0c\xbd\x12\x64\xda\x4e\x3a\x9e\x61\xe2\x32\x2b\x60\x58\
+\x11\x0a\xa0\x40\x22\xf0\x50\xc6\x45\x50\x40\xc7\xbe\x58\x7a\x54\
+\x51\x45\x60\x4b\xc5\xad\x36\xa4\x88\x22\xca\x60\x11\x22\xd8\x3a\
+\xf1\xaf\x5b\x8a\x32\x84\x01\x5c\x5c\x94\x64\x52\xe9\x6d\xe0\xeb\
+\xcc\x6f\xa3\xd8\x11\xa4\x3e\x65\xb5\x65\x1b\xf8\x0c\xcb\x98\xad\
+\x94\xe8\x67\xe9\x2c\x85\x8e\x66\xda\xfc\x80\xd0\xaf\x6f\xf8\x19\
+\x9d\x24\xe3\x90\xf6\x29\x1a\xcd\x97\x3d\x62\x76\x22\x73\xad\x52\
+\x4d\x00\x1f\x5f\x36\xbe\xce\x0e\x6f\x8b\x0e\xd1\xe0\xdf\x91\xcd\
+\x30\x00\xae\x8a\x8d\x0d\x91\x1e\xc9\x89\x1a\xc0\x7a\xab\x8b\x09\
+\xb6\x22\x88\x10\x47\xa5\x08\x0d\x5c\x5b\x20\xb1\xa5\xe6\x49\x96\
+\xb3\xf6\x14\xf1\xa1\x22\x0c\xa3\x9a\x89\x1b\x9e\xb1\x2e\x67\xe7\
+\x2c\xca\x80\xa9\x1f\x38\x56\xd6\xe5\x6f\x28\xdf\x55\x75\x45\x6c\
+\xf1\x3d\x0b\x60\xf5\x32\x60\xe0\xdd\x39\xb0\xcc\x06\x3e\x55\x30\
+\x65\x34\x1e\xb0\x5a\x6e\x1a\x7f\xd5\x7d\xbd\xe6\x32\xdb\x47\x93\
+\x81\x03\x6f\xdf\xe4\x3d\x6e\x57\x25\xbb\x72\x41\x6f\x55\x72\x98\
+\x68\x81\x3b\x1b\xe9\x9d\x77\x38\x99\xb2\x5f\xac\x51\x4a\xd1\x15\
+\xc9\x89\xe5\xe6\x9b\x1d\xd1\x63\x4a\xc5\x9c\x75\xe5\xb7\x81\xdc\
+\xac\x14\xf7\xd7\x94\xdb\xe1\x49\xe8\xdf\x55\xec\x02\x22\x8a\x48\
+\xd2\x95\x1e\x45\x54\x21\xa4\x87\x32\x7a\xb7\x59\x81\x73\x8b\x32\
+\x23\x0f\xb4\x5c\x88\x40\x28\x50\x03\x67\xbb\x95\x52\xea\xae\x65\
+\x22\x7c\x35\x27\x03\xf2\x55\x48\x16\xe7\x70\x00\x9f\xd0\x24\xdb\
+\x42\xed\xc2\x89\x9c\xb8\x71\x84\x89\x8c\xf4\x00\xed\x37\x27\x54\
+\xa7\xb5\x3c\x67\xa1\xe9\x18\xa2\xdc\xef\x89\x92\xb0\x4e\xb1\x19\
+\xf3\x5e\x9d\x69\xf6\xac\xce\xb0\xb1\x2d\x4f\xb7\xb5\x70\xa3\x5d\
+\x49\x05\x78\xe3\x1a\x7e\xc5\x20\xa1\xb0\x5a\x57\x65\x74\x7a\x53\
+\x0e\xbb\x66\x79\x25\xa3\xa8\xa6\xa8\xe5\x9a\x55\xb6\x67\xc4\x80\
+\x2c\xae\xc8\xe7\x7b\xe7\x6e\x0c\x07\x1d\xe6\xc5\x0e\x44\x0d\xe4\
+\xb5\xa7\x40\xc2\x10\xe1\xaa\x82\x6b\x4f\x31\x34\x4c\x6c\xf5\x32\
+\x71\xe8\x4a\xd5\xfd\x4d\xc9\x7a\x52\x34\x98\x38\x24\x5f\x6f\x08\
+\x27\x11\x53\x86\xae\x73\xa2\x3f\x29\x98\x4c\xe0\x62\xf2\x33\xf6\
+\x8b\xef\xf1\x99\x32\xf6\x4a\xf6\x95\x6e\x52\x7d\x61\xed\xb2\xb1\
+\x0f\xcb\x52\x6f\x81\x4e\xdc\xe3\x90\x35\x9c\x8e\xc6\x63\x4f\xbc\
+\x3e\xf0\x14\xc6\x3e\x45\x2c\x08\xde\x67\xfc\xdb\xf9\x96\xc3\x6a\
+\xc9\xaf\x98\x58\x67\x90\x05\xf8\x22\xc5\x25\x7b\x4c\xea\x4f\x4b\
+\x1c\xc9\x76\x71\x47\x32\xf1\x9d\x94\x38\x06\xb2\x00\x28\x27\xae\
+\x80\xd2\x64\x65\x9d\x9d\x30\x01\x74\xeb\x36\x78\xb2\xb6\xc6\x02\
+\x63\x7d\x15\x06\xb8\x2e\xd0\xde\xd0\xb9\x42\x2a\x23\x87\xf2\x96\
+\x13\xa1\x6d\x9a\x43\xa3\xb1\x32\x22\xee\xf4\x28\xc5\x54\x5b\x27\
+\x22\x32\x5b\x3d\xeb\xa2\xea\xc7\x44\x91\xa0\x30\xba\x56\xb7\x31\
+\x45\x6e\xdb\xea\xa8\x33\x00\x96\xe6\xf0\x2c\xa5\x32\x76\x4c\x64\
+\x42\xef\x25\x42\x54\x2e\x3b\x21\x1a\x8b\xba\x73\x00\xf6\xc8\xd8\
+\xf8\x15\xc9\xa1\x3c\xe9\x70\x96\xd6\x6b\x1e\xd7\x11\xff\xad\x9f\
+\x36\x58\x22\x43\x08\xdb\xb2\x94\x35\x58\x58\x7f\x6a\x12\x1c\x60\
+\xe0\xb1\xc6\xd3\x95\x3f\x20\xce\xbc\xba\x64\xed\xa4\x9d\x62\x10\
+\x17\x14\x55\xec\x00\x9d\x15\x01\x59\xc7\xd3\xc9\xba\x24\xd5\x76\
+\x5c\xec\xd7\x00\x8e\xdb\xeb\xf2\x66\x79\x24\x0c\x23\x92\x38\x61\
+\x32\x9d\xd5\x8c\x3f\xe8\xf0\xf4\xf1\x15\xc3\xc9\x98\x07\x5f\x7e\
+\xc1\x83\xc7\x3d\x18\xfb\x74\x27\x43\xc6\x13\x03\x5e\x03\x4e\xb7\
+\x35\x51\xcf\x4e\xdc\x70\x3a\xcc\x63\x55\xb9\x6a\xbd\x26\xc8\x14\
+\xc5\xa3\x98\x27\x13\x0d\x56\xdb\xad\xdd\x89\xf5\x71\xb4\xcc\x0a\
+\x17\x4d\xfd\xb1\x4b\x93\x85\x8f\x17\x76\xc7\x76\x5d\xba\x3d\xe0\
+\x97\xd2\xe3\x60\x80\x77\x68\x54\xdb\x9a\x16\x98\x03\x76\xc3\xdb\
+\x15\x0d\xbd\xdb\x64\xd0\x33\xc7\x5f\x10\x11\xd1\x24\x24\x4b\x2e\
+\xf0\x45\x0d\xd8\xaa\x1f\xeb\x34\x5c\x54\x39\x97\x57\x82\x03\x27\
+\xc7\xc5\x68\x0b\xda\xa6\xa1\x26\x74\x01\x46\xcb\x14\x79\xc6\x6a\
+\xf1\x5a\x1d\xd8\xad\x05\x89\xa9\xd6\x09\x11\xe9\xb6\xfd\x8e\xef\
+\x40\x6b\xc1\x7c\x0c\xea\x3c\x2e\xdb\xa1\x21\xd0\x92\x41\x94\xad\
+\x56\x26\x5b\xec\xf0\x2f\x9e\x52\x0c\x1e\x90\xc7\x25\xfe\xc5\x53\
+\xdd\x35\x1d\x47\x84\xd3\xae\x91\x1e\xb5\x2b\xb1\x34\xbe\xe9\x02\
+\xdf\xb1\x70\x7c\xa8\xc8\x3a\x9e\xc9\x73\x68\x3d\xbc\xc8\xca\x16\
+\x13\x77\x46\x55\x43\x5e\x68\x67\xc2\x76\x44\xef\x95\xe2\xd5\xcb\
+\x5f\xe8\xac\xef\xa6\xc4\xdf\x7e\xa0\xb8\xff\x86\xe2\xfb\xb9\x66\
+\x57\x13\xc2\x71\xdb\x26\xdb\x36\xfe\xdf\x6f\x6f\xf5\x76\xb1\x86\
+\x65\x49\x55\xae\x38\xac\x6a\x0f\xbc\x13\xf7\xdc\xc8\x80\xe9\x17\
+\x9f\xb3\xaa\x2a\x3e\x2e\xee\xe9\x4e\x86\x94\x62\xd6\xc8\x9b\x27\
+\xf8\xe8\x80\x7d\xdd\x28\x7a\xe1\xd8\x37\x59\x04\x2d\x36\x06\xc8\
+\xfd\xad\x2b\xa4\x9c\x6b\x52\x0d\xab\x28\x03\xe9\xd5\xe1\x19\x03\
+\x13\x81\x70\x5e\x71\x2d\x13\xbc\x56\x74\xb2\x95\x87\x20\x42\x52\
+\xb5\x53\x6a\x22\xd7\x93\x85\x9a\xa5\xe4\x46\x93\xe7\x71\xb9\xd8\
+\x39\xbe\x4a\x9d\x3c\x2e\xed\x82\xcd\xde\x67\x26\x02\x49\xa0\x5f\
+\x64\x7a\x87\x20\xd2\xbe\xb0\x69\x41\xe2\x4c\x97\x73\x93\x85\x2d\
+\x2b\x4b\xe5\xe1\x99\xd8\xa9\x05\xad\x95\x15\x76\xf2\x8f\x03\xb0\
+\x59\xcc\xe9\x49\x40\xa5\xb3\xd8\x94\x52\x08\x3b\x94\x44\x98\x8a\
+\x5c\x4f\x03\x39\x30\x56\x5c\xd1\xf0\x92\x6d\x89\x7a\x58\xe9\x06\
+\xad\x45\x55\x7b\xc8\x71\x50\xe0\x6f\xfa\xc4\x83\xed\x89\x76\x76\
+\x0b\xbe\x46\x1a\xee\xb0\xf2\xf4\x5a\xcb\xb1\x73\x6a\x5c\x0a\x78\
+\x9b\x49\x7e\xc8\xde\xf1\x2c\x7e\x4c\xc6\x90\xb2\xd4\xef\xe9\x57\
+\x3e\xf1\x62\x8d\x9a\x24\x0c\x97\x25\xeb\x71\x45\xb9\xd0\x7a\xb7\
+\x4e\xc7\x4d\xdd\xa2\x6e\xbc\xd2\x8b\x39\x7f\x92\xa0\xa8\x28\x17\
+\x23\xfc\x49\x41\xb6\x80\xb7\x8b\x35\x89\xb7\xe0\xd9\xaf\x3c\x41\
+\xc4\x7d\x3e\x6e\x34\x03\xaf\x4d\x85\xf3\x84\x55\x0d\x13\xd7\x8d\
+\xa2\x5a\x4e\x00\xdc\x72\xc0\x67\xc1\xc5\xe2\x21\xc1\xf4\x00\xf8\
+\xe4\x65\xff\xbc\x17\x6c\x41\x3c\xdf\x54\x44\xb9\x42\xe6\x25\x22\
+\x54\xd8\xce\xa4\xb2\x55\x46\x8e\xf0\xe5\xf9\x84\x82\x6a\x65\x2a\
+\xda\xc5\x0d\x0d\xe0\xcd\x49\x41\xc2\x5e\xfb\x54\xde\x41\x0a\x41\
+\xa4\x54\xed\x0f\x3b\xc0\x4a\x22\x21\x74\xa9\xb9\x51\xbd\xcb\x02\
+\x9f\x7e\xea\x53\xcc\xaa\xd6\xdf\x64\xab\x68\x9f\x5a\xd0\x35\xdb\
+\x93\xd4\x32\x68\x69\x62\xeb\x50\x0c\x4e\xfe\xbd\xd9\xc9\x6d\xa1\
+\x62\xc7\xc8\x1a\xc8\x3e\x42\x64\xee\xd8\x65\xc3\x40\x81\x97\xb5\
+\x87\xac\x54\x31\x50\xb2\xde\xed\xb5\x5f\x5c\x04\xf4\xb3\x88\x6d\
+\x2c\xc9\x81\x69\xa3\xec\xdc\x04\xb0\x5d\x04\x0e\x2b\x41\xb9\x08\
+\xd8\x0e\xf4\x2a\xc3\xb2\x73\xea\xe4\x46\x8f\x19\x13\x7e\xfa\xf8\
+\x67\x6e\x41\x96\x15\x11\x79\xa6\x18\x32\xe7\x36\x8e\x18\x02\x6f\
+\xa3\x1d\x43\xba\xf8\x93\x02\x1f\x5d\xf2\x1e\x8d\xa6\x4c\x0f\x4b\
+\xfc\xec\x0b\xc6\x23\x8f\xca\xd7\x12\xc1\x5f\xac\x18\x4e\xc6\xdc\
+\x4f\x2a\xfc\xc5\x8a\xf1\x17\x63\xc2\xc5\x92\xbb\xc5\x90\x37\xef\
+\x16\x4c\x33\xd8\xee\x74\xa5\xed\xcb\xa1\x47\xc7\x24\xeb\x9a\x12\
+\xa2\x29\x29\xf2\xec\x3c\x0a\xd2\x49\xe1\xa6\x6d\x08\x30\xc9\xb8\
+\xba\x68\xd2\x64\xe4\x50\x9b\xfd\x15\x03\x7c\x36\xb9\xa0\x13\xe2\
+\x1a\x3a\x05\xc2\xb8\x13\x19\x05\x10\x50\x39\xc6\x16\x26\x5b\x21\
+\x8e\x18\xd9\xea\xd9\x54\x7a\xf4\x3b\x7b\xb2\xc3\x00\xc8\xd9\x02\
+\x81\x54\x10\x9d\xd6\xdb\x4e\x8a\x1f\x8e\x89\x4d\x5a\xcd\x54\xea\
+\x22\x03\xe6\xd6\x7d\x40\x50\xc6\x4e\x4b\xdb\xe6\xd0\xf6\xac\x89\
+\xcc\xfd\x8d\xc7\x9a\xb8\x32\x0b\x33\x08\x8c\x4c\xa8\x5a\x5a\xf8\
+\xf4\x62\xbc\xe6\x62\xe3\x16\x27\xea\xcc\x0e\xa2\x41\xed\x1b\xfb\
+\x6d\x4e\x60\x3e\xaf\xe8\x09\x0d\xe6\xaa\xd6\xc2\xe0\xeb\xad\xd0\
+\x1d\xde\x76\xc1\xb3\xde\xc1\xb0\x17\x01\xca\x01\xbd\xc9\xca\xa0\
+\x47\x02\x9c\xbb\x24\xb1\xa9\xe0\x21\x18\x3f\x7d\x42\xb8\x49\xe9\
+\x4e\x9e\xd1\x05\xa2\x89\x62\xd3\x89\x74\x03\xd0\xea\x8e\x71\xef\
+\x8a\xe5\xee\x9a\x71\xef\x8a\xbb\xc5\x92\xe9\xa4\x60\xfe\xca\x94\
+\xd2\x78\x69\xaa\x6a\x13\x57\xa3\xbb\x5b\x4c\x18\x32\xe7\x8e\x29\
+\x77\x8b\xa5\x71\x78\x34\x83\x87\xbb\x3d\x79\x16\x71\x31\x9e\x50\
+\x4e\x86\x28\x8a\x13\xd9\x69\x01\x6c\x01\xb9\x1b\x97\xb0\x80\x64\
+\xe2\x73\x28\x3e\xf0\x78\xf1\x84\x74\x52\xb0\xae\xec\x20\x2c\xce\
+\x96\xaf\x7d\x52\x5d\xec\x18\x0c\x62\xa7\xe5\x06\xa6\x75\x48\x49\
+\x2d\x27\xea\x92\x70\x44\x61\xb5\x70\x43\x5b\xda\x38\xa6\x38\x93\
+\x03\xf6\x91\x26\xc0\xb1\xa9\xa1\x6a\x16\x91\xcd\x7e\x0c\x3b\x8c\
+\x30\x6a\x15\x94\xdb\xcd\x49\x91\x59\xb0\x49\x03\xee\x08\xd9\xaa\
+\xf4\xcd\x92\x82\xc2\xf6\xcb\xd9\xd6\xfc\xc6\xce\x55\x11\x23\x0c\
+\xd0\x76\xc6\xd7\x3d\x76\x29\x3c\x91\xa1\x96\x7b\x2a\xd1\x6b\x31\
+\xf1\xd6\x46\x34\xe3\xa3\x24\x55\x30\xe0\xb0\xd9\x20\x06\x89\x03\
+\xb6\xb2\xfa\x18\x9c\x57\x8c\x5b\xe4\x95\x2d\x06\x0e\x3c\x3d\x39\
+\x28\x35\x16\x5d\x62\x99\xdc\x56\xf6\x8c\x55\xb7\x46\xdb\x6c\x04\
+\x85\x8b\x74\x5a\x56\x76\x51\xcd\x66\xb0\xde\xb2\x31\x90\xc4\x39\
+\x12\x1d\x74\x0f\xc2\x80\x57\x1f\xfe\x8a\x7e\x57\x10\xee\x04\x79\
+\x76\xad\xa5\x6f\x3e\xe4\x62\x78\xed\x7a\xeb\xc2\x18\xe6\x8b\x88\
+\x3c\x96\x84\x59\x44\x1e\x0b\x53\xc8\x91\x0d\xfa\x92\x6c\x7a\x13\
+\xf2\x9d\x74\x05\x9d\x61\x35\x61\x34\x9a\xea\x46\xd9\x09\xbc\x01\
+\x62\xd6\x08\x1e\xb4\xfe\xed\xad\x30\x90\x92\x2c\xf3\x82\xa9\x17\
+\xba\x8e\x98\x4e\xf0\x19\xe9\xa4\x40\x72\x4f\xd4\x82\xb0\x0d\x18\
+\x0d\x1b\x8b\xbc\xc4\x44\x31\xed\x62\xce\xe8\x5d\xd5\xe8\x81\xb3\
+\xb2\xa0\x38\xb3\x60\xb2\x61\x20\xa1\x6c\x0f\x5e\x0d\x3e\x69\x3d\
+\x61\x36\x8d\xc7\x3e\x7d\xb1\x15\x38\xcb\xa6\x16\xe6\x91\x6d\xbb\
+\x6f\x48\x15\x07\x6f\xc3\xca\x49\x54\x71\x48\x03\x48\x24\xa8\xa8\
+\x9e\x94\x69\x62\x97\x98\xc5\x9b\x05\x74\xaf\x31\xc9\xd2\x02\xd8\
+\xca\x09\x31\xee\x1a\x56\x8e\x1c\x13\x27\x87\x92\x66\x48\x2c\x63\
+\x4f\x6c\xf4\x71\xb0\xd1\x51\xcd\x30\x36\xa0\xb3\x9f\xd3\x00\xad\
+\x6a\xe6\x2b\x44\xc9\x61\x37\x77\xce\xc5\x61\x37\x87\xa8\x24\x69\
+\xac\x13\x6a\x56\xcf\x48\xbd\x92\x40\xfa\xf8\xa2\x44\x1c\x22\x07\
+\xe0\xb5\xa7\x75\xf6\x49\xca\xed\xf8\x90\x4c\x08\xdc\xb3\xb9\x87\
+\x8b\xe1\x9e\x71\x3c\x26\xcf\x14\x0b\x25\x19\x18\xef\xfa\x62\xb8\
+\x67\xdc\xbb\xa2\x8c\x57\xae\x6b\x63\x70\x90\x04\x19\x74\x26\x3d\
+\x14\xa6\x0b\x64\x3a\xf9\xd1\xdf\xd0\xc6\x2f\x2b\xff\xd2\x84\x82\
+\x16\x74\xbd\x91\x2b\xbf\x5b\x09\xe1\xb6\x26\x60\x34\x0e\x77\xbc\
+\x5d\x94\x8e\x8d\xfd\xc9\x82\x74\x31\x21\x99\xcc\x18\x2c\xbe\x85\
+\xe1\x57\xba\x3d\x69\x7b\xa1\x19\xdc\x3a\x1c\x59\xe2\x2c\xb6\xd0\
+\xfa\xbe\x55\x54\x51\xca\xb8\x66\xd7\x48\xb4\x17\x69\xcd\x85\x9f\
+\x54\xf8\x4d\xf7\x41\x6d\x80\x01\xd2\xa6\x39\xc0\xb0\xf0\xce\x59\
+\x74\x41\x43\x38\x14\x48\x02\x3b\x53\xc2\x14\x43\xb6\x41\xe6\xc8\
+\xd7\x8d\x89\x35\xc5\x01\x54\x04\xaa\xd6\xc3\x56\x7f\x46\xa6\xca\
+\xe7\xba\x76\x45\xd5\x72\x20\x9a\x96\x9a\x65\xdf\xe3\xaa\x9d\x6d\
+\x16\xf5\x44\x81\x5a\xee\x9d\x2e\xb2\x4c\x7c\x2a\x26\x72\x0a\x21\
+\x08\x94\xc2\x0b\x29\xf9\xbd\x95\x00\x00\x20\x00\x49\x44\x41\x54\
+\x06\x6c\xf7\x77\x24\x45\x8f\xce\x80\x46\x67\x89\x72\xec\xac\x7d\
+\xe4\x7a\xf8\xa0\x10\x82\xd4\xcb\x48\x2a\xed\x4c\xf8\x55\xc6\x6e\
+\xa7\x0b\x0b\xc1\x46\x5b\xa9\x5f\x4c\x47\x2c\x6d\x2b\x96\xf9\xda\
+\x8a\x95\x2e\x96\xac\x1b\x9e\xf2\x8f\x01\xb8\xd9\xf2\x14\x74\x57\
+\x14\xbd\x09\x4f\xe2\x88\xee\x95\x68\xb5\xf2\xd7\xbf\x6a\xcf\x65\
+\x94\x01\x96\xa3\x89\xbb\xbe\xc8\x22\x4a\x5b\xf2\x68\xb4\x51\x35\
+\x27\x13\x09\xf1\xce\xe8\x7d\xc9\x3a\x8b\x78\x44\x40\x35\xdc\x00\
+\xbd\x96\x23\xe1\xa4\x84\x19\x66\x68\xc7\x66\xf5\x96\x3e\xfe\x64\
+\x41\xb9\x98\xe0\x4f\x16\xc0\x8c\xcd\xe4\x2b\x2e\x4c\x7b\x52\xd9\
+\x2f\xf0\xb7\xfa\xf5\xf6\x3d\xf6\x4a\xe9\xb2\xb3\xed\xc0\x08\xa4\
+\x6c\x31\x5e\x13\xb4\xcd\x7f\x6a\x57\x7a\x0e\xc0\x71\x51\x92\x89\
+\x9c\xb8\xe8\x91\x1d\x36\x2d\x85\xab\x7d\xdb\x1e\x19\xd0\x27\x62\
+\x6b\x80\x6b\x8b\x2b\x4d\x19\xd2\xeb\x47\xf8\x69\x40\x91\xa4\x48\
+\xe9\x1d\x39\x15\x5e\xad\x9e\x8d\x0e\xce\x84\x47\xac\xac\x7f\xbc\
+\xa3\x93\x14\x3a\xb3\xa0\x70\x4c\x6c\x01\xaa\x27\x60\xd6\x32\xa8\
+\xf7\x09\x9f\xd8\x16\x3b\x6c\x76\xc2\x96\xa3\xb7\x45\x87\x04\xad\
+\x7f\xad\x53\xb1\x53\xb9\x63\xe3\x3e\x17\x1a\xc8\xef\x2b\x78\xd4\
+\x6f\x15\x3b\x9a\x3e\xb2\x65\x66\x9f\x0c\x5d\x14\xcc\xb8\x55\x8a\
+\xe2\xed\x82\x0f\xab\x5b\x76\x77\x7b\x3e\x2c\xdf\xf2\x48\xe4\xfc\
+\xd5\x93\x9f\xf0\xd3\xe7\xda\x76\xaa\x06\x53\x3a\x55\xc2\xd5\x64\
+\x4c\xe0\x95\x40\x41\xbe\x92\x70\x26\xe2\xd9\xb4\xdd\xec\xed\xf5\
+\x22\x73\x76\x1f\x71\xa9\x3b\xb0\x33\x93\xcb\xcb\xd2\xd3\xd7\x34\
+\x0f\xdd\x71\x42\x9a\xa5\x5a\x5f\x37\x82\x44\xee\x08\x9a\x09\xfa\
+\x2c\x59\x2e\x20\x98\xe0\xbc\xe4\x92\x7b\x32\x86\x8c\x58\x81\xf2\
+\x4d\xa1\x83\xf6\xe2\x4e\x49\xba\x22\x22\xdc\xdc\x36\xdc\xa9\x19\
+\xcb\xe2\x9a\x31\x57\xa4\x8b\x92\xab\xa9\xfe\x4b\x9a\x4c\xdc\xf2\
+\x8a\x15\xba\xec\x8c\x49\xa4\x45\xd1\x84\x54\xea\x6a\x91\x30\x76\
+\x1a\x26\x81\x56\x18\xe0\xb9\xd2\x85\x19\xc8\x9d\xf5\xe3\xfa\xe7\
+\x92\xbe\x2b\x2b\x47\x91\x60\x7b\x34\x1c\xb0\xa9\x77\xb7\x48\x44\
+\x14\xd5\x95\x3f\x24\x24\x11\x30\xa5\x44\x11\xa4\x1e\x45\x52\x3a\
+\x2d\x8c\x8a\x9c\x6b\x81\x52\xc4\xf4\x88\x84\x44\xa8\x8c\x83\x9e\
+\xd3\xd3\xea\xa1\xeb\x89\xc8\x01\xd3\x5e\xb7\xba\xb8\x82\x93\xf6\
+\x24\x77\x5b\x05\x48\xea\x8a\x5d\x4e\x45\x1f\xc1\x76\x0f\xc9\x26\
+\x85\x60\xe0\xd8\xb8\xe9\x1b\x57\xfe\x0c\xaf\xeb\xa1\x96\x8a\x24\
+\x38\xb8\xb2\xb4\x17\x0c\x34\xd0\xb7\xd7\x6c\xc3\x09\x87\x4d\xca\
+\xdb\xbb\x0f\x6c\xb2\x15\x3f\x7c\xfb\xbd\xfe\x61\xa3\x4b\xd4\xf5\
+\x3b\xae\xf7\x1a\xe4\x7f\x79\xb7\x81\x3f\xff\xd7\xfc\xcb\x8b\x01\
+\x5f\x3e\xec\x90\x2d\x0b\xe2\x71\xc0\xdf\xfb\xfa\x37\x99\x3d\x0b\
+\x18\x8b\x3e\xb3\xcf\x1e\x30\x59\xc3\x75\x67\x8f\x98\x07\x84\x93\
+\x91\x2e\x96\x78\x05\x1e\xc9\x09\x30\x3d\xb5\x23\x4e\xba\x75\x07\
+\x36\xb0\x5e\x64\xc4\x41\x41\xb6\x08\x18\xf6\xba\x8d\xce\x6b\xbd\
+\x28\x94\xd9\x0c\x50\x8e\x6d\x93\x38\x41\x70\x8f\x6a\x4d\xe0\x94\
+\x2c\xb2\x31\xdb\xf8\x9a\x07\xf1\xd8\xb1\xeb\x7a\xb7\xe7\x89\xd7\
+\x83\x46\x50\xc8\x02\xf8\xb8\xd8\x91\x0f\xea\xeb\xe9\xc2\xca\xc9\
+\x7b\x60\xc2\x87\x6a\xc1\x8c\x19\x61\xb7\x51\x59\xb5\xd5\xbe\x6c\
+\x4d\x57\x24\x86\x89\x5b\xae\x6d\xbb\x4d\xc8\xea\x61\xcb\xa0\x96\
+\x4f\x14\x15\x42\x49\x5d\xc9\x33\x00\xb7\x56\x17\x46\x0a\xb8\x09\
+\xf2\x26\xff\x10\x48\x0f\x19\xd1\x7a\x3f\x5b\x1c\xd1\x96\x9a\xfe\
+\x1b\x92\x08\x48\xeb\x50\x7b\xa4\x1a\xf6\x9c\x93\x17\x0a\x44\x84\
+\x42\xb5\x7a\x1a\x6c\x5e\xa2\x6d\xff\x65\x8d\x83\xe5\xa9\x57\xdc\
+\x6a\x4f\x32\x5e\xf1\x71\xe9\x19\xd0\x63\x5f\x8b\x3b\x44\x3c\x3d\
+\x11\x18\x91\xc8\x08\xd1\xab\xfd\x3c\xee\x12\x66\xba\x2c\x1d\x6c\
+\x36\x04\x1b\xf8\xb6\x90\xdc\xbe\x7b\xc5\xab\x77\x19\xea\xfa\x1d\
+\x37\xcb\x37\xf5\x0e\x14\x6b\x6a\x98\x45\x4f\xb9\x97\x6f\x78\xf6\
+\xf4\xa7\x74\x0b\x0d\xea\xef\x6e\x0f\xa4\x77\x1b\x7e\x7a\x7b\xe0\
+\x7f\xf8\x8b\xff\x91\x17\xcf\x03\xa2\xc7\xff\x21\xff\xf1\x3f\xe8\
+\xf1\x60\xf4\x1f\x10\xcb\x15\x74\x21\xcf\xbb\xf8\x1d\x89\x57\x3d\
+\x04\x8e\x3a\xad\x9b\x15\x3c\x7a\x48\x46\x94\xdc\x33\xec\x75\xf5\
+\x00\xed\xd0\xce\x10\x6e\x57\xd1\xce\x8d\x67\x55\xce\x8d\xa9\x07\
+\xaf\x44\xb1\x62\x9f\x17\x7a\x04\x80\x29\xf5\xf7\xb3\xa8\x36\x33\
+\x1a\x91\xd4\x93\xe9\x9a\x4a\x4f\x1e\x7a\x6b\x6f\x4f\x16\x70\x87\
+\x93\x14\x0f\x17\x0b\x18\xce\xc8\xf7\x99\x03\xb2\x93\x23\xb6\x83\
+\xc5\xdf\xb7\x3d\xe4\x61\xe9\xb1\x95\xd2\x68\x52\xa9\x01\x28\x3d\
+\x8a\xc8\x00\xcf\x68\xe1\x75\x2a\x11\x89\x06\xa6\x02\x02\x93\x58\
+\x3b\x8e\xa7\xdb\x02\x48\xab\xf3\xf6\x9c\xa9\xd6\xd0\x9e\xa9\xf4\
+\xf0\xcd\x02\x4f\x2f\xec\xa4\x0b\xfc\x38\x6b\xad\xe1\x11\x97\xd5\
+\x16\x21\xa6\x28\x2a\x76\x66\xae\x84\x05\x72\xd3\x99\x50\x67\x5c\
+\x89\xe3\xdc\xc4\xb1\xfd\x66\xc3\xf1\x22\xee\x12\x66\x3e\xdb\x3d\
+\xa8\xe5\xbe\x55\x82\x6e\xca\x06\xab\x50\x42\x33\x88\xe5\xa6\x08\
+\xd8\xbc\xbb\x65\x79\x77\xcd\xdf\xbc\xc9\x1d\x38\x89\x1f\xb3\xca\
+\xbf\xe6\x8b\x81\xa2\x5b\xbc\x63\x1f\x3c\x6e\x01\x79\x16\x3d\x65\
+\x16\xa1\x1f\x7b\xfa\x53\xb6\xa6\xdf\xf7\x46\xbe\x81\xd7\x6f\xf8\
+\xfd\x6b\x9f\xaf\x2e\xbf\xe3\xf1\xd3\xdf\xe2\xcb\x9f\x8c\x08\x46\
+\xa5\x8e\x86\xae\x37\x8e\x4d\x5d\x51\x84\x7a\x0e\x73\x9a\xa5\x10\
+\xef\x48\x48\x4c\x6b\x93\x32\x91\xcd\x5e\xeb\x76\x42\xaf\x9e\x7b\
+\xd1\x92\x18\x5a\x4e\x94\x8b\x40\xa7\xe1\x0c\x4b\x87\x8d\xcc\xf3\
+\x49\x37\x89\x25\x9e\x13\x97\xc1\xa7\x14\x11\xdb\xc5\xc7\xd3\xcf\
+\x31\xda\xf8\x76\x82\xd3\xc4\xc7\xaf\xb7\x3a\x3b\x29\xbb\xa6\x65\
+\xdf\xf8\xba\xbe\x99\xe0\x6e\x17\x5c\x76\x3b\xd8\x56\x64\x81\x02\
+\x15\xa2\xa8\x78\x38\x6b\x03\xd1\x2d\xd4\x8e\xfc\x5f\xdf\xee\x08\
+\x8d\x12\x36\x47\xbd\x19\xc7\xd5\xbb\x56\xde\xd8\x31\xaf\x74\xa7\
+\x3a\x88\xec\x8e\x61\xc6\xf5\x1f\xbc\x7e\x63\x9a\x4e\xfb\x3c\x1e\
+\x9f\xb2\xd4\xf2\xa3\x56\xa5\x66\xc3\xa8\x75\x2b\x8e\x2b\x76\xeb\
+\xd8\xc7\xf7\x0b\x50\x92\x30\xbb\x38\xb1\xdc\x74\x9c\x32\xa5\xa8\
+\x12\x96\x4a\xb2\x58\x2c\xb9\xfb\xdb\x1f\x78\x69\xe6\x32\xdc\xef\
+\xeb\xe7\xcf\xa2\xa7\x20\x7f\x01\x3c\xe5\xe3\xc3\xe7\x3c\x0d\xcc\
+\x21\xfe\x16\xc2\x27\x2f\xe0\x5e\xdf\xde\x07\x8f\x99\x8f\x5e\x33\
+\x5d\x3d\x77\xe0\xee\x16\xba\x7f\xed\xdb\x1b\x8f\xf7\xea\xcf\xa8\
+\xe6\x13\x2e\xfe\xee\xd7\x8c\x45\x9f\xac\x0f\x76\xc4\xc4\xc4\x00\
+\x2b\xcf\x22\xbc\xfd\x12\x46\x38\x6d\x2b\x19\x99\xd6\x26\xad\x89\
+\xed\x10\x40\xdb\xea\x94\x92\xb7\xe4\x45\x13\xc0\x76\xa4\xc0\xc9\
+\xbf\x3d\x53\x10\xf7\x74\xff\xdf\xe4\x9e\xa6\xa5\xd3\x94\x0f\xee\
+\xfa\x27\x4e\xa1\xd0\x09\x3e\x63\x77\xf7\x81\xf1\x85\x4f\xba\x98\
+\xe8\xcc\xd0\x51\x83\x41\xf3\xfd\x5a\x4c\xec\x37\x42\xf1\x27\x8b\
+\xdc\xc0\x2e\xe5\x36\x08\x11\x35\x3a\x99\x55\x6d\x7c\x35\x1a\x33\
+\xa3\x33\xe0\x94\xb4\xa5\x84\x3c\x03\xe6\xd6\xb4\x9f\x93\xce\x46\
+\xe3\x25\xab\xfa\xb1\x43\x1a\xd0\x49\x0a\x0a\x0b\x76\x3b\x40\x45\
+\x54\x27\x65\x71\x61\x58\x53\xcf\x24\x6e\x3b\x17\x1a\xac\x09\x1b\
+\xbf\x6a\x8d\xb6\x02\x58\xc7\x3e\x9e\xaa\x88\x45\x0e\x22\x22\x38\
+\x94\xdc\xed\xef\xb9\x60\x76\x02\xe4\x55\xe5\x91\x2f\x17\xbc\x7e\
+\xbb\xe0\xf5\x9f\xfd\x6b\xae\xf7\x25\xe9\xdd\x86\xe4\x62\xd0\x06\
+\x30\xf0\xe2\xab\x7f\x00\xc0\x4f\x2e\x66\xfc\x5f\x87\x11\x7f\xbf\
+\xb3\x82\xce\xbd\xae\x52\x3d\x86\x37\xea\x9a\xd1\x7d\xce\x74\xf5\
+\xfc\x84\xa5\x01\xc6\x83\x1b\xb2\x65\xc1\x1f\x2e\xef\x78\x51\x24\
+\x3c\xfb\xf2\x09\x97\xcf\xd7\x04\xa3\xaf\x48\xb3\x1d\xfd\x2a\x6a\
+\x05\xfe\xf3\x5c\x92\x66\x11\xc4\x21\x65\x76\xcf\xf5\x62\x4f\x1c\
+\x14\x84\x59\xc4\x7a\xb7\xa7\x9f\x45\xa6\x62\xa7\xc1\x3a\x1a\x5e\
+\x1c\xfd\x00\xf7\x46\x72\xd4\xd2\xc3\x4e\x0f\xb2\x2d\x4b\x13\x11\
+\x51\x66\xf7\x67\x17\x89\x9f\xac\xd8\x0d\xda\x32\xe6\x50\x7c\xa0\
+\x77\xd1\x65\x79\x77\x4d\xef\xa2\x0b\xcc\x4c\x05\xf4\x47\xca\xce\
+\x0e\x58\x52\x1d\x85\x79\x2a\xa4\xe9\x4c\xde\x22\xf5\x4c\x09\x67\
+\x87\xe1\xba\x3b\xdc\x20\x6d\x75\xe4\x2a\x9c\x01\x63\xd0\x90\x26\
+\x67\x2b\x75\xe7\xcb\x5e\x8d\xec\x84\x6a\x06\x3c\x5a\xfa\x8c\x46\
+\x07\xc7\xb9\x2a\xa2\x6a\x1c\xfe\x43\x51\x11\x9a\x53\x1f\xb8\x8a\
+\x9d\xef\x52\xbf\x8e\x89\x0b\x91\xd2\x27\x66\x2b\xb4\x0f\xac\x94\
+\xa4\x1f\x0c\x10\x9d\x94\x2d\x29\xa2\x39\x1d\x49\x49\x3e\x2e\x56\
+\xfc\xe2\xdf\x7c\xcf\xcb\xd7\x6f\x48\xef\x74\x2e\x20\xb9\x18\x38\
+\x20\xcf\xa2\xa7\x0c\x1f\xc2\xd7\xbf\xf6\x05\x9f\x5d\x3d\xa5\x5c\
+\xf7\x99\x87\x1e\xff\x19\x70\xb3\xdc\x33\x9e\xe9\x21\x21\xcb\xbf\
+\x79\xcb\x53\x71\x05\x8f\x61\xfd\xae\xd6\xcf\x57\x5d\x9f\x3d\x70\
+\x2f\xdf\x00\x4f\xe9\xa2\x59\xf9\xe5\xab\xd7\x04\xea\x15\xd9\xe1\
+\xef\xf1\xc5\x57\xdf\xe2\x75\x9e\x52\x25\x29\xc5\xca\x07\xfa\x6c\
+\xf7\x8a\xe7\xbe\xaf\xa7\xc5\x65\x39\xf9\x62\x45\x8e\x07\x03\xed\
+\x3b\x8d\x7b\x57\x44\x13\x75\x04\xd6\xf3\xce\x73\x21\xba\x04\x6a\
+\x6f\x8a\x32\x5e\xab\x42\xb8\x57\xaa\x76\x30\x1a\x71\xcd\xba\xf1\
+\x34\x69\x6d\x8b\xde\x15\xe1\xe6\x07\x0e\xc5\x07\xc3\xc0\xba\x5c\
+\x5d\x2e\x26\x74\x02\x78\xb8\xf8\x1e\x86\x33\x42\x7f\xeb\x7e\xcd\
+\xe3\x1d\x22\xe9\x77\x08\x0f\x44\x7a\xa2\x62\x54\xb9\xe8\x65\xad\
+\x65\x95\x03\x30\x91\x3e\xac\x67\x87\x2e\x7e\x60\x60\x7a\x34\x57\
+\xa2\x06\xb0\x6c\xed\x00\x7d\xfb\x63\x2b\xb3\xc3\x44\xc7\x13\x7e\
+\x9a\x4c\xac\x1f\xf1\xb6\x15\xbd\x7e\xa4\xb3\xc2\xa2\x6a\xa5\xd6\
+\x38\x3e\xa5\x55\xe3\xf4\x60\x34\x4f\x0b\x66\xde\x51\x1c\x55\x1a\
+\x43\xe5\x9d\x48\x8a\xe6\xc2\x4e\x29\xdd\x67\x97\x31\x44\xa9\x0d\
+\x7d\x11\xbb\xbe\xba\x9c\xd2\x81\x77\x6b\x5e\x9b\x2f\x7d\x16\x8b\
+\x0d\xdf\xfd\xe5\x1f\xf3\xd2\x2c\xc6\x2c\xfb\x5a\x30\x03\x46\x0a\
+\x3c\x06\x15\xf0\xf9\x64\x4c\x32\xd1\xc5\x85\x70\x55\x71\xff\xc5\
+\x0b\xf2\xfb\x35\x9b\xfb\x3b\xe6\xbf\x35\x63\xf9\xdd\x5b\x6e\xee\
+\xee\x19\x3e\x7e\x0a\x87\x37\xac\x6f\x71\xda\xf9\xaa\xeb\x73\xdd\
+\x90\x17\xfb\xe0\x31\xdf\xde\xbc\xe3\x2b\xfe\x94\xb9\xf7\x35\xd3\
+\x2f\xa1\x58\xfd\xc4\xc8\x81\x85\x9e\xb8\xee\x5f\x81\xc9\xe3\x86\
+\x93\x11\xd3\x46\x77\x74\x84\x72\x5d\xd2\x1a\xc0\xe9\x19\x20\x9b\
+\xd0\x8e\xb2\xc3\x0c\xdb\xcf\x49\x33\x5c\x72\x2e\xcf\x25\x8c\xdb\
+\x3a\xb6\x14\x91\x2b\x70\xd8\xad\x67\xe6\xd8\x5d\x97\x57\x3c\x0b\
+\x4a\x7a\x17\x5d\x76\x77\x7b\xc7\xc6\x37\x8b\x2f\xe8\x15\x77\x84\
+\xe5\xdf\x39\x49\xc1\x95\xa6\x33\x3b\xdd\x1e\x08\x3b\x48\x94\xf4\
+\x10\x78\xad\xc6\xce\x52\x7a\xe6\xd4\x5e\x9e\x69\xee\xd4\x95\x39\
+\xa1\xb4\x1f\xdc\xca\x50\x28\xe9\x5c\x09\xfd\xe3\x5a\x45\xa4\x41\
+\x1b\xa4\x3e\x71\xb5\x25\x13\xa7\x5a\xda\xce\x21\xb6\x47\x02\x89\
+\x47\x5c\x94\xb0\x3e\xe8\x25\x42\x3f\x6e\x2f\x10\x8e\x00\x2c\xa8\
+\x58\xd8\x40\x90\xd2\x3e\xb7\x70\x61\x9c\xc8\x01\x59\x1d\xb1\xf2\
+\x49\x2a\xaa\x31\x3c\x51\x88\xc8\x01\xd4\xc7\xd3\x41\xa0\x32\x21\
+\xa7\x64\x4b\x46\x9f\xd8\x9d\x16\x01\xe0\xe3\xe2\x3d\x2f\x7f\x71\
+\x7d\x16\xc0\xcb\x71\xc4\x78\xa9\xbf\x99\xeb\x7d\xc9\x0b\xe0\x90\
+\xbd\xe3\xcf\xfe\x48\x31\x1e\x8f\x78\xfe\xec\x21\xa3\x2f\x86\x8c\
+\x83\x29\xab\xc9\x03\x1e\x3d\x19\x72\x2b\x61\x91\x57\xa8\x59\x84\
+\xb8\x97\xdc\xdc\xc1\xd0\xb0\xf2\xf7\x1b\xc1\x28\xd4\x32\x46\x33\
+\x32\x5c\x75\x35\x23\xa7\x1f\x0a\xbe\x15\x07\xbe\xe2\x9e\xe9\x97\
+\x7f\xcb\x65\xfc\x33\xe6\x0b\x7d\x3a\xad\xfd\x62\x0d\x93\xc4\x65\
+\x90\xdb\xe7\xc0\x4b\x1b\xdf\x48\xda\x62\xde\x20\x0b\x28\xe2\xa2\
+\x35\x1a\xa0\x5c\x28\xfc\x09\x24\x71\x0d\xe4\xa4\xe1\x82\x4d\xfc\
+\xe2\x6c\x89\xb9\x05\xe4\x26\xa3\x1e\xde\x40\xe7\xb1\x63\x62\xc0\
+\x5c\xff\xc0\x20\xb8\x3a\xab\x89\xf5\x18\x81\xa4\x0e\x00\x75\xa2\
+\xca\x00\x19\x57\x72\xb6\x00\x2d\x4c\x76\x42\x33\x99\x86\x42\x3e\
+\x3f\xd0\x79\x6c\xaa\x70\x91\x30\x2c\xae\x4b\xcd\xbe\xd7\x67\xeb\
+\x7b\xa6\x25\xc9\x27\x8a\xa4\xb9\xad\xa5\x88\x46\x79\xe6\xb4\xb6\
+\x34\xef\x19\x45\xc2\x74\x2d\xeb\x56\x26\x26\x3d\x77\x68\xaf\x27\
+\xbf\xab\x23\xde\xd6\x72\xa2\xc9\xd2\x75\x7b\xbe\x0d\xc4\x47\x2e\
+\x5d\x86\x19\x46\x2d\x84\x40\x2d\x7d\x42\x3b\xab\xd8\x9c\x98\xd1\
+\x2e\xf2\xb6\xa4\x84\xca\xa3\x14\x03\x60\xa3\x47\xbf\xa2\x25\x46\
+\x5f\xc4\x6c\xc9\x88\x22\xc1\x66\xe1\xf1\xf1\xfa\x9a\x6f\xfe\xcf\
+\x6b\xfa\xd7\xdf\x90\xe6\x9d\x16\xfb\xf6\xe3\x35\x49\x38\x68\xc1\
+\xc2\x97\x37\xec\xee\x9e\xc0\xc5\x3d\x72\x79\x4f\x59\x6d\xc9\x8a\
+\xc7\xbc\xb8\x0a\x18\xc7\x43\xf0\x21\x61\xc0\x8b\x9f\x7c\xc9\x57\
+\x8b\x19\x1f\x9e\x7b\xf0\xe7\xdf\x38\x56\xfe\xe2\x9d\x96\x12\x16\
+\xc0\x76\xe7\xd0\x54\x1f\xc2\xab\xd7\x04\x4a\xff\xdb\xfb\xbf\x91\
+\x52\x15\x1b\x92\xac\x42\x7d\xf6\xd0\x2d\xec\xdc\x62\xce\x6c\xb5\
+\x17\xbc\x6b\xf9\xc8\x3e\x82\x92\x94\xf5\x4e\xc2\xae\x4e\x9b\x85\
+\xb1\x84\x18\x86\xb4\x4f\xcf\x65\x99\x78\xb9\xbb\x26\xcf\x46\x8c\
+\x9b\x55\x6a\x53\x72\xf7\x4d\xb1\x4a\x6f\x7d\xf6\x96\x5a\x3a\x4f\
+\x39\x14\xd7\x9f\xd4\xbc\xd6\x62\xb3\x16\x5d\xb3\x62\xe7\xe6\x13\
+\x07\x44\x04\x0d\xae\x2a\x90\x46\xdc\x7a\x04\xd2\xd3\x16\x9a\x05\
+\xb8\xd2\xad\x45\xba\x65\xa9\x69\x9b\x29\x67\x79\xc5\x05\x64\x87\
+\x1d\x1c\xc0\x2b\x7a\x70\x50\xd0\xe9\x21\x03\x45\x54\x98\x25\xd6\
+\x61\x07\x41\xd4\x0a\xd2\x17\xcd\x6e\x65\xdb\xd1\xa1\x38\x93\x38\
+\x6e\x6b\x60\x94\x57\x57\xf7\x8e\xc0\x5b\x7f\x91\xb2\x5e\x8c\x58\
+\x50\x5b\xcf\x58\xc4\xad\xa1\x2a\xa1\xb2\xb2\x6a\x4d\x6c\x40\xdb\
+\xa7\x5e\xec\xf5\x89\xd9\xca\x8c\xc5\x62\xc5\xcb\x5f\x5c\xf3\xc3\
+\x9b\x9f\xb3\xd8\x45\x4c\x7a\xa7\x95\xaf\x77\x79\xce\xe3\xc6\xc2\
+\xee\xbb\xdb\x03\xf0\x96\xcf\xcc\x90\xbc\x1f\xee\xde\xf2\xc3\x77\
+\x6f\xf9\xf0\xe5\x13\xaa\xbe\xc7\x2c\x18\x31\x0a\xfa\x84\x93\x11\
+\xb3\x27\x0f\x39\xa4\x7d\x5e\xfc\xe6\x13\xf8\x33\xb8\xb9\xbb\x67\
+\x35\x0b\xc9\xdf\xbe\x3c\xf9\x9c\xab\xae\xcf\xf5\xbe\xe4\xaa\xeb\
+\xf3\xed\x8d\x07\xfc\x82\xdd\xf8\x92\x8b\xb0\xa0\x1a\x4c\x1d\xd0\
+\x5c\x07\x88\xa9\xc6\xd5\xee\x44\x7d\x6e\xbd\x3c\x53\xe4\xf1\x9e\
+\x4e\x4f\x30\x31\x7e\x72\x39\xb1\x33\x2f\xbc\x06\x7b\x9f\xd7\xce\
+\x3a\x59\xd7\x37\x5d\x21\x01\x9d\x66\x17\x58\x63\x36\x47\xb7\xc1\
+\xc4\x9d\xf8\x31\x87\xe2\x43\xcb\xa5\x38\x14\x1f\xd8\x14\x77\xc0\
+\x17\xad\x79\x1e\x2d\xbf\xd9\x16\x3b\x22\x24\xdb\x48\x77\x70\x54\
+\x64\x6e\xe1\x25\x51\x26\xf7\x50\x03\xa6\x14\x1d\xc8\x34\x7f\xb6\
+\x22\x21\x91\xd0\x0c\xbb\x3e\xc0\xb0\x43\x2c\x4d\x3a\x3f\x2b\x08\
+\xed\xa9\x36\x94\x47\x66\x7c\xc4\xb8\xd3\xa3\x3a\xd3\x09\x22\xcf\
+\x74\x88\xd4\x8b\xba\xe8\x14\xcc\x06\xb8\x91\xad\xd8\x99\x57\x58\
+\xfc\x0a\x4e\xf3\x1f\xe2\x68\xa9\x7b\x5c\xbd\x2b\x44\x4a\xa0\xb4\
+\x36\x54\x4a\x12\xe2\xe9\x69\xa0\xa2\xd6\xc2\x1b\xe5\xb1\xbe\x97\
+\xbc\x7c\xfd\x86\xc5\x4e\x1f\x8a\x6f\x97\xb7\x94\xf2\x23\x7e\xf4\
+\xc0\x6d\xbf\x78\xf4\x81\x2a\x7c\xec\x18\x3a\xb9\x18\xf0\xdd\xed\
+\x81\x6c\xf9\x9a\x78\x5c\xdb\x50\xd7\x3f\xcf\xf9\xfc\x71\xcc\x9b\
+\xbb\x37\x8c\x2f\xae\x18\xce\x03\xbe\x79\xf5\x57\xae\xcb\x66\xd0\
+\xdf\x73\x73\x47\xcb\xa9\x68\x5e\x2c\x1b\x37\x81\x5c\x7c\xf3\x06\
+\xef\xc1\x67\xf4\x1e\xed\x18\x35\x2c\xb3\x34\x83\x3c\xbf\xd3\x43\
+\x5c\x76\x4b\x13\x62\x12\x80\xae\xde\xd1\xeb\xba\x41\x29\x7a\x4c\
+\x86\x76\x1c\x44\x7c\xcf\x21\x0b\x28\x9c\x8c\x48\x5d\x37\x89\x1e\
+\x68\x98\xd6\xbe\xb1\x59\xd8\x75\x6c\xf3\xa4\xcd\x93\xd8\x3c\xb5\
+\x6a\x30\xf1\x99\x8b\x05\xf4\x3e\x9b\xd6\x7e\xbc\x8a\x8f\xa4\xc8\
+\xbd\x2e\x3b\x07\x52\xb3\x58\xd0\x58\x5a\x35\xe3\x92\x4d\xc6\x45\
+\xe9\x54\xdb\x7e\xda\x21\x57\xba\xdf\xcd\x49\x04\x57\xb1\x2b\xf5\
+\xe4\x16\x33\xf8\x62\xb8\x3e\x40\xa7\x47\xd5\x8f\x89\xb7\x86\x81\
+\x2d\x78\xb6\x19\x55\xdf\x33\x59\x63\xcf\x2d\x0e\xcf\xf9\xc7\x38\
+\xcd\x6b\xd8\x3f\xf5\xdb\xc5\x12\xd1\x38\xf5\x97\x09\x17\xc5\x8b\
+\x1d\xea\x51\xd7\xc5\x4a\xad\x25\x77\x3e\xfc\xab\x35\x7f\x61\xea\
+\xfc\x96\x91\x9b\x0b\x40\x3b\xe2\x2a\xc7\x63\x7b\x7d\xcd\x87\xf7\
+\xd7\xbc\x7d\x27\x99\xf4\x72\x07\x64\x3f\x7a\xc0\xf5\xf5\x47\x36\
+\xea\x8a\xe7\xd1\x8e\x6f\xe5\x1b\x1e\x4d\x15\xf1\x44\x90\x5c\x3c\
+\x76\x52\xe3\x26\x5e\x53\xed\x1f\xd7\x8b\xb3\x0d\xfc\xf5\xf5\x2f\
+\xf4\x0e\xbe\x7c\x4b\x19\x5d\x72\xd5\x0b\x29\x67\x0f\x88\xbc\x15\
+\xb2\x1a\x11\x5e\x48\x9e\x7f\xff\x96\x25\x97\xe7\xbd\x83\xbb\x0d\
+\x3f\x0d\x0f\xbc\x1e\x4f\xb9\xea\xfa\x7c\x58\xbe\x25\x50\xaf\x78\
+\x11\x7f\x8d\xba\x1c\x73\x55\x14\xbc\x3b\xe4\x2c\x97\x7b\x67\xbd\
+\x0d\x07\x3d\xc2\x49\xd4\xee\xd7\xcb\x72\xa7\x83\x13\xe7\x03\x07\
+\x1c\x8e\x9c\x8a\x66\x55\x70\x8d\x9e\xc8\x39\x5f\xac\xc9\x83\xc2\
+\x2d\xec\x4e\x98\xd8\xc4\x4c\x5b\x4c\xfc\x23\x72\xa2\x1b\xcf\xeb\
+\x1c\xb7\x28\xcd\xe0\x43\x9b\xc7\x30\x51\x4c\x94\xc4\x13\x15\x92\
+\x18\xdb\xbe\x7f\x30\x4c\x17\x34\x2c\x14\x1b\xc7\x3c\x18\x98\xf5\
+\x85\x0e\xe4\xb4\xea\x5e\x07\x74\xf4\xb2\xd3\x00\xb6\xd5\xb6\x96\
+\x43\x27\x13\x5d\x44\x31\xe0\x97\xd2\xa3\x1f\x09\x88\x6c\x20\x3c\
+\x6a\x49\x85\x48\x19\x77\xa2\xb5\xb0\x93\x14\x89\x66\xd9\xa2\xd1\
+\x0e\xef\x6d\xeb\x10\xfc\xa4\x1f\x71\x28\x63\xca\xed\x96\x83\xa7\
+\xc1\xbb\xf5\x33\xfa\x69\x4c\xc7\x10\x71\x2e\x2a\xba\x4a\x39\xb6\
+\x6b\x9e\x1e\xcc\x56\xe2\xb4\xb4\xd0\x05\x92\x91\x57\x91\x4a\x9f\
+\x74\xb1\xe3\xcd\x56\xb2\xbe\xc5\x49\x88\x49\x2f\x87\xde\x43\x16\
+\xbb\x90\xab\x2b\xa8\xf6\x1b\xe6\xf7\x5b\xa6\xab\x29\xef\xf9\x88\
+\x2f\x1f\xf0\x70\x5c\x3b\x15\x6f\x16\x53\x9e\xf2\x8e\xbf\xcc\x73\
+\x1e\x87\x21\x3a\x81\x6b\xa4\xc1\x12\xf6\x1b\xf0\x07\x6f\x29\x77\
+\x39\xbe\xbc\x71\x39\x8b\x57\xfe\x8e\xe9\x27\xd8\x2b\xb9\x18\xf0\
+\xf3\xbb\x0d\x09\x70\xb3\x7c\xc3\x25\x4f\x79\x3f\x0e\x79\x01\xc4\
+\xdb\x15\xeb\x87\x0f\x61\x1e\x33\x1e\x6b\x54\x0d\x7b\xdd\xd3\x00\
+\x90\xb9\x6e\xa5\xc7\xf5\x42\x03\xfe\xb0\xf9\x08\x9b\x0a\x6f\x3c\
+\x64\xca\xd0\x2c\xe4\x12\x88\x77\xad\xd7\x8f\x99\x50\xb2\x3d\x62\
+\xe2\x8c\x7a\x68\x46\xdc\x8a\x6f\xde\x2d\xbf\x39\x2b\x27\x5c\x46\
+\x32\xb8\x38\x91\x21\x7a\xca\xbd\x19\x8a\x68\x27\xc5\x57\x06\xc0\
+\x56\xdf\x76\x8c\xab\x60\x59\xb6\x38\x1a\xb4\x6d\x17\x73\xba\x63\
+\xb9\xa7\x81\x2b\x22\xa2\x89\x7e\x97\x4d\xdf\xa3\xea\xc7\x8d\x22\
+\x89\x65\xdd\xd8\x2d\xe2\xaa\x7e\xec\x1a\x46\x6d\x17\xf3\xf1\x28\
+\x69\xd9\x3c\x81\x62\xc3\x33\xa6\x51\xec\xa8\xdf\xbf\x7e\xde\xcc\
+\x9c\x07\xad\x93\x14\xf8\x9e\x1d\xac\xa2\x8f\x1a\x4d\x26\x0e\x95\
+\x47\x89\x71\x30\x84\xce\x22\xe7\xa2\x72\x6c\x0c\xf5\xf4\xcc\x50\
+\x79\xa4\xd2\xd7\x67\x7f\x52\x7b\xf2\xeb\x65\xeb\x90\xbe\x10\x6b\
+\xed\x4a\x8c\xe6\x3c\x1c\x3f\xe4\xf9\xe8\x4b\xae\xae\x1e\x70\x3f\
+\xdd\x73\x58\x4d\x9d\xdc\xb0\x8c\x3d\xe9\xe5\x6c\xb3\x21\xe3\xa5\
+\x24\xbd\xdb\xf0\x2e\xcf\xf1\xb2\x77\x4e\x12\x74\x8b\x77\x7c\xef\
+\xef\x50\xd7\xef\xf8\xee\xf6\xc0\x72\x73\xc9\xcb\xd7\x6f\xa8\x6e\
+\xfc\x13\x29\x61\x59\xd8\xca\x95\xf4\x6e\xc3\x36\x1b\x72\xbd\x2f\
+\xc9\xff\xf6\x03\xdf\xbe\x3e\xb0\x54\x5b\x86\x1b\x7d\x62\x9d\xe1\
+\x24\x76\x00\xb6\x13\x36\xc9\x72\xd6\x8b\x8c\xf5\x6e\xc9\x7a\xb7\
+\x67\xbd\xdb\xb3\xc0\x67\xd8\xeb\x52\xf4\x04\x9d\xc1\x03\x3a\x8f\
+\x1e\x32\x9d\x0c\x0d\x6b\x1b\x2b\x2e\xcb\x5b\x91\xd0\x6d\xac\x65\
+\x8b\x8e\x61\x6a\x26\x3e\x2e\xd1\x5b\x39\x71\xd8\xdd\xe0\x4d\xf3\
+\x96\x7c\xb8\xde\xb5\xd7\x15\x5a\x13\x5b\x77\xca\x9e\x8b\xa5\x30\
+\x80\x16\x5a\x13\x7b\xe6\x84\x2c\xf6\x47\xde\x34\xaa\x6a\x59\xe0\
+\x9b\xfb\xda\x05\x85\x8e\xed\xac\x88\x74\xf0\xbc\xe5\xf3\x46\xda\
+\x23\x26\xaa\xbd\xe7\x28\xaa\xb4\x53\x71\xb6\x25\xa9\x2e\x26\xe3\
+\x3a\x38\x4c\x00\x47\x79\xad\xb3\x82\xfe\xd8\xa5\xd7\x8f\x38\xa4\
+\x81\x3e\x59\x49\x30\x45\x71\x40\x50\x19\xd0\x6a\xbf\x59\xdb\x75\
+\x95\x63\x61\xbb\x80\x13\xce\x58\x0e\x40\xe4\x46\x0f\x9f\x9f\x9e\
+\x99\x2e\x76\xac\xd3\x2d\x2f\x5f\xbf\xe1\xed\x3b\xa9\x0d\x9e\xd1\
+\x9c\xd9\x4a\x91\xaa\x0d\x4f\x2e\x1e\x33\x7b\xf0\x94\xd1\x2c\x24\
+\x7f\x1b\xd1\x79\x27\x39\x74\xdf\xd7\x3b\x9e\x7c\xcf\x62\x24\x60\
+\x35\x6d\x2d\x04\xc7\x4b\xc9\x96\x21\x64\x1a\x88\xd7\xfb\x12\x6e\
+\x7c\xbe\xbd\x5b\x91\x5c\x0c\xf8\xe1\xcd\xcf\x1d\x40\xcf\x31\x70\
+\x13\xcc\xcd\xeb\x3f\xc4\x92\x70\xf9\x96\xcd\x5d\x87\x95\xe8\x13\
+\xf7\x2e\x59\x54\xfa\x2c\x2a\xc1\x22\x33\x1d\x29\x99\xcb\x3b\xc7\
+\x41\x8f\x4d\xa8\xc9\x68\xc6\x84\x32\x5e\x31\x01\x7c\xae\xf4\x18\
+\xab\xc3\x52\x0f\x67\xc9\x72\x73\xb6\xd3\x94\xb7\x59\xc2\x73\x3c\
+\x37\x11\x6e\xb8\xf4\x60\x3c\x82\x65\x49\xe7\x51\x55\x47\x52\xdd\
+\x11\xae\x66\xe3\xe1\xa2\x03\x9d\xa7\x80\x96\x13\x57\xbd\xb6\xf9\
+\x19\x6f\x1e\x34\x18\xbc\x31\xb0\x51\x94\x28\x15\xe8\xb2\xb3\x88\
+\x22\xbc\x6d\xd9\x0a\xe8\x34\xcb\xc3\x75\xa5\xad\x6a\xb4\x14\xe9\
+\xdb\xce\x0f\x36\x80\x2b\x90\x6c\x81\x81\x99\xf8\x33\x28\x2a\xb2\
+\xc0\x73\x85\x0f\x3b\x7f\x4d\x7a\x99\xfe\x0c\x13\x78\x2f\x0c\x80\
+\xb7\x48\xfa\xca\x7c\x8a\x01\xef\xa7\x7b\xdd\xda\xee\x84\x12\x11\
+\xba\xe6\x56\x72\x6f\xd4\xdb\x71\x35\x4f\x9f\x0e\x2c\x72\xcc\x5a\
+\x11\xb3\xb3\xc3\x01\x8d\x26\xd6\x3a\x58\x5b\x6c\x42\x44\x4e\x07\
+\x5b\xe0\xef\xd5\x9e\x0f\xef\xaf\xf9\xe3\xbf\x0a\x98\xde\xbf\x61\
+\x5e\xcd\x99\xfa\x8a\x1f\x4a\xc1\xd4\x7f\x03\x7f\x03\xcf\x3f\x7f\
+\xca\x17\xc5\xd7\xdc\x5c\x96\x78\x79\x07\x5e\xb5\xff\xe4\x89\x1a\
+\xb2\x30\xec\xdd\x04\xb3\xf5\x94\xdf\xe5\x39\x95\xfa\xc0\x44\x0d\
+\x5b\xc0\xb4\xdb\xc5\x2e\x74\xaf\x59\x88\x35\xdc\x81\xbf\xbb\xe5\
+\xde\xec\x1c\x33\xde\x53\xf6\xf4\x2c\xb5\x67\xfb\x88\x6c\x59\xb0\
+\x7b\xbb\x64\x79\xb1\xa5\xea\xcc\x49\x3f\xe8\xf7\x19\x8f\xc7\xe6\
+\x7b\x89\xdd\xf9\xa8\x75\x37\x5d\x69\xec\xb8\x7b\xb0\x45\x8c\xf8\
+\x9e\x74\x65\xf3\x17\xd6\x17\xd6\x79\x8b\x60\xa7\xa0\x17\x39\x97\
+\x63\x3d\xae\x18\x2e\x4b\xaa\xe1\x86\x43\x36\xa2\x13\x17\x0e\xc0\
+\x3a\xca\x99\x02\x31\x5d\x21\xf4\x74\xa2\xe6\x02\x75\x97\xb7\x80\
+\x9c\x0d\x3e\x12\x96\xbf\xd6\x98\x2e\xea\xb9\x4e\x99\xd5\xfa\x4e\
+\x0f\xd9\xde\x42\x9d\x0b\x3e\xec\x5a\xb3\x82\x2d\x1b\x47\xad\x13\
+\x82\x73\x02\x78\x54\xed\xd5\xf6\x8f\x78\xb6\x5f\xc6\xee\xf5\x11\
+\xb8\xe1\x80\x7d\xd3\x7a\x14\x89\x8a\x3e\x7a\x28\x76\xdf\x76\xd4\
+\x99\xb3\x7c\x5a\xcb\x2c\xfa\x31\x36\x6e\x9e\x3d\xf4\x4c\x1f\xb5\
+\x70\x27\xe5\x3e\x75\x42\x9a\xd5\x3a\x65\xd8\xa1\xc9\xd0\x4d\x00\
+\x2b\xe5\xb1\x59\x6a\x16\x5e\xdf\xc2\xb3\xe1\x96\xde\x65\x40\x35\
+\xeb\x43\xf5\x88\x72\x5b\x70\xb7\xee\x30\x5f\x49\xfe\x8f\x3f\xff\
+\x53\x7e\xef\x5f\xfc\x3e\xdf\xfe\x6f\x7f\x42\xa5\x4e\x75\xde\xed\
+\xf2\x96\x19\xef\x5b\x00\x5e\xec\x42\x57\x14\x99\x7e\x78\x0d\xab\
+\x5a\xf9\xfa\xbb\x5b\x16\x62\xcd\xed\xf2\x16\x7f\x77\x5b\xdf\xb7\
+\x0b\x99\xad\x14\xb7\xcb\x5b\x6e\x24\xb0\x9a\x72\x90\xef\xdd\xe3\
+\x00\x3f\xcf\x3b\x5c\xef\x4b\xde\xa7\x1f\xd9\xdc\x7d\x44\xca\x1d\
+\x62\xdc\x65\x3c\xee\xba\x93\xa9\x0f\x27\x71\x3b\x58\x7f\x54\x81\
+\xb3\xb7\xab\x24\x35\xce\x86\xe4\xcd\xbb\x35\x2b\x33\xde\x3e\x0e\
+\x0a\x37\x99\x33\x37\x33\xde\x18\xfb\x78\x8d\x3c\xf1\x69\x97\x78\
+\x8d\xb3\x66\x69\xfd\x3c\x51\x95\x4e\x4e\x08\x2a\xe7\x13\x87\x61\
+\x04\xc3\x0a\xdf\xe6\x26\xb4\x7e\xd5\xa3\xa8\x2c\x38\x5d\xde\xb7\
+\xd1\x91\x71\x0c\xe0\xbe\x95\x00\x46\xd3\x7a\xdb\x86\x5d\xd5\x8f\
+\x29\x92\xf4\x44\x40\x44\x46\xe3\x44\x06\x84\x5b\x03\x58\xe9\xca\
+\xd3\xf5\x4e\x11\x35\x18\x59\x8a\x7a\x28\x9f\x2e\x8c\xf4\x5c\xce\
+\x58\x77\x36\x47\x35\x3b\x37\xec\x35\x7d\x52\x6e\x79\xb6\xdf\xaf\
+\x9e\x12\xd4\x5c\xc8\xb5\xf5\x70\x6e\xce\x46\xaa\xa4\xe2\xc3\xc7\
+\x90\xbf\xdc\xd4\x3e\xed\xa3\x6e\xc4\x7c\xf6\xcb\x78\xcf\x47\x5c\
+\x0c\x1e\xc0\x60\x82\x2f\xfe\x3e\x9b\xad\xe0\xc3\x12\xb6\xff\x77\
+\xca\xfb\x7d\xdb\xdb\xee\x44\x8f\xda\x00\x6d\x58\x74\x8b\x5d\xa8\
+\x01\x69\x80\x7d\xbb\xbc\xe5\x9e\x47\x1c\x6e\x14\x9d\x4b\xc1\x8d\
+\xd4\x92\xa4\xb9\x75\x55\xae\xf9\x37\xda\xf9\x90\x70\x3f\x12\x0e\
+\xc8\x5e\xf6\x8e\xf7\x66\xfe\xc7\xa3\xd0\x23\x16\x25\xc3\xde\xb8\
+\x35\xe8\xdb\xe9\xda\xc6\x22\x2d\xcd\xf4\x54\xcd\xd5\x5a\xb2\xde\
+\xed\xa9\xde\x0e\x59\xef\xf6\xb0\xd9\x13\xc6\xc2\x9d\xfd\x29\x2b\
+\x02\x86\x04\x24\xb1\x9e\x32\xf4\xe9\x4b\xbd\xb8\x6b\x4e\xa8\x1f\
+\x3e\x3c\xcf\xc2\x1f\x96\x6f\x19\x04\x17\xe4\xfb\xf3\xdd\xe4\x93\
+\xe9\x4c\x4f\x00\xa2\x15\x93\xdc\x9c\xd8\x5b\xda\xf6\x92\xad\x06\
+\xd1\xe3\x92\x71\xe1\x16\x5c\x7a\x12\x4f\x16\xf8\x66\x52\xbc\x96\
+\x17\x52\xaa\x76\x89\xc2\x02\xce\x16\x0f\x84\xce\x58\x34\x83\xe8\
+\xf2\x18\xf6\x8d\x94\x5c\x6d\xb3\xed\x1c\x08\x95\x63\x62\xd9\x38\
+\x97\x88\x57\x6f\x8f\x00\x9c\x37\x66\xac\x7d\xea\x62\x99\x3a\x37\
+\x9f\xbb\xbe\x97\x70\x78\xc3\x78\xa9\x6d\x35\x0b\xc6\xab\xce\xdf\
+\xf2\xa8\x1b\x39\x66\xfe\xc9\x8b\x9c\xe7\x83\xc7\x9a\xa5\xcf\x79\
+\xa0\x0d\xf0\xdd\x48\x98\xf1\x9e\x83\x7c\x4f\x27\x7a\xe4\x98\xf4\
+\x20\xf5\x7d\x97\x11\xf5\x7d\x37\xaa\xf1\x3b\xe8\x1c\xee\xee\xa6\
+\x70\x5b\x3f\x7a\x50\x7f\x86\x79\xae\x05\xf2\x68\xb5\xe3\x4d\xea\
+\xb1\x54\x5b\x53\x23\x50\xba\x7d\xc9\x53\x0c\x2b\x41\xd6\xf1\xf4\
+\x18\xd8\x5c\x32\x5f\xac\xdd\xe2\x2e\x0e\x0a\xe7\x64\x6c\x63\xc9\
+\xb0\xd7\x25\x9c\x8c\x18\x4e\x62\x9e\xf4\xea\xef\x74\x4d\x41\x90\
+\x05\x84\xc3\x01\x43\x82\xda\x1f\x3e\x26\x8d\x46\xa1\x62\xd3\xd1\
+\xad\xfd\xeb\xdb\x1a\xc0\xea\xf5\x77\xad\xc5\x9d\x5b\xd8\x99\x69\
+\xf6\xd6\x27\x46\x94\xae\x62\xd7\x3a\x19\x42\xdc\xe9\x59\x5b\xa0\
+\x96\x0a\x26\x0b\x61\x2f\x76\x8c\x6b\x33\x3f\x1c\xb4\xc6\x4e\xe9\
+\x05\x62\x91\x94\xce\xff\x2d\xa2\xaa\xb5\x23\x1c\x27\x3e\xb7\x4a\
+\xd1\x17\xa2\xa5\x7f\x23\x23\x31\x4e\xcb\xcd\xb4\x2a\x7c\xee\xac\
+\x49\xcd\x8e\x0e\x57\xe9\x10\x66\xc4\x54\xd5\xaa\xda\xb5\x98\x56\
+\x14\xc0\x96\x24\xeb\xb6\xc1\x7d\xec\x94\xd8\xe2\xcd\xad\x66\xc8\
+\xc5\x4e\x2f\xe8\x2e\x23\xe8\x5c\x8a\x16\x33\x03\xdc\x4f\xf7\x0e\
+\xd8\xf6\xbe\x73\x60\xb6\x40\x6e\xde\x6e\x5e\x9a\x4c\x6b\x19\xbd\
+\x94\x1f\xb9\x09\xfa\xad\xfb\x7b\x97\xc1\x09\xe3\xdf\x48\x28\x7b\
+\x0f\xd9\x66\x43\xfe\x62\x71\x8d\xc8\x7f\x41\x55\x4d\x11\x87\xc8\
+\xb5\x28\x59\x40\xeb\xef\xcc\x1c\x8d\x62\x41\x1c\x14\x3a\xaa\x19\
+\x46\xae\x48\x72\x35\xe9\xd6\x7e\x72\x83\xb1\xe3\xa0\xd0\xc5\x8e\
+\xd8\x33\x1e\xb3\xe0\x90\x05\x7a\x56\xdb\x27\xba\x43\x40\x37\xa5\
+\xde\x2d\x17\x6e\x41\x77\xbd\xcb\x59\x5c\x3e\x6f\xb1\xb1\xb3\xd8\
+\xcc\x6f\x6a\x7d\x62\xd7\xd9\xe1\x98\xb8\x59\xac\x50\x52\x83\xb0\
+\xb1\xb8\xeb\x9b\xd6\x9b\xe2\xf8\x7c\x1e\xa2\x72\x9a\xb8\x99\x47\
+\xab\xfa\x5e\xad\x8f\x1b\x92\x44\x36\xb4\xae\x34\xe0\x75\x5a\xf8\
+\xa8\x25\xc8\xb9\x18\x6a\x61\x2a\x72\xf2\x13\xba\xf8\x4c\x19\xda\
+\x4a\x04\x25\x99\x05\x5d\xed\x3e\x28\x69\x16\x7f\x38\x76\xdd\x39\
+\x9d\xd6\x27\x8d\xf7\x27\x72\xa2\x09\xea\x7b\x29\xf9\xf0\xfe\xda\
+\x49\x89\x83\x7c\xcf\xeb\x1f\x16\xbc\x9f\x7f\x6c\x31\x64\x13\xcc\
+\x16\x54\x96\x2d\x8f\x41\x66\x6f\x37\xc1\xb9\xbb\x29\x78\xbf\x97\
+\x6e\x5b\xca\x8f\x6e\x3b\x9b\x77\xdd\x73\xed\xf5\xe6\x4e\x62\x3f\
+\xd3\xb2\xb4\x95\x28\x76\x81\xb7\xbd\xa9\x48\x8b\x1d\xf3\x62\xa7\
+\x4f\x24\x49\xe6\x66\x28\x5b\x67\x22\xeb\x78\x9a\x6d\x2d\x78\xe3\
+\xd0\x69\xe3\x34\xd3\xe0\xb5\xb7\x8b\x58\x83\xb7\x79\x5e\x11\x9d\
+\x5b\x6e\x58\x94\xe5\x4a\x77\xff\x64\x01\x90\x11\x64\xca\x1c\x21\
+\x33\x3a\xbd\xcb\xb3\x0b\xba\x0f\x4b\xdd\xb0\xf4\xd9\xf8\x09\x9b\
+\xe2\xae\xdd\x63\xd7\xc8\x61\x58\xb9\xe8\xdb\x1f\xdc\x95\x7a\x85\
+\x96\x04\xc1\xd1\x02\x6f\x6b\x40\xe9\xce\x9a\x74\xd4\x56\xa4\xdf\
+\xa7\x1d\x75\xdf\x1a\x95\xdb\x5c\x00\xda\xfb\x11\x95\x5b\xdc\x6d\
+\x1b\x8b\xb4\x02\xc9\x20\xfc\x8e\x87\xe1\x77\x5c\xc9\x3f\xe0\xaa\
+\xfa\x23\xbd\x95\x7f\xc0\x17\xf2\x0f\xce\x80\xb6\xbd\x60\xd3\x80\
+\xf5\x98\x65\x26\x8c\x53\xec\x48\xb2\xae\xfe\xe2\xcc\xde\x9c\x8b\
+\x8a\xb0\xb5\x43\xd4\x4c\x7c\x96\x8d\x8f\x80\x6d\x19\xd3\xbb\xdf\
+\x72\x58\x4d\xb9\xbe\xfe\x78\x02\x9e\x26\x2b\xf7\x2e\x83\xd6\x6d\
+\x0b\x44\x0b\xba\x47\xdd\x88\xdd\x4d\xc1\x61\x35\x75\x0c\x0e\x70\
+\x59\x6c\xf1\xa3\x07\xcc\xe6\x5d\x6e\x82\x3e\x9d\xd1\xdc\x5d\xff\
+\x14\xc3\x3f\xea\x46\x2d\x59\x71\x69\x9e\xf2\x43\x57\x7f\xe6\xc7\
+\x77\x5b\xd4\x72\x6e\x16\xad\x71\x6b\x01\x1c\x86\x91\x9b\x2c\xe4\
+\x16\x79\x59\xee\x0a\x1f\x55\x92\xb6\x16\x7b\x36\xe1\x36\x24\x30\
+\x27\x82\x84\xf5\xe6\x70\x32\x4a\x20\xc8\xb4\xbc\x50\x24\x0d\x99\
+\x11\xbb\x93\xd6\x58\x26\x6e\x82\xf7\x7a\x97\x13\xa8\x57\xec\xb3\
+\x69\x5b\x13\x1f\x9f\x17\x05\x08\x2d\x70\x20\x72\xbe\x6e\x3d\x0c\
+\xbb\x06\x68\xdf\x36\x6c\x46\xed\x2f\x4e\xdb\x64\xb5\x08\xd0\x0f\
+\x6b\xef\x37\x10\xc2\xcc\x1f\xae\x08\x54\xd4\x38\xac\xdb\x05\x9d\
+\xb6\xd9\xfa\x4a\x4b\x87\xad\x52\x7c\x5d\xfd\x11\xdf\x7f\xf7\x03\
+\xbf\xc6\x3f\x6f\x7d\xce\xe8\x57\x61\xf5\x6f\xe1\xea\x19\xcc\x57\
+\x5f\xb1\x0f\x3f\xd3\x96\x9a\xeb\xb9\x33\x21\x24\xa1\x13\x77\xf3\
+\xed\x1c\xdf\x4c\x90\xdf\x99\xf3\x8e\x1e\x33\x71\xcb\xff\x8d\xf7\
+\x66\xf4\x95\x70\xe5\x66\xcb\xca\x12\x49\x59\x64\xac\x6f\xe1\x71\
+\x18\xf2\xd6\x68\xd7\x6a\xd6\x67\x7e\x3f\x67\xea\x4d\x99\xdf\xcf\
+\x39\x78\x53\x3a\x68\x20\xdf\x04\xfd\x13\x90\x59\x0d\xfd\x88\xf7\
+\x0e\xcc\xb3\x79\x97\xf7\x53\xc9\xe5\x68\xcb\x4d\xd0\x77\xb7\x67\
+\x68\xb0\x5e\xca\x8f\xdc\x4f\xfb\x06\xf0\x30\x6b\xec\x0c\xcd\xf7\
+\x3d\x27\x45\xac\xa4\x78\x68\x54\xe2\x7b\x15\xf2\x2b\x71\xce\x78\
+\x3c\xd5\xa3\x18\x7a\x42\xcf\x76\x43\xb9\x59\x16\xf1\xa1\x22\x18\
+\x95\x78\x69\x52\x4b\x06\x03\xe6\x7e\x95\xd4\x21\xa2\x58\xe7\x62\
+\xc8\x20\xcf\xb7\x4c\xb3\xbe\xcb\x2b\xbb\x35\x85\x3f\x72\x92\x42\
+\x19\x3d\x6c\x2d\x36\x45\xd2\x38\x93\x93\x61\x62\x03\xde\x0f\xcb\
+\xb7\x5c\x8d\x9f\xf0\x76\xf7\x84\x17\xf1\xfc\x14\xc0\x26\x47\xe1\
+\x02\x41\x91\xd0\x91\xca\xed\x51\x91\xa3\xa5\x1f\x0d\xe0\xa4\x39\
+\x31\xe3\xb1\x47\xdb\x5c\x74\xe9\xbe\xbc\xa8\x15\xce\x29\x8c\x2e\
+\x2d\x94\x02\xe5\x11\x08\xd1\xf0\x89\x8d\x3b\x61\x98\x7e\xfe\xb1\
+\x38\x01\x30\x68\x00\x03\x24\x3f\xfc\x2e\xcb\xd5\xff\x4e\x37\xfb\
+\x43\xae\xaa\x3f\xa2\x77\xfb\xaf\xb8\x92\x7f\xa0\x65\x07\x92\x37\
+\xd7\xd7\x2c\xae\xaf\x5d\xa2\xae\xea\x7b\x2e\x5c\x6f\x83\xf1\x16\
+\xc0\xa1\x68\x9f\x69\x5e\x34\x0a\x21\xb9\xf2\x50\x4a\x91\x1b\xf6\
+\xbe\x5b\xea\x0a\xdd\xbb\x3c\x77\x8b\xba\x47\xdd\x88\xab\xab\x07\
+\x6e\x41\xd7\xbb\x0c\x9c\x56\xfd\x14\xd0\xec\x02\xce\x3e\xc7\x32\
+\xef\x61\xd5\x2e\x26\x77\x46\x73\x2e\x8b\x1a\xd8\x56\x4e\x58\x56\
+\xb7\x2c\xdb\x89\x1e\x69\xbb\xee\x13\x97\xcb\xa8\x5e\xdc\x7d\x36\
+\x7e\x42\x34\x11\xf8\xa2\x64\x1a\xf4\x18\xe4\xa9\x1b\x4e\x68\xe7\
+\x23\x03\x1a\xc0\x86\x79\x01\x2a\x4f\x03\x71\xeb\xa5\xee\xfe\xe6\
+\x49\xd6\xed\xc2\xae\x5e\x8d\xed\x9d\x94\x68\x6e\x15\x89\x91\x13\
+\x89\x73\x27\xe6\xe6\x24\xe7\x96\x89\x7d\x79\xe3\x98\x78\x72\xf3\
+\xba\xd6\xc4\x67\x2a\xb6\xd8\x28\xa6\x34\x4c\x1c\x34\x67\x12\x5b\
+\xa0\xba\xd3\xde\x4a\xe3\xe1\xd2\x6e\xf8\xb4\xaf\x55\xb5\x7b\x10\
+\x99\x96\x7f\xf7\x9e\x06\xb4\xf5\xb6\x7d\x98\x8e\x44\xc5\x42\xbe\
+\xe7\x4a\xea\x39\x0c\xf3\xee\xbf\xc7\xe8\xcb\x1a\xb4\x2d\xcd\xfe\
+\x52\x11\xbf\x10\x7c\xf9\xf2\x7f\x21\x7e\x21\xe0\x07\x13\x50\xf9\
+\x01\xbe\xe2\x77\x79\x13\xfd\xb7\x26\xe0\x08\x1f\xd7\x01\xdd\x87\
+\xbf\xc9\x58\x3c\xaa\xa7\x55\x9e\xe9\xf0\x68\xc6\x32\xed\x8e\x9b\
+\x2b\xcf\x65\x34\x6e\x17\x92\xb7\x77\x8a\x97\x6f\xdb\x83\xfb\x26\
+\xbd\xdc\x55\xde\x00\x9e\x9b\xaf\xef\x37\xa2\xf7\xdc\xf3\xa5\x73\
+\x16\xee\x47\x82\xd9\x4a\x71\x3f\x9a\xf3\xb0\xf7\x90\x85\x58\x73\
+\xb8\x79\xdf\x3a\xfc\xef\x6e\x0a\xee\xa7\x7b\xb7\x20\x9c\xcd\xbb\
+\xdc\x4c\xfb\x78\xf7\x5b\x2e\xc7\x5b\x6e\xa6\x7d\xa0\xcf\xcc\xb0\
+\xf7\x65\xa1\xff\x96\xf7\x12\x6e\x02\x3d\x69\xbd\x33\x14\x1c\x56\
+\x53\x7a\x97\x81\x4b\xd0\xe9\xfc\x59\x0d\xf2\x40\xbd\xc2\xdb\x3e\
+\x61\xb7\x93\x94\xbd\xb8\x35\x03\x19\x30\xed\x4c\x0d\x26\xad\x46\
+\x3a\xee\x64\x40\xdd\xdc\xda\xa2\x87\x1d\x45\x8b\xe9\x14\xc9\x73\
+\x09\x9b\x3d\x6b\x0a\x06\xe8\xb1\xb3\x76\x7e\xb2\x3d\x4f\x88\x6d\
+\x2a\x3d\x89\x70\x46\x97\x4e\x13\x5f\x8d\x9f\xf0\x61\xd4\xab\xa3\
+\x98\x67\x4a\xd7\xee\x77\x44\x08\x02\x75\x6c\x7f\x09\xe7\x32\x64\
+\x52\x21\xa9\x4f\xba\x58\x34\x7c\xe4\xbe\x10\xe6\x40\x6d\x2b\x6b\
+\x5a\x46\x38\x96\xc5\x04\x77\x94\x4e\x95\x79\x32\x23\x2a\x04\x15\
+\x86\x7d\x8d\x84\x78\xd6\x81\xe4\xbb\xdf\xd5\x9f\xf1\xec\x9f\x38\
+\x00\x5b\x09\x61\xc1\x6b\x81\x7c\x0c\x6a\xbb\x7d\x2a\xff\x7b\xf7\
+\xf8\xf2\xc5\x7f\xc5\x68\xf7\x15\x8a\x47\xda\xa5\x68\xe9\x66\xdd\
+\x8a\xe4\xe6\xa6\x19\x0f\xd9\xc9\x0d\xa5\xe8\x89\x29\xd1\xa3\x29\
+\xdd\xf9\x8a\x57\x7f\xfd\x3d\xa3\xfb\x25\xf7\xa6\x3c\xdc\xac\xbc\
+\xd1\xcb\x5d\xe5\xed\x20\xdf\xa3\x55\xde\x7b\xae\xaf\x3f\xf2\x6e\
+\x5b\xe0\xf7\x03\x0e\x57\x0f\xb8\x44\x11\x4f\x60\xd9\xfd\x8c\xce\
+\xe5\x07\x58\x4d\x79\xbd\xfa\xce\xb1\xb1\x5d\xac\x35\x81\xdc\x19\
+\xe3\x98\xb8\x33\x9a\x73\x33\xed\xb7\x00\x0e\x50\x6d\x57\xcc\xfb\
+\x02\x96\x50\xcd\xf6\xcc\x6e\xba\xf4\x2e\x1f\x38\x16\xbe\x91\xef\
+\xb9\xbf\x14\x4e\xfd\xce\xc6\x25\x1d\xff\x0e\x8f\x08\x3d\xc5\x2a\
+\x26\x0c\x23\x27\x25\xf4\x64\x7a\x13\x5e\x7f\xd7\x67\xc9\x9a\xe1\
+\xa0\x43\x18\x46\x0c\xca\x2d\x8b\x55\xc1\x6a\xb9\xe1\xbb\xa5\xc7\
+\x78\x5c\xb1\xac\x0a\xc6\x5e\xe0\xba\xf3\x96\x4b\x8f\x07\x55\xc5\
+\x43\x42\x16\x14\x84\xf3\x94\xce\x68\xe8\xf4\x73\x1d\x28\xcb\x5a\
+\x79\xe4\xeb\xa3\xa0\xd3\xb1\x3b\x51\xf7\x4c\xc6\x6d\x30\xaf\x3d\
+\xfc\x63\x8a\xce\xf0\x35\x90\x27\x3a\x3e\xe9\xca\xcd\x51\xbd\xea\
+\xb7\x20\x95\x8d\xa0\x4e\xd4\x00\x30\xc6\x3b\x8e\x1a\xa7\x24\x00\
+\x5c\x20\x9e\x46\xd8\xa7\x0f\x6c\xf2\x47\xfc\xe9\xb3\x7f\xca\xe8\
+\x57\xe1\xd1\xf0\x77\x4f\x24\x44\x13\xa8\xe7\xc0\xdc\xbc\x6d\x1f\
+\xff\x35\xfe\x39\xd3\xd1\xb7\x34\xcf\x34\xda\x3e\x12\x79\x47\xb7\
+\xdb\xef\xf7\xd3\xab\x47\xfc\xd2\xc3\x2f\xf8\x8d\x5f\xfa\x75\x7e\
+\xe7\x77\xfe\x4b\x56\xb3\x90\x77\x79\x4e\x3f\x5e\xb7\x42\x3f\x00\
+\x4f\x7d\x78\xf2\x38\xe2\xdf\xff\xb5\xdf\xe6\xeb\xdf\xfe\x4f\x98\
+\x7e\xfe\x9f\xf2\x1f\xfd\xce\xef\xf0\xdb\xff\xdd\x7f\xc3\xb3\x2f\
+\x7e\xc6\xdf\xbe\x0c\xf9\xc3\x9f\x87\x7c\xff\x5e\x31\x5e\x4a\x3c\
+\xf1\x59\x4b\x72\x58\x66\xb5\x60\x76\x7a\x36\xe8\x73\x59\x6c\x5d\
+\x88\xc8\x5e\x9f\xcd\xbb\x54\xb3\x3e\x53\x6f\x8a\xdf\xd7\x00\x9a\
+\x7a\xd3\x13\x0f\xf9\x9e\x47\x3c\x1c\x3f\x74\xe5\x6b\xfd\x47\x57\
+\xf4\x47\x5f\xe9\xe7\xa9\xbe\x9e\xef\xb6\x5b\x12\xcf\x77\xac\x37\
+\x07\x0e\x1f\xef\x79\xfd\xc3\x2d\xab\x37\xf7\xbc\x5c\x7c\xcf\x76\
+\x7f\x07\x1b\xed\x1f\x6f\xfc\x3e\x6b\x3c\x96\x4b\x8f\xd2\x68\x7f\
+\x7b\x26\xd0\x65\x55\xb0\x5c\x7a\x1c\xe6\x4b\x3e\x7a\xfa\xbb\x9d\
+\x8c\xf4\xdf\x76\x58\x79\x14\x71\x61\x1c\x8a\x76\xcf\x9e\x23\x84\
+\x9b\xd7\x94\xd1\x25\x65\x74\xc9\xe4\xe6\xb5\xf3\x8a\xad\x4f\x2c\
+\x5a\xf6\x5c\xe6\x16\x8c\x7a\x8c\x55\x53\xdb\x02\x3d\x95\x91\x89\
+\x18\x5f\x35\xa6\xfb\x98\x98\x64\x60\x9e\x13\x08\x71\x54\xf6\xad\
+\x90\xaa\x06\x70\x20\x84\x9b\xa1\x66\x27\xf8\xc4\x45\xd5\x2a\x61\
+\x7b\xdb\x0a\xb6\xd2\x55\xf6\x22\x35\xe1\x3d\xff\x84\x47\xc3\xdf\
+\x75\x0c\x7c\x8e\x71\xdd\xc2\xf9\x08\xcc\xf6\xf6\xf1\xf5\x41\xfe\
+\x3d\x9b\xfc\x57\x8d\x8f\x6c\x22\x97\x94\x27\x76\x9d\x95\x1b\x5b\
+\xb5\x60\xb0\x6d\x3f\xf6\x60\x1c\xf0\x54\x5c\xf1\xea\xc3\xcf\xd9\
+\xf6\x86\x75\xeb\x51\xfc\x18\xfa\x70\xd9\x1d\x21\xfe\x2e\x7c\xfd\
+\xac\x47\x67\xf6\x80\xc7\x0f\xea\x91\xa4\x6f\xff\xf3\xff\x9a\x5f\
+\x7c\xf3\xcf\xf8\x97\xbf\xf7\x27\xfc\x3f\x3f\xbf\xe5\x5d\xfe\x97\
+\x3c\xfe\xfa\x92\x87\xe3\x87\x2c\x46\x82\xc3\x8d\x72\x8b\x40\x2b\
+\x2b\x66\x8b\x3b\xee\xa7\x17\x8e\x75\x67\xf3\x2e\xf7\xd3\x3d\x97\
+\x05\xee\xba\x77\xbf\xe5\x7e\xa6\x65\x86\xd6\xce\x7b\xed\x66\x5c\
+\x3e\x00\x1e\x98\x00\xcf\x7b\x6e\x96\xf0\x70\xfc\x90\xcf\x86\x07\
+\xde\xab\x90\x17\xc5\x1d\xd5\xeb\x19\xde\xf2\x9e\xc5\x66\x06\xa3\
+\x1c\x56\x21\x25\x1f\xb9\x9e\xc3\xd5\x14\xa6\xe3\x0b\x18\x78\x3c\
+\x0f\xc6\x30\xe8\xba\x12\x6f\x9e\x4b\xa6\x93\x21\x17\x93\x17\x6e\
+\x42\xd0\x33\xcb\xf0\xe6\xc4\x8f\xeb\xdd\x03\xe2\x4c\xa2\x26\x5a\
+\x72\x0c\x67\x03\x9d\x68\xdb\x6e\x29\xfa\xfd\x86\xab\xd1\xee\x0c\
+\x59\x5c\x3e\x67\x7d\x0b\xcf\xcb\xd7\xce\x2b\x56\x37\xbb\xb6\x26\
+\x76\x85\x12\x9d\xc3\xe8\xc4\x45\x7d\xf6\x24\x0b\x60\xcb\xb0\xb1\
+\xd2\xfe\x6f\xd1\x00\x6c\xa0\xa2\xf3\xb6\x93\xd5\xc2\x8d\x60\x50\
+\x64\x16\x82\x36\x47\xe1\x6d\x2b\xb2\xc3\x0e\x2f\xa8\xf0\xb6\xc6\
+\x37\x6e\xb4\x2a\x79\xdb\x8c\xbc\x1f\xf1\x0b\xfe\x21\xac\x39\x01\
+\xb2\x05\x65\x13\x9c\x4d\xf0\x66\x2f\x55\x4b\x72\xb8\x7d\xfd\x87\
+\xdf\x65\xfb\xe5\x3f\x25\x1c\x97\xe4\x4b\x0f\xc4\xe9\x79\x3b\x74\
+\xdf\x5d\xec\x5c\x8e\x3e\x11\x1f\x56\xaf\xd8\x7a\xb7\x88\x43\x42\
+\xd5\x19\x51\x36\xce\x67\xb1\x10\x6b\x9e\xfa\x75\x4b\xd0\xcd\x34\
+\x87\xb9\x8f\xff\x2a\x60\xf9\x17\xff\x8a\xde\xd5\x13\x66\x2f\x4a\
+\x61\xbb\xb5\x57\x00\x00\x20\x00\x49\x44\x41\x54\xae\xa2\xa7\x8c\
+\x7e\xeb\xa7\x5c\x7c\xf9\x1d\xbf\xfe\xe2\x1f\xf1\xd5\x97\xff\x90\
+\x3f\xf9\x9f\xff\x57\xfe\xa7\x7f\xf6\x47\xbc\xfb\xc5\x5b\xf8\xfa\
+\xd4\x53\xbe\x1c\x6d\x99\xcd\xa7\x0e\xc0\x96\x99\xf5\x22\xcf\x30\
+\xf3\x68\xce\x6c\x3e\xa5\x33\x06\xcc\xc2\xaf\x66\xf5\x48\xeb\x70\
+\xf4\x22\xf2\x9e\x47\x5c\x46\xef\x29\x81\x9b\xfc\x73\x7e\x63\xb5\
+\xe3\xe3\xea\x5b\xf6\xd9\x94\x0f\xd5\x82\x08\xf8\xdc\x9b\xc2\xb8\
+\xc2\x1b\x7f\xc1\x97\x9f\x4f\xd8\xc6\x92\x7e\x16\xb5\x86\x77\x5b\
+\x00\xd7\xdb\xfb\x56\xe3\x28\xe8\x89\x43\xd5\x62\x0d\x4c\x58\xa3\
+\x98\x02\xfb\xed\x96\x43\xe5\xd1\x5d\x0f\x5c\x34\xd3\xfa\xcb\x82\
+\x98\x45\x26\x98\xfa\x35\x61\x0c\x1f\xc2\x4a\xf6\xb4\xac\xe8\x3d\
+\x61\x75\xa4\x89\x2d\x1b\x37\xab\x7e\x49\xbf\xa3\xe7\x4e\xf4\x1b\
+\x3e\x30\x4a\x9a\x74\x9a\x6e\x51\xda\x2a\xe9\xdc\x04\x17\x8a\x57\
+\xb2\x66\xe3\x46\x7a\x8d\x08\xe7\x74\x1c\x07\x81\xe2\x4e\x0f\x0a\
+\x5c\x27\x47\x9f\x08\x5b\xc7\x8b\x44\x45\xa0\x3c\x54\xf5\xdd\x59\
+\x5b\xed\xac\xd5\xf6\x5f\x88\x13\x90\x1f\x3f\x0f\x20\x5d\x7f\xcf\
+\x46\xfd\x8a\x61\x5a\x6b\xb5\x35\xcf\x2b\x12\x21\x54\x66\x66\xbb\
+\xd5\xc2\x63\xf1\xcd\x77\x4c\xff\xf1\x18\x8a\x05\xf3\x72\xc4\xcb\
+\x6f\xff\x98\xff\x97\xb1\x37\x0b\x92\xe5\xbe\xce\xfc\x7e\xb9\x55\
+\x65\x66\x65\xd6\xd6\xdd\xb7\xb7\xdb\xb7\xef\x0a\x10\x0b\x09\x82\
+\x94\x48\x88\x04\x29\x8a\xa3\x65\x28\x5b\x33\xf6\x84\x2d\xc6\x48\
+\xb2\x3c\x96\x46\xa1\xa7\x79\x72\xf8\xc1\x0f\x8e\x90\xdf\xec\x07\
+\xdb\x31\xe1\x07\x4d\x8c\x6c\x86\x56\xca\xb2\x3d\x5a\x47\xa4\x16\
+\x8b\x82\x28\x40\x24\x38\x20\x81\x0b\x5c\x2c\xbc\x6b\xef\xcb\xed\
+\xee\xda\x32\x2b\x33\xab\x72\xf3\xc3\x3f\xf3\x5f\x59\xdd\x17\xd2\
+\x54\x44\x47\xd6\xd2\x6b\xf5\xc9\x93\xdf\xf9\xce\x77\xbe\xe3\x3f\
+\xda\x65\xe3\x23\xab\x60\x8f\xc8\xed\x75\x8e\xba\x09\xf9\x91\xca\
+\x51\xb0\x4b\xf0\x28\x12\x8d\x8f\x91\x98\xce\x78\xf9\xda\x0a\xcf\
+\xbc\xb7\xcf\xb5\xa7\x6f\xd1\xf8\x44\x9d\x1f\x7b\xe1\xa3\x5c\xb9\
+\xfc\x4f\x68\xae\x6f\xf0\x6f\x7e\xf5\x77\x99\x1c\x4d\x2e\x74\xd9\
+\x54\x6b\x09\x86\xa9\xc8\xac\x5d\x47\x64\xe4\xce\xa2\xe4\x8f\x4b\
+\xb6\x62\xa5\xd5\x93\x70\x43\x7e\x5d\xb5\x4b\x17\xde\x46\xb5\x96\
+\x04\xed\x56\xfc\x1b\x94\x60\x1f\xea\xab\x2c\xb5\x6e\xf2\xfc\xad\
+\x9b\x1c\x6a\x53\x1a\x76\x1d\x2f\xd0\x64\x61\x97\xe1\x63\x43\x61\
+\xa2\xf2\x84\x2e\xa3\xad\xa3\x07\xc5\x4e\xbd\x71\x63\xee\xd8\x19\
+\x37\xd8\x56\x73\x94\xe8\xf0\x9c\xcd\x17\x4c\x73\x9f\x86\xe3\xc8\
+\xa6\x47\x6a\xa7\x44\x04\x58\xb6\x22\xd9\x89\xce\xd1\x36\xc3\x56\
+\x9d\x81\xb7\x42\xf3\x92\x28\xee\x5a\xc3\x59\x26\x8e\x0b\xae\xd9\
+\xac\x64\xe3\x88\x40\xe8\x89\xb5\x50\xc1\x2f\xf8\x61\xdf\x0a\x71\
+\xfd\x1c\x4d\x53\x29\x5d\x1b\x34\x14\x52\x22\xe2\x02\xf5\x36\x8b\
+\xc9\x8f\x38\x12\xba\xe2\x18\x4b\x2c\x65\xac\x32\x18\x73\x10\x25\
+\xac\x74\xf1\x66\xca\x63\xbf\x38\x6a\x58\xf4\xcb\xd5\x04\xe1\x3c\
+\x26\xae\x06\x63\x15\x23\x97\xcf\x3d\x29\xc8\xcf\x7f\xae\x7f\xe3\
+\x7a\xa5\x30\xb0\x3e\x24\x13\x2b\x17\x5c\x95\xde\x1b\x9d\x31\x79\
+\xf3\xeb\xd4\x59\xe6\xbb\x5b\x31\x7b\xfb\xe1\x1c\xbd\x05\xc0\xc3\
+\x43\xc2\x7e\x24\x33\x5f\x3c\xec\x62\xb4\x7a\xc4\xa3\x88\xdf\xfa\
+\xee\x5b\xb4\xde\x7a\xc4\x0f\x5c\x49\x78\xf9\xc5\x4f\x30\xfe\xcc\
+\xdb\x98\x9f\xfb\x29\x9e\xfb\xe2\x02\x3f\xb3\xff\x32\xaf\xfd\xe5\
+\x5f\x31\x39\x4a\x59\x5b\xb1\x24\x5f\x9c\xb5\x04\x27\xac\x9c\xc1\
+\x4a\xdb\x27\xce\xd7\x80\xe9\x5c\x26\x5e\xe8\xd5\xa0\x35\xc3\xcb\
+\x47\x9a\x23\xdb\xd0\x2b\xa9\x5f\xfc\x0e\x48\x86\xa2\xca\x13\xbf\
+\xd9\x3f\xa4\xf1\x7d\x0d\x77\x71\x49\x0e\x8f\xaa\x40\x69\x53\x6c\
+\xc6\x16\x91\x51\xe8\x4f\x8a\xd6\x74\xd9\x8d\xd3\x5a\x19\x8c\x93\
+\x0b\x2c\x45\x79\x1c\x4d\xa6\x24\x67\x03\x0c\x16\xe9\x2e\xa8\xb8\
+\xc5\x82\x1b\x9f\x84\x4e\x4b\x63\xea\xfb\xe0\x38\x73\xf0\xad\xdf\
+\x33\xa9\x0d\x4f\x24\x9c\x10\x93\x21\x47\xb4\x8e\x26\x98\x9b\x37\
+\x38\x66\x4f\x66\xe2\xb2\x59\x22\x5c\x87\x02\x4c\x02\x89\x89\xd5\
+\x52\x2f\x6c\x15\x81\x7c\x5e\x7a\x59\xbe\x1e\x9e\x2b\x8e\xc2\x22\
+\x80\x0d\x42\x01\x43\x42\x85\xf3\xdb\x23\x7c\x19\xac\x52\x0d\x21\
+\x77\x52\x68\xa6\x39\x73\xdb\xac\x60\xf2\x57\xef\x7c\xe9\x43\x39\
+\xcf\x6a\x40\x97\xb7\x77\xf8\xd2\x85\xe7\x5b\xcf\xc3\xf8\xca\x2f\
+\x33\xbe\xf2\xcb\xc4\xfa\x73\xe8\xd2\x15\xe8\x09\x05\x5e\xa1\xa8\
+\x22\x0a\xa5\xb7\x45\x58\xec\x50\xf6\x92\x35\x72\xb7\xcb\xc9\x83\
+\x37\xd9\x1e\x3e\xb8\xd0\x91\xdb\xcd\x90\x6a\xb2\xb9\x6c\x0a\xb4\
+\xda\x57\xe9\xb6\x2c\x1e\x0e\x5d\xde\xf9\x46\xca\x5f\xbc\xb6\xcd\
+\x5f\xfe\xc5\xd7\x98\xf6\xde\xa7\xfb\x42\x1b\xe7\xda\x06\xdb\x61\
+\x9d\x2c\x3c\x91\x05\x5b\xc9\x50\x2c\x17\xac\x44\x2f\xef\xcd\x15\
+\x79\x25\x4b\x51\x16\x79\xe5\x73\xc7\x83\x59\xf7\xf0\xac\x3b\xe5\
+\x78\x30\xfb\x3d\x56\x2c\x81\xdf\xfd\x60\x56\xdc\x79\xa7\x27\x74\
+\xe2\xc2\x6d\xa7\x68\x3b\x97\x41\x0b\xe0\xe4\x5d\x19\xbc\x25\x0f\
+\xac\x8c\x05\x7d\x56\xed\xc6\x95\x8f\x47\x93\x01\x83\xc1\x00\x86\
+\x3a\x6b\x9d\x84\x8e\x9a\x12\x0f\x15\xfa\xc3\x74\xae\xf1\x51\xe5\
+\x93\xcb\x42\x7a\xda\x5a\x92\x9a\x94\xce\xd1\x36\x03\x6f\x85\xfe\
+\xca\x26\x87\x93\x84\xd6\x70\x32\x47\xa7\x09\x8e\x79\xe6\xad\x37\
+\x8f\x89\x0b\x3c\x6b\x59\x39\xfd\x92\x22\x2b\xe9\xb4\xbe\xe8\x82\
+\x35\x11\x6b\xa6\x47\xe7\xa4\x38\x71\xa8\x88\xe5\xe6\x73\x19\x78\
+\x9e\x0f\x08\xe2\x09\x16\xb6\x80\x29\xc5\x66\xa4\xb9\x56\x6e\x81\
+\xa1\xaf\x18\xf0\xf5\xec\xaf\x78\x99\x7f\xf8\x36\xbc\x23\x82\xb5\
+\x6c\x8c\x54\xb3\xf2\x9d\x07\xff\x92\xda\xda\x75\x3c\xbd\xc0\x52\
+\x91\x52\x09\xe0\xb0\xe8\x4f\xce\xae\x0a\x22\x13\xe7\x33\x2f\x37\
+\x60\x6b\x3f\x00\x8e\xf1\x81\x81\xb7\x22\x03\xb4\x64\x27\xf6\xfc\
+\x7d\x16\x86\x11\x47\x15\x46\xc0\x68\xc1\xe4\x68\x86\x69\x8d\xa6\
+\x08\xc2\x3b\x1c\xb0\xb6\xbd\xc4\x35\x1e\x72\x7a\x3b\xe1\x7e\x07\
+\x94\x65\x03\xf7\xe1\x61\x51\xbd\x77\x61\x8e\x27\x16\x8f\x97\xdb\
+\x70\x7c\xe6\x73\xb4\xe0\x54\x20\x46\x54\x14\x76\xb0\xa0\x9e\xd2\
+\xcb\x4d\xd1\x31\xcc\x7b\xb2\xe0\x5b\x6e\xcf\x32\xf1\x59\xcb\x24\
+\x0b\x9a\xf2\xf7\xbe\x7f\xa4\x70\xed\x69\xe8\x3f\x36\x20\x0c\x51\
+\x34\x17\x02\x95\x49\x2a\x7e\x57\x45\x73\x19\xd9\x03\x6c\xad\x2e\
+\xdb\xc8\xfe\xd4\xa3\x11\x4c\xc1\x15\xef\xcd\xd8\x50\x69\xf4\xd2\
+\x42\x6f\xe2\xd0\xd0\x62\x1a\x41\xce\xb8\xd5\xc1\x01\xe2\x61\xb1\
+\x88\xb1\xdb\x90\x0c\xc5\x88\x94\x06\x62\x0f\x75\x56\x19\x44\x2b\
+\x33\x71\x89\x87\xdb\x1c\xc9\xe0\x19\xb6\xea\x4f\x16\x4e\x15\x90\
+\xc4\x84\x8b\x2a\x36\xc5\xcf\xe5\x3e\x66\x67\x2c\xf4\x13\xb6\x51\
+\x87\xa8\xb0\xb2\xc2\x91\x6b\x99\x9a\xb2\x13\x25\x96\x38\x96\x54\
+\xdc\x05\xb9\x64\x45\x83\xe1\x14\xd4\x5b\x58\x48\x2f\x4b\x41\x50\
+\x58\x60\xd4\x07\xe1\xd6\x1c\x14\xf8\x8f\x09\xe4\x5f\xcf\x6a\x73\
+\x30\xe3\x7b\xfc\x32\x93\x4b\x3f\x4c\x9c\x5c\x17\x2e\x99\xf2\xac\
+\xb7\x3e\x54\x0b\x21\x56\x25\x08\x58\x64\x12\x72\x96\x8b\x77\xf1\
+\x83\x37\xee\xf1\xdd\x3f\xf8\x4d\x6e\x9f\x7c\x5b\x34\x1e\x2c\xf0\
+\x83\x26\xbb\x19\xa2\x81\xc1\x9a\x0c\x60\xd5\x5a\x92\xfa\x86\x95\
+\xd4\x07\xe5\x60\x4e\x69\x76\x14\x42\xb2\x13\x71\x90\xee\x90\x1f\
+\xa9\xb4\x07\x21\xf9\x82\x73\x11\xef\x16\x59\xb9\x7c\x9c\x2f\x08\
+\x6c\x7c\x3c\x10\x54\x5c\x2f\xab\x00\x9f\x5c\xfc\xfc\x32\x63\x97\
+\xd4\x5b\xb5\xfb\x57\xd2\x6b\x65\x26\xb6\xdb\x1a\x93\xbd\x01\x4a\
+\xda\x03\x2f\xa7\xdf\xef\xd3\xef\xf7\x19\x8c\x12\x06\xbb\xd0\xef\
+\xf7\x89\x0f\x7c\x74\xdd\x22\x48\x35\xfc\x69\x44\x7c\x10\x33\xc8\
+\x53\xf0\x72\xc6\xa9\x41\xa3\x27\xb2\xa9\x53\x5b\xa4\x11\x4c\x69\
+\x69\x0e\xe3\xbc\x43\x43\xe9\xe3\x17\x06\xe4\xee\xb5\x26\x9d\x96\
+\x86\xa2\xb6\xc8\x2a\x30\xc2\x53\x1d\x49\xb5\x59\x76\x34\x97\x89\
+\xa9\x24\x8c\x92\x2b\x2e\x31\xb1\xea\xfb\x92\x67\xae\xca\x3c\xc7\
+\x7e\x8c\x9a\x5a\xb9\xd8\x5e\x64\x99\x72\xa6\x4e\xeb\x47\xf8\xd3\
+\x33\x88\x74\x31\xed\x61\x76\x65\xb6\x8d\x11\x03\x95\x71\xe1\x0a\
+\xa4\x95\xc7\x50\x91\x4a\xb7\x92\x27\x76\xe6\x66\xd4\xc2\xf9\x76\
+\x74\xa1\x66\x4b\x09\xb1\x22\xf1\xb5\xee\xc1\x16\xf6\xce\x0f\xf3\
+\xeb\x59\xed\x3f\x2a\x88\xcb\xcf\x7b\x07\x01\x41\x0e\x46\xbf\x5c\
+\xd1\x1f\x5b\xf2\xb2\x25\x3a\x72\x33\x71\x92\x98\xdf\x8b\x8a\x20\
+\xcf\x99\xf8\xe1\xac\x03\x54\x14\xac\xa3\xc7\x62\x60\xf3\x78\x64\
+\xcc\x4d\x59\x94\x19\x2d\xab\x5f\x92\x9d\xb0\xd2\x67\x62\xae\xd5\
+\x9c\xaf\x49\x01\x4f\x19\xe8\xdb\xb5\x75\x8e\x47\x86\x1c\x08\x2d\
+\x1b\x1d\x65\x93\x63\x2e\xdb\x14\x3f\x53\x64\x74\x73\xae\x90\x2b\
+\x3f\xbf\x97\xf7\x24\x5f\x5c\x3e\x5e\xe8\x9f\x62\x14\x85\xdf\x8a\
+\x35\xe3\xb2\xd5\xc9\x63\x82\xbe\x48\x50\x8f\x3b\x1d\xf2\x62\x51\
+\x62\x5b\xd1\xe8\x74\x3a\x74\x3a\x1d\x36\xaf\x3a\x6c\x76\xda\x74\
+\xda\x9b\x24\x89\xd0\x0e\x5f\xae\xad\x72\xe3\xc5\x75\xba\xd7\xaf\
+\xd1\x69\x6f\x72\xb9\xb6\x8a\xd2\xde\xa4\xd3\xde\x04\x3a\x28\xed\
+\x4d\x86\x03\x0f\xa7\x93\xa2\xb4\x9b\x05\x9b\x92\xa3\xa8\xad\x82\
+\x57\x2e\xf4\xc8\x85\x29\x84\x9b\xf9\x32\x8b\x7a\x86\xc5\xd1\xe9\
+\xd9\x9c\x30\x5e\xc2\xb2\xa2\xf1\x51\xf2\xc4\xb3\x13\xa1\x51\xd4\
+\x37\x36\x71\xa0\x89\x4c\xac\x99\x33\x0b\x14\xb9\xaa\xb6\xd3\x01\
+\xd3\xc2\x3f\x27\x92\xb7\xca\x9d\x64\x45\x86\x4b\xcb\x59\x8c\x42\
+\xbe\xa9\xf8\x02\x57\xeb\xa1\x28\x10\xc3\x7e\x84\xd5\xd7\x84\x25\
+\x40\x38\x2b\xf2\x6c\x3f\x28\xd8\x8b\x50\x66\x6a\x13\x13\x6f\xed\
+\x2a\x1f\x78\xdf\x62\xe7\xdd\xda\x3f\x98\x8d\x7f\x3d\xab\xb1\xf3\
+\xae\xf8\x90\x75\xd6\xce\x0e\xd1\x9a\x5a\x74\xe8\x66\xab\x74\x4b\
+\x56\x62\x5e\x64\x6f\x8a\x93\x71\xac\x51\x77\x8a\xe9\x90\x73\x3f\
+\x63\x6f\x3f\xe4\xe1\x41\x84\xff\x68\x97\xe5\xf6\x0c\x07\x5f\x76\
+\xd6\x65\x70\x9c\xc7\xc2\x17\x5a\xa9\x45\x96\x5e\x75\x14\xa9\x61\
+\x38\xaf\x3a\x2b\x71\xec\x4a\xea\xcb\x63\x99\x8d\x7b\x79\x8f\x23\
+\x4d\x04\x6a\xd9\xa5\xeb\xe5\x3d\x19\xb8\x0b\xbd\x9a\xcc\xc4\xcb\
+\x6d\x64\xa6\x2e\x8b\xba\x4e\xd4\xe4\xf1\xe0\x31\x07\xbd\x13\x8e\
+\x42\x21\x8e\xbf\xd4\xef\x33\xb6\xa7\x28\xed\x26\x69\x65\xcf\xc8\
+\xa8\xe8\xcc\x96\xf4\x5a\xd2\x1f\xb2\xab\xf6\xd8\x79\x38\xc6\x3b\
+\x3e\x62\x57\xed\xb1\x37\x3d\x04\xfa\x0c\xe8\xa3\xdb\x21\xba\x1d\
+\x62\xac\x5d\xa2\xe9\x1a\xb4\xe9\xa0\x77\x44\xf0\x96\x7a\x89\x86\
+\xcd\x9c\x9f\x5b\xe6\x38\x73\xf4\xdc\x95\xc2\xde\x61\xf4\x58\x64\
+\xe1\xb6\x3b\xeb\xda\x55\x31\x71\xc9\x2f\x6b\x41\xb9\x3b\x31\x10\
+\xdf\x53\xe8\x89\x43\xd1\x55\x3b\x27\x69\xb4\x2c\x53\x8c\xe0\x9b\
+\x16\xb9\x15\x48\xbf\x09\x2a\xd9\x56\x0b\x15\x69\xc4\xcd\x28\x16\
+\xc6\x28\x51\x28\x9c\x7e\xe2\x09\x49\xa0\x73\x9c\xf7\xc9\x23\xa1\
+\x8c\x3b\xe9\x47\xe8\x61\x48\xa0\xa9\x28\x7e\x40\xd8\x37\xb0\xd3\
+\x8c\xb0\x9f\x90\x0f\xb6\xd8\xe8\xc7\x8c\x57\x27\xbc\xf3\x76\xfd\
+\x43\xb3\xf1\xf0\x0e\xfc\xeb\xb7\x45\xf0\xde\xc9\xc6\x8c\x57\x67\
+\x7f\xe8\xf5\x2b\x57\xb0\x8d\xcf\xcc\x4f\x83\x48\x43\xc1\xf0\x82\
+\x88\x24\x8a\x14\x8c\x46\x4a\x3c\xd6\x64\xb3\xa3\xc4\xc4\x67\xe1\
+\x2e\x71\x78\x20\x29\xb0\x12\x5f\x6e\xa8\x82\xae\xea\x44\x4d\x09\
+\x27\x00\x96\xb5\x53\xb2\xf0\x44\x04\xab\xb5\x24\xb3\xe1\x6a\xa1\
+\xad\x56\x6a\x8b\x4f\xfc\x7b\x26\x47\xa9\xec\xd8\x1d\x0f\xb8\x70\
+\x5c\x6e\x8b\xa2\xad\x5a\xe4\x55\x03\xb9\xcc\xc6\x00\xf1\x28\x9a\
+\x3b\x56\x27\x3b\x0e\xf7\x52\xb2\xf0\x84\x61\xab\x4e\xb8\x7e\x95\
+\x89\x1f\x72\x3a\x0d\xd8\x3f\x1c\xd0\xef\xf7\x39\x9d\x06\xf4\xfb\
+\x7d\x0e\xa6\xa2\x73\x27\xd2\x66\x8d\x8e\x69\xd1\x5e\x37\x30\xdb\
+\x35\x3a\xed\x3a\xed\x95\x26\x7a\xb7\x56\x38\x06\x09\x65\x59\xa9\
+\x3f\x56\x3b\xe9\x1c\x6c\x68\xa2\x31\x0e\x98\x19\xb1\x14\x01\xdd\
+\xb0\x0b\x53\xc7\x61\xce\x4e\x2c\x10\x6d\xdb\x3d\xa2\xed\x1e\x49\
+\x38\x71\xfe\x56\x85\x13\x65\x46\x2e\x23\x56\xad\x96\x38\x98\xf9\
+\x6c\x73\x7d\xa9\x03\xb6\x72\x49\xaf\x11\x46\x62\xea\x23\x54\xf0\
+\xfb\x7d\xfc\x52\xe9\x66\x5a\xc2\x24\xa5\xea\x3f\x61\x5a\x34\x5b\
+\x1a\xcb\xad\x4b\xe2\x44\x70\x14\x1c\xd3\x22\x29\xa4\x9c\xbe\xd6\
+\x10\xcb\x6b\x34\x15\xf0\x38\x1d\x2f\xb2\xdb\x31\x78\x66\xe9\x65\
+\x94\xe7\x7b\xec\xbc\x5b\xe3\x5f\xbf\xfd\xe4\x8c\x5c\x06\x30\x80\
+\x77\xf7\xe7\xe4\xf3\xb7\x13\x95\x38\x3f\x38\x27\x96\xaf\xee\xfc\
+\x50\x66\x27\x6b\x41\xeb\xc5\xc5\xd6\xa6\xb2\x5a\x2e\xc7\x9d\x86\
+\xc9\x2d\x0c\x6b\x0d\xe5\xcc\x97\x01\x59\x36\x39\x72\x7b\x9d\x41\
+\x5b\x78\xaf\x95\x7a\xdd\x43\x3f\x67\xd5\x51\x38\x4e\x17\xc9\xc2\
+\x13\x9e\x1f\xac\xc9\x00\x5e\xd6\x4e\x9f\xf8\x8f\x31\xac\x35\xce\
+\xba\xd3\x39\xec\x5c\x66\x54\xe5\xcc\x27\x5f\x70\x64\x40\x57\xdb\
+\xca\x5d\xb5\x08\x52\x65\xa6\x6b\xee\xaa\x11\xbd\xcc\x64\xb9\x8d\
+\x84\x1f\xcb\xda\x29\x47\x61\x31\xba\x94\x8f\x58\xeb\x2e\xb1\xdc\
+\xbe\xcc\xc6\x92\x41\x77\xa3\xcd\x62\xcd\x66\x7d\xb5\x8d\xbe\xd0\
+\xa6\x6e\x5a\x74\x3a\x1d\xb1\xac\xd1\x36\x09\xd2\x59\x72\x68\xd6\
+\x6b\x98\xa6\x49\x33\x17\x1f\x25\xaf\x5c\x15\x0f\x25\x49\x38\xe7\
+\x22\x94\x24\x21\xa9\x9d\x4a\xaa\xad\x2a\x92\x97\x57\x29\x7b\x76\
+\x7f\xe0\xad\xcc\x65\xe2\x12\x4e\xc8\x02\xd0\x71\x64\x46\x8f\x8b\
+\x8c\x1c\x81\x98\x76\x9e\xf7\x98\x9c\x05\x74\x5a\x04\xad\x16\x2a\
+\x18\x84\x58\x15\x16\x42\xaa\x87\x8a\x06\x41\x69\xa6\x52\x7e\x84\
+\x08\xa3\xc0\xa0\x30\x48\x29\x9d\x35\x2d\x2b\x97\xd3\x1e\xaa\x95\
+\x0b\x45\x9c\x65\xe2\x03\xef\xef\xef\xc2\xe3\x1b\xd4\xf2\xa7\x04\
+\xce\x7d\xbb\x3e\x87\x7b\xab\x85\xdc\x9d\x6c\x4c\x7e\x47\xfc\x53\
+\xdd\xa7\x7e\x7b\x16\x14\xfa\x55\x3a\xd6\xf5\x4a\xf0\x7e\x88\x77\
+\xdb\xdc\x88\x53\x5d\x42\x9d\x30\x8a\x20\x8a\x48\x4e\x5d\x5a\xfa\
+\x3d\xe2\xf0\x80\xd5\xd5\x19\xa6\xdd\xcd\x40\x29\x6c\x54\x85\x6b\
+\x8f\xe8\x8e\x3d\x7b\x68\x08\xfb\x2a\x3f\x97\xd9\xf8\x4e\xfb\x80\
+\xc3\xa2\x7d\x7d\x9c\x8a\x2c\x6c\x77\x4c\x59\x18\xaa\x93\xc7\x42\
+\xe9\x96\xfa\x12\x26\xcc\x06\x24\x45\xa0\x56\x9f\xaf\x66\x62\x59\
+\xdc\xe5\x6b\x17\x9e\x2b\x83\x3e\x0b\x4f\xe4\x09\x75\xea\x9d\xd0\
+\x6d\x59\x3c\xff\xe2\x47\xa8\x2f\xd6\x08\xf4\x06\x69\xde\x40\xef\
+\xd6\x30\xb1\xe9\x98\x16\x1d\xd3\x42\xe9\xb4\xe5\x68\x12\xd8\x72\
+\xca\xa3\x9c\xc3\x4b\x92\x90\x91\x12\x09\xf1\x7c\xbd\x26\xc7\xfc\
+\x47\x93\xa9\x18\x1a\x2d\xf4\xc7\x49\x12\xd2\x6a\x5a\x8c\x03\x91\
+\x91\xcb\x2c\x5c\xc2\x09\xd5\xf7\x81\x06\x99\x21\x30\x5a\xb9\xc2\
+\xa1\x74\xbf\x1f\x78\x2b\x73\x22\xa0\xf3\x90\x22\xb5\x53\x89\xab\
+\xc7\xea\x14\x75\x6c\x65\x33\xea\xa9\xf8\x27\xa6\x15\xac\xca\x39\
+\x3a\xad\x54\x13\x39\xa6\x25\x82\xba\x90\x66\x6a\x17\x2c\x51\x28\
+\x3c\xdd\xaa\xcc\x72\xb9\x70\x3c\xaf\x28\xe6\x20\xd4\xeb\xe8\xab\
+\x6d\xe8\x36\x69\xad\xdc\xa2\x3d\xbc\x89\xf2\x7c\x8f\x3f\xfd\x5d\
+\x97\x7f\xa1\x4e\x2f\xe0\x60\x00\xe5\x79\xf1\x4f\xfd\x49\xe5\x27\
+\x79\xf9\xf9\xaf\x73\x37\xfc\x9f\x41\xb9\x01\x91\x52\xe8\x84\x0b\
+\xe1\x4f\x21\xa9\x94\x59\xb8\xa2\x81\x2e\x2d\x60\xc5\x54\x4b\x51\
+\x08\x86\x17\x47\x8d\x54\x6b\x09\xd5\x5a\xa2\x7b\xb2\x47\x3e\x5d\
+\xe7\xc6\x25\x03\x65\x25\x93\xa6\x25\xef\xad\xc6\x73\x83\x9a\x65\
+\xf0\x96\x99\xb9\xcc\xd6\xbb\x99\x28\x0c\x17\x86\x11\x47\x21\x1c\
+\x1e\x9e\xc8\xa0\x2b\x9b\xb7\x17\x02\xf5\xef\xb9\x9d\x87\x18\xcb\
+\x6d\x24\xb4\x50\xad\x25\x26\x47\x29\x87\x7b\x22\x0b\x3f\xf3\xe2\
+\x2d\x96\xdb\x97\x59\x6e\x5d\xa2\xdd\x6e\x63\x4b\x81\x79\x25\x40\
+\x26\xe2\x6f\x0f\x52\x8d\xb4\x2e\x32\x6e\x1f\x95\xa6\x25\xbe\xa7\
+\xa7\x37\xb0\xe3\x9c\xd1\x64\x4a\xaf\x3f\x62\xe7\xf8\x31\x23\x2f\
+\xc6\x09\x2c\x6c\x2d\x95\x1c\xb2\xae\x8b\x00\x2e\xb3\x70\x19\xc0\
+\xe5\x63\x4f\x75\x80\x31\x6a\x2c\xfe\xf8\xd2\x3c\x3c\x18\xa4\x4c\
+\xb5\x75\xda\xee\x11\x6a\x78\xc4\x61\x3e\xcb\xec\xd3\x02\x4e\x94\
+\x90\x42\x0b\x84\x8f\x6b\xc3\x31\x50\x1b\xa1\x2a\x2b\xf5\x52\xd4\
+\x5e\x06\xb0\x9d\x66\xd8\x69\x86\x1e\x9e\xb3\xb1\x2a\xb2\x6f\x19\
+\xb8\x17\xd6\xe6\x16\x81\x20\x97\x2f\x9a\x22\xdb\x96\x46\x85\x69\
+\x71\xa2\x94\x5f\xdb\x75\x15\xae\x2d\x76\xb1\x2d\x8b\x4e\xd6\xe4\
+\x0b\x9f\xff\xe2\x5c\xe0\x96\x90\xa2\x84\x11\x6f\xbf\x29\x84\x07\
+\x1f\xef\xfc\x02\xfb\x0b\x2b\x1c\x8c\x7e\x19\x4f\xbf\x2e\x5c\x3a\
+\x4d\x93\x64\x30\x28\xe8\xb2\x73\x53\xd2\xe7\x94\x6a\xf2\x14\x33\
+\x73\x4c\xd3\x14\xac\x85\x25\x0a\xdd\xf1\xa9\xc7\x61\xfc\xd4\xdc\
+\x3c\xdc\x5b\x7b\x39\xe3\xe3\x3d\x54\xee\xf1\x63\x2f\x3f\xc5\xad\
+\x97\x3e\x8a\xbb\xfc\x31\x39\x82\x54\x06\xf2\xf1\x40\x60\xd0\x9d\
+\xfd\x0e\x59\x78\xc2\x19\x6b\xd8\x1d\x81\xa7\xcb\x06\x49\xb5\x71\
+\xe2\xf9\x95\x69\x72\x3f\xbd\x10\xd4\xe5\x73\xe2\xd8\xff\xd0\xa0\
+\x3e\x1e\xcc\x98\x8b\xc9\x51\x2a\x83\xbc\xdb\xb2\x58\x6e\xc6\xd4\
+\x17\x6b\xac\x6c\x26\x42\x4f\x1c\xa9\xc2\xc2\xb5\xd0\xf8\x96\xbe\
+\x10\xe5\x73\x79\x7f\xc0\xfe\x78\xca\xc9\xf1\x01\xb7\x1f\xee\xf3\
+\xfa\x07\x77\xb9\xfb\xc1\x07\x7c\xf7\xfe\x2e\x0f\x0e\x0f\xd8\x9d\
+\x84\x44\x64\x82\x9e\xa3\x7f\xa1\x39\x32\x0b\xd6\x99\x87\x85\xa7\
+\x8a\x2c\x5c\xfa\xb8\x95\x16\x5a\x67\xe1\xae\x84\x11\x1f\x76\x53\
+\x9b\x22\x70\xcd\x39\x6a\x54\x50\x6c\x7a\x18\xcd\xfb\x12\x6b\x28\
+\x85\x07\xb1\x27\xc9\x31\x3f\x56\x70\x4a\xf1\x4c\x91\x79\x4b\x5d\
+\xb1\x71\xce\xab\xb8\x2c\x0a\xcb\xc5\xe3\x61\x18\x91\x72\xb1\x19\
+\xe2\x54\x2e\xed\x21\x16\x5a\xa7\x58\xb4\x68\xc1\xb5\xe6\x0f\xf0\
+\xf1\x4e\xc2\xd6\xc6\x37\xd9\x79\x77\x02\x1f\x9d\xf2\xea\x9d\x2f\
+\x71\x27\xfb\x33\x00\x3e\xf6\xe2\x3d\xda\xc3\x9b\x5c\x7d\x41\xe7\
+\xd9\xcd\x97\x85\x01\x92\x9c\x30\x89\xf8\xce\x77\x1e\xb1\x5a\xdf\
+\x25\x5b\x58\xc2\x6e\xc0\xae\x1f\xb2\xe1\x58\x2c\x75\x8a\x00\x0d\
+\x23\x82\x7e\x8f\xb8\x63\x16\x89\x7a\x42\x4c\x9f\x28\x99\x51\x71\
+\x83\xb6\x45\xfe\xf8\xb6\xcc\xd0\x0b\xbd\x1a\x3d\xe0\xad\xbd\x1e\
+\x8d\xe5\xcb\xfc\xd0\x0b\x2a\x57\x3e\xf5\x0c\x2b\x1b\x47\xfc\xed\
+\xff\x73\x83\xbf\x7b\x5f\x83\xfc\x35\xba\x47\x45\x3b\xd7\xd1\xa8\
+\xaf\x68\xac\x58\x4b\x64\x85\x41\x8a\x1f\x34\x89\x07\x8f\x99\x1c\
+\xef\xd2\xcb\x4c\x32\x3f\x65\xcc\x14\xd7\xb1\xe8\x67\x03\xf4\xc0\
+\xc4\x75\x34\xa0\x4f\xe6\x37\x51\x9d\x4e\x11\xb4\x85\x13\x10\x53\
+\x5c\x3a\x78\x7e\x88\xeb\x5c\xd4\x36\x2c\xb7\x41\xb5\x34\x0e\xa6\
+\x8e\x5c\xed\xad\xe6\x23\x36\xaf\x3e\x45\xa3\x2b\x4e\xfc\x47\x7b\
+\x09\x56\x3a\x00\x06\xc5\xea\x62\x70\x6a\xe2\xb8\xaf\x0e\x68\x16\
+\x5a\x06\xe1\xe9\x51\x9c\x58\x51\x48\xa7\xd3\xa4\x5e\xd0\x96\x1d\
+\xd3\x22\xad\x17\x54\xe4\xb0\x8f\x47\x4e\xb3\x08\xde\x20\xd5\xb0\
+\x99\xd9\xc8\xba\x99\x2f\x83\x17\xd5\x21\x73\x1c\x86\xa3\x90\xe5\
+\x26\x8c\x6d\x81\xbb\x17\xac\x0d\x06\x1e\xd4\xd8\x97\xc1\x3c\xf0\
+\x56\xe4\x4e\x12\x80\x24\x73\xd0\x64\xe7\xae\xd0\x26\x17\x7c\xb3\
+\xf4\x27\x0e\xb1\xa4\xbd\x2a\x51\x02\x08\x97\xf4\xf3\x2a\xfa\xf2\
+\x72\x6b\x22\x96\xc8\xb4\xc6\x0d\xfc\x62\x75\x58\xc9\x1d\xfb\x85\
+\x49\x77\x79\xa4\x32\x2c\x5a\xf5\xa8\x28\x67\xec\xac\x88\xd9\x65\
+\x1f\x70\x8d\x3a\xff\xd5\x47\x3f\xc2\xee\xf5\x67\x78\xe5\xe1\xfb\
+\xfc\xf4\xed\xaf\xf0\xbc\xfa\xb7\x02\x37\x0d\x6f\xf2\x85\xcf\x7f\
+\x91\xd6\xca\x2d\xd6\xeb\xcb\x72\xd4\xdf\x2a\x0b\x52\x33\xa4\x7e\
+\xf3\x19\x0e\xef\xbf\x0f\x27\x3a\x6b\xdd\x26\xd7\xcc\x70\x6e\xa8\
+\x54\xb5\x72\x74\x4b\x74\x97\xc4\x89\xd9\x21\xf2\x32\xfa\xb1\xc5\
+\x52\x57\xe7\x23\x2f\x75\x69\x3f\x7d\x99\x77\x6e\xff\x07\xb6\x5e\
+\x7f\x0f\xff\xd1\xee\xec\xd2\xed\xc1\xfb\x6f\xde\xe3\x6b\x03\x8f\
+\x1f\xfc\xcf\xee\xf3\xc9\x4f\x7c\x9a\xab\xbf\xf4\x73\xdc\x7a\xe7\
+\x36\x6f\xbc\x7a\x1d\x9f\xf7\x71\x8e\x37\x50\x96\x0d\x89\x9b\xc5\
+\x7f\x77\x24\xfd\x8b\x7b\x99\x89\xe7\x87\xc4\x4e\x0d\xc3\x17\x99\
+\xb8\xe3\xe4\x78\x45\x56\x6e\xd0\x44\x75\x46\x32\x90\xc7\x84\xb8\
+\x95\x2c\xd1\xa0\x46\x8f\x94\x2e\x33\x2d\x71\x95\x1b\x06\x0b\x56\
+\x80\xbb\x22\x6b\x5f\xbf\x76\x8b\x2b\x37\xaf\x73\xe9\xc6\x66\x31\
+\xc2\x50\x38\x3e\x15\xff\x4b\xbd\x48\x4c\x5d\x20\x9d\xb6\xd0\x6a\
+\x43\x3a\x99\x22\x18\x08\x33\x93\xc5\x5b\x75\x25\x18\x64\xf4\x51\
+\x51\xa2\x09\x4e\xcd\x94\x01\x0c\xa0\x7a\x0e\x74\x52\x19\xc0\x79\
+\x63\x8c\x37\x76\xc4\xe3\xc0\x41\xd7\x2d\x22\x1a\xa8\x81\x29\x33\
+\xf1\x8d\x4b\x06\x03\x6f\x1d\x06\xfb\xd8\x6d\xad\xc0\xc7\xf3\x58\
+\x58\x14\x85\xce\xdc\xf0\xa9\xdc\x63\x27\xc5\xec\x16\x28\xa1\x82\
+\x6a\x26\xb3\x82\xc8\x32\x71\xc2\x48\x76\xe4\xe2\x0a\x56\xd6\x42\
+\x05\x5f\x0d\xb0\xac\xfc\x82\x2d\xab\x66\x9a\xa4\x51\x24\x8f\x16\
+\x33\x75\x5c\x5a\xd1\x50\x94\x41\x1d\x86\x0a\x76\x9a\x0b\x89\x26\
+\x26\x53\x7d\x99\xe5\x16\x7c\xe1\x3a\x6c\x7d\xe3\x26\xbf\xf5\x78\
+\x99\x17\x6f\xbd\xc6\x8f\x7e\xe1\x5f\xb1\x79\x6b\x1d\x3b\x2a\xf6\
+\xdd\x45\x9c\x9b\xc1\x52\x58\x30\x15\xb2\x67\xae\x8a\xb3\xbc\x5b\
+\xc7\x2a\xf7\x89\x16\xda\x08\xcb\x34\xcf\x95\x7c\x39\xb0\x80\xdb\
+\x1f\x01\x36\x86\xe2\x89\xa5\x8f\x4f\xe2\x7d\x95\x26\xbd\xe1\x88\
+\x3f\x7e\x4b\x8c\xee\x7b\x67\x47\x18\xcb\x9f\xe3\xc7\xaf\x2d\xf2\
+\x89\x8d\x0e\xdb\x7b\x1d\x8e\x0f\x0e\x51\xc3\x23\x1e\xaa\x22\xd3\
+\xe4\x47\x2a\x0f\x0f\x22\x26\xc7\xbb\x9c\x8e\x0c\xc6\x14\x12\x4b\
+\x5f\x1c\x5d\x27\xc2\x2b\x24\xaa\xe2\x3e\xb8\x88\xe0\x6d\xf8\xb5\
+\x27\x66\xdd\x6e\x65\x4f\x5c\x2f\xef\xb1\x0c\xac\xac\x3e\x87\x6d\
+\x8f\xb8\xb6\xbe\xce\xa3\xfb\x0f\xe8\xf5\x15\xbe\xf8\x99\x0e\x37\
+\x57\x72\xdc\xee\x0a\x0b\x56\x9d\x34\xb7\x30\xea\x1d\xb4\x49\x84\
+\x55\x0c\xd5\x96\x59\x55\x9b\x44\x60\x4e\x49\x8b\xd7\xc5\x7b\xa6\
+\x0a\x0b\x40\x2d\x9d\x33\x53\xa1\x92\xe6\x3c\x35\xa7\x59\xb0\x18\
+\x49\x12\xe2\xdb\x21\x76\x92\xd2\x47\xa3\xab\x6a\xe4\x5e\x8e\xa7\
+\xce\xe0\xc5\xf9\x9b\xcc\xc4\x45\x81\x57\xb2\x14\xab\x4a\x32\x27\
+\xdf\xd4\x82\x96\x1c\x46\x4d\xed\x14\x83\x27\x6c\x14\xbd\x70\xb3\
+\x4c\x39\xae\x54\xbe\x65\x9a\x55\x32\x17\x8a\x1c\xeb\x11\x2e\x98\
+\x79\xa5\xbd\x6c\x49\x09\x67\xd9\x6e\x0e\x0b\xef\x8a\x92\x97\x4e\
+\x2b\x30\x26\x2c\x27\xac\xe3\x09\xf6\x48\x63\x94\xa7\xe8\x76\x82\
+\x6d\xd4\xd9\xcb\x6a\x74\x9e\xdd\x42\x7b\xa8\x70\x9c\xff\x2c\x97\
+\x17\x4d\x16\xc8\xc0\x9c\x59\xbf\x5a\x91\x22\x8a\xd2\xb2\x33\x17\
+\x28\xa8\x5a\x83\xfa\xa4\x47\xd4\x1f\x48\x08\x24\x3b\x75\x4f\x5a\
+\x8a\x16\xf6\x19\x8d\x43\x9a\x45\x76\x4e\xc7\x27\x6c\x6f\xdd\xe3\
+\xdd\xf7\x1e\xe3\x9a\xf3\x05\x54\xb7\x65\xf1\xa8\x77\xc4\x1f\xbf\
+\xf5\x88\x3f\x7e\xeb\x11\x1f\x7f\xe6\x11\xef\xdf\x5a\xe6\xe6\xa6\
+\x8d\xaa\x7d\x9a\xcb\xf9\x1e\xf7\x07\x0a\x0c\x0e\xd9\xcd\x60\xf2\
+\x68\x97\xe3\x01\x78\x7e\x8e\xeb\x8c\xc0\x37\x49\xec\x09\xf9\x28\
+\xc7\xd0\x4d\x19\xc0\x02\x1f\x8b\xfb\xfd\x6c\x40\xc7\x69\x8b\x23\
+\x6d\x09\x21\x24\x04\xa9\x24\x8c\xae\x1a\xf1\xe9\x85\x15\x8c\xb5\
+\x16\x76\xbb\xcb\x83\xc7\x31\x2b\x16\x1c\x76\x72\x1a\xcb\x97\x49\
+\xcd\xab\x74\xac\x19\x3c\x88\x27\x3d\xb4\xca\xb8\xbe\x36\x11\xc2\
+\x1a\x0d\x5b\x14\xee\x93\xf3\xdb\xa9\x32\xce\x39\x6c\x8b\x91\xa6\
+\x89\x38\x09\x95\x68\x02\x8d\x99\x78\x9e\x54\x58\x5d\xe1\xd6\x18\
+\x91\x92\xbb\x0a\xc5\x8c\xa9\xcc\xce\x42\xe0\x3e\x9f\x89\xcb\xcc\
+\x5b\xf2\xc5\x2d\xb6\x67\xed\xe5\x00\x1a\xc5\x74\x88\x9c\x12\x29\
+\x8a\x3c\xdd\x2a\x27\x94\xad\x52\xe7\x10\xce\x63\xe4\x48\xd0\x68\
+\x46\x45\x7d\xe6\x44\x96\x5c\x18\x63\xa7\x19\x9e\xa3\x14\x7b\x3f\
+\x66\x25\x93\x53\x1d\x5f\x2a\xe6\xed\xca\xad\x19\x56\x14\x51\x6e\
+\x75\x88\xc2\x10\x2b\x35\x45\x00\x17\x2e\x3b\x4d\x25\x23\x34\x73\
+\xea\x96\xc5\xb3\x5a\xc4\xfd\xad\x9f\x27\xdf\x3c\xe6\x27\xba\x75\
+\x0c\xb3\x0f\x74\xa4\x5b\x50\xd5\x2e\x36\x2c\x32\x31\x40\x43\x09\
+\xa1\xd3\x91\x85\x80\x45\x58\x08\x93\x8a\x1d\xd1\x61\xb9\xca\x61\
+\x16\x0c\x4a\xab\xce\x58\xab\x95\x12\x3c\xf2\xe3\x18\xd7\x3c\x94\
+\x4d\x85\xf2\x76\x3a\x32\x68\xb5\x5b\xe0\x41\x2f\x85\xbf\xb9\xf3\
+\x88\xb7\xf6\xca\xae\xd9\x43\xd9\x70\xe8\x65\xe1\x5c\x80\xba\xf9\
+\x2c\xe3\xea\x41\x5d\x2e\x2c\x8a\x93\x08\xa3\xb0\x53\x4d\xec\x09\
+\x7a\x50\xa7\xa3\xb6\x0b\x9c\x5c\x27\x23\x95\xb8\xb9\x85\x5b\x64\
+\x66\xf1\x3e\x74\xd5\x08\xa3\x69\xd2\xb0\x2f\x71\x65\x25\x07\x12\
+\x82\x9a\xca\xdf\x85\xd0\x6d\xde\xe0\xc5\xce\x2a\x37\x37\x0d\x1c\
+\x7d\x4c\x4e\x1d\x3d\x50\xd1\xed\x4c\x14\x74\x72\x99\xa4\x2d\xbb\
+\x60\xe7\xe7\xd8\x6c\xad\x4e\x50\xbc\xa7\xd5\x2c\x2c\xda\xd2\x16\
+\x03\x90\x70\xa2\xba\x85\xb4\x67\xe7\x98\x05\x3e\xee\x78\x39\xfd\
+\x4c\xbc\xe6\xa9\x0e\x49\x12\xa2\x05\xb3\xac\x3c\x3e\xf5\x18\x58\
+\xcf\x4a\x0c\x1c\x0c\x52\xda\xed\x23\x0e\x07\x3a\x3f\xa6\x05\x24\
+\x99\xf3\x44\x48\x21\xdb\xce\x8a\x1f\x40\xa4\xe3\xfa\x79\xe1\x9f\
+\x36\x7f\x4b\x09\x65\x03\x40\x2b\x98\x85\x12\x0a\xd8\x46\x5d\xfa\
+\x53\xa4\x17\xa4\x9a\x4f\x30\x9e\xaa\x70\xb4\xae\x9f\xa3\xf8\x39\
+\x56\x6a\x12\x6a\x11\x4a\x49\xbb\x35\x0d\x68\x1a\x58\xa9\xc9\xc4\
+\x0f\x09\xb1\xb9\x7a\x45\xe7\x85\xee\x9f\x8a\x4b\xb0\xb2\x36\xe7\
+\x16\x54\xde\x0f\x2b\x98\x37\x4b\xc7\x60\x89\x25\x07\x96\x69\xd2\
+\x31\x4d\x30\x3b\x73\x3c\x38\x96\x39\xa3\x11\x73\xf1\x77\xbb\xae\
+\x8d\x6a\x07\x9c\x45\x19\xbd\xdb\x03\x76\x46\xce\x05\x2a\x6b\xe0\
+\x88\xa2\xcd\xf3\x4d\x3c\xe3\x59\xba\xed\x0e\x69\x7b\x83\xde\x00\
+\x86\x83\x21\x77\xdf\x7a\xc8\xab\x6f\x3d\xe2\xf5\x87\x87\xf4\x06\
+\x02\x1e\xc8\x2c\xab\xcc\x02\x35\x4e\x22\xe2\x24\x2a\xf8\x6d\x13\
+\x37\x8f\x64\x70\x27\xf6\x44\x64\x60\x35\xc7\x75\x2c\xc6\x4c\xf1\
+\xfc\x90\x56\xe0\x56\x58\x8a\x59\x00\x7f\x7a\xa1\xcd\xf2\x52\x01\
+\xcf\xcc\xab\x92\x27\xde\xbc\xa6\x61\x6e\xde\x90\xfa\xe1\x34\x6f\
+\xa0\xdb\x99\x18\x0e\xb5\x33\xf4\x40\x9d\x9b\x59\x33\x2f\x4c\x14\
+\xdb\x04\xe9\x64\xae\xb9\x71\xfe\x96\x9b\x75\xfc\x69\x34\x37\x01\
+\x22\xdc\x2b\x6d\xec\x20\x2c\xae\x2a\xb3\xf4\xe6\x66\x42\x5c\x94\
+\xda\xb3\x9f\x56\x2e\x65\x2f\xa9\xb6\xea\xed\x30\xb5\xd1\x55\x1f\
+\x37\xf3\x19\x91\x4a\x0d\x45\x49\xb5\x8d\xfd\x18\x5d\xec\xd0\x98\
+\x10\xc4\x00\x13\xd1\x75\x2b\x60\x82\x53\x66\xd1\xca\xf8\x52\x89\
+\x85\xd3\xc2\x38\x5b\xc2\x85\x62\x1c\xdf\x2a\xee\x5b\x55\xc6\xa0\
+\xc2\x4c\xa4\x73\x6b\x09\x98\x1b\x22\x0d\xac\xc9\xec\x22\x37\x8a\
+\x09\x3b\x29\x9d\xa2\xc3\x77\xd4\xff\x4f\xa1\x53\x4a\x39\x43\xc2\
+\xc2\x26\x40\x40\x89\x19\x33\x21\xbc\x36\x8b\x8c\x62\xe6\xf4\xfb\
+\x03\xa9\xb6\xd3\x0a\xcd\x44\x29\x3e\xc2\x2a\x1d\x3d\x33\xc6\xa1\
+\x45\x03\x11\xf0\x47\xe3\x87\xc2\xae\xea\xf4\x8d\x0f\xc5\xa2\xb1\
+\x53\xa3\xcb\x7b\xe2\xf2\xe7\x37\x41\x2f\xd8\x84\x36\xb4\x80\x1e\
+\x29\x86\x3f\xc5\xf3\x9f\xf0\x8f\x2f\x60\x44\x35\x0b\x97\x01\x5e\
+\xc5\xc7\x5e\x91\x0e\x5c\x27\x2a\x8a\xbc\xb2\xd8\xd3\x8a\x4c\x6c\
+\xb1\xd6\x5d\xa2\x61\x77\xa8\xaf\x2e\xc8\xb1\x7c\x50\x58\xeb\x2e\
+\xcd\x35\x37\xce\x27\x94\xa4\x08\xe0\xf3\x9b\x57\xab\x33\x6c\x60\
+\x4b\x49\xe6\x93\x6e\x65\x61\x57\xcd\xce\xba\x6e\x61\xc7\x62\x0d\
+\x46\x99\x8d\xd7\x8d\xa9\xcc\xc0\x9e\xee\xc8\x79\xb9\xb3\x22\x9e\
+\xce\xef\xad\xb6\xdb\x1a\xc1\x20\x65\x55\x49\xa4\x8a\xad\x6c\x63\
+\xa7\xa4\xa8\xbe\x4f\xe6\x38\x32\x90\xd5\xb2\x55\x2c\x47\xd6\xcb\
+\x82\x26\x0a\x45\xa6\x2c\x2d\x58\x4b\x21\xbb\x29\xba\x73\x8e\xa4\
+\xd3\x84\xd9\xb6\x2c\xd0\x2a\x19\xb2\x0c\x5a\x2b\x52\xb0\xa2\x08\
+\xfb\x34\x94\x43\x98\xaa\xe2\x10\x68\x2a\xb9\x23\xcc\xae\xcb\x6c\
+\x1c\xc4\x93\xb9\xe5\x34\x61\x91\x2d\x57\x3a\xff\x9e\xb5\xcd\x87\
+\x52\xca\x59\x9e\x24\xe5\xb6\xd1\xb4\x82\x75\xad\x64\x22\x03\x35\
+\x26\x60\x74\x16\x72\xb6\x17\xe1\xf7\xfb\x78\xfd\x03\xa2\x28\x62\
+\x2f\x88\xe8\x13\x32\xee\x4f\x88\x22\x85\x2c\x1d\x33\x0e\x22\xa2\
+\xfe\x80\x47\x7b\x3e\xf9\x71\x7c\xa1\xdd\x5b\x75\xb9\xec\xa2\x91\
+\xf9\x4d\xf0\x40\x75\x46\xa8\xf9\x88\xcc\x4f\xf1\xfc\x50\x06\x70\
+\x99\x5d\x65\x51\x98\x1c\x3f\x59\x1f\x9b\x44\x17\x30\xb1\xeb\x44\
+\x73\x59\xbc\x2c\x06\xcb\xf0\xe9\xaa\x16\x57\xd6\x2c\x36\x94\x58\
+\x66\xe1\xd5\x8a\x66\xe2\xfa\x35\xd1\xdc\xb8\xb4\xbe\x8c\x65\xd5\
+\x45\x16\x0e\xc4\xba\x86\x24\x88\xd0\x6d\x93\xa4\x92\x8d\xa3\x39\
+\x18\x81\x84\x0f\x65\xfb\x39\x48\x27\x04\x86\x72\xa1\x39\x92\x9b\
+\x75\x9c\xda\xac\x4d\x5d\xe5\x89\xf5\x40\xc5\xd6\x52\x19\xc0\xe5\
+\xd8\x7f\xc9\xb1\x2c\xcc\xef\xdf\x9a\x5d\x07\x06\x22\x38\x0f\x73\
+\x7d\xe6\x8a\x59\xb4\xac\xcb\x2e\xa0\x9c\x76\x06\xd4\xb2\xf5\x8b\
+\x65\x8a\x0e\xdc\x39\x0b\xd4\x28\x0c\xa5\xc8\xa7\x0c\xd4\xb2\x79\
+\x51\xbe\x5e\x85\x1e\x56\xa4\x10\xa0\x16\xde\x6b\xa2\x71\xa2\xf8\
+\x81\xcc\xbe\x0b\xb9\xd8\xa3\x91\x36\xb2\x62\x0b\xa9\x60\x40\x72\
+\x6c\x49\xfd\xc8\x5f\xba\x02\x3f\x9e\x57\x1b\x1c\x6c\x5f\x97\xc1\
+\x29\x57\xe5\x56\x27\xb0\xab\xcd\x8c\x02\x22\xd8\x96\x45\x73\xbd\
+\xc7\x71\xfa\x06\xdf\xf7\xbe\x0a\xfa\x9b\x8c\x03\x85\x86\x2d\x4c\
+\x62\xfa\x39\x78\x9e\x90\x03\xb6\xfa\x23\x46\x67\x21\xc9\xde\x23\
+\xe2\xf0\x00\x2f\x5a\xc5\x68\xf5\x58\x5d\x5d\x92\xed\xe7\xd5\xd5\
+\xa5\x59\x57\xcc\xd1\xc0\xed\xe0\x45\xcf\x92\x29\x4d\x09\x15\x0c\
+\x7f\x2a\x03\x30\x4e\x22\x19\xbc\xaa\xbe\x4c\x9c\x44\x68\x0c\xe7\
+\x82\xb7\xcc\xca\x25\x6e\x4e\xec\x09\x78\x22\xa0\xdd\x3c\x9a\x73\
+\xdc\x15\xc1\xdc\xc1\x68\x9a\x28\xb5\x45\x1a\xf6\x25\xea\xab\x97\
+\x59\x1d\x45\x1c\x36\x4d\xc6\xc7\x29\x76\x5b\xc3\x5c\x5d\x67\xe9\
+\xa9\x45\xec\x92\x7a\x8c\x14\x92\xca\x25\x3c\x2a\x82\xcc\x53\xf3\
+\xb9\xbd\xd7\x65\x20\x27\x81\x3a\x17\xc0\xb6\x56\x97\xef\x6f\x55\
+\x57\x01\xe0\x4f\xa3\xbf\x37\x63\x97\x81\x5d\x16\x75\xe5\xe3\xb3\
+\xa2\x71\x33\x3e\xf5\x64\x16\xae\x76\xf0\xec\xb6\xc6\xaa\x16\xc8\
+\xef\xe1\xa9\x0e\x0d\x5b\x7c\x9f\xaa\x12\x4e\x8f\x8a\x0e\x9b\x9c\
+\xce\xb0\x2a\xc6\x29\x9a\x0a\x56\x77\xbe\x0d\x1d\x4e\x24\x37\x25\
+\x16\xd3\x98\x78\xc5\xc4\x47\xc7\x34\xf1\xa3\x90\x7a\xd1\xcc\xa8\
+\x0f\x8e\x50\x8a\x3d\x64\x81\x95\xa1\x98\x39\x5b\x96\x85\x43\x26\
+\xa8\xae\x28\x92\xd8\x59\x29\xb7\x29\x99\x39\xa3\xde\x08\xa5\xdb\
+\x04\x84\xcb\xbc\xae\x3e\xc7\x78\x75\xc2\x33\x4b\x0f\x81\x2f\x14\
+\xdb\x94\x94\x73\xeb\xc1\x22\x89\xc6\x75\xd3\x82\xa8\x47\xdf\xdc\
+\xe7\xdd\xdd\x3f\x83\xf4\x35\x00\xde\xef\x89\xbf\xf1\xb9\xa5\xcf\
+\x22\xfc\xf5\x2c\x3a\xb6\x49\x98\x5b\xdc\xed\x8f\x21\xab\x73\x7c\
+\xf8\x16\xc3\xe4\x16\xf0\x80\x9b\x2b\x87\xb2\x95\x6c\x58\x6b\xac\
+\x71\x20\x0d\x00\x0f\x8a\x6e\x82\x72\xe6\xd3\x48\xf6\x64\xa6\x2c\
+\x31\x6d\x6f\x00\xdd\x36\x68\x83\x21\x29\x2d\xd2\x4a\xf1\x56\x3e\
+\x2e\x03\xb8\x84\x14\x71\x12\x41\x1b\x0a\xef\x6b\x12\x7b\x82\x17\
+\x08\x26\xa3\x15\xd4\xc8\xfc\x1a\x6e\x3e\xa2\xab\x2a\xac\x3a\x16\
+\xd7\x36\x35\x16\xb4\x36\x93\xc3\x3d\x0e\x57\x2f\xcb\x69\x88\x35\
+\x33\xc1\x59\xde\xc7\xb4\xae\x91\xb2\xc0\x70\xd8\xc2\x69\x0e\xd0\
+\xbc\x13\x52\x77\xe6\xdd\x90\xd8\xe0\x06\x2a\x04\xc5\xff\xd6\x36\
+\x99\xd9\xbb\x22\x03\x53\xf0\xbf\xa9\x74\xcd\xbc\xe4\x19\xf8\xae\
+\xc8\xd4\x83\x82\x27\x16\x81\x6d\xcb\xe2\x2f\x09\x22\x9a\xe4\xc2\
+\x80\xbb\xd0\x58\xf4\x93\x10\x5d\x9d\xf1\xcd\x79\xbf\x28\xc2\x17\
+\x5d\xa6\xda\x3a\x67\xe1\x2e\xab\x35\x75\x2e\xa0\x0f\x53\x9b\x85\
+\x51\xb1\x6a\xb7\xe0\x99\x1b\x8e\x03\xc1\x0c\x17\xab\x06\xa1\x98\
+\xce\xc0\x22\x0e\x15\xfa\x05\x4e\x09\x34\x55\x72\xc3\xe5\xe4\x72\
+\x75\x49\xa2\x16\x2a\xf2\xd2\xaf\x87\x82\x9a\xb2\xa2\x08\xd7\xcf\
+\xd1\xc3\x10\xe5\x60\xca\xe9\x78\x91\xbc\xf7\x50\x16\x81\x66\xa7\
+\x23\x9c\x30\x9f\xd0\x02\x2e\x0b\x44\xd3\xb2\xb8\xb4\x7e\x95\xc4\
+\xb2\xa4\xa6\xe1\xda\xe5\x90\x56\xf0\xf3\x1c\x6c\x5f\x17\x2a\xb5\
+\x48\xe1\x71\xd8\xe3\x9d\xed\xbf\xe4\xfb\x93\x2d\xfc\xa8\x3f\xd7\
+\x8a\xf4\x92\x8c\x1d\xf5\x88\x77\xb7\xfe\x07\xde\x3f\x79\x55\x06\
+\xaf\xbc\x64\x27\x19\x53\x42\x82\xa8\x47\x18\xf6\xa1\xd0\x8f\x1c\
+\x9d\x9e\x31\x7a\x0c\xde\xf1\xdb\x73\x1a\x61\x63\xc5\x94\x73\x74\
+\x6b\x35\x4b\xb6\x8c\x95\x33\x5f\x52\x5e\x73\xf4\x53\x50\xa7\xab\
+\x41\x6f\x20\x02\xf6\x49\xb0\x41\x14\xca\xc3\x39\x66\x42\x69\x2a\
+\xf4\x33\x05\x75\x34\x00\xb7\x60\x30\x98\x1d\xc7\x4c\xe9\xb6\x2c\
+\x8c\xa6\xc9\x95\x7a\x8b\xfa\x69\x93\x83\x74\x47\x66\xe2\xea\x6d\
+\xa9\x75\x93\xd5\x85\x18\x27\xf6\x69\xeb\x23\xb9\xba\xa1\x84\x0f\
+\x26\xd0\x0d\xce\xd9\xd8\x06\x62\x61\xa2\x5d\x3e\xef\x09\x61\x8f\
+\x1d\x84\x22\x48\xbd\x29\x76\x6f\x82\x4f\x82\x3a\x39\x12\xc1\x3d\
+\x6e\x90\xa7\x9e\xc4\xd8\xd5\xa6\xc7\x79\x46\x63\x3e\x33\x8f\x59\
+\xec\xb4\x65\x26\x06\x61\x81\xf0\x24\x58\xa1\x36\x05\x84\x28\x33\
+\xf1\x38\x10\x22\x7b\xd5\xf7\x05\x3b\x11\x63\xc9\x81\x4f\x2c\x93\
+\xe6\x13\xd8\x89\xaa\x07\x9b\x55\xc2\x0f\xc1\x42\x91\x04\x3a\x56\
+\x2a\x2a\xfd\xb0\x1f\x31\x1a\xa6\x58\x7d\x8d\xe3\xbc\x4f\x53\xc9\
+\x88\x6e\x6c\xca\xc5\x8c\x73\xad\x67\x33\x2f\x4c\xb4\xc5\xd1\xb2\
+\x04\xcd\x56\x62\xe0\x52\x34\x5f\x42\x99\xa1\xfd\x9b\x22\x10\xa2\
+\x0e\x29\x21\x5b\x8f\xbf\xcb\x1f\xde\xfe\xb7\x7c\xf3\xce\x7f\xcf\
+\x7b\xdb\xaf\xe2\x85\x33\x06\x21\x1f\x4e\x38\x39\xfe\xd3\xb9\xe0\
+\xad\xde\x37\xf5\x08\xb3\xd3\xc6\xe9\x74\xb0\x3a\xe2\x32\xd9\x31\
+\x42\x76\xa3\x43\xb1\x5e\xab\xd5\x9b\x5b\x49\x50\xfa\x0f\x67\xe1\
+\x89\x14\xed\x94\x01\x3c\xb4\x3d\xdc\x7c\xc6\x34\x94\xc7\x5e\x3a\
+\x1f\xac\x4f\xba\x95\x01\x5e\x32\x15\xf9\x28\xa7\xa3\xe6\xa8\xfa\
+\xf2\x1c\x35\x57\xb6\x8f\xdd\x5c\xb0\x11\x6b\xdd\x25\xce\xda\x2e\
+\x93\xc5\x11\x6b\xda\x15\xc6\xc7\x29\x87\x85\xfc\x32\x18\xa4\xdc\
+\x3b\x78\xc4\x64\x6f\xc0\xe5\xf6\x0d\x6a\xed\x53\xc8\x66\x7c\x6b\
+\x9e\x7a\x12\x2e\x8c\x2a\x7b\x33\x66\xcf\x47\x8c\x50\x64\x20\x27\
+\x41\xc4\x70\xe0\x11\x1f\xf8\x0c\x07\x1e\xc3\x81\xc7\xe8\x6c\x9b\
+\xfe\x63\x83\x24\x88\x38\x53\x4f\x18\x8c\x12\xf2\xc1\xa8\x08\x76\
+\x4d\xb2\x12\x81\x9d\xcf\x69\x2a\x3a\x6a\x3a\x87\x99\x8f\xb3\xf9\
+\x93\x48\xee\xa8\xae\xdc\xaa\x70\xa2\x84\x11\x25\x53\xe1\xa9\x8e\
+\xb0\xb1\x32\x08\xe5\xe8\xbd\xc1\x6c\x4c\x47\x21\x90\x10\x22\xaa\
+\xd0\x66\xe5\x06\x24\x2c\x13\xc7\xb4\xd0\xed\x44\x70\xbc\xe9\xfc\
+\x2f\xe0\xda\x2d\xd4\x56\x87\xdc\x12\x70\x22\xd4\x22\x29\x34\xaa\
+\x1a\x4b\x95\x38\xdb\x27\xc4\x2a\xb4\x0d\x61\x18\x11\x86\x82\x4b\
+\xb6\x2c\x93\x38\x9a\x15\x00\x86\xd9\xe7\xbd\xed\x57\xb9\x7d\xfa\
+\x15\xa1\x05\xd8\x4f\xb8\x7d\xfa\x15\xee\x9e\xfc\x2e\x3b\x93\xad\
+\x42\xfa\xf8\x06\xef\x9f\xbc\xfa\xa1\x18\xcd\x30\xfb\x95\x6a\xdd\
+\x22\xc2\xe2\x74\x30\x60\xc3\x5c\x2d\x34\x9f\x5d\x28\xda\xb8\x07\
+\xd3\x90\x83\x69\xc8\xfe\xbd\x23\xee\xef\x85\x73\xc5\xd5\x98\x29\
+\x7a\x50\xc7\x53\xcc\x19\x1c\x28\x82\x52\x63\x38\x07\x1f\x3e\x2c\
+\x90\x65\xa1\xa8\x21\xb3\x77\x19\xd4\x55\x1a\xae\x6c\xb2\xac\x3a\
+\x0a\x1f\x69\x74\x58\x6e\xc6\xac\x69\x57\xd0\x33\x31\x6c\x3a\x39\
+\xdc\x93\x9f\xf7\x68\x3b\xe5\x7f\xfc\x3f\xfe\x6f\xfe\xe8\xab\xbf\
+\xc3\x5a\x57\x5c\xa5\x9c\xe4\x54\x0c\x85\x7a\x39\x79\xea\x89\x8f\
+\xc1\x48\x7c\xa4\x9e\x78\xbe\x7c\x3c\x18\x31\x4c\x7d\x46\x28\x34\
+\xc9\xe5\xd8\x51\xab\xed\x16\xc5\xee\xa2\xc4\xc2\x6a\x14\x63\xb0\
+\x28\x5f\x8b\xbd\x93\x4a\x16\xae\xcf\x4d\x48\x97\x54\x5b\x19\xd8\
+\xba\x3a\xdf\x44\x3a\x9f\x89\xed\xb6\xc6\x59\xc7\x44\x2f\x78\xe2\
+\xb2\xa0\x2b\x27\xa7\xdd\xcc\x17\x23\xfb\xf1\x39\xf2\x45\x0b\x15\
+\xcc\x62\x3a\xa3\x1c\x10\x35\x08\xe9\x17\xa3\xf9\x17\x6e\xc5\x42\
+\xc6\xc0\xb1\xc5\x0a\xad\xae\x41\xb0\xd6\x82\x4e\x07\xbf\x58\x38\
+\x5e\x2e\x61\xec\x17\xcd\x94\xf4\x1c\xe3\x21\x99\x0d\x98\xe3\xaa\
+\xa5\x9a\xce\xb2\x68\x05\x3f\xcf\xd0\xfe\x4d\x3c\x7f\x55\x06\x6f\
+\x79\x7b\x6f\x38\xe6\xfd\x93\x57\x19\x1e\xdd\x63\x67\xb2\xc5\xd6\
+\x4e\x32\xf7\xfa\x05\x36\x20\xea\xcc\xf1\xca\x7a\xa7\x49\x72\xea\
+\x32\xda\x9f\x59\xb7\x32\xec\x4a\xfb\x56\xe5\xcc\x67\xe0\x88\xe0\
+\xea\x0d\xfa\x92\xa7\x6d\x30\x6b\x09\x97\x4c\x44\x57\x9b\x65\xd9\
+\x38\x89\x18\x28\xf9\x85\x40\x2e\x9f\xab\x06\x70\x2f\x85\x61\x3a\
+\x9c\x2b\xf4\xca\xa3\x9b\x47\x74\x5b\x16\xd7\x5b\x1e\x57\xea\x2d\
+\x26\x8b\x23\x09\x25\x76\x72\xc1\xa2\xd4\x57\x2f\xcf\x7d\xcf\xfb\
+\x5b\x11\xaf\xff\xc6\x9f\xf1\x27\xbf\xfd\x7d\x8c\x56\x46\x9e\x77\
+\xc9\x07\x23\xc6\x76\x0d\xbc\x5c\x7c\x80\x98\x60\xf6\xf2\xd9\x24\
+\xb3\x5d\x34\x7b\x8a\xd7\xcb\x40\x6e\xb5\x5d\x70\x6b\xb4\x36\x16\
+\x38\x53\x33\x5a\x6d\x17\xa7\xb6\x8a\xd5\x71\x49\xdc\x06\x7a\x4f\
+\xb4\xe4\x5a\x9a\x43\x60\x5b\xb3\xc9\x8f\x0f\x29\xf4\xb4\x40\x23\
+\xc9\xba\x12\x13\x97\x38\xb8\x9a\x8d\x83\x41\x4a\xbd\x7f\x89\x44\
+\xf5\xe7\x98\x8d\x5e\x52\xe1\x2d\x47\x0a\xba\x59\x76\xa3\xc3\x88\
+\x18\x05\x2d\x0a\x49\x02\x5d\xb4\x7d\x43\x55\x58\x3f\x15\x7b\xe8\
+\x64\xfe\x54\x02\xc1\x2f\x16\x63\xfd\x3d\xec\x02\x8e\x88\xa0\xec\
+\x17\xcb\x5c\x3a\x45\x9f\x3b\x04\x52\xcb\x22\xe9\x0b\xa1\x91\x63\
+\xe5\x85\x6e\x19\xe9\x3e\x24\x79\x64\xb2\x42\x46\x54\x6a\x76\xcc\
+\xd9\x04\x09\xc2\x27\x78\x6b\x67\x3e\x40\x9f\x6d\x35\x78\x6f\x38\
+\x06\xbe\xc2\x0b\xfc\x02\x5b\x5b\xdf\x84\x96\x08\xf4\x6b\xeb\x17\
+\x3b\xeb\x7b\xa7\x11\x8b\x49\x0f\x55\x6b\xd0\x98\x4c\x79\xe4\x3f\
+\xe4\xd1\xfd\x77\x8a\xe5\x8a\xd0\x67\xb6\xf5\xb3\xf9\xa1\xce\xa2\
+\x00\x00\x20\x00\x49\x44\x41\x54\xcf\x1a\x9b\x3f\xb4\xc9\x95\xe3\
+\x98\x38\x3c\xe0\xee\x23\x9d\x31\xe0\x72\x28\xcd\xfc\x44\x37\x6d\
+\x02\xa3\x7c\x0e\x46\x9c\xc7\xbf\x29\x2d\x06\x4a\x4e\x3b\x9f\xbf\
+\x8c\xf6\xd2\xd9\xeb\x55\x48\x12\x27\x11\x5d\x8d\x82\xf9\x88\x49\
+\x1a\x62\x9a\xf2\x78\x64\xb0\x10\x3c\x46\xc7\xa4\x7e\xda\x84\x65\
+\x18\x1f\xa7\x34\x96\x35\x29\xd4\x87\x7b\xfc\xd1\xde\x19\xfe\xd7\
+\xfe\x98\x6b\x4f\xdf\xc2\x5d\x54\xa1\x09\x8d\x51\x07\x5c\x05\x45\
+\x73\xc9\x53\x4f\x64\xe7\x36\xa2\x08\x5b\xcb\x59\x0b\x14\x46\x45\
+\x07\xae\xcc\xd0\x07\x76\x8d\x86\x16\xe3\x8f\x1d\xdc\x4c\xa1\xd5\
+\x76\x19\xa6\x3e\x8a\xa6\x30\x0e\x23\x16\xac\xc7\x64\xdd\x0d\xa0\
+\xf7\xa1\x38\xb8\xda\xae\x2e\xa7\x3e\xf4\xa0\x27\x31\xf1\x74\xe3\
+\x59\x59\xd8\x55\x6f\x0e\x3b\xc0\x75\x92\x24\x44\xd1\x5b\x24\xc9\
+\x2c\xa0\x3d\xd5\x99\x37\x4f\x31\x81\xa4\xd8\xf3\xac\xdb\x89\x64\
+\x14\x88\xc2\x79\x5f\x89\x73\x78\x19\x20\x33\x67\xff\x94\x7e\x14\
+\x51\x37\x33\xea\xa5\x1d\x7d\x81\x7b\x35\x2c\xb9\x0f\x3a\xec\x47\
+\x72\xa8\xb4\xc4\xbf\x5a\xa8\x08\x0e\x38\x8c\x24\xa4\x98\x1b\xa8\
+\xdc\x7c\x88\x77\xf7\xe7\x48\xb2\x77\x49\x86\xbf\x07\x20\x03\xf4\
+\xd1\x7e\x22\x03\x79\x6b\x27\x61\xd0\xba\x3f\xbb\xb4\x3e\x21\x23\
+\x5f\x5e\x34\x51\xb5\x06\x1d\x05\x46\x63\xbf\x22\xfa\x3f\x60\x7b\
+\xf8\x00\xff\xd1\x2e\xdb\xc3\x07\xbc\xf5\x78\x9b\x38\x3c\x60\x5d\
+\xd7\xf9\xdc\x67\x9e\xe2\xd6\x17\x7e\x94\x9f\xf8\xb1\x4d\x9e\x7b\
+\xf6\xd2\x1c\xd5\x56\x16\x5f\x55\xaa\x4c\x63\xc8\x40\xc9\x59\xc8\
+\x47\x0c\x94\x5c\x06\xe8\xf9\x00\xae\x06\xf8\x93\x20\x47\xa6\x34\
+\x59\x6c\xc6\x5c\x59\x13\x19\x7f\x67\x32\xfb\x9c\xe3\x91\xc1\x64\
+\x71\x84\x9e\x1d\x62\x5f\x3e\x65\x7c\x3c\x0b\x9e\x9b\x9b\xd7\x71\
+\x17\x37\x79\x63\x47\xe7\x95\x3f\xfa\x6d\xe8\x17\xfc\x7d\x77\x8a\
+\xa2\xb9\x24\x76\x86\xa2\xb9\x45\x07\x4f\x64\xdc\x24\x50\x8b\x2c\
+\x9a\xa1\x17\xaf\x1b\x6b\x0e\x4e\xcd\x44\xd1\x5c\x94\x68\x82\x3f\
+\x15\x18\xb9\xa5\x39\x78\x6a\x8e\x1a\xc5\xe4\x66\x9d\x8c\x1e\x81\
+\x9d\x4b\x03\x42\x89\xe5\x3d\xe7\x89\x74\x1b\x34\xe6\xd8\x89\x5a\
+\xba\x7f\x21\x80\x57\x95\x04\xbf\xb3\x39\xd3\x6a\x90\x0a\x96\xa2\
+\x80\x16\x49\x12\x8a\x4c\x5c\x95\x81\x39\x66\xb1\xe3\xc8\x2c\x3a\
+\x5c\x85\xc8\x47\xc3\x22\x0e\x23\x34\xcb\x9a\x2b\xf6\xca\x72\x6d\
+\x12\x05\xa5\x4e\x4c\x14\x86\x51\x50\x74\xc7\x66\x66\x24\x32\x53\
+\x47\xb3\x8e\x1c\x56\x86\x92\xd6\x09\xe2\x44\xb6\x8d\xe4\xe2\x46\
+\x39\x6d\x91\xe3\x14\x13\xd9\x49\xf2\x2a\xf0\x45\xf4\xd6\x97\x09\
+\xe3\x5f\xe5\x51\xc1\xc4\x5c\x5b\xd7\x79\x6f\x38\xe6\xd9\x56\x83\
+\xb7\xf6\xbf\xc2\xdb\x6f\xde\xe2\x63\x2f\xde\x9b\x0b\x74\x39\xab\
+\x95\x3f\x85\xdb\xe9\x60\x91\x11\x46\x0a\x9b\x37\xdb\x6c\xd2\xe6\
+\xf2\xa2\xc9\x4b\x67\x9f\xe2\x2c\x0f\x49\x0e\x07\x72\xed\xed\xf6\
+\xf0\x01\x93\x57\xef\xf2\xe8\xfe\x03\xae\xdd\xbc\xc1\xb5\x4f\xa9\
+\x2c\xbc\xf3\x14\xb7\x4f\x7a\xb0\x53\x71\xc3\x29\x34\x0f\xe5\xed\
+\x4c\x69\xa2\xa4\x1e\x67\x5a\x93\x85\x7c\x34\xc7\x52\x68\x0c\xe9\
+\x65\x0a\x2d\xb5\xf9\xa1\x01\x5c\xc2\x92\x6e\x33\x96\x33\x73\x92\
+\x2b\x3e\xde\x23\xa8\x2d\x62\x03\xb5\xd1\x63\x76\x9a\x97\xb8\xb2\
+\x03\x8d\x55\x0d\x8e\xc4\xc9\x78\xea\x9d\xb0\xe8\x2e\xd1\x1b\x8d\
+\x38\x7a\xbd\xcf\xdb\x1f\xf9\x16\x9f\xfc\xc9\x97\x60\x0c\x89\x9d\
+\x11\x45\x21\x4e\x31\xfe\x1e\x16\xa6\x7e\x4a\x34\xc1\x2c\x82\xda\
+\x84\x4a\x8b\x5a\x50\x72\x6b\xd4\x19\xa1\x90\x07\x53\x86\xa9\x8f\
+\x65\x37\xe8\x99\x06\x6e\xa6\x10\x14\x63\x4d\xea\xe4\x88\xac\x58\
+\x28\xa3\xeb\x16\x49\x31\x39\x5d\x35\xe3\x2e\x19\x6f\xa5\xa3\x5e\
+\xc8\xc4\x55\x6c\x5c\x4e\x76\x64\x23\x31\x0d\x9a\x24\x21\xa5\x53\
+\x4a\x13\x4d\xe4\xfd\x66\x5e\xf0\xc4\x72\x70\x31\x87\x50\x21\xb4\
+\x72\x0c\x59\xd0\x39\x18\x84\x84\x16\x72\x71\xf9\x6c\x1a\x4f\x3c\
+\x6e\x9e\xc3\xca\xa5\xdc\x32\x2e\x9c\x34\x4d\x29\xd5\x01\x8a\xac\
+\x1d\x10\x02\x2e\x81\x96\x60\x39\x3a\x61\x98\x14\x5d\xc0\x59\x6b\
+\x58\x37\x33\x32\x9a\xd4\x8a\xe0\x1b\xb4\x5e\x01\xbe\x48\x32\xfc\
+\x3d\xac\xac\xce\xb5\x75\x9d\x47\xfb\x02\xff\x3e\xbb\x2e\x32\xb1\
+\x45\x5d\x06\xf0\xf9\xdb\x33\x5d\x85\xd6\xca\x2d\x08\x1b\xf4\x95\
+\x00\xc2\x08\x6f\xff\xa8\x70\xfb\x11\x96\xfb\xc9\x24\x81\xe5\x7d\
+\x7e\x64\xfd\x69\xec\x8f\x76\xc9\xc6\xbf\xc4\x07\xdf\x7e\xc8\xdf\
+\xfe\xcd\x5f\xb1\xb7\x1f\xf2\x77\xbf\xe1\xb0\x6a\xbc\x22\xe9\xb6\
+\x83\x05\xc1\x54\xe8\x41\x1d\x37\x8f\x28\x4b\x15\x25\xf5\xc8\x35\
+\xf7\x42\x00\x0b\x38\xd1\xa2\xa5\xc2\x30\x1b\xa1\x07\x36\x0d\xe7\
+\x43\x8a\x3f\xb7\x03\x44\xc4\xa3\x88\xc3\x0a\xc4\x5a\x75\x14\xf2\
+\xe9\x29\x41\x7f\x91\x40\x69\xa2\x37\xcb\xe0\x4e\x4b\x89\xb8\xa0\
+\xfd\xbc\x13\x16\x9b\x37\x78\x5b\x39\xa0\x7b\xf0\x88\x6b\x0f\x6e\
+\xe1\x5c\x5b\x64\x1c\x8a\x55\xc0\x5e\x34\x9b\x7a\x51\x08\xc8\x4d\
+\x9b\x28\x0a\x30\x4d\x8b\x24\x50\x49\xec\x0c\x93\xa0\xa0\xcf\x54\
+\x02\xdb\xa4\x1d\x58\xf4\x19\xd1\xd2\x1c\x46\x41\x97\x66\x31\xf8\
+\x59\x76\xf7\xec\x69\x97\x32\xa3\xc9\xac\xeb\x4d\xb1\xcf\x65\xe8\
+\x71\x00\x49\xd6\x65\xb4\xbf\x3b\x87\x89\xab\xd9\xb8\x2a\xc5\xac\
+\x4e\x8b\xb8\x99\x4f\x2f\xd3\x68\x35\xad\xc2\x64\xbb\x12\xc0\x31\
+\x16\xe1\x79\xdd\xb0\x99\x12\x87\x0a\x56\xa8\x30\x31\x85\x54\x4f\
+\xc3\xfa\x7b\x2b\xed\xf2\xc4\xc8\x4c\x45\x32\x1e\x73\xf2\x4e\x20\
+\xed\x98\x44\x1d\xbd\xe8\xda\x95\x8d\x13\xf1\x7d\xc7\x56\x46\xcd\
+\x74\x51\x69\x52\x37\x67\x99\xb4\x3d\xbc\xc9\xee\xc1\x26\x7a\xeb\
+\xcb\x73\x50\xa1\xcc\xb6\x96\x2f\xde\xbd\xb7\xdf\xbc\x45\xe8\x4c\
+\x2e\xfc\x5e\x35\xf5\xbf\xc1\x9a\x5e\xe2\xc4\x3f\x65\xb4\xd7\x67\
+\x74\x16\xb2\xb5\x1f\xf0\x68\x7b\x97\xec\xf6\x6d\x1e\x6d\x6d\x13\
+\xee\xff\x2d\xea\x96\xc6\xde\xfd\x3f\x67\xe1\x83\xbf\xe3\x73\x37\
+\x1e\xf3\x33\xff\xf2\x13\xfc\xea\x6f\xfd\x77\xfc\x4f\xff\xe6\x7f\
+\xe7\x67\x7f\xea\xd3\x18\xd6\x1a\x77\x1f\xe9\xdc\x7d\xa4\xe3\x6f\
+\x9f\x48\xa1\xba\xa7\x98\x73\x81\xd8\xce\x67\xae\x8f\xe7\xe1\x03\
+\x40\x4b\x6d\x5e\xa0\xdc\x4a\x96\x02\xb7\x33\x9b\x6a\xfe\x30\xf1\
+\xcd\xf4\x94\xb3\xb6\x2b\x70\xf1\x13\x6e\xca\x66\x4b\x4c\x44\xe7\
+\x6b\xd4\x4f\x9b\xec\xe5\x6d\xc2\xa2\x59\x55\xf2\xc6\x4a\x34\x41\
+\x21\xc0\xc9\x1a\x58\xa6\x58\x38\x5f\x72\xc9\x7a\xa0\x4a\xfe\xb7\
+\xec\xf6\x0d\xe8\xa3\xb4\x9b\x45\x21\xd7\xc7\x60\x71\xd6\xd5\x2b\
+\x68\xb9\xf3\x1d\xbd\xf3\x10\x23\x48\xc5\xd8\xbe\x36\xec\xd3\x5c\
+\xdf\x98\xe3\x89\xab\x85\x5d\x75\xc6\xae\x4a\xd1\x8d\x5c\x85\x8e\
+\x2a\x6c\x00\xc6\xea\x14\xed\x17\xff\xeb\x2f\xff\x8a\x0e\xa8\x89\
+\x82\x9e\x24\xd4\x0c\x71\x22\xd5\x12\x05\x3d\x0a\xd1\x93\x04\xc5\
+\xd5\xd1\x0c\xd0\x93\x18\x8d\x84\x29\x86\xa4\xe5\x94\x22\x1b\xab\
+\x18\xe4\x24\x92\xaa\x8b\xb1\xa8\x25\xb3\xcf\x51\x99\x71\xc5\x96\
+\xa1\x93\x62\x54\x8c\xe0\x22\x62\x55\xc1\x30\x74\x30\x4d\x6c\x1d\
+\x14\xea\xd4\x4d\x9d\x20\xb3\xc8\xb5\x3a\x5e\x36\xe2\x71\xfe\xef\
+\xb8\xba\x92\xe0\x0d\x3b\x1c\xbe\xb1\x8d\x72\xa9\x18\x25\xf2\x32\
+\x3a\x4d\x95\xc3\x3c\xc4\x98\xea\x2c\xaf\xf6\x30\xa6\xfa\x1c\x66\
+\xfe\xcc\x8d\xcf\xd3\x5d\x79\x89\xae\xbd\x44\xbd\x6e\x50\x37\x14\
+\xb2\x85\x36\x76\xb6\xc6\x7e\xf2\x01\x77\xb6\x15\x26\x83\x6d\xa6\
+\x6a\x9d\xfe\x60\x80\x91\x65\xec\xbd\x99\xf3\xc6\x5f\xff\x21\x6a\
+\xf8\x3a\x6b\xa9\x4f\x67\xc1\xe3\xb3\x3f\xb4\xc6\x17\xfe\xe9\x97\
+\x59\x79\xee\x29\x06\x93\x6d\x1e\xef\xe8\x4c\xa3\x13\xe2\x72\xb7\
+\x71\x26\x7e\x66\x3a\x56\x09\xf5\x31\x2d\xb5\xc9\xd8\x8f\xa9\xd5\
+\x04\x3e\x48\xfd\x84\x7a\x2d\xc6\xf7\x35\xac\x9a\x2f\x77\xb4\x69\
+\x0c\xd1\xf5\x36\x75\x37\xa1\x6b\x59\x84\xb9\x8e\x55\xc9\x44\xd9\
+\x24\x91\x1f\x43\x2f\xa1\x55\xac\x9f\x5d\x4d\x14\x8c\xc6\x21\x8e\
+\xd9\x64\xd8\xee\xa3\x9b\x8b\xf8\x9e\x4a\xcf\x88\x51\xce\x7c\x2c\
+\x25\xe1\x99\x4f\xac\xb0\x70\xe3\x32\x2d\xd7\x66\xd5\x5d\xa6\x96\
+\xe5\xc4\x9a\x82\x12\x65\xc5\x32\x4a\xa8\xe5\x35\xd4\x58\xa1\x5e\
+\xc1\xec\xbe\x3a\xa6\x96\x8b\x00\xcc\x8c\x29\x09\x31\x6a\xdc\x25\
+\x1f\x3c\xa6\xd6\x71\x38\xeb\xeb\x9c\xa9\x27\xb4\x8c\x04\xd7\x76\
+\x19\x4d\x5b\x44\xe9\x09\x79\x6a\x52\xaf\x6b\x04\xe9\x04\x63\x9c\
+\x41\x79\x5f\x15\xef\x8d\xa1\xe6\xa4\xa9\x81\x5f\x5f\xe0\xcd\x6f\
+\x7e\x93\xe1\xe8\x84\x49\xbd\xc6\xc2\xd9\x19\x43\xd3\xc2\xd5\x14\
+\xf2\xec\x21\x6b\xaa\xcb\xc6\x33\x9b\xb4\xad\x0e\x51\xae\x12\xe5\
+\x85\x47\x45\x9c\xc9\x8c\xfc\x6b\xff\xe7\x1f\xa1\x0b\x6b\x53\x87\
+\x04\x5f\x98\xc1\x61\x61\x11\xcc\x74\x0b\xa6\x45\x1c\xce\xb2\x68\
+\x35\xb3\x96\xc1\x1a\x57\x38\xd7\x27\x57\xe6\xd6\xdc\x72\x9b\xb0\
+\x92\xad\x6b\xa1\x32\x6f\x08\x57\xb9\x1d\x4c\x32\xd6\xcc\x33\x0e\
+\x22\x91\x05\x1a\x87\x75\x0e\x82\xeb\x5c\xbd\xa2\xf3\xe7\xcf\x7d\
+\x89\x65\x7e\x67\xae\x80\x7b\x76\xbd\xc1\x23\x3f\x99\x7b\xee\xda\
+\xba\xce\x4f\x7e\xfc\x0b\x2c\x2d\xff\x27\x5c\xaa\x5f\x2d\x76\x74\
+\x44\xf2\x0a\xd0\x6f\x4c\x66\x45\xdd\x51\x4a\xef\xf6\xdb\x2c\x6f\
+\x74\x08\xba\x4b\x40\x1f\xbb\xb6\xce\x07\xbf\xb7\xc7\xdf\xd5\xff\
+\x3f\xae\x6f\xbe\x0e\xc0\x47\x3e\xb3\xc6\x27\xd7\x6e\xb1\xf1\x8f\
+\x3f\xc3\x6b\xee\x21\xb7\x4f\x74\xde\x7a\x73\x0b\xc3\x9f\xce\xb1\
+\x0f\x25\xe6\x05\x9b\xb1\x1f\x93\xd8\x21\x2d\xa7\x49\x4a\x8b\xa6\
+\x33\x94\x99\x57\x64\xab\x56\xf1\xae\x74\x8a\x63\xff\x43\xdf\xcf\
+\x72\xa2\xba\xf4\xb5\x98\x36\x2f\x09\xaa\xad\x07\x70\x0f\x75\x22\
+\x0c\x59\x0e\xfd\x14\x9a\xb0\xdc\x8c\x59\x6e\x5f\xe6\xc6\x66\xca\
+\x38\x99\x5c\xd0\xc7\x34\xe2\x0c\xb4\xf3\x97\xed\x1c\x37\x6b\xe0\
+\xa9\xb9\x94\xbd\x8a\x0c\xdd\x07\x57\x11\x8d\x92\xc6\x18\xb5\x1f\
+\x33\xb6\x6c\x8c\x54\xa3\x49\x0f\x34\x87\x51\x01\x21\x12\x54\x90\
+\xf3\x95\x36\x78\xa1\xc8\xca\xde\x94\xc6\xba\x45\x6f\x5f\x70\xd8\
+\x49\xfb\x13\xac\xd6\x1e\xb0\xdd\xee\x4a\x38\xa1\xa8\xd7\x39\xcc\
+\x61\xc2\x31\x70\x4d\xb2\x1a\x1d\x35\x95\x7c\x71\x3f\x2b\xd6\x1d\
+\xa4\x1d\x13\xc2\x14\xbd\xf0\xee\x4d\xa2\x10\xaf\xd2\xc9\xd1\x41\
+\x42\x0c\x2b\x8c\x88\x2d\xeb\x42\x73\xc4\xac\x48\xfa\xce\x5f\x00\
+\x8d\x8a\xb2\x38\x0b\x15\x72\x2b\x90\x01\x3f\xb3\x69\x61\x7e\x2b\
+\x53\xc9\x48\x98\x11\x07\x91\xc9\x42\x9e\x31\x6d\x5d\x63\xaf\xbf\
+\xca\x20\xfb\x0a\xbb\xf7\xbf\xc4\xf2\xc2\xd7\xe7\x0a\xb8\xf2\x76\
+\x6d\x5d\xa7\x15\xfc\xfc\x5c\x97\xaf\x96\x3f\xc5\x7a\x7d\x79\x26\
+\x12\x2a\x30\x77\x33\xea\x73\x82\xc9\x60\xef\x69\xe0\x51\x65\x6a\
+\xb8\x4f\x3c\x8a\x88\x2e\xf5\x78\x6a\xba\xce\x71\xba\xc8\x71\x00\
+\x3b\x77\xf7\x50\x6a\x8b\xfc\x7e\xff\x80\x1f\x68\x6f\xd3\xe8\xde\
+\xa2\xd7\x9a\x70\x39\x5c\x27\x5e\x8d\x78\xf7\xf0\x08\x86\xa2\x62\
+\x6e\x34\x0d\x81\xd7\xba\xcb\x6c\x5c\xb6\x8a\x89\x66\x97\x2c\x39\
+\xa6\xa5\xb5\x80\xd6\x6c\xbe\xc7\x2d\x27\x34\x2c\x7a\x59\x9f\x5e\
+\x56\xdc\x1f\x86\xe0\x96\xcf\x9b\x52\xbd\x56\x8a\xee\x71\x2c\x76\
+\x26\x43\xae\xec\xc0\x6e\x6e\x90\x4f\x4f\x39\xf4\x73\x8e\x07\x42\
+\x73\xac\x3a\x1a\xbd\x6c\x84\xa2\x5e\xe7\xd9\x4f\x6a\xb8\x8b\x9f\
+\x20\x88\x54\xc2\x48\xc1\xcd\x14\xbc\x22\x38\x7d\x03\xdc\xac\x0c\
+\xdc\x2e\xd0\x17\x81\x1b\x08\xad\x76\x29\xa4\x8f\x0a\xd5\x9b\xa2\
+\xb9\x15\xe8\x98\x57\xc4\x43\x8a\xa4\xe6\x02\xb7\x81\x4e\x4e\x80\
+\x8d\x4d\x3a\x5f\xd4\xb9\x35\xe1\x0c\xd4\x12\x05\x7b\x4b\xbf\xc7\
+\xe1\x14\x36\x07\x3d\xb6\xdb\x5d\x09\x2d\x56\x95\x84\x3a\xcb\x73\
+\xf8\xba\xaa\x88\x93\x3c\xb1\xc4\xc3\x61\xb9\xdb\xcd\x22\x26\xc0\
+\x28\xd4\xfe\xfd\x0a\xbd\x16\x5a\x79\x91\x27\xac\x8b\x58\xf7\x5c\
+\xe6\x45\x1a\x70\xcf\xa8\x38\xd5\xca\x49\x8b\x6c\x3f\x1b\x37\x14\
+\x5b\x4a\xcb\x5d\xce\x16\x30\x54\x72\x3a\x39\x1c\x44\x26\x6d\xa3\
+\x41\x3f\xde\x23\xed\x9f\xd1\x79\x76\x8b\x6f\xfe\xfb\x5b\xc0\x7d\
+\xd8\xb9\xf5\xa1\x3f\xff\x6a\x7d\x13\x96\xf7\x99\x2a\x2f\x73\xb0\
+\x7d\x9d\xcb\x9b\x2f\x17\xeb\xc8\x84\x6b\x8c\x19\xaa\x58\x56\x46\
+\x88\x45\x3b\xe8\xd3\xd2\xef\xd1\x2b\xc4\xef\xdd\xd6\xec\x77\x0b\
+\x8e\x2c\x76\xd4\x90\x5e\x76\x57\x9c\x14\x2b\x21\xad\x74\x91\xe5\
+\xe9\x1e\xaf\xeb\x21\xda\xc0\xe0\x8a\xb9\xcf\x6e\xb4\x3e\x87\x83\
+\xc7\xea\x94\x06\x06\x5a\x73\x80\x9b\xb7\x00\x4b\x4e\x63\x64\xfe\
+\x06\xe4\x23\x32\xa5\x89\x8a\x06\x6e\x5f\x06\xf0\xe9\xc8\x60\xb1\
+\x09\xbd\x61\x48\xcf\x35\xc1\x0d\x81\x0e\xbd\x61\xbf\xb8\x2f\xfc\
+\x28\x4a\xac\xbc\x73\x10\x62\x34\x4d\x0e\xfd\x81\xb4\xae\x3a\x1d\
+\x19\xa8\xce\xa8\xe0\x89\xfa\xe0\xc1\x83\xef\x7f\x8b\xef\xbf\x96\
+\xb3\xfe\xdc\x2a\xa1\x16\xe1\x45\x0a\x0e\x2e\x69\x60\x11\xdb\x01\
+\x35\xb3\x26\x0b\xd2\x5e\x69\x09\x30\x84\x86\x65\x62\x4e\x8b\xeb\
+\xa4\x9a\x42\xa4\xc9\x29\x0e\x80\x78\x1c\xa2\x07\x11\x8d\xc5\x18\
+\xa8\x31\xa2\x4b\x93\x1e\x8a\xe6\x62\x07\x82\x6e\x0b\x52\xe4\x5e\
+\xbb\x32\x0b\xe3\xd6\x04\xbb\x30\xec\x33\x5c\xd0\x61\x4f\x04\x6d\
+\x99\x89\x6b\x8f\x4f\x99\x5e\x5a\x64\xd8\xaa\xcb\x4c\x0c\x42\x04\
+\xe4\x5d\x18\x58\x05\x3d\x2e\x38\x62\x2a\x05\x9d\x4b\xe1\xda\x13\
+\x2a\xd2\x97\xb8\xea\x00\x64\x86\x11\x69\x31\xce\x54\xce\xdc\x95\
+\xa3\x97\xd5\xcc\x6b\x5e\x10\xd2\x17\x99\xbb\x42\xbd\x95\x59\x58\
+\x2c\x83\x34\x2f\x64\xe2\x49\x98\xd1\xa1\xc5\x59\x32\xa0\x71\x78\
+\x51\xee\x57\x7a\x50\x7c\xec\xc5\x7b\xb3\xe6\xc6\xf2\x3e\xba\xfa\
+\x1c\x64\x70\xf5\x0a\xe8\xfb\xc7\xec\x2c\x42\x27\x6b\x62\x60\x13\
+\x11\x11\x45\x30\x3a\x13\xfb\x9a\xcb\xc2\x62\xb9\x0d\xc7\x03\x53\
+\x8e\xfe\xe0\x85\xf4\xdc\x70\x2e\xa8\x03\xee\x32\x5c\x09\x79\xf6\
+\xbe\xc1\x6e\xbe\x8b\xb8\x0e\xec\x72\xa4\x39\x28\x99\x37\x33\x27\
+\x18\x29\x33\xff\x5b\x99\x41\x2d\x7a\x4e\xa9\x81\x1d\x81\x27\x5a\
+\xc9\xbd\x61\x48\x8f\x10\xd5\x0d\x39\x1d\x35\x51\xdd\x10\xbc\x7e\
+\x91\xa9\xfb\x32\x53\x0b\xa8\xd1\xa7\x97\xcd\x8a\xbe\xe3\x81\x08\
+\xd4\x4c\x69\x16\xe3\xff\x5a\x45\x38\xdf\xa1\xdb\x8a\xd8\x39\x08\
+\xf9\xf3\xbf\xf9\x36\x3f\x6a\x5e\xe5\xfa\x3f\x5a\x27\x39\x55\x21\
+\x4c\x50\xcc\x84\x1a\x35\x99\x60\xb2\x50\x41\x35\x2d\xb2\x28\xa4\
+\x99\x29\xa4\xc0\x59\x18\xd0\xb0\x4c\xb4\xb3\x29\x69\x23\x23\xee\
+\x87\x0c\x06\x43\x74\xdb\x22\x09\x42\x74\x3b\x11\x41\xab\x19\x40\
+\x4f\x76\xf8\x02\x3b\xc7\xf6\xa6\x42\x5e\x6f\xe7\xd8\x81\x22\x8a\
+\x3f\xb7\x2e\xf6\xdc\xad\x2b\x0c\x4e\x12\x5a\x67\x09\x3b\xa7\x1e\
+\x87\x8b\xae\xcc\xc4\xab\x97\x16\x39\x9c\x66\x7c\x62\x28\x32\x71\
+\xd9\xae\xee\x67\x1a\x64\x33\x83\x96\x8e\x9a\x8a\x41\x51\xbd\x17\
+\x93\x48\x6d\xc4\x19\x16\x0b\xf8\x76\x42\xde\x13\x15\xb4\x62\xb7\
+\x30\x80\x04\xd0\x7b\x3a\xd8\x7d\x30\xad\x8a\x34\x33\x42\x43\x41\
+\xa1\x47\x8e\x2d\x7c\x2b\xe4\x88\x87\x78\x2d\xaa\x9c\x24\x5a\xa8\
+\x88\x0d\x9e\xf9\x03\x31\xbb\x67\xad\x41\xa8\x14\x1c\x74\x3e\x6f\
+\xce\x9d\x2e\xa0\xe1\x61\x53\xc3\xd4\x23\xf4\xd6\x97\xf9\xa8\xf1\
+\x87\xbc\xfb\x5e\x4c\x76\x6b\x85\x5b\x9f\xbb\x83\xe5\xd7\x65\x20\
+\x03\x12\x4a\x04\xf9\x1f\xf0\xb5\xdb\xaf\x70\x6d\x5d\xe7\x36\xd0\
+\x7a\xf8\xf3\x5c\xbd\xa2\x73\xeb\xca\x75\xe2\xa8\x83\x12\x29\x1c\
+\x1f\x1c\xb2\x35\xd9\xa6\x3f\xd1\x67\x01\x51\x09\x96\x7e\x43\x81\
+\x0c\xd4\xd1\x80\x56\xbb\x45\x3f\x53\xe8\xa8\x39\xc1\x3d\x8b\xbf\
+\x56\x4c\x5c\x67\xa6\x9e\xf3\xfd\x90\x3c\xc9\x19\xfb\x31\x8d\xac\
+\x86\xd6\x14\x13\x25\xc3\x74\x48\xcb\x6b\x51\xb2\x6c\xc2\x33\xad\
+\xf4\x93\x80\x5e\x16\x16\x41\xda\x11\x01\xab\xcc\x9a\x1c\xaa\x37\
+\x2a\x68\xb6\xd2\x87\xa2\x2f\x7f\xb7\xed\x91\xd0\x1a\x7b\x8a\x09\
+\x0a\xb8\x8e\x46\x5c\x06\xa4\x53\x99\x84\x2e\x9d\x84\x0e\x42\xee\
+\xbe\xf2\x75\x5e\xfc\xe4\x2f\xf2\xec\xb3\x26\x7b\x87\x42\x28\x5f\
+\x62\x5d\x5f\x1d\x93\x9b\xf6\x1c\xb4\xd3\x81\xba\x69\x15\xd0\xc3\
+\x42\x07\x14\x26\xb4\x25\xdd\x53\xa3\xd3\xe9\x08\x3e\xd9\x9b\xca\
+\x00\x1e\xa1\x08\x28\x61\xe7\x42\xce\x99\x4e\x44\x16\x4e\x27\x82\
+\xb9\xb0\x61\x95\x7a\x11\x55\xf3\x98\x18\xa0\xf6\xf8\x14\xda\x5d\
+\x69\xb2\xdd\x51\x53\x19\xc8\xe5\xfd\xea\x94\x88\xf6\x5f\xfc\xf4\
+\x8f\xfc\x4a\x42\x88\x81\x4d\x42\x48\x42\x08\xf1\x04\x8b\x05\x01\
+\x29\x8c\x0c\x35\xd0\x89\xe3\x3e\x06\x36\xaa\x91\xe1\x27\x09\xd3\
+\x24\xa1\x96\x24\x78\x7a\x4c\x8e\x41\x14\x25\x4c\xf4\x98\x29\x31\
+\x71\x94\x00\x06\x89\xfc\x35\x21\x4b\x14\xb2\x44\x41\xb1\x72\x32\
+\x0c\xe2\xe4\x4d\x3e\xd8\xff\x36\x0b\xcd\x65\x74\xe3\x92\x1c\x63\
+\xb2\x30\x88\x8d\x9c\x3a\x53\xb4\x54\xc1\xa6\x46\x6a\x66\x4c\x26\
+\x3e\x63\xe5\x1b\xdc\x7b\xfb\x98\x93\x93\x4c\xec\x55\xde\xb9\x44\
+\xf3\xd6\x21\x9f\xfb\xd8\x98\xab\xfa\xbf\xe0\xa5\xa7\x7f\x90\xcd\
+\xa7\x9f\x26\x0d\x56\x89\xf9\x80\x7b\x47\x5b\x0c\xbc\x8c\xc3\x3c\
+\x64\x2f\x7b\x83\x3b\xfd\xef\xb0\xa8\x83\x37\x9e\xd2\x4e\x1b\x0c\
+\xec\x2d\xfa\xdf\x07\x6d\x1a\x31\x6d\xa7\xc4\x6c\x31\xad\x5f\x47\
+\x09\x85\x88\x3d\x19\x9b\xb4\xea\x09\x66\x6c\xc2\x14\xa6\xd1\x90\
+\x49\x34\x21\x74\x2d\xd2\x30\x91\x8f\x83\xc8\x44\x53\x75\xb2\x2c\
+\x21\x9e\x66\xc4\x4a\x4a\xbd\x36\x2b\x77\x4d\xd5\x24\xac\x25\x58\
+\x8a\x81\xd1\x34\x71\x4c\xa8\x4f\x15\xc2\x5a\x42\x57\xb5\x08\x73\
+\xb7\xc8\xb8\x1d\x16\xcc\x29\xe1\x28\x41\x71\x6d\xb2\xb8\x86\x52\
+\x1b\x02\x1d\xfc\xe9\x84\xfa\x24\xa1\x6f\x4c\x48\xc6\x85\xb6\x42\
+\xb1\xa9\xa1\x11\xda\x01\xc9\x38\x27\xd7\x03\x42\xc5\xc0\x3a\x57\
+\x2a\x8b\xe9\x14\x97\xb7\xb6\x1f\x92\x3c\x7a\xc4\xf2\xd3\x4b\x58\
+\x96\x42\x10\x66\xc4\x7e\xc8\xd4\xc8\x69\xc4\x19\x5a\xc3\xc0\x0c\
+\xc7\xd4\x95\x3a\x53\x45\x4c\x87\x5b\x53\xc1\x17\x5b\x53\x15\xcd\
+\xca\x31\xb3\x4b\x58\x16\x58\x96\x85\x65\x59\x34\xc9\x31\x62\x85\
+\xc0\xce\x71\xe2\x99\xd6\xc2\x88\x15\x62\x03\x8c\x71\x46\x6c\x40\
+\x9c\xa7\xd8\x81\x78\x0e\x6c\x54\x4b\x25\x1f\x2b\xdc\x79\xff\xfb\
+\x78\x8f\xdf\x66\x52\xaf\xb1\x39\xe8\x31\x34\x2d\x86\xa6\xc5\x8a\
+\xbe\xc5\xd2\xd4\x61\xe3\x99\x4d\x14\x12\xf2\x22\x60\xa3\x5c\xa5\
+\xa3\xa6\x44\xb9\x4a\x96\x25\xfc\xd6\x57\xfe\x10\xd5\x62\x01\xd7\
+\x6e\x11\xd9\x09\xae\xdd\x62\x59\xe9\xe0\xda\x2d\x74\x3b\x41\xb7\
+\x13\xc1\x5c\x74\x0d\xc2\x5c\x7c\x0e\xa6\x45\x6e\xe6\x58\x1d\x13\
+\xc5\xcc\x31\x8a\x49\x00\xdd\xb4\x30\xb0\x31\xb0\xd1\xcd\x99\xfa\
+\x21\x89\x42\x4c\xc0\x8c\x42\xcc\x28\x44\x09\xed\x19\x9e\x4e\x5f\
+\xe3\xde\xce\xc3\x62\x0a\x44\x29\x67\x92\x69\x84\x2a\x2a\x4d\x6c\
+\x12\xd2\xa2\x7d\xed\x98\x1d\xf6\x5f\xbf\xc9\xfe\xc1\x4c\x20\x74\
+\xeb\x73\x77\x24\x0b\xf1\xc2\xa7\x9e\xe1\xd6\xe6\x3f\xe1\x52\xfd\
+\x2a\x97\xd5\x29\x07\xdb\xd7\xe7\xba\x75\x96\x5f\xc7\xf2\xeb\x7c\
+\xed\xad\x57\xf8\xc3\xdb\xff\x96\xbb\xe9\x9f\xb2\xb5\x93\x30\x3e\
+\xf5\x78\x3c\x78\xcc\xe9\xe1\xeb\xb4\x94\x17\x58\xab\x59\x2c\xb7\
+\x3b\xe4\x0b\x1b\x73\xe3\x45\xa5\x26\x42\xd5\x97\xe9\x8c\x73\x94\
+\xa6\x42\x4b\x6b\x15\x45\x1a\x9c\xa4\x21\x03\x25\x27\x76\x75\x9a\
+\xce\x6c\xec\xa0\x7c\xfd\x82\x92\xae\x69\xce\x15\x6c\x42\x1f\xd1\
+\xa7\x37\x0c\xe5\x7d\x31\xf2\xd4\x14\xe3\xfa\x45\xd6\xed\x8c\x73\
+\xc9\x4b\xcf\xae\x3e\xae\x3c\xb6\xfd\xf3\x56\x58\x45\x07\xb1\x3b\
+\xa5\xdb\xbc\xc1\xab\x8f\x8e\xf8\xcb\x5f\xfd\x0e\x4d\x7f\x97\x56\
+\xc3\x43\x35\x81\x48\xc3\x37\x1c\xa2\xc1\x94\xb1\xa1\x12\xa8\xa7\
+\xb8\x99\x82\xe6\x09\x51\x8f\xe6\x8d\x69\x92\x17\x8f\xfb\x52\xe9\
+\x56\xc2\x06\x79\xe5\xb4\x73\x9a\xe4\x0c\x0b\xab\x5a\x5b\xab\xcb\
+\x6c\x6c\x07\x8a\xe4\x8b\xed\x20\x84\x20\x61\x90\xcc\xff\x9e\xdb\
+\xed\x2e\x4a\x20\xda\xcf\x47\x89\x18\x78\x9d\x70\x4c\xab\xf4\x7e\
+\xf6\xa6\xe8\xba\x45\x3f\xd3\xe6\x70\xb1\xaa\xdb\x09\x3e\x60\x06\
+\xe2\x1f\xde\xb3\xc4\x6e\x0d\x1f\xc4\x0a\x00\x53\x00\x7a\xbb\x31\
+\x73\xc1\xb4\x2d\x21\xa0\x4f\x2c\x6b\x0e\xc5\x1a\x56\x8e\x61\xe5\
+\x98\xc5\xe5\xc8\xb4\x4c\x9c\x4e\x47\xf8\xfe\x9a\x16\xe0\xa2\x12\
+\x12\x84\x21\x77\xf3\xff\x55\xd0\x43\xca\x5d\xe2\xfc\xa0\x70\xf0\
+\x11\x05\x9e\x6e\xe6\x4c\xa3\x79\x83\xef\x99\xf1\x21\x64\xb7\x56\
+\xf8\xd8\x8b\xf7\x64\x60\x86\xce\x84\xdb\xdf\x79\x9f\xa4\x7f\x80\
+\xe7\x05\x6c\xed\x07\x24\xc3\xdf\xbb\x80\xa1\xab\x0d\x90\xaf\xbd\
+\xf5\x0a\xca\xde\x1b\x38\xcf\x37\xb8\xfe\xf2\x35\x3e\x7e\xeb\x9f\
+\x61\xac\xcc\x3b\xb2\x8b\x4b\x79\x87\x7e\x43\xa1\xad\x37\x51\xf5\
+\x65\x31\xc8\xa9\x98\x74\xd4\x1c\x4f\x99\x0d\x78\xb6\x73\x45\x52\
+\x6b\x23\xdf\x96\xcd\x8b\x52\x99\x86\x27\xa0\x83\xf4\x10\x2e\x9c\
+\xe0\x05\xb6\xed\xc8\x21\xd0\x4c\x69\xa2\xe6\x23\x7a\x03\x71\xe2\
+\xa8\xf9\x88\x38\x11\x3f\xb3\x2a\xcb\x1c\x33\x65\xcc\x14\x35\x1f\
+\x49\x51\x7e\xf5\xb9\x6a\x20\x1b\xad\xde\x9c\x1b\xfd\x9f\xbf\xfb\
+\x36\xbf\xf3\x17\xc7\x4c\xb3\x45\xda\xed\x36\x0d\x2d\x46\x89\x26\
+\xe4\x66\x9d\x1c\x1b\x3b\x5b\xc4\x57\xc7\x28\x9a\x2b\x8f\x23\x14\
+\x52\xb7\x41\x93\x99\xfa\x6d\x54\x42\xc5\x73\xc3\xa7\x33\x9e\x6e\
+\x3a\xd7\xfc\x28\x1b\x22\x81\x7d\x8e\xe2\x5b\x9c\xb1\x1d\x57\xa6\
+\x16\x87\xd3\x4c\x52\x6d\x25\x3b\x51\x16\x86\x25\x4b\x51\x1e\xc7\
+\xea\x14\xd5\x9f\xfb\x25\x74\x12\x7c\x72\x33\x27\xd4\x45\x00\xf8\
+\x51\x48\x82\x2f\x46\x7e\x0a\x86\x22\x0e\x15\x6a\x85\x68\xc7\x8f\
+\x42\x92\xa2\xfb\x53\x32\x1c\x51\x18\x11\x59\xa6\x38\x16\x18\xcb\
+\x04\x22\x33\x11\x8f\xf5\x37\x61\xbf\x25\xb3\x71\x9c\x6c\x31\xee\
+\x4f\xe4\x40\x7d\x52\x14\x7d\x7e\xb9\xfe\xd4\x6e\xa0\x16\x93\xd5\
+\xed\xa5\xcb\x7c\xfe\x7a\x3e\x17\x94\x65\xa7\xee\xfb\xde\x57\x85\
+\xca\x6d\xb2\xcd\x9d\x6c\xcc\x9d\x6c\x4c\xe8\x4c\xe4\xeb\xe5\xb1\
+\xfc\xba\x37\x1b\x62\x82\xe3\xea\x15\x9d\x5b\x2f\x7d\x94\xab\x1f\
+\x79\x99\xeb\x2f\x5f\x63\xf3\x4a\x87\xfe\xd9\x90\x87\xc3\x1e\xbb\
+\x7b\x8f\xd1\x83\x3a\x63\xa6\x85\x7d\x54\x73\x6e\xa0\xb3\x1a\x58\
+\x4f\x52\xa8\xa5\xb4\x64\xa0\xe3\x09\xe6\xe1\x78\xd0\xe7\xd4\x3b\
+\xe1\x74\x64\x14\xde\x14\x21\x78\x30\x48\x46\x0c\x92\x11\x0f\xb3\
+\xfc\xc2\x15\xa0\xbc\x2a\x9c\x0f\xe6\xf3\x8f\xdd\x3c\x92\xc1\x5f\
+\x1a\x15\x1e\x0f\x90\x8b\x69\xc8\xd7\x20\x5f\xe3\x4f\xff\xe0\x2f\
+\xf9\xf6\x6f\xfc\x11\xb6\x3f\xa4\xbe\x64\xe1\xe8\xc7\x4c\x10\xb3\
+\x86\x83\xa4\x89\x93\x35\xf0\xd5\x31\x4e\xd6\x98\x1b\xfc\x2c\xb3\
+\xac\xd0\x2f\xcc\xe4\x9a\xe5\xe3\x11\x0a\x0b\x43\x45\x66\x66\x91\
+\x79\x95\x0b\x5d\xbb\xb9\x04\x55\x14\xd6\xe3\x53\x4f\x66\xe3\xa3\
+\xc1\xae\x7c\x7d\x58\x9a\x2f\x16\x27\x85\xcc\xc2\xde\x54\x2c\x63\
+\x0c\xc6\x88\x2c\x6b\x27\x24\x81\x4e\x30\x86\xa6\x69\x63\x14\x57\
+\xe2\x50\xaf\xe3\xea\x2a\x5e\x92\x15\x60\xdf\x2d\xce\x79\x11\xbc\
+\x66\xa0\x13\xd9\x09\x49\x14\xe2\x98\x56\x31\x32\x1f\xcd\xfc\xa5\
+\x8a\x63\x64\x99\x85\xdc\x33\xb8\xf0\x47\x6c\x1d\x64\x3c\xbb\x19\
+\x10\x16\xd6\x54\x94\x36\x01\x66\x0e\x4a\x80\xe7\x5b\x50\x04\xf1\
+\xe6\x95\x0e\x3f\xf2\x85\x7f\x0e\xc0\x77\x1f\xff\xb7\xf4\xf7\xaf\
+\xd2\x79\x76\x0b\x02\x38\xd8\xbe\xce\xd5\xba\x28\xa8\xfc\x37\x5f\
+\xc2\x79\xf1\xdb\x32\x70\xcb\xe0\x2d\xb3\x77\xf9\x58\xd9\x7b\x03\
+\xae\xbc\xc4\xfd\xad\xdb\x5c\xcf\xea\xa8\xd7\x5f\xe0\xea\x15\x9d\
+\x1f\xf9\xd1\x7f\xcc\x2b\xaf\xbe\xc9\xd6\xdd\x0f\xe8\x9f\x0d\x45\
+\x23\x23\x19\x61\xf8\x17\xf9\xec\xb1\x1f\xd3\x70\x0c\x19\xc0\x0d\
+\xc7\x28\xda\xcd\x23\x5a\x6a\x53\xe8\x90\x2b\x6a\x35\x06\x14\x9c\
+\x0f\xc5\xfd\x99\xe6\xe2\xc3\x4e\x88\x32\x98\xcf\x4f\x90\x9c\x1f\
+\x7d\xea\x8d\x14\x68\x0a\x49\xa8\xa1\x97\xde\x6e\xa5\x21\xcc\x10\
+\x9a\x33\xac\xfe\xd5\x6f\x7c\x93\xb3\xe3\x01\x3f\xfc\x4f\x3b\x74\
+\x9f\xf9\x0c\xab\x78\x0c\xc7\xa0\xd5\xce\xf0\x58\x40\x89\x34\xa8\
+\x95\xfc\xb1\x22\x8e\xb8\xe4\xc5\xef\x2e\x82\x37\x9f\x0d\x96\xda\
+\x19\xcd\x00\xce\x5a\xb9\x54\x8b\x88\x39\xbd\x69\x25\x0b\xe7\xd8\
+\x41\x48\xa2\xa5\xe8\x5e\xc6\x43\xcf\x94\x9d\x5b\xc7\x1e\x41\x30\
+\x62\xa5\xbd\x51\xb4\x9f\x45\xcc\x65\xf5\x15\x49\xcd\x05\xa9\x26\
+\x1c\x86\x0a\x0f\xa3\xb1\x1f\xa3\xdb\x0d\x70\xcd\x9c\xb8\x67\x10\
+\x72\x46\x57\x59\x90\xdf\x34\x02\x5c\xbd\xe8\xa3\xbb\xe5\x1b\xea\
+\x4b\x52\x7b\xd6\x53\xf7\x67\x9a\x89\x32\x78\x2d\xb3\xb0\x29\x2c\
+\xec\x0a\x8b\xe7\x13\xcb\xe2\xe1\xce\x07\x73\x63\x43\xcf\x2c\xdd\
+\x25\x08\x3f\xc9\x25\x6b\x26\xfe\x91\xbb\xed\x2c\x18\x26\x6f\xb1\
+\x3f\xed\xb1\xe7\xef\x73\xd9\x59\xe7\xda\x62\x39\x46\xff\xbf\xc0\
+\x25\x48\xb2\x77\x79\xe5\x9b\xdf\xe0\x70\xfd\x5d\x86\x76\x03\x6f\
+\xef\xe7\xd8\xbc\xd2\xe1\xf4\x4e\x97\xe8\xa5\x43\x09\x39\x9e\x14\
+\xd0\xb1\xfb\x00\x78\x89\x9b\x57\x5f\x20\xc9\xde\x25\xcb\xde\x85\
+\xe3\x75\x92\xe5\x77\x79\xf9\xc6\x35\x2e\x5f\x56\xd9\xbd\x7f\x48\
+\x7c\x24\x9a\x19\x49\xe6\x49\xdf\x88\x93\x34\x04\x05\xda\xce\xfc\
+\xf8\xd5\x30\x1b\xc9\x8e\x9d\x10\xf9\x58\x45\x70\xb7\x24\x7b\x41\
+\xa1\xc0\x2a\x4f\x80\xea\x11\x57\xa7\x9d\x2b\x4f\xcc\xec\xd5\x00\
+\xd7\x18\x72\xa6\x34\xe7\x3f\xa7\x99\xc3\x48\x41\x6b\x0e\x88\x93\
+\x52\x70\x2f\xe6\xf8\x1a\xd4\x0a\x1e\x59\xa3\xab\x46\xdc\xdf\x8a\
+\xe8\x0d\x5f\xe7\xde\x5e\xc2\x33\x5f\xac\xf1\x23\xff\x68\x93\x56\
+\x0b\x86\x63\x17\x8d\x33\x2c\xad\x4e\x62\xd7\xc4\x30\x69\xa1\xb3\
+\xa0\x36\x7f\x12\x6b\xca\x18\xdd\x6e\x08\xc1\x50\xa0\x32\x2c\x34\
+\xc8\xb4\xcb\xc0\x16\x6c\x84\x1d\x08\xf8\xd1\x0c\x20\xb0\x2d\x6c\
+\x52\x12\xb7\xc1\x75\x37\x62\x67\x20\x78\xe2\xfb\xa7\x4d\x21\x06\
+\x7a\x7c\x8a\x52\x0b\x19\x5e\xba\x4a\xdb\x74\x60\x72\x44\xe6\xae\
+\xcc\x0d\xa3\x06\xe9\x84\xc0\xb6\x05\x13\xf4\x4b\x3f\xfb\xcf\x7e\
+\xc5\x1b\x8d\x04\x2b\x01\x18\xd8\x04\xca\x94\x2c\x31\x41\xcf\x25\
+\x84\xb0\x42\x85\x28\xca\x69\x64\x6a\x05\x50\x1b\x98\x7a\x4e\x4d\
+\x37\x98\x26\x09\x59\x92\xa0\xea\x86\x50\xc1\x85\x29\x86\x21\x9a\
+\x22\x13\x1c\x8c\x24\x2e\x06\x46\xa1\x37\x18\x93\xe6\x6f\x89\x81\
+\x46\x4b\x01\xf5\x0a\x0b\x8d\x8f\xa2\x1a\x16\x49\x92\x60\xe8\x3a\
+\x09\x70\x12\xbe\xcb\x69\xff\x5b\xbc\x7b\xff\x1b\x7c\xf0\xad\xaf\
+\xd2\x7f\xb8\x4c\xf7\xd9\x36\x37\x6e\x3c\x83\xe9\x3a\x2c\x2d\x98\
+\xb8\x8d\x26\x23\xcf\xe2\x7b\xfd\xaf\x62\x4c\x75\x06\x5e\x46\x50\
+\x7b\x0b\x3b\xbc\x45\xbd\x13\xe2\x7a\x97\x88\xcc\x99\x96\xa2\xd3\
+\x54\xe9\x34\x55\x96\xcc\x1a\x9d\xa6\xca\xdd\xd1\x84\xa3\xbb\x43\
+\xf2\xbd\x3b\x74\xd3\x4d\x9e\x6e\xe7\x9c\x3a\x1e\x5b\x3b\x09\xc3\
+\xed\xbf\x62\xab\x77\x9f\xcd\xeb\xcf\xd3\x55\x1f\x60\x2d\x5d\xa1\
+\x33\x99\x72\x96\x4d\x38\x8b\x62\xda\xb9\x82\x89\x08\xb6\xd4\x4f\
+\xa4\x3e\xc2\x54\xea\x4c\xf2\x09\x93\x7c\x82\x1e\x58\x24\x76\x88\
+\x1a\x1b\xc4\x85\xb8\x25\x6c\xf8\xa4\x89\x3a\x7b\xac\x8f\x51\x63\
+\x83\x5a\xa4\x13\x34\x0b\x48\xa6\x5c\xd4\x1e\x0f\xb3\x11\xa6\x52\
+\xc7\x44\x61\x98\x8d\xa8\x29\x2d\xf9\xf3\x4d\x14\xc1\x4d\xd7\x41\
+\xab\x0f\x49\x47\x6d\xa8\x43\x98\x8b\x40\x9e\x2a\x3a\x35\x34\xd4\
+\x7c\x04\x75\x8b\x4b\x2f\xbd\xc4\xca\xd2\x06\x7b\x3d\x9b\x93\x41\
+\xcc\x3b\x6f\xbd\xcd\x69\x3f\xc2\xe8\x8f\x68\x99\x1a\x8e\x69\xa0\
+\x28\x21\xea\x74\x04\xf9\x90\x3c\xd3\xa8\xa9\x19\xe4\x53\x5a\xb6\
+\xcb\x24\x9f\x42\x3e\x45\x49\x5c\xb2\x58\x21\x4f\x3d\x0c\xc7\xc0\
+\x4d\xeb\x4c\xa2\x29\x13\x23\x46\x51\xeb\xa8\x46\x2e\x33\xb0\x13\
+\x97\x9c\x71\x82\xde\x70\xe8\x07\xf0\x17\x6f\xec\xa2\x46\x87\x4c\
+\xea\x35\xe2\x60\x4a\x9d\x53\x06\xee\x32\x18\x4d\xae\x25\x09\x4b\
+\xb7\x56\xc9\xda\x4b\xe8\xc3\x9c\xd8\x00\x3b\x48\x08\xf4\x1a\xb6\
+\xa6\x62\xa8\x39\x5f\xf9\x77\xff\x2f\xba\x17\x0c\x99\x9c\x4e\xa5\
+\x97\x6f\x54\x92\x62\x66\x4a\x68\xe5\x24\x5e\x8e\x8e\x82\x97\x64\
+\xb8\xba\x2a\xf1\x6f\x5e\x30\x13\x11\x08\x88\x50\x39\x41\xad\x0a\
+\x87\x1c\xa3\x80\xe5\x63\x58\x14\x13\xd5\x17\x95\x59\xef\x9f\xbc\
+\xca\xd3\xee\xcf\x90\x5a\x42\x5f\x11\x02\x51\xf8\xee\xdc\xb8\xfd\
+\x9d\x2c\xc6\x9f\x86\xdc\xd2\x6f\x48\xfd\x43\x84\x82\x69\x9a\x34\
+\x2e\x4d\xf9\x78\xe7\x17\xf8\x56\xfc\xab\x32\xdb\xa6\xfa\x3d\xb4\
+\xe4\x16\xa9\x2e\xbc\x8c\x3b\xcf\x6e\xc9\x51\xa6\x6a\x46\x6e\x0f\
+\x6f\x72\xe9\x6c\x83\xef\x05\xb7\xf9\x93\xd7\xfe\x84\xf5\xb5\x80\
+\xc5\xd5\x4f\xf3\x03\xed\x98\x23\xfd\x53\x90\xbc\x22\x26\x45\x10\
+\xf2\x82\xfa\xb5\x0d\x9e\xbf\x15\xb1\xf7\x70\x91\xc1\xc9\x9e\xc8\
+\xca\x5e\x42\xec\xea\x0c\xd3\xd1\xb9\xa9\x67\x6b\xee\x98\xd8\x21\
+\x7a\x60\xc9\xc0\xae\xbe\x06\x30\x74\x86\x18\x9e\x55\x29\xde\x90\
+\x5f\xd7\x52\x9b\xe8\x81\xc5\xc0\x15\x42\xfb\x96\x2a\xb2\x3a\x88\
+\x2b\xc1\xd8\x8f\x69\x34\xcb\x8c\xde\x82\x66\x8e\x36\xe8\xd3\x5a\
+\xe8\xe0\x29\xa6\xf0\xc1\xf0\x22\x70\xe1\xb3\x9f\xdc\xe0\xa7\xff\
+\xf9\x17\x59\x59\xb9\xce\xeb\x6f\xbc\xc7\xb7\xbf\xf5\x1d\xd9\xe6\
+\x3d\x8a\x1e\xb1\xb6\xb7\x44\x6d\x51\x9c\x60\xf5\xfe\x25\xbc\xf4\
+\x14\xb7\xd8\x9b\x93\xe7\x5d\x89\x8b\xe7\xa6\x43\x4a\xec\x5b\x8e\
+\x3c\x15\x18\x39\x28\x47\x9c\x02\x24\x7f\xfc\x61\x37\xa7\xd8\x99\
+\xbd\x39\xe8\xb1\x53\x0b\x69\x5c\x11\x23\x57\xb6\x3f\xc4\xb7\x3b\
+\x12\x9a\x88\x4c\x2c\x06\x52\xc7\x7e\x8c\x6e\xb1\x00\x8b\x67\x34\
+\xbb\x39\x61\x41\x97\xc5\x04\x8c\x73\x0b\x95\x00\xdd\x55\xc8\x02\
+\x1b\x57\x9f\x15\x70\x12\x87\x15\xf8\xb6\xa4\xd9\xb0\x4c\xe2\xb0\
+\x87\x81\x2d\xb3\x77\x39\x64\x12\x87\x63\xa9\xac\xb8\xba\xa6\x72\
+\x77\x6f\x5e\xe7\xfb\x68\xf4\x06\xcf\x76\x5e\x16\xd6\x53\x51\x9f\
+\xbd\x9d\x87\x90\xbd\x26\xa7\x94\xf3\x3b\x5d\x1a\xc6\x5d\x36\xb4\
+\x44\x2e\x89\x29\x27\x4a\x26\xd6\x75\xae\x5e\xb9\xc7\x5b\xb7\x67\
+\xc1\x39\x68\xdd\xa7\x3d\x84\x6c\x6f\x83\x61\x7e\x1b\x10\x94\xcd\
+\x0f\x76\x0e\x41\x05\xbd\xf5\x65\x76\xef\x1f\xb2\xbd\xd3\x67\xff\
+\xec\x84\x7c\xe1\x29\xda\x4b\x00\x77\x39\x3d\x7c\x9d\xdf\x7f\xd3\
+\xc2\x5e\xf9\x1e\x4f\xdb\x2f\xf0\x78\x61\x97\x6b\xba\xcd\x23\x66\
+\x3a\x8d\x95\xd4\x47\x51\x73\xfa\x4d\x85\x58\xd1\x31\xbc\x84\xc4\
+\x9e\x0f\xe0\x32\x68\xcf\x07\x75\xf9\x7c\x62\x87\x44\xc9\x18\x33\
+\x98\x15\x4f\xcd\xc4\x67\x54\x70\xa2\x0d\xc7\x60\x98\x8d\xe8\xaa\
+\x39\xbd\x6c\x44\xcb\x69\x42\x2e\xd8\x8f\xc4\x1e\xd1\x75\x72\xc9\
+\x86\x94\x9f\xab\x63\x49\xec\xad\x2e\xae\x42\x51\x10\xf6\x06\x70\
+\xb3\x6b\xb1\x79\x75\x83\x9b\x57\x63\x56\xf3\x57\xb9\xd4\x35\xf9\
+\xe9\xff\xfc\x26\x2f\xbd\x20\xae\x20\x4d\x7f\x97\x83\xf4\x29\x9c\
+\xf8\x21\xf5\x7e\x8d\xc3\xd4\x66\x3a\x7d\x8d\xc9\xe3\x65\x98\x7e\
+\x1f\xd7\xfa\x2c\x63\x77\x42\x23\x10\x70\x28\x77\xbd\xb9\x40\x3e\
+\x98\x9e\xd2\xd0\xea\x2c\x0c\x15\xce\x5a\xa2\xc8\x23\x50\xd0\xed\
+\x8c\x51\xa0\x8a\xc2\x2f\x50\x19\x21\xbc\x90\x75\x6f\x3c\x6f\xc2\
+\x12\x34\x71\xd8\x67\xbb\xbd\x8e\x12\xec\x73\x10\xe9\x7c\xec\x43\
+\x02\xbe\xd4\x62\x34\x1c\x03\x35\xb2\x13\x8c\xee\x0a\x8f\x13\x93\
+\x98\x00\x2f\xc9\x48\x2c\x0b\xd5\x2e\x46\xa5\xbd\x9c\x2c\x1d\x13\
+\x13\x10\xea\x75\xf2\x8a\xb7\x5a\xc9\x0b\xcf\x04\xf5\x91\xdc\x8e\
+\x94\x05\x76\x25\x33\x8f\xe7\xf5\xc4\x8f\x6f\x80\xf6\xd9\x0b\xe3\
+\xf4\x23\x80\xfe\x84\xbd\xca\x34\x73\xa9\x5e\x7b\x27\x5e\x60\x1c\
+\x3f\xc5\xd6\x64\x1b\xf2\x07\x98\xa6\x89\x1a\x99\xc4\xb9\x4b\xbb\
+\xa3\xa3\xab\xcf\xf1\xf1\xce\x2f\xcc\xd1\x68\x83\xd6\x7d\x86\xf9\
+\x6d\xc6\xf1\x53\xf4\x77\x7b\xf4\x77\x7b\xec\xbc\xf3\x29\xf4\xb3\
+\xcf\x03\xf0\xb9\x2f\x6e\xf0\xc3\x3f\xfe\x53\xac\xff\x60\x84\x7f\
+\x75\x11\x7f\xfb\x84\xbd\xa3\x65\xf6\x8e\x96\xc9\x17\x36\x04\xe3\
+\x11\xdc\x26\xb9\x67\xf2\x60\x4b\xb8\xa5\x2c\x1d\x5a\x64\x7b\x1b\
+\xe8\xb7\x4a\xc5\xd9\xec\xb2\x9f\x6b\xae\xcc\xb4\xd5\xa0\x8d\x92\
+\xf1\xdc\xb1\xfa\xba\xa9\x37\xe4\x6b\x7a\x60\xd1\x6b\x6a\x73\x05\
+\x63\xae\xb9\xa4\xb4\xe4\xd7\x48\x35\x9c\xda\x94\x54\x5e\x62\x87\
+\x0c\x33\x51\x44\x36\x1c\x43\xaa\xe3\x4a\xe7\x21\xd7\x89\xf8\xe2\
+\xf3\x5d\xbe\xf0\xc3\x57\xf9\xf1\x1f\xba\xc9\x0f\x3d\xb3\x49\xef\
+\x24\x25\x7a\xf0\x1e\x83\xb7\xbf\x49\xd3\xdf\xa5\xe9\xef\x32\x8a\
+\x0e\x58\x2b\x46\x6f\xce\x3a\x26\xdd\xd6\x7d\xa8\x3d\x4d\xfd\xd2\
+\x31\xd4\x9e\xc6\x4b\x4f\x31\xf4\x87\x28\x69\x4f\x7c\x28\x3d\xf2\
+\xc1\x48\x4e\x4a\x37\x02\x31\x84\x7a\xd6\xca\x65\x26\x16\x0e\x9c\
+\x42\x40\x34\x42\x11\xd6\x59\xc5\xf4\x48\xe2\x36\x68\xe9\x22\x31\
+\x6c\x0e\x7a\x17\x02\xb5\x35\x9c\x08\x4c\x5c\x72\xce\x55\x9d\x72\
+\x51\xe8\x8d\xfd\x18\xbd\x0c\x4a\xc1\x40\x98\xa2\x90\xab\x24\x5c\
+\x8f\x1c\xdd\x55\x30\x42\x9b\x88\x8c\x28\x31\x71\x4d\x55\x36\x32\
+\xf4\x62\x01\x4d\x49\xaf\x59\xc5\x64\x48\x23\x0c\x67\xc5\xdd\xb9\
+\x25\x36\xc9\xfa\x32\xec\xcc\x67\xe2\xa9\x72\x17\x3d\xfc\x24\x5e\
+\x6f\xc4\x54\xb9\x3b\x17\xdc\x7b\xfd\x55\x3e\x6a\x9c\xb1\x7f\x10\
+\xa2\xec\x05\xa0\x7c\x89\x96\xe9\xd2\x32\x61\xdc\x6d\xc0\x3e\x1c\
+\x65\xef\x4a\x1a\xad\x9c\xf8\x00\xe8\x6c\x74\x19\x3f\x2c\xde\x14\
+\xe5\x05\xb2\xf0\x84\x37\xf7\x0f\x60\x1f\x94\x6b\x97\xd9\xfc\x0c\
+\x5c\xbb\xfc\xaf\xf8\x51\xe0\xfe\xf5\x4b\xec\xde\x3f\x64\xe7\xcd\
+\xb7\xe1\x6c\xc4\x78\xa1\xd8\xd9\x61\xde\xc5\x0d\x61\xb8\x2b\xe4\
+\x31\xe3\xb8\x41\x63\xb7\x07\x95\x3d\x76\x73\x7f\x9f\x1d\xd2\x55\
+\xf3\x22\x63\x86\x5c\x1a\xe5\xf4\xec\x10\x33\x68\xcc\x65\xda\xc4\
+\x0e\xe9\x8e\x52\x1e\xa3\xc8\x60\x3e\xff\x7d\x16\xf2\x9c\x5e\xa6\
+\xa0\x33\x9f\xd1\x35\x47\x48\x3c\x7b\x99\x42\xae\xb9\xf2\x44\xea\
+\x6a\x85\xfb\x66\x1e\xd1\x6a\xb7\x58\x6e\x77\xf8\xec\x8b\x2b\x34\
+\xba\xb7\x78\xea\x6a\xca\x92\x95\xb2\x6a\x6d\x30\x71\x84\x19\xcc\
+\x28\x3a\xa0\x69\x8a\xbf\xa3\x3c\xd6\xfd\x35\x70\x1e\x52\xf7\xd7\
+\x84\xef\x83\xb5\x21\x9d\x81\x0e\x0f\x76\x61\x4d\xc0\x0c\x3f\x69\
+\xd0\x70\x15\x5a\x9a\x23\xe6\xee\xda\xae\xec\xd8\x55\xa9\xb8\x79\
+\x88\xa5\x82\x2d\x5c\xe6\xf3\xbd\x5d\x86\xc9\x2d\x74\xbe\x27\x5a\
+\xce\x15\xaa\xcd\xb1\x91\x83\xaf\x92\x9d\xb0\x2b\x22\xa2\x0a\xc5\
+\xa6\x8a\x3d\x15\x02\x1a\xcc\x18\x08\xe1\x92\x13\x13\xa0\x6a\x0d\
+\x12\x2f\x97\xd0\xc1\xd5\x55\x99\xb1\xcb\x13\x20\x0e\x95\x39\xea\
+\xac\x8a\x89\xcf\x07\x30\x61\x84\x85\xc5\xd3\xee\xcf\xcc\x65\x63\
+\xd2\xd7\xe8\xab\x23\xb6\x92\x7b\x17\x3c\x23\x2e\x77\x0e\x19\xc7\
+\x4f\xd1\x51\x73\x6e\xbc\xfc\x8b\xfc\xc0\x0f\x76\x68\x2d\x6f\x62\
+\x77\x5b\x58\xbd\x43\xa2\xc1\xf7\xd9\x3d\xd8\x64\xf7\xfe\x21\xed\
+\xe1\xcd\x0b\x6f\x5c\xb9\xec\xf0\x60\x1a\xe2\x99\x07\xb8\xd1\x1a\
+\x2d\xe5\x05\xee\xbd\x9f\xf1\xf5\xff\xed\x1b\xfc\xd9\xaf\xfd\x1a\
+\xde\x1b\x7f\xc2\xd5\x2b\x3a\x9f\x7b\xee\x25\x3e\xfb\x5f\xfe\x04\
+\xf9\xc2\x06\xca\xd9\x2e\xca\xd9\x2e\xe3\xf8\x29\xa9\xab\x08\x8e\
+\xd6\x68\x18\x77\x09\x8e\xd6\xe8\x67\x83\xf9\x2e\x5c\x81\x8d\xf5\
+\xc0\x92\x59\x12\x90\x41\x0b\xf0\xb8\xca\xec\x8c\x32\x46\xba\x83\
+\xde\x54\x2f\x40\x8e\xf2\x7e\x2f\x53\xe6\xb2\x70\xa3\x60\x42\xce\
+\x14\x91\x75\x5b\x6a\xf3\x42\x01\x58\x8e\xf8\xbf\x78\xfd\x29\x3e\
+\xfb\xe2\x0a\xb7\xd6\xae\xf1\xd9\x67\xa6\x2c\x59\x29\xdd\x25\x4d\
+\x06\xb0\x0c\xd8\x22\x98\xcb\xdb\xc4\x99\x05\x76\xf9\xb9\x87\xe1\
+\x2e\x87\xe1\x2e\xab\xd6\x06\x0b\xfd\x08\x2f\x3d\xc5\xd1\xc7\x84\
+\xc6\x84\x7d\x75\xd6\xfc\x10\x7a\x11\x5f\x36\x48\x12\xe9\x87\x5c\
+\xb0\x5c\xc5\xfd\x0e\x19\xca\xe5\xf5\x0b\x5c\x71\xb5\xf9\x31\x3e\
+\x4e\x19\x44\x3e\xea\xe4\x68\x46\xd7\x79\x53\x02\x7b\xd6\x29\x1c\
+\xfb\xf1\x6c\xb8\xc2\xc0\xc6\x08\x91\x7c\xb0\xa0\x54\x14\x32\x5d\
+\x5c\x02\xa7\xf9\x02\xa6\x7e\x86\x97\x98\x72\x6a\x2e\x4a\x4c\xa6\
+\x9a\x25\x0c\xad\x8b\x13\xc1\xc0\xe6\x1f\xbc\x85\x11\x56\xc7\xa4\
+\x36\x7a\x8a\xa9\x86\x2c\xde\x3e\xd4\xec\xc4\xbb\xc1\xe6\x95\x0e\
+\x5c\xe9\x70\x79\xd1\x64\xf7\x9e\xce\xc3\x83\xef\x72\xf4\x1f\xfe\
+\x8a\x07\x8f\x63\xf6\xfc\x7d\x36\x54\xb1\xae\x76\x3b\xba\x47\xe3\
+\xb0\xce\xb5\xf5\xd9\xf8\x92\x6a\x2d\x41\x3e\xfb\x27\xa9\xd6\x12\
+\xc3\xfc\x36\x2e\x6b\x44\x97\x7a\x18\xd1\x1a\xbf\xff\xd7\xef\x63\
+\xbf\xff\x3d\x99\xbd\xd7\x6a\x1b\x1c\x54\x02\xb9\x0c\x60\xe8\x13\
+\x1c\x95\x26\xd7\x0a\xf9\x28\x97\xd8\x6c\xec\xc7\x18\x9e\xf8\x99\
+\x4d\x27\x98\x0b\x40\x3d\xb0\x04\xfe\xd5\x1b\x02\x3a\x34\x55\x49\
+\x15\x57\x03\xb7\x84\x16\xd5\xcc\xdc\x74\x82\xb9\x93\x22\x76\x05\
+\x06\xa7\x08\xe8\xaa\x3f\x45\xa9\x3f\x7e\xe6\xc5\x5b\xdc\xbc\x1a\
+\xb3\x62\x5e\x43\xff\x84\x06\xfd\x6c\x2e\x70\x27\xce\x81\xc8\xc2\
+\x8b\x6b\x73\xd9\xb8\x7a\xbf\xbe\x08\x9c\x8a\xcf\xbd\xba\xb8\x21\
+\x02\xdd\x87\xe1\x60\x93\xd5\xf6\x36\x67\x1c\x63\x27\xcb\x88\x66\
+\x6f\x5d\x62\xe3\xb2\xd0\x2b\x1f\x57\x03\xb9\x0c\xe6\x91\x12\x31\
+\xd8\x3d\x45\x1f\x7c\x4f\x06\xee\xf8\xd4\x13\x8b\xd4\x03\x91\x89\
+\xcb\xb6\xb3\xaf\x6f\x80\x2e\x54\x71\x12\x13\x17\x8c\x87\xa0\x7f\
+\x8b\x46\x46\x99\x61\xc1\xc4\x4a\x26\xb2\x63\x27\x05\x4b\xca\x19\
+\x06\x36\x53\x4d\xe0\xe5\xc4\xcb\x31\xf5\x08\x88\xf0\x12\x13\x53\
+\x17\x27\x42\x4c\x80\x11\xb9\xc4\xa6\xf7\xa1\x01\x6d\x58\x82\x2e\
+\xbf\xbc\xf9\x32\xde\xe4\x16\x27\x85\xe3\x69\x47\x7d\x30\x37\x2a\
+\xf9\x4c\x57\x61\xe7\xdd\x1a\x37\xd6\x2e\x91\x6f\xc1\xc3\x83\x88\
+\x0f\xfe\xe2\xbb\x7c\xe5\xbd\xff\x8b\xc3\xc3\x13\xb1\xbc\x25\x89\
+\xb8\xd9\xb9\xc1\xee\xc7\x1b\x6c\x04\xfb\x5c\xbd\xfe\x79\x39\xd2\
+\x2f\xab\xfe\x02\x17\x5f\xbe\x7e\xca\xde\xc3\xa7\x68\x15\x34\xed\
+\x91\xe6\x70\x79\xe3\xff\xe7\xec\x4d\x63\x24\x49\xef\x33\xbf\x5f\
+\x44\x46\x1e\x91\x77\x66\xdd\xdd\x55\xdd\x5d\xd5\xdd\xc3\x69\x0e\
+\x39\x33\xa4\x48\x91\xa2\xa4\x15\xe1\x7e\xba\x07\x00\x00\x20\x00\
+\x49\x44\x41\x54\xb5\xdc\x5d\xd0\xdc\xc5\x7a\xd7\xd2\xae\xbd\x6b\
+\x08\x82\x05\x08\x86\x77\x05\xfb\xc3\x2e\x20\xd8\x1f\x6c\xd9\x30\
+\x60\xaf\xe1\x05\x0c\xfb\x83\xf5\xc1\xb2\x56\xb0\x21\xcb\xd6\xb5\
+\xb2\x6e\xea\xe0\x50\x9a\xa1\x66\x28\x72\x86\x33\x54\x4f\xcf\x74\
+\x75\xd7\xdd\x75\x57\x9e\x11\x19\x79\xc4\xe1\x0f\x6f\xbc\x6f\xbe\
+\x11\x99\xd5\x43\x39\x1b\x8d\xc8\x23\x32\x2b\x33\xe2\x79\x9f\x78\
+\xfe\x77\x93\xa3\x9d\x32\xa5\xd5\x63\x06\xa7\x36\xc5\x55\x0f\x7f\
+\xbb\x00\x5c\x50\x2a\x1c\x53\x5b\x7b\x45\xbd\x5f\x82\xb9\x45\x15\
+\x23\xec\x63\xf6\x3a\xaa\xc0\x53\x1a\x57\x92\x1d\x74\x00\x2b\x2d\
+\x5c\x35\x19\xf6\x04\x80\xfd\x5e\x48\xc1\x2a\x31\xa9\x58\x04\xed\
+\x2e\x05\xab\xa4\x0c\xbe\x82\x25\x64\x47\xab\x9a\x11\x6c\x5c\xf4\
+\xb0\xe2\x85\x22\x19\xbf\x54\xce\xce\x74\xd3\x14\xe9\xa4\x0d\x7e\
+\xf4\xae\xc9\xb8\x3a\x61\xa5\x52\xa4\xbc\x60\xb0\xd4\x8e\xdb\xd4\
+\x2e\x65\x68\x5d\x04\x34\x97\x8e\x15\x98\x7b\x1c\x0b\x50\x3b\x24\
+\x18\x5a\x82\x39\xbf\x08\xce\xe5\xe7\xd9\xeb\x5e\x02\xf7\x58\xcb\
+\x0c\xa8\xd5\xf7\xb5\x90\x76\x48\x8d\x3e\x93\xae\x8b\x63\x2d\x02\
+\xd3\x28\x9f\x9e\x3c\xaf\x87\xa4\x1d\xd3\xe5\x56\x54\x25\x73\x23\
+\x8b\x5f\xff\x34\x56\xe7\x6d\xc5\xc4\x72\x00\xbc\x5a\x70\xac\x50\
+\xf6\xdb\x74\xc6\x0b\x74\x03\xd1\x2a\x40\x06\x56\x40\x4c\x14\xb5\
+\x26\x0c\xa8\x58\x45\xc5\xc6\x43\x62\x99\xe0\x8b\x68\x5d\xc1\x1a\
+\x32\xf4\x0b\x62\x3c\x96\x35\xc0\x2c\x46\x0a\xc0\xe3\x68\x81\x9c\
+\x71\xa5\x34\xb3\x64\x6f\x09\xe0\x34\x33\x67\xed\x88\x81\xe7\xb1\
+\xbd\xff\x6d\x95\x37\x91\x8b\x5e\x20\xc7\x0b\x31\xa3\xdc\x01\x76\
+\x78\xd0\x34\x78\xd4\x8a\x78\xd4\x8a\x28\x01\x2b\x95\x22\x4f\x98\
+\x30\x3a\x3b\xe4\x1b\xc0\xc3\xb7\xb6\xa1\x1a\x51\xb7\xaa\x74\x18\
+\xb2\xdf\x7f\x46\xf8\xb5\x33\x0e\xea\x35\xa2\xbd\x36\xeb\x5b\x6b\
+\xd0\x86\xcd\x8f\xef\xd1\xee\x0a\x66\xe5\xf0\x31\x47\x3b\x2f\x50\
+\xca\x3e\xa6\x1b\x09\x7d\x4c\xf6\x5d\xf5\x9c\x3b\x79\x81\xd5\xba\
+\xc3\xe9\x64\x43\x68\xe0\xe1\x0d\xb5\x00\x2a\xc3\x1b\x50\x78\x0c\
+\xab\x82\x8d\x9b\xb4\x69\xf5\xa6\xbd\xd4\x64\xb9\x91\xce\x96\xba\
+\x77\xc2\xaa\x9a\xe2\x31\x9e\x00\x6b\xbc\x95\x80\xcc\x5a\xa5\x19\
+\x46\xee\x59\x65\x2c\x2d\xb8\x29\xd9\xb8\x54\xce\x2a\x30\x27\x00\
+\x5c\x81\x57\xd7\x9b\x94\x56\xd6\xc9\xdf\x99\x70\xab\x52\xa4\xb9\
+\x30\xa6\x6e\x4f\x73\x28\x5a\x17\x81\x02\xef\x89\x77\x48\x73\xe9\
+\x58\xb1\xf2\x0c\x43\xc7\x6c\x5c\xb8\xfb\x71\x88\xee\xb3\xff\xf6\
+\xb7\x79\xfc\xf4\x9b\x9c\x76\x0e\x19\xb4\x87\x7c\xac\x71\xc5\x6a\
+\xed\x26\x0b\x9f\xda\xe0\xb3\x2f\xdc\x60\x52\xfb\x12\x74\x9f\x10\
+\x45\x4d\x9c\xac\x4b\x69\x12\x2a\xcf\x45\x2d\x53\x4e\xf4\x7d\x2b\
+\x87\x25\x7a\xa3\x31\xe1\xd0\x53\x4c\x3c\xe3\xa5\x28\xf6\x54\x2a\
+\xa6\x72\xd7\x55\x4a\xaa\x89\xfd\x90\xb8\x21\x62\x35\xc2\x32\x86\
+\x06\x7d\x2b\xc9\xc4\x12\xcc\xd2\xd8\x93\xcc\x3c\xf4\x45\x88\xd0\
+\xaa\x18\xe0\xc5\x63\x05\x2c\x12\xba\x57\x56\x86\x48\x00\x2b\x57\
+\x9b\x5d\x60\xe2\x0d\xd9\x3b\xff\x36\xe3\xf0\x17\xb5\x06\x7f\xaf\
+\xf3\xa0\x69\x40\xe6\x07\x79\x78\xf8\x98\x17\x6e\xbc\xc8\x6f\xbd\
+\x97\xf4\x25\x1a\x93\x15\x16\x3a\x8f\xc8\xaf\x6c\xc4\x8d\xfe\xb6\
+\xc9\x16\x3e\x8e\xeb\xef\x28\x36\x32\xad\x15\xba\x9d\x33\xc2\xd0\
+\xa0\x73\x01\x0d\x33\xa2\x7d\x58\xa5\x66\x08\x2f\xc3\x0b\x96\xcd\
+\x99\x61\x63\xae\x37\x09\x8f\x36\xe2\x16\xad\xaf\x50\x09\x2e\x98\
+\xb4\x9b\xb0\xfc\x98\x53\xa6\xc3\x17\xa5\x76\x3e\xcd\x94\xa1\xf0\
+\x98\xc1\xa9\x2d\x74\x32\x87\xb4\x43\x03\xa3\x2a\x3a\xbe\x4f\x23\
+\x72\xc5\x84\xac\xd0\xdd\x6b\x7e\x2f\xc4\x7a\xce\x88\x1f\x25\x0f\
+\x9e\x63\x24\xea\x75\x79\x69\xf6\xd5\x01\x7c\xef\x4e\x72\x42\x4c\
+\xc7\x7b\x46\xdd\x4e\x8e\x11\x10\x00\x16\xac\xbc\x66\x13\x6f\x37\
+\x12\x60\xa6\x20\x00\x5c\x28\x2d\x72\xef\xd3\x5b\x6c\x6d\xdd\xe1\
+\xbd\x6f\xdf\xe7\x7f\xfe\x7f\xdf\xe4\xcd\xf7\xff\x98\x3f\x63\x85\
+\xdb\xb6\xcb\xcb\x5f\xfd\x7d\xde\xff\xd4\x67\xf9\x7b\xff\xc9\x6d\
+\x6e\x37\x36\xd9\x6f\xef\x62\x52\x42\xd5\xed\x6b\xb9\x15\x51\xd0\
+\x27\x5b\x29\x31\xe9\xbb\x50\xc8\xa9\x5c\x62\x1d\xc8\x12\xc0\xd2\
+\x3b\x91\xf8\x8c\x81\x41\x2f\xd6\xd5\xd5\x38\x02\xa8\x34\xb1\x94\
+\x14\xb2\x3a\x5e\xea\x62\x09\x6a\x29\x2d\x0a\xd6\x90\xf1\x60\x21\
+\xd6\xc0\x02\xe8\x82\x79\xa7\x80\xb5\x3c\x4f\xb1\xb0\xa7\x97\x36\
+\x69\x33\xed\x66\x82\x1d\xad\x08\x78\x5d\x19\x78\x0f\x9a\x86\x7a\
+\x7e\xf3\xea\x2e\x23\xff\x28\xae\xd1\xbb\x10\x45\xa9\xd5\x08\xfc\
+\x1d\x35\x81\xc8\xa8\x1a\x58\x83\x3c\xa6\xb5\x42\xcd\x14\xe3\x02\
+\xfa\x40\xeb\x03\x78\x56\xdd\xa6\x61\x46\x84\xf5\x06\xf7\x1f\x5c\
+\x11\xad\xff\x0d\xb8\x03\xd9\xd8\x47\x4c\xa6\x4c\x69\x59\x48\x89\
+\xd2\xaa\xf0\x8a\x48\xe9\x50\xa9\x83\x71\x75\xc8\x20\xfe\xe2\xa5\
+\xec\x63\x06\xd8\x58\x83\xbc\xea\xb3\x56\x37\xab\x74\x2a\x11\x46\
+\xd0\x9f\x31\xca\x54\x40\x03\x21\x23\x0a\x83\x52\x02\xdc\xa5\x30\
+\x87\x6b\x8e\xe7\x02\x58\x0f\x8c\xb4\x8a\x1e\xd6\x60\x42\xb5\x3c\
+\x6d\xac\x22\x73\x29\x9a\x35\xd1\x31\xbe\xbc\x61\xb0\x5c\x10\x12\
+\x02\xa0\xb2\xb0\x4a\xeb\xea\x94\xca\xc2\x2a\x10\x70\xe1\x65\x58\
+\x9a\xc3\xca\x12\xd0\x27\x17\x87\xca\x2b\xd5\xf1\xde\xa4\xb5\x9d\
+\xe3\x07\x2f\xa1\xf0\x37\xff\x46\x9c\x45\x18\xf1\xf2\xf7\xbd\xcc\
+\xff\xd0\xa8\xf2\xcb\x2f\x2e\xf1\xf3\xff\xeb\xff\xc5\xbe\x97\xe7\
+\xd2\x2f\xb3\xf8\xf0\x3d\xdc\x7f\x7d\xce\x57\x7e\xf2\xef\x73\xeb\
+\xd3\x9f\x63\x70\x7c\x86\x1b\x64\x21\x18\x52\xce\x25\x03\x22\x7e\
+\x5c\xa3\x57\x8d\x0a\x5c\x5d\x66\xe7\x06\x3c\x9c\x41\x15\x73\x74\
+\x4e\xe9\xc5\x64\xf5\x6a\x14\xf4\x45\x7f\x65\x2d\x4f\xa3\x54\xce\
+\x92\xf9\x07\x3f\xf9\x4f\x7e\x6e\x1c\x46\xd8\xfe\x88\x61\x6c\xb0\
+\x15\xac\x21\x7e\x68\xe1\x87\x96\xba\x0f\x60\x99\x3e\x93\x20\xc2\
+\x34\x3d\x32\x64\x19\x87\x11\x56\xce\xc7\x18\x1a\x04\xd6\x04\xd3\
+\xf7\x15\x98\xf3\x7e\x0e\x3f\x0b\x96\xe7\x31\xb6\x2d\xe5\xb5\xa8\
+\xd6\x8e\xb8\xea\xbd\xc3\xe5\x35\x25\x7a\x97\x9e\x08\x45\x9f\xbc\
+\xf9\x80\xc2\xd5\x12\xd6\x55\x95\x76\x77\xcc\x5b\x57\x1d\x1e\xef\
+\xed\x91\x5d\xbc\x64\xbf\x56\x63\x6b\xa9\x45\xbf\x9f\x05\x31\x72\
+\x84\x30\xf4\xc9\x98\x16\xe3\xf1\x94\xf2\xc2\xd0\x87\x91\x48\x66\
+\x3f\xef\x44\x5c\x5c\x7a\x8c\x8f\x5b\x2c\xe4\x4f\xa8\xde\xf9\x18\
+\xb7\x22\x1f\x7f\x60\x30\xe2\x8c\x71\x7e\x8b\x5c\xe6\x4a\x80\xb9\
+\x26\x1e\x47\xf9\x3d\x26\xce\x32\xd1\xc2\x12\x86\xd7\x63\xe2\x64\
+\x69\x87\x06\x61\x36\x10\xe3\x4d\x62\x26\x68\xe4\x1c\x26\xee\x34\
+\xe0\x60\x8a\xcc\x6f\xc2\xac\x8f\x35\xb0\x19\x7b\x63\xac\xaa\xa9\
+\x1e\x97\xc2\x1c\x13\x23\x60\x62\xcc\xe6\xfd\x56\x7d\x07\xb7\x1c\
+\xf7\xe5\x9d\x64\xa9\x96\x07\x78\x91\x81\x39\xc9\xaa\xf2\x7e\xaf\
+\x6b\xd0\x2c\x4e\x01\xbc\x75\x7f\x85\x92\x55\xe2\xde\xed\xa9\x9c\
+\x19\x7b\x4e\x0c\x60\x38\x3b\x3b\x67\x7d\xc1\xe6\xc2\xcb\x50\xca\
+\x4e\x89\x65\xcd\xde\xc0\xf1\x7b\x78\x83\xe9\x73\x17\x5e\x86\xde\
+\x69\x95\x0f\xbe\x71\xc8\xd7\x7f\xe5\x6b\x5c\xee\x3f\xe1\x85\x4f\
+\xbe\x82\x5d\x76\x70\x4b\x36\x8d\xb5\x25\xb6\xee\x7f\x8c\xbf\xf3\
+\xf2\x8b\x7c\xf5\xe1\x11\x8e\x13\x50\xb7\x8a\xbc\x7d\x70\x89\xfb\
+\xf5\xd7\x29\xdc\xf4\x78\x61\xf5\x2e\x41\xc9\x20\x37\x09\x31\xcc\
+\x3c\xc8\x10\x75\x2c\x2f\x5c\xcb\xc7\xb0\xb3\xf4\x7a\x97\xbc\xf5\
+\xc6\xeb\xd8\xd6\xd4\xe8\x1c\x4f\xf2\x71\xf3\x19\x97\xd5\x5c\x8d\
+\xad\xcf\x6f\x60\x79\x6b\x8c\x30\xc8\x96\xb3\x54\x07\x06\x79\xc0\
+\x9b\x98\xe4\x81\xff\xe5\xdf\xfc\x3f\x64\x7e\xfc\x27\xfe\xf1\xcf\
+\x01\xf8\x71\x4f\x80\x8a\x9f\x25\xf2\x27\x64\xc3\x80\x6c\x18\x30\
+\xa4\x30\x03\xea\xa1\x5f\xc0\x34\x3d\xfc\xd0\x22\x34\x6a\x64\xb2\
+\x82\x89\x87\x51\x15\xc3\xe8\xe1\x4f\x6a\xe4\x0c\x1f\x7c\x8f\x71\
+\xb4\x40\xd6\xef\x91\xf7\x73\xb8\x91\xcd\x64\xb2\x42\x77\x74\xc5\
+\x52\xe1\x90\x25\xdb\x98\x01\xf3\x83\xa6\xc1\x37\x5e\xbf\x4d\xdd\
+\xbf\x03\x41\x95\xcb\xee\x05\xdf\xba\xff\x2d\x46\x2d\x9f\x83\xf3\
+\x90\x8b\x8b\x90\x4f\xfe\xad\x13\x38\xb7\xa9\x56\x26\xf4\x2e\x85\
+\x81\x13\x95\x03\xc2\x6c\x80\x39\x99\x82\xb8\x15\x4d\x28\x60\xe0\
+\x38\x19\x72\xb9\x0c\x97\x97\x13\xba\x83\x31\x4f\x9e\x9c\x72\xbe\
+\x73\x44\xb8\xde\xc3\xa8\xf6\xa8\x2c\xfc\x6d\xca\xb5\x0f\xb8\xba\
+\xda\x80\x62\x8d\x5c\xe6\x8a\x49\xb8\xc0\x24\x5c\xa0\x54\xdb\xc3\
+\xbf\x18\x08\x29\xe1\xf5\xb0\x0d\x18\x46\x06\x5c\x88\x3c\x85\x41\
+\xde\xa4\xc8\x08\xd7\xf2\x29\x18\x79\x02\xd7\xc4\x2f\x7a\x54\x46\
+\x25\x02\x5f\xdc\xcf\x05\x45\xcc\x49\x16\x73\x92\x55\xec\x7b\xdd\
+\x2d\x5f\xf5\x99\xb8\x62\x7f\xbf\xe8\xe1\xc5\xee\xb3\x4a\xbe\xa8\
+\x6a\xf7\x9a\x8d\x88\x95\x8d\x06\xeb\x0b\x59\xb6\xee\xaf\x50\x69\
+\x42\xde\x86\x72\x7e\xca\x6c\x95\x85\x55\x9c\xd3\x88\x5c\xd9\x20\
+\x5f\x2c\x33\xf0\xcd\x04\x13\x03\x38\x7e\x0f\x72\x1f\x83\xe0\x8a\
+\x0b\x2f\xc3\xf9\x91\x41\xfb\x69\xc0\x37\x8f\x8e\x79\xfb\xd1\x01\
+\x6f\x1c\xfa\xbc\xbb\x7f\xc6\xc1\xaf\x7f\x97\x85\xdb\x11\x77\x6e\
+\x3f\x80\x4c\x01\xdf\xce\x71\xab\xb1\xc8\xf7\xdf\x59\xe6\xd9\x38\
+\xc7\xc3\xed\x03\x26\x66\x95\x67\xe3\x21\xce\xce\x77\xa8\xad\x67\
+\x59\xb9\xd1\x24\x18\x16\x71\xfd\x88\xa5\x6c\x71\x9a\x6b\x91\xa9\
+\x90\xf5\x47\x50\x5c\x64\x6f\xcf\xe3\xfd\x47\x0f\x13\x20\x2e\x17\
+\x7b\x8c\x27\x79\x8c\xc0\xe5\xc1\x8b\x8b\x2c\x2d\xdf\xc2\xce\x07\
+\xe4\x02\x9b\xec\xc4\x50\xd2\x42\x26\xe4\xff\xca\x2f\xfe\xb6\x90\
+\x13\x51\x77\x84\x11\x8b\xe8\xbe\x35\x01\xf2\x6a\x78\x8b\x74\xa5\
+\x29\x39\x11\xbb\xda\x86\x7e\x41\x79\x27\x94\x7f\xcf\xf0\x70\x23\
+\x21\x37\xa4\x26\xce\x1a\x9e\xea\x4b\x11\x06\x2e\x05\x6b\x48\x2e\
+\x12\xae\xb5\x79\x3d\x84\xbf\xf1\xfa\x6d\xc2\xa3\x0d\x06\xf6\x90\
+\x62\xa3\xc0\xc5\x5a\x12\xe5\xe1\xfd\x55\xa0\xcf\x77\x27\x0b\x34\
+\x2f\x3c\x8c\xaa\xf2\xc3\x27\x7a\xa1\x4d\xfc\xa1\x9e\x6c\xa7\xf4\
+\xaa\x0c\xd3\xb6\xc2\x1e\xbb\x7f\xd8\xa3\x5e\xaf\xf1\x62\xf3\x5b\
+\x98\xf6\x06\xeb\x5b\x87\x71\x98\x3a\x96\x0e\xa7\x36\x03\x6c\xe5\
+\x33\x16\xc5\x8a\xb1\x5b\xad\x2a\x00\x95\x35\x27\xf4\x28\xd2\x2c\
+\x0f\x68\xc5\x61\x5f\x6b\x60\xcf\x00\x55\xc9\x88\x6a\xa4\xb5\x01\
+\x4d\xbe\x56\xf5\x45\x7b\x26\xb9\x0c\x65\x16\x5c\xcd\xac\xaa\xcc\
+\xb4\x5a\xa3\xc6\xab\x0f\x9a\xb1\x7c\x58\xa6\x12\x27\xf4\x49\x19\
+\x21\x6d\x08\x80\xc6\xea\x21\x76\xff\xd3\xf4\x2a\xd3\xe1\x2d\xa3\
+\xf3\x15\x11\x81\x53\xd4\xf7\x21\x17\x5e\x06\xe7\x34\x62\xfb\x78\
+\x97\x9d\xed\x33\x0e\x8e\x3d\x2e\x7b\x59\xee\xdd\xbe\x01\xc6\x31\
+\xbf\xb1\xf3\x3a\xc1\x7f\xf1\x88\x27\xff\xf1\x84\x1f\xfb\xf7\xff\
+\x19\xf5\xd2\x15\xbd\x46\x9e\x57\xbf\xf4\x2a\x3f\x7b\xe7\x36\xff\
+\x0a\x78\xf3\x6b\x7f\xcc\x62\x65\x89\x6f\x1e\xc2\x8d\x7f\xfb\x3e\
+\x4b\xb5\x7b\x34\xef\x82\xe7\x56\x38\x26\xa0\xcc\xd4\xed\xf6\xbc\
+\x9b\x33\x98\xed\x66\xd4\xce\xe6\x30\xc6\x86\x32\x12\x25\x80\xfd\
+\x81\x29\x3a\x00\xfd\xf8\x4f\xfc\xe3\x9f\x33\x62\x31\x1c\x75\x47\
+\xc8\xfb\xbe\x69\x29\x76\x96\x00\x1e\xfa\x05\xa2\x68\x02\xa5\x2c\
+\xe1\x18\xc5\xce\x7e\x68\x91\x37\xe3\x9e\x5e\x46\x8f\x0c\x59\x06\
+\x7e\x06\xd3\xf4\x18\xf8\x19\x6c\x33\x27\xf4\x75\x29\x4b\xde\xcf\
+\x51\x2d\x2d\xd1\x77\xc7\x34\x4b\x25\x96\x0a\x87\x5c\x7a\x22\x31\
+\xe7\x62\x34\x21\x30\x7b\xd8\x79\x8b\xe5\xaa\x8f\x91\xe9\x53\xae\
+\x1d\x70\x1e\x4d\x30\x96\x3d\xce\x1f\xe6\x31\x5a\x0e\xcb\x2f\x8d\
+\x59\xbe\x82\x9e\xdb\x24\xeb\x1a\x62\x1c\x97\x33\x62\x6c\x58\x62\
+\xd0\x4b\xe8\xc7\xd5\xd6\x86\x0a\x10\x74\x8c\x88\x8a\x65\x13\x86\
+\x22\xdb\xac\x64\x0c\xc9\x19\x35\x32\xa3\x2e\xdb\xad\x2e\xee\xd5\
+\x33\xce\x2e\x2d\x7c\xf7\x8a\x6c\xd9\xc7\x9d\xbc\x40\xa9\x76\xc6\
+\xc4\xc9\xaa\xad\x04\xb0\xcc\x26\x23\x0f\x93\x71\xa8\x3c\x07\x92\
+\x3d\xf5\x6d\x98\xf5\x15\x0b\x03\x2a\x73\x4d\xbf\xc9\xfd\x27\x41\
+\x49\xed\x27\xf7\xad\xe4\x8b\x8a\x7d\x0b\xb5\x02\xaf\xde\x9d\x05\
+\x30\x40\xc5\x5c\x87\x4c\x1c\xde\xcf\xb8\x8c\x3d\x07\xab\x78\x93\
+\x30\xff\x01\x21\x35\xaa\xfd\x45\xda\xe6\x90\x6a\xbd\x9f\x90\x0e\
+\x03\xdf\xe4\xc9\xde\x0e\xad\xf7\x43\x5e\x3f\x18\xd0\x3a\xbd\xa2\
+\xd5\xf5\x58\xa8\xae\xab\x16\x58\x3f\x52\x1e\xf1\xa7\xc3\x32\x7f\
+\xf0\xbb\xbf\x4d\xdd\x3b\xe6\xe3\x4b\x2f\x61\xaf\x2e\xc7\x95\x29\
+\x79\xbe\xf8\xea\x5d\x1e\x9e\x79\x3c\xdc\x3e\xe0\x46\x29\xcf\xdb\
+\x07\x97\x64\x4e\x0f\xd9\xfa\xf4\x3a\xd5\x8a\xc5\xb0\x6f\x32\xca\
+\xda\x4c\x46\x23\xf2\xd9\x12\xae\x1f\x51\xcc\x5a\x3c\x3b\x1f\xcc\
+\x30\xb1\x39\x3a\x27\xb2\x4a\x18\x81\x8b\xbd\xb4\xcc\xbd\xad\x9b\
+\x64\x73\x8b\x94\x27\x50\x30\x73\x74\x03\x87\xb1\x99\x27\x18\x3a\
+\xd4\xcc\x1c\x3f\xff\xcb\xbf\x4e\xe6\x27\xfe\xc9\xbf\xfb\x73\x12\
+\xac\x45\x2b\xc0\x37\x2d\xda\x13\x1b\x3b\x93\x34\x36\xa4\x2e\x2e\
+\x58\x43\xc2\xac\x00\x71\xc1\x1a\x62\x99\x3e\x7e\x68\x61\x9a\x1e\
+\xc3\xa8\x4a\xc1\x98\x66\xbc\x49\xdd\x6c\x9a\x53\x59\x91\x21\x4b\
+\x86\x2c\xc5\xc5\x5b\x58\x85\x1b\x94\x2a\x5f\xa2\x18\x8d\xd8\x3b\
+\x38\x22\x1b\xeb\xd9\xf6\xe2\x09\x95\x9b\x5d\x0a\x57\x4b\x84\xf9\
+\x36\xa5\x1b\x11\xed\xbf\xa8\x13\x3c\x9d\xe0\xe5\x4d\x4e\xc7\xb7\
+\x39\x0f\x8b\x94\x4f\x9e\x61\x98\x65\xaa\xe3\x0c\x8e\x61\x4c\x75\
+\xb0\x96\x77\x5b\x8d\xd3\x23\x87\x06\xe4\xc2\x80\x8e\x11\x31\x34\
+\xc0\x8b\x53\x1a\x23\x0a\x14\x8c\x3c\x8e\x93\x61\xdc\x17\xc3\x4d\
+\xba\x97\x65\x8a\x91\xd0\xc0\xd0\x60\xe2\xf8\xb4\xa8\xd2\x34\x46\
+\x78\x43\x18\x45\x23\x02\xd7\x24\x37\xb4\xf0\x4a\x42\x0f\x57\xcb\
+\x03\x5c\xcb\x57\x46\x9b\x04\xa3\xdc\x4a\x50\xa7\xf5\xef\xc8\xcc\
+\x4d\xf5\x6f\xac\x87\xa5\xec\x98\x18\x01\xb9\x5c\x46\xe9\xdf\x8f\
+\xdd\xac\xf2\xe2\x8a\x41\xa1\x94\x04\xf0\x4a\xa5\x38\x05\xb0\x26\
+\x27\x44\x5f\x0f\x01\x60\xaf\xf2\x36\x0b\x76\x59\x01\x77\xe0\x9b\
+\x38\xa7\x11\xfd\xed\x23\xbe\xf9\xc1\x84\x6f\x6f\x6f\x73\x76\xe2\
+\x31\x18\x65\x58\xa8\xae\xd3\x8a\x5a\x78\x91\x85\x87\x47\x2f\x73\
+\x83\x62\xbe\x44\x60\x65\xf9\xe3\xd7\xdf\xa0\x7f\xf2\x2e\x9f\xa8\
+\xaf\x53\xdc\x68\x60\xe6\xc6\x14\x16\x1a\x7c\xe1\x07\x3e\xc5\x07\
+\x7b\x1d\x25\x2d\xee\xf6\x73\x9c\x1d\x5c\xf0\xb9\x57\x6d\xfc\xea\
+\x3a\x13\xa7\x4f\x29\x63\xe0\xfa\x11\xa5\xcc\x84\x28\x58\xe4\xb8\
+\xf3\x98\xf7\xdf\xdf\x57\x20\x6e\x8f\x2c\x8a\xf4\x15\x88\xef\x17\
+\x2b\x6c\x7d\x7e\x83\x49\x2f\xcb\xd8\xcc\x33\x0c\x1c\x6a\x99\xb2\
+\xda\xf6\x30\xf8\xc5\x5f\xfe\x35\x61\xd8\x29\xa0\xc6\x60\x96\x00\
+\xd6\x99\x39\x01\xe6\xa0\x44\x3e\xd3\x17\x2e\xb7\x18\xc4\x96\xe9\
+\x13\x50\x24\x67\xf8\xca\xf0\x9b\x30\xc0\x36\x73\x84\x4c\x98\x04\
+\x11\x94\xb2\x0c\x87\x11\x79\x53\xe4\x26\x67\x83\x12\x76\x71\x15\
+\xb7\xd3\x66\x64\xbd\xcb\x49\xe4\xf1\xc2\x52\x01\xe7\x4a\xe4\xfc\
+\x0e\x17\x2e\xd8\x6c\xff\x30\xc1\x59\x91\x61\xc5\xa2\x91\x5b\x22\
+\x6b\x44\xac\xd7\x7a\xdc\x9b\x34\x58\xa8\xd7\x69\x56\xb3\x9c\xf5\
+\xc4\x84\x4e\x59\x71\xac\xae\x1e\x31\x13\x0f\xf2\x26\x0b\x51\x8f\
+\x88\x82\xca\xd3\xd5\xf3\x6f\xe9\x19\xe4\x2a\x22\xbf\xd7\xca\x89\
+\x96\x53\x41\x98\xc1\xf7\x0b\xe4\xd6\x1a\x18\x5e\x06\x9b\x2e\xed\
+\xd0\xa0\x33\x8e\xa8\x1b\x05\x26\xe3\x90\x5c\xc5\xa4\x60\xe4\xf1\
+\x2c\x97\x9c\x51\x23\x70\x67\x1b\x72\x55\xcb\x03\x46\xe3\xec\x5c\
+\x30\x4b\x00\xab\x4b\xbd\x99\x13\x00\x2e\x8b\x86\x78\xb9\x5c\x46\
+\x34\x18\xd4\x3c\x10\x3a\x80\x1b\xed\x2c\xb5\xe5\xd9\x4a\x13\x63\
+\xb2\x42\xa9\x7c\x48\x18\xbb\xe3\xc2\xfc\x07\xd4\xed\x9b\x5c\x78\
+\x62\x41\xf7\xaf\x4e\x19\x7b\x0e\x4f\x8e\x2e\xf8\x83\x0f\x26\x5c\
+\x3d\x3b\x54\xc9\xf2\x46\xce\xc4\x75\x1c\x0c\xad\x3b\xa5\x17\xff\
+\x5b\xc8\x2f\x12\x65\x3c\x3e\x3c\xed\x70\xfa\xfa\x1e\x2f\xdd\xbd\
+\xa4\x72\xe7\x53\x90\x29\x50\x2a\x98\xfc\xc8\x8b\x5b\x3c\x3c\xf3\
+\x38\xda\xdb\xe1\x70\x78\xc4\xc3\xc3\x1d\x16\x7d\x9f\x97\x3f\x96\
+\x21\x30\x8a\xb8\x81\x09\x85\x0c\xb9\x30\xc2\x30\x43\x4e\x5b\x59\
+\xde\x7f\xf4\x90\x61\x60\x62\x5b\x21\xc3\xc0\x64\xb1\x31\x51\x9a\
+\xb8\x76\x67\x95\xad\x1b\xeb\x80\x4d\xcd\xcc\x31\xea\x8d\x18\x65\
+\x27\x22\x57\x23\x70\xc8\x96\xb3\xfc\xc2\x2f\xfd\x7a\x72\x40\xb9\
+\x94\x0c\xea\x60\xd4\xe6\xcf\x26\x0b\x03\x57\x19\x7c\x52\x1b\x0f\
+\xfd\x02\x56\x65\x40\xbf\x2f\x06\x9a\xfb\x95\x08\xbf\x5f\x60\x48\
+\xa8\xc2\xd4\xd3\x28\x5f\xec\x53\x5d\x2a\xe1\x5e\xf4\x55\xc6\xda\
+\xc7\x6b\xa5\x44\x97\xcb\xfa\xe3\x8f\x93\x77\xaa\x2c\x2f\xc2\x32\
+\x90\xdf\xa8\x72\x70\xd7\xe3\xd6\xd8\xe6\x20\xe7\x69\x61\xe4\x21\
+\x27\x8f\x1f\xd3\xd2\x0b\x29\xe3\x5c\x5b\xbf\xe8\xb1\x94\x59\x66\
+\xe2\x0b\x40\xd7\xf5\x2a\x0a\x73\x2c\xf4\xa9\x09\xa5\x5e\x4e\xf4\
+\xbe\x95\x2d\xa8\xa4\x5b\x67\xbf\x8b\x51\x16\x85\x9b\xdd\xb0\x8b\
+\x21\x9a\xe3\xa8\x84\x1c\xd7\x99\x40\x11\xd5\x73\x4d\x0f\x4c\xf8\
+\x45\x2f\xf6\xeb\x4e\x34\x1f\x32\x73\xc3\xc9\x7a\x30\x43\xef\x9e\
+\xd9\xac\xad\x6a\x2e\xb4\x24\x03\xe7\xd7\xd6\x39\xed\xef\x26\xf4\
+\x30\x40\x79\xd5\x60\xc2\xad\xb8\xe8\x20\xa0\xe3\x91\x00\xf0\x59\
+\x7f\xc0\x93\xbd\x2c\x8f\xde\xd9\xe3\xb2\x97\x05\xb2\xaa\x57\x85\
+\x6c\x7f\x95\xbe\xb5\x08\x20\x6a\xd1\xac\xde\x05\xe0\x4f\x7a\x0f\
+\x09\x7e\xf6\x11\x3f\xf5\x9f\xdf\xe6\x85\x7f\xef\xd3\x98\x61\x83\
+\xfa\x66\x93\x7f\xf5\x5f\xff\x34\x3f\x1b\x6b\x64\x80\xff\xe9\xb7\
+\xde\xc3\x37\xd7\xf8\x77\xfe\xe9\x4b\x0c\xfc\x88\xc1\xb0\x4d\x29\
+\xae\x00\x3f\xbd\x14\x35\x7d\x8d\xbc\x20\x9e\x05\x8e\x19\xb4\x81\
+\xfc\xac\x2e\xee\x76\x66\xb5\xb4\x3f\x30\x29\x85\x39\xd1\xa0\xa0\
+\x10\x77\x29\xd6\x01\xac\x1b\x76\xe9\x9b\x7c\x4d\xdf\x5f\x82\x74\
+\x26\x6b\x29\x4e\x2a\xd2\xff\x46\xdf\x0f\xb1\x2a\x06\xa3\xa1\xc9\
+\xe9\xa3\xbd\xb9\x9d\x7d\x00\x96\x0b\xcb\xac\x2c\x79\xdc\xc8\xdc\
+\xe2\x96\x91\x65\x61\xa5\xce\xa7\x1a\x6b\x2c\xac\xd4\xd9\xba\x73\
+\x87\xd5\xfa\x06\xab\xf5\x0d\xbe\xf0\xf1\xfb\xdc\x7a\xe5\x8b\x82\
+\x59\x35\x00\xcb\x04\x99\xce\x9c\x03\x40\xcf\x10\xd1\x2f\xad\x54\
+\x48\x2f\xef\x71\x9d\x89\xf0\x05\xb7\xfa\xb4\x3a\x72\x86\xb0\xad\
+\x52\x2e\xf5\x84\x9c\x74\xee\x43\x2b\x34\xd4\xf3\xf2\xbb\xc8\xfd\
+\xf5\x72\x7e\x3d\xc2\x17\x50\x53\x00\xce\xd0\xa5\x99\x81\x17\xee\
+\xdc\xe1\xf6\x9d\x8d\xb9\x00\x06\x88\xb2\x67\x73\x25\x84\x88\xbe\
+\x8a\x34\xc1\x9d\xa3\x0b\x26\xdc\x22\xcb\x01\xce\x69\xc4\xd3\xc3\
+\x55\xde\x7b\x27\xe0\xd1\xdb\xae\x62\x5f\x09\xda\x16\x02\xc0\xb2\
+\x52\x5a\xaf\x98\x96\xe3\x80\xf7\xfb\xcf\x44\xbb\xaf\xea\x5d\x7e\
+\xe3\x38\xe2\x7f\xff\xef\xfe\x4b\xce\xfe\xf4\x37\x09\xcd\x76\x0c\
+\x44\x83\xff\xf4\xef\x7f\x9e\xca\xfa\x16\x93\xf3\x47\xb4\xda\x06\
+\x6f\x7e\xfb\x77\x79\xfb\xe1\x1f\x51\x2b\x89\xf3\x70\x15\x64\x54\
+\x3a\xa6\x32\xde\x46\x56\x3c\xa6\x41\xef\x00\x15\x5f\x55\x75\x5c\
+\xf5\xa7\x19\x72\x55\x22\xd1\x01\x48\x02\x4b\x67\x61\x19\xa1\x93\
+\xcf\xe9\x85\xa2\x05\x6b\x88\x17\xb3\x70\xdb\xec\x61\x8f\x97\x13\
+\xde\x0b\xc1\xc8\x86\xa8\x08\xa9\xcc\xd6\x87\xc9\x7d\xf2\x85\x22\
+\xfb\xdb\x87\xfc\x9f\xbf\xff\xfb\xac\x6f\xad\xd1\x58\xdb\x4b\xec\
+\xf7\x29\xe7\xa7\xb9\x71\xc3\x8f\xe3\xe7\x00\xeb\xe8\x50\x2f\xe1\
+\xc3\x2a\x1c\x0f\x05\x6b\x7f\x76\xb3\xc4\xc3\xf7\xf2\x74\x3a\xfd\
+\x44\x0e\x83\x1e\x45\x2b\x85\x39\x5c\x67\x9c\xa8\x6f\xc3\x8c\xbd\
+\x16\x3d\x43\x31\xb1\x6b\x8e\xd5\x73\x92\xad\xa5\x6b\x4c\xa6\x3d\
+\x76\xe3\x9c\x5e\x09\x4c\x09\x48\xc9\xb6\x2e\x93\x44\xf2\xbb\x04\
+\x7a\xd0\xab\x53\xad\x76\x14\x53\xcb\x1e\xc5\x72\x41\x64\xe8\x52\
+\xb1\x36\x58\x59\xcf\x70\xff\x81\xc9\x72\x21\x43\xa5\xb9\x3c\x73\
+\x1c\x25\xfb\xea\x2c\xdc\x8f\x83\x1b\x62\x2b\x98\xb8\xb9\x30\xa6\
+\x7d\x1a\x71\x3a\xf4\x79\xb2\x77\xc4\xa3\x77\x44\xfe\xee\x65\x3f\
+\xc9\xbe\x9d\x32\xd4\x1d\x68\x95\x83\x69\x87\x1f\x8d\x99\x25\xa0\
+\xc5\xa4\x54\x9b\x56\xd4\xe2\xde\x9d\x02\xaf\x75\x3d\xf8\xd9\x5f\
+\xe0\xbf\xfd\xd5\x2f\x62\xdd\x01\xb3\x7e\x87\x57\xbf\xf4\x2a\xff\
+\xa2\xd5\xe1\x5f\x03\xfd\xa3\x1d\xbe\xfa\xee\x23\xee\x7f\xf5\x92\
+\xad\xa6\xc1\xda\x9d\x09\xed\xab\x01\xbe\x96\x6f\xde\x1e\x59\x2c\
+\x70\xcc\xa9\x07\x61\x7d\x19\x73\x74\xae\xb2\xd8\x64\xa5\x48\xf6\
+\x20\x62\xd2\x98\x56\x8d\xc8\x6c\x39\x71\x25\x4e\xb1\x6a\xd4\x15\
+\x00\xd6\x99\x58\xa6\x69\x56\x2c\x53\x81\x74\x1c\x2d\x60\x8f\x97\
+\x15\x30\xa3\xee\x68\x86\x99\x93\x12\x62\xea\xae\x6b\x56\x0c\xf6\
+\xb7\x9f\xf1\xdb\xff\xe3\xaf\x13\xed\x8b\x94\x9f\xef\x73\xbe\x28\
+\xfc\xc4\x4b\x3f\xc4\x57\x8c\xaf\xb0\x56\x79\xc6\x8d\x92\x68\x9a\
+\x71\xa3\xb4\x44\x94\x3d\x53\x8f\xcb\xab\x86\xda\xae\xd4\xd7\xb9\
+\x51\xf0\x29\xd6\x33\xd3\xaa\xde\xde\xd4\x2b\x21\x80\x3b\x51\xc0\
+\x95\xcc\x3b\xf7\x75\x9d\x91\xe3\x9e\x06\xfa\xf3\x93\x8a\x85\x11\
+\xf4\x71\x9d\x89\x02\xf0\xa4\x62\xcd\x24\xff\xe8\xee\xbc\xaa\x9f\
+\xf4\xa7\xe9\x9f\x59\x33\xab\x6a\x92\x92\x5c\x34\xb5\x7a\x8d\xb5\
+\xf5\x0c\x37\x9a\x4b\x2c\x17\x96\xe7\x5e\xa1\x56\x2a\x45\xce\xfa\
+\x83\x84\x06\x6e\x2e\x8c\x13\x8c\xdc\xbf\x12\xe9\x8b\xad\xab\x1c\
+\xee\x59\xc0\x77\xde\x5f\xe0\xd1\x3b\xdb\x71\x9b\x80\x42\x42\x32\
+\xc8\xfb\x66\x39\x43\x5d\xfb\xba\x66\x39\x33\x33\x68\x32\x74\x92\
+\x97\xfa\x66\xf5\x2e\xbf\x75\x74\xc5\x6f\xff\x57\xff\x0d\x61\x4b\
+\xb0\x71\xd7\xb0\xf8\x3b\x9f\x79\x99\x97\xee\x8b\x31\xc6\xf5\x66\
+\x85\x3f\x7c\xf8\x1e\x7f\xf1\xb5\xd7\x71\xba\x17\x94\x1a\x79\xfc\
+\x14\x13\x5f\xd5\x0a\x2c\xc7\x00\xbe\xe2\x06\xd1\xf8\x52\xe5\x13\
+\x03\xf8\xd5\x56\x82\x8d\x75\xb7\xa9\x39\x88\x8d\xda\x28\x8e\x53\
+\x4b\x1d\x3c\x70\xd1\x7c\xc1\x02\x8c\x6e\x64\x53\xb0\x44\x8e\xb0\
+\xf4\xf9\xca\xa4\x1f\xa3\x26\x80\xef\xe5\xce\x95\xac\x90\x6c\xac\
+\x12\x88\x62\x1d\x7c\x75\x34\xe4\x6b\xbf\xfe\x4d\x9e\xb4\x9f\xd2\
+\x69\xf5\x59\xbe\xda\xa0\xdf\x12\x40\x2e\xec\x3e\xa0\xb2\xb0\xca\
+\xcd\xdc\x27\xe8\x55\x2e\x15\x70\xe5\xa5\xf2\x46\x69\x89\x6a\x7f\
+\x91\xcd\xcd\x90\x6a\x7f\x91\x8d\x8c\x4b\x79\xd5\x60\xd0\xd1\xb4\
+\x9c\x04\xa2\xce\xaa\x12\x60\xf1\x6b\x0a\xcc\xf1\xeb\x6a\xab\x57\
+\x1d\x6b\x60\xd4\x2b\x98\x75\xb0\xa6\x73\x79\x75\x4d\x2b\x2b\x35\
+\xa6\xd5\xce\xb3\x61\xd6\x7a\xd7\x4c\x04\x31\x5e\x5d\x6f\x72\xff\
+\x81\xc9\xe6\xed\x0c\x95\x26\xb3\x5e\x08\xe0\xa4\x7f\x73\x46\x07\
+\xb7\xae\x72\x54\x16\x56\xc9\x72\xa0\x18\xd9\x39\x8d\x78\xb2\x3f\
+\xe0\x57\xbf\xf5\x4d\xde\xfd\xe6\xeb\xb4\xba\xde\x73\xe5\x42\x2b\
+\x6e\x14\x6e\x96\xc5\xfd\xd0\x09\xa8\x94\x6d\xd5\xbf\xc2\x65\x9c\
+\x78\x7f\x2b\x2c\x80\x71\x4c\x60\x36\x79\xeb\xfd\x6d\xfe\xf2\xb7\
+\xbe\x4a\x14\xec\x51\x8b\x7c\x8c\xad\x65\xfe\xd9\x7f\xf8\x25\x2a\
+\xeb\x5b\xb8\xd6\x3a\x4f\xf6\x86\xfc\xd5\x1f\xfc\x11\x1f\xbe\xf1\
+\x94\xc6\x64\x4c\x33\x35\x0b\x7a\xa1\x3b\xe4\xbc\x73\x4e\x98\x9f\
+\x2e\x5c\x79\x95\x15\x12\xae\x89\x5b\x1c\x27\x6a\xf8\xe4\x79\x30\
+\x8b\x5a\x41\x81\x97\x3b\x57\x60\x96\xcf\xeb\x00\x34\x8b\xc9\xac\
+\xb4\xa1\x9f\x4c\xdb\xf4\xac\x7c\x82\x9d\x6d\x7f\x84\xdf\x8f\x30\
+\x33\xe2\xc3\x2a\x95\x22\x97\xdd\x5d\x7e\xed\xd7\xbe\xce\xc3\xf7\
+\xcf\xa9\x5b\x55\x32\xd5\x0e\xc5\x46\x41\x9d\x24\xa5\x83\x62\xa3\
+\x04\xa0\x57\xb9\xa4\xda\x5f\x54\x4e\xfb\xfc\x7a\x5d\x39\xed\xcf\
+\xe3\x01\x8e\x85\xb5\x9b\xac\xad\x2d\x25\x81\xa2\x81\x59\x3d\xdf\
+\x33\x66\x8c\x3f\xfd\x39\xf9\xfc\xa4\x62\x25\xc0\x6b\x0d\x6c\xb2\
+\x7d\x9f\x6e\xd8\x4b\xfc\x0d\xf9\x19\x72\x2b\xf7\x97\x8f\x9b\x66\
+\xa4\x72\x28\xa4\xa1\x29\x35\xb3\x6e\xc0\xdd\xbb\x53\x60\x65\xa3\
+\xa1\xf4\xef\x3c\xe9\x20\xc1\xbb\x56\x79\x36\xa3\x8d\x9b\x0b\x63\
+\x9c\xd3\x48\x19\x74\x4f\xf6\x76\xf8\xea\x5f\x3c\xe1\xb5\xd7\xc6\
+\x9c\x1d\xb6\x55\xa2\x50\xdf\xf1\x12\xcc\x2b\xb5\x70\xe8\x04\x4a\
+\xf7\xca\xfb\x2e\x63\xda\x61\x87\x12\x39\xd1\x71\x33\x1a\x2a\x40\
+\xeb\x40\xae\x37\x2b\xfc\xc6\x71\xc4\xff\xf1\xab\xbf\x40\xe7\xbd\
+\xdf\xc4\x98\x74\x31\x87\x23\x3e\xfd\xc2\xdd\x04\x1b\xbf\xe6\x85\
+\xfc\xe1\xd7\xdf\xe4\x6c\xf8\x94\x61\xd6\xa3\xf7\xec\x50\x8d\x1b\
+\x96\x7a\xd8\x1c\x9d\xb3\xc0\x31\x46\x6e\x91\x1b\x05\x5f\x94\x27\
+\xf5\x23\x8c\xa0\xa5\x6a\xfb\x66\xfc\xec\xad\x62\x97\xa8\x3b\xc2\
+\x5e\x88\xb0\xc7\xcb\x53\x46\xd5\xf2\x89\x65\xef\x89\x84\x11\x61\
+\x99\x4a\x72\xd8\xfe\x28\x21\x19\x6c\x7f\x84\x77\x65\x24\xbc\x19\
+\x56\xa5\x42\xbf\x3f\xe0\x77\x7f\xe3\x21\x6f\xfc\xd9\x1f\xa9\x95\
+\x5d\xab\x0b\x4b\xd5\x30\xb7\x38\xe9\x8b\x6c\x2b\xe7\x34\xa2\x57\
+\xb9\x64\x74\xbe\xa2\x00\x7c\xec\x5e\xe0\x9c\x46\x1c\xbb\x17\xec\
+\x7e\xb8\x4d\xaf\x72\xc9\xee\xae\xc9\x72\x5b\x9c\xa0\xcf\x7d\xfc\
+\x0e\x9b\xf7\xee\xd2\xac\x37\xa6\xa0\x95\xe0\x8c\x8d\xb5\x19\x03\
+\x4e\xb2\x63\x7c\x5f\x02\x50\xa6\x48\xa6\x8b\x3b\xa5\x51\x27\xb3\
+\xd4\xe6\x97\xdf\xd8\x09\xe3\xad\x15\x1a\x34\x7b\x41\x82\xdd\xa5\
+\x61\x28\xd9\x77\xb3\x29\x3c\x10\x42\x03\x2f\xcf\x30\xf0\x59\x7f\
+\x90\x00\xaf\x8c\xc8\x25\x0c\xa3\xd3\x0d\xa2\xec\x19\xce\x69\xc4\
+\x1b\xdf\x9d\xf0\xee\x5b\x67\xfc\xc9\xdb\x8f\x79\xb2\xbf\x23\x7a\
+\xbb\x55\x44\xd7\x22\xa1\x69\x05\x98\x25\x20\xa5\x84\x90\x4c\x2c\
+\x25\x84\x18\x8c\x5e\x51\xdd\x8f\x64\x27\x23\xd9\x3a\x4b\x02\xd9\
+\x2c\x67\xa8\x37\x2b\xfc\xc9\x3b\x7d\x3e\xf8\x9d\xa7\x30\x38\xa5\
+\x6a\x3a\x98\x75\x93\xff\xe0\x27\xff\x96\x62\xe3\x56\xdb\xa0\xbe\
+\xd7\xe1\xc3\x37\x9e\xd2\xe9\x74\xa8\xce\x57\x4b\x4a\x4e\x1c\x0f\
+\x2d\x3a\x43\xf1\xe5\xda\xe6\xfc\x9e\x76\xa5\x30\x87\xd9\x1c\xd4\
+\x12\xac\x0a\xd0\x2a\x26\xa7\xf8\xb8\x91\xad\x80\xac\x8a\x49\x87\
+\x1e\x52\x8a\x78\x56\x1e\x23\x6e\x3d\x65\xfb\x23\xa2\x41\x97\x62\
+\x49\x48\x12\x2f\x77\x2e\x02\x24\x83\x90\xc7\x5f\xdf\xe3\xaf\xbe\
+\xf6\x8c\x52\x39\x4b\xa5\x70\x42\xa5\x2c\x9a\xf7\xad\x54\x27\xdc\
+\x5b\x8d\x30\xb5\x6a\x62\x09\x58\xb9\x55\x49\x2b\x71\x2f\x33\xe7\
+\x34\x22\xca\x9e\xa9\x7d\x72\xfe\x19\x9b\xb7\x37\x58\x5b\x5b\xc2\
+\x35\xc7\xb8\xce\x44\x48\x84\x58\xf3\xea\xf7\x13\x97\x7e\x4d\x3f\
+\x5b\x03\x5b\x31\xb0\xd2\xb4\x31\x20\x25\x98\xf5\x8c\xb3\x52\x59\
+\x44\xda\xe4\x7f\xdd\xeb\x20\xdf\x57\x33\xab\xb4\xaa\x99\xc4\xdf\
+\x95\x8d\x4f\x64\x16\x5a\xb6\x5a\xa0\xbc\xa1\x95\x86\xb5\x66\x59\
+\x58\x6a\xe0\xb3\xfe\x60\xc6\x2b\x21\x2f\xbd\x4f\xf6\x07\x7c\xf5\
+\x2f\x9e\xf0\xe8\x9d\x6d\xfe\xf4\xaf\x5a\xd4\xad\x2a\xcd\x5b\xf5\
+\x18\xb4\x05\x35\xfd\xb4\xef\x78\x54\xca\xb6\x92\x0a\x92\x91\x75\
+\x3d\x1c\x3a\x81\x6a\xdf\x25\x81\xad\xb7\xd2\x2a\x91\xa3\xa3\x8d\
+\xa8\x5b\xac\x2c\x11\x98\x4d\xfe\xed\x6f\xbe\x46\x6b\xe7\xf7\x94\
+\xb7\xe2\x53\x5b\x9b\x8a\x8d\xb3\xcb\x0f\x78\xcd\x0b\xd9\x3e\xde\
+\x65\x10\x57\xac\x67\xed\x1b\xca\xc5\x96\xbe\xe9\x57\xe5\x46\xd8\
+\x15\x72\xa2\x1f\x89\x0c\x39\xcd\xc6\x30\x13\xec\x19\xb3\xaf\x3d\
+\x5e\x4e\x30\x6b\x18\xb8\xaa\x82\x59\x37\xde\x24\x50\x75\x46\xf6\
+\xac\x3c\x5e\x54\x13\x9a\x7a\xa9\x4b\x25\x7f\x17\xdf\xb6\x79\xeb\
+\xdd\x0f\xf9\xed\xaf\xfe\x2a\xf8\x3b\x82\x2d\xe5\x17\x6d\x2e\x61\
+\x98\x5b\x1c\x0f\x2d\x56\x0b\x9b\x73\xf5\x90\xfa\xc2\x67\x01\xdf\
+\xce\x95\x67\x72\x04\xa2\xec\x19\x3b\x3b\xaf\xf3\xe2\xca\x33\x3e\
+\xf3\xc9\x2f\x2a\x00\xea\x5a\x77\x86\x7d\xe3\x4b\x7e\xa7\x16\x26\
+\x58\x52\xa5\x48\xc6\xc0\xd6\xfd\xb8\xe9\x5c\x07\x99\x4b\x9c\x76\
+\xb1\xe9\xef\x93\x0b\x60\x5e\x32\x7b\xf3\x56\xc4\xad\x1b\x36\x9f\
+\x5b\xa8\xb3\x5c\x58\x9e\x61\xe1\x46\x3b\xab\xc0\xbb\x5a\xd8\xe4\
+\xac\x3f\x48\x1c\x23\x63\xb2\xc2\x49\xff\x26\x67\xfd\x01\x3b\x7b\
+\x7b\xec\x6c\x9f\xf1\xed\xf7\x4e\xb9\xec\x65\xb5\x63\xdc\x8e\xbd\
+\x0a\xb6\xca\xfd\x10\x3d\xe5\x82\x84\x34\x90\x60\x95\xc0\x34\xcb\
+\x19\xfc\xe2\x28\xf6\x04\xe5\x14\x78\xf5\x4e\xa1\x4d\x6d\xd0\x47\
+\x2b\x6a\x29\xc9\xf0\x07\xff\xf7\x5b\x0c\xdd\x0f\x31\x26\x5d\x72\
+\x8d\xbc\xd2\xc6\x20\xfa\x2e\x77\xbf\x66\x72\xfe\x6c\xba\x10\xcf\
+\x3b\x42\x42\xcc\xbb\x45\x91\xd0\xc2\x41\xc7\x10\x72\xa2\x62\x50\
+\xca\x4c\x12\xc6\x9d\x39\x70\x85\x31\x37\x70\x3f\xba\x34\x4e\xd6\
+\xd2\xcd\xfc\xa1\x41\x97\x81\x2b\x00\x5d\xe8\x9d\x2b\x03\x51\xea\
+\xe3\xc9\xd1\x90\xdf\xfd\xc5\xd7\x68\x1d\x74\xd4\xc1\x14\xa5\x34\
+\xb0\x79\x3b\x43\xb9\xbe\xc3\x8d\x82\xaf\x80\x7b\x3c\xb4\x58\x68\
+\xef\xf1\xe4\xd4\xe0\x78\x68\xe1\x9e\x05\x9c\x0e\x77\xe9\xd6\xf2\
+\x98\x6c\xe3\x9e\x05\xea\x79\x79\x32\x8d\xc9\x0a\xce\x69\xc4\xc7\
+\x36\x2c\x9a\xf5\x06\x43\xdf\xa5\x63\x44\x09\x46\xcd\xd0\x55\x79\
+\x14\x12\xa4\xd9\xbe\xaf\x3c\x04\x7e\xd1\x23\xdb\xf7\x67\x8c\x3c\
+\xdd\xa7\x2b\x1f\xcb\x82\xd0\x34\x0b\x57\xcb\x83\x19\xd7\x9e\x5c\
+\x00\x19\xba\x6a\x18\x8d\xac\x44\x2e\x6f\x18\xb4\x96\x7b\x09\x16\
+\x96\xff\xdb\x8d\xe9\xc2\x3a\x1d\x8a\xa0\x46\x94\x3d\x53\xc0\x3e\
+\x1e\x5a\x98\x6c\xc7\x81\x8b\x6d\xde\xfe\xc0\x4f\x30\xa9\x04\x6d\
+\xa7\x2c\x1e\xf7\x1d\x8f\x86\x59\xc7\x65\xac\x58\x57\x9e\x0f\x09\
+\x54\xf9\x7c\xdf\xf1\x54\x42\x95\x64\x61\xd9\x9d\x53\x7d\xd7\x94\
+\x3e\x5e\xac\x2c\xd1\x6a\x1b\xbc\xfe\xce\xdb\x0c\x9f\xbe\x4f\x68\
+\xb6\xa9\x45\x7e\x42\x1b\x77\x5a\x7d\xde\x31\x77\x78\xed\x8f\xff\
+\x94\xe1\xc9\xb3\xb9\x78\x6a\xe4\x7d\x4e\x9c\x78\x40\xa4\x21\xb4\
+\x70\xaf\x59\xc5\x08\x5a\x49\x16\x0e\x46\xc2\x3b\x21\x19\xb4\x58\
+\x42\x79\x17\xd2\x99\x6b\xba\xac\xb0\x2a\x15\xac\x8a\x81\x67\x09\
+\xe0\x17\x4b\x60\x23\x7a\x32\xd8\x46\x57\xf4\x31\x5e\xea\xaa\x40\
+\x47\x7f\xf4\x94\x5f\xfb\xb5\xaf\x33\x39\x7f\x44\x76\xf9\xc1\x74\
+\x15\x9b\x43\xc5\xc2\x21\xa2\xd3\xbb\x04\xa8\xdb\xda\xe6\x20\x9a\
+\x10\x85\x3b\xd4\xba\x23\xba\xb5\x7c\x82\x81\xba\xb5\xbc\x7a\x5e\
+\xf7\x27\xde\x28\x2d\x51\x7e\x39\xc3\xad\xad\x57\xf0\x82\x20\x61\
+\x60\x89\xcc\xb5\x38\x49\x29\xe8\xab\xdc\x5f\xf9\x58\x82\x52\x37\
+\xd8\x66\x18\x3a\x7e\x6c\x0d\x6c\x8c\xa0\x9f\xe8\xe2\x23\x75\xae\
+\xac\xbc\xd0\x17\x81\xde\xea\x35\x43\x97\x5a\x46\x00\xf8\xfe\x03\
+\x53\x05\x75\x94\xad\xd1\x64\x46\x13\x57\xba\xb7\x66\xdc\x6a\x67\
+\xfd\x01\x6e\x6b\x9b\xf7\xde\x09\x78\xe3\xdb\xef\xf1\x64\x6f\xa8\
+\x64\x41\xb7\xd8\x57\x8c\x1a\x99\x15\xb2\xce\x58\xe9\x5a\x09\x38\
+\xc9\xbc\xb2\x62\x5b\xea\x5c\xf9\xbc\xde\xff\x58\xb2\xb0\x5e\x4d\
+\xa2\x7f\x9e\x32\x10\xa3\xa7\x64\xaa\x1d\xbe\x75\x60\xf1\xc1\xef\
+\x3c\xc5\x74\x46\xc2\xc8\xd3\xb4\x71\x76\xf9\x01\x97\x3d\xb1\xe8\
+\x5e\xff\xf6\x37\x94\x61\x97\x0e\x7c\xac\x95\x0d\xdc\xb3\x80\xa8\
+\xd2\xc4\x08\x5a\xd0\x8d\x65\x5e\x26\x36\xa4\x8b\x39\x4a\x99\xbc\
+\xf0\x4e\xd8\x46\x97\x68\xd0\x55\x6e\xb5\xc2\x45\x2d\x61\xbc\xc9\
+\x66\x28\x6e\x24\xaa\x9a\xc3\x41\xa8\x5e\x93\x72\xa2\x15\xf9\x71\
+\xe2\xce\x94\x81\xbd\xdc\x39\xfd\xd1\x19\x5f\xff\x8d\x90\x87\xef\
+\x9f\x93\x5d\x7e\x40\xa5\x70\xa2\x19\x3c\xe2\xa0\xe4\xce\x2f\x71\
+\x5b\xdb\x6c\x1f\xef\xd2\x6f\x4d\x07\xf0\x19\xe6\xd6\xf4\x72\x11\
+\x6b\xe5\x5a\x77\x44\xc8\xfd\x84\x76\x06\xd1\x9f\xe0\x46\x69\x89\
+\x5e\xe5\x92\xd5\xae\xc9\x46\xa3\x45\x79\xb1\xa9\xdc\x57\xd2\xa3\
+\x20\x7d\xbb\x72\x4b\xaa\xf8\x72\x52\xb1\xa6\x9a\x38\x96\x14\x92\
+\x45\xab\xbe\x93\x78\x8f\x94\x11\x12\xf8\xf5\xc8\x98\x61\xef\xf4\
+\x63\x05\xe0\x8d\x86\x1a\xdf\x25\x01\x2c\x41\x2b\x59\xb8\xd1\x9e\
+\x32\x4e\x71\xfd\x32\xa1\x89\x85\xf7\x21\xab\xe4\x03\x7d\x61\xfd\
+\xcb\xa0\x85\x6c\xb6\xdd\x29\x43\xd6\x19\x33\x29\xe7\x14\xf0\x74\
+\x90\x96\xc8\x29\xb6\x95\x3a\x57\xbe\x26\x41\x9a\xbe\xf5\x8d\x02\
+\x7e\x71\xa4\x5e\x4b\xba\xec\xaa\x6c\x36\x57\xe9\x5e\xb5\x79\x6b\
+\xcf\x65\xec\xff\x99\xd2\xc6\x77\x63\x6d\x3c\x39\x7f\x84\x6b\xad\
+\x27\x5b\x2a\xd8\x70\x9a\xba\xc8\x1b\xb9\x45\x4a\x2b\x19\x8c\x7e\
+\x8b\x28\xd3\x24\xac\x76\x84\x9b\x2d\x66\xe2\xd2\x60\x3c\xf5\x13\
+\x7b\x51\x2d\xa1\x71\x8b\x25\x91\x18\x5f\xb1\x4c\xdc\xc8\x06\xca\
+\x98\x99\x92\xea\x02\x34\xf5\xaf\x65\x12\x39\x16\xc5\x12\x4a\x3e\
+\xb4\x27\x36\x95\xfc\x0a\xdd\x77\x07\x22\x86\xee\xef\x30\x29\x1c\
+\x29\x57\x4e\x8b\x80\xa6\x39\xe4\xd4\x83\x0f\xdc\x36\x67\xbd\x2c\
+\x67\x3d\xf1\xe5\xa2\x70\x87\xb3\x5e\x56\x0c\xe3\xcb\xdc\x4a\xb0\
+\x70\xb7\x96\xe7\x46\xc1\x27\xe4\x7e\xc2\x11\x0e\x28\xe3\xef\xd0\
+\x35\x58\xad\x6f\x24\x7c\xc0\xf3\xd8\x75\x5e\x70\xc2\x08\xfa\x09\
+\xc3\xad\xea\x3b\x8a\x59\x7b\x56\x99\x52\x39\xab\xc0\xac\x03\x35\
+\xad\x87\x75\x2f\x87\xee\xda\xab\x65\x6a\x34\x6b\x36\x6b\x65\x43\
+\xb9\xd2\xce\x87\xe7\x09\x63\x4e\xb2\xf0\x41\x34\x49\xb0\xae\x2e\
+\x37\x9e\xec\x65\x79\xf2\xf4\x30\x21\x1f\x24\x40\xa5\x1c\x70\x19\
+\x2b\x00\xeb\x06\x9b\x04\xb4\xce\xc6\xe9\xed\xdc\x3a\x40\x5f\x74\
+\xd6\x9c\xf8\x43\xd5\x99\x3e\xbd\x7f\xa7\x4c\x9c\x8b\x01\x27\xef\
+\xfc\x25\x7f\xf5\x97\x21\x70\x85\x31\xe9\x72\xb7\x9e\xe1\xcb\x3f\
+\xf4\x22\xcd\x4f\xff\xdd\xf8\x12\x71\x83\xb3\xb8\x6d\x47\x1a\xc0\
+\x13\xef\x38\xf1\x9c\x11\xb4\x30\x0d\x69\x0b\x39\xb8\x41\x16\xb7\
+\x38\x0d\x6c\x99\x00\x5e\x54\x53\x8d\xb5\x3d\x2b\x8f\x9b\xcf\x29\
+\xc0\xda\x9e\x8b\x59\x14\x4d\x54\xb2\x14\x09\x03\x57\x05\x33\xa4\
+\x9c\x90\x1e\x0a\x29\x45\x1a\x59\x8f\xd3\xc3\x36\x7f\xfe\x8d\xc7\
+\xe0\xef\x80\x15\x5b\xa7\xce\x98\x6e\xb1\x2f\x1c\xeb\x61\x81\x95\
+\xcc\x34\x59\x7b\x83\x67\x9c\xf5\xb2\xe4\x2f\xab\xac\xc4\x3d\x74\
+\x4b\x2b\x99\x84\x85\x7a\xa3\x20\x1a\xde\x01\x8c\x4e\x8e\x66\x13\
+\xaa\x4f\x23\x96\xdb\xed\xc4\x68\xd5\xeb\x8a\x2f\x55\xb2\x79\xec\
+\x41\x90\x2d\xa3\x74\xab\x37\x30\x9b\x33\xb9\x0f\x41\xbd\x81\x5f\
+\xf4\x12\x0b\x62\x52\xb1\x12\xbe\x66\xe9\x86\xd3\x17\x49\xa6\xda\
+\x49\x64\xa3\xe9\xf9\x21\x69\x26\xd6\x1f\xa7\x75\xf2\xee\x7e\xc0\
+\xa3\x77\xb6\x39\x39\x0a\x12\xec\x28\x99\x31\xcd\xb4\x52\x4a\x28\
+\xd7\xa1\x33\x9e\xd9\x6f\xc6\x80\x8e\x35\x70\x1a\xa4\x12\xc8\x66\
+\xd4\x4b\x68\x6f\xa9\xb9\xf5\xc5\xf2\x9a\x17\xf2\xc1\x6b\x5f\xe3\
+\xea\xd1\xd5\x54\xeb\xbe\xf2\xb2\x62\xe3\xcb\xfe\x85\xaa\x9b\xd4\
+\x6f\xa7\x9e\xf0\x58\xe8\xd8\x88\x32\xcd\x79\xe9\xf3\x74\x7a\x3e\
+\x54\x23\x21\x27\x8a\xa5\x64\x32\x4f\x18\xb8\x62\xc8\x4c\x51\x54\
+\x2d\xdb\x9e\x41\xce\xb8\x4a\xf8\x81\x7d\x1c\x8c\x5a\x1e\x8b\xa9\
+\xb7\x40\x32\xf1\x65\xa7\xc3\x77\x7e\xe7\x1b\x3c\x7c\xef\x4d\x4a\
+\xe4\x98\x14\x8e\x14\x2b\x58\x83\x7c\xac\xc3\xda\x53\xf1\x9e\x7b\
+\xc6\x21\xc2\x47\x3c\x5a\x14\xc3\x03\x6f\x64\x6e\xcd\xb8\x90\xdc\
+\xb3\x80\x4a\xf7\x16\x83\x4e\x40\xbb\x31\xa1\xd6\x1d\x71\x3a\xdc\
+\x4d\x78\x32\x0e\x83\x52\xa2\x9b\x4c\x3a\xa0\x21\xc1\xaa\x4b\x0a\
+\xf9\x5a\xda\x7d\xe6\x9a\x63\xaa\xe5\x41\xc2\x78\xd3\xc1\x2e\x19\
+\xb7\x1e\x89\xd2\xf1\x6e\xd8\x4b\x84\x91\x75\xc6\xae\xd5\x6b\x6c\
+\xd5\xfa\x8a\x81\xd3\x01\x0d\xdd\xad\x26\xef\x4b\xe0\x02\x9c\xf5\
+\xb2\xec\xee\x07\xca\xfb\xa0\x03\x71\xe2\xcf\x02\x2e\x0d\x52\xe9\
+\x69\x90\x7e\x62\x5d\x36\xcc\xc4\x00\xa2\xa4\x01\xa7\x37\xf4\x96\
+\xc6\x9d\x94\x1b\x69\xf6\x07\xa8\x2c\xde\xa6\x7b\xd5\xe6\xf5\x77\
+\xde\xc6\x3f\x79\x08\x03\x11\x02\xff\xfc\xed\x1a\xaf\xbe\xb8\x44\
+\x76\xf9\x01\xae\xb5\x4e\x7f\xb8\xc6\xa4\x37\x64\x74\x3a\x5d\x90\
+\x2b\x99\x4b\xa5\x93\xd3\x1e\x2a\x11\xb1\x2b\x53\x1a\x8c\x99\xb8\
+\x19\xea\x55\x2b\xd6\xc4\x2c\x10\x0d\xba\x2a\x60\x21\xdd\x65\x22\
+\xe1\xa7\xac\x65\x45\x15\x15\x3b\x5b\x94\x45\x07\x79\x3f\x1b\x97\
+\x33\x25\xb3\xd6\x76\x8f\x1c\x5e\x7f\xa7\x05\xd6\x56\x22\x46\xdf\
+\x8c\x5b\xde\x34\xcc\x88\x96\xd6\x01\xaa\x79\x3e\x8d\xc7\x4b\x29\
+\x71\x1c\x1c\x70\x3c\xb4\x14\x48\x4d\xb6\x39\x89\x2c\x8e\x83\x03\
+\xa2\x70\x87\x7e\x0b\x8e\x83\x03\x2a\xdd\x5b\xca\x7a\xd7\xeb\xb4\
+\xb2\x7d\x3f\xd9\xc0\x4f\x73\xaf\xc9\xfc\x07\xbd\xe2\xb8\x14\xe6\
+\xe6\x06\x30\xf4\x26\x28\x52\x2f\x4b\xc3\x50\x06\x36\xf4\x90\xb4\
+\x0c\x43\xeb\x4c\xdd\xac\xc3\x67\x1a\x3e\x85\x17\x85\x4b\x50\x4a\
+\x88\xe7\xdd\x74\x50\x9f\xf5\x84\x7c\xf8\xf6\x7b\xa7\x74\xfc\xa4\
+\x01\xe6\x32\x4e\x34\x51\xd1\x8d\x2e\xb9\x9f\xae\x7d\xe7\x01\x3d\
+\xdd\x02\x40\xba\xd2\x74\x96\x96\x7f\x23\x6b\x89\xd7\x24\x53\xeb\
+\xfe\x62\xfd\x6f\x06\x66\x93\x6f\x1d\x58\xec\xbe\xf9\x94\x8b\xc3\
+\x7d\x8c\x89\xb0\xbb\xbe\xf0\x7d\x2f\x2b\x77\x5b\xc9\x3f\x52\xa1\
+\xeb\xd0\xbb\x20\xf4\x2e\x30\x72\x8b\xb3\xdf\x33\x0e\x37\x8b\x88\
+\x9d\x43\x27\x0a\xc8\x96\xa6\xc0\x37\x3b\x97\x27\x4a\x1a\x78\x57\
+\x46\x22\xf9\xc7\xf2\x2e\x54\x98\x59\x6f\x6f\x35\x4d\x49\x9b\xad\
+\xd6\xbd\x68\x89\x1f\x5b\xbe\xd9\x67\x52\x38\xa2\xef\x78\xea\x12\
+\xd6\x8e\xbd\x03\x7d\x47\x4c\xa3\x97\xfd\xcd\x74\x17\x93\x3c\x69\
+\xf9\xcb\x2a\x6e\x6b\x9b\x7e\x4b\x18\x74\xfd\x96\xd0\xcb\x72\xa2\
+\xbc\xdc\x9e\x44\x02\xe0\x12\xcc\x1b\x19\x97\xa8\x78\x53\x01\x4e\
+\xca\x87\xeb\x72\x22\x54\x10\xc4\x1c\xcf\x78\x27\xd2\x59\x68\x3a\
+\x78\x3b\x46\xa4\xb2\xd7\xa6\x33\x9c\x67\x33\xe7\x36\x6a\x59\x56\
+\xea\x0d\xfc\xd2\xb2\x92\x0f\xd7\x25\xf6\x28\xbf\x69\x0c\xf2\xf3\
+\xe1\xb9\x02\xf0\xd9\x61\x5b\x8c\x5b\xb0\x92\xb3\x42\xd2\x63\x0f\
+\xd2\x0c\xab\xdf\xaf\x94\x87\x6a\xd6\xc8\x3c\xcd\xab\xfa\x18\xc7\
+\x21\x6a\x1d\xe4\xb2\x45\x01\x88\x76\x01\x62\xc2\xd3\x73\x16\x45\
+\x4c\x1a\x27\x1f\x3e\xc3\xcd\xf7\x08\xcd\x36\x95\x7c\x86\xc6\x0b\
+\x5b\xca\xdd\xe6\xb4\xe4\x57\x92\x00\x00\x20\x00\x49\x44\x41\x54\
+\x5a\xeb\xca\x28\x3c\xeb\x88\xf6\x62\x69\x7d\x3c\xe2\x4c\x85\x9b\
+\xaf\x8a\x13\x26\x6e\x66\x0a\xe0\x58\xd6\x9a\xe1\xc2\x92\x72\x8f\
+\xd9\x86\x08\x41\xcb\x00\x86\xcc\xfd\x95\x00\x96\x92\x43\xb2\x6f\
+\x1a\xd8\x51\x77\x44\xe0\x4e\x3d\x10\xd9\xe1\xba\xba\x94\x4d\xfc\
+\x61\x82\x0d\x4c\x6b\x05\xfa\x10\x8d\x2f\x71\xcf\x16\x18\xb4\x87\
+\x0c\xda\xe2\x00\x0e\xda\x43\x3e\x70\xdb\xf8\x07\x43\xce\x7a\x59\
+\x8e\x83\x69\x0b\xcd\x83\x9c\xc7\x59\x2f\xcb\x68\xb1\xa7\x0c\xc1\
+\x4a\xf7\x16\xfd\x9a\x60\xee\x5e\xe5\x92\xcd\xdb\x1b\x2c\x65\x92\
+\xbd\x80\x75\x60\xea\x9a\x55\x07\x72\x9a\x89\xd3\x41\x8c\x74\xe2\
+\x8f\x8c\xcc\xb9\xce\x44\x19\x80\xd5\xf2\x80\x6c\xdf\x27\x43\x97\
+\x6a\x79\x30\x63\xc8\xcd\xbb\x55\x9a\x49\xe0\x4a\x83\xcf\x3d\x5b\
+\x50\x00\x16\x33\x38\x0a\x33\xc0\x9b\x07\x64\x1d\x4c\xba\x97\xa1\
+\xef\x14\x94\xbf\xf7\x3a\xa3\x4d\xee\xa3\x0f\xd6\x91\x7f\xb7\x1e\
+\x19\xea\xb1\x7e\x25\xa8\x3b\xd3\xbf\x23\x3f\xbb\x6e\x55\xe9\x06\
+\x5d\x1e\x05\x63\xf2\x7b\x87\xca\xc0\x03\x78\xf5\xc5\xa5\x44\xa4\
+\x4f\xca\xa3\xe3\xb1\xa7\xb4\xf0\x89\x13\x71\xa3\xe0\x33\xf1\xb7\
+\xb8\x8a\x9b\xa9\x64\x5c\x93\x6c\x29\xa0\x34\xc8\x31\x71\x33\x8a\
+\xa1\x55\xc4\xce\x8b\x6a\x78\x51\x0d\xdb\xe8\xce\x00\x73\xc6\x8f\
+\x37\xb1\x67\xb6\x97\x9d\x0e\x57\x91\xc7\xee\x91\xc3\xde\x5b\xef\
+\x63\x5c\x39\x4c\x0a\x47\x31\x18\xf2\xea\x80\xe8\x07\xb0\x1b\x74\
+\x39\x71\xa2\x38\xed\xee\x4a\x01\x58\xe9\xdb\x28\x8b\x91\x7b\xa6\
+\xd8\xf9\xac\x97\xe5\xd6\xd8\xe6\xd6\xd8\x56\xde\x0c\xc3\xdc\xe2\
+\x38\x38\xc0\xe9\x6c\xb1\xd0\xde\xe3\x9d\xb7\x77\x18\x9e\x3c\x53\
+\x56\xb8\x0e\x44\x09\x60\xd1\x10\xdb\x4b\xe4\x44\x74\x6a\xa1\x8a\
+\xac\xcd\xcb\x87\x48\x34\x3d\x29\x67\xc9\x74\xda\xca\x07\xac\xbf\
+\xa7\x15\x1a\xca\x2d\x27\x73\x22\x9e\x07\xe0\xf3\xe1\x79\x42\x3a\
+\xc8\xe7\x9c\xc3\x88\xe3\xd6\x05\x8f\xf7\xf6\x12\x43\x67\xf4\x63\
+\x98\xb5\x0a\x33\xcc\x3c\x4f\xc7\xea\xa0\xee\x1b\x05\x05\x58\xf9\
+\x3f\x6b\x15\x08\xfd\xb3\x29\x90\x8d\xe7\xb3\xfd\x75\x8b\xa6\xe3\
+\xf7\x94\x7d\x61\x46\x3d\xe8\x84\x1c\xb7\xb6\xd9\xdb\x1f\x13\xb6\
+\x62\x9f\xb8\x0d\xab\x8b\x0b\x4a\x52\xe8\x89\x48\x0b\xed\x4b\xce\
+\x02\x21\x27\xa4\x0b\x72\xc8\x10\xc3\x89\x08\x4a\x71\x43\x1f\x37\
+\xa3\xe4\xc4\xc4\xcd\x4c\x2b\x3b\x8e\xc2\x9c\x02\xaf\x04\xb2\x8c\
+\xbe\x19\xb5\xfc\x0c\x90\x0b\xa5\x7d\xe5\x85\xf0\x72\xe7\x34\xb2\
+\x02\x08\x12\xc0\x0f\xdf\x7b\x93\x16\xc2\x5a\xd5\x5d\x3a\xfa\x41\
+\x50\x07\xa8\x37\xe4\xc4\x89\x70\x0e\x93\x55\x21\xd1\x58\xac\xc8\
+\xf5\xb1\x00\xb0\xf4\x58\xe8\x65\x49\x80\x1a\x15\x15\x85\x3b\x7c\
+\xcb\x13\x1e\x8e\xa7\x1f\xfe\x85\x00\x9f\xd6\x32\x55\xca\x00\x1d\
+\xc0\x7a\x80\x43\x1a\x75\xe9\xe0\xc6\x3c\x9d\x2c\xbd\x14\x7a\x25\
+\xb5\x9e\x23\x0c\x62\x08\xa3\x34\xe4\x74\xc6\xfd\x28\xf9\x20\x82\
+\x37\x0b\x7c\xe7\xa8\xc5\xd9\x61\x5b\x31\xbc\xce\xc2\xcf\x03\xae\
+\x0e\xcc\x79\x52\x43\x67\x57\xfd\x33\x03\x6a\xaa\x29\xb7\xfe\x19\
+\xe9\x5b\xa2\x03\xe7\x75\xee\xb8\xd6\x48\xc9\x8d\xc3\x68\x89\x63\
+\xf7\x82\xf6\xd9\xd4\x0b\x51\xbf\xbb\xce\xad\xaa\xa3\xc2\xd5\x7a\
+\xec\x40\xf7\x56\x1c\x0f\x2d\x2a\xd6\x31\xa6\x51\x26\xe3\x9a\x04\
+\xa5\x90\xba\x91\x21\x28\x85\xd3\x8c\xb6\x6a\x24\x40\xbc\x60\xd8\
+\xd0\xac\xce\x0f\x29\xc7\x3d\x29\xa4\xfb\xac\x3d\xb1\x95\x17\x22\
+\xea\x8e\x18\xba\xb7\xb9\xec\x08\x2b\xcd\x3f\xda\x65\xbf\xfb\x14\
+\xac\x2d\x31\x32\xab\x3c\xbb\x72\x3b\x86\x68\x3b\x25\x0f\x5c\xab\
+\x3b\x1d\x50\x28\x81\xab\xdf\x0e\xb9\xc9\x4a\x75\x32\x03\xe4\x85\
+\x4e\x9f\xdd\x7d\x41\x51\xbb\xfb\x01\xbb\xfb\x01\xcd\xf3\x2a\xee\
+\xd9\x11\x7f\xfe\xc1\x00\x3a\xbd\x19\x8d\xab\x1b\x67\x12\xd0\xcf\
+\x73\xc3\xc9\xe8\x9c\x0e\x64\x09\x6c\xf9\x79\x3a\x80\xd3\xfe\xe0\
+\xc2\x8b\x2b\x09\x0d\xac\x33\xee\xf9\xf0\x3c\x61\xe0\x45\xe3\x38\
+\x83\xef\x30\x62\x7f\xef\x50\x69\xcf\xeb\xd8\xef\xa3\x9e\xbf\x8e\
+\x34\xd2\x8b\x20\x0d\xe4\x34\x18\xaf\xfb\x7b\x92\xad\x13\x2e\x3a\
+\x2d\x53\x50\x1a\x77\x67\x87\x6d\xe5\x0e\x0d\xcd\x27\x54\xf2\x19\
+\x6e\xd7\x16\xa8\xac\x88\x41\x06\xd1\x82\x00\x49\x7f\xb8\xa6\x48\
+\x4d\x77\xa9\x4e\xfc\x2d\xea\x46\x3c\xd0\x87\x88\x4e\x14\x90\x71\
+\x4d\xc5\xc6\xae\x33\xc1\x1c\x2e\x75\xb9\x8a\x3c\x91\x37\xbc\x94\
+\x64\x63\x19\x42\x8e\xba\x23\x15\xc9\x2b\x94\xf6\x13\x09\xf4\x6b\
+\x76\x5b\xb1\xf0\xd1\x33\x0f\xe7\x59\x05\xfc\x1d\x2a\x65\x9b\xc6\
+\x42\x8d\x97\xd6\x56\x55\x7a\xa4\xd4\x55\xed\x7e\x98\x90\x14\xad\
+\xae\xa7\xdc\x6d\x3a\x90\xa3\xf1\x25\x46\xee\x19\xfe\xc1\x50\x49\
+\x0a\x29\x39\x0e\xa3\xd8\x30\x3b\x9b\xfa\x8b\x0f\x46\xe2\xfb\x77\
+\x3a\x7d\xae\x3a\x9d\xb9\x27\x54\x7a\x0f\xd2\x0c\xab\x3f\xd6\x19\
+\x3a\x1d\x8e\xd6\x47\x7a\xc9\x5c\x0b\x23\xe8\x8b\xdf\x17\x37\x38\
+\x59\xd9\x68\x70\xfb\xce\xc6\x47\x1a\x6e\xd3\xc4\xa6\x05\x8c\xdc\
+\x33\x9e\xee\x2d\x70\xe2\x44\xec\xb6\x4e\x13\xde\x9b\xff\x3f\xc0\
+\x9d\x07\xc4\xb4\x1c\x79\xee\xe7\xc5\xf3\xf0\x5c\x67\x22\x16\xaa\
+\xe6\x07\xd7\x59\x5e\x77\xf3\x51\x8d\x12\x95\x31\xcd\x46\x44\xf7\
+\xaa\xcd\x69\xf7\x19\xfe\xc9\x43\x25\x29\xac\x85\x29\x61\x3a\xcf\
+\x84\xbb\x52\x46\x73\x2f\x7b\x59\x46\xa7\x41\xc2\x4b\xd1\x89\x02\
+\x25\x25\x80\x84\xb4\x28\x95\xb3\x98\x7a\x98\x59\x32\xac\x04\xb0\
+\xfe\x9c\x64\x63\xf9\x58\x26\xd0\xb7\x4d\x21\xba\xf7\xf7\xb6\x71\
+\x76\x0f\x15\x80\xa3\x85\x32\xb7\x6f\x35\xd8\xbc\x77\x97\x5b\x5b\
+\xaf\xd0\xa9\x85\x73\xfd\xb1\x41\xaf\x1e\x5b\xa7\xc2\x6f\x7c\xe2\
+\x44\x09\x0b\xd5\x39\x8c\x38\x8c\xb2\x0c\xda\x43\xdc\xb3\x23\xdc\
+\xb3\x23\xa2\xf1\xa5\xfa\x2f\xc1\x2e\xef\x97\x56\xd6\xe7\xea\x5a\
+\xbf\xe8\x31\xa9\x58\x89\x82\xcf\x79\x60\xd6\xbf\x9f\x5f\xf4\x04\
+\x40\xb5\x1c\x60\x1d\xc0\x51\xa6\x92\xa8\x93\xcb\x54\x3b\xa2\xbc\
+\xa8\x6c\x50\x5a\xb9\x9a\x09\x64\xe8\x00\x96\xf2\x49\xdf\x9e\x9c\
+\x3c\xe6\xd1\x9e\x90\x10\x59\xab\x90\x60\xf9\xef\xe5\xfe\x5f\x07\
+\xe8\xcf\xf3\x6e\x48\x63\x57\x5e\x6d\x16\xa2\x5e\x02\x9c\xcf\xfb\
+\x6c\x5d\x8e\xf5\x8d\x02\xd4\x4d\x06\x9d\x2a\xef\xb5\x8e\xe3\x64\
+\xad\x2e\xb5\xb0\x97\x30\xee\xd2\x49\x4b\x18\xc7\x1c\xb7\xa6\xb2\
+\x22\x8c\x92\x25\x5e\x19\xad\x35\x82\xeb\x4c\x84\x9c\x58\x37\xc7\
+\x44\xdd\x91\x48\x8e\x37\xba\x1c\xc5\xa5\x3b\x92\x99\xa5\x2e\x96\
+\x00\x1e\x2e\x75\x29\x5c\xd4\x54\x9e\x84\x7f\xd2\x21\x3a\x9b\xb0\
+\xdf\x7f\x06\xd6\x16\x2b\x75\xb8\x91\x13\x27\xdb\x58\x0d\xb9\xf3\
+\xb9\x8f\xb3\x94\x7f\x89\xa3\xc9\xe5\xcc\x6a\xcf\x54\x3b\x62\xfe\
+\x71\x1f\xe5\x72\x5b\xc9\x08\x81\x2f\x45\xbe\x0e\x52\x79\x93\xcc\
+\x9d\xde\xee\x1c\x0f\xa1\x5e\x55\x1d\xd9\x75\x90\xea\x7a\x38\x3d\
+\x1c\x66\x1e\x2b\xeb\xaf\xe9\xc0\x4e\xcb\x11\xd7\x99\x90\x09\x5b\
+\x6c\x36\x57\x79\x75\xbd\xa9\x74\xb0\x1e\x85\x3b\xeb\x65\x95\xc1\
+\x26\x81\xbb\xeb\x0f\xd4\xef\xfb\xce\x51\x04\xfd\x24\xc8\xe4\x40\
+\x46\x79\x05\xd1\xef\xcf\x2b\x8f\x9a\x07\xe8\x4e\x2d\x7c\x2e\xd8\
+\xaf\x03\xa2\xaa\x02\x8f\x8d\xd5\xef\x65\x41\xe8\x59\x83\x7a\x6e\
+\xf5\x71\x4b\xe4\xba\x48\x5d\x1c\x99\xd5\x19\xe3\x4e\x37\xf0\x2e\
+\x7b\x59\x65\xd8\x95\xad\x64\x7a\xa5\x04\xb4\xdc\x2a\xc3\x4e\xca\
+\x07\xc9\xc0\x0b\x86\x9d\xd0\xc4\x51\x77\x34\x95\x1a\xb9\x73\x05\
+\x60\xc9\xc6\xbb\xfb\x87\x7c\x67\x47\xf4\x98\xbd\x6d\x8f\x30\xed\
+\x25\xb2\xab\x05\xd6\xcb\x37\xb9\x73\xcb\xe2\xde\xc7\xee\xf3\x89\
+\x1f\xbd\x49\x79\xb1\xa9\x26\xd1\xab\xd0\x6e\xac\xc3\xe4\x20\x6f\
+\xc9\xc8\xd2\xf9\x2d\xd9\x19\xe0\x2c\x58\x54\xf7\xd3\x80\x9e\xf4\
+\x86\x1c\x1c\x7b\x9c\x9c\x3c\xc6\x08\x45\x86\x59\x7a\x98\x8b\xee\
+\x61\x90\x1e\x04\xbf\xe8\xcd\x14\x73\x4a\xd6\x95\xfb\xcb\x13\xa3\
+\xfb\x8d\xf5\xc7\x55\xdf\xa1\xb6\xd0\x48\x78\x22\x96\x0b\xcb\xf4\
+\x5b\x53\xe6\x35\x72\xcf\x70\x0e\x23\x1e\xfb\xcf\xd4\x6f\xf0\xb7\
+\x0b\x9c\x38\x11\xdf\x39\x6a\xd1\x0e\x3b\x4a\x03\x77\x8c\x68\x2e\
+\xe8\x74\x20\xab\x63\x28\x2f\xf7\xa9\xd7\x75\xf9\xa6\x6f\xbf\x57\
+\x30\xa7\xf3\x4e\xbe\x17\xb6\xd7\x17\x94\x7c\x6d\xe8\xbb\xec\x74\
+\x2b\x38\xa7\x11\x9d\xa1\x43\x68\xb6\x29\xd8\x49\xe3\x4e\xea\x61\
+\x3d\xc3\x4e\x1e\xa3\xab\x8e\x99\x00\xad\x69\x94\x09\x23\x47\xe5\
+\x52\xa8\xa4\x78\xf3\xea\x82\xa3\x30\xc7\xe8\x72\xac\xbc\x14\x57\
+\x91\xa7\x74\xb0\x64\x5c\xc9\xc6\x92\x99\x0b\x17\x35\xae\x22\x8f\
+\xa3\x67\x22\xa0\x51\x29\xdb\x64\x6b\x49\x7f\xd1\xde\x81\x4f\xe0\
+\x9e\xb0\xbe\x6e\x26\x58\x2d\x1d\x7c\xe8\x39\x45\xba\x9d\xee\x8c\
+\xb8\xd7\x81\x2a\x2d\x57\xf9\x03\x0f\x8e\x85\x51\x38\xe9\x0d\x69\
+\x85\x9e\xf8\xdf\x81\x4e\xa7\xab\x66\x64\x5c\xc7\xb4\x3d\xa7\x48\
+\xd5\x77\xc4\x90\x18\x6d\x30\xcc\xdc\xf0\x73\xaa\xbf\x84\xee\x72\
+\xab\x96\x07\x50\x37\x55\x7d\x5c\x22\x68\xb3\x28\x02\x30\x6f\x39\
+\x7b\x42\x2e\x38\x11\x85\x73\x41\xcf\x8f\xfd\x67\x6a\xd1\x02\x6a\
+\xf6\x47\x1a\xb0\x3a\x30\x5d\x67\xa2\x80\x22\xbf\xe3\x44\x1b\xa1\
+\x9b\xb8\x55\x93\x8f\xd3\x2c\x9e\xce\xed\xb8\x8e\x91\xd3\x36\x41\
+\x22\xd3\xac\x6a\x24\x5d\x79\x73\x3e\x6b\x99\x88\x56\xd7\x53\xc6\
+\x9d\xe9\x8c\xa8\xe4\x33\x34\xfd\x48\x19\x77\xa5\xb8\xff\xb4\x64\
+\xe2\x79\x9e\x0f\x09\x5a\x09\x60\x5d\x62\x98\x57\x91\xc7\x45\xb3\
+\xcc\xba\x29\xa6\x8a\x1e\x85\x39\xae\x22\x8f\x75\x73\xcc\x55\xe4\
+\xa9\x5c\x08\xdb\x17\x6c\xdc\x9e\xd8\xca\xb0\x1b\x2e\x75\xf1\x2f\
+\x2b\xec\x77\x9f\x72\x11\x78\x44\x0b\x65\xf2\x9b\x1b\x64\x57\x85\
+\xe5\x6a\x0c\x9e\xc1\xce\x09\x4f\xf6\xde\xe5\xe8\x28\xa4\x5e\xab\
+\xcd\xd5\x4f\x32\xdf\xb6\x15\x1a\x74\x3b\x5d\x76\x5b\xa7\x2a\xc3\
+\x49\x02\xba\x5f\x38\x56\xf7\xd3\xc0\xdd\xef\x45\xf4\x9d\x42\xa2\
+\xc9\x89\x1c\xee\x22\x07\x1e\x02\x34\x7b\x41\x82\x8d\x75\xf0\xce\
+\xd3\xc9\x7a\x7e\xc5\xf3\xea\xea\x36\x9b\xab\x33\xa9\x95\xe7\xc3\
+\x73\x31\xfc\x1c\x31\x10\xf2\xc4\x89\x38\xeb\xb4\x69\x85\x62\xe1\
+\x15\xce\x9b\x9c\x75\xda\xb4\x43\x23\x61\xc4\xe9\x40\xd5\xb7\x7a\
+\xf1\xaa\x7e\x5f\x26\xf5\x1b\x41\x3f\x31\x0b\x5a\xff\xde\xf2\x33\
+\x25\x6b\xcf\x63\x58\xd7\x99\x90\xa1\x9b\xcc\xc0\x0b\x73\x2a\x45\
+\x75\x1e\x80\x75\x03\x7d\x26\x33\xb0\x27\x00\x1e\xd4\x1b\xca\xb8\
+\xeb\x5f\x5e\xe0\x8f\xe3\x29\x5c\x0b\x9a\xe1\xd6\xea\x27\x24\x45\
+\xdf\x28\xa8\x73\xed\xc5\x73\xf5\xc2\xc8\x49\x00\x58\x07\xb2\x59\
+\x5a\x1e\xb3\x58\xaf\x2b\x1d\xbc\x6e\x8e\x59\x30\x6c\x8e\xc2\x9c\
+\x02\xf2\x82\x61\x73\xe8\x08\x66\x96\x3e\x62\x10\xb9\xc7\xd6\x62\
+\x1f\xc3\x78\x85\x7a\x64\x28\x1d\xac\xdc\x63\xa1\xd0\xa8\x3b\xaf\
+\xef\x32\xde\x13\xef\x93\x39\xbe\xe9\x03\x23\x67\xba\x49\x40\x77\
+\x3b\x7b\x89\x93\x2e\x26\x16\x4d\x99\xab\x15\x7a\xf1\x7e\x5d\x11\
+\x12\xed\xf4\x13\x4c\x20\x87\xbb\xe8\x33\x33\xa8\x9b\x33\x2e\xb3\
+\xe7\x69\x61\xfd\xf3\xf4\xf2\x24\x7d\x9f\x5a\xa6\xa6\x1a\x5d\x8b\
+\x61\xe7\xd3\xdb\xae\x3f\xc0\x39\x8c\xe8\x46\xef\x72\xd6\x69\xd3\
+\x34\x6d\xf5\xdd\xe5\x55\xc3\xec\x25\xdd\x10\x93\x8a\x95\x60\x5e\
+\x1d\x20\x69\x2d\xac\x57\x5e\xeb\xad\x04\xe6\x85\xd8\xd3\x9f\x21\
+\x35\xaf\x9e\x52\xaa\xe7\x89\x7c\x94\xa4\x88\x7a\x11\x8d\x8a\x99\
+\x04\x70\x2c\x61\x4a\x61\x4e\x15\xe7\x36\xe3\xd4\x99\x41\xa7\xca\
+\xe8\xa8\xc3\x38\x3f\xf5\xcc\x2c\xdc\x11\x57\x93\xec\xf2\x03\x42\
+\x27\x50\xff\x2b\x91\x20\xa8\xed\xe3\x5d\x6a\xb1\xc7\xc9\x34\xca\
+\x0c\x26\xb9\x19\x4d\x0c\x60\x95\x82\x4d\x42\x5c\x16\xeb\xf5\x38\
+\x42\xb2\x0c\xdd\x11\x8b\xf5\x3a\x5e\x77\xc4\x82\x21\x18\x37\xe3\
+\xde\xc6\xc8\x7a\xb8\xe7\x39\xec\x7a\x9e\xcb\x4e\x87\x05\xc3\x66\
+\xf7\xc8\x81\xcb\x37\x68\xd6\x1b\x64\x57\x0b\x6c\x98\x02\xbc\x93\
+\xd3\x21\xc7\x63\x0f\xe3\x2a\x76\x6a\x13\x40\xa7\x07\x18\xb1\x6b\
+\xca\x9e\xd1\xaa\x3d\x0b\xd5\xa3\xb7\xe6\xd4\x68\x11\x89\xd6\xfe\
+\x15\x0f\xfa\xd0\x8a\xfb\xf1\xb7\xf0\xe8\x06\x5d\x4c\x6b\x85\xe0\
+\x9a\xcb\x98\x35\xb0\xd5\x9c\x0c\xc5\xbc\xf1\x02\xb9\xee\xf2\x38\
+\x0f\xd4\x7a\xe7\x1e\x2b\x6e\x7c\x22\x07\x2a\x6e\xd4\xb2\x09\x19\
+\x71\x73\xf2\x03\x89\x80\xc5\xd2\x38\xe2\xe0\xd8\x63\x10\xda\x89\
+\x85\xd7\x77\xa6\x2e\x2a\x11\xf1\x43\xb1\xa8\x94\x06\x7a\xc7\xa2\
+\x49\xc5\x82\x48\xb8\xf7\x6a\xe5\xaa\x72\xf5\xa9\x2b\x45\x0c\x7c\
+\xc9\x9a\x92\x9d\xb3\xf1\xa2\x70\xfb\xc9\xb4\xd1\x7a\x39\x0b\x44\
+\x33\x75\x85\x35\x6a\x22\x73\x2f\xfe\x7d\x32\x37\xba\x6e\x56\x67\
+\x02\x1e\x13\x7f\x48\xbb\x1f\xb2\x64\xd9\x94\xca\x4c\x7b\x7c\xf4\
+\x72\x64\xc2\x16\x41\x3c\x6d\x55\x04\x3d\xda\x1c\xb7\xb6\x39\x76\
+\x1f\x70\xef\xc0\xa0\xb8\x71\x48\x73\xe1\x06\x1b\x85\x35\x2a\xeb\
+\x5b\xf4\x8f\x76\xa6\x0b\xc7\x5a\x07\x7f\x87\x70\x6f\x9a\xbe\x30\
+\x98\x8c\x80\x1c\xe5\x5c\x0e\x34\xbf\xb4\x33\x8e\x87\x31\xca\x22\
+\xd0\xc4\xa5\x22\x2e\xfb\x31\x6a\x79\x8c\x5a\x9e\x52\xb0\xa9\xa2\
+\x72\xeb\x8b\x05\xa2\x18\xe4\x99\xa6\xd0\x77\x6b\x6b\x4b\xdc\xda\
+\x7a\x85\xf5\xf2\x4d\x8e\x72\x2b\xd0\x15\xcf\x1b\x57\x0e\x2d\x02\
+\x5a\x9d\x36\x74\x7a\xaa\x79\xc9\x3c\x36\x94\x9e\x04\x31\x35\xc8\
+\x26\x13\xb6\xa0\x67\x08\x3f\x72\x47\x38\xfe\xf5\xff\x00\xe1\xe5\
+\xc9\xb5\x9a\x4e\x4a\x88\x19\x63\x44\xbb\x02\xa4\x59\xa6\x66\x56\
+\x67\xa2\x79\x7e\xd1\x13\xf9\x11\x5a\xe7\x9e\x9e\x55\xa6\xea\x3b\
+\x34\x6b\xb6\x2a\x31\x4a\xdf\x8e\x5b\x17\x1c\x1c\x7b\x0a\xb8\xf2\
+\xaa\xd1\xea\x24\x93\x69\xea\xf5\x4a\xe2\x72\x4f\xcf\x50\x60\xec\
+\xd4\x42\xda\xa3\x5e\x3c\x61\xa9\xa0\xd8\x56\xce\x7b\x56\xa0\xbc\
+\xc6\xf7\x7d\x9d\x9f\x3c\x1d\x95\xd4\x0d\x6d\xf9\xfb\x24\x53\xeb\
+\x5d\x8a\xd2\x40\x96\xb9\x14\xfa\x42\x70\xcd\x31\x41\xbd\x41\xa6\
+\xd3\xa6\xd9\x10\x41\x8f\x8b\x74\x2b\xbc\xe1\xec\x31\x53\x7a\xb8\
+\x70\x42\x25\x1a\x52\x5b\x68\x88\x1c\x99\x23\x71\xa5\x2a\x66\xc7\
+\x38\xe3\xb1\x60\xe0\xb8\x54\xa9\x98\x15\x6e\x40\xeb\xf4\xd1\x1e\
+\xd6\x5a\xfd\xda\x1f\xbd\x51\xb6\x19\x65\x4a\x1a\x38\x0a\x88\x41\
+\x19\x60\x37\x61\x73\xbd\x8c\x7f\xef\xae\x72\xa7\xdd\x3c\xb5\xd8\
+\xf5\xf6\x39\x39\xb9\x50\xec\xab\x0e\x76\xcc\x2c\xe9\xc1\xdd\x69\
+\xf0\x15\xac\x52\xac\x57\xc7\xe0\x14\x81\x79\x40\x2d\xe2\x57\x3d\
+\xfc\x9e\xcb\x72\xdd\xe0\xbc\x13\x25\xe6\x24\xa7\x3f\x4f\x2d\xd0\
+\xa0\x0f\xd8\x73\x0d\x11\x31\x89\x47\x78\x23\xdc\xfe\x34\x8b\xed\
+\xaa\x62\x91\xc5\x9f\xeb\x8d\x90\x3a\x58\x67\xe0\xe3\xd6\x85\xd2\
+\xec\xf4\xa7\x9e\x17\x7d\xe6\x5d\x5d\x16\x9c\xfa\x43\xc5\x92\xa3\
+\xb6\xc3\xc6\x9d\x06\x5f\x7a\xe5\x25\x8a\xdf\x27\xaa\x59\x8e\x8e\
+\x42\xf6\xb7\xf3\x1c\x7e\xe7\x37\xa7\xa9\x9d\x65\x31\x2a\xb7\x16\
+\x7f\xcf\x6e\xd1\x83\x38\x47\xba\x1b\xf4\x00\x9b\x7a\xd7\xc4\x35\
+\xe7\x87\xd3\x67\xec\x92\x8a\x35\x3b\x82\xa1\x1a\x7d\xcf\x5e\x09\
+\xd7\x99\x88\x6c\x39\xf9\x19\x3d\x43\x68\xe1\xa0\x4b\x00\x2c\x55\
+\x60\xa7\x5b\xe1\x4b\xf2\x9c\x30\x20\xdb\xee\xb2\xba\xb8\xc0\xad\
+\xaa\xc3\x43\x92\xdd\x88\xfa\x86\xc8\xe5\x70\xcf\x8e\x38\x76\xd7\
+\x69\x70\x87\xc1\x24\x37\x35\xf0\x6a\x3e\x61\xe4\x30\x98\xe4\xc4\
+\x1c\x3b\x00\xff\xa4\x43\xef\x9c\xb9\xcd\x2c\x76\xe9\x70\x18\x5c\
+\xb0\x21\x9b\x6e\x67\x37\xb0\x16\x3d\xe8\x78\x5c\x76\x3a\xec\x1e\
+\x39\x18\xab\x21\xcd\xee\x6d\x5a\xec\xab\x6c\xa4\x76\x0c\x60\x79\
+\x59\xcb\xf6\x7d\xa8\x66\xc1\x99\x3f\x81\x3e\x7d\x19\x97\xc3\x0a\
+\xa5\x81\xa6\xef\x2b\x81\xe9\xf7\x42\xac\xaa\xc9\x79\x27\x54\xc3\
+\x0c\xf5\xf7\xa5\x01\x3c\x2f\x99\x67\x9e\x7c\x90\xd3\xea\x6b\x66\
+\x95\x6e\xb1\x47\xb6\x9f\x7c\x4f\x6d\xa1\x41\xf1\xbe\x37\x53\x62\
+\x24\x3c\x10\x17\x42\xb7\xc7\xe0\xad\xc5\x6d\x4c\x45\xc6\x5b\x72\
+\x68\xa3\x94\x00\x2a\x21\x7c\x73\x8d\x4f\xbd\x7c\x8b\xaf\xfc\xa3\
+\xaf\x50\xfa\xc4\x0b\x5c\x99\xd0\xde\x1e\xf1\x27\xfc\x1e\x3b\x4f\
+\x2d\xba\x81\x90\x13\xad\xd0\x88\x67\x47\xcb\xdc\x0d\x21\x21\xba\
+\x7a\xc6\x5e\x0c\x28\x29\x2f\x66\x7e\x73\xdc\xc2\xb6\x1b\x4e\x7f\
+\x9f\x3c\x76\x69\x43\x4d\x77\x9d\x49\x29\xa1\x8c\xc8\x9e\x41\xb5\
+\x3a\xa0\xe7\xa4\xdc\x73\x64\x45\x20\x4b\xef\x6d\x17\x8f\xb9\x5d\
+\x2a\x14\xe8\x67\x8d\x19\x26\x56\xa5\x6b\xe5\x21\xdd\x8e\xf0\x42\
+\x1d\x0f\x2d\x36\x8d\x0e\x9d\x48\xe4\x87\x86\x91\x83\xd9\xab\x63\
+\xd6\x62\x92\xab\x46\x58\x7f\xfe\xf0\x4d\x8c\xc2\x0a\x37\x2d\x8b\
+\xab\x7d\xc1\xa6\xd1\xa9\x89\xb5\xbe\x49\xe0\x3f\xa5\xd9\xbd\xcd\
+\xed\xca\x11\xa1\x1d\xb7\x0d\x9d\x1c\xb2\x7b\x64\xb1\x91\xf1\x39\
+\x0c\x2c\x02\x5f\x18\x33\xad\xda\x3e\xd1\xa9\xc9\x33\x3f\x3e\x29\
+\x12\xc0\x9a\x2b\xa8\x1b\xf4\xa0\x48\xa2\xc0\x52\x19\x53\xd2\x10\
+\xd3\xb6\x0c\x50\xc3\x0b\x67\x46\xca\x0e\x52\xef\x21\xf6\xe1\x22\
+\x64\x49\x61\x30\x7f\xe0\xb7\xc8\x62\x9b\x0f\xe0\x9a\x53\x4b\x9c\
+\x7c\xb7\x2f\x98\x59\xf7\x0f\x37\x7b\x01\xcd\xda\x0d\x3e\xbe\xb9\
+\x30\x13\x42\x96\xfe\x6a\x9d\x7d\xbb\x41\x37\x1e\x30\x8e\xda\xaa\
+\x4b\x7b\xd7\x84\x6a\x96\x97\x1e\xbc\xc0\xe6\xbd\xbb\xdc\x5d\xce\
+\x72\xeb\xde\x16\xc5\x9b\x2b\x74\xdb\x01\xa7\xef\x74\x78\xfd\x83\
+\x3f\x63\xef\xf1\x07\x64\xfb\x3e\xf5\xfa\x72\x9c\xd2\x6a\x43\x6c\
+\x68\x4a\x26\x15\xfa\xf5\xfa\xe8\xa3\xf4\x77\x2b\xad\x1d\x77\xfb\
+\x94\xbf\x6f\x26\x27\x79\x4e\xee\x35\xc0\x45\xe0\xb1\x64\xd9\xd4\
+\x25\x1b\x57\xa3\x69\x3b\x83\xf8\x73\xab\xe5\x81\xf0\xff\xc7\x00\
+\x0e\xea\x0d\x76\x5b\xa7\x1c\x07\x07\x94\xdb\xfb\x30\xfc\x24\x64\
+\xcb\x2c\xad\x5b\xc2\xcd\xf6\xfe\x1f\xd3\x1f\xae\x51\xe2\x48\x54\
+\x89\x94\x1b\x10\xe7\x9b\xd7\x52\xc9\x67\x83\x49\x8e\x62\xb5\xc3\
+\x60\x3c\x6d\x0c\x69\xad\x97\x6f\x2a\xe0\x3d\xf3\x7d\x38\x82\x68\
+\x78\x02\x1f\x3c\x8b\x13\x70\x4e\xe0\x02\x8c\x82\xf8\xa1\x37\x63\
+\x6b\x69\x37\x96\x0f\x00\xd1\xa9\xd0\x38\x47\xcf\x3c\x26\xde\x31\
+\xce\xb3\x8a\xd0\x4c\xfe\x90\x4e\xcc\x04\xf5\xc8\x48\x8c\xbc\xd5\
+\xe7\xb4\xc9\xc7\x12\xb0\x0a\x9c\x96\x60\xdd\x4c\xa6\x06\x74\xa7\
+\xcc\x1a\x3b\x0a\x74\xd0\x4b\x26\x2e\x0c\x4a\x0c\x7b\x2e\x3e\x42\
+\x52\xe8\x4c\x2c\x80\xd8\x67\xe8\x4f\xf7\x6f\xf6\x02\xa5\xc3\x25\
+\x80\xf5\x74\x4d\x6b\x20\x18\xd9\x65\x42\xd3\x8c\xa8\xdd\x91\x79\
+\x11\x57\x8a\x85\xa5\x0f\x58\x67\xe0\x80\x9a\xca\xb3\xf0\x7d\xf1\
+\x7d\xe4\x1c\x3b\xc8\xaa\xb6\xb2\x9f\xb9\xb3\xcc\xdf\xfc\xa7\xf7\
+\xb9\x63\xdd\xc7\x66\x81\xca\x4d\x8b\x63\xe0\xe8\x9b\xdf\xe5\xe7\
+\xff\xb7\xd7\x79\xba\x2d\x86\xf3\x98\xc5\x08\x3a\x02\x28\xa5\x6a\
+\x36\x31\x9c\xd1\xed\x4f\x70\x99\x02\x52\x1a\x7c\x89\x81\x90\x45\
+\x0f\xd7\x91\xe0\x1c\xcf\x18\xae\x3a\x0b\xeb\x4c\x3d\x4f\x53\x5f\
+\x04\x1e\x75\x8c\x44\x74\xcf\x35\xc7\x6a\xa8\x8e\x34\x56\xe9\x19\
+\x64\x9b\x79\x2a\xd1\x90\xee\x55\x88\x7f\x30\xe4\x24\x28\xb2\x64\
+\x3a\xc0\x22\x8d\xc1\xd4\xc5\x39\x29\x1c\x81\x13\xbb\xd8\x1c\x8f\
+\x5a\xa6\x46\xb7\xd3\xe5\x38\x38\xe0\x13\xbc\x48\x31\x9b\x67\x30\
+\x11\x3a\x58\x4a\x0b\x95\x9d\xa8\x03\x53\x6e\x29\xdf\x9c\x7b\x99\
+\x7f\xe6\xfb\x18\x83\x67\xc2\x78\x03\x38\x12\xef\x79\xe6\xfb\xd4\
+\x3b\x1e\xfb\xdd\xfd\xb8\x55\xeb\x98\x8b\xc0\x03\x63\x3a\x87\x58\
+\x9d\xd0\x39\xab\x3e\x5d\x41\xa1\xef\x53\xb0\x4a\xd0\xf7\x09\xe2\
+\xfb\xf3\xe4\x85\x3c\xf8\xe9\xc9\x9d\x72\x7f\xc9\xf4\x69\x5f\xb0\
+\xf4\x88\xe8\x60\x96\xba\xd9\x2f\x6a\x03\x15\x7b\x39\xaa\xa1\x43\
+\x2d\xd3\x88\x27\x77\x4e\x01\x7c\x30\xbc\xc9\xc8\x39\x54\x00\x6e\
+\xb5\x0d\x5c\x53\xe8\x78\x0b\x9b\xf1\xf8\x04\x62\x83\x4c\xaf\xd3\
+\x93\x03\xcc\xd7\xca\x06\x7b\x07\x3e\x66\xb8\xc3\xa0\xb3\xcd\xe9\
+\x1f\x1f\xf2\x03\xaf\xfe\x10\x00\x9f\xf8\xd1\x9b\xdc\xb6\x3f\x4b\
+\x6b\xe1\x81\xb2\xe0\xcf\xb6\xdf\xa0\x49\x53\x63\xc0\x89\x02\xae\
+\x3c\xc6\x6e\x6c\x43\xc8\xb6\x5c\xfa\xa0\x48\x1d\x74\x7a\xf0\x46\
+\x12\x86\x3c\x4e\x99\xb8\x87\xf2\xdc\x4e\x9e\xb1\x8c\x90\x19\xe9\
+\x72\xf1\xcf\xb8\xf4\xaa\x59\x91\x9f\x1c\x67\xca\x1d\x8c\xba\x30\
+\xfe\x10\xf8\x7e\x16\x32\x11\x7b\x95\x12\x5b\x95\x21\x0f\xd7\xb7\
+\xe8\xef\xed\x28\xcf\x83\xe8\xfb\x86\x60\xe3\x5e\x96\x43\xd7\xa0\
+\x52\x14\x03\x0b\x07\x13\x7d\x5e\x74\x9c\x69\x28\xe5\x43\x7a\x9b\
+\x06\xef\x4d\xcb\xe2\xa6\x65\x11\x59\x37\xb9\xa9\x3d\x0f\x10\x9d\
+\x4d\x78\x77\xe7\x21\x51\xdc\x0e\xe9\x22\xf0\x94\x1f\xd3\x2f\x82\
+\x3b\xe7\xb2\x95\x98\x7d\x9c\x9a\x44\x6f\x61\xce\x68\x59\x09\xc8\
+\xb4\xbc\x60\x30\xdf\xf8\x48\x03\x7e\xd8\x73\xa7\x2e\x37\x8d\xe9\
+\xe5\xdf\xed\x59\x82\xe5\xba\xe5\x6e\xa2\xb3\x8f\x72\xb1\x99\x4d\
+\x56\x36\xea\xca\x9d\x26\x2b\x2f\x46\xad\x29\x80\x0f\xbb\x13\x86\
+\xa1\x0b\xa1\xb6\x80\x62\x00\xcb\xef\x2a\xbd\x1d\x3d\x47\x8c\x0d\
+\x33\x72\x8b\xac\x5c\x1e\xf0\xd4\xbf\xc3\x07\xaf\x3f\x06\xe3\x98\
+\xa8\x78\x93\xfb\x9f\xff\x24\x3f\x76\xe3\x0b\x14\xbf\xfc\x05\x26\
+\x8d\x02\x17\xad\x2f\xf1\xd6\x1f\xee\xf2\x26\x30\x39\x7f\x04\x3d\
+\x03\xbf\xec\xc5\xda\xb8\x88\xcb\xac\xf4\x91\x25\x55\x69\x3b\x20\
+\x13\xb6\xf0\xcb\x99\xc4\x00\xf5\x82\x55\x12\x83\xd1\x7b\x0e\xe7\
+\xb8\xe0\x94\x66\xd2\x2b\xf5\xec\x36\xf5\x58\x6b\x40\x9e\x96\x23\
+\xea\xbd\x71\x0e\x89\xe5\x9e\xb3\xbb\x6b\xb2\xb1\x75\xc1\xc2\xc6\
+\x6d\x2a\x0b\x8b\x74\x17\xe4\x49\xd8\xc2\x2c\x9c\x28\x03\xaf\x44\
+\x8e\x7e\x27\x6e\xec\xee\x6f\x03\x9f\xc1\x1f\x58\x58\xc5\x3e\x50\
+\x49\x78\x44\x4c\x80\xae\x7f\x7f\xea\xc4\x8e\x01\x6c\xac\x86\x82\
+\x79\x57\x43\x6e\x5a\x96\x92\x0e\xfa\x56\x32\xf7\x7e\xf7\x29\xad\
+\x83\x4e\x02\xc0\x1d\x23\xa2\x66\x56\xe7\xb2\xaf\x1e\x54\x48\xaf\
+\x74\x69\xb0\xe9\x46\x9c\x6e\xa4\xe9\xa1\x64\xfd\x73\xd3\x9a\x59\
+\x37\xfe\x74\x50\xfb\xbd\x90\x28\x53\x51\x72\x42\x06\x32\xfc\xa2\
+\x97\x00\x70\xa2\x8a\x23\x14\x5d\xd1\xd7\xca\xd3\x0a\x8d\x83\xe1\
+\x4d\x8e\x5b\xc2\x88\x6b\x75\x62\x00\xfb\xee\xdc\x2b\x80\xba\x52\
+\xc4\x7f\xaf\x15\x0a\x5f\x79\xd0\xab\x73\xdc\xba\xc0\xfe\xf4\x16\
+\x3f\x7c\xcb\xe0\xc1\x8f\xdf\xe3\xc5\x1f\xfc\x22\x9b\xb7\x37\xf0\
+\x4f\x3a\x7c\xeb\xf0\x82\x77\xdf\x38\xe1\xfd\xdf\xd9\x65\xcd\xdb\
+\xe7\x1f\xfc\x0d\x93\x2f\xff\xc4\x06\xd9\xe5\x07\x1c\x4d\x2e\x89\
+\x32\x95\x44\xcf\x37\xfd\x7b\xcf\xdb\xca\xbf\x9f\x0e\xb3\xeb\x84\
+\x71\x8e\x91\x78\xec\x9a\x63\x5c\x73\x3c\x75\xb3\x69\x1d\x46\x13\
+\xb3\x4f\xb4\x9b\x1e\xf5\xd3\x0d\xbb\x9d\xae\x00\xdf\xd9\xf0\x29\
+\xe3\xe1\x15\x99\x6e\x9b\x8d\xc2\x9a\xc8\xa1\xf0\x77\x66\xab\x45\
+\xea\x26\x83\xf6\x90\x6a\x7f\x91\xfe\xa0\x8b\x55\xf4\xf1\x07\x96\
+\x62\x61\x95\x3b\x11\x9d\x9a\xd4\xd7\x3f\x4c\x80\x57\x82\xba\xcc\
+\x83\x19\x46\x4e\x3f\xb6\xd6\x37\xb9\x5d\xbb\x4b\xb6\x99\xe7\x22\
+\xf0\x44\xda\x5e\x2a\x14\x19\x65\x2a\x89\x18\xbc\x7e\x40\xf5\x01\
+\x31\xd7\x01\x53\x02\x21\x0d\x50\xc9\xdc\x12\x2c\x2a\xd4\xdc\x0b\
+\x67\x16\x8d\xee\xa9\xd0\xf5\xae\xcc\xa3\xb8\xce\x53\xe2\x3a\x13\
+\x6a\x77\xa6\xc9\x3d\x52\x03\x37\x2f\x8e\x14\x80\xaf\x3a\x9d\x04\
+\x9b\xe9\xdf\x5b\x7e\x17\x1d\x60\x7a\x7f\x8b\xb3\xc3\x36\x7b\xaf\
+\x1d\x52\x5e\x35\xf8\xe2\x67\x3e\xc7\x8f\xfe\xbd\xcf\xf2\xf2\x27\
+\x57\xb9\x73\xb3\xc8\x46\xc6\xe7\x5b\xdf\x7d\x8d\xdf\xfa\x8d\x5f\
+\xe1\xf7\x7e\xf5\xf7\x38\x0a\x73\xdc\xbb\xf3\x0a\xad\x07\x1b\x34\
+\xf2\xd5\x99\x06\xdf\xd7\x79\x5c\x12\x55\xdf\x73\x8e\xb1\x7e\x7f\
+\x99\x48\x91\x46\x22\x76\x10\xf4\xe7\xba\xe9\xd2\xcf\xa5\xcf\xab\
+\xee\x92\x6b\x75\x3d\xa2\xec\x19\x79\x56\x70\x49\x85\xb2\xad\x64\
+\xb9\x52\x89\x1c\x01\x35\xd1\xe2\xd5\xbd\x60\xa3\x34\xdf\xe5\x57\
+\x2a\x67\xb1\xee\x7f\xfe\x93\xf8\x97\x15\xac\xcf\xf7\x45\xf4\x0d\
+\x78\xf5\xee\x90\xc3\xe0\x2e\x0b\x77\x7c\x02\x1f\x16\xec\x0d\x5a\
+\xec\xc7\xa0\xfe\x50\x31\xf6\xfa\xba\xa8\xe6\x30\x56\xb2\xe2\x4b\
+\x04\x0f\x55\x56\x5a\x3d\x32\xe8\xc4\x91\x26\x79\x49\x13\xee\x9e\
+\xf9\x2e\xae\xb4\x3e\x53\x46\x9a\xef\x42\x0f\x7c\xdc\x84\x11\x37\
+\x57\x0f\xc7\xd2\x41\xee\x3b\xec\xb9\x09\xa3\x45\x07\xb2\x6e\xd0\
+\x28\x3d\x88\xa9\x5c\x4d\xcd\xfa\x40\x15\x82\x16\x57\x93\x25\x56\
+\x8f\xfd\x67\x14\xce\x9b\x74\x3b\x5d\xdc\x98\x09\x75\xf6\x95\x2c\
+\xaf\xff\x16\x7d\xe1\xd6\x23\x43\xc8\x8c\x6a\xc4\xf6\x55\x87\xee\
+\xaf\x7f\x9d\x47\xef\xdc\xa0\xfc\xca\x21\x0b\x5d\xd1\x19\xe9\x0b\
+\x1f\xbf\x4f\xb1\x9e\x61\xf3\xde\x5d\x8e\xc7\x1e\x61\x7e\x19\x3f\
+\x7c\x88\x65\xbe\xc4\x0f\x1b\x23\xde\x90\x2e\xba\x39\x2c\x7c\x5d\
+\xe4\x32\x7d\xac\xf5\xab\x97\xce\xc4\x46\x3f\x22\xdf\x28\xcf\x1c\
+\x2f\x5d\xeb\xea\xe4\x23\xc9\x44\x12\x4b\xda\xd5\x26\xd9\xbf\x06\
+\x8c\x0f\x26\xf0\xfd\x10\x19\x5d\x20\x98\x1b\xf4\x90\x92\xa2\xa9\
+\x35\x79\xba\x74\x45\xae\x85\x55\xf4\x29\x7a\x2e\x7d\x16\x89\x68\
+\x09\x4d\xbc\xba\xb1\x81\xb3\x50\xa6\x5c\x74\x58\xdd\x00\xbf\x2f\
+\xc2\x2b\x2b\xdd\x51\x9c\x00\xf4\x4a\x2c\x6b\xea\xf8\xf9\x0e\xd6\
+\xda\x2b\xec\x5a\x9a\x53\x70\x1d\xd6\xfd\xa7\xec\xaf\x6f\xb1\xfb\
+\xd6\x9f\x53\xcf\x2e\xaa\x4b\x88\x8c\x0e\xd5\xca\xc2\xdf\x0a\x95\
+\x19\x8b\x39\x7d\x5f\xd7\xc9\xc2\xa8\x22\x21\x23\xa4\x0b\x2d\xed\
+\x47\x96\x5e\x09\xaa\xe2\x3d\xfa\xeb\xe9\x13\xb6\x4c\xa4\x2e\x9b\
+\xcb\x44\xf4\x00\x33\xec\x01\x75\xc2\x4e\x87\xe5\x66\x4d\x65\xb9\
+\xd5\xea\x0d\x5e\xb0\xa6\x39\xc2\xdb\x8f\x42\x0a\xbd\x26\xbb\xad\
+\x53\x7a\x4e\x51\x7d\xae\x6e\xc0\x0d\xfd\xa9\x27\xc2\x1a\xd8\x6a\
+\xa1\xc8\xdf\xa4\x8f\xba\x2d\x58\x25\x7a\xc0\x5b\x3b\x27\x98\x4f\
+\x3e\x24\x72\x2b\x2c\x55\x44\x7f\xb2\xf5\x7b\x5f\x64\xf3\xde\x06\
+\x5f\x78\x61\x93\x93\x70\x0d\xcb\x14\x44\xf3\xf0\xfd\xf3\x99\x2b\
+\xca\x75\x41\xa3\x79\x72\x4b\x5e\xb9\xe8\xcd\x46\x36\x0b\x56\x89\
+\x11\xce\xcc\xfe\x05\xab\x94\x18\xb2\xa3\x37\x57\xd4\xf7\xd5\xff\
+\xa6\x0c\x9b\x97\xca\x62\xd0\x7a\x37\x80\x9d\xfd\x3e\x2f\x5e\x5e\
+\xd0\xb8\xb5\xc5\x62\x63\x13\xd8\x4b\xba\xd9\xfc\x23\x05\xe4\xbe\
+\x51\x50\x19\x8b\x1e\x57\x71\xe3\xca\x0a\xbd\xc8\xc3\x2a\x7a\xf8\
+\x72\x1c\xb2\x4d\x0e\x8a\x5a\x32\x45\x25\xbe\xd4\x55\x2a\xac\x02\
+\x36\x01\x1e\x19\xc2\x41\x48\x18\xe7\x57\xc8\x3c\x8b\x28\x06\xfa\
+\xf2\xc2\x57\xc8\x58\x1f\xb2\xf3\xb4\x09\x5d\xe1\x10\x97\xda\x78\
+\x52\xb1\xe8\x10\x51\x37\xab\x74\x88\x34\x46\xf6\x67\xee\xa7\xa5\
+\x86\xce\x64\xf2\x80\x4b\xb6\x4d\xb0\xb5\xe6\x52\x4b\xeb\x69\xdd\
+\x90\x93\x8f\x7b\x56\x19\x7c\x97\xaa\xef\x08\x30\x03\x8b\x66\x85\
+\x16\x90\xcb\xad\xd1\x73\x44\x7e\x44\xed\x4e\x43\x25\xb9\xef\xfa\
+\x03\xc2\xa3\x0d\xfa\x85\x77\x39\xd9\x1b\x27\xb4\xa8\x34\xe0\x74\
+\x06\x4e\xe8\xd3\xd8\xaf\x9d\xce\x8e\x2b\x55\xb3\x4c\x0c\x8b\x7a\
+\xd7\xa4\x64\xe6\xa0\x5e\xa7\xb9\x04\x9f\x7a\xe5\x05\x3e\xf1\xa9\
+\x17\x09\xef\x3c\xc3\xdc\x3b\xe5\x1b\xe7\x13\x16\x6c\x9f\xab\x27\
+\x87\xbc\xf1\xfe\x5f\x31\x39\x3f\x52\x75\xea\xfa\x15\x4e\xff\x3e\
+\xf2\x6f\xa6\x01\xac\xa2\x9a\xbd\x59\x90\x0e\x7d\x97\x51\xdb\x21\
+\xaa\x18\x62\xa1\xa7\x5e\x5b\x26\xa2\xe7\x94\x67\xe4\x42\x9a\xcd\
+\xe5\xdf\xc9\x84\x2d\x4a\xd5\xc6\x34\x5a\xd9\x11\x39\x14\xa3\xa3\
+\x0e\xd1\xfa\x39\xb9\x8d\x06\x37\x3e\x56\xe5\x3b\x1f\xc4\x55\x1c\
+\xbe\xf0\x50\xa8\x4e\x9b\x8e\xc8\x58\x3c\x1e\x5a\xdc\x02\xaa\x46\
+\xc8\x80\x3e\x90\x4c\x1d\xb0\x3c\xc6\xe4\x0b\x21\xa3\xa1\x39\xb3\
+\x55\x65\x4b\xe4\xe2\x39\x83\x7a\xf5\xab\x07\x95\x05\xb2\xb4\xa8\
+\x34\x96\xf9\xdb\x1b\x77\xf9\xb3\x3f\x3a\x10\xe1\x51\x3f\x62\xc9\
+\xb2\x55\x75\x82\x14\xfb\x75\xb3\x4a\x27\x8e\xf5\xcb\xe8\x92\x9e\
+\xb4\xa2\x07\x23\x54\x07\xf6\x5e\x88\x15\x9f\xb1\x82\x55\x52\x5e\
+\x06\xc9\x76\x09\x66\xd1\xa4\x83\x7c\x6f\xda\x9f\x2c\x13\x78\x86\
+\x18\x0a\xcc\xca\xa0\x89\x43\xca\x3d\xab\x4c\x50\x6f\xb0\x12\x37\
+\xaa\xde\xf5\x07\x2c\x9d\xd8\x7c\xe7\xe4\x31\x7d\xa7\x41\xcf\xe9\
+\xcf\x8d\x06\x8e\xc7\x27\xe4\x58\x9b\x0b\x64\xfd\x52\xde\x2d\x8a\
+\xc8\x9b\xeb\x4c\xc8\x02\xae\x29\x82\x2b\x5b\xa6\x41\xf1\xbe\x17\
+\x03\x58\x5c\x52\x9f\x9e\x4f\x78\xfd\xf7\xdf\x10\x9d\x7f\x34\xf7\
+\x98\xee\x49\xd1\x43\xe9\xba\x27\x64\x9e\x4e\x4f\x3f\x97\x5e\xf0\
+\x51\x3c\xd4\xe5\x42\x73\x02\x0c\xf5\x63\x74\x8d\x7c\x49\x2f\x08\
+\x19\xe4\xd0\x23\x7f\xd4\xc5\x39\xea\x55\x2e\x31\x96\x97\xb1\xa9\
+\xf0\xc9\xdb\x9f\xe1\x83\xca\x43\xe1\x75\xf1\x87\x98\x75\x5b\x25\
+\xc8\xcb\x71\x63\x2a\xd0\x61\x87\xf8\x03\x8b\xaa\x11\xd2\x1b\x78\
+\x58\x45\x5b\x34\x14\xb4\xc9\x61\x0e\x23\x6c\x02\xcc\x61\x3c\x93\
+\x21\xde\xe6\x0b\x61\xfc\x21\xde\x14\xb8\x6a\x2b\x9e\xb7\xb1\xf1\
+\xdb\x67\xd8\x35\x9f\x9f\xfa\x99\x2f\x51\x5f\x7c\x85\xa3\xab\x2b\
+\x2e\x02\x4f\x95\x85\x4b\x4f\x85\x9e\xef\x2a\x19\x44\x4f\xc8\x49\
+\x07\x19\x74\x9d\xab\x07\x44\xae\xab\x8f\xd3\x25\x84\xae\x9d\x75\
+\x00\x5b\x55\x53\x49\x89\x79\x9a\xb0\x67\x95\xa9\x96\x07\xdc\x6b\
+\x8a\xa6\x27\x17\x6b\x1e\x4b\x27\x36\x8f\xfd\x67\xa2\x61\x75\x47\
+\x00\xd8\x0c\x7b\x33\x97\xe1\x5c\x6e\x6d\xae\xaf\x3b\xed\x03\xd7\
+\x7f\x8f\xdc\x2f\xdb\xf7\x69\x05\x70\xf6\xa4\xc1\xd7\x77\xf6\xf8\
+\xf3\x3f\x3d\xe4\x4f\x7f\x79\x9b\x3f\xfc\xfd\xaf\xb1\xb3\xbb\xaf\
+\x0a\x5f\xe7\x75\x2c\x92\xbf\x4d\x97\x4e\xba\x36\x9f\xe7\xb9\x19\
+\xfa\xae\xea\xe1\x5c\xb0\x4a\x18\xfd\x88\x65\xa6\xc6\x53\x54\x31\
+\xbe\xa7\xec\x3e\xdd\x08\xd4\x8f\xa5\xde\x6d\xbf\x63\x88\x3e\x75\
+\x74\x42\x0e\x23\x31\xfd\xaa\x7d\xb0\xc3\x78\x78\x45\x34\x39\xa6\
+\x7a\x73\x43\x94\x2a\xf5\x0c\xfa\xc3\x35\xd5\xa4\xb0\xef\x14\x68\
+\x85\x1e\x6e\x5c\xde\x24\x3d\x13\x03\x3b\xc4\x88\xfd\x76\x71\x65\
+\x87\x97\x64\x57\x5d\x64\x0f\x0b\x78\xaa\xf1\xc6\x75\x40\x06\x8f\
+\x0c\xfe\xf1\x29\x9b\xf7\xef\xf3\x77\xff\xa3\x2f\xb2\x79\xf3\x87\
+\x45\x3a\x60\xa7\x4f\xa7\xd3\xa7\x51\x31\x67\xaa\x14\xd2\xae\x35\
+\xc9\xc6\x3a\xa8\x25\xf8\xfc\xa2\x37\xd7\xeb\x20\x73\x85\x75\xb6\
+\x9d\x77\x40\x75\x40\xeb\xde\x82\x74\xd8\xbb\xea\x3b\x54\xcb\x03\
+\x6a\xf5\x1a\xc3\xe5\x16\x17\x6b\x9e\x0a\x27\x9f\x3d\x69\x24\x72\
+\x7f\x43\xb3\x3a\xa3\x27\xa5\x6e\xd7\x7f\x83\xee\x19\xf0\x8b\xc2\
+\xaf\x2b\xaf\x4c\x52\xfb\x27\x4a\x8d\x3a\x7d\xfe\xe4\x37\xff\x8c\
+\xd7\x5e\x7b\x97\x6f\xfe\xe5\x43\x26\xad\x11\xcd\x5a\x93\x4c\xa3\
+\x96\x30\x98\x66\x02\x42\x73\xb4\x70\x9a\x69\xd3\xc7\xd0\xce\x64\
+\xd4\x6b\x51\xc5\x48\x64\x9b\x49\x80\x7b\x41\xa0\xfe\xeb\xbf\x51\
+\xff\xdb\xf3\x58\x58\x5d\x2d\xc2\x1e\xf5\xc8\x20\xca\x54\xb8\x0c\
+\xfb\x42\x1e\xc4\x6d\x78\x33\x83\x0c\x4e\x2f\x69\x34\xcb\x86\x3b\
+\x6a\x94\xc2\x9c\x61\xb0\xfe\xc0\x22\xa2\x05\xf4\xa7\x7e\x62\xfd\
+\x66\x93\xc3\x63\xac\x6d\x03\xf5\x8a\xbe\xd7\x8c\x21\xd1\xee\xe0\
+\x84\x7d\x7e\xe0\x2b\x3f\xcc\x7f\xf6\xdf\xff\x34\x5f\xfe\x47\xff\
+\x82\x8d\x57\xff\x21\xed\x51\x0f\x6b\x90\x57\x6d\xa5\x9e\x5b\xb3\
+\x15\x03\x59\x4f\x85\xd4\x99\x38\x11\x42\xd6\xc0\x9b\x8e\xc8\xa5\
+\xc1\xec\x05\xc1\x5c\xd9\x31\xb3\x30\xea\x26\xb5\x7a\x8d\xe2\xaa\
+\xc7\x0b\xd6\x4d\xda\x87\x2d\xfc\xed\x02\x1f\xb4\x3a\x84\xfe\x19\
+\xe7\x9d\x48\x81\xc4\x0c\x7b\xea\x04\xea\x27\x54\x46\xc8\xa2\x4c\
+\x25\xb9\xc8\xa4\x8f\x36\x9e\x24\xaa\x03\x41\x56\x54\xeb\x9f\xa3\
+\xb2\xcf\xcc\x31\x9d\x5a\x98\x58\xe0\xba\x54\x4a\xbf\x4f\x6f\x18\
+\x93\xf0\xfa\xa4\xae\x46\x33\xe9\xb7\xfd\x28\xc1\xbe\x12\xe0\xe9\
+\xed\xf3\x5c\x74\xf2\xb1\x5e\x64\xaa\x8f\x06\xce\xe5\xd6\xa6\x87\
+\xba\x50\x26\x73\xcb\xa4\xb1\x24\xbe\xcb\xad\xaa\x43\x76\xf9\x81\
+\xea\xdb\xa7\x7c\xce\x41\x57\xb5\x6a\x98\xbd\x55\x24\x13\xdb\x0a\
+\x98\x1e\x19\x60\xda\x0d\x5e\x00\xd8\x4e\x30\xee\x3c\x36\xb6\xc9\
+\xe1\xd9\x25\xec\xf6\x19\xe5\x41\xc8\xe6\xfd\xfb\x7c\xf9\x67\x5e\
+\xe4\x9f\xff\xcb\x1f\xe3\xe5\xcf\xfd\x24\x9d\x4e\x5f\xc9\x0b\x29\
+\x27\xae\x3a\x1d\xd5\xb3\x21\x68\x77\x71\x2e\x5b\x04\xed\x6e\xe2\
+\xc4\xea\x27\xbb\x69\x46\x89\xcb\xa5\x7e\x72\xd2\x60\xd4\x41\xdf\
+\x1e\xf5\x68\x68\x03\xaf\xf5\x13\x19\x76\x3a\x0a\x84\x4d\x33\x4a\
+\x00\xf8\xb1\xff\x8c\xca\xf0\x06\x67\x9d\x36\x51\x6f\x9a\xe4\x22\
+\x59\x47\x67\x62\x9d\x89\xa4\x91\xaa\x03\x53\xff\xbe\xf3\x6a\xd6\
+\x9e\x97\xa4\xaf\x2f\x6c\x3d\x99\x67\x1e\xdb\xa6\x0d\xdb\xb4\x4f\
+\x5d\x2e\x3a\xf9\xf7\x24\xbb\xea\xf2\xc1\x48\xcd\xe7\xf6\x82\x20\
+\x01\x60\x3d\xb2\x9a\x06\xb2\xdc\x66\xc2\x56\x02\xc8\xba\xcd\xd0\
+\x0a\x45\xbd\x5d\x67\xe8\x60\x3a\x19\x36\x1b\x9b\xd4\x3f\xb6\x7e\
+\xed\xef\xaf\x65\x6a\x2c\x74\xfa\x8c\x2e\xc7\xca\xc5\x66\x15\x7d\
+\x15\xf0\x50\x33\x3b\x04\x1c\x05\xeb\xba\x03\x83\x52\x31\x96\x11\
+\xde\x50\x03\xab\x27\x0c\x3c\x6f\xa8\xc0\xec\x69\xd3\x73\x04\x73\
+\x67\x70\x46\x2d\x9c\xab\xef\xb2\x10\xc2\xda\xcd\x02\x3f\xf5\x33\
+\x5f\x62\xe3\xd5\x7f\x48\xb6\xef\xb3\x7b\xf6\x8c\xa3\xab\x2b\x8e\
+\xae\xae\xf0\x82\x80\xd2\xfa\x02\x77\xee\xbf\xc4\xbd\xef\xfb\x24\
+\xeb\x77\x37\x71\xfb\x22\x09\xbc\xdf\x9e\xa8\xd2\x22\x79\x70\x64\
+\xbe\xb0\xae\x8b\xd3\x72\x61\x1e\x2b\xd8\x99\x4c\xe2\x79\x9d\x89\
+\xc3\x38\x09\x5e\x3e\x27\xcb\x87\x54\x75\x75\xa7\x1d\xfb\x82\x27\
+\x73\x3d\x1e\x73\xfd\xd5\x73\xca\xfd\xf5\xe8\xa0\x7e\xa5\xf9\x5e\
+\x92\xf8\xf5\x54\xcd\x79\x85\x04\x69\x37\xe2\x75\x36\x42\x3a\xfa\
+\x79\xdd\x4d\x67\x63\xa3\x1f\xcd\x00\xf8\xba\x9b\xfc\xfd\x32\x17\
+\x5c\x8f\xe2\x49\xe9\x98\xcb\xad\xd1\xed\x74\x39\x88\x26\x71\xbd\
+\xdd\x25\xad\xb0\xcb\x6a\x7d\xda\x11\x68\x5e\x4f\x8b\xc3\x28\xcb\
+\xbd\xdb\x59\x0d\xbc\xe2\xd8\x55\x8d\x30\xce\x01\xf7\xda\x60\x17\
+\x94\x7c\x28\x15\x03\xdc\xc1\x90\x52\xb1\x00\xb6\x94\x14\x36\xee\
+\x60\x88\x59\x1c\x63\xdb\x0d\x6c\xaf\x0d\x76\x43\xe4\x73\xe2\x29\
+\x30\xdb\x71\x02\x87\x07\x74\xdb\x5d\x6c\xc6\xbc\xd0\x28\xf1\xcf\
+\xff\xe5\x8f\xf1\xdd\x77\x6f\x71\xb5\x67\xe1\xf0\x88\x9b\x96\x85\
+\xb5\xbe\xc9\x67\x3f\xb1\x8e\x99\x29\x31\xa0\x8a\x37\xec\xf0\xe4\
+\xc3\x6d\xf6\xf7\xb6\xd9\x7b\xfc\x01\xbb\x3b\x07\xb4\x2f\x5b\x84\
+\x03\x71\x50\x6f\x7d\xf2\x8e\xb8\xbc\x1e\x5d\x25\x4f\x60\x2f\x19\
+\xd8\x90\xec\x5b\x69\x64\x67\x2e\xb9\x72\xff\x74\x35\x87\x9c\x66\
+\x34\x5c\x6e\x51\x19\xde\xa0\x5f\x38\x56\x35\x7d\x22\x78\x33\x99\
+\x3d\x61\xd7\xe4\x6c\xe8\x41\x81\x04\xd8\x52\xa9\xa1\xba\x57\x26\
+\xed\x39\x98\xe7\xf9\x98\x97\x0b\x3d\xcf\x38\xd5\x17\xb8\xf4\x5f\
+\x17\x72\x6b\x33\x57\x8d\x79\x0c\x9b\x96\x14\xcf\x33\xee\xae\x5b\
+\x78\xfa\x77\xd7\x93\xe4\xeb\x55\xa0\x9c\x85\x4e\xc8\xce\xf6\x19\
+\xfc\x28\x84\x3d\xb0\xcc\x88\xe5\xf6\xd4\xc5\x9b\x2d\x7c\x1c\xfc\
+\xa3\x69\x92\x7c\xec\x21\x79\xb2\x3f\x41\x14\x8f\x57\xa8\x1a\x2e\
+\x66\xad\xa1\x65\xb1\xd9\x0d\x3c\xc6\x84\x83\x21\xa5\x62\x14\x33\
+\x71\x14\x3f\x17\x0a\x30\x7b\x6d\x4a\xc5\x06\x78\x6d\x3c\x1b\xc2\
+\xc8\xa6\xa4\x71\xb0\x8d\x87\x3b\x30\xa0\x88\x02\xbd\x40\xf3\x90\
+\xb6\x9d\x61\xed\x66\x85\xd5\xfa\x97\xe1\x8b\x7d\x9a\x93\x2f\xd1\
+\x0f\xce\xc0\x8e\x2d\xea\xa1\x41\x35\x9f\x63\x62\x98\x6c\xae\x7e\
+\x19\x7e\xe4\xcb\x9c\x76\xae\x28\x5c\x79\x9c\x5e\x5e\x71\x38\x14\
+\xb5\x56\x9b\xeb\x65\x7e\xe9\x17\xdf\xe7\xe8\xe9\x2f\x51\x5e\x6c\
+\x52\xe8\x97\x12\x8c\xa3\x4b\x0a\x3b\x93\xc1\xef\x85\xea\x44\xa5\
+\xfd\xc4\x89\xbc\x64\x50\x32\xa2\x70\xde\xa4\xbf\x3c\x05\xf0\xe1\
+\xd1\x64\xd6\xf7\x0a\xd3\x54\xd0\x54\xb4\x4a\x82\x37\x51\xb0\x3a\
+\x27\x62\x26\xdf\x2b\x7d\xbb\xe9\xab\xc8\x3c\x00\x4f\xa5\x85\x3d\
+\x03\xd8\xeb\x8c\xbb\xa1\xef\xce\x05\xf0\xf3\x58\x38\x0d\x64\xf9\
+\xf8\xa3\xde\x3b\x6f\x11\x59\x55\x93\x9a\x53\x9b\xe6\x5b\x68\x79\
+\x14\x17\xdd\x27\x74\xbd\x4d\x8a\x1b\x4d\xce\xdb\x65\x95\xcd\x76\
+\xf8\x9d\xdf\x84\x7a\x45\x25\x01\xb5\x3a\x43\xa2\xf1\x25\x3b\x3b\
+\x5f\xe3\xac\x73\x9f\xd0\x5e\x65\x3d\x3a\x22\xb8\xb8\x43\x36\xb3\
+\x22\x98\x38\xe7\x0d\x71\x23\x62\xe0\x66\x00\xe1\x56\x93\xa0\x06\
+\x31\x39\xc9\x64\x0c\x76\x89\x9a\x17\x32\x2e\x16\x14\x5b\x0b\xd0\
+\xa2\xee\xd7\xbc\x90\x76\x24\x24\x89\x1b\x89\xa1\x20\xfd\xf6\x1e\
+\x50\xc6\x26\x47\xbf\xd0\x87\xe1\x90\xf6\x50\x04\x50\xcc\xa2\x09\
+\x23\xd1\x7f\x78\xc4\x3e\xe5\x7c\x93\xb5\x9b\x05\xa2\x46\x8e\xca\
+\x46\x86\xef\x2f\x2c\xd1\x8b\x2a\x74\xfc\x08\x78\x7f\x06\x54\x32\
+\x32\x96\x0e\x47\x5b\x55\x13\xbb\x97\xd4\x89\xfa\x89\x58\x26\x02\
+\x33\xa2\xa6\x55\x66\x65\xab\x05\x5a\xa7\x36\xa1\x53\xa5\xef\x1f\
+\xe2\x17\x0d\xf5\xb9\x7a\x16\x5a\x9a\x19\x25\xcb\xce\x1b\x1b\x76\
+\x2d\x60\x32\x15\xfc\x62\x7f\xc6\x68\xbd\x8e\x85\x75\x69\x31\x6f\
+\xdf\xeb\xd8\x3c\x0d\x60\xb9\xbd\x4e\x26\xa4\xd9\x57\x02\x7b\x58\
+\x71\x3f\x52\xfa\xa4\x33\xe2\x7c\x3c\x55\x3c\xaa\x1b\xcf\x27\x4e\
+\x84\x73\x1a\xc1\x4b\x50\x2a\xd6\xb9\x5d\x0b\xf9\xa3\x85\xe9\x24\
+\x57\xd5\x7d\xde\x11\x81\xb3\x13\x27\x62\x0b\x18\x74\x02\xe8\x3c\
+\xe3\xcf\xc7\x11\x6b\xb9\x7d\x8a\xf5\xb8\x5f\x45\x5b\x03\xb0\x60\
+\xde\x08\xbc\x36\x66\xd1\x14\xec\x8a\x18\xc2\x68\x93\xc3\xf6\x5c\
+\xc6\x76\x21\x96\x1d\x05\xc5\xd6\x60\x83\xd7\x26\x1c\x84\x8c\xed\
+\x82\x00\xf0\x60\x48\xc3\x40\x19\x89\xe0\xe0\xd1\xa2\xdf\x3e\xe6\
+\x6a\x60\x88\xbf\xa5\x0d\x77\xb4\x3c\x0f\xbf\xdf\xa7\x73\xb9\x4f\
+\xfb\x60\x97\x5e\xfb\x12\x77\x30\xe4\xe0\xa2\x45\xd6\xe8\xd3\xbe\
+\x10\x6e\x99\x46\xbe\x4a\xb6\xef\x27\x12\x80\xfc\x5e\x48\xa6\x51\
+\x4b\xe8\xbd\xb4\x81\x93\x28\x1f\xf3\x1d\xe1\x89\x88\x4b\x87\xa4\
+\x16\x96\xed\x00\x3a\x7e\x8f\x80\x5a\xc2\x80\x92\x4c\x28\x8b\x35\
+\x96\x90\x1f\x66\x00\x00\x19\x9b\x49\x44\x41\x54\xe7\xb9\x08\xe7\
+\x25\xc4\x3c\x4f\xeb\x5e\x67\x20\x3d\xef\x52\x7d\x1d\xeb\x5d\x07\
+\xfc\x8f\x62\xe0\xb4\x21\xa7\x3f\x27\xb7\x12\xd8\xba\xee\x7d\xde\
+\xad\xea\x3b\x33\xae\x38\x55\x84\xea\x14\x55\x4f\x89\xce\xd0\x81\
+\x81\x60\x1a\x99\xcd\xe6\x3a\x13\x5c\x6b\x3d\x31\x7b\x6f\xd2\x1b\
+\xb2\xbb\x1f\xcc\x0c\x14\x1a\x74\x82\x69\x8d\x1d\xde\x90\x30\xb2\
+\x63\xe0\xc6\xa0\x8c\x41\xe6\x61\x12\x46\x36\x0c\x86\x94\x8a\x0d\
+\xdc\x81\xec\x86\x28\xb6\x42\x82\x88\xd7\x4a\x5e\x1b\x77\x20\x58\
+\x19\x40\x2e\x10\x77\x50\xc4\x2c\x9a\x84\x83\x90\x6c\xd1\x66\x3c\
+\x20\x66\xf9\x82\x08\x67\x07\x11\x54\x6c\xcc\x81\x18\x76\x03\x65\
+\x6c\xcf\x8d\x47\x90\x4d\x6f\xfb\x95\x09\x81\x66\xad\xeb\xae\x23\
+\xe9\xd9\x98\x77\xc2\x66\x0c\xbf\x38\x72\xd4\xac\xd9\x0c\x97\x5b\
+\xb4\x4e\x81\xd3\xe9\xd8\x58\x59\xf9\xa0\x97\xb9\x8b\xf1\x60\x36\
+\xa8\xd6\xae\x3c\xb7\x4e\xf0\x3a\x69\x90\x0e\x76\xcc\x2b\xa3\x9a\
+\xc7\xa6\x32\xd7\xa1\xea\x3b\x60\x25\x93\x73\x9e\xc7\xb8\xd7\x45\
+\xe6\xa4\x67\xc2\xae\x64\x66\xa4\x83\x64\xdf\x8f\x5a\x44\xd7\xdd\
+\xf4\x48\x68\x42\x1b\xc7\x00\x6f\x75\xb3\x6c\x1f\xef\xb2\x79\x79\
+\x9f\x71\xe3\x52\xb5\x42\x00\xa8\x2f\xbe\x42\xc9\x3f\xc2\x25\x1e\
+\x96\x33\xc8\x89\xb9\x1e\xbb\x01\xd9\xd6\x9b\xec\xda\xa2\x11\xe1\
+\x51\x3c\x13\xda\x35\xc7\x98\x25\xc3\xc3\xb3\x93\x07\x52\x32\xa4\
+\x1b\xd9\x53\x76\x8e\x3d\x18\xf2\x35\x09\x54\x8f\x0c\x0d\x03\xdc\
+\xc1\x50\x0d\x6c\x74\x07\x43\x4a\x86\x17\x33\xb2\x91\x60\x64\xc9\
+\xee\xf2\x7e\xc3\x40\xcc\xc9\x1b\x08\x17\x56\x38\x28\xe2\xf7\xfb\
+\x49\x00\x7b\x31\xe8\x1e\x1d\x26\x00\x3c\x4f\x1b\xea\x27\x49\xfa\
+\x88\xf5\xe7\x97\xeb\xa2\x7f\xb0\x64\xe1\xc1\xa9\xad\x98\xb8\x1d\
+\x1a\x89\x80\x86\x3e\x3a\x37\xca\x54\x54\x85\x8a\x2c\xed\x7f\x5e\
+\x33\xc2\xeb\x4e\xb6\xfe\x9e\x66\x2f\x98\x49\x50\xba\xee\xf3\xf4\
+\xae\x45\x32\x8f\x61\xde\x71\x78\x1e\x80\x13\xf1\x80\x4c\x86\xe2\
+\xc0\x9c\x6b\xd4\x49\x00\xe7\x1b\xe5\x6b\x3d\x10\xcf\x5b\xb4\x55\
+\xdf\x99\xd9\x47\x36\x9f\x39\xc7\x80\x0a\xdc\xc8\xdc\xe2\xa2\xfb\
+\x84\xbd\xfd\x0e\xbd\x6e\x3c\x7f\x7a\xe5\x65\x2e\x46\x0f\xd5\xb0\
+\xc6\x86\x99\x5c\x48\xa6\x3d\xed\xa4\xe9\xec\x1e\x72\x7a\xf2\x50\
+\x04\x3b\xdc\xc8\xc6\xf6\xc4\x0f\x95\xdb\x34\x03\xba\x03\x43\x4d\
+\x13\x75\x23\x7b\xca\xbe\x31\xa0\xc7\x78\x94\x8a\x51\xac\x83\x05\
+\xa3\x7b\x76\x09\x3c\xf1\xe5\xc6\x76\x21\x01\x7c\x01\x74\x61\x40\
+\xb6\x23\x68\x18\xc9\xc5\x63\x66\x4a\x94\x46\xf1\xb0\x14\x3f\xcb\
+\x85\x35\x4d\xb6\xb9\x6a\xf7\xa7\x8d\xb2\xb5\x88\x5e\xfa\xe0\xea\
+\x4e\xfa\x99\x83\x5f\x11\xff\x5b\xa1\x47\x71\x75\xda\x1b\xc2\xec\
+\x75\x12\x1d\x20\x65\xc8\x54\xef\x9c\x23\x9d\xf7\x69\x00\xeb\x3e\
+\xdc\xeb\xf2\x79\xd3\xcf\x5d\x35\xea\xcf\xcd\x6b\xd0\xfd\xbb\xe9\
+\x08\x9d\x04\xf3\x3c\x59\x91\xce\xd8\xfb\x28\xe0\x49\x00\x4b\xf0\
+\x0e\x8a\x21\x51\xc5\x60\xd4\x76\xe6\x12\xc4\xbc\x85\xa1\x7f\x87\
+\x73\x66\xbd\x1a\x7a\xc2\x14\x7d\x31\xf9\xaa\xda\x5f\xa4\x13\x05\
+\xf8\x57\x1d\x98\x1c\xe2\xf0\x88\xa5\xfc\x4b\x94\xfc\xa3\x78\xe4\
+\x6e\x35\x96\x7b\x43\xd5\xe3\x2f\x6b\xdf\x10\xf2\xe3\xc5\x35\xf2\
+\xcd\x57\x66\x99\x58\x6e\x15\xdb\x1a\x1e\x66\xd1\x14\xa0\x8b\xc1\
+\x39\x05\x60\x41\x81\xdd\x8d\x6c\xc1\xb0\xb1\x96\x0e\x07\x21\x36\
+\x39\xf5\x1e\x25\x41\xe4\x56\xbe\x2f\x66\xe5\x31\xde\xdc\xc5\x03\
+\xe0\xe6\x73\x54\x02\x97\xd1\xbe\x33\x17\x30\xb2\x7a\xe3\x3a\x37\
+\x93\xbc\x2d\x13\xcd\xb4\xa2\x6a\x9a\xb6\xf2\x44\xb4\x3a\x71\xc5\
+\x45\x2f\xbc\x36\x39\x7e\x12\x57\x15\xfb\x45\xef\xb9\x1d\x23\x75\
+\xc0\xe9\x06\x67\xda\xaf\x7d\x9d\x7b\x6d\x1e\xe8\x54\x37\xcf\x54\
+\x07\xcf\xe7\xb1\xb8\xd1\x8f\x54\x15\x87\x7e\x2c\xe6\x49\x85\x74\
+\xb8\x59\x6a\xe1\x51\xdb\xf9\x6b\xc9\xa5\xe7\x2d\x98\x8e\x21\xf2\
+\x33\x64\x14\xee\xbc\xd1\x20\xec\xb6\xe9\x76\x32\xaa\xcc\x2d\x51\
+\xd9\x11\xdf\x5a\x61\x41\xb1\xf0\x02\xc7\x0a\xc8\xf2\x78\x98\xe2\
+\x12\x2e\xf4\x6f\x9a\x89\xa5\x9c\xf0\xec\x52\x82\x89\xcd\xa2\xa9\
+\x58\x56\x86\xa5\x25\xa8\xed\xd4\x84\x4a\x7b\xce\xc4\x4a\x7d\x91\
+\xc8\xbf\xa3\xd8\x38\x66\x60\x37\x9f\x53\xf7\x3d\xc6\xec\xd6\x44\
+\xe6\xff\x42\xa3\x32\xc3\x70\x69\x97\xd9\xbc\xa0\x87\x3c\x99\xb5\
+\x7a\x4d\x3b\x38\x9e\x92\x11\x19\xba\x09\x43\x4e\xea\xe1\x79\x7d\
+\x81\xf5\x46\x83\xf3\x2a\x52\x94\xd7\x42\x0b\x80\xa4\x81\x36\xa9\
+\x58\xcf\xf5\x0f\xa7\x75\x6c\xba\xb4\xe8\xa3\x64\x83\xcc\x87\x98\
+\xb7\x28\x74\x57\x5a\x7a\x2b\xaf\x5e\x12\xcc\xd7\xf9\x8a\xd3\xdf\
+\xf3\xa3\x8c\xd2\xb9\x8d\xcf\x8f\x1e\xd3\x8b\xe2\xcc\x36\xd9\xf9\
+\xc0\xdf\xa1\x53\x4e\x8e\x2e\x6b\x9a\xc3\x04\x0b\x37\xf2\x3e\xed\
+\x91\xc5\x02\xc7\x04\xf5\x86\x90\x13\x20\xc6\x79\xa5\xb5\x31\xa0\
+\x98\x55\xc8\x88\x82\x02\xae\x7c\x2c\xa5\x86\x64\x59\xe1\x53\x2e\
+\xcc\xb0\xaf\xee\x89\x50\xab\x2d\xd6\xd0\xd2\x08\xd4\x6f\xe9\xf6\
+\x5a\xd6\xd9\x1b\x62\xbf\x51\x4f\x85\x6e\xf5\x26\x29\xcf\x0b\xdf\
+\xce\x63\xe1\x04\x43\x74\xba\x2a\xa7\x61\xe8\xbb\xc9\x71\xb7\x1a\
+\xf3\xcb\x06\x7e\xb2\x86\xec\xa3\x52\x2e\xe7\x45\x14\x25\xb8\xf5\
+\xa6\xdd\xd7\xe5\xe3\xea\xb5\x85\xf3\xa2\x92\x69\x00\xeb\x3a\xf9\
+\xa3\x02\x13\x12\x9c\x69\x20\xeb\x00\x46\x15\x0b\x7c\xf4\xe7\xc9\
+\x4c\xb8\xf4\x3e\x7e\xd1\x53\x19\x6d\xd9\xbe\xaf\x16\xa1\x7b\x76\
+\xc4\xf1\xd0\xc2\xe3\x0a\xa7\x7d\x39\x53\xa6\x24\x01\x6c\x96\x7b\
+\x6a\x98\xfd\x02\xc7\x84\xf9\x65\xda\x23\x8b\x46\xde\x27\xcc\x2f\
+\x4f\x3b\xc5\x9b\x45\x13\x33\x33\xdf\xb8\xd3\x5d\x61\x52\x07\xeb\
+\xc0\x35\x8b\xa6\x02\xa3\xbc\xaf\x22\x7e\x29\xb6\xd5\xc1\x3b\x0f\
+\xc8\x92\x81\xa5\x2e\x96\xf7\xfd\x8c\x88\xce\x5c\x8c\x1e\x62\x67\
+\x32\x89\xde\x63\x7a\xd2\xcb\x75\x01\x83\x56\x35\x33\xc3\xc2\xea\
+\xb5\xce\x34\x2f\x43\x26\xec\xa4\xdb\x94\xca\x7e\x65\x52\x0f\xeb\
+\x35\x72\xe9\x44\xfe\x79\x57\x89\x79\x85\xab\xf3\xea\x04\xe7\xb1\
+\x9d\x9e\x4e\xfa\xbc\x80\x48\xc1\x2a\x71\x8e\xf1\x91\x9e\x83\x79\
+\x6e\xb4\xa8\x62\x60\x86\x3d\x06\xc5\x10\x33\xec\x29\x7b\xc2\x0b\
+\x02\x42\xb3\xfa\x91\x52\xc2\xe8\x47\x8a\xf9\xd3\x0b\x2c\x3d\xcd\
+\x55\xbf\xdd\x28\xf8\x6a\xac\x86\xaa\x7a\xf6\x77\xd4\xd4\x2d\x39\
+\x57\x0f\x44\xa5\x4b\x98\x5f\xa6\x5c\xec\x61\xac\x64\x69\x8f\x2c\
+\x95\xf2\x99\x70\xa0\x4a\x0f\x82\xd4\xc0\xf3\x40\xa7\xd8\x3a\x36\
+\xd6\xa4\x04\xf1\xec\xd2\xf4\xfd\xb1\xe1\x97\xd8\xff\x1a\x49\x91\
+\xfe\x7c\x9d\x81\xe5\x7d\xb3\x7f\xc5\xd5\x9e\xa5\x0e\x9c\xbc\xbc\
+\xcf\x6b\xa4\x9d\xbe\xcc\x59\x55\x53\xa5\x3f\xa6\x6f\x7d\xa7\x80\
+\xeb\x4c\x12\x46\x87\x04\x64\xba\x87\x82\x64\x4e\xe9\xad\x78\x9e\
+\xd7\x21\xed\x5f\x4e\x97\x52\xcd\x73\x8b\xa5\xa3\x6f\x33\x69\x94\
+\xa9\x36\x5e\x69\x40\xcb\x1c\xe7\xef\xc5\x90\x9b\xc7\xc8\xa1\x59\
+\xc5\xce\x64\x12\xa0\x95\x60\xfe\x28\x36\x5e\xaa\x3c\x5f\x13\xcf\
+\x1b\x95\x06\x60\xad\xbf\xc0\xa7\x6f\xaf\x50\xb9\x5b\xa7\x76\xe5\
+\x2b\x26\x96\x03\x1e\xd5\x64\xa7\xbe\x90\xae\xe5\x4f\x94\x60\x6b\
+\x8d\xdb\x77\xee\xf3\xd9\xcd\x12\xa5\xc5\xca\xb4\x53\xfc\x34\x20\
+\xc1\xb5\x06\x56\x1a\xe8\xd2\x28\x93\xfb\xea\x9f\xa1\xbb\xd1\xd2\
+\x9f\xad\x33\xf3\x3c\x89\x61\x66\x4a\x53\xf0\x66\x4a\x94\x8a\x05\
+\x5a\x65\xe3\xda\xa4\x98\x8f\xd2\x63\x12\xc0\xf3\x58\x78\xe2\x0f\
+\x67\xda\x01\xe8\x80\xd4\x2b\x7c\xd3\x63\x76\xe7\x31\x70\x5a\x23\
+\x26\x7a\x65\x68\xef\xb9\xce\x00\x4d\x4b\x88\x99\x56\x05\xda\x02\
+\x48\xef\x2f\x13\x6c\xce\x31\x54\xc5\xf2\xf3\x58\x78\x50\x0c\x31\
+\xfa\x11\x46\x3f\xc2\x0b\x82\x84\x14\xf8\xeb\x24\xfe\x48\x9d\x2e\
+\x17\xe2\x75\x6e\x3d\x69\x5f\xe8\xb2\xce\x3f\x7a\x8c\x1b\x8c\x58\
+\x08\x97\xa8\xde\x14\xd3\xa6\x26\xc3\xf7\x13\xb3\x0f\x27\xfe\x90\
+\xee\x55\x9b\x17\x4b\x0d\xbe\xb8\xf5\x80\x2f\x6e\x3d\x60\x73\xbd\
+\x4c\xf9\xd3\x2f\xf1\x23\x0f\x3e\x2f\x70\x62\x16\xcd\x84\xfe\xd5\
+\x19\x30\x6d\x80\x5d\xf7\xdc\x75\x9a\xf7\x3a\xf0\xce\x63\xfb\x34\
+\x90\x81\xff\xaf\xb3\xab\xeb\x71\x1c\x4b\xcb\x8f\x3f\x52\x89\xed\
+\x38\x76\x52\x55\xdd\xd5\xbd\xdd\x3d\x3d\xd5\x3b\x2b\xcd\xdc\xec\
+\x0a\x84\x84\xd0\x08\x81\x10\xdc\x00\x17\x08\xc1\x25\xab\x15\x3f\
+\x8a\x0b\x7e\x01\x3f\x61\xaf\xd1\x0a\xd0\x22\x56\xa3\xd5\xd0\x30\
+\x3d\xd3\xd3\x1f\xc5\x54\x77\x57\x25\x71\xe2\xd8\x49\x2a\x8e\xcd\
+\x85\xfd\x9e\xbc\xe7\xe4\x1c\x27\xbd\x96\x4a\x49\x1c\x97\x93\xd8\
+\x8f\x1f\x3f\xef\x37\xc6\xab\xa6\x4d\xd6\xed\x16\x0b\x3c\x97\xc0\
+\xcb\x0d\x23\xe9\xea\x66\xd1\x39\x77\x60\xd7\x43\x06\x07\xfb\x5d\
+\x3f\x67\x49\xdd\x15\x5d\xe7\x9e\x6a\x9b\xa8\xa4\xba\xd7\xa2\x96\
+\xdb\xad\x64\x74\x2a\xd5\x29\x3a\x26\xd5\xbd\x56\x93\xfb\xdb\x3e\
+\xe7\xee\xee\x1a\xf7\x50\xe1\x26\x05\x4e\xed\x61\xab\x3b\xcd\xcf\
+\x6d\xe1\x4a\xf3\x73\x5b\xf2\x11\xab\xc1\x0e\x93\xa4\x20\x1d\x4c\
+\x1e\x0c\xd3\x9d\x45\x92\x6f\xa5\x05\x34\x4d\x51\xfa\x17\x16\xa6\
+\xd3\x04\x63\xfb\x46\xe4\xc8\x74\x7a\x5f\x88\x9c\xe2\x00\x27\x82\
+\x8d\xdf\x9c\x2c\xf1\x38\xa8\x30\x18\x0d\xf0\x69\xff\x1c\xbf\xef\
+\x04\x88\x7e\x14\x34\x77\x0a\xca\x5f\x60\xac\x49\x20\xca\x2a\x0f\
+\xe5\x36\xd3\x4a\x0b\x0e\x46\x13\x7b\x9b\x24\x03\xdf\x77\xdb\x32\
+\xec\x2c\xd1\xeb\x55\xb0\xe3\x33\xbc\x7e\xd1\x95\xd8\xb0\x93\x16\
+\x72\xbe\xac\x26\x49\x9e\x32\xd4\x86\x1a\x39\xc1\x07\x0f\x9a\xdc\
+\x59\x6d\xc1\x0c\x5d\x7f\x85\xb6\x5c\x02\xae\x89\x75\x40\x36\x25\
+\xd3\xa8\x91\xb9\x36\x6f\x46\x69\x0f\x30\x77\xfb\xe8\x0e\xfb\x18\
+\x97\xd3\x83\x49\x3e\x7e\x6e\x4b\x46\x9c\xc9\xf5\x66\xb3\x8b\x9d\
+\x3f\xae\xa7\x0b\x8c\xa2\x91\xf0\x82\x1c\x23\x61\x22\x7b\x20\x6c\
+\x94\xc5\xbb\x0a\xb1\x95\xe0\xb4\x3c\xc7\xe3\x5e\x9d\x30\x9f\xdc\
+\x7e\xa5\x77\x71\xbe\xbf\xc2\xcd\xec\x5b\x54\x2b\x0b\x3d\x58\xc8\
+\xbd\xa0\x69\xba\x0d\xbd\x9c\x90\x4e\x68\x18\x1e\x05\x4e\x1d\x5b\
+\xb7\xc9\x12\x21\x17\x0c\x0c\x4e\xeb\x57\x2b\x0b\xdd\x55\x61\x4c\
+\x7b\x54\xcb\x8e\xf8\x42\x29\x96\x3a\x16\xe6\xe5\xe6\x87\xa2\x5b\
+\x5c\x4e\xb4\x01\xfc\x90\x05\xaf\xf6\x66\x30\xb5\xa0\x6d\x03\x83\
+\x29\xe0\xc0\xc1\x7c\x48\x4a\x70\x20\x7b\x8e\x23\x5e\xe7\x7e\xa9\
+\xdd\x9e\x17\x00\xf0\x7d\xd3\xc5\x62\xa5\x15\x4e\xed\xa1\xd6\x87\
+\x2d\xce\x67\x79\x02\xcc\x6b\x77\xe5\x68\xbe\xbb\x70\xd6\xf1\x05\
+\x56\x41\x0a\x6c\xde\x8a\xb0\xb3\xd4\xb8\x1b\x27\x98\x0c\x9c\x5d\
+\xd2\x10\x80\xfe\xd2\x97\x71\x74\xe8\x44\x50\x1f\x0a\x2e\x33\x38\
+\x38\xdb\xbc\x0f\x6d\x12\x43\x27\x2f\x74\xeb\x9d\x6e\xff\xa3\x4f\
+\x28\x19\x73\xe5\x20\xde\xab\xd1\x22\x6b\x57\xa7\xa5\xdb\xc0\xc3\
+\x5d\x62\xba\xd0\xb2\x09\x54\x26\x69\xa0\x93\x1c\x3a\x3d\x7d\x28\
+\xc0\x70\xcc\x05\xa8\x33\xe4\x48\x13\xab\x12\x43\xf5\x19\x5b\x41\
+\x6a\xbc\xc0\x28\xa2\x57\x85\x16\xc6\xe5\x54\x44\xea\xb4\x9a\xb8\
+\xe9\x9a\x19\x57\x16\x6e\xcb\x54\x14\x1e\x58\x8b\x0a\xae\x7d\x01\
+\x74\x1e\x0b\x26\x56\x67\x4a\x47\xf6\x00\xef\x93\x29\x7e\x58\xd5\
+\x44\xb2\xf0\x72\xf4\x4f\x4e\x76\xe3\x0e\x4c\x7e\x59\x93\xa1\xc5\
+\xb7\xe5\x52\xc3\xe4\x07\x36\x01\xd8\x24\x47\xf8\x7a\xfa\xbc\xe5\
+\x2a\x41\x55\x7d\x85\xc5\xed\x44\x5b\x11\xa1\xde\xea\x46\x76\x85\
+\x2d\x22\x0c\xed\x4a\xf4\x09\x16\xbf\xb3\x78\x2f\x9a\x9e\x1c\xcb\
+\xa0\x1c\xb8\xbc\x01\xe2\x31\xc1\x0a\x9d\x34\x30\x19\x83\xba\x10\
+\xef\xa1\x7c\x08\xca\x55\x38\xd6\xad\x46\x86\x1c\x01\x3a\x4b\x4b\
+\x01\xdc\x05\xaa\x3d\x4d\xac\x2b\xc3\x22\x29\x41\x5d\x82\xb8\x0c\
+\xe1\x79\x13\xf4\x3b\x85\x6b\x6d\x6e\x69\x35\x76\x95\xbe\x16\x9a\
+\x38\x3e\xfb\xe9\x3e\x81\xb8\x3d\xcc\x5e\x4d\x61\xe3\x05\xfc\xa5\
+\x5d\x8f\x3e\xb0\x73\xb1\x4f\x5b\x07\x56\x93\xa1\xa5\xbe\xe6\x72\
+\xc0\xe4\x6d\x38\xa4\x8f\x4d\x40\x27\xcd\xbc\x5d\xdf\xe0\x7f\x92\
+\x7b\x62\x06\xb0\xc9\x88\x53\xd7\x39\x4d\x37\x64\x92\x13\xb3\x64\
+\x86\x69\x69\xed\x0d\xe1\x3e\x74\xfb\xe7\xc0\x55\xf5\xb0\x4e\x27\
+\x9a\x7c\xb9\x52\x89\x94\xc6\x43\xa1\x0b\x39\x1f\xca\x0f\xa6\x85\
+\x3c\x12\x26\x39\xa2\xa6\x54\xf2\x10\x73\x1f\x96\xa4\x8b\x89\xa1\
+\x4d\x99\x6c\x5c\x4a\x10\x80\xb9\x51\xc8\x7d\xd5\x54\xc9\x2d\xec\
+\x86\x66\x56\x34\xff\xae\xf5\x50\x19\x08\x4d\x4c\x8d\x05\x33\xdc\
+\x21\x73\x1f\x89\x74\xcc\xe8\x74\x88\x45\x72\x89\x13\x7f\x52\xf7\
+\x27\x5e\xb9\x40\xaf\xd8\x97\x13\x2a\x58\x0f\x81\x51\x35\xd0\xd2\
+\xc2\xac\xad\x0f\x19\x7e\xba\x0b\x20\x74\x6d\x2c\xe1\x88\x68\xdd\
+\xa1\x88\x11\xdd\x7a\xa2\x38\x92\xc0\x4b\x60\xb6\xe7\x89\xdc\xb1\
+\x11\xfa\xea\x08\xde\x9c\xf0\x90\xc1\x67\xca\xf1\x35\x05\x2e\x78\
+\xd4\x4e\xa7\xc7\x8f\xc9\x44\xe3\xeb\x88\xf9\x78\xd2\x8d\x29\x3a\
+\xc7\x75\x30\xf9\x81\xe9\xf5\x02\x15\x82\xd0\x86\x9f\xdb\x22\x7b\
+\x4d\x05\x3d\x81\x76\x3d\x5d\xec\x35\x5b\xa1\xe7\x04\x50\x5e\x38\
+\x1b\xf4\x3b\x52\xab\xd7\xb9\xdb\x17\x9d\x7d\xd2\x7c\x86\xc5\xdd\
+\x9d\xd0\xc4\x70\x2f\x77\x43\xd5\x8b\x97\x08\x58\xda\x42\x55\xbe\
+\x44\x52\xc5\x20\x8d\xd8\x2f\xfd\xda\x4f\xcc\xa5\x81\xca\xc4\x3a\
+\x66\xe6\xa0\xa5\xff\x21\x16\xe7\x6c\xae\xfb\x5f\x75\x5d\x1b\x23\
+\x93\xe4\x28\x9c\x21\xc6\xaf\x5c\xdc\xac\xbf\x16\x09\xf1\x04\x34\
+\x35\xb9\x66\xd0\xcf\x05\x03\x73\xf0\x4e\x4b\x0b\xd3\xd2\x92\x58\
+\xd0\x94\xa3\xa0\x1a\x89\x26\xd9\xa1\x36\x25\x31\xe5\x2f\xe8\xa4\
+\x0f\xaf\x34\x69\xd3\xf9\xc7\x48\x14\x62\xbe\x7b\xa8\x8e\xce\x54\
+\xb3\xd2\x4a\xd4\x2e\x02\x40\xd6\x0c\x55\xcc\xd2\x12\xb9\x5f\x4a\
+\x12\x41\x65\xe3\x2a\xb4\xf6\x52\x34\xf9\x42\x17\x13\x97\x4d\x62\
+\x74\xef\xa0\x42\x1c\x87\x75\xdf\x3a\x40\x8c\x32\xd8\xe6\x1e\xe6\
+\x1f\x80\x37\xf3\x7a\xbf\x34\x8f\x5a\x32\xc6\xc7\x53\x56\xba\x5f\
+\xdf\x95\xcb\x6a\xb1\x1f\xb1\xe3\x4c\x5c\x6e\x33\xac\x9c\x07\xe2\
+\x39\x25\xe3\x98\x34\xb3\xee\x71\x2f\xf2\xe6\x1c\x17\x45\x22\x56\
+\x0f\xfc\x1e\xec\x74\xbc\xe7\x21\x20\xa0\xf1\x6e\x36\xc4\x00\x94\
+\x27\xcc\xbd\x12\xd5\xbc\x12\x65\xf7\xc7\x30\x27\x67\x60\xb5\x5a\
+\x58\xcd\xef\xd5\xb9\xcb\xa6\xeb\xb9\x36\x02\xa7\x7e\xd6\xa1\xd4\
+\x46\x1d\x90\x4d\xf2\xa3\x2d\xe4\xcc\x75\x2f\x31\x67\x1f\xb5\x1e\
+\x26\x90\xda\x7e\x65\xcc\xad\x38\x74\x17\x54\x2f\x16\x0a\xb6\xf0\
+\x1e\xcf\xd4\x5d\x7e\x53\xac\x44\xff\x89\x34\x7a\x03\x0f\xa7\x70\
+\x46\x29\x06\xf7\xea\xde\x13\x9b\x0f\xcf\x45\x90\x83\xe7\x50\x44\
+\xa7\x43\x3c\xb9\xf3\x90\xe6\x33\xf8\x4d\x94\x38\xdf\xd4\x43\x1f\
+\x6d\x1d\x5b\x12\x08\x7b\xdb\xeb\xbd\x9c\x86\x43\x40\x56\xf5\xb5\
+\x0a\xe8\x63\x16\xce\xd8\x39\x06\x58\xe0\xf9\x5e\xa4\x8e\x17\x86\
+\xf6\xdc\x40\x54\x6b\x88\x26\xe2\xe9\x8e\x8d\x3f\xc6\x0d\x26\xf9\
+\x9a\x59\x36\x9a\xc8\xd3\x50\xf4\x2c\x15\xa0\xf2\xfc\x8d\x61\x77\
+\xd0\x9a\xa8\xa3\x03\xe4\xb1\x9e\x97\x63\xa2\x94\x7b\xb2\x2d\xb4\
+\xb5\xd9\x6a\x41\x68\x0b\x19\xc1\x81\x6c\x62\x61\xdd\xf7\xe5\x7a\
+\x1a\x00\x46\xd1\x68\x3f\x9f\x98\x9a\x72\x37\x15\x1c\xd4\x7f\x22\
+\x9c\x3d\xc1\x12\xe3\x5a\xdf\x36\xde\x89\xce\xbd\xcf\xb5\x61\xfd\
+\xd9\x76\x86\xbb\x7b\x75\x7b\x57\xca\x7c\x13\x86\x9d\x0a\x3c\xdb\
+\x09\x5a\x59\x15\xa8\x13\xd5\xf9\x63\x9b\xf1\xf7\x31\x80\xe5\xa0\
+\xa7\x7d\x2f\x57\x09\x5e\xbf\xe8\x4a\x4c\xcc\x7b\xad\xf1\xdb\x96\
+\xea\x13\x8e\xe2\x08\xe9\xa2\xb7\x37\xb3\x58\x3d\x31\x6a\x6e\x00\
+\x35\x64\x59\x15\x19\x2a\x27\x6c\xad\x6d\xa3\xfe\x13\x62\xe2\x53\
+\xc3\xc4\xea\xc9\xd5\xb5\x5a\x35\x19\x74\x2a\x60\x8e\xc9\x37\x6e\
+\xf3\x31\x9b\xd2\x2e\xad\xb4\x12\x00\x0f\xac\x4c\xfc\x71\xe3\x8e\
+\xf6\x69\x0a\x65\xf3\xf0\xb4\x95\x56\x7b\x41\x96\x41\xb1\xa8\xbb\
+\xcd\xb3\xa0\x50\x69\x0f\x44\x62\x7c\xe8\x47\xf0\x86\xf5\x7b\xd6\
+\xfd\x8e\xf0\x29\xd3\xa8\x31\x00\xb0\xab\x39\x22\x27\xc2\x03\xab\
+\x80\x87\xd3\xba\x91\x20\x73\xdd\xd9\x6d\x40\xe2\x8f\x92\x5b\xad\
+\x61\xe5\x36\x76\x3e\x96\x85\x4d\xe0\x4f\xdd\xfa\x87\x79\xbd\x58\
+\x62\x61\x5d\x57\x47\xea\xde\x23\x5f\x69\x35\x1b\x17\xfe\x5a\x78\
+\x24\x4c\xc5\x97\xaa\xcb\x27\x9d\xee\x32\xd5\xac\x6d\x6a\x94\x01\
+\xc4\xda\xab\x22\x83\x33\x8c\x04\x83\xf7\xcf\x46\xe2\xe4\xea\x12\
+\x7e\xd4\x0b\xc1\xf4\x5c\x17\xbc\x38\x54\x1c\xba\xd7\xe1\xbd\x69\
+\x98\xcd\x41\x29\xb4\x71\x90\x0a\xb6\xcd\xaa\x00\x0b\x00\x55\x16\
+\x0a\x83\x8f\xef\x53\xf5\x80\x50\x24\xaf\xcd\xfb\xc1\xf3\xb8\xd5\
+\x0c\xb6\x51\x54\x03\x31\xb6\x12\x5c\xc4\x0f\x1b\x89\x53\x4f\x26\
+\xe8\x8c\xba\x3b\xe3\xae\xd1\xc3\x3f\xfb\x7c\x84\xde\x27\xcf\xe4\
+\xa8\x6b\xd3\xe3\xc3\x2e\xb7\x19\xa6\x9b\xa6\xc6\x6c\xe3\xed\x19\
+\x66\x5c\xcf\x92\x4e\x56\x0d\x3b\xf5\xaf\x8d\x6d\xdb\x0c\x3f\x75\
+\x7d\xea\x04\x48\xfe\xf7\x4a\xb0\x9b\xe9\x24\xaa\x00\x9e\x25\x33\
+\x31\x8a\xcb\x9e\x27\xda\x72\xa2\xb6\x25\x1c\x76\x44\xe1\x69\xe5\
+\x84\x98\xae\xe7\xa8\x9c\x50\xea\xe9\xa6\xea\x67\x5e\xa8\xba\xb8\
+\x9d\xec\x49\x13\xf5\xf6\x7f\x6c\x95\xb3\xca\xde\x26\xa3\xd4\xc4\
+\xcc\x54\x9d\x41\xc0\xa5\x3b\xc4\x02\x75\x24\x6e\x01\x26\x2f\xb2\
+\x50\x44\xed\x74\xee\x35\x1e\xcc\xa0\x48\x9e\x49\x37\xab\x44\x43\
+\x4c\xdc\x71\x7b\xe8\xb9\x01\xbe\x7f\xf9\xc3\xee\x77\x01\xf8\x9c\
+\x0d\x02\x4d\x92\x54\xcc\x09\x21\x36\x0e\xee\x3f\x42\xf7\xec\x44\
+\x74\x01\x02\x00\xa7\xc9\x36\xb4\x6d\x27\xc0\x13\xab\x40\xb9\xcd\
+\x30\xec\xd4\x01\x06\x02\x35\x67\x47\x4a\xc6\xf1\x31\x17\x60\xa7\
+\x6d\x49\x82\x70\x29\x62\x02\xb0\xca\xbc\x6d\xbe\xe9\x55\xba\xc1\
+\xdb\xd5\x35\xd2\xab\x97\xc2\x33\xc1\xbd\x02\x34\x89\x48\xa6\xd1\
+\x06\xd4\xe1\x2e\x47\x42\x57\xe7\xd6\x6a\x54\x4e\x37\x12\x38\x3d\
+\xc7\xc1\x76\x3a\x43\xff\x6c\x64\xd4\xcf\x1c\x58\xbc\xf7\x9b\x8e\
+\x41\x75\xfe\xed\x36\xcd\xae\x6e\xdf\x16\x1c\x31\x7d\x2e\x67\xe2\
+\xe5\x76\x0b\xdb\xaf\xa4\x47\x8a\xd6\x95\xb9\xa5\xf5\x13\x93\x57\
+\xc3\xc4\xba\x26\xf0\xaa\x9d\xe3\x37\x93\xb5\x08\xce\x90\xb7\xe1\
+\x7c\xd4\x81\xfb\xf0\x3e\x2e\x43\x16\x6e\xe6\x29\xaf\xb1\x8d\xcb\
+\xa7\x4f\x11\xfa\x35\x59\xd1\xd0\x19\xda\xa7\x5d\x6e\x33\xbc\xa9\
+\x5c\x09\x54\x34\x8c\xdc\xe4\x5d\xa0\xf7\xc7\xab\x12\xa7\x3d\x5b\
+\xcb\xae\xe3\x55\x89\xb0\xe8\x68\xe5\x84\x6e\x7b\x95\xf1\x29\x29\
+\xe9\xd5\x7f\xfc\x37\x92\xdb\xaf\x76\x1d\x21\x99\xf6\x34\xc9\x08\
+\x62\x62\x0a\x7a\xb4\xb1\x30\x6f\x61\x4a\x07\xdc\x73\x1c\x09\xc8\
+\xa2\x69\x34\x63\x5b\x1d\x38\x4d\xef\xa9\xcc\xad\x26\xc6\xb7\xe9\
+\x5a\x3e\x35\x95\xeb\xec\x63\x42\xcd\x94\xac\xce\x41\xe7\x39\x8e\
+\xa4\x63\xcb\x7c\xe7\x27\x26\xaf\x05\x07\x28\xff\xcc\xee\xb0\x2f\
+\x12\xe7\x4d\xe0\x35\x1d\x17\xd2\xaf\x99\x7d\x87\xb9\xdb\xc7\x74\
+\x36\x13\x49\x3d\x6f\x5f\xbe\x07\x92\x7a\x9f\xe1\xa3\xcb\xfa\x5c\
+\xcf\x2d\xc9\x1b\x95\x4d\x5e\x20\xcd\xeb\xe3\xef\xfa\x1e\xb6\x6c\
+\xfc\xaf\x7c\x89\x27\xbb\x94\x45\xce\xc6\xd3\x8d\x27\x01\x97\xc0\
+\x36\xec\x2c\xf7\xf4\xf3\x78\x55\x8a\xf7\x52\x77\x63\xf4\x1f\x9b\
+\xc0\x4d\xfb\x2f\x9c\x21\x7e\xfb\xd5\xaf\xa5\xf9\x14\x1c\xc8\xa6\
+\x89\xf2\xb3\xa4\x4e\xfa\x99\x34\xc7\x7e\x52\xb6\x57\x3b\x70\xc7\
+\x3f\xf5\x28\xa3\x5e\xc0\xe9\x74\x23\xf5\x2e\xd3\x55\x90\xe8\xc0\
+\xcb\x53\x13\xb9\xe1\xa8\x1a\x80\x87\x5c\x6f\x9c\xe9\x8b\x79\xa9\
+\xcd\xf1\x6d\xbb\x68\x54\x23\x8e\x83\x92\xfc\xc4\xc4\xc4\x7d\xec\
+\xb6\x25\xd7\x1b\xe5\x53\xa8\xbf\xab\xca\x42\x2d\x78\x75\xe7\xc4\
+\x24\x73\x86\x51\x84\x37\x3f\x2c\xf1\xcd\x2b\x07\xd3\x69\x82\x22\
+\x5f\x8a\xea\x8e\x7a\x0e\x78\x25\x6a\x1a\x89\xb5\xd7\xb7\x77\x28\
+\x72\x17\x45\xbe\x84\x43\x21\x6d\xf2\x13\x13\x40\xa7\xc1\x4e\x4c\
+\x8b\x75\x0a\x80\x9f\x58\xc5\x4e\x3b\x37\xa0\x27\xe0\x11\x8b\x1b\
+\x83\x26\x49\xbc\x97\x2b\xac\x3e\x17\x92\xe6\xe6\x46\x04\x39\xc8\
+\x33\xc1\xdb\x38\x71\x16\x1e\xd9\x9e\x08\x66\x94\x83\x18\xb3\x64\
+\x06\x07\xcd\x4c\xe5\x23\xb4\x30\xf7\x04\x78\x8e\x83\xc5\xed\x04\
+\x9e\xe3\x48\xae\x32\xea\xef\xa6\x7a\x1b\x54\xef\x01\xe5\x14\xd0\
+\xfe\xee\xee\xae\x85\x5f\xd4\x54\x2f\xf7\x31\x52\x47\xc7\xc2\x6a\
+\x6f\x0d\x2e\x21\xd4\xe8\x1b\x4f\xbf\x24\x16\xa6\x8b\x83\x00\x4c\
+\x2e\xb7\xe5\x76\x2b\x19\x81\x3c\xeb\x4d\x07\x50\xb5\x7b\x3c\xfd\
+\x51\x47\x20\x7e\xec\x6e\xcb\x14\x9d\x41\x0f\x0f\x7b\x05\xfc\x4e\
+\x17\xae\xef\x89\xea\x8e\x4d\xe8\x8a\x2a\x90\x4d\xe8\x8a\xfc\xe3\
+\x9a\x85\x8b\x66\x9e\xdd\x52\x61\xe2\x44\x49\x1a\x67\xaf\x87\x9d\
+\xa5\xc4\xca\xa9\xbb\xc1\x30\xeb\x4a\xa0\xa7\x6d\xc2\xa2\x23\x19\
+\x89\x7c\x5f\xd3\x8d\x07\xc4\x89\x00\x2c\xdf\xaf\x90\x2f\xcd\xb6\
+\x54\x9f\xf7\xf5\x8b\x97\xcd\x60\xee\x70\x2f\x5a\xc6\x17\x5e\xb5\
+\x6c\xcf\x13\x91\x04\xcf\x7b\x1a\xb7\x2d\x9c\x39\x97\xdb\x2d\x86\
+\xdd\x81\x30\xe2\x74\x8d\xab\xd5\xb4\x47\xee\xfe\xe2\x21\x5e\xd5\
+\xc3\xa0\xba\xca\x78\x9e\x6e\x9b\xdc\xd1\x31\x35\xff\x0e\x04\x42\
+\xd5\xe8\x35\x95\xdc\x7b\x8e\x03\xdb\xaf\xa4\x80\x07\xb9\xd5\x82\
+\xd0\x16\xc1\x11\x62\xe1\x2a\xb4\xe0\xa4\xb2\x8c\x30\x75\x16\xd2\
+\x1d\x6f\x6e\x10\xf2\xf7\x29\xf4\x3c\x9f\x6d\xb1\xcd\x3d\x89\x89\
+\xa9\x8e\x52\xf5\x19\xd7\x4c\xec\xa2\xf0\x7b\x58\xa1\xaa\x99\x98\
+\xc0\x35\xdd\x78\x78\x68\x25\xe0\xaf\x09\x58\xc3\xce\x52\x7a\x44\
+\x5c\x77\xc9\x89\xf3\x44\xda\x86\xdc\x62\x61\xd1\xc1\xb0\xb3\xac\
+\x7d\xbd\xcd\xb6\xc4\xb0\x62\x7d\x12\xe3\xb4\x67\xcb\xc0\x0f\xd6\
+\xe2\xf9\xfa\xf5\x02\xe9\xd5\x4b\x6c\x42\xb7\x9e\x13\xcd\x0e\x1e\
+\x6f\x88\x0d\xd4\x15\x0c\x43\xbb\xc2\x30\x6b\xa2\x4f\x4d\x17\x9f\
+\x0f\x49\x75\xf0\xd6\x46\x27\x9b\x9f\x60\x95\xd1\x78\x78\x5b\x6d\
+\x72\xa2\x73\xfc\x4f\xd7\x73\xb1\x4f\x62\x61\x9d\xaf\xf7\xa4\xe9\
+\x58\xa9\xfa\x94\x55\xc0\x91\x67\x86\x03\xfa\x90\x71\xa7\xcb\x6d\
+\xa0\xd7\x64\xc8\x91\x06\xe6\x79\x14\xdc\x77\x4c\xdb\x02\xc0\x26\
+\x8a\x85\x37\x42\x0d\x7a\x98\xc2\xee\xf7\xb0\x33\x04\x79\x5e\x8a\
+\x64\xc0\xe3\x05\x96\x18\xa3\xc2\x04\xd1\xb8\xc0\x93\xc1\x02\x71\
+\x1c\xd6\x4c\x3c\xdf\x7d\xf7\x7c\xba\x82\xb3\x7a\x25\xd8\xb8\xd3\
+\x74\x8c\x92\x34\xf1\xb0\xb3\xc4\x0f\x55\x2c\x58\x31\xce\x77\x80\
+\xae\x57\xb0\xc7\x86\x31\x13\x3f\x16\xeb\x38\xab\xbe\xa9\x5c\x20\
+\x89\x05\xa8\xa7\x1b\x0f\x48\x62\x90\x3b\x2f\xeb\x9e\x88\xfd\xa5\
+\x8b\x40\x7c\xe6\xb0\xb3\xac\x2f\x06\x27\xd8\x95\xab\xa4\x85\xf9\
+\xb6\xfa\x61\x04\x60\x2a\x45\x75\x48\x62\xf0\x4e\x3e\xba\xe2\x51\
+\xf5\x64\xab\xc6\x0a\x9f\x67\xa1\x03\xa0\x3a\x70\x85\x77\xa4\xe7\
+\xda\xd5\x94\x3e\xc9\x3f\xbb\xad\x9e\x8d\xbe\xab\x3b\xb0\xb5\x17\
+\x98\x2e\x24\xdd\xa6\x45\xa9\x7e\x8e\x7a\xae\x99\x32\xdd\x4c\x59\
+\x6c\xc7\x32\x30\x65\xb4\xd1\xfe\x74\xc3\x1a\x01\x20\x9d\x00\xeb\
+\xdb\x3b\x3c\xff\xb0\x5b\x77\xb3\x5d\xd6\xe3\x31\x06\x95\xe8\x38\
+\x5f\xdd\xdd\x4a\x6c\x4c\xe7\x37\x28\x4f\x60\x13\x58\xab\xd9\x5a\
+\x32\xe4\xac\xea\x3e\x86\x9d\x65\xbd\x3e\x89\xa5\x6d\xb8\x8c\xa8\
+\x66\x6b\xa1\x9b\xf9\x73\xa1\xaf\x1b\x96\xe6\xff\x43\x7a\xba\xdc\
+\x66\x98\x06\xeb\x5a\x27\x33\xd9\xb1\x4a\x37\x42\x0f\xab\xbd\x1f\
+\x82\x7e\x47\x00\x75\x75\x6f\xe7\x8f\xa5\x64\x77\x0a\x35\xeb\xe6\
+\x7c\xa8\xc6\x12\x3f\xe0\x6a\xc0\xc3\x04\x5c\x93\x1b\x8c\x33\xa6\
+\xee\x7d\xce\xda\xc7\x74\xb1\xe4\xdf\x55\xd5\xe3\x6d\x81\x91\x43\
+\x2e\xb7\xdc\x2f\xf7\x0a\x43\xb9\xeb\x4d\x8d\xf2\x05\x96\x5c\x37\
+\xa7\x76\xea\xa7\x7e\x77\x6a\xdf\x09\x7e\x81\xa8\x13\xaf\x7a\x6e\
+\x80\xb3\x51\x84\xce\xa0\x07\xcb\xbe\xc4\xf5\xba\x10\x59\x6c\x6f\
+\xe6\x7d\x9c\x3b\x1e\x36\x93\xb5\x48\x8e\x9f\xbb\x7d\x5c\x2f\x2a\
+\x91\x14\x0f\x00\x61\x3f\x93\x99\x78\xd8\x59\x0a\x56\x15\x60\x66\
+\x8c\x8b\x38\x91\xb6\x91\xc0\x1e\x75\x85\xac\x48\xfc\x58\x68\x5d\
+\xa1\x79\xe3\x64\xef\x7f\x54\x23\xb2\xdc\x66\x62\xbb\xd3\x9e\x8d\
+\xe5\x2a\x11\x7a\x58\x5d\x28\x4b\x0d\x80\x68\x41\x35\x2d\x2d\x94\
+\xc5\x7b\x6d\x29\xd2\xa1\x72\x1d\xdd\x49\xe4\x27\xf3\x10\xe0\x38\
+\x33\xf2\x7e\x0d\xa6\x6d\x0f\x75\x83\xd7\x7d\x66\xdb\x76\x1f\xb3\
+\x88\x64\xf8\x06\x98\xdc\x73\x91\xfb\x25\xfc\xdc\xde\x63\xe4\xa1\
+\xfb\xc9\x9e\xf1\xa6\x16\x26\x70\x03\xd8\x14\x45\xa4\xa1\x3c\x6e\
+\xee\xe1\xee\xee\x1a\x5b\x44\x78\x38\xaa\x5b\x53\x3d\xe8\xd6\xb9\
+\x13\xe3\xe5\x5b\x3c\xe8\x7c\x03\xb8\x97\x75\xd4\xae\x09\x74\x6c\
+\xc7\xff\xb7\xb7\x4f\x92\x13\x41\x79\x02\xdb\x8a\xba\x98\x6e\x3c\
+\xc4\x79\xb2\x0f\xe6\x38\x01\xbd\x2f\x69\x60\x0e\x76\x26\x2b\x88\
+\xd5\x25\x0d\xdd\x6c\xab\xfa\x9e\xd5\x85\x1b\x8f\xdb\xec\x7a\xcf\
+\x23\x41\x57\x31\x01\x95\x06\x25\x72\x0d\x4c\x2c\xbc\x45\xf4\xd1\
+\x27\x98\x37\x0d\x51\x83\x15\x6d\xfd\x21\xda\xc0\xac\xbb\x05\x9b\
+\x52\x37\x75\xb9\x16\x6d\x6e\xbc\x63\xbd\x18\x5a\x49\x51\x05\x70\
+\xcb\x99\x30\xe6\x72\x7f\xe7\xbe\xb3\x82\x54\x7c\x9f\x2c\x2d\x31\
+\x99\x4d\x8c\x95\xd3\x04\x4c\x7a\xce\xbd\x32\xfc\x58\xf1\xc1\xf0\
+\x94\x3b\x31\x72\x00\x7f\xd8\x83\x1f\x37\xc7\xaa\x61\xe2\xeb\xcd\
+\x4f\x10\x14\x57\x52\xd8\x79\xd3\x74\x42\x27\xfd\x4c\x72\xd1\xcd\
+\x57\x75\x16\x1b\x81\x31\xf1\x63\x09\x98\x56\xd4\x05\x92\x58\x0b\
+\x56\xf1\x3e\x03\x28\x67\x65\x6e\x1c\x56\xb3\xb5\xb4\x6f\xba\x10\
+\x54\xc6\xa6\xf5\x81\xdf\xc3\x8b\xcd\x4f\x91\x5e\xbd\x14\x09\xd5\
+\xf4\xe3\x79\x13\x14\x6a\x88\x4d\xae\x35\xce\xc2\x6a\x05\xf2\x31\
+\x27\x5f\x95\x13\x3a\xad\xa9\xb2\x3a\x4f\xb9\x34\x4d\x33\x32\x25\
+\xfb\xa8\x6c\x7b\xc8\x07\x7c\x28\xa0\xa2\x3e\xaa\x1d\x83\xd4\x8b\
+\x64\x13\xc5\x52\xa9\x3e\x00\xb8\xe5\x0c\xcf\xce\x9f\xe0\xcf\xfe\
+\xe6\x8f\xf1\x57\x7f\xfe\xb7\x78\xf6\xd9\x97\x58\xa0\xc2\x64\x36\
+\x91\x59\xb0\x39\x2f\x9b\x66\x3a\xec\x26\x74\xb5\xd3\x92\xd4\x7e\
+\x74\x52\x0e\x45\x08\x5c\x3e\x7d\x8a\xfb\x71\x1d\x4e\x06\x80\x59\
+\xf1\x19\x46\xe3\xe7\xc8\x70\x87\xce\xa8\xdb\x64\x10\xb1\xd6\x01\
+\xf8\x0c\x1e\x4e\x51\xf8\x3d\x0c\xed\xb1\x38\xd7\x76\xe2\xc7\x12\
+\xc3\x72\x46\xad\xac\xf7\x42\x22\x70\x30\x73\xff\xb1\xca\xc2\x56\
+\xd4\x15\x4c\xfc\xc4\x2a\x60\x45\x5d\xf1\xa8\x03\x3f\xbf\x28\xaa\
+\xd9\x1a\xa9\x13\xe0\xd3\xd9\x4b\xc1\xc4\xbc\x13\x4f\x14\x47\xa2\
+\x97\x30\x67\x61\xf2\x0d\xeb\x0e\xde\xa1\x5b\xab\x89\x05\x8f\xd1\
+\xc2\xdc\xd0\x3a\xc4\xfc\x87\x7a\x4d\xa8\xdf\xe1\x50\x51\xa9\xe9\
+\xbb\xea\xa6\x37\xa9\xfb\x26\xd9\xc0\x8d\x37\x4a\x8c\xbf\xff\x78\
+\x88\xbf\xff\xbd\x2f\xf1\x77\xff\xf8\x17\xf8\xcb\x5f\xfc\x09\x7e\
+\xf6\xa7\xff\x00\xfb\x49\x2c\x7d\x26\x75\xf3\x21\x37\x58\x5c\xd5\
+\xf3\x38\xa8\x6b\xa8\xea\x37\xe6\xcf\xe9\x7c\xde\x8f\x87\xb0\x51\
+\x4f\x0a\x0d\x47\x17\xf5\x36\xc9\x7f\xe1\xf5\xb2\xbb\xbb\x58\x9a\
+\x69\xb4\x3c\xf1\x68\x89\x31\xdc\x7c\x85\x69\xb9\xcb\x66\xb3\xe3\
+\x3c\x41\xe2\xc7\xd8\x66\xd7\x20\x40\xab\x8f\xfc\x56\xcf\x19\x95\
+\x18\x94\xc0\x4b\x86\xdc\x6d\x92\xe0\xdd\xed\x18\xf3\x6c\x81\xb0\
+\xe8\xe0\xa4\x77\x82\x6a\xb6\xc6\xbb\xe7\xaf\x50\xcd\xd6\x38\xef\
+\x9f\xc1\x19\x8d\xa4\x30\x36\xff\x0c\xee\x99\xa0\x36\xaa\xd6\xc0\
+\x92\x7c\xc2\x94\x27\x51\x0e\x62\xa9\x31\xb6\xea\x4b\xd6\x25\xed\
+\x10\x00\x45\xb7\x74\xc7\x39\xe8\xb3\x35\xe9\x5c\x75\x3d\x1f\x35\
+\xdb\xa6\x5f\x0f\x31\xf1\x31\x3d\x29\xd4\x46\x31\x3c\x22\x48\x39\
+\x17\x6d\xee\x3b\x49\x62\x04\xb5\x3f\xf9\xe1\xe8\x1c\xdd\x2f\xde\
+\x62\xf4\x49\x81\x3f\xf8\xf2\x8f\xf0\xf3\x5f\x7c\x81\xcb\x67\x7f\
+\x2d\xa2\x98\xab\x22\xdb\xeb\x16\x9a\x58\x95\x54\xa1\x4c\x2c\xad\
+\x66\xaf\xd1\x7a\xf2\x04\x95\xf8\xac\x66\xe0\xef\xd6\x78\xbb\x75\
+\x45\x7f\x35\xee\x52\xe5\x7e\x66\x11\x17\xa8\x0a\x8c\xec\x4a\xcc\
+\xb1\x73\x09\xa8\x63\xc3\x8f\x13\xc6\x9a\x06\xe0\xdb\xec\x1a\x56\
+\x1c\x23\x9e\x25\xb8\xad\x96\x38\x8b\x81\x69\x00\xfc\xe7\x2f\x57\
+\xf8\xfa\xdf\xfe\x19\x0f\x1e\xd4\xc2\xbd\x73\xd1\xc3\xe6\xdd\xae\
+\x3d\xe7\xa3\x1f\x79\xf8\xf4\x93\x3a\x09\xda\x7d\x10\xe3\xd3\xfe\
+\x39\x42\xab\x40\x1a\x75\x11\xbb\x8a\x5f\xd3\x09\x81\x0a\xda\x06\
+\x28\xa9\xd5\x83\x3d\x7f\x2f\xaa\x39\x26\xdb\x9d\xe1\xc7\xa7\x27\
+\x1d\x0a\x39\x93\x9c\xd0\x59\xfc\xe4\x3e\x53\xf7\x43\xfb\x56\xd7\
+\x07\x56\x86\x12\x83\xdf\xc9\xe8\x52\x0d\xa4\x43\xcf\x79\xe4\x8f\
+\x86\xb5\x8b\x01\x39\xa0\xca\x8a\x8d\xf4\x7b\xd5\x32\x25\x71\x9c\
+\xb3\x3e\x86\x91\x05\x7f\xd8\x03\x3e\x3c\x83\x5b\x14\xf0\x56\x2f\
+\xf0\xfd\xd5\x02\xb8\xfd\x55\x3d\x30\xb3\xf9\xcd\xab\x22\x03\x16\
+\x01\x3a\x00\xd0\x54\x6d\x6c\x8a\x15\x62\x58\x02\xcc\x71\xb1\xaa\
+\x47\x7e\x35\xc6\x17\xc9\x82\x78\x66\xc3\x19\x45\x78\xd0\xb4\x26\
+\xeb\x3d\x39\x87\x0b\x1f\xd1\xaf\x6a\xc9\x78\xb3\xfe\x5a\x9a\x3e\
+\x1b\x57\x96\x16\x9b\x1b\x3f\x87\x9b\x03\x98\x5b\x70\xd7\xaf\x17\
+\x18\x9f\x2d\x85\x41\x35\x06\x80\x6c\x29\x1e\x01\xe0\xdd\x6d\x08\
+\xf7\xcc\xf0\xde\xb7\x5b\xb8\xcd\xff\xdf\x26\x09\xbe\xbf\xba\xc2\
+\xbf\xfe\xcb\x3f\xc9\x9f\x78\x0d\x54\xa7\x7d\x5c\x6c\x17\x58\x2f\
+\x6f\xf0\xdd\x04\xf8\xee\xb7\xff\x2e\xde\xfe\xf1\xb3\xc7\x78\xfa\
+\xf9\x1f\xe2\xfe\xc3\x07\x58\x84\x13\x49\x73\xf6\xc3\x11\x46\x0d\
+\x4e\x46\xb6\x27\x98\x38\x5d\xf4\x10\x56\x2b\xc0\x89\x30\x99\x5a\
+\x70\x06\x89\x18\x0d\xe9\xe6\x1e\x0a\xec\x2a\x2c\x3e\x66\x0c\x80\
+\xae\x2f\x9a\xee\x42\xe0\x51\x32\xbe\xaf\xf2\x40\x5b\x2b\xb3\xc6\
+\xcd\x8c\xc6\x5c\x5b\x11\x29\x00\x9c\xc6\x31\x12\xab\xc2\x69\x15\
+\x8b\xdb\xfc\xc6\x8a\x80\xb4\x10\xc0\xad\x13\x78\x02\xac\xb1\xd8\
+\xab\x50\xf6\x1c\xa7\xc9\xfa\xab\xf0\xfc\x37\x2f\x90\x4f\x57\x78\
+\xb7\x04\xae\xaf\x6f\x90\x2e\x96\x78\xff\xfd\x35\x2c\x00\xc3\xa1\
+\xdc\x44\xe5\x34\x8e\xa5\xe4\xf5\xd8\x1d\xd4\x53\x8f\x00\xc4\x8b\
+\x7a\x02\x52\xbc\x00\xb2\xd1\x9d\x28\xf8\xcc\x46\x77\x08\xfb\x11\
+\x82\xfb\x8f\x50\x7a\x17\xb8\xd7\xe9\x22\x0f\xa2\xba\x17\xdb\xb7\
+\xdf\xd4\xd2\xc4\xbd\xc4\xa6\x77\x85\x78\x01\xc0\x3d\x81\x13\xcf\
+\xf0\x70\x74\x8e\xd2\xbb\x80\x87\x53\x78\x16\x50\x34\x8c\x8c\x41\
+\x85\xff\x07\x5b\x53\xe4\xea\xf5\xd8\xe3\x94\x00\x00\x00\x00\x49\
+\x45\x4e\x44\xae\x42\x60\x82\
+"""
+
+qt_resource_name = b"""\
+\x00\x09\
+\x06\xa8\xaa\x74\
+\x00\x71\
+\x00\x75\x00\x6f\x00\x74\x00\x65\x00\x2e\x00\x74\x00\x78\x00\x74\
+\x00\x0a\
+\x07\x2b\x67\xc7\
+\x00\x73\
+\x00\x61\x00\x6d\x00\x70\x00\x6c\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\
+"""
+
+qt_resource_struct = b"""\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x00\x18\x00\x00\x00\x00\x00\x01\x00\x00\x00\x39\
+"""
+
+
+def qInitResources():
+ QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+
+qInitResources()
diff --git a/sources/pyside6/tests/QtCore/sample.png b/sources/pyside6/tests/QtCore/sample.png
new file mode 100644
index 000000000..60450f0dc
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/sample.png
Binary files differ
diff --git a/sources/pyside6/tests/QtCore/setprop_on_ctor_test.py b/sources/pyside6/tests/QtCore/setprop_on_ctor_test.py
new file mode 100644
index 000000000..de8f67bb3
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/setprop_on_ctor_test.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+
+
+class SetPropOnCtorTest(unittest.TestCase):
+ def testIt(self):
+ timer = QTimer(interval=42)
+ self.assertEqual(timer.interval(), 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/signal_sender.py b/sources/pyside6/tests/QtCore/signal_sender.py
new file mode 100644
index 000000000..2552591e5
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/signal_sender.py
@@ -0,0 +1,91 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import (QCoreApplication, QObject, QStringListModel,
+ QTimer, Signal, Slot, Qt)
+
+
+class Sender(QObject):
+ testSignal = Signal()
+
+ def emitSignal(self):
+ self.testSignal.emit()
+
+
+class Receiver(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__()
+ self._sender = None
+ self._slot_count = 0
+
+ @Slot()
+ def testSlot(self):
+ self._sender = self.sender()
+ self._slot_count += 1
+
+
+class DerivedReceiver(Receiver):
+ pass
+
+
+class TestSignalSender(UsesQApplication):
+ """Test PYSIDE-2144/1295, check that QObject::sender() works also if it is
+ routed via GlobalReceiverV2 in case of a non-C++ slot (Python callback,
+ as for derived classes)."""
+ def testSignalSender(self):
+ sender = Sender()
+ receiver = Receiver()
+ sender.testSignal.connect(receiver.testSlot)
+ derived_receiver = DerivedReceiver()
+ sender.testSignal.connect(derived_receiver.testSlot)
+ sender.emitSignal()
+
+ QTimer.singleShot(100, self.app.quit)
+ while derived_receiver._slot_count == 0:
+ QCoreApplication.processEvents()
+
+ self.assertEqual(receiver._sender, sender)
+ self.assertEqual(derived_receiver._sender, sender)
+
+
+class TestConstructorConnection(UsesQApplication):
+ """PYSIDE-2329: Check constructor connections for signals from the
+ base as well as signals with arguments."""
+ def testConstructorConnection(self):
+
+ was_destroyed = False
+ was_changed = False
+
+ def destroyed_handler():
+ nonlocal was_destroyed
+ was_destroyed = True
+
+ def changed_handler():
+ nonlocal was_changed
+ was_changed = True
+
+ data_list = ["blub"]
+ model = QStringListModel(data_list,
+ destroyed=destroyed_handler,
+ dataChanged=changed_handler)
+ model.setData(model.index(0, 0), "bla", Qt.EditRole)
+ del model
+
+ self.assertTrue(was_changed)
+ self.assertTrue(was_destroyed)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/snake_prop_feature_test.py b/sources/pyside6/tests/QtCore/snake_prop_feature_test.py
new file mode 100644
index 000000000..82087ab9a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/snake_prop_feature_test.py
@@ -0,0 +1,143 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Property, QSize
+from PySide6.QtWidgets import QApplication, QMainWindow, QWidget
+
+is_pypy = hasattr(sys, "pypy_version_info")
+if not is_pypy:
+ from PySide6.support import feature
+
+"""
+snake_prop_feature_test.py
+--------------------------
+
+Test the snake_case and true_property feature.
+
+This works now, including class properties.
+"""
+
+
+class Window(QWidget):
+ def __init__(self):
+ super().__init__()
+
+
+@unittest.skipIf(is_pypy, "__feature__ cannot yet be used with PyPy")
+class FeatureTest(unittest.TestCase):
+ def setUp(self):
+ qApp or QApplication()
+ feature.reset()
+
+ def tearDown(self):
+ feature.reset()
+ qApp.shutdown()
+
+ def testRenamedFunctions(self):
+ window = Window()
+ window.setWindowTitle('camelCase')
+
+ # and now the same with snake_case enabled
+ from __feature__ import snake_case
+
+ # Works with the same window! window = Window()
+ window.set_window_title('snake_case')
+
+ def testPropertyAppearVanish(self):
+ window = Window()
+
+ self.assertTrue(callable(window.isModal))
+ with self.assertRaises(AttributeError):
+ window.modal
+
+ from __feature__ import snake_case, true_property
+ # PYSIDE-1548: Make sure that another import does not clear the features.
+ import sys
+
+ self.assertTrue(isinstance(QWidget.modal, property))
+ self.assertTrue(isinstance(window.modal, bool))
+ with self.assertRaises(AttributeError):
+ window.isModal
+
+ # switching back
+ feature.reset()
+
+ self.assertTrue(callable(window.isModal))
+ with self.assertRaises(AttributeError):
+ window.modal
+
+ def testClassProperty(self):
+ from __feature__ import snake_case, true_property
+ # We check the class...
+ self.assertEqual(type(QApplication.quit_on_last_window_closed), bool)
+ x = QApplication.quit_on_last_window_closed
+ QApplication.quit_on_last_window_closed = not x
+ self.assertEqual(QApplication.quit_on_last_window_closed, not x)
+ # ... and now the instance.
+ self.assertEqual(type(qApp.quit_on_last_window_closed), bool)
+ x = qApp.quit_on_last_window_closed
+ qApp.quit_on_last_window_closed = not x
+ self.assertEqual(qApp.quit_on_last_window_closed, not x)
+ # make sure values are equal
+ self.assertEqual(qApp.quit_on_last_window_closed,
+ QApplication.quit_on_last_window_closed)
+
+ def testUserClassNotAffected(self):
+ FunctionType = type(lambda: 42)
+ # Note: the types module does not have MethodDescriptorType in low versions.
+ MethodDescriptorType = type(str.split)
+
+ class UserClass(QWidget):
+
+ def someFunc1(self):
+ pass
+
+ @staticmethod
+ def someFunc2(a, b):
+ pass
+
+ inspect = UserClass.__dict__
+ self.assertTrue(isinstance(inspect["someFunc1"], FunctionType))
+ self.assertTrue(isinstance(inspect["someFunc2"], staticmethod))
+ self.assertTrue(isinstance(UserClass.someFunc2, FunctionType))
+ self.assertTrue(isinstance(UserClass.addAction, MethodDescriptorType))
+
+ from __feature__ import snake_case
+
+ inspect = UserClass.__dict__
+ self.assertTrue(isinstance(inspect["someFunc1"], FunctionType))
+ self.assertTrue(isinstance(inspect["someFunc2"], staticmethod))
+ self.assertTrue(isinstance(UserClass.someFunc2, FunctionType))
+ self.assertTrue(isinstance(UserClass.add_action, MethodDescriptorType))
+
+ def testTrueProperyCanOverride(self):
+ from __feature__ import true_property
+
+ class CustomWidget(QWidget):
+ global prop_result
+ prop_result = None
+
+ @Property(QSize)
+ def minimumSizeHint(self):
+ global prop_result
+ print("called")
+ prop_result = super().minimumSizeHint
+ return prop_result
+
+ window = QMainWindow()
+ window.setCentralWidget(CustomWidget(window))
+ window.show()
+ self.assertTrue(isinstance(prop_result, QSize))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/staticMetaObject_test.py b/sources/pyside6/tests/QtCore/staticMetaObject_test.py
new file mode 100644
index 000000000..223c334d3
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/staticMetaObject_test.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Slot, QMetaObject
+
+
+class MyObject(QObject):
+ @Slot(int, str)
+ def slot1(self, a, b):
+ pass
+
+
+class testAttribute(unittest.TestCase):
+ def testBug896(self):
+ mo = MyObject.staticMetaObject
+ self.assertTrue(isinstance(mo, QMetaObject))
+ self.assertEqual(mo.className(), 'MyObject')
+ self.assertTrue(mo.indexOfSlot('slot1(int,QString)') > -1)
+
+ def testDuplicateSlot(self):
+ mo = MyObject.staticMetaObject
+ self.assertEqual(mo.indexOfSignal('destroyed(void)'), -1)
+ self.assertTrue(mo.indexOfSignal('destroyed()') > -1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/static_method_test.py b/sources/pyside6/tests/QtCore/static_method_test.py
new file mode 100644
index 000000000..bbf96e44a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/static_method_test.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for overloads involving static and non-static versions of a method.'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QFile
+
+
+class StaticNonStaticMethodsTest(unittest.TestCase):
+ '''Test cases for overloads involving static and non-static versions of a method.'''
+
+ def setUp(self):
+ filename = 'somefile%d.txt' % os.getpid()
+ self.existing_filename = os.path.join(os.path.curdir, filename)
+ self.delete_file = False
+ if not os.path.exists(self.existing_filename):
+ f = open(self.existing_filename, 'w')
+ for line in range(10):
+ f.write('sbrubbles\n')
+ f.close()
+ self.delete_file = True
+
+ self.non_existing_filename = os.path.join(os.path.curdir, 'inexistingfile.txt')
+ i = 0
+ while os.path.exists(self.non_existing_filename):
+ i += 1
+ filename = 'inexistingfile-%d.txt' % i
+ self.non_existing_filename = os.path.join(os.path.curdir, filename)
+
+ def tearDown(self):
+ if self.delete_file:
+ os.remove(self.existing_filename)
+
+ def testCallingStaticMethodWithClass(self):
+ '''Call static method using class.'''
+ self.assertTrue(QFile.exists(self.existing_filename))
+ self.assertFalse(QFile.exists(self.non_existing_filename))
+
+ def testCallingStaticMethodWithInstance(self):
+ '''Call static method using instance of class.'''
+ f = QFile(self.non_existing_filename)
+ self.assertTrue(f.exists(self.existing_filename))
+ self.assertFalse(f.exists(self.non_existing_filename))
+
+ def testCallingInstanceMethod(self):
+ '''Call instance method.'''
+ f1 = QFile(self.non_existing_filename)
+ self.assertFalse(f1.exists())
+ f2 = QFile(self.existing_filename)
+ self.assertTrue(f2.exists())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/thread_signals_test.py b/sources/pyside6/tests/QtCore/thread_signals_test.py
new file mode 100644
index 000000000..a453d1ac1
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/thread_signals_test.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test case for QObject.signalsBlocked() and blockSignal()'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Signal, QThread
+from helper.usesqapplication import UsesQApplication
+
+
+class MyThread(QThread):
+
+ test = Signal(str)
+
+ def run(self):
+ self.test.emit("INdT - PySide")
+
+
+class TestThreadSignal(UsesQApplication):
+
+ __called__ = True
+
+ def _callback(self, msg):
+ self.assertEqual(msg, "INdT - PySide")
+ self.__called__ = True
+ self.app.quit()
+
+ def testThread(self):
+ t = MyThread()
+ t.test.connect(self._callback)
+ t.start()
+
+ self.app.exec()
+ t.wait()
+ self.assertTrue(self.__called__)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtCore/tr_noop_test.py b/sources/pyside6/tests/QtCore/tr_noop_test.py
new file mode 100644
index 000000000..a3b2e257f
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/tr_noop_test.py
@@ -0,0 +1,66 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QT_TR_NOOP, QT_TR_NOOP_UTF8
+from PySide6.QtCore import QT_TRANSLATE_NOOP, QT_TRANSLATE_NOOP3, QT_TRANSLATE_NOOP_UTF8
+
+
+class QtTrNoopTest(unittest.TestCase):
+
+ def setUp(self):
+ self.txt = 'Cthulhu fhtag!'
+
+ def tearDown(self):
+ del self.txt
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testQtTrNoop(self):
+ refcnt = sys.getrefcount(self.txt)
+ result = QT_TR_NOOP(self.txt)
+ self.assertEqual(result, self.txt)
+ self.assertEqual(sys.getrefcount(result), refcnt + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testQtTrNoopUtf8(self):
+ refcnt = sys.getrefcount(self.txt)
+ result = QT_TR_NOOP_UTF8(self.txt)
+ self.assertEqual(result, self.txt)
+ self.assertEqual(sys.getrefcount(result), refcnt + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testQtTranslateNoop(self):
+ refcnt = sys.getrefcount(self.txt)
+ result = QT_TRANSLATE_NOOP(None, self.txt)
+ self.assertEqual(result, self.txt)
+ self.assertEqual(sys.getrefcount(result), refcnt + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testQtTranslateNoopUtf8(self):
+ refcnt = sys.getrefcount(self.txt)
+ result = QT_TRANSLATE_NOOP_UTF8(self.txt)
+ self.assertEqual(result, self.txt)
+ self.assertEqual(sys.getrefcount(result), refcnt + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testQtTranslateNoop3(self):
+ refcnt = sys.getrefcount(self.txt)
+ result = QT_TRANSLATE_NOOP3(None, self.txt, None)
+ self.assertEqual(result, self.txt)
+ self.assertEqual(sys.getrefcount(result), refcnt + 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/translation_test.py b/sources/pyside6/tests/QtCore/translation_test.py
new file mode 100644
index 000000000..da09e47b6
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/translation_test.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests to test QTranslator and translation in general.'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTranslator, QCoreApplication
+
+from helper.usesqapplication import UsesQApplication
+
+
+class TranslationTest(UsesQApplication):
+ '''Test case for Qt translation facilities.'''
+
+ def setUp(self):
+ super(TranslationTest, self).setUp()
+ self.trdir = os.path.join(os.path.dirname(__file__), 'translations')
+
+ def testLatin(self):
+ # Set string value to Latin
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_latin.qm'))
+ self.app.installTranslator(translator)
+
+ obj = QObject()
+ obj.setObjectName(obj.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), 'Orbis, te saluto!')
+
+ def testLatinClass(self):
+ # Set string value to Latin, no instance
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_latin.qm'))
+ self.app.installTranslator(translator)
+
+ obj = QObject()
+ obj.setObjectName(QObject.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), 'Orbis, te saluto!')
+
+ def testLatinDerived(self):
+ # PYSIDE-131: Test that derived classes work, too.
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_latin.qm'))
+ self.app.installTranslator(translator)
+
+ class Derived(QObject):
+ pass
+
+ obj = Derived()
+ obj.setObjectName(obj.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), 'Orbis, te saluto!')
+
+ def testLatinDerivedClass(self):
+ # PYSIDE-131: Test that derived classes work, too, no instance.
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_latin.qm'))
+ self.app.installTranslator(translator)
+
+ class Derived(QObject):
+ pass
+
+ obj = Derived()
+ obj.setObjectName(Derived.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), 'Orbis, te saluto!')
+
+ def testRussian(self):
+ # Set string value to Russian
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_russian.qm'))
+ self.app.installTranslator(translator)
+
+ obj = QObject()
+ obj.setObjectName(obj.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), 'привет мир!')
+
+ def testUtf8(self):
+ translator = QTranslator()
+ translator.load(os.path.join(self.trdir, 'trans_russian.qm'))
+ self.app.installTranslator(translator)
+
+ obj = QObject()
+ obj.setObjectName(obj.tr('Hello World!'))
+ self.assertEqual(obj.objectName(), 'привет мир!')
+
+ def testTranslateWithNoneDisambiguation(self):
+ value = 'String here'
+ obj = QCoreApplication.translate('context', value, None)
+ self.assertTrue(isinstance(obj, str))
+ self.assertEqual(obj, value)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/translations/trans_latin.qm b/sources/pyside6/tests/QtCore/translations/trans_latin.qm
new file mode 100644
index 000000000..efdbee8c7
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/translations/trans_latin.qm
Binary files differ
diff --git a/sources/pyside6/tests/QtCore/translations/trans_latin.ts b/sources/pyside6/tests/QtCore/translations/trans_latin.ts
new file mode 100644
index 000000000..b9fcf41be
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/translations/trans_latin.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="lt">
+<defaultcodec></defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Hello World!</source>
+ <translation>Orbis, te saluto!</translation>
+ </message>
+</context>
+</TS>
diff --git a/sources/pyside6/tests/QtCore/translations/trans_russian.qm b/sources/pyside6/tests/QtCore/translations/trans_russian.qm
new file mode 100644
index 000000000..5f16552a7
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/translations/trans_russian.qm
Binary files differ
diff --git a/sources/pyside6/tests/QtCore/translations/trans_russian.ts b/sources/pyside6/tests/QtCore/translations/trans_russian.ts
new file mode 100644
index 000000000..d1ba49bd2
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/translations/trans_russian.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS><TS version="1.1" language="ru">
+<defaultcodec></defaultcodec>
+<context>
+ <name>QObject</name>
+ <message>
+ <source>Hello World!</source>
+ <translation>привет мир!</translation>
+ </message>
+</context>
+</TS>
diff --git a/sources/pyside6/tests/QtCore/unaryoperator_test.py b/sources/pyside6/tests/QtCore/unaryoperator_test.py
new file mode 100644
index 000000000..7b38685c8
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/unaryoperator_test.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests the presence of unary operator __neg__ on the QPoint class'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPoint
+
+
+class NegUnaryOperatorTest(unittest.TestCase):
+ '''Tests the presence of unary operator __neg__ on the QPoint class'''
+
+ def setUp(self):
+ # Acquire resources
+ self.x, self.y = 10, 20
+ self.neg_x, self.neg_y = -self.x, -self.y
+ self.qpoint = QPoint(self.x, self.y)
+
+ def tearDown(self):
+ # Release resources
+ del self.qpoint
+ del self.x
+ del self.y
+ del self.neg_x
+ del self.neg_y
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testNegUnaryOperator(self):
+ # Test __neg__ unary operator on QPoint class
+ __neg__method_exists = True
+ try:
+ neg_qpoint = -self.qpoint
+ except:
+ __neg__method_exists = False
+
+ self.assertTrue(__neg__method_exists)
+ self.assertEqual(self.qpoint, -neg_qpoint)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/unicode_test.py b/sources/pyside6/tests/QtCore/unicode_test.py
new file mode 100644
index 000000000..73ce96c77
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/unicode_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QString conversion to/from Python Unicode'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtCore import QByteArray
+
+
+class UnicodeConversion(unittest.TestCase):
+ '''Test case for QString to/from Python Unicode conversion'''
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def testSetRegularStringRetrieveUnicode(self):
+ # Set regular Python string retrieve unicode
+ obj = QObject()
+ obj.setObjectName('test')
+ self.assertEqual(obj.objectName(), 'test')
+
+ def testSetUnicodeRetrieveUnicode(self):
+ # Set Python unicode string and retrieve unicode
+ obj = QObject()
+ obj.setObjectName('ümlaut')
+ self.assertEqual(obj.objectName(), 'ümlaut')
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtCore/versioninfo_test.py b/sources/pyside6/tests/QtCore/versioninfo_test.py
new file mode 100644
index 000000000..63414378a
--- /dev/null
+++ b/sources/pyside6/tests/QtCore/versioninfo_test.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+
+
+class TestVersionInfo(unittest.TestCase):
+ def testIt(self):
+
+ v = PySide6.__version_info__
+ self.assertEqual(type(v), tuple)
+ self.assertEqual(len(v), 5)
+ self.assertEqual(type(v[0]), int)
+ self.assertEqual(type(v[1]), int)
+ self.assertEqual(type(v[2]), int)
+ self.assertEqual(type(v[3]), str)
+ self.assertEqual(type(v[4]), str)
+
+ self.assertEqual(type(PySide6.__version__), str)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtDBus/CMakeLists.txt b/sources/pyside6/tests/QtDBus/CMakeLists.txt
new file mode 100644
index 000000000..bf2d2105a
--- /dev/null
+++ b/sources/pyside6/tests/QtDBus/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(ENABLE_UNIX)
+ PYSIDE_TEST(test_dbus.py)
+endif()
diff --git a/sources/pyside6/tests/QtDBus/QtDBus.pyproject b/sources/pyside6/tests/QtDBus/QtDBus.pyproject
new file mode 100644
index 000000000..76c3963e4
--- /dev/null
+++ b/sources/pyside6/tests/QtDBus/QtDBus.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["test_dbus.py"]
+}
diff --git a/sources/pyside6/tests/QtDBus/test_dbus.py b/sources/pyside6/tests/QtDBus/test_dbus.py
new file mode 100644
index 000000000..a37db9421
--- /dev/null
+++ b/sources/pyside6/tests/QtDBus/test_dbus.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QDBus'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+import sys
+from PySide6.QtCore import QCoreApplication
+from PySide6.QtDBus import (QDBusConnection, QDBusConnectionInterface,
+ QDBusInterface, QDBusReply)
+
+
+def service_names():
+ session_bus = QDBusConnection.sessionBus()
+ if not QDBusConnection.sessionBus().isConnected():
+ print("Cannot connect to the D-Bus session bus.", file=sys.stderr)
+ return []
+ reply = session_bus.interface().registeredServiceNames()
+ if not reply.isValid():
+ print("Error:", reply.error().message(), file=sys.stderr)
+ return []
+ return reply.value()
+
+
+class TestDBus(UsesQApplication):
+ '''Simple Test case for QDBus'''
+
+ def test_service_names(self):
+ names = service_names()
+ print(names)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtDataVisualization/CMakeLists.txt b/sources/pyside6/tests/QtDataVisualization/CMakeLists.txt
new file mode 100644
index 000000000..61b347263
--- /dev/null
+++ b/sources/pyside6/tests/QtDataVisualization/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(datavisualization_test.py)
diff --git a/sources/pyside6/tests/QtDataVisualization/QtDataVisualization.pyproject b/sources/pyside6/tests/QtDataVisualization/QtDataVisualization.pyproject
new file mode 100644
index 000000000..23a8a141c
--- /dev/null
+++ b/sources/pyside6/tests/QtDataVisualization/QtDataVisualization.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["datavisualization_test.py"]
+}
diff --git a/sources/pyside6/tests/QtDataVisualization/datavisualization_test.py b/sources/pyside6/tests/QtDataVisualization/datavisualization_test.py
new file mode 100644
index 000000000..98ada6d47
--- /dev/null
+++ b/sources/pyside6/tests/QtDataVisualization/datavisualization_test.py
@@ -0,0 +1,104 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtDataVisualization'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QTimer
+from PySide6.QtDataVisualization import (Q3DBars, QBar3DSeries, QBarDataItem,
+ QBarDataProxy, QCategory3DAxis,
+ QValue3DAxis, QValue3DAxisFormatter,
+ qDefaultSurfaceFormat)
+
+
+def dataToBarDataRow(data):
+ result = []
+ for d in data:
+ result.append(QBarDataItem(d))
+ return result
+
+
+def dataToBarDataArray(data):
+ result = []
+ for row in data:
+ result.append(dataToBarDataRow(row))
+ return result
+
+
+class QtDataVisualizationTestCase(UsesQApplication):
+ '''Tests related to QtDataVisualization'''
+
+ def testBars(self):
+ self.bars = Q3DBars()
+ self.columnAxis = QCategory3DAxis()
+ self.columnAxis.setTitle('Columns')
+ self.columnAxis.setTitleVisible(True)
+ self.columnAxis.setLabels(['Column1', 'Column2'])
+
+ self.rowAxis = QCategory3DAxis()
+ self.rowAxis.setTitle('Rows')
+ self.rowAxis.setTitleVisible(True)
+ self.rowAxis.setLabels(['Row1', 'Row2'])
+
+ self.valueAxis = QValue3DAxis()
+ self.valueAxis.setTitle('Values')
+ self.valueAxis.setTitleVisible(True)
+ self.valueAxis.setRange(0, 5)
+
+ self.bars.setRowAxis(self.rowAxis)
+ self.bars.setColumnAxis(self.columnAxis)
+ self.bars.setValueAxis(self.valueAxis)
+
+ self.series = QBar3DSeries()
+ self.arrayData = [[1, 2], [3, 4]]
+ self.series.dataProxy().addRows(dataToBarDataArray(self.arrayData))
+
+ self.bars.setPrimarySeries(self.series)
+
+ self.bars.show()
+ QTimer.singleShot(500, self.app.quit)
+ self.app.exec()
+
+ def testBarDataProxy(self):
+ '''PSYSIDE-1438, crashes in QBarDataProxy.addRow()'''
+ items = [QBarDataItem(v) for v in [1.0, 2.0]]
+ data_proxy = QBarDataProxy()
+ data_proxy.addRow(items)
+ data_proxy.addRow(items, 'bla')
+ data_proxy.insertRow(0, items)
+ data_proxy.insertRow(0, items, 'bla')
+ data_proxy.setRow(0, items)
+ data_proxy.setRow(0, items, 'bla')
+ self.assertTrue(data_proxy.rowCount(), 4)
+
+ def testDefaultSurfaceFormat(self):
+ format = qDefaultSurfaceFormat(True)
+ print(format)
+
+ def testQValue3DAxisFormatter(self):
+ """PYSIDE-2025: Test the added setters of QValue3DAxisFormatter."""
+ formatter = QValue3DAxisFormatter()
+ float_values = [float(10)]
+ formatter.setGridPositions(float_values)
+ self.assertEqual(formatter.gridPositions(), float_values)
+
+ formatter.setLabelPositions(float_values)
+ self.assertEqual(formatter.labelPositions(), float_values)
+
+ label_strings = ["bla"]
+ formatter.setLabelStrings(label_strings)
+ self.assertEqual(formatter.labelStrings(), label_strings)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtDesigner/CMakeLists.txt b/sources/pyside6/tests/QtDesigner/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtDesigner/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtGraphs/CMakeLists.txt b/sources/pyside6/tests/QtGraphs/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtGraphs/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtGui/CMakeLists.txt b/sources/pyside6/tests/QtGui/CMakeLists.txt
new file mode 100644
index 000000000..71a5c7eb9
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/CMakeLists.txt
@@ -0,0 +1,60 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#Keep this in alphabetical sort
+
+PYSIDE_TEST(bug_367.py)
+PYSIDE_TEST(bug_493.py)
+PYSIDE_TEST(bug_606.py)
+PYSIDE_TEST(bug_617.py)
+PYSIDE_TEST(bug_652.py)
+PYSIDE_TEST(bug_660.py)
+PYSIDE_TEST(bug_716.py)
+PYSIDE_TEST(bug_740.py)
+PYSIDE_TEST(bug_743.py)
+PYSIDE_TEST(bug_785.py)
+PYSIDE_TEST(bug_991.py)
+PYSIDE_TEST(bug_1091.py)
+PYSIDE_TEST(bug_PYSIDE-344.py)
+PYSIDE_TEST(deepcopy_test.py)
+PYSIDE_TEST(event_filter_test.py)
+PYSIDE_TEST(float_to_int_implicit_conversion_test.py)
+PYSIDE_TEST(pyside_reload_test.py)
+PYSIDE_TEST(qbrush_test.py)
+PYSIDE_TEST(qcolor_test.py)
+PYSIDE_TEST(qcolor_reduce_test.py)
+PYSIDE_TEST(qcursor_test.py)
+PYSIDE_TEST(qdatastream_gui_operators_test.py)
+PYSIDE_TEST(qdesktopservices_test.py)
+PYSIDE_TEST(qfont_test.py)
+PYSIDE_TEST(qfontmetrics_test.py)
+PYSIDE_TEST(qguiapplication_test.py)
+PYSIDE_TEST(qicon_test.py)
+PYSIDE_TEST(qimage_test.py)
+if(WIN32)
+ PYSIDE_TEST(qimage_win_test.py)
+endif()
+PYSIDE_TEST(qitemselection_test.py)
+PYSIDE_TEST(qpainter_test.py)
+PYSIDE_TEST(qpen_test.py)
+PYSIDE_TEST(qpdfwriter_test.py)
+PYSIDE_TEST(qpixelformat_test.py)
+PYSIDE_TEST(qpixmap_constructor.py)
+PYSIDE_TEST(qpixmap_test.py)
+PYSIDE_TEST(qpixmapcache_test.py)
+PYSIDE_TEST(qpolygonf_test.py)
+PYSIDE_TEST(qkeysequence_test.py)
+PYSIDE_TEST(qradialgradient_test.py)
+PYSIDE_TEST(qrasterwindow_test.py)
+PYSIDE_TEST(qregion_test.py)
+PYSIDE_TEST(qshortcut_test.py)
+PYSIDE_TEST(qstandarditemmodel_test.py)
+PYSIDE_TEST(qstring_qkeysequence_test.py)
+PYSIDE_TEST(qstylehints_test.py)
+PYSIDE_TEST(qtextdocument_functions.py)
+PYSIDE_TEST(qtextdocument_undoredo_test.py)
+PYSIDE_TEST(qtextdocumentwriter_test.py)
+PYSIDE_TEST(qtextline_test.py)
+PYSIDE_TEST(qtransform_test.py)
+PYSIDE_TEST(repr_test.py)
+PYSIDE_TEST(timed_app_and_patching_test.py)
diff --git a/sources/pyside6/tests/QtGui/QtGui.pyproject b/sources/pyside6/tests/QtGui/QtGui.pyproject
new file mode 100644
index 000000000..75b5e084f
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/QtGui.pyproject
@@ -0,0 +1,56 @@
+{
+ "files": ["bug_1091.py",
+ "bug_367.py",
+ "bug_493.py",
+ "bug_606.py",
+ "bug_617.py",
+ "bug_652.py",
+ "bug_660.py",
+ "bug_716.py",
+ "bug_740.py",
+ "bug_743.py",
+ "bug_785.py",
+ "bug_991.py",
+ "bug_PYSIDE-344.py",
+ "deepcopy_test.py",
+ "event_filter_test.py",
+ "float_to_int_implicit_conversion_test.py",
+ "pyside_reload_test.py",
+ "qbrush_test.py",
+ "qcolor_reduce_test.py",
+ "qcolor_test.py",
+ "qcursor_test.py",
+ "qdatastream_gui_operators_test.py",
+ "qdesktopservices_test.py",
+ "qfont_test.py",
+ "qfontmetrics_test.py",
+ "qguiapplication_test.py",
+ "qicon_test.py",
+ "qimage_test.py",
+ "qimage_win_test.py",
+ "qitemselection_test.py",
+ "qkeysequence_test.py",
+ "qpainter_test.py",
+ "qpdfwriter_test.py",
+ "qpen_test.py",
+ "qpixelformat_test.py",
+ "qpixmap_constructor.py",
+ "qpixmap_test.py",
+ "qpixmapcache_test.py",
+ "qpolygonf_test.py",
+ "qradialgradient_test.py",
+ "qrasterwindow_test.py",
+ "qregion_test.py",
+ "qshortcut_test.py",
+ "qstandarditemmodel_test.py",
+ "qstring_qkeysequence_test.py",
+ "qstylehints_test.py",
+ "qtextdocument_functions.py",
+ "qtextdocument_undoredo_test.py",
+ "qtextdocumentwriter_test.py",
+ "qtextline_test.py",
+ "qtransform_test.py",
+ "repr_test.py",
+ "timed_app_and_patching_test.py",
+ "xpm_data.py"]
+}
diff --git a/sources/pyside6/tests/QtGui/bug_1091.py b/sources/pyside6/tests/QtGui/bug_1091.py
new file mode 100644
index 000000000..9b9f35807
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_1091.py
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' unit test for BUG #1091 '''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QPainter
+
+
+class QPainterTestCase(unittest.TestCase):
+ def testIt(self):
+ self.assertTrue("PixmapFragment" in dir(QPainter))
+ self.assertTrue("drawPixmapFragments" in dir(QPainter))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_367.py b/sources/pyside6/tests/QtGui/bug_367.py
new file mode 100644
index 000000000..771fa5a4b
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_367.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 367: http://bugs.openbossa.org/show_bug.cgi?id=367'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+
+
+class BugTest(UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCase(self):
+ model = QStandardItemModel()
+ parentItem = model.invisibleRootItem()
+ for i in range(10):
+ item = QStandardItem()
+ rcount = sys.getrefcount(item)
+ parentItem.appendRow(item)
+ self.assertEqual(rcount + 1, sys.getrefcount(item))
+ parentItem = item
+
+ self.assertTrue(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_493.py b/sources/pyside6/tests/QtGui/bug_493.py
new file mode 100644
index 000000000..ba8b67bbb
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_493.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QEvent
+from PySide6.QtGui import QGuiApplication, QKeyEvent, QKeySequence
+
+
+class TestBug493(unittest.TestCase):
+
+ def testIt(self):
+ # We need a qapp otherwise Qt will crash when trying to detect the
+ # current platform
+ app = QGuiApplication([])
+ ev1 = QKeyEvent(QEvent.KeyRelease, Qt.Key_Delete, Qt.NoModifier)
+ ev2 = QKeyEvent(QEvent.KeyRelease, Qt.Key_Copy, Qt.NoModifier)
+ ks = QKeySequence.Delete
+
+ self.assertTrue(ev1.matches(ks))
+ self.assertFalse(ev2.matches(ks))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_606.py b/sources/pyside6/tests/QtGui/bug_606.py
new file mode 100644
index 000000000..80b79f640
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_606.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QVector2D, QVector3D, QVector4D, qFuzzyCompare
+from PySide6.QtGui import QColor
+
+
+class testCases(unittest.TestCase):
+ def testQVector2DToTuple(self):
+ vec = QVector2D(1, 2)
+ self.assertEqual((1, 2), vec.toTuple())
+ self.assertTrue(qFuzzyCompare(vec, vec))
+ vec2 = QVector2D(1, 3)
+ self.assertFalse(qFuzzyCompare(vec, vec2))
+
+ def testQVector3DToTuple(self):
+ vec = QVector3D(1, 2, 3)
+ self.assertEqual((1, 2, 3), vec.toTuple())
+ vec2 = QVector3D(1, 3, 4)
+ self.assertFalse(qFuzzyCompare(vec, vec2))
+
+ def testQVector4DToTuple(self):
+ vec = QVector4D(1, 2, 3, 4)
+ self.assertEqual((1, 2, 3, 4), vec.toTuple())
+ self.assertTrue(qFuzzyCompare(vec, vec))
+ vec2 = QVector4D(1, 3, 4, 5)
+ self.assertFalse(qFuzzyCompare(vec, vec2))
+
+ def testQColorToTuple(self):
+ c = QColor(0, 0, 255)
+ c.setRgb(1, 2, 3)
+ self.assertEqual((1, 2, 3, 255), c.toTuple())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_617.py b/sources/pyside6/tests/QtGui/bug_617.py
new file mode 100644
index 000000000..d90d1e754
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_617.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QEvent
+from PySide6.QtGui import QColor
+
+
+class MyEvent(QEvent):
+ def __init__(self):
+ QEvent.__init__(self, QEvent.Type(999))
+
+
+class Bug617(unittest.TestCase):
+ def testRepr(self):
+ c = QColor.fromRgb(1, 2, 3, 4)
+ s = c.spec()
+ self.assertEqual(repr(s), repr(QColor.Rgb))
+
+ def testOutOfBounds(self):
+ e = MyEvent()
+ self.assertEqual(repr(e.type()), "<Type.999: 999>")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_652.py b/sources/pyside6/tests/QtGui/bug_652.py
new file mode 100644
index 000000000..17d6c3b77
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_652.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QTextBlockUserData, QTextCursor, QTextDocument
+
+
+class MyData(QTextBlockUserData):
+ def __init__(self, data):
+ super().__init__()
+ self.data = data
+
+ def getMyNiceData(self):
+ return self.data
+
+
+class TestBug652(unittest.TestCase):
+ """Segfault when using QTextBlock::setUserData due to missing ownership transfer"""
+ def testIt(self):
+ td = QTextDocument()
+ tc = QTextCursor(td)
+ tc.insertText("Hello world")
+ heyHo = "hey ho!"
+ tc.block().setUserData(MyData(heyHo))
+ self.assertEqual(type(tc.block().userData()), MyData)
+ self.assertEqual(tc.block().userData().getMyNiceData(), heyHo)
+
+ del tc
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ tc = QTextCursor(td)
+ blk = tc.block()
+ self.assertEqual(type(blk.userData()), MyData)
+ self.assertEqual(blk.userData().getMyNiceData(), heyHo)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_660.py b/sources/pyside6/tests/QtGui/bug_660.py
new file mode 100644
index 000000000..4ab8e9f19
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_660.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QStandardItemModel, QStandardItem
+
+
+class MyItemModel(QStandardItemModel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.appendRow([QStandardItem('Item 1'),])
+
+ def mimeTypes(self):
+ mtypes = super(MyItemModel, self).mimeTypes()
+ mtypes.append('application/my-form')
+ return mtypes
+
+ def mimeData(self, indexes):
+ self.__mimedata = super(MyItemModel, self).mimeData(indexes)
+ self.__mimedata.setData('application/my-form', bytes('hi', "UTF-8"))
+ return self.__mimedata
+
+
+class TestBug660(unittest.TestCase):
+ '''QMimeData type deleted prematurely when overriding mime-type in QStandardItemModel drag and drop'''
+ def testIt(self):
+ model = MyItemModel()
+ model.mimeData([model.index(0, 0)]) # if it doesn't raise an exception it's all right!
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_716.py b/sources/pyside6/tests/QtGui/bug_716.py
new file mode 100644
index 000000000..90d78ea89
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_716.py
@@ -0,0 +1,20 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import Qt, QPersistentModelIndex, QStringListModel
+
+if __name__ == '__main__':
+ stringListModel = QStringListModel(['one', 'two'])
+ idx = stringListModel.index(1, 0)
+ persistentModelIndex = QPersistentModelIndex(idx)
+ stringListModel.data(persistentModelIndex, Qt.DisplayRole)
+
diff --git a/sources/pyside6/tests/QtGui/bug_740.py b/sources/pyside6/tests/QtGui/bug_740.py
new file mode 100644
index 000000000..ece314cc8
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_740.py
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QSize
+from PySide6.QtGui import QBitmap, QImage
+
+
+class TestQBitmap(UsesQApplication):
+ def testFromDataMethod(self):
+ dataBits = bytes('\x38\x28\x38\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\xfe\xfe\x7c\x7c\x38\x38\x10\x10', "UTF-8")
+ bim = QBitmap.fromData(QSize(8, 48), dataBits, QImage.Format_Mono) # missing function
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_743.py b/sources/pyside6/tests/QtGui/bug_743.py
new file mode 100644
index 000000000..a870e4bf1
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_743.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QMatrix4x4
+
+
+class TestQMatrix(unittest.TestCase):
+ def testOperator(self):
+ m = QMatrix4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
+ v = 1
+ for x in range(4):
+ for y in range(4):
+ self.assertEqual(m[x, y], v)
+ v += 1
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_785.py b/sources/pyside6/tests/QtGui/bug_785.py
new file mode 100644
index 000000000..04425f063
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_785.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QItemSelection
+from PySide6.QtGui import QStandardItemModel, QStandardItem
+
+
+class Bug324(unittest.TestCase):
+ def testOperators(self):
+ model = QStandardItemModel()
+ for i in range(100):
+ model.appendRow(QStandardItem(f"Item: {i}"))
+
+ first = model.index(0, 0)
+ second = model.index(10, 0)
+ third = model.index(20, 0)
+ fourth = model.index(30, 0)
+
+ sel = QItemSelection(first, second)
+ sel2 = QItemSelection()
+ sel2.select(third, fourth)
+
+ sel3 = sel + sel2 # check operator +
+ self.assertEqual(len(sel3), 2)
+ sel4 = sel
+ sel4 += sel2 # check operator +=
+ self.assertEqual(len(sel4), 2)
+ self.assertEqual(sel4, sel3)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_991.py b/sources/pyside6/tests/QtGui/bug_991.py
new file mode 100644
index 000000000..e74adc198
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_991.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtGui import QPen, QBrush
+
+
+class TestBug991 (unittest.TestCase):
+ def testReprFunction(self):
+ reprPen = repr(QPen())
+ self.assertTrue(reprPen.startswith("<PySide6.QtGui.QPen"))
+ reprBrush = repr(QBrush())
+ self.assertTrue(reprBrush.startswith("<PySide6.QtGui.QBrush"))
+ reprObject = repr(QObject())
+ self.assertTrue(reprObject.startswith("<PySide6.QtCore.QObject"))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/bug_PYSIDE-344.py b/sources/pyside6/tests/QtGui/bug_PYSIDE-344.py
new file mode 100644
index 000000000..6519eef61
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/bug_PYSIDE-344.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for PYSIDE-344, imul/idiv are used instead of mul/div, modifying the argument passed in'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QMargins, QPoint, QPointF, QSize, QSizeF
+from PySide6.QtGui import (QMatrix4x4, QQuaternion, QTransform, QVector2D,
+ QVector3D, QVector4D)
+
+
+def testList():
+ return [QPoint(10, 10), QPointF(1, 1), QSize(10, 10), QSizeF(1, 1),
+ QMargins(10, 10, 10, 10),
+ QTransform(), QMatrix4x4(),
+ QVector2D(1, 1), QVector3D(1, 1, 1), QVector4D(1, 1, 1, 1),
+ QQuaternion(1, 1, 1, 1)]
+
+
+class TestMulDiv(unittest.TestCase):
+
+ def testMultiplication(self):
+ fails = ''
+ for a in testList():
+ mul = (a * 2)
+ if a == mul:
+ fails += ' ' + type(a).__name__
+ self.assertEqual(fails, '')
+
+ def testDivision(self):
+ fails = ''
+ for a in testList():
+ div = (a * 2)
+ if a == div:
+ fails += ' ' + type(a).__name__
+ self.assertEqual(fails, '')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/deepcopy_test.py b/sources/pyside6/tests/QtGui/deepcopy_test.py
new file mode 100644
index 000000000..9a13eb485
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/deepcopy_test.py
@@ -0,0 +1,140 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+from copy import deepcopy
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPoint
+from PySide6.QtGui import QMatrix2x2, QMatrix2x3, QMatrix2x4
+from PySide6.QtGui import QMatrix3x2, QMatrix3x3, QMatrix3x4
+from PySide6.QtGui import QMatrix4x2, QMatrix4x3, QMatrix4x4
+from PySide6.QtGui import QVector2D, QVector3D, QVector4D
+from PySide6.QtGui import QColor, QTransform, QKeySequence, QQuaternion
+from PySide6.QtGui import QPolygon
+
+
+class DeepCopyHelper:
+ def testCopy(self):
+ copy = deepcopy([self.original])[0]
+ self.assertTrue(copy is not self.original)
+ self.assertEqual(copy, self.original)
+
+
+class DeepCopyColorHelperF:
+ def testCopy(self):
+ copy = deepcopy([self.original])[0]
+ self.assertTrue(copy is not self.original)
+ self.assertEqual(copy.spec(), self.original.spec())
+ # impossible to compare float point
+ # self.assertEqual(copy, self.original)
+
+
+class QColorDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QColor("red")
+
+
+class QColorRGBDeepCopy(DeepCopyColorHelperF, unittest.TestCase):
+ def setUp(self):
+ self.original = QColor.fromRgbF(0.2, 0.3, 0.4, 0.5)
+
+
+class QColorHSLDeepCopy(DeepCopyColorHelperF, unittest.TestCase):
+ def setUp(self):
+ self.original = QColor.fromHslF(0.2, 0.3, 0.4, 0.5)
+
+
+class QColorHSVDeepCopy(DeepCopyColorHelperF, unittest.TestCase):
+ def setUp(self):
+ self.original = QColor.fromHsvF(0.2, 0.3, 0.4, 0.5)
+
+
+class QColorCMYKDeepCopy(DeepCopyColorHelperF, unittest.TestCase):
+ def setUp(self):
+ self.original = QColor.fromCmykF(0.2, 0.3, 0.4, 0.5, 0.6)
+
+
+class QTransformDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QTransform(1, 2, 3, 4, 5, 6, 7, 8, 9)
+
+
+class QKeySequenceDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QKeySequence("Ctrl+P")
+
+
+class QQuaternionDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QQuaternion(1, 2, 3, 4)
+
+
+class QVector2DDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QVector2D(1, 2)
+
+
+class QVector3DDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QVector3D(1, 2, 3)
+
+
+class QVector4DDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QVector4D(1, 2, 3, 4)
+
+
+class QPolygonDeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QPolygon([QPoint(1, 2), QPoint(3, 4), QPoint(5, 6)])
+
+
+# Avoid these tests until get gcc fixed
+# Related bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247
+"""
+class QMatrix2x2DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix2x2([1, 2, 3, 4])
+
+class QMatrix2x3DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix2x3([1, 2, 3, 4, 5, 6])
+
+class QMatrix2x4DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix2x4([1, 2, 3, 4, 5, 6, 7, 8])
+
+class QMatrix3x2DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix3x2([1, 2, 3, 4, 5, 6])
+
+class QMatrix3x3DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix3x3([1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+class QMatrix3x4DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix3x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
+
+class QMatrix4x2DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix4x2([1, 2, 3, 4, 5, 6, 7, 8])
+
+class QMatrix4x3DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix4x3([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
+
+class QMatrix4x4DeepCopy(DeepCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix4x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
+"""
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/event_filter_test.py b/sources/pyside6/tests/QtGui/event_filter_test.py
new file mode 100644
index 000000000..01d8fbc02
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/event_filter_test.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QObject, QEvent
+from PySide6.QtGui import QWindow
+
+
+class MyFilter(QObject):
+ def eventFilter(self, obj, event):
+ if event.type() == QEvent.KeyPress:
+ pass
+ return QObject.eventFilter(self, obj, event)
+
+
+class EventFilter(UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCount(self):
+ o = QObject()
+ filt = MyFilter()
+ o.installEventFilter(filt)
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ o.installEventFilter(filt)
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ o.removeEventFilter(filt)
+ self.assertEqual(sys.getrefcount(o), 2)
+
+ def testObjectDestructorOrder(self):
+ w = QWindow()
+ filt = MyFilter()
+ filt.app = self.app
+ w.installEventFilter(filt)
+ w.show()
+ w.close()
+ w = None
+ self.assertTrue(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/float_to_int_implicit_conversion_test.py b/sources/pyside6/tests/QtGui/float_to_int_implicit_conversion_test.py
new file mode 100644
index 000000000..ba438f8e0
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/float_to_int_implicit_conversion_test.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QImage'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QImage, qRgb
+
+from helper.usesqapplication import UsesQApplication
+
+
+class SetPixelFloat(UsesQApplication):
+ '''Test case for calling setPixel with float as argument'''
+
+ def setUp(self):
+ # Acquire resources
+ super(SetPixelFloat, self).setUp()
+ self.color = qRgb(255, 0, 0)
+ self.image = QImage(200, 200, QImage.Format_RGB32)
+
+ def tearDown(self):
+ # Release resources
+ del self.color
+ del self.image
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(SetPixelFloat, self).tearDown()
+
+ def testFloat(self):
+ # QImage.setPixel(float, float, color) - Implicit conversion
+ self.image.setPixel(3.14, 4.2, self.color)
+ self.assertEqual(self.image.pixel(3.14, 4.2), self.color)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/pyside_reload_test.py b/sources/pyside6/tests/QtGui/pyside_reload_test.py
new file mode 100644
index 000000000..1ac65f709
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/pyside_reload_test.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import importlib
+import importlib.util
+import os
+import shutil
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+
+orig_path = os.path.join(os.path.dirname(__file__))
+workdir = os.getcwd()
+src = os.path.normpath(os.path.join(orig_path, '..', 'QtWidgets', 'test_module_template.py'))
+dst = os.path.join(workdir, 'test_module.py')
+shutil.copyfile(src, dst)
+sys.path.append(workdir)
+
+
+def reload_module(moduleName):
+ importlib.reload(moduleName)
+
+
+def increment_module_value():
+ modfile = open(dst, 'a')
+ modfile.write('Sentinel.value += 1' + os.linesep)
+ modfile.flush()
+ modfile.close()
+ if not sys.dont_write_bytecode:
+ import importlib.util
+ cacheFile = importlib.util.cache_from_source(dst)
+ os.remove(cacheFile)
+
+
+class TestModuleReloading(unittest.TestCase):
+
+ def testModuleReloading(self):
+ '''Test module reloading with on-the-fly modifications.'''
+
+ import test_module
+ self.assertEqual(test_module.Sentinel.value, 10)
+
+ increment_module_value()
+ reload_module(sys.modules['test_module'])
+ self.assertEqual(test_module.Sentinel.value, 11)
+
+ reload_module(sys.modules['test_module'])
+ self.assertEqual(test_module.Sentinel.value, 11)
+
+ increment_module_value()
+ reload_module(sys.modules['test_module'])
+ self.assertEqual(test_module.Sentinel.value, 12)
+
+
+if __name__ == "__main__":
+ unittest.main()
+
+
diff --git a/sources/pyside6/tests/QtGui/qbrush_test.py b/sources/pyside6/tests/QtGui/qbrush_test.py
new file mode 100644
index 000000000..69262328b
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qbrush_test.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QBrush'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QColor, QBrush, QConicalGradient
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Constructor(UsesQApplication):
+ '''Test case for constructor of QBrush'''
+
+ def testQColor(self):
+ # QBrush(QColor) constructor
+ color = QColor('black')
+ obj = QBrush(color)
+ self.assertEqual(obj.color(), color)
+
+ obj = QBrush(Qt.blue)
+ self.assertEqual(obj.color(), Qt.blue)
+
+ def testGradient(self):
+ """Test type discovery on class hierarchies with non-virtual
+ destructors by specifying a polymorphic-id-expression without
+ polymorphic-name-function."""
+ gradient = QConicalGradient()
+ brush = QBrush(gradient)
+ self.assertEqual(type(brush.gradient()), type(gradient))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qcolor_reduce_test.py b/sources/pyside6/tests/QtGui/qcolor_reduce_test.py
new file mode 100644
index 000000000..609951be6
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qcolor_reduce_test.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import pickle
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QColor
+
+
+class TestQColor (unittest.TestCase):
+ def reduceColor(self, c):
+ p = pickle.dumps(c)
+ c2 = pickle.loads(p)
+ self.assertEqual(c.spec(), c2.spec())
+ self.assertEqual(c, c2)
+
+ def testReduceEmpty(self):
+ self.reduceColor(QColor())
+
+ def testReduceString(self):
+ self.reduceColor(QColor('gray'))
+
+ def testReduceRGB(self):
+ self.reduceColor(QColor.fromRgbF(0.1, 0.2, 0.3, 0.4))
+
+ def testReduceCMYK(self):
+ self.reduceColor(QColor.fromCmykF(0.1, 0.2, 0.3, 0.4, 0.5))
+
+ def testReduceHsl(self):
+ self.reduceColor(QColor.fromHslF(0.1, 0.2, 0.3, 0.4))
+
+ def testReduceHsv(self):
+ self.reduceColor(QColor.fromHsvF(0.1, 0.2, 0.3, 0.4))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qcolor_test.py b/sources/pyside6/tests/QtGui/qcolor_test.py
new file mode 100644
index 000000000..bbd558f10
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qcolor_test.py
@@ -0,0 +1,111 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import colorsys
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QColor, QColorConstants
+
+
+class QColorGetTest(unittest.TestCase):
+
+ def setUp(self):
+ self.color = QColor(20, 40, 60, 80)
+
+ def testGetRgb(self):
+ self.assertEqual(self.color.getRgb(), (20, 40, 60, 80))
+
+ def testGetHslF(self):
+ hls = colorsys.rgb_to_hls(20.0 / 255, 40.0 / 255, 60.0 / 255)
+ hsla = hls[0], hls[2], hls[1], self.color.alphaF()
+ for x, y in zip(self.color.getHslF(), hsla): # Due to rounding problems
+ self.assertTrue(x - y < 1 / 100000.0)
+
+ def testGetHsv(self):
+ hsv = colorsys.rgb_to_hsv(20.0 / 255, 40.0 / 255, 60.0 / 255)
+ hsva = int(hsv[0] * 360.0), int(hsv[1] * 255), int(hsv[2] * 256), self.color.alpha()
+ self.assertEqual(self.color.getHsv(), hsva)
+
+ def testGetCmyk(self): # not supported by colorsys
+ self.assertEqual(self.color.getCmyk(), (170, 85, 0, 195, 80))
+
+ def testGetCmykF(self): # not supported by colorsys
+ for x, y in zip(self.color.getCmykF(), (170 / 255.0, 85 / 255.0, 0, 195 / 255.0, 80 / 255.0)):
+ self.assertTrue(x - y < 1 / 10000.0)
+
+
+class QColorQRgbConstructor(unittest.TestCase):
+ '''QColor(QRgb) constructor'''
+ # Affected by bug #170 - QColor(QVariant) coming before QColor(uint)
+ # in overload sorting
+
+ def testBasic(self):
+ '''QColor(QRgb)'''
+ color = QColor(255, 0, 0)
+ # QRgb format #AARRGGBB
+ rgb = 0x00FF0000
+ self.assertEqual(QColor(rgb), color)
+
+
+class QColorEqualGlobalColor(unittest.TestCase):
+
+ def testEqualGlobalColor(self):
+ '''QColor == Qt::GlobalColor'''
+ self.assertEqual(QColor(255, 0, 0), Qt.red)
+
+
+class QColorCopy(unittest.TestCase):
+
+ def testDeepCopy(self):
+ '''QColor deepcopy'''
+
+ from copy import deepcopy
+
+ original = QColor(0, 0, 255)
+ copy = deepcopy([original])[0]
+
+ self.assertTrue(original is not copy)
+ self.assertEqual(original, copy)
+ del original
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(copy, QColor(0, 0, 255))
+
+ def testEmptyCopy(self):
+ from copy import deepcopy
+
+ original = QColor()
+ copy = deepcopy([original])[0]
+ self.assertTrue(original is not copy)
+ self.assertEqual(original, copy)
+ del original
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(copy, QColor())
+
+
+class QColorRepr(unittest.TestCase):
+ def testReprFunction(self):
+ # QColorConstants are disabled for MSVC/5.15, fixme: Check Qt 6
+ c = QColorConstants.Yellow if sys.platform != 'win32' else QColor(100, 120, 200)
+ c2 = eval(c.__repr__())
+ self.assertEqual(c, c2)
+
+ def testStrFunction(self):
+ c = QColor('red')
+ c2 = eval(c.__str__())
+ self.assertEqual(c, c2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qcursor_test.py b/sources/pyside6/tests/QtGui/qcursor_test.py
new file mode 100644
index 000000000..1494fe370
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qcursor_test.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test for Bug 630 - Fails to resolve overload for QCursor(QBitmap, QBitmap, int, int)
+http://bugs.openbossa.org/show_bug.cgi?id=630
+'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QBitmap, QCursor, QPixmap
+from helper.usesqapplication import UsesQApplication
+
+
+class TestQCursor(UsesQApplication):
+ def testQCursorConstructor(self):
+ bmp = QBitmap(16, 16)
+ cursor = QCursor(bmp, bmp, 16, 16)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qdatastream_gui_operators_test.py b/sources/pyside6/tests/QtGui/qdatastream_gui_operators_test.py
new file mode 100644
index 000000000..f2c86abf7
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qdatastream_gui_operators_test.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDataStream, QByteArray, QIODevice, Qt
+from PySide6.QtGui import QPixmap, QColor
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QPixmapQDatastream(UsesQApplication):
+ '''QDataStream <<>> QPixmap'''
+
+ def setUp(self):
+ super(QPixmapQDatastream, self).setUp()
+ self.source_pixmap = QPixmap(100, 100)
+ # PYSIDE-1533: Use Qt.transparent to force Format_ARGB32_Premultiplied
+ # when converting to QImage in any case.
+ self.source_pixmap.fill(Qt.transparent)
+ self.output_pixmap = QPixmap()
+ self.buffer = QByteArray()
+ self.read_stream = QDataStream(self.buffer, QIODevice.ReadOnly)
+ self.write_stream = QDataStream(self.buffer, QIODevice.WriteOnly)
+
+ def testStream(self):
+ self.write_stream << self.source_pixmap
+
+ self.read_stream >> self.output_pixmap
+
+ image = self.output_pixmap.toImage()
+ pixel = image.pixel(10, 10)
+ self.assertEqual(pixel, QColor(Qt.transparent).rgba())
+ self.assertEqual(self.source_pixmap.toImage(), image)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qdesktopservices_test.py b/sources/pyside6/tests/QtGui/qdesktopservices_test.py
new file mode 100644
index 000000000..8d578152d
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qdesktopservices_test.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QDesktopServices'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QDesktopServices
+from PySide6.QtCore import QUrl
+
+
+class QDesktopServicesTest(unittest.TestCase):
+ def testOpenUrl(self):
+ # At the bare minimum check that they return false for invalid url's
+ url = QUrl()
+ self.assertEqual(QDesktopServices.openUrl(url), False)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qfont_test.py b/sources/pyside6/tests/QtGui/qfont_test.py
new file mode 100644
index 000000000..f81d47ec6
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qfont_test.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QFont
+from helper.usesqapplication import UsesQApplication
+
+
+class QFontTest(UsesQApplication):
+
+ def testStringConstruction(self):
+ """PYSIDE-1685: Test that passing str to QFont works after addding
+ QFont(QStringList) by qtbase/d8602ce58b6ef268be84b9aa0166b0c3fa6a96e8"""
+ font_name = 'Times Roman'
+ font = QFont(font_name)
+ families = font.families()
+ self.assertEqual(len(families), 1)
+ self.assertEqual(families[0], font_name)
+
+ font = QFont([font_name])
+ families = font.families()
+ self.assertEqual(len(families), 1)
+ self.assertEqual(families[0], font_name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qfontmetrics_test.py b/sources/pyside6/tests/QtGui/qfontmetrics_test.py
new file mode 100644
index 000000000..98c4c8f96
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qfontmetrics_test.py
@@ -0,0 +1,215 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests for inject codes and modifications on QFontMetrics
+ and QFontMetricsF'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QFont, QFontMetrics, QFontMetricsF
+from PySide6.QtCore import QRect, QRectF, Qt, QSize, QSizeF
+from helper.usesqapplication import UsesQApplication
+
+
+class QFontMetricsTest(UsesQApplication):
+ '''Base class for QFontMetrics tests'''
+
+ def setUp(self):
+ super(QFontMetricsTest, self).setUp()
+ self.font = QFont()
+ self.metrics = QFontMetrics(self.font)
+
+ def tearDown(self):
+ del self.metrics
+ del self.font
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QFontMetricsTest, self).tearDown()
+
+
+class BoundingRectTest(QFontMetricsTest):
+ '''Tests for QFontMetrics.boundingRect inject code'''
+
+ def testIntDefault(self):
+ '''QFontMetrics.boundingRect(int, int, int, int, ...) - default args'''
+ rect = self.metrics.boundingRect(0, 0, 0, 0,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT')
+ self.assertTrue(isinstance(rect, QRect))
+
+ def testIntWithArg(self):
+ '''QFontMetrics.boundingRect(int, int, int, int, ...) - single arg'''
+ rect = self.metrics.boundingRect(0, 0, 0, 0,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 2)
+ self.assertTrue(isinstance(rect, QRect))
+
+ def testIntWithFull(self):
+ '''QFontMetrics.boundingRect(int, int, int, int, ...) - all argss'''
+ rect = self.metrics.boundingRect(0, 0, 0, 0,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20, [1, 2, 3, 4, 5])
+ self.assertTrue(isinstance(rect, QRect))
+
+ def testIntTypeError(self):
+ '''QFontMetrics.boundingRect(int, int, int, int, ...) - type error'''
+ self.assertRaises(TypeError, self.metrics.boundingRect, 0, 0, 0, 0,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20, ['aaaa', 'ase'])
+
+ def testQRectDefault(self):
+ '''QFontMetrics.boundingRect(QRect, ...) - default args'''
+ arg = QRect(0, 0, 100, 200)
+ rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT')
+ self.assertTrue(isinstance(rect, QRect))
+
+ def testQRectWithArg(self):
+ '''QFontMetrics.boundingRect(QRect, ...) - only tabstops'''
+ arg = QRect(0, 0, 100, 200)
+ rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 2)
+ self.assertTrue(isinstance(rect, QRect))
+
+ def testQRectWithFull(self):
+ '''QFontMetrics.boundingRect(QRect, ...) - all arguments'''
+ arg = QRect(0, 0, 100, 200)
+ rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20,
+ [1, 2, 3, 4, 5])
+ self.assertTrue(isinstance(rect, QRect))
+
+ def testQRectTypeError(self):
+ '''QFontMetrics.boundingRect(QRect, ...) - type error'''
+ arg = QRect(0, 0, 100, 200)
+ self.assertRaises(TypeError, self.metrics.boundingRect, arg,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20, ['aaaa', 'ase'])
+
+
+class SizeTest(QFontMetricsTest):
+ '''Tests for QFontMetrics.size inject code'''
+
+ def testDefault(self):
+ '''QFontMetrics.size - default arguments'''
+ size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine,
+ 'PySide by INdT')
+ self.assertTrue(isinstance(size, QSize))
+
+ def testWithTabStops(self):
+ '''QFontMetrics.size - only tabstops'''
+ size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine,
+ 'PySide by INdT', 2)
+ self.assertTrue(isinstance(size, QSize))
+
+ def testFull(self):
+ '''QFontMetrics.size - all arguments'''
+ size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine,
+ 'PySide by INdT', 2, [1, 2, 3, 4])
+ self.assertTrue(isinstance(size, QSize))
+
+ def testTypeError(self):
+ '''QFontMetrics.size - type error'''
+ self.assertRaises(TypeError, self.metrics.size,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20, ['aaaa', 'ase'])
+
+
+class QFontMetricsFTest(UsesQApplication):
+ '''Base class for QFontMetrics tests'''
+
+ def setUp(self):
+ super(QFontMetricsFTest, self).setUp()
+ self.font = QFont()
+ self.metrics = QFontMetricsF(self.font)
+
+ def tearDown(self):
+ del self.metrics
+ del self.font
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QFontMetricsFTest, self).tearDown()
+
+
+class FBoundingRectTest(QFontMetricsFTest):
+ '''Tests for QFontMetricsF.boundingRect inject code'''
+
+ def testQRectDefault(self):
+ '''QFontMetricsF.boundingRect(QRectF, ...) - default args'''
+ arg = QRectF(0, 0, 100, 200)
+ rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT')
+ self.assertTrue(isinstance(rect, QRectF))
+
+ def testQRectWithArg(self):
+ '''QFontMetricsF.boundingRect(QRectF, ...) - only tabstops'''
+ arg = QRectF(0, 0, 100, 200)
+ rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 2)
+ self.assertTrue(isinstance(rect, QRectF))
+
+ def testQRectWithFull(self):
+ '''QFontMetricsF.boundingRect(QRectF, ...) - all arguments'''
+ arg = QRectF(0, 0, 100, 200)
+ rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20,
+ [1, 2, 3, 4, 5])
+ self.assertTrue(isinstance(rect, QRectF))
+
+ def testQRectTypeError(self):
+ '''QFontMetricsF.boundingRect(QRectF, ...) - type error'''
+ arg = QRectF(0, 0, 100, 200)
+ self.assertRaises(TypeError, self.metrics.boundingRect, arg,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20, ['aaaa', 'ase'])
+
+
+class FSizeTest(QFontMetricsFTest):
+ '''Tests for QFontMetricsF.size inject code'''
+
+ def testDefault(self):
+ '''QFontMetricsF.size - default arguments'''
+ size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine,
+ 'PySide by INdT')
+ self.assertTrue(isinstance(size, QSizeF))
+
+ def testWithTabStops(self):
+ '''QFontMetricsF.size - only tabstops'''
+ size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine,
+ 'PySide by INdT', 2)
+ self.assertTrue(isinstance(size, QSizeF))
+
+ def testFull(self):
+ '''QFontMetricsF.size - all arguments'''
+ size = self.metrics.size(Qt.TextExpandTabs | Qt.TextSingleLine,
+ 'PySide by INdT', 2, [1, 2, 3, 4])
+ self.assertTrue(isinstance(size, QSizeF))
+
+ def testTypeError(self):
+ '''QFontMetricsF.size - type error'''
+ self.assertRaises(TypeError, self.metrics.size,
+ Qt.TextExpandTabs | Qt.AlignLeft,
+ 'PySide by INdT', 20, ['aaaa', 'ase'])
+
+
+class QCharTest(QFontMetricsFTest):
+
+ def testBoundingRect(self):
+ retCh = self.metrics.boundingRectChar('a')
+ self.assertEqual(type(retCh), QRectF)
+
+ def testWith(self):
+ retCh = self.metrics.horizontalAdvance('a')
+ self.assertTrue(retCh > 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qguiapplication_test.py b/sources/pyside6/tests/QtGui/qguiapplication_test.py
new file mode 100644
index 000000000..a3d0942aa
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qguiapplication_test.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QGuiApplication
+
+
+class TestQGuiApplication(unittest.TestCase):
+ def testNoArguments(self):
+ app = QGuiApplication()
+ self.assertIsInstance(app, QGuiApplication)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qicon_test.py b/sources/pyside6/tests/QtGui/qicon_test.py
new file mode 100644
index 000000000..18ef3d815
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qicon_test.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.timedqguiapplication import TimedQGuiApplication
+from PySide6.QtGui import QIcon
+
+
+class QIconCtorWithNoneTest(TimedQGuiApplication):
+ '''Test made by seblin, see Bug #944: http://bugs.pyside.org/show_bug.cgi?id=944'''
+
+ def testQIconCtorWithNone(self):
+ icon = QIcon(None)
+ pixmap = icon.pixmap(48, 48)
+ self.app.exec()
+
+
+PIX_PATH = os.fspath(Path(__file__).resolve().parents[2]
+ / "doc/tutorials/basictutorial/icons.png")
+
+
+class QIconAddPixmapTest(TimedQGuiApplication):
+ '''PYSIDE-1669: check that addPixmap works'''
+
+ def testQIconSetPixmap(self):
+ icon = QIcon()
+ icon.addPixmap(PIX_PATH)
+ sizes = icon.availableSizes()
+ self.assertTrue(sizes)
+
+ def testQIconSetPixmapPathlike(self):
+ icon = QIcon()
+ pix_path = Path(PIX_PATH)
+ icon.addPixmap(pix_path)
+ sizes = icon.availableSizes()
+ self.assertTrue(sizes)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qimage_test.py b/sources/pyside6/tests/QtGui/qimage_test.py
new file mode 100644
index 000000000..5912bf318
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qimage_test.py
@@ -0,0 +1,56 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QImage'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QImage
+from helper.usesqapplication import UsesQApplication
+from xpm_data import xpm
+
+
+class QImageTest(UsesQApplication):
+ '''Test case for calling setPixel with float as argument'''
+
+ def testQImageStringBuffer(self):
+ '''Test if the QImage signatures receiving string buffers exist.'''
+ file = Path(__file__).resolve().parent / 'sample.png'
+ self.assertTrue(file.is_file())
+ img0 = QImage(file)
+
+ # btw let's test the bits() method
+ img1 = QImage(img0.bits(), img0.width(), img0.height(), img0.format())
+ img1.setColorSpace(img0.colorSpace())
+ self.assertEqual(img0, img1)
+ img2 = QImage(img0.bits(), img0.width(), img0.height(), img0.bytesPerLine(), img0.format())
+ img2.setColorSpace(img0.colorSpace())
+ self.assertEqual(img0, img2)
+
+ ## test scanLine method
+ data1 = img0.scanLine(0)
+ data2 = img1.scanLine(0)
+ self.assertEqual(data1, data2)
+
+ def testEmptyBuffer(self):
+ img = QImage(bytes('', "UTF-8"), 100, 100, QImage.Format_ARGB32)
+
+ def testEmptyStringAsBuffer(self):
+ img = QImage(bytes('', "UTF-8"), 100, 100, QImage.Format_ARGB32)
+
+ def testXpmConstructor(self):
+ img = QImage(xpm)
+ self.assertFalse(img.isNull())
+ self.assertEqual(img.width(), 27)
+ self.assertEqual(img.height(), 22)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qimage_win_test.py b/sources/pyside6/tests/QtGui/qimage_win_test.py
new file mode 100644
index 000000000..2d9cb96f1
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qimage_win_test.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QImage/Windows'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QImage
+from helper.usesqapplication import UsesQApplication
+
+
+def create_image():
+ result = QImage(20, 20, QImage.Format_RGB32)
+ result.fill(Qt.white)
+ return result
+
+
+class QImageWinTest(UsesQApplication):
+
+ def test_to_hbitmap(self):
+ """Test conversion to/from a Windows HBITMAP."""
+
+ image = create_image()
+ hbitmap = image.toHBITMAP()
+ self.assertTrue(hbitmap > 0)
+
+ image2 = QImage.fromHBITMAP(hbitmap)
+ image2.setColorSpace(image.colorSpace())
+ self.assertEqual(image, image2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qitemselection_test.py b/sources/pyside6/tests/QtGui/qitemselection_test.py
new file mode 100644
index 000000000..179bff745
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qitemselection_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QItemSelection
+from PySide6.QtGui import QStandardItemModel
+
+
+class QItemSelectionTest(UsesQApplication):
+ def testLen(self):
+ model = QStandardItemModel(2, 2)
+ model.insertRow(0)
+ model.insertRow(1)
+ model.insertColumn(0)
+ model.insertColumn(1)
+ selection = QItemSelection(model.index(0, 0), model.index(1, 1))
+ self.assertEqual(len(selection), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qkeysequence_test.py b/sources/pyside6/tests/QtGui/qkeysequence_test.py
new file mode 100644
index 000000000..3d72fb50a
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qkeysequence_test.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QKeySequence, qt_set_sequence_auto_mnemonic
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QKeySequenceTest(UsesQApplication):
+
+ def testGetItemOperator(self):
+ # bug #774
+ # PYSIDE-1735: Remapped from Qt.Modifier to Qt.KeyboardModifier
+ # Note that Qt.(Keyboard)?Modifier will be no longer IntFlag.
+ ks = QKeySequence(Qt.ShiftModifier, Qt.ControlModifier, Qt.Key_P, Qt.Key_R)
+ self.assertEqual(ks[0].keyboardModifiers(), Qt.ShiftModifier)
+ self.assertEqual(ks[1].keyboardModifiers(), Qt.ControlModifier)
+ self.assertEqual(ks[2].key(), Qt.Key_P)
+ self.assertEqual(ks[3].key(), Qt.Key_R)
+
+ def testAutoMnemonic(self):
+ qt_set_sequence_auto_mnemonic(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qpainter_test.py b/sources/pyside6/tests/QtGui/qpainter_test.py
new file mode 100644
index 000000000..103b91ad6
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpainter_test.py
@@ -0,0 +1,115 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QPainter, QLinearGradient, QImage
+from PySide6.QtCore import QLine, QLineF, QPoint, QPointF, QRect, QRectF, Qt
+
+
+try:
+ import numpy as np
+ HAVE_NUMPY = True
+except ModuleNotFoundError:
+ HAVE_NUMPY = False
+
+
+class QPainterDrawText(UsesQApplication):
+ def setUp(self):
+ super(QPainterDrawText, self).setUp()
+ self.image = QImage(32, 32, QImage.Format_ARGB32)
+ self.painter = QPainter(self.image)
+ self.text = 'teste!'
+
+ def tearDown(self):
+ del self.text
+ self.painter.end()
+ del self.painter
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QPainterDrawText, self).tearDown()
+
+ def testDrawText(self):
+ # bug #254
+ rect = self.painter.drawText(100, 100, 100, 100,
+ Qt.AlignCenter | Qt.TextWordWrap,
+ self.text)
+ self.assertTrue(isinstance(rect, QRect))
+
+ def testDrawTextWithRect(self):
+ # bug #225
+ rect = QRect(100, 100, 100, 100)
+ newRect = self.painter.drawText(rect, Qt.AlignCenter | Qt.TextWordWrap,
+ self.text)
+
+ self.assertTrue(isinstance(newRect, QRect))
+
+ def testDrawTextWithRectF(self):
+ '''QPainter.drawText(QRectF, ... ,QRectF*) inject code'''
+ rect = QRectF(100, 52.3, 100, 100)
+ newRect = self.painter.drawText(rect, Qt.AlignCenter | Qt.TextWordWrap,
+ self.text)
+
+ self.assertTrue(isinstance(newRect, QRectF))
+
+ def testDrawOverloads(self):
+ '''Calls QPainter.drawLines overloads, if something is
+ wrong Exception and chaos ensues. Bug #395'''
+ self.painter.drawLines([QLine(QPoint(0, 0), QPoint(1, 1))])
+ self.painter.drawLines([QPoint(0, 0), QPoint(1, 1)])
+ self.painter.drawLines([QPointF(0, 0), QPointF(1, 1)])
+ self.painter.drawLines([QLineF(QPointF(0, 0), QPointF(1, 1))])
+ self.painter.drawPoints([QPoint(0, 0), QPoint(1, 1)])
+ self.painter.drawPoints([QPointF(0, 0), QPointF(1, 1)])
+ self.painter.drawConvexPolygon([QPointF(10.0, 80.0),
+ QPointF(20.0, 10.0),
+ QPointF(80.0, 30.0),
+ QPointF(90.0, 70.0)])
+ self.painter.drawConvexPolygon([QPoint(10.0, 80.0),
+ QPoint(20.0, 10.0),
+ QPoint(80.0, 30.0),
+ QPoint(90.0, 70.0)])
+ self.painter.drawPolygon([QPointF(10.0, 80.0),
+ QPointF(20.0, 10.0),
+ QPointF(80.0, 30.0),
+ QPointF(90.0, 70.0)])
+ self.painter.drawPolygon([QPoint(10.0, 80.0),
+ QPoint(20.0, 10.0),
+ QPoint(80.0, 30.0),
+ QPoint(90.0, 70.0)])
+ self.painter.drawPolyline([QPointF(10.0, 80.0),
+ QPointF(20.0, 10.0),
+ QPointF(80.0, 30.0),
+ QPointF(90.0, 70.0)])
+ self.painter.drawPolyline([QPoint(10.0, 80.0),
+ QPoint(20.0, 10.0),
+ QPoint(80.0, 30.0),
+ QPoint(90.0, 70.0)])
+ if HAVE_NUMPY:
+ x = np.array([10.0, 20.0, 80.0, 90.0])
+ y = np.array([80.0, 10.0, 30.0, 70.0])
+ self.painter.drawPointsNp(x, y)
+
+
+class SetBrushWithOtherArgs(UsesQApplication):
+ '''Using qpainter.setBrush with args other than QBrush'''
+
+ def testSetBrushGradient(self):
+ image = QImage(32, 32, QImage.Format_ARGB32)
+ with QPainter(image) as painter:
+ gradient = QLinearGradient(0, 0, 0, 0)
+ painter.setBrush(gradient)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qpdfwriter_test.py b/sources/pyside6/tests/QtGui/qpdfwriter_test.py
new file mode 100644
index 000000000..2dca2aca2
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpdfwriter_test.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QPageLayout, QPageSize, QPdfWriter, QTextDocument
+from PySide6.QtCore import QDir, QMarginsF, QTemporaryFile
+
+
+class QPdfWriterTest(UsesQApplication):
+
+ def testWrite(self):
+ temporaryFile = QTemporaryFile(QDir.tempPath() + "/pdfwriter_test_XXXXXX.pdf")
+ self.assertTrue(temporaryFile.open())
+ pdfWriter = QPdfWriter(temporaryFile)
+ pdfWriter.setPageLayout(QPageLayout(QPageSize(QPageSize.A4), QPageLayout.Portrait, QMarginsF(10, 10, 10, 10)))
+ doc = QTextDocument("Some text")
+ doc.print_(pdfWriter)
+ temporaryFile.close()
+ self.assertTrue(temporaryFile.size() > 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qpen_test.py b/sources/pyside6/tests/QtGui/qpen_test.py
new file mode 100644
index 000000000..7e8604606
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpen_test.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import Qt, QTimer
+from PySide6.QtGui import QPen, QPainter, QRasterWindow
+
+
+class Painting(QRasterWindow):
+ def __init__(self):
+ super().__init__()
+ self.penFromEnum = None
+ self.penFromInteger = None
+
+ def paintEvent(self, event):
+ with QPainter(self) as painter:
+ painter.setPen(Qt.NoPen)
+ self.penFromEnum = painter.pen()
+ intVal = Qt.NoPen.value
+ painter.setPen(intVal)
+ self.penFromInteger = painter.pen()
+ QTimer.singleShot(20, self.close)
+
+
+class QPenTest(UsesQApplication):
+
+ def testCtorWithCreatedEnums(self):
+ '''A simple case of QPen creation using created enums.'''
+ width = 0
+ style = Qt.PenStyle(0)
+ cap = Qt.PenCapStyle(0)
+ join = Qt.PenJoinStyle(0)
+ pen = QPen(Qt.blue, width, style, cap, join)
+
+ def testSetPenWithPenStyleEnum(self):
+ '''Calls QPainter.setPen with both enum and integer. Bug #511.'''
+ w = Painting()
+ w.show()
+ w.setTitle("qpen_test")
+ self.app.exec()
+ self.assertEqual(w.penFromEnum.style(), Qt.NoPen)
+ self.assertEqual(w.penFromInteger.style(), Qt.SolidLine)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qpixelformat_test.py b/sources/pyside6/tests/QtGui/qpixelformat_test.py
new file mode 100644
index 000000000..869d15952
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpixelformat_test.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit test for QPixelFormat'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QSize, Qt
+from PySide6.QtGui import QColor, QImage, QPixelFormat, qPixelFormatRgba
+
+
+class QPixelFormatTest(UsesQApplication):
+ def test(self):
+ image = QImage(QSize(200, 200), QImage.Format_ARGB32)
+ image.fill(QColor(Qt.red))
+ pixelFormat = image.pixelFormat()
+ print(pixelFormat.greenSize())
+ self.assertEqual(pixelFormat.alphaSize(), 8)
+ self.assertEqual(pixelFormat.redSize(), 8)
+ self.assertEqual(pixelFormat.greenSize(), 8)
+ self.assertEqual(pixelFormat.blueSize(), 8)
+ self.assertEqual(pixelFormat.bitsPerPixel(), 32)
+
+ def testHelpers(self):
+ format = qPixelFormatRgba(8, 8, 8, 8, QPixelFormat.UsesAlpha,
+ QPixelFormat.AtBeginning, QPixelFormat.Premultiplied,
+ QPixelFormat.UnsignedByte)
+ self.assertEqual(format.redSize(), 8)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qpixmap_constructor.py b/sources/pyside6/tests/QtGui/qpixmap_constructor.py
new file mode 100644
index 000000000..dd658af52
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpixmap_constructor.py
@@ -0,0 +1,260 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QPixmap
+
+from helper.usesqapplication import UsesQApplication
+
+xpm = [
+ "27 22 206 2",
+ " c None",
+ ". c #FEFEFE",
+ "+ c #FFFFFF",
+ "@ c #F9F9F9",
+ "# c #ECECEC",
+ "$ c #D5D5D5",
+ "% c #A0A0A0",
+ "& c #767676",
+ "* c #525252",
+ "= c #484848",
+ "- c #4E4E4E",
+ "; c #555555",
+ "> c #545454",
+ ", c #5A5A5A",
+ "' c #4B4B4B",
+ ") c #4A4A4A",
+ "! c #4F4F4F",
+ "~ c #585858",
+ "{ c #515151",
+ "] c #4C4C4C",
+ "^ c #B1B1B1",
+ "/ c #FCFCFC",
+ "( c #FDFDFD",
+ "_ c #C1C1C1",
+ ": c #848484",
+ "< c #616161",
+ "[ c #5E5E5E",
+ "} c #CECECE",
+ "| c #E2E2E2",
+ "1 c #E4E4E4",
+ "2 c #DFDFDF",
+ "3 c #D2D2D2",
+ "4 c #D8D8D8",
+ "5 c #D4D4D4",
+ "6 c #E6E6E6",
+ "7 c #F1F1F1",
+ "8 c #838383",
+ "9 c #8E8E8E",
+ "0 c #8F8F8F",
+ "a c #CBCBCB",
+ "b c #CCCCCC",
+ "c c #E9E9E9",
+ "d c #F2F2F2",
+ "e c #EDEDED",
+ "f c #B5B5B5",
+ "g c #A6A6A6",
+ "h c #ABABAB",
+ "i c #BBBBBB",
+ "j c #B0B0B0",
+ "k c #EAEAEA",
+ "l c #6C6C6C",
+ "m c #BCBCBC",
+ "n c #F5F5F5",
+ "o c #FAFAFA",
+ "p c #B6B6B6",
+ "q c #F3F3F3",
+ "r c #CFCFCF",
+ "s c #FBFBFB",
+ "t c #CDCDCD",
+ "u c #DDDDDD",
+ "v c #999999",
+ "w c #F0F0F0",
+ "x c #2B2B2B",
+ "y c #C3C3C3",
+ "z c #A4A4A4",
+ "A c #D7D7D7",
+ "B c #E7E7E7",
+ "C c #6E6E6E",
+ "D c #9D9D9D",
+ "E c #BABABA",
+ "F c #AEAEAE",
+ "G c #898989",
+ "H c #646464",
+ "I c #BDBDBD",
+ "J c #CACACA",
+ "K c #2A2A2A",
+ "L c #212121",
+ "M c #B7B7B7",
+ "N c #F4F4F4",
+ "O c #737373",
+ "P c #828282",
+ "Q c #4D4D4D",
+ "R c #000000",
+ "S c #151515",
+ "T c #B2B2B2",
+ "U c #D6D6D6",
+ "V c #D3D3D3",
+ "W c #2F2F2F",
+ "X c #636363",
+ "Y c #A1A1A1",
+ "Z c #BFBFBF",
+ "` c #E0E0E0",
+ " . c #6A6A6A",
+ ".. c #050505",
+ "+. c #A3A3A3",
+ "@. c #202020",
+ "#. c #5F5F5F",
+ "$. c #B9B9B9",
+ "%. c #C7C7C7",
+ "&. c #D0D0D0",
+ "*. c #3E3E3E",
+ "=. c #666666",
+ "-. c #DBDBDB",
+ ";. c #424242",
+ ">. c #C2C2C2",
+ ",. c #1A1A1A",
+ "'. c #2C2C2C",
+ "). c #F6F6F6",
+ "!. c #AAAAAA",
+ "~. c #DCDCDC",
+ "{. c #2D2D2D",
+ "]. c #2E2E2E",
+ "^. c #A7A7A7",
+ "/. c #656565",
+ "(. c #333333",
+ "_. c #464646",
+ ":. c #C4C4C4",
+ "<. c #B8B8B8",
+ "[. c #292929",
+ "}. c #979797",
+ "|. c #EFEFEF",
+ "1. c #909090",
+ "2. c #8A8A8A",
+ "3. c #575757",
+ "4. c #676767",
+ "5. c #C5C5C5",
+ "6. c #7A7A7A",
+ "7. c #797979",
+ "8. c #989898",
+ "9. c #EEEEEE",
+ "0. c #707070",
+ "a. c #C8C8C8",
+ "b. c #111111",
+ "c. c #AFAFAF",
+ "d. c #474747",
+ "e. c #565656",
+ "f. c #E3E3E3",
+ "g. c #494949",
+ "h. c #5B5B5B",
+ "i. c #222222",
+ "j. c #353535",
+ "k. c #D9D9D9",
+ "l. c #0A0A0A",
+ "m. c #858585",
+ "n. c #E5E5E5",
+ "o. c #0E0E0E",
+ "p. c #9A9A9A",
+ "q. c #6F6F6F",
+ "r. c #868686",
+ "s. c #060606",
+ "t. c #1E1E1E",
+ "u. c #E8E8E8",
+ "v. c #A5A5A5",
+ "w. c #0D0D0D",
+ "x. c #030303",
+ "y. c #272727",
+ "z. c #131313",
+ "A. c #1F1F1F",
+ "B. c #757575",
+ "C. c #F7F7F7",
+ "D. c #414141",
+ "E. c #080808",
+ "F. c #6B6B6B",
+ "G. c #313131",
+ "H. c #C0C0C0",
+ "I. c #C9C9C9",
+ "J. c #0B0B0B",
+ "K. c #232323",
+ "L. c #434343",
+ "M. c #3D3D3D",
+ "N. c #282828",
+ "O. c #7C7C7C",
+ "P. c #252525",
+ "Q. c #3A3A3A",
+ "R. c #F8F8F8",
+ "S. c #1B1B1B",
+ "T. c #949494",
+ "U. c #3B3B3B",
+ "V. c #242424",
+ "W. c #383838",
+ "X. c #6D6D6D",
+ "Y. c #818181",
+ "Z. c #939393",
+ "`. c #9E9E9E",
+ " + c #929292",
+ ".+ c #7D7D7D",
+ "++ c #ADADAD",
+ "@+ c #DADADA",
+ "#+ c #919191",
+ "$+ c #E1E1E1",
+ "%+ c #BEBEBE",
+ "&+ c #ACACAC",
+ "*+ c #9C9C9C",
+ "=+ c #B3B3B3",
+ "-+ c #808080",
+ ";+ c #A8A8A8",
+ ">+ c #393939",
+ ",+ c #747474",
+ "'+ c #7F7F7F",
+ ")+ c #D1D1D1",
+ "!+ c #606060",
+ "~+ c #5C5C5C",
+ "{+ c #686868",
+ "]+ c #7E7E7E",
+ "^+ c #787878",
+ "/+ c #595959",
+ ". . . + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / . . + + ",
+ ". ( + _ : < [ & } | 1 2 $ 3 4 5 3 6 7 + + 8 9 + . + . ",
+ ". + 0 9 a ( 3 a b c d e c f g h i g j $ k + l m + . + ",
+ "+ 2 8 n o p | ( q r s . # t + + + u ^ v e w + x + + + ",
+ "+ y z . @ A k B 7 n + ( s | p 8 C D 2 E 4 + + F G + . ",
+ "# H I $ J G K L - M N . 2 O P Q R R S T U s s V W j + ",
+ "X Y Z @ o ` _ g ...+.( 4 @.#.m G $.%.7 &.X *.=.-.;.&.",
+ "Q >.C ,.'.} e + ).!.k + . + + . ~.{.> ].x f 7 ^./.k (.",
+ "_.:.4 @ <.[.}.|.1.2.+ + + >.} 4 B + ( @ _ 3.4.5.6.r 7.",
+ "3.8.9.~ 0.+ a.Q b.+ + c.d.#.=.$ |.b #.e.z ^ ; ^. .f.g.",
+ "-.h.+ i.S M + # p j.% n 9.5.k.H l.m.V ^.n.o.M + M p.q.",
+ "7 r.N s.1.R t.<.|.| u.v.~ w.x.E + s y.z.A.B.C.+ 5 D.q ",
+ ").p.2 E.0.9 F.%.O {._ @.+ + i { [ i.G.H.P I.+ s q.} + ",
+ ").p.6 J.R b.K.L.M.A.! b.g.K [.R M k + N.I + + >.O.+ . ",
+ ").8.9.N.P...R R R R E.t.W n.+ Q.R.6 @.| + . + S.+ + . ",
+ "n }.w T.U.B.<.i.@ Y + + U.+ c u V.= B B 7 u.W.c + . + ",
+ "N T.# + }.X.Y.,.8.F.8 Z.[.`. +.+}.4 ++@+O.< ~.+ ( . + ",
+ "d #+1 + _ ~.u.$+b $.y @+| $+%+I.&+k.h W +.9.+ ( . + . ",
+ "w 0 |.*+. >.<.=+++++p a.p -+;+5.k.>+,+@ + . . + . + + ",
+ "q '+9.R.^ I.t b %.I.)+4 $+n.I.,+ .|.+ . . . + . + + + ",
+ ". p !+( + + + + + + E 0. .-+8.f.+ + . . + + . + + + + ",
+ ". ( A ~+{+]+^+l > /+D f.c q . + . . + + . + + + + + + "
+]
+
+
+class QStringSequenceTest(UsesQApplication):
+ def testQPixmapConstructor(self):
+ pixmap1 = QPixmap(xpm)
+ self.assertFalse(pixmap1.isNull())
+ self.assertEqual(pixmap1.width(), 27)
+ self.assertEqual(pixmap1.height(), 22)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qpixmap_test.py b/sources/pyside6/tests/QtGui/qpixmap_test.py
new file mode 100644
index 000000000..b80ae2ad5
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpixmap_test.py
@@ -0,0 +1,67 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QColor, QPixmap
+from PySide6.QtCore import QFile, QIODevice, QObject, QSize, Qt
+
+
+class QPixmapTest(UsesQApplication):
+ def testQVariantConstructor(self):
+ obj = QObject()
+ pixmap = QPixmap()
+ obj.setProperty('foo', pixmap)
+ self.assertEqual(type(obj.property('foo')), QPixmap)
+
+ def testQSizeConstructor(self):
+ pixmap = QPixmap(QSize(10, 20))
+ self.assertTrue(pixmap.size().height(), 20)
+
+ def testQStringConstructor(self):
+ pixmap = QPixmap("Testing!")
+
+ def testQPixmapLoadFromDataWithQFile(self):
+ f = QFile(os.path.join(os.path.dirname(__file__), 'sample.png'))
+ self.assertTrue(f.open(QIODevice.ReadOnly))
+ data = f.read(f.size())
+ f.close()
+ pixmap = QPixmap()
+ self.assertTrue(pixmap.loadFromData(data))
+
+ def testQPixmapLoadFromDataWithPython(self):
+ data = open(os.path.join(os.path.dirname(__file__), 'sample.png'), 'rb').read()
+ pixmap = QPixmap()
+ self.assertTrue(pixmap.loadFromData(data))
+
+
+class QPixmapToImage(UsesQApplication):
+
+ def testFilledImage(self):
+ '''QPixmap.fill + toImage + image.pixel'''
+ pixmap = QPixmap(100, 200)
+ pixmap.fill(Qt.red) # Default Qt.white
+
+ self.assertEqual(pixmap.height(), 200)
+ self.assertEqual(pixmap.width(), 100)
+
+ image = pixmap.toImage()
+
+ self.assertEqual(image.height(), 200)
+ self.assertEqual(image.width(), 100)
+
+ pixel = image.pixel(10, 10)
+ self.assertEqual(pixel, QColor(Qt.red).rgba())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qpixmapcache_test.py b/sources/pyside6/tests/QtGui/qpixmapcache_test.py
new file mode 100644
index 000000000..2ecb439d3
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpixmapcache_test.py
@@ -0,0 +1,56 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QPixmapCache, QPixmap
+
+
+class QPixmapCacheTest(UsesQApplication):
+
+ def testWithString(self):
+ pm1 = QPixmap()
+ ok = QPixmapCache.find('img', pm1)
+ self.assertFalse(ok)
+
+ self.assertEqual(QPixmapCache.find('img'), None)
+
+ pm2 = QPixmap()
+ ok = QPixmapCache.insert('img', pm2)
+ self.assertTrue(ok)
+
+ pm3 = QPixmap()
+ ok = QPixmapCache.find('img', pm3)
+ self.assertTrue(ok)
+ b1 = QPixmapCache.find('img').toImage().bits()
+ b2 = pm3.toImage().bits()
+ self.assertEqual(QPixmapCache.find('img').toImage().bits(), pm3.toImage().bits())
+
+ def testWithKey(self):
+ pm1 = QPixmap()
+ ok = QPixmapCache.find(QPixmapCache.Key(), pm1)
+ self.assertFalse(ok)
+
+ self.assertEqual(QPixmapCache.find(QPixmapCache.Key()), None)
+
+ pm2 = QPixmap()
+ key = QPixmapCache.insert(pm2)
+
+ pm3 = QPixmap()
+ ok = QPixmapCache.find(key, pm3)
+ self.assertTrue(ok)
+
+ self.assertEqual(QPixmapCache.find(key).toImage().bits(), pm3.toImage().bits())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qpolygonf_test.py b/sources/pyside6/tests/QtGui/qpolygonf_test.py
new file mode 100644
index 000000000..8a283fddc
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qpolygonf_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPoint, QPointF
+from PySide6.QtGui import QPolygon, QPolygonF
+
+
+class QPolygonFNotIterableTest(unittest.TestCase):
+ """Test if a QPolygonF is iterable"""
+
+ def testIt(self):
+ points = []
+ for i in range(0, 4):
+ points.append(QPointF(float(i), float(i)))
+
+ p = QPolygonF(points)
+ self.assertEqual(len(p), 4)
+
+ i = 0
+ for point in p:
+ self.assertEqual(int(point.x()), i)
+ self.assertEqual(int(point.y()), i)
+ i += 1
+
+ def testPolygonShiftOperators(self):
+ p = QPolygon()
+ self.assertEqual(len(p), 0)
+ p << QPoint(10, 20) << QPoint(20, 30) << [QPoint(20, 30), QPoint(40, 50)]
+ self.assertEqual(len(p), 4)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qradialgradient_test.py b/sources/pyside6/tests/QtGui/qradialgradient_test.py
new file mode 100644
index 000000000..ebab42b15
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qradialgradient_test.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QRadialGradient
+from PySide6.QtCore import QPointF
+
+
+class QRadialGradientConstructor(unittest.TestCase):
+ def _compare(self, qptf, tpl):
+ self.assertEqual((qptf.x(), qptf.y()), tpl)
+
+ def _assertValues(self, grad):
+ self._compare(grad.center(), (1.0, 2.0))
+ self._compare(grad.focalPoint(), (3.0, 4.0))
+ self.assertEqual(grad.radius(), 5.0)
+
+ def testAllInt(self):
+ grad = QRadialGradient(1, 2, 5, 3, 4)
+ self._assertValues(grad)
+
+ def testQPointF(self):
+ grad = QRadialGradient(QPointF(1, 2), 5, QPointF(3, 4))
+ self._assertValues(grad)
+
+ def testSetQPointF(self):
+ grad = QRadialGradient()
+ grad.setCenter(QPointF(1, 2))
+ self._compare(grad.center(), (1.0, 2.0))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qrasterwindow_test.py b/sources/pyside6/tests/QtGui/qrasterwindow_test.py
new file mode 100644
index 000000000..4920902d5
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qrasterwindow_test.py
@@ -0,0 +1,77 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit test for QBackingStore, QRasterWindow and QStaticText'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QPoint, QRect, QSize, QTimer, Qt
+from PySide6.QtGui import (QColor, QPainter, QRasterWindow, QStaticText,
+ QTextCursor, QTextDocument, QAbstractTextDocumentLayout)
+
+
+# Window using convenience class QRasterWindow
+class StaticTextRasterWindow(QRasterWindow):
+ def __init__(self):
+ super().__init__()
+ self.text = QStaticText("QRasterWindow")
+
+ def paintEvent(self, event):
+ clientRect = QRect(QPoint(0, 0), self.size())
+ with QPainter(self) as painter:
+ painter.fillRect(clientRect, QColor(Qt.red))
+ painter.drawStaticText(QPoint(10, 10), self.text)
+
+
+class TextDocumentWindow(QRasterWindow):
+ """PYSIDE-2252, drawing with QAbstractTextDocumentLayout.PaintContext"""
+
+ def __init__(self):
+ super().__init__()
+ self.m_document = QTextDocument()
+ self.m_document.setPlainText("bla bla")
+
+ def paintEvent(self, event):
+ with QPainter(self) as painter:
+ clientRect = QRect(QPoint(0, 0), self.size())
+ painter.fillRect(clientRect, QColor(Qt.white))
+ ctx = QAbstractTextDocumentLayout.PaintContext()
+ ctx.clip = clientRect
+
+ sel = QAbstractTextDocumentLayout.Selection()
+ cursor = QTextCursor(self.m_document)
+ cursor.movePosition(QTextCursor.Start)
+ cursor.movePosition(QTextCursor.NextWord, QTextCursor.KeepAnchor)
+ sel.cursor = cursor
+ sel.format.setForeground(Qt.red)
+ ctx.selections = [sel]
+
+ self.m_document.documentLayout().draw(painter, ctx)
+
+
+class QRasterWindowTest(UsesQApplication):
+ def test(self):
+ rasterWindow = StaticTextRasterWindow()
+ rasterWindow.setFramePosition(QPoint(100, 100))
+ rasterWindow.resize(QSize(400, 400))
+ rasterWindow.show()
+
+ rasterWindow2 = TextDocumentWindow()
+ rasterWindow2.setFramePosition(rasterWindow.frameGeometry().topRight() + QPoint(20, 0))
+ rasterWindow2.resize(QSize(400, 400))
+ rasterWindow2.show()
+
+ QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qregion_test.py b/sources/pyside6/tests/QtGui/qregion_test.py
new file mode 100644
index 000000000..df14fc3e0
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qregion_test.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QRegion
+from PySide6.QtCore import QPoint, QRect, QSize
+from helper.usesqapplication import UsesQApplication
+
+
+class QRegionTest(UsesQApplication):
+
+ def testFunctionUnit(self):
+ r = QRegion(0, 0, 10, 10)
+ r2 = QRegion(5, 5, 10, 10)
+
+ ru = r.united(r2)
+ self.assertTrue(ru.contains(QPoint(0, 0)))
+ self.assertTrue(ru.contains(QPoint(5, 5)))
+ self.assertTrue(ru.contains(QPoint(10, 10)))
+ self.assertTrue(ru.contains(QPoint(14, 14)))
+
+ def testSequence(self):
+ region = QRegion()
+ region += QRect(QPoint(0, 0), QSize(10, 10))
+ region += QRect(QPoint(10, 0), QSize(20, 20))
+ self.assertEqual(len(region), 2)
+ for r in region:
+ pass
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qshortcut_test.py b/sources/pyside6/tests/QtGui/qshortcut_test.py
new file mode 100644
index 000000000..f2650589a
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qshortcut_test.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test the QShortcut constructor'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QTimer
+from PySide6.QtGui import QGuiApplication, QKeySequence, QShortcut, QWindow
+
+
+class Foo(QWindow):
+ def __init__(self):
+ super().__init__()
+ self.ok = False
+ self.copy = False
+
+ def slot_of_foo(self):
+ self.ok = True
+
+ def slot_of_copy(self):
+ self.copy = True
+
+
+class MyShortcut(QShortcut):
+ def __init__(self, keys, wdg, slot):
+ QShortcut.__init__(self, keys, wdg, slot)
+
+ def emit_signal(self):
+ self.activated.emit()
+
+
+class QAppPresence(unittest.TestCase):
+
+ def testQShortcut(self):
+ self.qapp = QGuiApplication([])
+ f = Foo()
+
+ self.sc = MyShortcut(QKeySequence(Qt.Key_Return), f, f.slot_of_foo)
+ self.scstd = MyShortcut(QKeySequence.Copy, f, f.slot_of_copy)
+ QTimer.singleShot(0, self.init)
+ self.qapp.exec()
+ self.assertEqual(f.ok, True)
+ self.assertEqual(f.copy, True)
+
+ def init(self):
+ self.sc.emit_signal()
+ self.scstd.emit_signal()
+ self.qapp.quit()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qstandarditemmodel_test.py b/sources/pyside6/tests/QtGui/qstandarditemmodel_test.py
new file mode 100644
index 000000000..55aca9113
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qstandarditemmodel_test.py
@@ -0,0 +1,85 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtGui import QStandardItemModel, QStandardItem
+from shiboken6 import Shiboken
+from helper.usesqapplication import UsesQApplication
+
+
+class QStandardItemModelTest(UsesQApplication):
+
+ def setUp(self):
+ super(QStandardItemModelTest, self).setUp()
+ self.parent = QObject()
+ self.model = QStandardItemModel(0, 3, self.parent)
+
+ def tearDown(self):
+ del self.parent
+ del self.model
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QStandardItemModelTest, self).tearDown()
+
+ def testInsertRow(self):
+ # bug #227
+ self.model.insertRow(0)
+
+ def testClear(self):
+
+ model = QStandardItemModel()
+ root = model.invisibleRootItem()
+ model.clear()
+ self.assertFalse(Shiboken.isValid(root))
+
+
+class QStandardItemModelRef(UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCount(self):
+ model = QStandardItemModel(5, 5)
+ items = []
+ for r in range(5):
+ row = []
+ for c in range(5):
+ row.append(QStandardItem(f"{r},{c}"))
+ self.assertEqual(sys.getrefcount(row[c]), 2)
+
+ model.insertRow(r, row)
+
+ for c in range(5):
+ ref_after = sys.getrefcount(row[c])
+ # check if the ref count was incremented after insertRow
+ self.assertEqual(ref_after, 3)
+
+ items.append(row)
+ row = None
+
+ for r in range(3):
+ my_row = model.takeRow(0)
+ my_row = None
+ for c in range(5):
+ # only rest 1 reference
+ self.assertEqual(sys.getrefcount(items[r][c]), 2)
+
+ my_i = model.item(0, 0)
+ # ref(my_i) + parent_ref + items list ref
+ self.assertEqual(sys.getrefcount(my_i), 4)
+
+ model.clear()
+ # ref(my_i)
+ self.assertEqual(sys.getrefcount(my_i), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qstring_qkeysequence_test.py b/sources/pyside6/tests/QtGui/qstring_qkeysequence_test.py
new file mode 100644
index 000000000..f68374263
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qstring_qkeysequence_test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests conversions of QString to and from QKeySequence.'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtGui import QAction, QKeySequence
+
+
+class QStringQKeySequenceTest(UsesQApplication):
+ '''Tests conversions of QString to and from QKeySequence.'''
+
+ def testQStringFromQKeySequence(self):
+ '''Creates a QString from a QKeySequence.'''
+ keyseq = 'Ctrl+A'
+ a = QKeySequence(keyseq)
+ self.assertEqual(a, keyseq)
+
+ def testPythonStringAsQKeySequence(self):
+ '''Passes a Python string to an argument expecting a QKeySequence.'''
+ keyseq = 'Ctrl+A'
+ action = QAction(None)
+ action.setShortcut(keyseq)
+ shortcut = action.shortcut()
+ self.assertTrue(isinstance(shortcut, QKeySequence))
+ self.assertEqual(shortcut.toString(), keyseq)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qstylehints_test.py b/sources/pyside6/tests/QtGui/qstylehints_test.py
new file mode 100644
index 000000000..d2b21d30d
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qstylehints_test.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit test for QStyleHints'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QStyleHints
+
+
+class QStyleHintsTest(UsesQApplication):
+ def test(self):
+ styleHints = self.app.styleHints()
+ self.assertTrue(styleHints.startDragDistance() > 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qtextdocument_functions.py b/sources/pyside6/tests/QtGui/qtextdocument_functions.py
new file mode 100644
index 000000000..2ac72df56
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qtextdocument_functions.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QPageRanges, Qt
+
+
+class QTextDocumentFunctions(unittest.TestCase):
+
+ def testFunctions(self):
+ self.assertFalse(Qt.mightBeRichText('bla'))
+ self.assertTrue(Qt.mightBeRichText('<html><head/><body><p>bla</p></body></html>'))
+ html = Qt.convertFromPlainText("A & B", Qt.WhiteSpaceNormal)
+ self.assertEqual(html, '<p>A &amp; B</p>')
+
+
+class QPageRangesTest(unittest.TestCase):
+ """PYSIDE-2237: Test that field QPageRanges.Range.from is properly mangled."""
+
+ def test(self):
+ pr = QPageRanges()
+ pr.addPage(1)
+ r0 = pr.toRangeList()[0]
+ self.assertEqual(r0.from_, 1)
+ self.assertEqual(r0.to, 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qtextdocument_undoredo_test.py b/sources/pyside6/tests/QtGui/qtextdocument_undoredo_test.py
new file mode 100644
index 000000000..b74c6704f
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qtextdocument_undoredo_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QTextDocument, QTextCursor
+
+
+class QTextDocumentTest(unittest.TestCase):
+
+ def testUndoRedo(self):
+ text = 'foobar'
+ doc = QTextDocument(text)
+
+ self.assertFalse(doc.isRedoAvailable())
+ self.assertTrue(doc.isUndoAvailable())
+ self.assertEqual(doc.toPlainText(), text)
+
+ cursor = QTextCursor(doc)
+ doc.undo(cursor)
+
+ self.assertTrue(doc.isRedoAvailable())
+ self.assertFalse(doc.isUndoAvailable())
+ self.assertEqual(doc.toPlainText(), '')
+
+ doc.redo(cursor)
+
+ self.assertFalse(doc.isRedoAvailable())
+ self.assertTrue(doc.isUndoAvailable())
+ self.assertEqual(doc.toPlainText(), text)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qtextdocumentwriter_test.py b/sources/pyside6/tests/QtGui/qtextdocumentwriter_test.py
new file mode 100644
index 000000000..4f72b98e7
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qtextdocumentwriter_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QTextDocumentWriter, QTextDocument
+from PySide6.QtCore import QBuffer
+
+
+class QTextDocumentWriterTest(unittest.TestCase):
+
+ def testWrite(self):
+ text = 'foobar'
+ doc = QTextDocument(text)
+ b = QBuffer()
+ b.open(QBuffer.ReadWrite)
+ writer = QTextDocumentWriter(b, bytes("plaintext", "UTF-8"))
+ writer.write(doc)
+ b.close()
+ self.assertEqual(b.buffer(), text)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/qtextline_test.py b/sources/pyside6/tests/QtGui/qtextline_test.py
new file mode 100644
index 000000000..c34a4c98a
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qtextline_test.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QTextLayout, QTextOption
+from helper.usesqapplication import UsesQApplication
+
+
+class QTextLineTest(UsesQApplication):
+
+ def testCursorToX(self):
+ textLayout = QTextLayout()
+ textLayout.beginLayout()
+ line = textLayout.createLine()
+ self.assertTrue(line.isValid())
+ x, cursorPos = line.cursorToX(0)
+ self.assertEqual(type(x), float)
+ self.assertEqual(type(cursorPos), int)
+ x, cursorPos = line.cursorToX(1)
+ self.assertEqual(type(x), float)
+ self.assertEqual(type(cursorPos), int)
+
+ def testTextOption(self):
+ """PYSIDE-2088, large enum values causing MSVC issues."""
+ v = QTextOption.IncludeTrailingSpaces | QTextOption.ShowTabsAndSpaces
+ self.assertEqual(v.value, 2147483649)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/qtransform_test.py b/sources/pyside6/tests/QtGui/qtransform_test.py
new file mode 100644
index 000000000..dc51a74e6
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/qtransform_test.py
@@ -0,0 +1,90 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPointF
+from PySide6.QtGui import QTransform, QPolygonF, QPolygonF, QQuaternion, QVector3D
+
+
+class QTransformTest(unittest.TestCase):
+
+ def testMap(self):
+ transform = QTransform()
+ values = (10.0, 20.0)
+ tx, ty = transform.map(*values)
+ self.assertTrue(isinstance(tx, float))
+ self.assertTrue(isinstance(ty, float))
+ self.assertEqual((tx, ty), values)
+
+ def testquadToQuad(self):
+ q1 = QPolygonF()
+ q1.append(QPointF(10.0, 10.0))
+ q1.append(QPointF(20.0, 10.0))
+ q1.append(QPointF(10.0, -10.0))
+ q1.append(QPointF(20.0, -10.0))
+
+ q2 = QPolygonF()
+ q2.append(QPointF(20.0, 20.0))
+ q2.append(QPointF(30.0, 20.0))
+ q2.append(QPointF(20.0, -20.0))
+ q2.append(QPointF(30.0, -20.0))
+
+ t1 = QTransform()
+ r1 = QTransform.quadToQuad(q1, q2, t1)
+ r2 = QTransform.quadToQuad(q1, q2)
+
+ self.assertTrue(r1)
+ self.assertTrue(r2)
+
+ self.assertEqual(t1, r2)
+
+ def testquadToSquare(self):
+ q1 = QPolygonF()
+ q1.append(QPointF(10.0, 10.0))
+ q1.append(QPointF(20.0, 10.0))
+ q1.append(QPointF(10.0, -10.0))
+ q1.append(QPointF(20.0, -10.0))
+
+ t1 = QTransform()
+ r1 = QTransform.quadToSquare(q1, t1)
+ r2 = QTransform.quadToSquare(q1)
+
+ self.assertTrue(r1)
+ self.assertTrue(r2)
+
+ self.assertEqual(t1, r2)
+
+ def testsquareToQuad(self):
+ q1 = QPolygonF()
+ q1.append(QPointF(10.0, 10.0))
+ q1.append(QPointF(20.0, 10.0))
+ q1.append(QPointF(10.0, -10.0))
+ q1.append(QPointF(20.0, -10.0))
+
+ t1 = QTransform()
+ r1 = QTransform.squareToQuad(q1, t1)
+ r2 = QTransform.squareToQuad(q1)
+
+ self.assertTrue(r1)
+ self.assertTrue(r2)
+
+ self.assertEqual(t1, r2)
+
+ def testQQuaternion(self):
+ """Test return tuples."""
+ q = QQuaternion(1, 1, 1, 1)
+ self.assertEqual(len(q.getAxisAndAngle()), 2)
+ self.assertEqual(len(q.getEulerAngles()), 3)
+
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtGui/repr_test.py b/sources/pyside6/tests/QtGui/repr_test.py
new file mode 100644
index 000000000..2858e7175
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/repr_test.py
@@ -0,0 +1,96 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+from PySide6.QtCore import QPoint
+from PySide6.QtGui import QMatrix2x2, QMatrix2x3, QMatrix2x4
+from PySide6.QtGui import QMatrix3x2, QMatrix3x3, QMatrix3x4
+from PySide6.QtGui import QMatrix4x2, QMatrix4x3, QMatrix4x4
+from PySide6.QtGui import QVector2D, QVector3D, QVector4D
+from PySide6.QtGui import QColor, QTransform, QKeySequence, QQuaternion
+from PySide6.QtGui import QPolygon
+
+
+class ReprCopyHelper:
+ def testCopy(self):
+ copy = eval(self.original.__repr__())
+ self.assertTrue(copy is not self.original)
+ self.assertEqual(copy, self.original)
+
+
+class QTransformReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QTransform(1, 2, 3, 4, 5, 6, 7, 8, 9)
+
+
+class QQuaternionReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QQuaternion(1, 2, 3, 4)
+
+
+class QVector2DReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QVector2D(1, 2)
+
+
+class QVector3DReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QVector3D(1, 2, 3)
+
+
+class QVector4DReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QVector4D(1, 2, 3, 4)
+
+
+# Avoid these tests until get gcc fixed
+# Related bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247
+"""
+class QMatrix2x2ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix2x2([1, 2, 3, 4])
+
+class QMatrix2x3ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix2x3([1, 2, 3, 4, 5, 6])
+
+class QMatrix2x4ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix2x4([1, 2, 3, 4, 5, 6, 7, 8])
+
+class QMatrix3x2ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix3x2([1, 2, 3, 4, 5, 6])
+
+class QMatrix3x3ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix3x3([1, 2, 3, 4, 5, 6, 7, 8, 9])
+
+class QMatrix3x4ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix3x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
+
+class QMatrix4x2ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix4x2([1, 2, 3, 4, 5, 6, 7, 8])
+
+class QMatrix4x3ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix4x3([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
+
+class QMatrix4x4ReprCopy(ReprCopyHelper, unittest.TestCase):
+ def setUp(self):
+ self.original = QMatrix4x4([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])
+"""
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/sample.png b/sources/pyside6/tests/QtGui/sample.png
new file mode 100644
index 000000000..60450f0dc
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/sample.png
Binary files differ
diff --git a/sources/pyside6/tests/QtGui/timed_app_and_patching_test.py b/sources/pyside6/tests/QtGui/timed_app_and_patching_test.py
new file mode 100644
index 000000000..6e9a661ce
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/timed_app_and_patching_test.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths # noqa: E402
+init_test_paths(False)
+
+from helper.timedqguiapplication import TimedQGuiApplication
+
+
+class TestTimedApp(TimedQGuiApplication):
+ '''Simple test case for TimedQGuiApplication'''
+
+ def testFoo(self):
+ # Simple test of TimedQGuiApplication
+ self.app.exec()
+
+# deprecated.py is no longer needed.
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtGui/xpm_data.py b/sources/pyside6/tests/QtGui/xpm_data.py
new file mode 100644
index 000000000..3603d8190
--- /dev/null
+++ b/sources/pyside6/tests/QtGui/xpm_data.py
@@ -0,0 +1,237 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test data for QImage'''
+
+
+xpm = [
+ "27 22 206 2",
+ " c None",
+ ". c #FEFEFE",
+ "+ c #FFFFFF",
+ "@ c #F9F9F9",
+ "# c #ECECEC",
+ "$ c #D5D5D5",
+ "% c #A0A0A0",
+ "& c #767676",
+ "* c #525252",
+ "= c #484848",
+ "- c #4E4E4E",
+ "; c #555555",
+ "> c #545454",
+ ", c #5A5A5A",
+ "' c #4B4B4B",
+ ") c #4A4A4A",
+ "! c #4F4F4F",
+ "~ c #585858",
+ "{ c #515151",
+ "] c #4C4C4C",
+ "^ c #B1B1B1",
+ "/ c #FCFCFC",
+ "( c #FDFDFD",
+ "_ c #C1C1C1",
+ ": c #848484",
+ "< c #616161",
+ "[ c #5E5E5E",
+ "} c #CECECE",
+ "| c #E2E2E2",
+ "1 c #E4E4E4",
+ "2 c #DFDFDF",
+ "3 c #D2D2D2",
+ "4 c #D8D8D8",
+ "5 c #D4D4D4",
+ "6 c #E6E6E6",
+ "7 c #F1F1F1",
+ "8 c #838383",
+ "9 c #8E8E8E",
+ "0 c #8F8F8F",
+ "a c #CBCBCB",
+ "b c #CCCCCC",
+ "c c #E9E9E9",
+ "d c #F2F2F2",
+ "e c #EDEDED",
+ "f c #B5B5B5",
+ "g c #A6A6A6",
+ "h c #ABABAB",
+ "i c #BBBBBB",
+ "j c #B0B0B0",
+ "k c #EAEAEA",
+ "l c #6C6C6C",
+ "m c #BCBCBC",
+ "n c #F5F5F5",
+ "o c #FAFAFA",
+ "p c #B6B6B6",
+ "q c #F3F3F3",
+ "r c #CFCFCF",
+ "s c #FBFBFB",
+ "t c #CDCDCD",
+ "u c #DDDDDD",
+ "v c #999999",
+ "w c #F0F0F0",
+ "x c #2B2B2B",
+ "y c #C3C3C3",
+ "z c #A4A4A4",
+ "A c #D7D7D7",
+ "B c #E7E7E7",
+ "C c #6E6E6E",
+ "D c #9D9D9D",
+ "E c #BABABA",
+ "F c #AEAEAE",
+ "G c #898989",
+ "H c #646464",
+ "I c #BDBDBD",
+ "J c #CACACA",
+ "K c #2A2A2A",
+ "L c #212121",
+ "M c #B7B7B7",
+ "N c #F4F4F4",
+ "O c #737373",
+ "P c #828282",
+ "Q c #4D4D4D",
+ "R c #000000",
+ "S c #151515",
+ "T c #B2B2B2",
+ "U c #D6D6D6",
+ "V c #D3D3D3",
+ "W c #2F2F2F",
+ "X c #636363",
+ "Y c #A1A1A1",
+ "Z c #BFBFBF",
+ "` c #E0E0E0",
+ " . c #6A6A6A",
+ ".. c #050505",
+ "+. c #A3A3A3",
+ "@. c #202020",
+ "#. c #5F5F5F",
+ "$. c #B9B9B9",
+ "%. c #C7C7C7",
+ "&. c #D0D0D0",
+ "*. c #3E3E3E",
+ "=. c #666666",
+ "-. c #DBDBDB",
+ ";. c #424242",
+ ">. c #C2C2C2",
+ ",. c #1A1A1A",
+ "'. c #2C2C2C",
+ "). c #F6F6F6",
+ "!. c #AAAAAA",
+ "~. c #DCDCDC",
+ "{. c #2D2D2D",
+ "]. c #2E2E2E",
+ "^. c #A7A7A7",
+ "/. c #656565",
+ "(. c #333333",
+ "_. c #464646",
+ ":. c #C4C4C4",
+ "<. c #B8B8B8",
+ "[. c #292929",
+ "}. c #979797",
+ "|. c #EFEFEF",
+ "1. c #909090",
+ "2. c #8A8A8A",
+ "3. c #575757",
+ "4. c #676767",
+ "5. c #C5C5C5",
+ "6. c #7A7A7A",
+ "7. c #797979",
+ "8. c #989898",
+ "9. c #EEEEEE",
+ "0. c #707070",
+ "a. c #C8C8C8",
+ "b. c #111111",
+ "c. c #AFAFAF",
+ "d. c #474747",
+ "e. c #565656",
+ "f. c #E3E3E3",
+ "g. c #494949",
+ "h. c #5B5B5B",
+ "i. c #222222",
+ "j. c #353535",
+ "k. c #D9D9D9",
+ "l. c #0A0A0A",
+ "m. c #858585",
+ "n. c #E5E5E5",
+ "o. c #0E0E0E",
+ "p. c #9A9A9A",
+ "q. c #6F6F6F",
+ "r. c #868686",
+ "s. c #060606",
+ "t. c #1E1E1E",
+ "u. c #E8E8E8",
+ "v. c #A5A5A5",
+ "w. c #0D0D0D",
+ "x. c #030303",
+ "y. c #272727",
+ "z. c #131313",
+ "A. c #1F1F1F",
+ "B. c #757575",
+ "C. c #F7F7F7",
+ "D. c #414141",
+ "E. c #080808",
+ "F. c #6B6B6B",
+ "G. c #313131",
+ "H. c #C0C0C0",
+ "I. c #C9C9C9",
+ "J. c #0B0B0B",
+ "K. c #232323",
+ "L. c #434343",
+ "M. c #3D3D3D",
+ "N. c #282828",
+ "O. c #7C7C7C",
+ "P. c #252525",
+ "Q. c #3A3A3A",
+ "R. c #F8F8F8",
+ "S. c #1B1B1B",
+ "T. c #949494",
+ "U. c #3B3B3B",
+ "V. c #242424",
+ "W. c #383838",
+ "X. c #6D6D6D",
+ "Y. c #818181",
+ "Z. c #939393",
+ "`. c #9E9E9E",
+ " + c #929292",
+ ".+ c #7D7D7D",
+ "++ c #ADADAD",
+ "@+ c #DADADA",
+ "#+ c #919191",
+ "$+ c #E1E1E1",
+ "%+ c #BEBEBE",
+ "&+ c #ACACAC",
+ "*+ c #9C9C9C",
+ "=+ c #B3B3B3",
+ "-+ c #808080",
+ ";+ c #A8A8A8",
+ ">+ c #393939",
+ ",+ c #747474",
+ "'+ c #7F7F7F",
+ ")+ c #D1D1D1",
+ "!+ c #606060",
+ "~+ c #5C5C5C",
+ "{+ c #686868",
+ "]+ c #7E7E7E",
+ "^+ c #787878",
+ "/+ c #595959",
+ ". . . + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / . . + + ",
+ ". ( + _ : < [ & } | 1 2 $ 3 4 5 3 6 7 + + 8 9 + . + . ",
+ ". + 0 9 a ( 3 a b c d e c f g h i g j $ k + l m + . + ",
+ "+ 2 8 n o p | ( q r s . # t + + + u ^ v e w + x + + + ",
+ "+ y z . @ A k B 7 n + ( s | p 8 C D 2 E 4 + + F G + . ",
+ "# H I $ J G K L - M N . 2 O P Q R R S T U s s V W j + ",
+ "X Y Z @ o ` _ g ...+.( 4 @.#.m G $.%.7 &.X *.=.-.;.&.",
+ "Q >.C ,.'.} e + ).!.k + . + + . ~.{.> ].x f 7 ^./.k (.",
+ "_.:.4 @ <.[.}.|.1.2.+ + + >.} 4 B + ( @ _ 3.4.5.6.r 7.",
+ "3.8.9.~ 0.+ a.Q b.+ + c.d.#.=.$ |.b #.e.z ^ ; ^. .f.g.",
+ "-.h.+ i.S M + # p j.% n 9.5.k.H l.m.V ^.n.o.M + M p.q.",
+ "7 r.N s.1.R t.<.|.| u.v.~ w.x.E + s y.z.A.B.C.+ 5 D.q ",
+ ").p.2 E.0.9 F.%.O {._ @.+ + i { [ i.G.H.P I.+ s q.} + ",
+ ").p.6 J.R b.K.L.M.A.! b.g.K [.R M k + N.I + + >.O.+ . ",
+ ").8.9.N.P...R R R R E.t.W n.+ Q.R.6 @.| + . + S.+ + . ",
+ "n }.w T.U.B.<.i.@ Y + + U.+ c u V.= B B 7 u.W.c + . + ",
+ "N T.# + }.X.Y.,.8.F.8 Z.[.`. +.+}.4 ++@+O.< ~.+ ( . + ",
+ "d #+1 + _ ~.u.$+b $.y @+| $+%+I.&+k.h W +.9.+ ( . + . ",
+ "w 0 |.*+. >.<.=+++++p a.p -+;+5.k.>+,+@ + . . + . + + ",
+ "q '+9.R.^ I.t b %.I.)+4 $+n.I.,+ .|.+ . . . + . + + + ",
+ ". p !+( + + + + + + E 0. .-+8.f.+ + . . + + . + + + + ",
+ ". ( A ~+{+]+^+l > /+D f.c q . + . . + + . + + + + + + "
+]
diff --git a/sources/pyside6/tests/QtHelp/CMakeLists.txt b/sources/pyside6/tests/QtHelp/CMakeLists.txt
new file mode 100644
index 000000000..422dc51c7
--- /dev/null
+++ b/sources/pyside6/tests/QtHelp/CMakeLists.txt
@@ -0,0 +1,2 @@
+PYSIDE_TEST(help_test.py)
+PYSIDE_TEST(helpsearchengine_test.py)
diff --git a/sources/pyside6/tests/QtHelp/QtHelp.pyproject b/sources/pyside6/tests/QtHelp/QtHelp.pyproject
new file mode 100644
index 000000000..939dca5ba
--- /dev/null
+++ b/sources/pyside6/tests/QtHelp/QtHelp.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["help_test.py",
+ "helpsearchengine_test.py"]
+}
diff --git a/sources/pyside6/tests/QtHelp/help_test.py b/sources/pyside6/tests/QtHelp/help_test.py
new file mode 100644
index 000000000..4ded7763c
--- /dev/null
+++ b/sources/pyside6/tests/QtHelp/help_test.py
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtHelp import QHelpEngine
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QHelpEngineCreation(UsesQApplication):
+
+ def testConstructor(self):
+ helpEngine = QHelpEngine('mycollection.qch')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtHelp/helpsearchengine_test.py b/sources/pyside6/tests/QtHelp/helpsearchengine_test.py
new file mode 100644
index 000000000..b25e643f6
--- /dev/null
+++ b/sources/pyside6/tests/QtHelp/helpsearchengine_test.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtHelp import QHelpEngineCore, QHelpSearchEngine, QHelpSearchResult
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QHelpSearchEngineTest(UsesQApplication):
+
+ def testQHelpSearchEngine(self):
+ helpEngineCore = QHelpEngineCore('')
+ helpSearchEngine = QHelpSearchEngine(helpEngineCore)
+ helpSearchResult = helpSearchEngine.searchResults(0, 0)
+ self.assertEqual(len(helpSearchResult), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtHttpServer/CMakeLists.txt b/sources/pyside6/tests/QtHttpServer/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtHttpServer/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtLocation/CMakeLists.txt b/sources/pyside6/tests/QtLocation/CMakeLists.txt
new file mode 100644
index 000000000..b97ac1098
--- /dev/null
+++ b/sources/pyside6/tests/QtLocation/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(location.py)
diff --git a/sources/pyside6/tests/QtLocation/QtLocation.pyproject b/sources/pyside6/tests/QtLocation/QtLocation.pyproject
new file mode 100644
index 000000000..6ca661a96
--- /dev/null
+++ b/sources/pyside6/tests/QtLocation/QtLocation.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["location.py"]
+}
diff --git a/sources/pyside6/tests/QtLocation/location.py b/sources/pyside6/tests/QtLocation/location.py
new file mode 100644
index 000000000..8fbd55f02
--- /dev/null
+++ b/sources/pyside6/tests/QtLocation/location.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit test for Location'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtLocation import QGeoServiceProvider
+
+
+class QLocationTestCase(unittest.TestCase):
+ def test(self):
+ geoServiceProvider = QGeoServiceProvider("none")
+ self.assertEqual(geoServiceProvider.errorString(),
+ 'The geoservices provider none is not supported.')
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtMultimedia/CMakeLists.txt b/sources/pyside6/tests/QtMultimedia/CMakeLists.txt
new file mode 100644
index 000000000..62150eb79
--- /dev/null
+++ b/sources/pyside6/tests/QtMultimedia/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(audio_test.py)
diff --git a/sources/pyside6/tests/QtMultimedia/QtMultimedia.pyproject b/sources/pyside6/tests/QtMultimedia/QtMultimedia.pyproject
new file mode 100644
index 000000000..622ceea3c
--- /dev/null
+++ b/sources/pyside6/tests/QtMultimedia/QtMultimedia.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["audio_test.py"]
+}
diff --git a/sources/pyside6/tests/QtMultimedia/audio_test.py b/sources/pyside6/tests/QtMultimedia/audio_test.py
new file mode 100644
index 000000000..af359e525
--- /dev/null
+++ b/sources/pyside6/tests/QtMultimedia/audio_test.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QHttp'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QByteArray
+from PySide6.QtMultimedia import QAudioBuffer, QAudioFormat, QMediaDevices
+
+
+class testAudioDevices(UsesQApplication):
+
+ def setUp(self):
+ super().setUp()
+ self._devices = []
+ for d in QMediaDevices.audioOutputs():
+ if d:
+ self._devices.append(d)
+
+ def test_list_devices(self):
+ if not self._devices:
+ print("No audio outputs found")
+ return
+
+ for dev_info in self._devices:
+ print("Testing ", dev_info.id())
+ fmt = QAudioFormat()
+ for sample_format in dev_info.supportedSampleFormats():
+ fmt.setSampleFormat(sample_format)
+ fmt.setChannelCount(dev_info.maximumChannelCount())
+ fmt.setSampleRate(dev_info.maximumSampleRate())
+ self.assertTrue(dev_info.isFormatSupported(fmt))
+
+ def test_audiobuffer(self):
+ """PYSIDE-1947: Test QAudioBuffer.data()."""
+ if not self._devices:
+ print("No audio outputs found")
+ return
+ size = 256
+ byte_array = QByteArray(size, '7')
+ buffer = QAudioBuffer(byte_array, self._devices[0].preferredFormat())
+ self.assertEqual(buffer.byteCount(), 256)
+ data = buffer.data()
+ actual_byte_array = QByteArray(bytearray(data))
+ self.assertEqual(byte_array, actual_byte_array)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtMultimediaWidgets/CMakeLists.txt b/sources/pyside6/tests/QtMultimediaWidgets/CMakeLists.txt
new file mode 100644
index 000000000..2fc655f89
--- /dev/null
+++ b/sources/pyside6/tests/QtMultimediaWidgets/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(qmultimediawidgets.py)
diff --git a/sources/pyside6/tests/QtMultimediaWidgets/QtMultimediaWidgets.pyproject b/sources/pyside6/tests/QtMultimediaWidgets/QtMultimediaWidgets.pyproject
new file mode 100644
index 000000000..6627af561
--- /dev/null
+++ b/sources/pyside6/tests/QtMultimediaWidgets/QtMultimediaWidgets.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["qmultimediawidgets.py"]
+}
diff --git a/sources/pyside6/tests/QtMultimediaWidgets/qmultimediawidgets.py b/sources/pyside6/tests/QtMultimediaWidgets/qmultimediawidgets.py
new file mode 100644
index 000000000..968558a13
--- /dev/null
+++ b/sources/pyside6/tests/QtMultimediaWidgets/qmultimediawidgets.py
@@ -0,0 +1,44 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtMultimediaWidgets'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtMultimediaWidgets import QGraphicsVideoItem, QVideoWidget
+from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QVBoxLayout, QWidget
+from PySide6.QtCore import QTimer
+
+
+class MyWidget(QWidget):
+ def __init__(self):
+ super().__init__()
+
+ layout = QVBoxLayout(self)
+ layout.addWidget(QVideoWidget())
+
+ graphicsScene = QGraphicsScene()
+ graphicsView = QGraphicsView(graphicsScene)
+ graphicsScene.addItem(QGraphicsVideoItem())
+ layout.addWidget(graphicsView)
+
+
+class QMultimediaWidgetsTest(UsesQApplication):
+ def testMultimediaWidgets(self):
+ w = MyWidget()
+ w.show()
+
+ timer = QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/CMakeLists.txt b/sources/pyside6/tests/QtNetwork/CMakeLists.txt
new file mode 100644
index 000000000..bff3580a8
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(bug_446.py)
+PYSIDE_TEST(bug_1084.py)
+PYSIDE_TEST(accessManager_test.py)
+PYSIDE_TEST(dnslookup_test.py)
+# Qt${QT_MAJOR_VERSION}: QHttp is gone PYSIDE_TEST(http_test.py)
+PYSIDE_TEST(qhostinfo_test.py)
+PYSIDE_TEST(qpassworddigestor_test.py)
+PYSIDE_TEST(tcpserver_test.py)
+PYSIDE_TEST(udpsocket_test.py)
+PYSIDE_TEST(qipv6address_test.py)
diff --git a/sources/pyside6/tests/QtNetwork/QtNetwork.pyproject b/sources/pyside6/tests/QtNetwork/QtNetwork.pyproject
new file mode 100644
index 000000000..0ba3f5947
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/QtNetwork.pyproject
@@ -0,0 +1,11 @@
+{
+ "files": ["accessManager_test.py",
+ "bug_1084.py",
+ "bug_446.py",
+ "dnslookup_test.py",
+ "qhostinfo_test.py",
+ "qipv6address_test.py",
+ "qpassworddigestor_test.py",
+ "tcpserver_test.py",
+ "udpsocket_test.py"]
+}
diff --git a/sources/pyside6/tests/QtNetwork/accessManager_test.py b/sources/pyside6/tests/QtNetwork/accessManager_test.py
new file mode 100644
index 000000000..87711b278
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/accessManager_test.py
@@ -0,0 +1,55 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QHttp'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUrl
+from PySide6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
+from helper.usesqapplication import UsesQApplication
+from httpd import TestServer
+
+
+class AccessManagerCase(UsesQApplication):
+
+ def setUp(self):
+ super(AccessManagerCase, self).setUp()
+ self.httpd = TestServer()
+ self.httpd.start()
+ self.called = False
+
+ def tearDown(self):
+ super(AccessManagerCase, self).tearDown()
+ if self.httpd:
+ self.httpd.shutdown()
+ self.httpd = None
+
+ def goAway(self):
+ self.httpd.shutdown()
+ self.app.quit()
+ self.httpd = None
+
+ def slot_replyFinished(self, reply):
+ self.assertEqual(type(reply), QNetworkReply)
+ self.called = True
+ self.goAway()
+
+ def testNetworkRequest(self):
+ manager = QNetworkAccessManager()
+ manager.finished.connect(self.slot_replyFinished)
+ port = self.httpd.port()
+ manager.get(QNetworkRequest(QUrl(f"http://127.0.0.1:{port}")))
+ self.app.exec()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/bug_1084.py b/sources/pyside6/tests/QtNetwork/bug_1084.py
new file mode 100644
index 000000000..515220c80
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/bug_1084.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' unit test for BUG #1084 '''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtNetwork import QTcpSocket
+
+
+class QTcpSocketTestCase(unittest.TestCase):
+ def setUp(self):
+ self.sock = QTcpSocket()
+ self.sock.connectToHost('127.0.0.1', 25)
+
+ def testIt(self):
+ self.sock.write(bytes('quit', "UTF-8"))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/bug_446.py b/sources/pyside6/tests/QtNetwork/bug_446.py
new file mode 100644
index 000000000..f28ddb369
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/bug_446.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtNetwork import QHostAddress, QTcpServer, QTcpSocket
+from helper.usesqapplication import UsesQApplication
+
+
+class HttpSignalsCase(UsesQApplication):
+ '''Test case for launching QHttp signals'''
+ DATA = bytes("PySide rocks", "UTF-8")
+
+ def onError(self):
+ self.assertTrue(False)
+
+ def onNewConnection(self):
+ self.serverConnection = self.server.nextPendingConnection()
+ self.serverConnection.errorOccurred.connect(self.onError)
+ self.serverConnection.write(HttpSignalsCase.DATA)
+ self.server.close()
+
+ def onReadReady(self):
+ data = self.client.read(100)
+ self.assertEqual(len(data), len(HttpSignalsCase.DATA))
+ self.assertEqual(data, HttpSignalsCase.DATA)
+ self.done()
+
+ def onClientConnect(self):
+ self.client.readyRead.connect(self.onReadReady)
+
+ def initServer(self):
+ self.server = QTcpServer()
+ self.server.newConnection.connect(self.onNewConnection)
+ self.assertTrue(self.server.listen())
+ self.client = QTcpSocket()
+ self.client.connected.connect(self.onClientConnect)
+ self.client.connectToHost(QHostAddress(QHostAddress.LocalHost), self.server.serverPort())
+
+ def done(self):
+ self.serverConnection.close()
+ self.client.close()
+ self.app.quit()
+
+ def testRun(self):
+ self.initServer()
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/dnslookup_test.py b/sources/pyside6/tests/QtNetwork/dnslookup_test.py
new file mode 100644
index 000000000..c50a6b5d4
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/dnslookup_test.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QDnsLookup'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication
+from PySide6.QtNetwork import QDnsLookup
+
+
+class DnsLookupTestCase(unittest.TestCase):
+ '''Test case for QDnsLookup'''
+
+ def setUp(self):
+ self._app = QCoreApplication([])
+ self._lookup = QDnsLookup(QDnsLookup.ANY, 'www.qt.io')
+ self._lookup.finished.connect(self._finished)
+
+ def tearDown(self):
+ del self._lookup
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def _finished(self):
+ if self._lookup.error() == QDnsLookup.NoError:
+ nameRecords = self._lookup.canonicalNameRecords()
+ if nameRecords:
+ print(nameRecords[0].name())
+ self._app.quit()
+
+ def testLookup(self):
+ self._lookup.lookup()
+ self._app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/qhostinfo_test.py b/sources/pyside6/tests/QtNetwork/qhostinfo_test.py
new file mode 100644
index 000000000..8d8d2cae4
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/qhostinfo_test.py
@@ -0,0 +1,76 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for QHostInfo.'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import (QCoreApplication, QElapsedTimer, QObject, QThread,
+ Slot, SLOT)
+from PySide6.QtNetwork import QHostInfo
+
+
+HOST = 'www.qt.io'
+
+
+TIMEOUT = 30000
+
+
+class Receiver(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._slot_called = False
+
+ def slot_called(self):
+ return self._slot_called
+
+ @Slot(QHostInfo)
+ def info_received(self, host_info):
+ name = host_info.hostName()
+ if host_info.error() == QHostInfo.NoError:
+ addresses = [a.toString() for a in host_info.addresses()]
+ addresses_str = ', '.join(addresses)
+ print(f'"{name}" resolved to {addresses_str}')
+ else:
+ error = host_info.errorString()
+ print(f'Unable to resolve "{name}": {error}', file=sys.stderr)
+ self._slot_called = True
+
+
+class QHostInfoTest(UsesQApplication):
+ '''Test case for QHostInfo.'''
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self._timer = QElapsedTimer()
+
+ def testStringBasedLookup(self):
+ receiver = Receiver()
+ self._timer.restart()
+ QHostInfo.lookupHost(HOST, receiver, SLOT('info_received(QHostInfo)'))
+ while not receiver.slot_called() and self._timer.elapsed() < TIMEOUT:
+ QCoreApplication.processEvents()
+ QThread.msleep(10)
+ print(f'String-based: Elapsed {self._timer.elapsed()}ms')
+ self.assertTrue(receiver.slot_called())
+
+ def testCallableLookup(self):
+ receiver = Receiver()
+ self._timer.restart()
+ QHostInfo.lookupHost(HOST, receiver.info_received)
+ while not receiver.slot_called() and self._timer.elapsed() < TIMEOUT:
+ QCoreApplication.processEvents()
+ QThread.msleep(10)
+ print(f'Callable: Elapsed {self._timer.elapsed()}ms')
+ self.assertTrue(receiver.slot_called())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/qipv6address_test.py b/sources/pyside6/tests/QtNetwork/qipv6address_test.py
new file mode 100644
index 000000000..67b103d3c
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/qipv6address_test.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QIPv6Address'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtNetwork import QIPv6Address
+
+
+class QIPv6AddressGetItemTest(unittest.TestCase):
+ def testLength(self):
+ ip = QIPv6Address()
+ self.assertEqual(len(ip), 16)
+
+ def testSetItemNegativeIndex(self):
+ ip = QIPv6Address()
+ ip[-1] = 8
+ self.assertEqual(ip[-1], 8)
+
+ def testSetItemLargeIndex(self):
+ ip = QIPv6Address()
+ self.assertRaises(IndexError, ip.__setitem__, 32, 16)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/qpassworddigestor_test.py b/sources/pyside6/tests/QtNetwork/qpassworddigestor_test.py
new file mode 100644
index 000000000..db7a90da9
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/qpassworddigestor_test.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QPasswordDigestor'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray, QCryptographicHash
+from PySide6.QtNetwork import QPasswordDigestor
+
+
+class TestPasswordDigestor(unittest.TestCase):
+ def test(self):
+ b = QPasswordDigestor.deriveKeyPbkdf1(QCryptographicHash.Sha1,
+ b'test', b'saltnpep', 10, 20)
+ self.assertEqual(b.size(), 20)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/tcpserver_test.py b/sources/pyside6/tests/QtNetwork/tcpserver_test.py
new file mode 100644
index 000000000..845afdfae
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/tcpserver_test.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QTCPServer'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtNetwork import QTcpServer
+
+
+class ListenDefaultArgsCase(unittest.TestCase):
+ '''Test case for TcpServer.listen with default args'''
+
+ def setUp(self):
+ # Acquire resources
+ self.server = QTcpServer()
+
+ def tearDown(self):
+ # Release resources
+ del self.server
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testDefaultArgs(self):
+ # @bug 108
+ # Default arguments for QTcpServer.listen
+ self.server.listen()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetwork/udpsocket_test.py b/sources/pyside6/tests/QtNetwork/udpsocket_test.py
new file mode 100644
index 000000000..950849801
--- /dev/null
+++ b/sources/pyside6/tests/QtNetwork/udpsocket_test.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QUdpSocket'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUrl, QObject, SIGNAL, QCoreApplication, QTimer
+from PySide6.QtNetwork import QUdpSocket, QHostAddress
+
+
+class HttpSignalsCase(unittest.TestCase):
+ '''Test case for bug #124 - readDatagram signature
+
+ QUdpSocket.readDatagram must return a tuple with the datagram, host and
+ port, while receiving only the max payload size.'''
+
+ def setUp(self):
+ # Acquire resources
+ self.called = False
+ self.app = QCoreApplication([])
+
+ self.socket = QUdpSocket()
+
+ self.server = QUdpSocket()
+ self.server.bind(QHostAddress(QHostAddress.LocalHost), 45454)
+
+ def tearDown(self):
+ # Release resources
+ del self.socket
+ del self.server
+ del self.app
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def sendPackage(self):
+ addr = QHostAddress(QHostAddress.LocalHost)
+ self.socket.writeDatagram(bytes('datagram', "UTF-8"), addr, 45454)
+
+ def callback(self):
+ while self.server.hasPendingDatagrams():
+ datagram, host, port = self.server.readDatagram(self.server.pendingDatagramSize())
+ self.called = True
+ self.app.quit()
+
+ def testDefaultArgs(self):
+ # QUdpSocket.readDatagram pythonic return
+ # @bug 124
+ self.server.readyRead.connect(self.callback)
+ self.sendPackage()
+ self.app.exec()
+
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtNetworkAuth/CMakeLists.txt b/sources/pyside6/tests/QtNetworkAuth/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtNetworkAuth/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtNfc/CMakeLists.txt b/sources/pyside6/tests/QtNfc/CMakeLists.txt
new file mode 100644
index 000000000..fafa0b76b
--- /dev/null
+++ b/sources/pyside6/tests/QtNfc/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(test_nfc.py)
diff --git a/sources/pyside6/tests/QtNfc/QtNfc.pyproject b/sources/pyside6/tests/QtNfc/QtNfc.pyproject
new file mode 100644
index 000000000..680de8ea2
--- /dev/null
+++ b/sources/pyside6/tests/QtNfc/QtNfc.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["test_nfc.py"]
+}
diff --git a/sources/pyside6/tests/QtNfc/test_nfc.py b/sources/pyside6/tests/QtNfc/test_nfc.py
new file mode 100644
index 000000000..a73c52153
--- /dev/null
+++ b/sources/pyside6/tests/QtNfc/test_nfc.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtNfc'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtNfc import QNearFieldManager
+
+from helper.usesqapplication import UsesQApplication
+
+
+class TestNfc(UsesQApplication):
+
+ def test(self):
+ manager = QNearFieldManager()
+ print(manager.isEnabled())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtOpenGL/CMakeLists.txt b/sources/pyside6/tests/QtOpenGL/CMakeLists.txt
new file mode 100644
index 000000000..92b4afbac
--- /dev/null
+++ b/sources/pyside6/tests/QtOpenGL/CMakeLists.txt
@@ -0,0 +1,2 @@
+PYSIDE_TEST(qopenglbuffer_test.py)
+PYSIDE_TEST(qopenglwindow_test.py)
diff --git a/sources/pyside6/tests/QtOpenGL/QtOpenGL.pyproject b/sources/pyside6/tests/QtOpenGL/QtOpenGL.pyproject
new file mode 100644
index 000000000..9a19a32b6
--- /dev/null
+++ b/sources/pyside6/tests/QtOpenGL/QtOpenGL.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["qopenglbuffer_test.py",
+ "qopenglwindow_test.py"]
+}
diff --git a/sources/pyside6/tests/QtOpenGL/qopenglbuffer_test.py b/sources/pyside6/tests/QtOpenGL/qopenglbuffer_test.py
new file mode 100644
index 000000000..e4ff6feb4
--- /dev/null
+++ b/sources/pyside6/tests/QtOpenGL/qopenglbuffer_test.py
@@ -0,0 +1,77 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit tests for QOpenGLBuffer'''
+
+import ctypes
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QOffscreenSurface, QOpenGLContext, QSurface, QWindow
+from PySide6.QtOpenGL import QOpenGLBuffer
+
+
+def createSurface(surfaceClass):
+ if surfaceClass == QSurface.Window:
+ window = QWindow()
+ window.setSurfaceType(QWindow.OpenGLSurface)
+ window.setGeometry(0, 0, 10, 10)
+ window.create()
+ return window
+ elif surfaceClass == QSurface.Offscreen:
+ # Create a window and get the format from that. For example, if an EGL
+ # implementation provides 565 and 888 configs for PBUFFER_BIT but only
+ # 888 for WINDOW_BIT, we may end up with a pbuffer surface that is
+ # incompatible with the context since it could choose the 565 while the
+ # window and the context uses a config with 888.
+ format = QSurfaceFormat
+ if format.redBufferSize() == -1:
+ window = QWindow()
+ window.setSurfaceType(QWindow.OpenGLSurface)
+ window.setGeometry(0, 0, 10, 10)
+ window.create()
+ format = window.format()
+ offscreenSurface = QOffscreenSurface()
+ offscreenSurface.setFormat(format)
+ offscreenSurface.create()
+ return offscreenSurface
+ return 0
+
+
+class QOpenGLBufferTest(UsesQApplication):
+ def testBufferCreate(self):
+ surface = createSurface(QSurface.Window)
+ ctx = QOpenGLContext()
+ ctx.create()
+ ctx.makeCurrent(surface)
+
+ buf = QOpenGLBuffer()
+
+ self.assertTrue(not buf.isCreated())
+
+ self.assertTrue(buf.create())
+ self.assertTrue(buf.isCreated())
+
+ self.assertEqual(buf.type(), QOpenGLBuffer.VertexBuffer)
+
+ buf.bind()
+ buf.allocate(128)
+ self.assertEqual(buf.size(), 128)
+
+ buf.release()
+
+ buf.destroy()
+ self.assertTrue(not buf.isCreated())
+
+ ctx.doneCurrent()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtOpenGL/qopenglwindow_test.py b/sources/pyside6/tests/QtOpenGL/qopenglwindow_test.py
new file mode 100644
index 000000000..3e6bc4c9d
--- /dev/null
+++ b/sources/pyside6/tests/QtOpenGL/qopenglwindow_test.py
@@ -0,0 +1,96 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit test for QOpenGLContext, QOpenGLTexture, QOpenGLWindow and related classes'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import QSize, QTimer, Qt
+from PySide6.QtGui import (QColor, QGuiApplication, QImage, QOpenGLContext,
+ QSurfaceFormat)
+from PySide6.QtOpenGL import QOpenGLTexture, QOpenGLWindow
+
+
+try:
+ from OpenGL import GL
+ from PySide6.QtOpenGL import QOpenGLVersionProfile, QOpenGLVersionFunctionsFactory
+except ImportError:
+ print("Skipping test due to missing OpenGL module/GLES only build")
+ sys.exit(0)
+
+
+class OpenGLWindow(QOpenGLWindow):
+ def __init__(self):
+ super().__init__()
+
+ self.m_functions = None
+ self.m_texture = None
+ self.visibleChanged.connect(self.slotVisibleChanged)
+
+ def slotVisibleChanged(self, visible):
+ if not visible and self.m_texture is not None and self.context().makeCurrent(self):
+ self.m_texture = None
+ self.context().doneCurrent()
+
+ def initializeGL(self):
+ profile = QOpenGLVersionProfile()
+ profile.setVersion(1, 3)
+ profile.setProfile(QSurfaceFormat.CompatibilityProfile)
+ self.m_functions = QOpenGLVersionFunctionsFactory.get(profile)
+ self.m_functions.initializeOpenGLFunctions()
+
+ print("GL_MAX_LIGHTS=", self.m_functions.glGetIntegerv(GL.GL_MAX_LIGHTS))
+ image = QImage(QSize(200, 200), QImage.Format_RGBA8888)
+ image.fill(QColor(Qt.red))
+ self.m_texture = QOpenGLTexture(image)
+
+ def paintGL(self):
+ self.m_functions.glMatrixMode(GL.GL_MODELVIEW)
+ self.m_functions.glLoadIdentity()
+
+ self.m_functions.glMatrixMode(GL.GL_PROJECTION)
+ self.m_functions.glLoadIdentity()
+ self.m_functions.glOrtho(0, 1, 1, 0, -1, 1)
+
+ self.m_functions.glClear(GL.GL_COLOR_BUFFER_BIT)
+ self.m_functions.glEnable(GL.GL_TEXTURE_2D)
+ self.m_texture.bind()
+
+ d = 0.5
+ self.m_functions.glBegin(GL.GL_QUADS)
+ self.m_functions.glTexCoord2f(0, 0)
+ self.m_functions.glVertex2f(0, 0)
+ self.m_functions.glTexCoord2f(d, 0)
+ self.m_functions.glVertex2f(d, 0)
+ self.m_functions.glTexCoord2f(d, d)
+ self.m_functions.glVertex2f(d, d)
+ self.m_functions.glTexCoord2f(0, d)
+ self.m_functions.glVertex2f(0, d)
+ self.m_functions.glEnd()
+ self.m_texture.release()
+
+ def resizeGL(self, w, h):
+ self.m_functions.glViewport(0, 0, self.width(), self.height())
+
+
+class QOpenGLWindowTest(UsesQApplication):
+ # On macOS, glClear(), glViewport() are rejected due to GLbitfield/GLint not being resolved properly
+ def test(self):
+ openGlWindow = OpenGLWindow()
+ openGlWindow.resize(640, 480)
+ openGlWindow.show()
+ QTimer.singleShot(100, openGlWindow.close)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtOpenGLWidgets/CMakeLists.txt b/sources/pyside6/tests/QtOpenGLWidgets/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtOpenGLWidgets/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtPdf/CMakeLists.txt b/sources/pyside6/tests/QtPdf/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtPdf/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtPdfWidgets/CMakeLists.txt b/sources/pyside6/tests/QtPdfWidgets/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtPdfWidgets/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtPositioning/CMakeLists.txt b/sources/pyside6/tests/QtPositioning/CMakeLists.txt
new file mode 100644
index 000000000..b9f7631b1
--- /dev/null
+++ b/sources/pyside6/tests/QtPositioning/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(positioning.py)
diff --git a/sources/pyside6/tests/QtPositioning/QtPositioning.pyproject b/sources/pyside6/tests/QtPositioning/QtPositioning.pyproject
new file mode 100644
index 000000000..e90ccd8a2
--- /dev/null
+++ b/sources/pyside6/tests/QtPositioning/QtPositioning.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["positioning.py"]
+}
diff --git a/sources/pyside6/tests/QtPositioning/positioning.py b/sources/pyside6/tests/QtPositioning/positioning.py
new file mode 100644
index 000000000..d8e670247
--- /dev/null
+++ b/sources/pyside6/tests/QtPositioning/positioning.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Unit test for Positioning'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtPositioning import QGeoPositionInfoSource
+
+
+class QPositioningTestCase(unittest.TestCase):
+ def test(self):
+ source = QGeoPositionInfoSource.createDefaultSource(None)
+ self.assertTrue(source is not None)
+ name = source.sourceName()
+ print(f"QtPositioning source: {name}")
+ self.assertTrue(name)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtPrintSupport/CMakeLists.txt b/sources/pyside6/tests/QtPrintSupport/CMakeLists.txt
new file mode 100644
index 000000000..510c5fe0b
--- /dev/null
+++ b/sources/pyside6/tests/QtPrintSupport/CMakeLists.txt
@@ -0,0 +1,2 @@
+PYSIDE_TEST(bug_500.py)
+PYSIDE_TEST(returnquadruplesofnumbers_test.py)
diff --git a/sources/pyside6/tests/QtPrintSupport/QtPrintSupport.pyproject b/sources/pyside6/tests/QtPrintSupport/QtPrintSupport.pyproject
new file mode 100644
index 000000000..dbc9641d7
--- /dev/null
+++ b/sources/pyside6/tests/QtPrintSupport/QtPrintSupport.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["bug_500.py",
+ "returnquadruplesofnumbers_test.py"]
+}
diff --git a/sources/pyside6/tests/QtPrintSupport/bug_500.py b/sources/pyside6/tests/QtPrintSupport/bug_500.py
new file mode 100644
index 000000000..1ba5b35e2
--- /dev/null
+++ b/sources/pyside6/tests/QtPrintSupport/bug_500.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtPrintSupport import QPrintDialog
+from helper.usesqapplication import UsesQApplication
+
+
+class NeverDiesTest(UsesQApplication):
+
+ def testIt(self):
+ QPrintDialog()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtPrintSupport/returnquadruplesofnumbers_test.py b/sources/pyside6/tests/QtPrintSupport/returnquadruplesofnumbers_test.py
new file mode 100644
index 000000000..97b3505da
--- /dev/null
+++ b/sources/pyside6/tests/QtPrintSupport/returnquadruplesofnumbers_test.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QTextCursor
+from PySide6.QtPrintSupport import QPrinter, QPrinterInfo
+from PySide6.QtWidgets import QLayout, QWidget, QGraphicsLayout, QGraphicsLayoutItem
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Layout(QLayout):
+ def __init__(self):
+ super().__init__()
+
+
+class GraphicsLayout(QGraphicsLayout):
+ def __init__(self):
+ super().__init__()
+
+
+class GraphicsLayoutItem(QGraphicsLayoutItem):
+ def __init__(self):
+ super().__init__()
+
+
+class ReturnsQuadruplesOfNumbers(UsesQApplication):
+ def compareTuples(self, ta, tb):
+ for va, vb in zip(ta, tb):
+ if round(va) != round(vb):
+ return False
+ return True
+
+ def testQGraphicsLayoutGetContentsMargins(self):
+ obj = GraphicsLayout()
+ values = (10.0, 20.0, 30.0, 40.0)
+ obj.setContentsMargins(*values)
+ self.assertTrue(self.compareTuples(obj.getContentsMargins(), values))
+
+ def testQGraphicsLayoutItemGetContentsMargins(self):
+ obj = GraphicsLayoutItem()
+ self.assertTrue(self.compareTuples(obj.getContentsMargins(), (0.0, 0.0, 0.0, 0.0)))
+
+ def testQLayoutGetContentsMargins(self):
+ obj = Layout()
+ values = (10, 20, 30, 40)
+ obj.setContentsMargins(*values)
+ self.assertTrue(self.compareTuples(obj.getContentsMargins(), values))
+
+ def testQTextCursorSelectedTableCells(self):
+ obj = QTextCursor()
+ self.assertEqual(obj.selectedTableCells(), (-1, -1, -1, -1))
+
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtQml/CMakeLists.txt b/sources/pyside6/tests/QtQml/CMakeLists.txt
new file mode 100644
index 000000000..30bf7e786
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(bug_451.py)
+PYSIDE_TEST(bug_456.py)
+PYSIDE_TEST(bug_557.py)
+PYSIDE_TEST(bug_726.py)
+PYSIDE_TEST(bug_814.py)
+PYSIDE_TEST(bug_825_old.py)
+PYSIDE_TEST(bug_825.py)
+PYSIDE_TEST(bug_847.py)
+PYSIDE_TEST(bug_915.py)
+PYSIDE_TEST(bug_926.py)
+PYSIDE_TEST(bug_951.py)
+PYSIDE_TEST(bug_995.py)
+PYSIDE_TEST(bug_997.py)
+PYSIDE_TEST(bug_1029.py)
+PYSIDE_TEST(groupedproperty.py)
+PYSIDE_TEST(listproperty.py)
+PYSIDE_TEST(qmlregistertype_test.py)
+PYSIDE_TEST(qqmlapplicationengine_test.py)
+PYSIDE_TEST(qqmlnetwork_test.py)
+PYSIDE_TEST(qqmlcomponent_test.py)
+PYSIDE_TEST(qquickview_test.py)
+PYSIDE_TEST(connect_python_qml.py)
+PYSIDE_TEST(registerattached.py)
+PYSIDE_TEST(registerextended.py)
+PYSIDE_TEST(registerparserstatus.py)
+PYSIDE_TEST(registertype.py)
+PYSIDE_TEST(registerforeign.py)
+PYSIDE_TEST(registerqmlfile.py)
+PYSIDE_TEST(registeruncreatabletype.py)
+PYSIDE_TEST(registersingletontype.py)
+PYSIDE_TEST(javascript_exceptions.py)
+PYSIDE_TEST(qqmlincubator_incubateWhile.py)
+PYSIDE_TEST(qquickitem_grabToImage.py)
+PYSIDE_TEST(signal_arguments.py)
diff --git a/sources/pyside6/tests/QtQml/ModuleType.qml b/sources/pyside6/tests/QtQml/ModuleType.qml
new file mode 100644
index 000000000..d7e5e653c
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/ModuleType.qml
@@ -0,0 +1,8 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQml
+
+QtObject {
+ objectName: "moduleType"
+}
diff --git a/sources/pyside6/tests/QtQml/QtQml.pyproject b/sources/pyside6/tests/QtQml/QtQml.pyproject
new file mode 100644
index 000000000..5a05c71a1
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/QtQml.pyproject
@@ -0,0 +1,65 @@
+{
+ "files": ["ModuleType.qml",
+ "bug_1029.py",
+ "bug_1029.qml",
+ "bug_451.py",
+ "bug_451.qml",
+ "bug_456.py",
+ "bug_456.qml",
+ "bug_557.py",
+ "bug_726.py",
+ "bug_726.qml",
+ "bug_814.py",
+ "bug_814.qml",
+ "bug_825.py",
+ "bug_825.qml",
+ "bug_847.py",
+ "bug_847.qml",
+ "bug_915.py",
+ "bug_926.py",
+ "bug_926.qml",
+ "bug_951.py",
+ "bug_951.qml",
+ "bug_995.py",
+ "bug_995.qml",
+ "bug_997.py",
+ "bug_997.qml",
+ "connect_python_qml.py",
+ "connect_python_qml.qml",
+ "groupedproperty.py",
+ "groupedproperty.qml",
+ "hw.qml",
+ "javascript_exceptions.py",
+ "javascript_exceptions.qml",
+ "listproperty.py",
+ "qqmlapplicationengine.qml",
+ "qqmlapplicationengine_test.py",
+ "qqmlincubator_incubateWhile.py",
+ "qqmlincubator_incubateWhile.qml",
+ "qqmlincubator_incubateWhile_component.qml",
+ "qqmlnetwork_test.py",
+ "qquickitem_grabToImage.py",
+ "qquickitem_grabToImage.qml",
+ "qquickview_test.py",
+ "registerattached.py",
+ "registerattached.qml",
+ "registerextended.py",
+ "registerextended.qml",
+ "registerforeign.py",
+ "registerforeign.qml",
+ "registerparserstatus.py",
+ "registerparserstatus.qml",
+ "registerqmlfile.py",
+ "registersingletontype.py",
+ "registersingletontype.qml",
+ "registertype.py",
+ "registertype.qml",
+ "registeruncreatable.qml",
+ "registeruncreatabletype.py",
+ "signal_arguments.py",
+ "signal_arguments.qml",
+ "signal_types.py",
+ "signal_types.qml",
+ "view.qml",
+ "viewmodel.qml"]
+}
diff --git a/sources/pyside6/tests/QtQml/bug_1029.py b/sources/pyside6/tests/QtQml/bug_1029.py
new file mode 100644
index 000000000..69ca5c18d
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_1029.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUrl
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import qmlRegisterType
+from PySide6.QtQuick import QQuickView, QQuickItem
+
+
+def register_qml_types():
+ class TestClass(QQuickItem):
+ def __init__(self, parent=None):
+ QQuickItem.__init__(self, parent)
+
+ qmlRegisterType(TestClass, "UserTypes", 1, 0, "TestClass")
+
+
+def main():
+ app = QGuiApplication([])
+
+ # reg qml types here
+ register_qml_types()
+
+ # force gc to run
+ gc.collect()
+
+ view = QQuickView()
+ url = QUrl(__file__.replace(".py", ".qml"))
+ view.setSource(url)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/sources/pyside6/tests/QtQml/bug_1029.qml b/sources/pyside6/tests/QtQml/bug_1029.qml
new file mode 100644
index 000000000..e4e95f865
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_1029.qml
@@ -0,0 +1,18 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import UserTypes 1.0
+
+Rectangle
+{
+ width: 200
+ height: 200
+
+ color: "#ff0000"
+
+ TestClass
+ {
+
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/bug_451.py b/sources/pyside6/tests/QtQml/bug_451.py
new file mode 100644
index 000000000..d81a99d94
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_451.py
@@ -0,0 +1,93 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''
+Test bug 451: http://bugs.openbossa.org/show_bug.cgi?id=451
+
+An archive of said bug:
+https://srinikom.github.io/pyside-bz-archive/451.html
+'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+
+from PySide6.QtCore import QObject, QUrl, Property
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQuick import QQuickView
+from PySide6.QtQml import QmlElement
+
+
+QML_IMPORT_NAME = "test.PythonObject"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class PythonObject(QObject):
+ def __init__(self):
+ super().__init__(None)
+ self._called = ""
+ self._arg1 = None
+ self._arg2 = None
+
+ def setCalled(self, v):
+ self._called = v
+
+ def setArg1(self, v):
+ self._arg1 = v
+
+ def setArg2(self, v):
+ self._arg2 = v
+
+ def getCalled(self):
+ return self._called
+
+ def getArg1(self):
+ return self._arg1
+
+ def getArg2(self):
+ return self._arg2
+
+ called = Property(str, getCalled, setCalled)
+ arg1 = Property(int, getArg1, setArg1)
+ arg2 = Property('QVariant', getArg2, setArg2)
+
+
+class TestBug(unittest.TestCase):
+ def testQMLFunctionCall(self):
+ app = QGuiApplication(sys.argv)
+ view = QQuickView()
+
+ obj = PythonObject()
+ view.setInitialProperties({"python": obj})
+ file = Path(__file__).resolve().parent / 'bug_451.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ root = view.rootObject()
+ self.assertTrue(root, quickview_errorstring(view))
+ root.simpleFunction()
+ self.assertEqual(obj.called, "simpleFunction")
+
+ root.oneArgFunction(42)
+ self.assertEqual(obj.called, "oneArgFunction")
+ self.assertEqual(obj.arg1, 42)
+
+ root.twoArgFunction(10, app)
+ self.assertEqual(obj.called, "twoArgFunction")
+ self.assertEqual(obj.arg1, 10)
+ self.assertEqual(obj.arg2, app)
+
+ rvalue = root.returnFunction()
+ self.assertEqual(obj.called, "returnFunction")
+ self.assertEqual(rvalue, 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_451.qml b/sources/pyside6/tests/QtQml/bug_451.qml
new file mode 100644
index 000000000..0867b861f
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_451.qml
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import test.PythonObject 1.0
+
+Rectangle {
+ id: page
+ required property PythonObject python
+
+ function simpleFunction() {
+ python.called = "simpleFunction"
+ }
+
+ function oneArgFunction(x) {
+ python.called = "oneArgFunction"
+ python.arg1 = x
+ }
+
+ function twoArgFunction(x, y) {
+ python.called = "twoArgFunction"
+ python.arg1 = x
+ python.arg2 = y
+ }
+
+ function returnFunction() {
+ python.called = "returnFunction"
+ return 42
+ }
+
+}
diff --git a/sources/pyside6/tests/QtQml/bug_456.py b/sources/pyside6/tests/QtQml/bug_456.py
new file mode 100644
index 000000000..7743ee3fd
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_456.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+from PySide6.QtCore import QObject, QTimer, QUrl, Property, Slot
+from PySide6.QtQuick import QQuickView
+from PySide6.QtQml import QmlElement
+
+QML_IMPORT_NAME = "test.RotateValue"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class RotateValue(QObject):
+ def __init__(self):
+ super().__init__()
+
+ @Slot(result=int)
+ def val(self):
+ return 100
+
+ def setRotation(self, v):
+ self._rotation = v
+
+ def getRotation(self):
+ return self._rotation
+
+ rotation = Property(int, getRotation, setRotation)
+
+
+class TestConnectionWithInvalidSignature(TimedQGuiApplication):
+
+ def testSlotRetur(self):
+ view = QQuickView()
+ rotatevalue = RotateValue()
+
+ timer = QTimer()
+ timer.start(2000)
+
+ view.setInitialProperties({"rotatevalue": rotatevalue})
+ file = Path(__file__).resolve().parent / 'bug_456.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ root = view.rootObject()
+ self.assertTrue(root, quickview_errorstring(view))
+ button = root.findChild(QObject, "buttonMouseArea")
+ view.show()
+ button.entered.emit()
+ self.assertEqual(rotatevalue.rotation, 100)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_456.qml b/sources/pyside6/tests/QtQml/bug_456.qml
new file mode 100644
index 000000000..092cca325
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_456.qml
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import test.RotateValue 1.0
+
+Rectangle {
+ id: page
+
+ width: 500; height: 200
+ color: "lightgray"
+ required property RotateValue rotatevalue
+
+ Rectangle {
+ id: button
+ width: 150; height: 40
+ color: "darkgray"
+ anchors.horizontalCenter: page.horizontalCenter
+ y: 120
+ MouseArea {
+ id: buttonMouseArea
+ objectName: "buttonMouseArea"
+ anchors.fill: parent
+ onEntered: {
+ rotatevalue.rotation = rotatevalue.val()
+ }
+ }
+ Text {
+ id: buttonText
+ text: "Press me!"
+ anchors.horizontalCenter: button.horizontalCenter
+ anchors.verticalCenter: button.verticalCenter
+ font.pointSize: 16;
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/bug_557.py b/sources/pyside6/tests/QtQml/bug_557.py
new file mode 100644
index 000000000..eb43973f6
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_557.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import adjust_filename
+
+from PySide6.QtCore import QUrl
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import QQmlEngine, QQmlComponent
+
+app = QGuiApplication(sys.argv)
+
+engine = QQmlEngine()
+component = QQmlComponent(engine)
+
+# This should segfault if the QDeclarativeComponent has not QQmlEngine
+file = Path(__file__).resolve().parent / 'foo.qml'
+assert (not file.is_file())
+component.loadUrl(QUrl.fromLocalFile(file))
+
diff --git a/sources/pyside6/tests/QtQml/bug_726.py b/sources/pyside6/tests/QtQml/bug_726.py
new file mode 100644
index 000000000..56c1e70f1
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_726.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+from PySide6.QtCore import QObject, QUrl, Slot
+from PySide6.QtQuick import QQuickView
+from PySide6.QtQml import QmlElement
+
+QML_IMPORT_NAME = "test.ProxyObject"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class ProxyObject(QObject):
+ def __init__(self):
+ super().__init__()
+ self._o = None
+ self._receivedName = ""
+
+ @Slot(result='QObject*')
+ def getObject(self):
+ if self._o:
+ return self._o
+
+ self._o = QObject()
+ self._o.setObjectName("PySideObject")
+ return self._o
+
+ @Slot(str)
+ def receivedObject(self, name):
+ self._receivedName = name
+
+
+class TestConnectionWithInvalidSignature(TimedQGuiApplication):
+
+ def testSlotRetur(self):
+ view = QQuickView()
+ proxy = ProxyObject()
+
+ view.setInitialProperties({"proxy": proxy})
+ file = Path(__file__).resolve().parent / 'bug_726.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ root = view.rootObject()
+ self.assertTrue(root, quickview_errorstring(view))
+ button = root.findChild(QObject, "buttonMouseArea")
+ view.show()
+ button.entered.emit()
+ self.assertEqual(proxy._receivedName, "PySideObject")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_726.qml b/sources/pyside6/tests/QtQml/bug_726.qml
new file mode 100644
index 000000000..f80c9cdda
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_726.qml
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import test.ProxyObject 1.0
+
+Rectangle {
+ id: page
+
+ width: 500; height: 200
+ color: "lightgray"
+ required property ProxyObject proxy
+
+ Rectangle {
+ id: button
+ width: 150; height: 40
+ color: "darkgray"
+ anchors.horizontalCenter: page.horizontalCenter
+ y: 120
+ MouseArea {
+ id: buttonMouseArea
+ objectName: "buttonMouseArea"
+ anchors.fill: parent
+ onEntered: {
+ proxy.receivedObject(proxy.getObject().objectName)
+ }
+ }
+ Text {
+ id: buttonText
+ text: "Press me!"
+ anchors.horizontalCenter: button.horizontalCenter
+ anchors.verticalCenter: button.verticalCenter
+ font.pointSize: 16;
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/bug_814.py b/sources/pyside6/tests/QtQml/bug_814.py
new file mode 100644
index 000000000..0e7858b6c
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_814.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# Copyright (C) 2011 Thomas Perl <m@thp.io>
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# Test case for PySide bug 814
+# http://bugs.pyside.org/show_bug.cgi?id=814
+# archive:
+# https://srinikom.github.io/pyside-bz-archive/814.html
+# 2011-04-08 Thomas Perl <m@thp.io>
+# Released under the same terms as PySide itself
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtCore import QUrl, QAbstractListModel, QModelIndex, Qt
+from PySide6.QtQuick import QQuickView
+from PySide6.QtQml import QmlElement
+
+QML_IMPORT_NAME = "test.ListModel"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class ListModel(QAbstractListModel):
+ def __init__(self):
+ super().__init__()
+
+ def roleNames(self):
+ return {Qt.DisplayRole: b'pysideModelData'}
+
+ def rowCount(self, parent=QModelIndex()):
+ return 3
+
+ def data(self, index, role):
+ if index.isValid() and role == Qt.DisplayRole:
+ return 'blubb'
+ return None
+
+
+class TestBug814(TimedQGuiApplication):
+ def testAbstractItemModelTransferToQML(self):
+ view = QQuickView()
+ model = ListModel()
+ view.setInitialProperties({"pythonModel": model})
+ file = Path(__file__).resolve().parent / 'bug_814.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ root = view.rootObject()
+ self.assertTrue(root, quickview_errorstring(view))
+ view.show()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtQml/bug_814.qml b/sources/pyside6/tests/QtQml/bug_814.qml
new file mode 100644
index 000000000..4331e424f
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_814.qml
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import test.ListModel 1.0
+
+ListView {
+ required property ListModel pythonModel
+ width: 300; height: 300
+ delegate: Text { text: pysideModelData }
+ model: pythonModel
+}
+
diff --git a/sources/pyside6/tests/QtQml/bug_825.py b/sources/pyside6/tests/QtQml/bug_825.py
new file mode 100644
index 000000000..a8bd304ec
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_825.py
@@ -0,0 +1,80 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+This is the corrected version for Python 3.
+Unfortunately, this touches a Python 3.8 error that was fixed late.
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+
+from PySide6.QtCore import Qt, QUrl, QTimer
+from PySide6.QtGui import QGuiApplication, QPen
+from PySide6.QtWidgets import QGraphicsItem
+from PySide6.QtQml import qmlRegisterType
+from PySide6.QtQuick import QQuickView, QQuickItem, QQuickPaintedItem
+
+paintCalled = False
+
+
+class MetaA(type):
+ pass
+
+
+class A(object, metaclass=MetaA):
+ pass
+
+
+MetaB = type(QQuickPaintedItem)
+B = QQuickPaintedItem
+
+
+class MetaC(MetaA, MetaB):
+ pass
+
+
+class C(A, B, metaclass=MetaC):
+ pass
+
+
+class Bug825 (C):
+ def __init__(self, parent=None):
+ QQuickPaintedItem.__init__(self, parent)
+
+ def paint(self, painter):
+ global paintCalled
+ pen = QPen(Qt.black, 2)
+ painter.setPen(pen)
+ painter.drawPie(self.boundingRect(), 0, 128)
+ paintCalled = True
+
+
+class TestBug825 (unittest.TestCase):
+ def testIt(self):
+ global paintCalled
+ app = QGuiApplication([])
+ qmlRegisterType(Bug825, 'bugs', 1, 0, 'Bug825')
+ self.assertRaises(TypeError, qmlRegisterType, A, 'bugs', 1, 0, 'A')
+
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'bug_825.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.show()
+ QTimer.singleShot(250, view.close)
+ app.exec()
+ self.assertTrue(paintCalled)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_825.qml b/sources/pyside6/tests/QtQml/bug_825.qml
new file mode 100644
index 000000000..77c6b5014
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_825.qml
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import bugs 1.0
+
+Item {
+ width: 300; height: 200
+
+ Bug825 {
+ anchors.fill: parent
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/bug_825_old.py b/sources/pyside6/tests/QtQml/bug_825_old.py
new file mode 100644
index 000000000..c44fa75f4
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_825_old.py
@@ -0,0 +1,80 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+This is the now incorrect old version from Python 2.
+It happens to work in another way and will be retained.
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+
+from PySide6.QtCore import Qt, QUrl, QTimer
+from PySide6.QtGui import QGuiApplication, QPen
+from PySide6.QtWidgets import QGraphicsItem
+from PySide6.QtQml import qmlRegisterType
+from PySide6.QtQuick import QQuickView, QQuickItem, QQuickPaintedItem
+
+paintCalled = False
+
+
+class MetaA(type):
+ pass
+
+
+class A(object):
+ __metaclass__ = MetaA
+
+
+MetaB = type(QQuickPaintedItem)
+B = QQuickPaintedItem
+
+
+class MetaC(MetaA, MetaB):
+ pass
+
+
+class C(A, B):
+ __metaclass__ = MetaC
+
+
+class Bug825 (C):
+ def __init__(self, parent=None):
+ QQuickPaintedItem.__init__(self, parent)
+
+ def paint(self, painter):
+ global paintCalled
+ pen = QPen(Qt.black, 2)
+ painter.setPen(pen)
+ painter.drawPie(self.boundingRect(), 0, 128)
+ paintCalled = True
+
+
+class TestBug825 (unittest.TestCase):
+ def testIt(self):
+ global paintCalled
+ app = QGuiApplication([])
+ qmlRegisterType(Bug825, 'bugs', 1, 0, 'Bug825')
+ self.assertRaises(TypeError, qmlRegisterType, A, 'bugs', 1, 0, 'A')
+
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'bug_825.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.show()
+ QTimer.singleShot(250, view.close)
+ app.exec()
+ self.assertTrue(paintCalled)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_847.py b/sources/pyside6/tests/QtQml/bug_847.py
new file mode 100644
index 000000000..947eb494e
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_847.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# Copyright (C) 2011 Thomas Perl <m@thp.io>
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# Testcase for PySide bug 847
+# Released under the same terms as PySide itself
+# 2011-05-04 Thomas Perl <m@thp.io>
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import Slot, Signal, QUrl, QTimer, QCoreApplication
+from PySide6.QtQuick import QQuickView
+
+
+class View(QQuickView):
+ def __init__(self):
+ super().__init__()
+
+ called = Signal(int, int)
+
+ @Slot(int, int)
+ def blubb(self, x, y):
+ self.called.emit(x, y)
+
+
+class TestQML(UsesQApplication):
+ def done(self, x, y):
+ self._sucess = True
+ self.app.quit()
+ print("done called")
+
+ def testPythonSlot(self):
+ self._sucess = False
+ view = View()
+
+ # Connect first, then set the property.
+ view.called.connect(self.done)
+ file = Path(__file__).resolve().parent / 'bug_847.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ while view.status() == QQuickView.Loading:
+ self.app.processEvents()
+ self.assertEqual(view.status(), QQuickView.Ready)
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.rootObject().setProperty('pythonObject', view)
+
+ view.show()
+ while not view.isExposed():
+ self.app.processEvents()
+
+ # Essentially a timeout in case method invocation fails.
+ QTimer.singleShot(30000, QCoreApplication.instance().quit)
+ self.app.exec()
+ self.assertTrue(self._sucess)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtQml/bug_847.qml b/sources/pyside6/tests/QtQml/bug_847.qml
new file mode 100644
index 000000000..18efd80ce
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_847.qml
@@ -0,0 +1,37 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+Rectangle {
+ width: 500
+ height: 500
+ color: 'red'
+
+ property variant pythonObject: undefined
+
+ Text {
+ anchors.centerIn: parent
+ text: 'click me'
+ color: 'white'
+ }
+
+ onPythonObjectChanged: {
+ if (pythonObject) {
+ // Delay execution of method invocation, so that the event loop has a chance to start,
+ // which will subsequently be stopped by the method.
+ timer.start()
+ }
+ }
+
+ Timer {
+ id: timer
+ interval: 100; running: false;
+ onTriggered: {
+ if (pythonObject) {
+ pythonObject.blubb(42, 84)
+ }
+ }
+ }
+}
+
diff --git a/sources/pyside6/tests/QtQml/bug_915.py b/sources/pyside6/tests/QtQml/bug_915.py
new file mode 100644
index 000000000..3095eba2a
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_915.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtQuick import QQuickView, QQuickItem
+
+
+class TestBug915(TimedQGuiApplication):
+ def testReturnPolicy(self):
+ view = QQuickView()
+
+ item1 = QQuickItem()
+ item1.setObjectName("Item1")
+ item1.setParentItem(view.contentItem())
+ self.assertEqual(item1.objectName(), "Item1") # check if the item still valid
+
+ item2 = QQuickItem()
+ item2.setObjectName("Item2")
+ item2.setParentItem(view.contentItem())
+ item1 = None
+ self.assertEqual(item2.objectName(), "Item2") # check if the item still valid
+
+ view = None
+
+
+if __name__ == '__main__':
+ unittest.main()
+
+
diff --git a/sources/pyside6/tests/QtQml/bug_926.py b/sources/pyside6/tests/QtQml/bug_926.py
new file mode 100644
index 000000000..085e9a68f
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_926.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import sys
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+
+from PySide6.QtCore import QUrl, QTimer, QObject, Signal, Property
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import qmlRegisterType
+from PySide6.QtQuick import QQuickView
+
+
+class MyClass (QObject):
+
+ def __init__(self):
+ super().__init__()
+ self.__url = QUrl()
+
+ def getUrl(self):
+ return self.__url
+
+ def setUrl(self, value):
+ newUrl = QUrl(value)
+ if (newUrl != self.__url):
+ self.__url = newUrl
+ self.urlChanged.emit()
+
+ urlChanged = Signal()
+ urla = Property(QUrl, getUrl, setUrl, notify=urlChanged)
+
+
+class TestBug926 (unittest.TestCase):
+ def testIt(self):
+ app = QGuiApplication([])
+ qmlRegisterType(MyClass, 'Example', 1, 0, 'MyClass')
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'bug_926.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+
+ view.show()
+ QTimer.singleShot(0, app.quit)
+ app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_926.qml b/sources/pyside6/tests/QtQml/bug_926.qml
new file mode 100644
index 000000000..6f7b608d0
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_926.qml
@@ -0,0 +1,20 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import Example 1.0
+
+Rectangle {
+ width: 100
+ height: 62
+
+ MyClass {
+ id: myClass
+ urla: "http://www.pyside.org"
+ }
+
+ Text {
+ id: name
+ text: myClass.urla
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/bug_951.py b/sources/pyside6/tests/QtQml/bug_951.py
new file mode 100644
index 000000000..8a512d06f
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_951.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtCore import QUrl
+from PySide6.QtQml import qmlRegisterType
+from PySide6.QtQuick import QQuickItem, QQuickView
+
+
+class MyItem(QQuickItem):
+ COMPONENT_COMPLETE_CALLED = False
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setObjectName("myitem")
+
+ def componentComplete(self):
+ MyItem.COMPONENT_COMPLETE_CALLED = True
+ super(MyItem, self).componentComplete()
+
+
+class TestRegisterQMLType(TimedQGuiApplication):
+ def setup(self):
+ super.setup(100 * 3) # 3s
+
+ def testSignalEmission(self):
+ qmlRegisterType(MyItem, "my.item", 1, 0, "MyItem")
+
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'bug_951.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+
+ self.app.exec()
+ self.assertTrue(MyItem.COMPONENT_COMPLETE_CALLED)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_951.qml b/sources/pyside6/tests/QtQml/bug_951.qml
new file mode 100644
index 000000000..02bf0c708
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_951.qml
@@ -0,0 +1,10 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import my.item 1.0
+Rectangle{
+ width:10
+ height:10
+ MyItem{ }
+}
diff --git a/sources/pyside6/tests/QtQml/bug_995.py b/sources/pyside6/tests/QtQml/bug_995.py
new file mode 100644
index 000000000..868c584e2
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_995.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import adjust_filename
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import QUrl
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQuick import QQuickView
+
+app = QGuiApplication([])
+file = Path(__file__).resolve().parent / 'bug_995.qml'
+assert (file.is_file())
+view = QQuickView(QUrl.fromLocalFile(file))
+view.show()
+view.resize(200, 200)
+contentItem = view.contentItem()
+item = contentItem.childAt(100, 100)
+
+# it CAN NOT crash here
+print(item)
+
diff --git a/sources/pyside6/tests/QtQml/bug_995.qml b/sources/pyside6/tests/QtQml/bug_995.qml
new file mode 100644
index 000000000..4f47cbd05
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_995.qml
@@ -0,0 +1,15 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+Rectangle {
+ width: 100
+ height: 100
+ color: "red"
+
+ Text {
+ text: "Hello World"
+ anchors.centerIn: parent
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/bug_997.py b/sources/pyside6/tests/QtQml/bug_997.py
new file mode 100644
index 000000000..501c221c3
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_997.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QCoreApplication, QTimer, QUrl, Slot
+from PySide6.QtQml import QQmlPropertyMap
+from PySide6.QtQuick import QQuickView
+
+
+class TestBug(UsesQApplication):
+
+ def setUp(self):
+ super().setUp()
+ self._complete = False
+
+ @Slot()
+ def complete(self):
+ self._complete = True
+ self.app.quit()
+
+ def testQMLFunctionCall(self):
+ ownerData = QQmlPropertyMap()
+ ownerData.insert('name', 'John Smith')
+ ownerData.insert('phone', '555-5555')
+ ownerData.insert('newValue', '')
+
+ self._view = QQuickView()
+ self._view.engine().quit.connect(self.complete)
+ self._view.setInitialProperties({'owner': ownerData})
+ file = Path(__file__).resolve().parent / 'bug_997.qml'
+ self.assertTrue(file.is_file())
+ self._view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(self._view.rootObject(), quickview_errorstring(self._view))
+ self._view.show()
+ if not self._complete:
+ self.app.exec()
+ self.assertEqual(ownerData.value('newName'), ownerData.value('name'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/bug_997.qml b/sources/pyside6/tests/QtQml/bug_997.qml
new file mode 100644
index 000000000..23188f31f
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/bug_997.qml
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+Text {
+ required property var owner
+ text: owner.name + " " + owner.phone
+ Component.onCompleted: {
+ owner.newName = owner.name
+ Qt.quit()
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/connect_python_qml.py b/sources/pyside6/tests/QtQml/connect_python_qml.py
new file mode 100644
index 000000000..2e60aec4f
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/connect_python_qml.py
@@ -0,0 +1,55 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''
+Test case for bug #442
+
+archive:
+https://srinikom.github.io/pyside-bz-archive/442.html
+'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+from PySide6.QtCore import QObject, QUrl, SIGNAL
+from PySide6.QtGui import QColor
+from PySide6.QtQuick import QQuickItem, QQuickView
+
+
+class TestConnectionWithInvalidSignature(TimedQGuiApplication):
+ def onButtonClicked(self):
+ self.buttonClicked = True
+ self.app.quit()
+
+ def onButtonFailClicked(self):
+ pass
+
+ def testFailConnection(self):
+ self.buttonClicked = False
+ self.buttonFailClicked = False
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'connect_python_qml.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ root = view.rootObject()
+ self.assertTrue(root, quickview_errorstring(view))
+ button = root.findChild(QObject, "buttonMouseArea")
+ self.assertRaises(TypeError, QObject.connect,
+ [button, SIGNAL('entered()'), self.onButtonFailClicked])
+ button.entered.connect(self.onButtonClicked)
+ button.entered.emit()
+ view.show()
+ self.app.exec()
+ self.assertTrue(self.buttonClicked)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/connect_python_qml.qml b/sources/pyside6/tests/QtQml/connect_python_qml.qml
new file mode 100644
index 000000000..1ed171e96
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/connect_python_qml.qml
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+Rectangle {
+ id: page
+ width: 500; height: 200
+ color: "lightgray"
+
+ Rectangle {
+ id: button
+ width: 150; height: 40
+ color: "darkgray"
+ anchors.horizontalCenter: page.horizontalCenter
+ y: 150
+ MouseArea {
+ id: buttonMouseArea
+ objectName: "buttonMouseArea"
+ anchors.fill: parent
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/groupedproperty.py b/sources/pyside6/tests/QtQml/groupedproperty.py
new file mode 100644
index 000000000..4554d4b31
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/groupedproperty.py
@@ -0,0 +1,112 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""Test grouped properties (PYSIDE-1836)."""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QCoreApplication, QUrl, QObject, Property)
+from PySide6.QtQml import (QQmlComponent, QQmlEngine, QmlAnonymous, QmlElement)
+
+
+QML_IMPORT_NAME = "grouped"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class ShoeDescription(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._brand = ""
+ self._size = 0
+ self._price = 0
+
+ @Property(str)
+ def brand(self):
+ return self._brand
+
+ @brand.setter
+ def brand(self, b):
+ self._brand = b
+
+ @Property(int)
+ def size(self):
+ return self._size
+
+ @size.setter
+ def size(self, s):
+ self._size = s
+
+ @Property(int)
+ def price(self):
+ return self._price
+
+ @price.setter
+ def price(self, p):
+ self._price = p
+
+
+@QmlElement
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ""
+ self._shoe = ShoeDescription()
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(ShoeDescription)
+ def shoe(self):
+ return self._shoe
+
+
+def component_error(component):
+ result = ""
+ for e in component.errors():
+ if result:
+ result += "\n"
+ result += str(e)
+ return result
+
+
+class TestQmlGroupedProperties(unittest.TestCase):
+ def testIt(self):
+ app = QCoreApplication(sys.argv)
+ file = Path(__file__).resolve().parent / "groupedproperty.qml"
+ url = QUrl.fromLocalFile(file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+ person = component.create()
+ self.assertTrue(person, component_error(component))
+
+ # Check the meta type of the property
+ meta_object = person.metaObject()
+ index = meta_object.indexOfProperty("shoe")
+ self.assertTrue(index > 0)
+ meta_property = meta_object.property(index)
+ meta_type = meta_property.metaType()
+ self.assertTrue(meta_type.isValid())
+
+ # Check the values
+ self.assertEqual(person.shoe.brand, "Bikey")
+ self.assertEqual(person.shoe.price, 90)
+ self.assertEqual(person.shoe.size, 12)
+
+ del engine
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/groupedproperty.qml b/sources/pyside6/tests/QtQml/groupedproperty.qml
new file mode 100644
index 000000000..d32bd6005
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/groupedproperty.qml
@@ -0,0 +1,9 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import grouped
+
+Person {
+ name: "Bob Jones"
+ shoe { size: 12; brand: "Bikey"; price: 90 }
+}
diff --git a/sources/pyside6/tests/QtQml/hw.qml b/sources/pyside6/tests/QtQml/hw.qml
new file mode 100644
index 000000000..723901d96
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/hw.qml
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+Rectangle {
+ id: page
+ width: 500; height: 200
+ color: "lightgray"
+
+ Text {
+ id: helloText
+ text: "Hello world!"
+ y: 30
+ anchors.horizontalCenter: page.horizontalCenter
+ font.pointSize: 24; font.bold: true
+ }
+
+ Image {
+ // It's okay for this to fail.
+ source: "http://localhost/logo.png"
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/javascript_exceptions.py b/sources/pyside6/tests/QtQml/javascript_exceptions.py
new file mode 100644
index 000000000..e2b530aaf
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/javascript_exceptions.py
@@ -0,0 +1,91 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import Slot, Property, Signal, QObject, QUrl
+from PySide6.QtQml import QJSEngine, qmlRegisterType
+from PySide6.QtQuick import QQuickView
+
+test_error_message = "This is an error."
+
+method_test_string = """
+(function (obj) {
+ obj.methodThrows();
+})
+"""
+
+property_test_string = """
+(function (obj) {
+ obj.propertyThrows;
+})
+"""
+
+test_1 = False
+test_2 = False
+
+
+class TestClass(QObject):
+ @Slot()
+ def methodThrows(self):
+ raise TypeError(test_error_message)
+
+ @Property(str)
+ def propertyThrows(self):
+ raise TypeError(test_error_message)
+
+ @Slot(int)
+ def passTest(self, test):
+ global test_1, test_2
+
+ if test == 1:
+ test_1 = True
+ else:
+ test_2 = True
+
+
+class JavaScriptExceptionsTest(UsesQApplication):
+ def test_jsengine(self):
+ engine = QJSEngine()
+ test_object = TestClass()
+ test_value = engine.newQObject(test_object)
+
+ result_1 = engine.evaluate(method_test_string).call([test_value])
+
+ self.assertTrue(result_1.isError())
+ self.assertEqual(result_1.property('message').toString(), test_error_message)
+ self.assertEqual(result_1.property('name').toString(), 'TypeError')
+
+ result_2 = engine.evaluate(property_test_string).call([test_value])
+
+ self.assertTrue(result_2.isError())
+ self.assertEqual(result_2.property('message').toString(), test_error_message)
+ self.assertEqual(result_2.property('name').toString(), 'TypeError')
+
+ def test_qml_type(self):
+ qmlRegisterType(TestClass, 'JavaScriptExceptions', 1, 0, 'JavaScriptExceptions')
+
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'javascript_exceptions.qml'
+ self.assertTrue(file.is_file())
+ qml_url = QUrl.fromLocalFile(file)
+
+ view.setSource(qml_url)
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+
+ self.assertTrue(test_1)
+ self.assertTrue(test_2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/javascript_exceptions.qml b/sources/pyside6/tests/QtQml/javascript_exceptions.qml
new file mode 100644
index 000000000..1ab0fa3bb
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/javascript_exceptions.qml
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import QtQuick.Controls 2.0
+import JavaScriptExceptions 1.0
+
+Rectangle {
+ JavaScriptExceptions {
+ id: obj
+ }
+
+ Component.onCompleted: {
+ // Method call test
+ try {
+ obj.methodThrows();
+ } catch(e) {
+ obj.passTest(1);
+ }
+
+ // Property accessor test
+ try {
+ obj.propertyThrows;
+ } catch(e) {
+ obj.passTest(2);
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/listproperty.py b/sources/pyside6/tests/QtQml/listproperty.py
new file mode 100644
index 000000000..884600d29
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/listproperty.py
@@ -0,0 +1,136 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths # noqa: E402
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication # noqa: E402, F401
+
+from PySide6.QtCore import QObject, QUrl, Property, qInstallMessageHandler # noqa: E402
+from PySide6.QtQml import ListProperty, QmlElement # noqa: E402
+from PySide6.QtQuick import QQuickView # noqa: E402
+
+
+QML_IMPORT_NAME = "test.ListPropertyTest"
+QML_IMPORT_MAJOR_VERSION = 1
+
+output_messages = []
+
+
+def message_handler(mode, context, message):
+ global output_messages
+ output_messages.append(f"{message}")
+
+
+class InheritsQObject(QObject):
+ pass
+
+
+def dummyFunc():
+ pass
+
+
+@QmlElement
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent=None)
+ self._name = ''
+ self._friends = []
+
+ def appendFriend(self, friend):
+ self._friends.append(friend)
+
+ def friendCount(self):
+ return len(self._friends)
+
+ def friend(self, index):
+ return self._friends[index]
+
+ def removeLastItem(self):
+ if len(self._friends) > 0:
+ self._friends.pop()
+
+ def replace(self, index, friend):
+ if 0 <= index < len(self._friends):
+ self._friends[index] = friend
+
+ def clear(self):
+ self._friends.clear()
+
+ @Property(str, final=True)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ self._name = value
+
+ friends = ListProperty(QObject, append=appendFriend, count=friendCount, at=friend,
+ removeLast=removeLastItem, replace=replace, clear=clear)
+
+
+class TestListProperty(UsesQApplication):
+ def testIt(self):
+
+ # Verify that type checking works properly
+ type_check_error = False
+
+ try:
+ ListProperty(QObject)
+ ListProperty(InheritsQObject)
+ except Exception:
+ type_check_error = True
+
+ self.assertFalse(type_check_error)
+
+ try:
+ ListProperty(int)
+ except TypeError:
+ type_check_error = True
+
+ self.assertTrue(type_check_error)
+
+ # Verify that method validation works properly
+ method_check_error = False
+
+ try:
+ ListProperty(QObject, append=None, at=None, count=None, replace=None, clear=None,
+ removeLast=None) # Explicitly setting None
+ ListProperty(QObject, append=dummyFunc)
+ ListProperty(QObject, count=dummyFunc, at=dummyFunc)
+ except Exception:
+ method_check_error = True
+
+ self.assertFalse(method_check_error)
+
+ try:
+ ListProperty(QObject, append=QObject())
+ except Exception:
+ method_check_error = True
+
+ self.assertTrue(method_check_error)
+
+ def testListPropParameters(self):
+ global output_messages
+ qInstallMessageHandler(message_handler)
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'listproperty.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ view.show()
+ self.assertEqual(output_messages[0], "List length: 3")
+ self.assertEqual(output_messages[1], "First element: Alice")
+ self.assertEqual(output_messages[2], "Removing last item: Charlie")
+ self.assertEqual(output_messages[3], "Replacing last item: Bob")
+ self.assertEqual(output_messages[4], "Replaced last item: David")
+ self.assertEqual(output_messages[5], "List length after clearing: 0")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/listproperty.qml b/sources/pyside6/tests/QtQml/listproperty.qml
new file mode 100644
index 000000000..7b71e30ba
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/listproperty.qml
@@ -0,0 +1,50 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick 2.0
+import test.ListPropertyTest
+
+Rectangle {
+ width: 360
+ height: 360
+
+ Person {
+ id: person
+ friends: [
+ Person{
+ name: "Alice"
+ },
+ Person{
+ name: "Bob"
+ },
+ Person{
+ name: "Charlie"
+ }
+ ]
+ }
+
+ Person{
+ id: david
+ name: "David"
+ }
+
+ Component.onCompleted: {
+ // Access the length of the list
+ console.log("List length: " + person.friends.length);
+
+ // Access the first element of the list
+ console.log("First element: " + person.friends[0].name);
+
+ // Remove the last item of the list
+ console.log("Removing last item: " + person.friends.pop().name);
+
+ // Repalce the last item of the list
+ console.log("Replacing last item: " + person.friends[person.friends.length - 1].name);
+ person.friends[person.friends.length - 1] = david;
+ console.log("Replaced last item: " + person.friends[person.friends.length - 1].name);
+
+ // Clear the list
+ person.friends = [];
+ console.log("List length after clearing: " + person.friends.length);
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/qmlregistertype_test.py b/sources/pyside6/tests/QtQml/qmlregistertype_test.py
new file mode 100644
index 000000000..0042d6fd3
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qmlregistertype_test.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+
+from PySide6.QtCore import QCoreApplication, QObject # noqa: F401
+from PySide6.QtQml import QQmlApplicationEngine, qmlRegisterType
+
+
+class BaseClass(QObject):
+ def __init__(self, p=None):
+ super().__init__(p)
+
+
+class ChildClass(BaseClass):
+ def __init__(self, p=None):
+ super().__init__(p)
+
+
+class TestQmlRegisterType(UsesQApplication):
+ """Test the legacy QML register functions."""
+
+ def test(self):
+ qmlRegisterType(BaseClass, 'test', 1, 0, 'BaseClass')
+ qmlRegisterType(ChildClass, 'test', 1, 0, 'ChildClass')
+ # PYSIDE-2709: qmlRegisterType() would set additional class info
+ # on the meta objects for registration which caused another meta
+ # object to be created, breaking inheritance.
+ child = ChildClass()
+ base = BaseClass()
+ self.assertTrue(child.metaObject().inherits(base.metaObject()))
+
+ engine = QQmlApplicationEngine()
+ file = Path(__file__).resolve().parent / 'qmlregistertype_test.qml'
+
+ engine.load(file)
+ rootObjects = engine.rootObjects()
+ self.assertTrue(rootObjects)
+ self.assertTrue(type(rootObjects[0]), ChildClass)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/qmlregistertype_test.qml b/sources/pyside6/tests/QtQml/qmlregistertype_test.qml
new file mode 100644
index 000000000..108bb84b1
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qmlregistertype_test.qml
@@ -0,0 +1,7 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import test
+
+ChildClass {
+}
diff --git a/sources/pyside6/tests/QtQml/qqmlapplicationengine.qml b/sources/pyside6/tests/QtQml/qqmlapplicationengine.qml
new file mode 100644
index 000000000..77149ecdc
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qqmlapplicationengine.qml
@@ -0,0 +1,23 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtQuick.Window
+
+Window {
+ width: 300
+ height: 200
+ visible: true
+
+ Item {
+ width: 200
+ height: 60
+ Text {
+ anchors {
+ verticalCenter: parent.verticalCenter;
+ horizontalCenter: parent.horizontalCenter;
+ }
+ text: "Text"
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/qqmlapplicationengine_test.py b/sources/pyside6/tests/QtQml/qqmlapplicationengine_test.py
new file mode 100644
index 000000000..ea54e9e25
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qqmlapplicationengine_test.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for QQmlApplicationEngine'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtCore import QUrl, QObject, QTimer, Qt
+from PySide6.QtQml import QQmlApplicationEngine
+
+
+class TestQQmlApplicationEngine(TimedQGuiApplication):
+
+ def testQQmlApplicationEngine(self):
+ engine = QQmlApplicationEngine()
+
+ qml_file_path = Path(__file__).resolve().parent / "qqmlapplicationengine.qml"
+
+ # PYSIDE-1736: load from a string.
+ engine.load(os.fspath(qml_file_path))
+ rootObjects = engine.rootObjects()
+ self.assertTrue(rootObjects)
+ window = rootObjects[0]
+ window.setTitle("TestQQmlApplicationEngine")
+ QTimer.singleShot(100, window.close)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/qqmlcomponent_test.py b/sources/pyside6/tests/QtQml/qqmlcomponent_test.py
new file mode 100644
index 000000000..5521c64fa
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qqmlcomponent_test.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Property, QObject
+from PySide6.QtQml import QQmlComponent
+
+
+class WithComponent(QObject):
+ def get_component(self):
+ return None
+
+ component = Property(QQmlComponent, fget=get_component)
+
+
+class TestQmlSupport(unittest.TestCase):
+
+ def testMetatypeValid(self):
+ m = WithComponent.staticMetaObject
+ c = m.property(m.indexOfProperty("component"))
+
+ self.assertTrue(c.typeId() > 0)
+ self.assertTrue(c.typeName() == "QQmlComponent*")
+ self.assertTrue(c.metaType().isValid())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.py b/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.py
new file mode 100644
index 000000000..12a73e398
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+
+from PySide6.QtCore import QObject, QUrl, Slot, QTimer
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import QQmlIncubationController, VolatileBool
+from PySide6.QtQuick import QQuickView
+
+
+class CustomIncubationController(QObject, QQmlIncubationController):
+ def __init__(self, test):
+ QObject.__init__(self)
+ QQmlIncubationController.__init__(self)
+ self.test = test
+ self.interrupted = False
+
+ # Incubate every 50 milliseconds
+ self.startTimer(50)
+ self.incubationShouldContinue = VolatileBool(True)
+ self.test.assertEqual(self.incubationShouldContinue.get(), True)
+
+ @Slot()
+ def interrupter(self):
+ if not self.interrupted:
+ self.interrupted = True
+ self.incubationShouldContinue.set(False)
+ self.test.assertEqual(self.incubationShouldContinue.get(), False)
+ QTimer.singleShot(0, QGuiApplication.instance().quit)
+
+ def timerEvent(self, ev):
+ # Incubate items for 2000 milliseconds, or until the volatile bool is set to false.
+ self.incubateWhile(self.incubationShouldContinue, 2000)
+
+
+class TestBug(unittest.TestCase):
+ def testIncubateWhileCall(self):
+ app = QGuiApplication(sys.argv)
+ view = QQuickView()
+ controller = CustomIncubationController(self)
+ view.engine().setIncubationController(controller)
+ view.setResizeMode(QQuickView.SizeRootObjectToView)
+ file = Path(__file__).resolve().parent / 'qqmlincubator_incubateWhile.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.show()
+
+ root = view.rootObject()
+ # The QML code will issue an interrupt signal after half of its items are loaded.
+ root.shouldInterrupt.connect(controller.interrupter)
+ res = app.exec()
+
+ itemsToCreate = root.property("itemsToCreate")
+ loadedItems = root.property("loadedItems")
+ self.assertEqual(loadedItems, itemsToCreate / 2)
+
+ # Finish incubating the remaining items.
+ controller.incubateFor(1000)
+ loadedItems = root.property("loadedItems")
+ self.assertEqual(loadedItems, itemsToCreate)
+
+ # Deleting the view before it goes out of scope is required to make sure all child QML
+ # instances are destroyed in the correct order.
+ del view
+ del app
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.qml b/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.qml
new file mode 100644
index 000000000..803dec128
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile.qml
@@ -0,0 +1,42 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+import QtQuick 2.0
+
+
+Rectangle {
+ id: root
+ objectName: "theNicestRoot"
+ width: 400; height: 400
+
+ signal shouldInterrupt()
+ property int loadedItems: 0
+ property int itemsToCreate: 10
+
+ Row {
+ anchors.centerIn: parent
+ spacing: 20
+
+ Rectangle {
+ id: initialRectangle
+ width: 10; height: 10
+ color: "red"
+ }
+
+ Repeater {
+ model: itemsToCreate
+ Loader {
+ id: loader
+ asynchronous: true
+ source: "qqmlincubator_incubateWhile_component.qml"
+ onLoaded: {
+ root.loadedItems += 1
+
+ // Interrupt incubation after half of the items are loaded.
+ if (root.loadedItems >= (itemsToCreate / 2)) {
+ root.shouldInterrupt()
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile_component.qml b/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile_component.qml
new file mode 100644
index 000000000..0f6693952
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qqmlincubator_incubateWhile_component.qml
@@ -0,0 +1,10 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 10; height: 10
+ color: "yellow"
+}
diff --git a/sources/pyside6/tests/QtQml/qqmlnetwork_test.py b/sources/pyside6/tests/QtQml/qqmlnetwork_test.py
new file mode 100644
index 000000000..abdb4529e
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qqmlnetwork_test.py
@@ -0,0 +1,76 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QQmlNetwork'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUrl, QTimer
+from PySide6.QtGui import QGuiApplication, QWindow
+from PySide6.QtQuick import QQuickView
+from PySide6.QtQml import QQmlNetworkAccessManagerFactory
+from PySide6.QtNetwork import QNetworkAccessManager
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+
+
+request_created = False
+
+
+def check_done():
+ global request_created
+ if request_created:
+ windows = QGuiApplication.topLevelWindows()
+ if windows:
+ windows[0].close()
+
+
+class CustomManager(QNetworkAccessManager):
+ """CustomManager (running in a different thread)"""
+ def createRequest(self, op, req, data=None):
+ global request_created
+ print(">> createRequest ", self, op, req.url(), data)
+ request_created = True
+ return QNetworkAccessManager.createRequest(self, op, req, data)
+
+
+class CustomFactory(QQmlNetworkAccessManagerFactory):
+ def create(self, parent=None):
+ return CustomManager()
+
+
+class TestQQmlNetworkFactory(TimedQGuiApplication):
+ def setUp(self):
+ super().setUp(timeout=2000)
+
+ def testQQuickNetworkFactory(self):
+ view = QQuickView()
+ self.factory = CustomFactory()
+ view.engine().setNetworkAccessManagerFactory(self.factory)
+
+ file = Path(__file__).resolve().parent / 'hw.qml'
+ self.assertTrue(file.is_file())
+ url = QUrl.fromLocalFile(file)
+
+ view.setSource(url)
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.show()
+
+ self.assertEqual(view.status(), QQuickView.Ready)
+
+ timer = QTimer()
+ timer.timeout.connect(check_done)
+ timer.start(50)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/qquickitem_grabToImage.py b/sources/pyside6/tests/QtQml/qquickitem_grabToImage.py
new file mode 100644
index 000000000..25341b0b2
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qquickitem_grabToImage.py
@@ -0,0 +1,69 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+from PySide6.QtCore import QTimer, QUrl
+from PySide6.QtGui import QColor
+from PySide6.QtQuick import QQuickItem, QQuickView
+
+
+class TestGrabToSharedPointerImage(TimedQGuiApplication):
+ def setUp(self):
+ super().setUp(1000)
+
+ def testQQuickItemGrabToImageSharedPointer(self):
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'qquickitem_grabToImage.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.show()
+
+ # Get the QQuickItem objects for the blue Rectangle and the Image item.
+ root = view.rootObject()
+ blueRectangle = root.findChild(QQuickItem, "blueRectangle")
+ imageContainer = root.findChild(QQuickItem, "imageContainer")
+
+ # Start the image grabbing.
+ grabResultSharedPtr = blueRectangle.grabToImage()
+
+ # Implicit call of operator bool() of the smart pointer, to check that it holds
+ # a valid pointer.
+ self.assertTrue(grabResultSharedPtr)
+
+ self.grabbedColor = None
+
+ def onGrabReady():
+ # Signal early exit.
+ QTimer.singleShot(50, self.app.quit)
+
+ # Show the grabbed image in the QML Image item.
+ imageContainer.setProperty("source", grabResultSharedPtr.url())
+
+ # Wait for signal when grabbing is complete.
+ grabResultSharedPtr.ready.connect(onGrabReady)
+ self.app.exec()
+
+ # Get the first pixel color of the grabbed image.
+ self.image = grabResultSharedPtr.image()
+ self.assertTrue(self.image)
+ self.grabbedColor = self.image.pixelColor(0, 0)
+ self.assertTrue(self.grabbedColor.isValid())
+
+ # Compare the grabbed color with the one we set in the rectangle.
+ blueColor = QColor("blue")
+ self.assertEqual(self.grabbedColor, blueColor)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/qquickitem_grabToImage.qml b/sources/pyside6/tests/QtQml/qquickitem_grabToImage.qml
new file mode 100644
index 000000000..90235f078
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qquickitem_grabToImage.qml
@@ -0,0 +1,44 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+Item {
+ id: root
+ width: 600
+ height: 600
+
+ Rectangle {
+ id: blue
+ objectName: "blueRectangle"
+ width: 200
+ height: 200
+ anchors.top: root.top
+ anchors.horizontalCenter: root.horizontalCenter
+ color: "blue"
+ }
+
+ Text {
+ text: qsTr("Original blue rectangle")
+ anchors.left: blue.right
+ anchors.verticalCenter: blue.verticalCenter
+ }
+
+ Image {
+ id: imageContainer
+ objectName: "imageContainer"
+ width: 200
+ height: 200
+ anchors.bottom: root.bottom
+ anchors.horizontalCenter: root.horizontalCenter
+ }
+
+ Text {
+ text: qsTr("Image with the source URL set to the result of calling QQuickItem::grabToImage on the rectangle. If you see a second blue rectangle, that means it works.")
+ anchors.left: imageContainer.right
+ anchors.verticalCenter: imageContainer.verticalCenter
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ width: 200
+ }
+
+}
diff --git a/sources/pyside6/tests/QtQml/qquickview_test.py b/sources/pyside6/tests/QtQml/qquickview_test.py
new file mode 100644
index 000000000..226509669
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/qquickview_test.py
@@ -0,0 +1,87 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QQuickView'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtCore import QUrl, QObject, Property, Slot, Signal
+from PySide6.QtQml import QQmlEngine, QQmlContext
+from PySide6.QtQuick import QQuickView
+
+
+class MyObject(QObject):
+ titleChanged = Signal()
+
+ def __init__(self, text, parent=None):
+ QObject.__init__(self, parent)
+ self._text = text
+
+ def getText(self):
+ return self._text
+
+ @Slot(str)
+ def qmlText(self, text):
+ self._qmlText = text
+
+ title = Property(str, getText, notify=titleChanged)
+
+
+class TestQQuickView(TimedQGuiApplication):
+
+ def testQQuickViewList(self):
+ view = QQuickView()
+
+ dataList = ["Item 1", "Item 2", "Item 3", "Item 4"]
+
+ view.setInitialProperties({"model": dataList})
+
+ file = Path(__file__).resolve().parent / 'view.qml'
+ self.assertTrue(file.is_file())
+ url = QUrl.fromLocalFile(file)
+ view.setSource(url)
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.show()
+
+ self.assertEqual(view.status(), QQuickView.Ready)
+ rootObject = view.rootObject()
+ self.assertTrue(rootObject)
+ context = QQmlEngine.contextForObject(rootObject)
+ self.assertTrue(context)
+ self.assertTrue(context.engine())
+
+ test_context = QQmlContext(context) # Context properties, PYSIDE-1921
+ prop_pair = QQmlContext.PropertyPair()
+ prop_pair.name = "testProperty"
+ prop_pair.value = 42
+ test_context.setContextProperties([prop_pair])
+ self.assertTrue(test_context.contextProperty("testProperty"), 42)
+
+ def testModelExport(self):
+ view = QQuickView()
+ dataList = [MyObject("Item 1"), MyObject("Item 2"), MyObject("Item 3"), MyObject("Item 4")]
+
+ view.setInitialProperties({"model": dataList})
+
+ file = Path(__file__).resolve().parent / 'viewmodel.qml'
+ self.assertTrue(file.is_file())
+ url = QUrl.fromLocalFile(file)
+ view.setSource(url)
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.show()
+
+ self.assertEqual(view.status(), QQuickView.Ready)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registerattached.py b/sources/pyside6/tests/QtQml/registerattached.py
new file mode 100644
index 000000000..dd300dc89
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerattached.py
@@ -0,0 +1,101 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QCoreApplication, QUrl, QObject, Property)
+from PySide6.QtQml import (QQmlComponent, QQmlEngine, QmlAnonymous,
+ QmlAttached, QmlElement, ListProperty,
+ qmlAttachedPropertiesObject)
+
+
+QML_IMPORT_NAME = "TestLayouts"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+EXPECTED_MARGINS = [10, 20]
+
+
+def component_error(component):
+ result = ""
+ for e in component.errors():
+ if result:
+ result += "\n"
+ result += str(e)
+ return result
+
+
+@QmlAnonymous
+class TestLayoutAttached(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._leftMargin = 0
+
+ @Property(int)
+ def leftMargin(self):
+ return self._leftMargin
+
+ @leftMargin.setter
+ def leftMargin(self, m):
+ self._leftMargin = m
+
+
+@QmlElement
+class TestWidget(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+@QmlElement
+@QmlAttached(TestLayoutAttached)
+class TestLayout(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._widgets = []
+
+ def widget(self, n):
+ return self._widgets[n]
+
+ def widgetCount(self):
+ return len(self._widgets)
+
+ def addWidget(self, w):
+ self._widgets.append(w)
+
+ @staticmethod
+ def qmlAttachedProperties(self, o):
+ return TestLayoutAttached(o)
+
+ widgets = ListProperty(TestWidget, addWidget)
+
+
+class TestQmlAttached(unittest.TestCase):
+ def testIt(self):
+ app = QCoreApplication(sys.argv)
+ file = Path(__file__).resolve().parent / 'registerattached.qml'
+ url = QUrl.fromLocalFile(file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+ layout = component.create()
+ self.assertTrue(layout, component_error(component))
+
+ actual_margins = []
+ for i in range(layout.widgetCount()):
+ w = layout.widget(i)
+ a = qmlAttachedPropertiesObject(TestLayout, w, False)
+ actual_margins.append(a.leftMargin)
+ self.assertEqual(EXPECTED_MARGINS, actual_margins)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registerattached.qml b/sources/pyside6/tests/QtQml/registerattached.qml
new file mode 100644
index 000000000..7ae8730bd
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerattached.qml
@@ -0,0 +1,20 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import TestLayouts
+
+TestLayout {
+ id: layout
+
+ widgets: [
+ TestWidget {
+ id: widget1
+ TestLayout.leftMargin: 10
+ },
+
+ TestWidget {
+ id: widget2
+ TestLayout.leftMargin: 20
+ }
+ ]
+}
diff --git a/sources/pyside6/tests/QtQml/registerextended.py b/sources/pyside6/tests/QtQml/registerextended.py
new file mode 100644
index 000000000..b87b5aaaf
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerextended.py
@@ -0,0 +1,74 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QCoreApplication, QUrl, QObject,
+ Property)
+from PySide6.QtQml import (QQmlComponent, QQmlEngine, QmlExtended,
+ QmlElement)
+
+
+"""Test for the QmlExtended decorator. Extends a class TestWidget
+ by a property leftMargin through a TestExtension and verifies the setting."""
+
+
+QML_IMPORT_NAME = "TestExtension"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+def component_error(component):
+ result = ""
+ for e in component.errors():
+ if result:
+ result += "\n"
+ result += str(e)
+ return result
+
+
+class TestExtension(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._leftMargin = 0
+
+ @Property(int)
+ def leftMargin(self):
+ return self._leftMargin
+
+ @leftMargin.setter
+ def leftMargin(self, m):
+ self._leftMargin = m
+
+
+@QmlElement
+@QmlExtended(TestExtension)
+class TestWidget(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+class TestQmlExtended(unittest.TestCase):
+ def testIt(self):
+ app = QCoreApplication(sys.argv)
+ file = Path(__file__).resolve().parent / 'registerextended.qml'
+ url = QUrl.fromLocalFile(file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+ widget = component.create()
+ self.assertTrue(widget, component_error(component))
+ extension = widget.findChild(TestExtension)
+ self.assertTrue(extension)
+ self.assertEqual(extension.leftMargin, 10)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registerextended.qml b/sources/pyside6/tests/QtQml/registerextended.qml
new file mode 100644
index 000000000..74095f83f
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerextended.qml
@@ -0,0 +1,9 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import TestExtension
+
+TestWidget {
+ id: widget1
+ leftMargin: 10
+}
diff --git a/sources/pyside6/tests/QtQml/registerforeign.py b/sources/pyside6/tests/QtQml/registerforeign.py
new file mode 100644
index 000000000..d9a982d95
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerforeign.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import qmlcomponent_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtCore import Property, QObject, QUrl, qVersion
+from PySide6.QtGui import QGuiApplication, QRasterWindow
+from PySide6.QtQml import (QmlNamedElement, QmlForeign, QQmlEngine,
+ QQmlComponent)
+
+
+"""Test the QmlForeign decorator, letting the QQmlEngine create a QRasterWindow."""
+
+
+QML_IMPORT_NAME = "Foreign"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlNamedElement("QRasterWindow")
+@QmlForeign(QRasterWindow)
+class RasterWindowForeign(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+class TestQmlForeign(TimedQGuiApplication):
+
+ def testIt(self):
+ engine = QQmlEngine()
+ file = Path(__file__).resolve().parent / 'registerforeign.qml'
+ self.assertTrue(file.is_file())
+ component = QQmlComponent(engine, QUrl.fromLocalFile(file))
+ window = component.create()
+ self.assertTrue(window, qmlcomponent_errorstring(component))
+ self.assertEqual(type(window), QRasterWindow)
+ window.setTitle(f"Qt {qVersion()}")
+ window.show()
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registerforeign.qml b/sources/pyside6/tests/QtQml/registerforeign.qml
new file mode 100644
index 000000000..0537abb7c
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerforeign.qml
@@ -0,0 +1,8 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import Foreign
+
+QRasterWindow {
+ id: rasterWindow
+}
diff --git a/sources/pyside6/tests/QtQml/registerparserstatus.py b/sources/pyside6/tests/QtQml/registerparserstatus.py
new file mode 100644
index 000000000..bbcc14635
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerparserstatus.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QCoreApplication, QUrl)
+from PySide6.QtQml import (QQmlComponent, QQmlEngine,
+ QmlElement, QPyQmlParserStatus)
+
+
+QML_IMPORT_NAME = "ParserStatus"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+def component_error(component):
+ result = ""
+ for e in component.errors():
+ if result:
+ result += "\n"
+ result += str(e)
+ return result
+
+
+@QmlElement
+class TestItem(QPyQmlParserStatus):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.component_complete_called = False
+ self.class_begin_called = False
+
+ def componentComplete(self):
+ self.component_complete_called = True
+
+ def classBegin(self):
+ self.class_begin_called = True
+
+
+class TestQmlAttached(unittest.TestCase):
+ def testIt(self):
+ app = QCoreApplication(sys.argv)
+ file = Path(__file__).resolve().parent / 'registerparserstatus.qml'
+ url = QUrl.fromLocalFile(file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+ item = component.create()
+ self.assertTrue(item, component_error(component))
+ self.assertTrue(item.component_complete_called)
+ self.assertTrue(item.class_begin_called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registerparserstatus.qml b/sources/pyside6/tests/QtQml/registerparserstatus.qml
new file mode 100644
index 000000000..a39f03227
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerparserstatus.qml
@@ -0,0 +1,8 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import ParserStatus
+
+TestItem {
+ id: item
+}
diff --git a/sources/pyside6/tests/QtQml/registerqmlfile.py b/sources/pyside6/tests/QtQml/registerqmlfile.py
new file mode 100644
index 000000000..335652e5d
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registerqmlfile.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDir, QUrl
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import qmlRegisterType
+
+
+class TestQmlSupport(unittest.TestCase):
+
+ def testIt(self):
+ app = QGuiApplication([])
+
+ file = os.fspath(Path(__file__).resolve().parent / 'ModuleType.qml')
+ url = QUrl.fromLocalFile(QDir.fromNativeSeparators(file))
+ result = qmlRegisterType(url, "CustomModule", 1, 0, "ModuleType")
+ self.assertTrue(result != -1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registersingletontype.py b/sources/pyside6/tests/QtQml/registersingletontype.py
new file mode 100644
index 000000000..6beca1131
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registersingletontype.py
@@ -0,0 +1,152 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+
+from PySide6.QtCore import Property, Signal, QTimer, QUrl, QObject, Slot
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import (qmlRegisterSingletonType, qmlRegisterSingletonInstance,
+ QmlElement, QmlSingleton, QJSValue)
+from PySide6.QtQuick import QQuickView
+
+
+URI = "Singletons"
+
+
+finalResult = 0
+qObjectQmlTypeId = 0
+
+
+class SingletonQObject(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+ self._data = 100
+
+ def getData(self):
+ return self._data
+
+ def setData(self, data):
+ global finalResult
+ finalResult = self._data = data
+
+ data = Property(int, getData, setData)
+
+
+def singletonQObjectCallback(engine):
+ obj = SingletonQObject()
+ obj.setData(50)
+ return obj
+
+
+def singletonQJSValueCallback(engine):
+ return engine.evaluate("new Object({data: 50})")
+
+
+QML_IMPORT_NAME = URI
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+@QmlSingleton
+class DecoratedSingletonQObject(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._data = 200
+
+ def getData(self):
+ return self._data
+
+ def setData(self, data):
+ self._data = data
+
+ data = Property(int, getData, setData)
+
+
+@QmlElement
+@QmlSingleton
+class DecoratedSingletonWithCreate(QObject):
+ def __init__(self, data, parent=None):
+ super().__init__(parent)
+ self._data = data
+
+ @staticmethod
+ def create(engine):
+ return DecoratedSingletonWithCreate(400)
+
+ def getData(self):
+ return self._data
+
+ def setData(self, data):
+ self._data = data
+
+ data = Property(int, getData, setData)
+
+
+class TestQuickView(QQuickView):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._singleton_instance_qobject_int = False
+ self._singleton_instance_qobject_str = False
+ self._singleton_instance_jsvalue_int = False
+
+ @Slot()
+ def testSlot(self):
+ engine = self.engine()
+ instance = engine.singletonInstance(qObjectQmlTypeId)
+ if instance is not None and isinstance(instance, QObject):
+ self._singleton_instance_qobject_int = True
+ instance = engine.singletonInstance(URI, 'SingletonQObjectNoCallback')
+ if instance is not None and isinstance(instance, QObject):
+ self._singleton_instance_qobject_str = True
+ instance = engine.singletonInstance(URI, 'SingletonQJSValue')
+ if instance is not None and isinstance(instance, QJSValue):
+ self._singleton_instance_jsvalue_int = True
+ self.close()
+
+
+class TestQmlSupport(unittest.TestCase):
+ def testIt(self):
+ app = QGuiApplication([])
+
+ qObjectQmlTypeId = qmlRegisterSingletonType(SingletonQObject, URI, 1, 0,
+ 'SingletonQObjectNoCallback')
+ qmlRegisterSingletonType(SingletonQObject, URI, 1, 0, 'SingletonQObjectCallback',
+ singletonQObjectCallback)
+
+ qmlRegisterSingletonType(URI, 1, 0, 'SingletonQJSValue', singletonQJSValueCallback)
+
+ # Accepts only QObject derived types
+ l = [1, 2]
+ with self.assertRaises(TypeError):
+ qmlRegisterSingletonInstance(SingletonQObject, URI, 1, 0, 'SingletonInstance', l)
+
+ # Modify value on the instance
+ s = SingletonQObject()
+ s.setData(99)
+ qmlRegisterSingletonInstance(SingletonQObject, URI, 1, 0, 'SingletonInstance', s)
+
+ view = TestQuickView()
+ file = Path(__file__).resolve().parent / 'registersingletontype.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ self.assertTrue(view.rootObject(), quickview_errorstring(view))
+ view.resize(200, 200)
+ view.show()
+ QTimer.singleShot(250, view.testSlot)
+ app.exec()
+ self.assertEqual(finalResult, 899)
+ self.assertTrue(view._singleton_instance_qobject_int)
+ self.assertTrue(view._singleton_instance_qobject_str)
+ self.assertTrue(view._singleton_instance_jsvalue_int)
+
+
+if __name__ == '__main__': unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registersingletontype.qml b/sources/pyside6/tests/QtQml/registersingletontype.qml
new file mode 100644
index 000000000..31ca7fe4d
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registersingletontype.qml
@@ -0,0 +1,14 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import Singletons 1.0
+
+Item {
+ Component.onCompleted: {
+ SingletonQObjectCallback.data += SingletonQObjectNoCallback.data
+ + SingletonQJSValue.data
+ + SingletonInstance.data
+ + DecoratedSingletonQObject.data + DecoratedSingletonWithCreate.data;
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/registertype.py b/sources/pyside6/tests/QtQml/registertype.py
new file mode 100644
index 000000000..6c9874f32
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registertype.py
@@ -0,0 +1,116 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+
+from PySide6.QtCore import Property, QObject, QTimer, QUrl
+from PySide6.QtGui import QGuiApplication, QPen, QColor, QPainter
+from PySide6.QtQml import (qjsEngine, qmlContext, qmlEngine, qmlRegisterType,
+ ListProperty, QmlElement, QmlNamedElement)
+from PySide6.QtQuick import QQuickView, QQuickItem, QQuickPaintedItem
+
+
+QML_IMPORT_NAME = "Charts"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class PieSlice (QQuickPaintedItem):
+ def __init__(self, parent=None):
+ QQuickPaintedItem.__init__(self, parent)
+ self._color = QColor()
+ self._fromAngle = 0
+ self._angleSpan = 0
+
+ def getColor(self):
+ return self._color
+
+ def setColor(self, value):
+ self._color = value
+
+ def getFromAngle(self):
+ return self._angle
+
+ def setFromAngle(self, value):
+ self._fromAngle = value
+
+ def getAngleSpan(self):
+ return self._angleSpan
+
+ def setAngleSpan(self, value):
+ self._angleSpan = value
+
+ color = Property(QColor, getColor, setColor)
+ fromAngle = Property(int, getFromAngle, setFromAngle)
+ angleSpan = Property(int, getAngleSpan, setAngleSpan)
+
+ def paint(self, painter):
+ global paintCalled
+ pen = QPen(self._color, 2)
+ painter.setPen(pen)
+ painter.setRenderHints(QPainter.Antialiasing, True)
+ painter.drawPie(self.boundingRect(), self._fromAngle * 16, self._angleSpan * 16)
+ paintCalled = True
+
+
+@QmlNamedElement("PieChart")
+class PieChartOriginalName(QQuickItem):
+ def __init__(self, parent=None):
+ QQuickItem.__init__(self, parent)
+ self._name = ''
+ self._slices = []
+
+ def getName(self):
+ return self._name
+
+ def setName(self, value):
+ self._name = value
+
+ name = Property(str, getName, setName)
+
+ def appendSlice(self, _slice):
+ global appendCalled
+ _slice.setParentItem(self)
+ self._slices.append(_slice)
+ appendCalled = True
+
+ slices = ListProperty(PieSlice, append=appendSlice)
+
+
+appendCalled = False
+paintCalled = False
+
+
+class TestQmlSupport(unittest.TestCase):
+
+ def testIt(self):
+ app = QGuiApplication([])
+
+ view = QQuickView()
+ file = Path(__file__).resolve().parent / 'registertype.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ root_object = view.rootObject()
+ self.assertTrue(root_object, quickview_errorstring(view))
+ self.assertTrue(qjsEngine(root_object))
+ self.assertEqual(qmlEngine(root_object), view.engine())
+ self.assertTrue(qmlContext(root_object))
+
+ view.show()
+ QTimer.singleShot(250, view.close)
+ app.exec()
+ self.assertTrue(appendCalled)
+ self.assertTrue(paintCalled)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/registertype.qml b/sources/pyside6/tests/QtQml/registertype.qml
new file mode 100644
index 000000000..3be2f9f04
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registertype.qml
@@ -0,0 +1,32 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import Charts 1.0
+
+Item {
+ width: 300; height: 200
+
+ PieChart {
+ anchors.centerIn: parent
+ width: 100; height: 100
+
+ slices: [
+ PieSlice {
+ anchors.fill: parent
+ color: "red"
+ fromAngle: 0; angleSpan: 110
+ },
+ PieSlice {
+ anchors.fill: parent
+ color: "black"
+ fromAngle: 110; angleSpan: 50
+ },
+ PieSlice {
+ anchors.fill: parent
+ color: "blue"
+ fromAngle: 160; angleSpan: 100
+ }
+ ]
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/registeruncreatable.qml b/sources/pyside6/tests/QtQml/registeruncreatable.qml
new file mode 100644
index 000000000..b121c014d
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registeruncreatable.qml
@@ -0,0 +1,13 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import Charts 1.0
+
+Item {
+ width: 300; height: 200
+
+ Uncreatable {
+ name : 'uncreatable'
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/registeruncreatabletype.py b/sources/pyside6/tests/QtQml/registeruncreatabletype.py
new file mode 100644
index 000000000..3a4df69f6
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/registeruncreatabletype.py
@@ -0,0 +1,62 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import qmlcomponent_errorstring
+
+from PySide6.QtCore import Property, QObject, QUrl
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtQml import QmlElement, QmlUncreatable, QQmlEngine, QQmlComponent
+
+noCreationReason = 'Cannot create an item of type: Uncreatable (expected)'
+
+QML_IMPORT_NAME = "Charts"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+@QmlUncreatable(noCreationReason)
+class Uncreatable(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+ self._name = 'uncreatable'
+
+ def getName(self):
+ return self._name
+
+ def setName(self, value):
+ self._name = value
+
+ name = Property(str, getName, setName)
+
+
+class TestQmlSupport(unittest.TestCase):
+
+ def testIt(self):
+ app = QGuiApplication([])
+
+ engine = QQmlEngine()
+ file = Path(__file__).resolve().parent / 'registeruncreatable.qml'
+ self.assertTrue(file.is_file())
+ component = QQmlComponent(engine, QUrl.fromLocalFile(file))
+
+ # Check that the uncreatable item produces the correct error
+ self.assertEqual(component.status(), QQmlComponent.Error)
+ errorFound = False
+ for e in component.errors():
+ if noCreationReason in e.toString():
+ errorFound = True
+ break
+ self.assertTrue(errorFound)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/signal_arguments.py b/sources/pyside6/tests/QtQml/signal_arguments.py
new file mode 100644
index 000000000..f5b0f8bd3
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/signal_arguments.py
@@ -0,0 +1,61 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtQuick import QQuickView
+from PySide6.QtCore import QObject, Signal, Slot, QUrl, QTimer, Property
+from PySide6.QtQml import QmlElement
+
+QML_IMPORT_NAME = "test.Obj"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class Obj(QObject):
+ def __init__(self):
+ super().__init__()
+ self.value = 0
+
+ sumResult = Signal(int, name="sumResult", arguments=['sum'])
+
+ @Slot(int, int)
+ def sum(self, arg1, arg2):
+ self.sumResult.emit(arg1 + arg2)
+
+ @Slot(str)
+ def sendValue(self, s):
+ self.value = int(s)
+
+
+class TestConnectionWithQml(TimedQGuiApplication):
+
+ def testSignalArguments(self):
+ view = QQuickView()
+ obj = Obj()
+
+ view.setInitialProperties({"o": obj})
+ file = Path(__file__).resolve().parent / 'signal_arguments.qml'
+ self.assertTrue(file.is_file())
+ view.setSource(QUrl.fromLocalFile(file))
+ root = view.rootObject()
+ self.assertTrue(root, quickview_errorstring(view))
+ button = root.findChild(QObject, "button")
+ self.assertTrue(button)
+ view.show()
+ button.clicked.emit()
+ self.assertEqual(obj.value, 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/signal_arguments.qml b/sources/pyside6/tests/QtQml/signal_arguments.qml
new file mode 100644
index 000000000..dbc991c77
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/signal_arguments.qml
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+
+import QtQuick 2.5
+import QtQuick.Controls 2.12
+import QtQuick.Layouts 1.2
+import test.Obj 1.0
+
+Rectangle {
+ visible: true
+ required property Obj o
+ GridLayout {
+ Button {
+ id: button
+ objectName: "button"
+ text: "sum!"
+ onClicked: {
+ o.sum(40, 2)
+ }
+ }
+ Text {
+ id: sumResultText
+ }
+ }
+ Connections {
+ target: o
+ function onSumResult(sum) {
+ // set the value on the Qml side
+ sumResultText.text = sum
+ // set internal Python value from the already
+ // modified value
+ o.sendValue(sumResultText.text)
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/signal_types.py b/sources/pyside6/tests/QtQml/signal_types.py
new file mode 100644
index 000000000..240c0fd6e
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/signal_types.py
@@ -0,0 +1,124 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import json
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.helper import quickview_errorstring
+from helper.timedqguiapplication import TimedQGuiApplication
+
+from PySide6.QtQuick import QQuickView
+from PySide6.QtCore import QObject, Signal, Slot, QUrl
+from PySide6.QtQml import QmlElement
+
+"""PYSIDE-2098: Roundtrip test for signals using QVariantList/QVariantMap.
+
+@QmlElement Obj has signals of list/dict type which are connected to an
+instance of Connections in QML. The QML instance sends them back to Obj's
+slots and additionally sends them back as stringified JSON. This verifies that
+a conversion is done instead of falling back to the default PyObject
+passthrough converter, resulting in a QVariant<PyObject> and reference leaks
+on the PyObject.
+"""
+
+QML_IMPORT_NAME = "test.Obj"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class Obj(QObject):
+ listSignal = Signal(list)
+ dictSignal = Signal(dict)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._last_data = None
+ self._last_json_data = None
+
+ def clear(self):
+ self._last_data = None
+ self._last_json_data = None
+
+ def last_data(self):
+ """Last data received."""
+ return self._last_data
+
+ def last_json_data(self):
+ """Last data converted from JSON."""
+ return self._last_json_data
+
+ def emit_list(self, test_list):
+ self.listSignal.emit(test_list)
+
+ def emit_dict(self, test_dict):
+ self.dictSignal.emit(test_dict)
+
+ @Slot(list)
+ def list_slot(self, l):
+ self._last_data = l
+ print("list_slot", l)
+
+ @Slot(dict)
+ def dict_slot(self, d):
+ self._last_data = d
+ print("dict_slot", d)
+
+ @Slot(str)
+ def json_slot(self, s):
+ self._last_json_data = json.loads(s)
+ print(f'json_slot "{s}"->', self._last_json_data)
+
+
+class TestConnectionWithQml(TimedQGuiApplication):
+
+ def setUp(self):
+ super().setUp()
+ self._view = QQuickView()
+ self._obj = Obj()
+
+ self._view.setInitialProperties({"o": self._obj})
+ file = Path(__file__).resolve().parent / "signal_types.qml"
+ self.assertTrue(file.is_file())
+ self._view.setSource(QUrl.fromLocalFile(file))
+ root = self._view.rootObject()
+ self.assertTrue(root, quickview_errorstring(self._view))
+
+ def tearDown(self):
+ super().tearDown()
+ del self._view
+ self._view = None
+
+ def testVariantList(self):
+ self._obj.clear()
+ test_list = [1, 2]
+ before_refcount = sys.getrefcount(test_list)
+ self._obj.emit_list(test_list)
+ received = self._obj.last_data()
+ self.assertTrue(isinstance(received, list))
+ self.assertEqual(test_list, received)
+ self.assertEqual(test_list, self._obj.last_json_data())
+ refcount = sys.getrefcount(test_list)
+ self.assertEqual(before_refcount, refcount)
+
+ def testVariantDict(self):
+ self._obj.clear()
+ test_dict = {"1": 1, "2": 2}
+ before_refcount = sys.getrefcount(test_dict)
+ self._obj.emit_dict(test_dict)
+ received = self._obj.last_data()
+ self.assertTrue(isinstance(received, dict))
+ self.assertEqual(test_dict, received)
+ self.assertEqual(test_dict, self._obj.last_json_data())
+ refcount = sys.getrefcount(test_dict)
+ self.assertEqual(before_refcount, refcount)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtQml/signal_types.qml b/sources/pyside6/tests/QtQml/signal_types.qml
new file mode 100644
index 000000000..6b03b3abd
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/signal_types.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import test.Obj
+
+Rectangle {
+ visible: true
+ required property Obj o
+
+ Connections {
+ target: o
+ function onListSignal(list) {
+ var json_data = JSON.stringify(list)
+ console.log("Connections.onListSignal: " + typeof(list) + " " + json_data)
+ o.list_slot(list)
+ o.json_slot(json_data)
+ }
+ function onDictSignal(dict) {
+ var json_data = JSON.stringify(dict)
+ console.log("Connections.onDictSignal: " + typeof(dict) + " " + json_data)
+ o.dict_slot(dict)
+ o.json_slot(json_data)
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/view.qml b/sources/pyside6/tests/QtQml/view.qml
new file mode 100644
index 000000000..8557271c2
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/view.qml
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+ListView {
+ width: 100
+ height: 100
+ anchors.fill: parent
+ model: myModel
+ delegate: Component {
+ Rectangle {
+ required property string modelData
+ height: 25
+ width: 100
+ Text { text: modelData }
+ }
+ }
+}
diff --git a/sources/pyside6/tests/QtQml/viewmodel.qml b/sources/pyside6/tests/QtQml/viewmodel.qml
new file mode 100644
index 000000000..33db6072e
--- /dev/null
+++ b/sources/pyside6/tests/QtQml/viewmodel.qml
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+
+ListView {
+ width: 100; height: 100
+ anchors.fill: parent
+
+ delegate: Rectangle {
+ height: 25
+ width: 100
+ Text { text: model.modelData.title }
+ }
+}
+
diff --git a/sources/pyside6/tests/QtQuick/CMakeLists.txt b/sources/pyside6/tests/QtQuick/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtQuick/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtQuick3D/CMakeLists.txt b/sources/pyside6/tests/QtQuick3D/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtQuick3D/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtQuickControls2/CMakeLists.txt b/sources/pyside6/tests/QtQuickControls2/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickControls2/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtQuickTest/CMakeLists.txt b/sources/pyside6/tests/QtQuickTest/CMakeLists.txt
new file mode 100644
index 000000000..49f15e447
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickTest/CMakeLists.txt
@@ -0,0 +1,3 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+PYSIDE_TEST(quicktestmainwithsetup/tst_quicktestmainwithsetup.py)
diff --git a/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/data/tst_setup.qml b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/data/tst_setup.qml
new file mode 100644
index 000000000..2cfe936a6
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/data/tst_setup.qml
@@ -0,0 +1,20 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick 2.0
+import QtTest 1.2
+
+import QmlRegisterTypeCppModule 1.0
+import ImportPathQmlModule 1.0
+
+TestCase {
+ name: "setup"
+
+ QmlRegisterTypeCppType {}
+ ImportPathQmlType {}
+
+ function initTestCase()
+ {
+ verify(qmlEngineAvailableCalled)
+ }
+}
diff --git a/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/ImportPathQmlType.qml b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/ImportPathQmlType.qml
new file mode 100644
index 000000000..617bdaaf6
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/ImportPathQmlType.qml
@@ -0,0 +1,3 @@
+import QtQuick 2.0
+
+Item {}
diff --git a/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/qmldir b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/qmldir
new file mode 100644
index 000000000..dea7c9a8a
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/imports/ImportPathQmlModule/qmldir
@@ -0,0 +1,2 @@
+module ImportPathQmlModule
+ImportPathQmlType 1.0 ImportPathQmlType.qml
diff --git a/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/quicktestmainwithsetup.pyproject b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/quicktestmainwithsetup.pyproject
new file mode 100644
index 000000000..61e89f4af
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/quicktestmainwithsetup.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["tst_quicktestmainwithsetup.py", "data/tst_setup.qml",
+ "imports/ImportPathQmlModule/ImportPathQmlType.qml"]
+}
diff --git a/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/tst_quicktestmainwithsetup.py b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/tst_quicktestmainwithsetup.py
new file mode 100644
index 000000000..33b2db08f
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickTest/quicktestmainwithsetup/tst_quicktestmainwithsetup.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[2]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from pathlib import Path
+from PySide6.QtCore import QObject, Slot
+from PySide6.QtQml import QQmlEngine, qmlRegisterType
+from PySide6.QtQuickTest import QUICK_TEST_MAIN_WITH_SETUP
+
+
+"""Copy of the equivalent test in qtdeclarative."""
+
+
+class QmlRegisterTypeCppType(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+class CustomTestSetup(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ @Slot(QQmlEngine)
+ def qmlEngineAvailable(self, qmlEngine):
+ # Test that modules are successfully imported by the TestCaseCollector
+ # that parses the QML files (but doesn't run them). For that to happen,
+ # qmlEngineAvailable() must be called before TestCaseCollector does its
+ # thing.
+ qmlRegisterType(QmlRegisterTypeCppType, "QmlRegisterTypeCppModule", 1, 0,
+ "QmlRegisterTypeCppType")
+ import_dir = Path(__file__).parent / "imports"
+ qmlEngine.addImportPath(os.fspath(import_dir))
+ qmlEngine.rootContext().setContextProperty("qmlEngineAvailableCalled", True)
+
+
+data_dir = Path(__file__).parent / "data"
+exitCode = QUICK_TEST_MAIN_WITH_SETUP("qquicktestsetup", CustomTestSetup, sys.argv,
+ os.fspath(data_dir))
+sys.exit(exitCode)
diff --git a/sources/pyside6/tests/QtQuickWidgets/CMakeLists.txt b/sources/pyside6/tests/QtQuickWidgets/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtQuickWidgets/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtRemoteObjects/CMakeLists.txt b/sources/pyside6/tests/QtRemoteObjects/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtRemoteObjects/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtScxml/CMakeLists.txt b/sources/pyside6/tests/QtScxml/CMakeLists.txt
new file mode 100644
index 000000000..dde186697
--- /dev/null
+++ b/sources/pyside6/tests/QtScxml/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(test_dynamic.py)
diff --git a/sources/pyside6/tests/QtScxml/QtScxml.pyproject b/sources/pyside6/tests/QtScxml/QtScxml.pyproject
new file mode 100644
index 000000000..21ee7c9ab
--- /dev/null
+++ b/sources/pyside6/tests/QtScxml/QtScxml.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["test_dynamic.py"]
+}
diff --git a/sources/pyside6/tests/QtScxml/test_dynamic.py b/sources/pyside6/tests/QtScxml/test_dynamic.py
new file mode 100644
index 000000000..212d6f7c1
--- /dev/null
+++ b/sources/pyside6/tests/QtScxml/test_dynamic.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.timedqapplication import TimedQApplication
+from PySide6.QtCore import QCoreApplication, QObject, Slot, SIGNAL, SLOT
+from PySide6.QtScxml import QScxmlStateMachine, QScxmlEvent
+
+
+class Receiver(QObject):
+ def __init__(self):
+ super().__init__()
+ self.eventReceived = False
+ self.reachedStable = False
+
+ @Slot(QScxmlEvent)
+ def handleEvent(self, event):
+ self.eventReceived = True
+
+ @Slot()
+ def slotReachedStable(self):
+ self.reachedStable = True
+
+
+class testDynamicStateMachine(TimedQApplication):
+ def setUp(self):
+ super().setUp()
+ filePath = Path(__file__).parent / "trafficlight.scxml"
+ self.assertTrue(filePath.is_file())
+ self._machine = QScxmlStateMachine.fromFile(os.fspath(filePath))
+ self._receiver = Receiver()
+ self._machine.connectToEvent("*", self._receiver,
+ SLOT("handleEvent(QScxmlEvent)"))
+ self._machine.reachedStableState.connect(self._receiver.slotReachedStable)
+ self.assertTrue(not self._machine.parseErrors())
+ self.assertTrue(self._machine)
+
+ def test(self):
+ self._machine.start()
+ while not self._receiver.reachedStable and not self._receiver.eventReceived:
+ QCoreApplication.processEvents()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtScxml/trafficlight.scxml b/sources/pyside6/tests/QtScxml/trafficlight.scxml
new file mode 100644
index 000000000..699409e68
--- /dev/null
+++ b/sources/pyside6/tests/QtScxml/trafficlight.scxml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+-->
+<scxml
+ xmlns="http://www.w3.org/2005/07/scxml"
+ xmlns:qt="http://theqtcompany.com/scxml/2015/06/"
+ version="1.0"
+ name="TrafficLightStateMachine"
+ initial="working"
+>
+ <state id="working" initial="yellow">
+ <state id="red">
+ <onentry>
+ <send event="startGoingGreen" delay="3s"/>
+ </onentry>
+ <transition event="startGoingGreen" target="redGoingGreen"/>
+ </state>
+
+ <state id="yellow" initial="greenGoingRed">
+ <state id="redGoingGreen">
+ <onentry>
+ <send event="goGreen" delay="1s"/>
+ </onentry>
+ <transition event="goGreen" target="green"/>
+ </state>
+
+ <state id="greenGoingRed">
+ <onentry>
+ <send event="goRed" delay="1s"/>
+ </onentry>
+ <transition event="goRed" target="red"/>
+ </state>
+ </state>
+
+ <state id="green">
+ <onentry>
+ <send event="startGoingRed" delay="3s"/>
+ </onentry>
+ <transition event="startGoingRed" target="greenGoingRed"/>
+ </state>
+
+ <transition event="smash" target="broken"/>
+ </state>
+
+ <state id="broken" initial="blinking">
+ <state id="blinking">
+ <onentry>
+ <send event="unblink" delay="1s"/>
+ </onentry>
+ <transition event="unblink" target="unblinking"/>
+ </state>
+
+ <state id="unblinking">
+ <onentry>
+ <send event="blink" delay="1s"/>
+ </onentry>
+ <transition event="blink" target="blinking"/>
+ </state>
+
+ <transition event="repair" target="working"/>
+ </state>
+</scxml>
diff --git a/sources/pyside6/tests/QtSensors/CMakeLists.txt b/sources/pyside6/tests/QtSensors/CMakeLists.txt
new file mode 100644
index 000000000..87e548f87
--- /dev/null
+++ b/sources/pyside6/tests/QtSensors/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(sensors.py)
diff --git a/sources/pyside6/tests/QtSensors/QtSensors.pyproject b/sources/pyside6/tests/QtSensors/QtSensors.pyproject
new file mode 100644
index 000000000..2090754d9
--- /dev/null
+++ b/sources/pyside6/tests/QtSensors/QtSensors.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["sensors.py"]
+}
diff --git a/sources/pyside6/tests/QtSensors/sensors.py b/sources/pyside6/tests/QtSensors/sensors.py
new file mode 100644
index 000000000..84bd1a92f
--- /dev/null
+++ b/sources/pyside6/tests/QtSensors/sensors.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QSensor'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtSensors import QSensor, QSensorReading
+
+
+class QSensorTest(unittest.TestCase):
+ def test(self):
+ for sensorType in QSensor.sensorTypes():
+ identifiers = QSensor.sensorsForType(sensorType)
+ values = []
+ error = ''
+ for identifier in identifiers:
+ sensor = QSensor(sensorType, None)
+ sensor.setIdentifier(identifier)
+ if sensor.connectToBackend():
+ usedIdentifier = identifier
+ reading = sensor.reading()
+ if reading:
+ for i in range(0, reading.valueCount()):
+ values.append(reading.value(i))
+ break
+ else:
+ error = "Unable to obtain reading"
+ else:
+ error = "Unable to connect to backend"
+ if values:
+ print('Sensor ', sensorType, usedIdentifier, values)
+ else:
+ print(f"{sensorType}: {error}", file=sys.stderr)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtSerialBus/CMakeLists.txt b/sources/pyside6/tests/QtSerialBus/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtSerialBus/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtSerialPort/CMakeLists.txt b/sources/pyside6/tests/QtSerialPort/CMakeLists.txt
new file mode 100644
index 000000000..554373445
--- /dev/null
+++ b/sources/pyside6/tests/QtSerialPort/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(serial.py)
diff --git a/sources/pyside6/tests/QtSerialPort/QtSerialPort.pyproject b/sources/pyside6/tests/QtSerialPort/QtSerialPort.pyproject
new file mode 100644
index 000000000..1b7c0f694
--- /dev/null
+++ b/sources/pyside6/tests/QtSerialPort/QtSerialPort.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["serial.py"]
+}
diff --git a/sources/pyside6/tests/QtSerialPort/serial.py b/sources/pyside6/tests/QtSerialPort/serial.py
new file mode 100644
index 000000000..f1e54f2ac
--- /dev/null
+++ b/sources/pyside6/tests/QtSerialPort/serial.py
@@ -0,0 +1,72 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QSerialPort'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtSerialPort import QSerialPort, QSerialPortInfo
+from PySide6.QtCore import QIODevice
+
+
+class QSerialPortTest(unittest.TestCase):
+ def testDefaultConstructedPort(self):
+ serialPort = QSerialPort()
+
+ self.assertEqual(serialPort.error(), QSerialPort.NoError)
+ self.assertTrue(not serialPort.errorString() == "")
+
+ # properties
+ defaultBaudRate = QSerialPort.Baud9600
+ self.assertEqual(serialPort.baudRate(), defaultBaudRate)
+ self.assertEqual(serialPort.baudRate(QSerialPort.Input), defaultBaudRate)
+ self.assertEqual(serialPort.baudRate(QSerialPort.Output), defaultBaudRate)
+ self.assertEqual(serialPort.dataBits(), QSerialPort.Data8)
+ self.assertEqual(serialPort.parity(), QSerialPort.NoParity)
+ self.assertEqual(serialPort.stopBits(), QSerialPort.OneStop)
+ self.assertEqual(serialPort.flowControl(), QSerialPort.NoFlowControl)
+
+ self.assertEqual(serialPort.pinoutSignals(), QSerialPort.NoSignal)
+ self.assertEqual(serialPort.isRequestToSend(), False)
+ self.assertEqual(serialPort.isDataTerminalReady(), False)
+
+ # QIODevice
+ self.assertEqual(serialPort.openMode(), QIODevice.NotOpen)
+ self.assertTrue(not serialPort.isOpen())
+ self.assertTrue(not serialPort.isReadable())
+ self.assertTrue(not serialPort.isWritable())
+ self.assertTrue(serialPort.isSequential())
+ self.assertEqual(serialPort.canReadLine(), False)
+ self.assertEqual(serialPort.pos(), 0)
+ self.assertEqual(serialPort.size(), 0)
+ self.assertTrue(serialPort.atEnd())
+ self.assertEqual(serialPort.bytesAvailable(), 0)
+ self.assertEqual(serialPort.bytesToWrite(), 0)
+
+ def testOpenExisting(self):
+ allportinfos = QSerialPortInfo.availablePorts()
+ for portinfo in allportinfos:
+ serialPort = QSerialPort(portinfo)
+ self.assertEqual(serialPort.portName(), portinfo.portName())
+
+
+class QSerialPortInfoTest(unittest.TestCase):
+ def test_available_ports(self):
+ allportinfos = QSerialPortInfo.availablePorts()
+ for portinfo in allportinfos:
+ portinfo.description()
+ portinfo.hasProductIdentifier()
+ portinfo.hasVendorIdentifier()
+ portinfo.isNull()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtSpatialAudio/CMakeLists.txt b/sources/pyside6/tests/QtSpatialAudio/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtSpatialAudio/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtSql/CMakeLists.txt b/sources/pyside6/tests/QtSql/CMakeLists.txt
new file mode 100644
index 000000000..eedb31e98
--- /dev/null
+++ b/sources/pyside6/tests/QtSql/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(bug_1013.py)
+PYSIDE_TEST(qsqldatabaseandqueries_test.py)
+PYSIDE_TEST(qvarianttype_test.py)
diff --git a/sources/pyside6/tests/QtSql/QtSql.pyproject b/sources/pyside6/tests/QtSql/QtSql.pyproject
new file mode 100644
index 000000000..8282cb404
--- /dev/null
+++ b/sources/pyside6/tests/QtSql/QtSql.pyproject
@@ -0,0 +1,5 @@
+{
+ "files": ["bug_1013.py",
+ "qsqldatabaseandqueries_test.py",
+ "qvarianttype_test.py"]
+}
diff --git a/sources/pyside6/tests/QtSql/bug_1013.py b/sources/pyside6/tests/QtSql/bug_1013.py
new file mode 100644
index 000000000..b47aecb77
--- /dev/null
+++ b/sources/pyside6/tests/QtSql/bug_1013.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QTimer
+from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
+
+
+class TestBug1013 (unittest.TestCase):
+
+ def someSlot(self, row, record):
+ record.setValue(0, 2)
+ self._wasCalled = True
+
+ def testIt(self):
+ app = QCoreApplication([])
+ db = QSqlDatabase.addDatabase('QSQLITE')
+ db.setDatabaseName(':memory:')
+ db.open()
+ query = QSqlQuery()
+ query.exec('CREATE TABLE "foo" (id INT);')
+ model = QSqlTableModel()
+ model.setTable('foo')
+
+ self._wasCalled = False
+ model.primeInsert.connect(self.someSlot)
+ model.select()
+ QTimer.singleShot(0, lambda: model.insertRow(0) and app.quit())
+ app.exec()
+ self.assertTrue(self._wasCalled)
+ self.assertEqual(model.data(model.index(0, 0)), 2)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtSql/qsqldatabaseandqueries_test.py b/sources/pyside6/tests/QtSql/qsqldatabaseandqueries_test.py
new file mode 100644
index 000000000..a3e70a3a7
--- /dev/null
+++ b/sources/pyside6/tests/QtSql/qsqldatabaseandqueries_test.py
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QtSql database creation, destruction and queries'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
+from PySide6.QtWidgets import QApplication, QWidget
+from helper.usesqapplication import UsesQApplication
+
+
+class Foo(QWidget):
+ def __init__(self):
+ super().__init__()
+ self.model = QSqlTableModel()
+
+
+class SqlDatabaseCreationDestructionAndQueries(UsesQApplication):
+ '''Test cases for QtSql database creation, destruction and queries'''
+
+ def setUp(self):
+ # Acquire resources
+ super().setUp()
+ self.assertFalse(not QSqlDatabase.drivers(), "installed Qt has no DB drivers")
+ self.assertTrue("QSQLITE" in QSqlDatabase.drivers(), "\"QSQLITE\" driver not available in this Qt version")
+ self.db = QSqlDatabase.addDatabase("QSQLITE")
+ self.db.setDatabaseName(":memory:")
+ self.assertTrue(self.db.open())
+
+ def tearDown(self):
+ # Release resources
+ self.db.close()
+ QSqlDatabase.removeDatabase(":memory:")
+ del self.db
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super().tearDown()
+
+ def testTableCreationAndDestruction(self):
+ # Test table creation and destruction
+ query = QSqlQuery()
+ query.exec("CREATE TABLE dummy(id int primary key, dummyfield varchar(20))")
+ query.exec("DROP TABLE dummy")
+ query.clear()
+
+ def testTableInsertionAndRetrieval(self):
+ # Test table creation, insertion and retrieval
+ query = QSqlQuery()
+ query.exec("CREATE TABLE person(id int primary key, "
+ "firstname varchar(20), lastname varchar(20))")
+ query.exec("INSERT INTO person VALUES(101, 'George', 'Harrison')")
+ query.prepare("INSERT INTO person (id, firstname, lastname) "
+ "VALUES (:id, :firstname, :lastname)")
+ query.bindValue(":id", 102)
+ query.bindValue(":firstname", "John")
+ query.bindValue(":lastname", "Lennon")
+ query.exec()
+
+ lastname = ''
+ query.exec("SELECT lastname FROM person where id=101")
+ self.assertTrue(query.isActive())
+ query.next()
+ lastname = query.value(0)
+ self.assertEqual(lastname, 'Harrison')
+
+ def testTableModelDeletion(self):
+ bar = Foo()
+ model = bar.model
+ del bar
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtSql/qvarianttype_test.py b/sources/pyside6/tests/QtSql/qvarianttype_test.py
new file mode 100644
index 000000000..3999be20e
--- /dev/null
+++ b/sources/pyside6/tests/QtSql/qvarianttype_test.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QVariant::Type converter'''
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QMetaType
+from PySide6.QtSql import QSqlField
+
+
+class QVariantTypeTest(unittest.TestCase):
+ def testQVariantType(self):
+ cmp_id = QMetaType.QString.value
+
+ f = QSqlField("name", QMetaType(QMetaType.QString))
+ self.assertEqual(f.metaType().id(), cmp_id)
+
+ f = QSqlField("name", QMetaType.fromName(b"QString"))
+ self.assertEqual(f.metaType().id(), cmp_id)
+
+ f = QSqlField("name", QMetaType.fromName(b"double"))
+ self.assertEqual(f.metaType(), float)
+
+ f = QSqlField("name", float)
+ self.assertEqual(f.metaType(), float)
+
+ f = QSqlField("name", int)
+ self.assertEqual(f.metaType(), int)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtStateMachine/CMakeLists.txt b/sources/pyside6/tests/QtStateMachine/CMakeLists.txt
new file mode 100644
index 000000000..e42f8cc8b
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(bug_1031.py)
+PYSIDE_TEST(qabstracttransition_test.py)
+PYSIDE_TEST(qstatemachine_test.py)
+PYSIDE_TEST(qstate_test.py)
+PYSIDE_TEST(setprop_on_ctor_test.py)
diff --git a/sources/pyside6/tests/QtStateMachine/QtStateMachine.pyproject b/sources/pyside6/tests/QtStateMachine/QtStateMachine.pyproject
new file mode 100644
index 000000000..46c1b8b12
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/QtStateMachine.pyproject
@@ -0,0 +1,7 @@
+{
+ "files": ["bug_1031.py",
+ "qabstracttransition_test.py",
+ "qstate_test.py",
+ "qstatemachine_test.py",
+ "setprop_on_ctor_test.py"]
+}
diff --git a/sources/pyside6/tests/QtStateMachine/bug_1031.py b/sources/pyside6/tests/QtStateMachine/bug_1031.py
new file mode 100644
index 000000000..7fe5fc1e6
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/bug_1031.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtStateMachine import QStateMachine, QState
+
+
+mach = QStateMachine()
+state = QState(mach)
+print(state.machine())
diff --git a/sources/pyside6/tests/QtStateMachine/qabstracttransition_test.py b/sources/pyside6/tests/QtStateMachine/qabstracttransition_test.py
new file mode 100644
index 000000000..9c52bfd59
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/qabstracttransition_test.py
@@ -0,0 +1,175 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QCoreApplication, QObject, QParallelAnimationGroup,
+ QTimer, SIGNAL)
+from PySide6.QtStateMachine import (QEventTransition, QFinalState, QState,
+ QStateMachine, QSignalTransition)
+
+
+def addStates(transition):
+ sx = QState()
+ sy = QState()
+ transition.setTargetStates([sx, sy])
+
+
+def addAnimation(transition):
+ animation = QParallelAnimationGroup()
+ transition.addAnimation(animation)
+
+
+class QAbstractTransitionTest(unittest.TestCase):
+
+ def testBasic(self):
+ app = QCoreApplication([])
+
+ o = QObject()
+ o.setProperty("text", "INdT")
+
+ machine = QStateMachine()
+ s1 = QState()
+ s1.assignProperty(o, "text", "Rocks")
+
+ s2 = QFinalState()
+ t = s1.addTransition(o, SIGNAL("change()"), s2)
+
+ self.assertEqual(t.targetStates(), [s2])
+
+ addStates(t)
+ self.assertEqual(len(t.targetStates()), 2)
+
+ animation = QParallelAnimationGroup()
+ t.addAnimation(animation)
+
+ self.assertEqual(t.animations(), [animation])
+
+ addAnimation(t)
+ self.assertEqual(t.animations()[0].parent(), None)
+
+ machine.addState(s1)
+ machine.addState(s2)
+ machine.setInitialState(s1)
+ machine.start()
+
+ QTimer.singleShot(100, app.quit)
+ app.exec()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountOfTargetState(self):
+ transition = QEventTransition()
+ state1 = QState()
+ refcount1 = sys.getrefcount(state1)
+
+ transition.setTargetState(state1)
+
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(sys.getrefcount(transition.targetState()), refcount1 + 1)
+
+ state2 = QState()
+ refcount2 = sys.getrefcount(state2)
+
+ transition.setTargetState(state2)
+
+ self.assertEqual(transition.targetState(), state2)
+ self.assertEqual(sys.getrefcount(transition.targetState()), refcount2 + 1)
+ self.assertEqual(sys.getrefcount(state1), refcount1)
+
+ del transition
+
+ self.assertEqual(sys.getrefcount(state2), refcount2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountOfTargetStates(self):
+ transition = QEventTransition()
+ state1 = QState()
+ state2 = QState()
+ states = [state1, state2]
+ refcount1 = sys.getrefcount(state1)
+ refcount2 = sys.getrefcount(state2)
+
+ transition.setTargetStates(states)
+
+ self.assertEqual(transition.targetStates(), states)
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(sys.getrefcount(transition.targetStates()[0]), refcount1 + 1)
+ self.assertEqual(sys.getrefcount(transition.targetStates()[1]), refcount2 + 1)
+
+ del states
+ del transition
+
+ self.assertEqual(sys.getrefcount(state1), refcount1 - 1)
+ self.assertEqual(sys.getrefcount(state2), refcount2 - 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountOfTargetStatesAfterSingleTargetState(self):
+ transition = QEventTransition()
+ state0 = QState()
+ refcount0 = sys.getrefcount(state0)
+
+ transition.setTargetState(state0)
+
+ self.assertEqual(transition.targetState(), state0)
+ self.assertEqual(sys.getrefcount(transition.targetState()), refcount0 + 1)
+
+ state1 = QState()
+ state2 = QState()
+ states = [state1, state2]
+ refcount1 = sys.getrefcount(state1)
+ refcount2 = sys.getrefcount(state2)
+
+ transition.setTargetStates(states)
+
+ self.assertEqual(sys.getrefcount(state0), refcount0)
+ self.assertEqual(transition.targetStates(), states)
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(sys.getrefcount(transition.targetStates()[0]), refcount1 + 1)
+ self.assertEqual(sys.getrefcount(transition.targetStates()[1]), refcount2 + 1)
+
+ del states
+ del transition
+
+ self.assertEqual(sys.getrefcount(state1), refcount1 - 1)
+ self.assertEqual(sys.getrefcount(state2), refcount2 - 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountOfTargetStatesBeforeSingleTargetState(self):
+ transition = QEventTransition()
+ state1 = QState()
+ state2 = QState()
+ states = [state1, state2]
+ refcount1 = sys.getrefcount(state1)
+ refcount2 = sys.getrefcount(state2)
+
+ transition.setTargetStates(states)
+
+ self.assertEqual(transition.targetStates(), states)
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(sys.getrefcount(transition.targetStates()[0]), refcount1 + 1)
+ self.assertEqual(sys.getrefcount(transition.targetStates()[1]), refcount2 + 1)
+
+ state3 = QState()
+ refcount3 = sys.getrefcount(state3)
+
+ transition.setTargetState(state3)
+
+ self.assertEqual(transition.targetState(), state3)
+ self.assertEqual(sys.getrefcount(transition.targetState()), refcount3 + 1)
+
+ del states
+
+ self.assertEqual(sys.getrefcount(state1), refcount1 - 1)
+ self.assertEqual(sys.getrefcount(state2), refcount2 - 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtStateMachine/qstate_test.py b/sources/pyside6/tests/QtStateMachine/qstate_test.py
new file mode 100644
index 000000000..4a33141c8
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/qstate_test.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QObject, SIGNAL, QTimer
+from PySide6.QtStateMachine import (QEventTransition, QFinalState, QState,
+ QStateMachine, QSignalTransition)
+
+
+class QStateTest(unittest.TestCase):
+ def testBasic(self):
+ app = QCoreApplication([])
+
+ o = QObject()
+ o.setProperty("text", "INdT")
+
+ machine = QStateMachine()
+ s1 = QState()
+ s1.assignProperty(o, "text", "Rocks")
+
+ s2 = QFinalState()
+ t = s1.addTransition(o, SIGNAL("change()"), s2)
+ self.assertTrue(isinstance(t, QSignalTransition))
+
+ machine.addState(s1)
+ machine.addState(s2)
+ machine.setInitialState(s1)
+ machine.start()
+
+ o.emit(SIGNAL("change()"))
+
+ QTimer.singleShot(100, app.quit)
+ app.exec()
+
+ txt = o.property("text")
+ self.assertTrue(txt, "Rocks")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtStateMachine/qstatemachine_test.py b/sources/pyside6/tests/QtStateMachine/qstatemachine_test.py
new file mode 100644
index 000000000..5e17b3a1f
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/qstatemachine_test.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import (QObject, QParallelAnimationGroup,
+ QPropertyAnimation, QTimer, SIGNAL)
+from PySide6.QtStateMachine import (QFinalState, QState, QStateMachine)
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QStateMachineTest(UsesQApplication):
+
+ def cb(self, *args):
+ self.assertEqual(self.machine.defaultAnimations(), [self.anim])
+
+ def testBasic(self):
+ self.machine = QStateMachine()
+ s1 = QState()
+ s2 = QState()
+ s3 = QFinalState()
+
+ self.machine.started.connect(self.cb)
+
+ self.anim = QParallelAnimationGroup()
+
+ self.machine.addState(s1)
+ self.machine.addState(s2)
+ self.machine.addState(s3)
+ self.machine.setInitialState(s1)
+ self.machine.addDefaultAnimation(self.anim)
+ self.machine.start()
+
+ QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+
+class QSetConverterTest(UsesQApplication):
+ '''Test converter of QSet toPython using QStateAnimation.configuration'''
+
+ def testBasic(self):
+ '''QStateMachine.configuration converting QSet to python set'''
+ machine = QStateMachine()
+ s1 = QState()
+ machine.addState(s1)
+ machine.setInitialState(s1)
+ machine.start()
+
+ QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+ configuration = machine.configuration()
+
+ self.assertTrue(isinstance(configuration, set))
+ self.assertTrue(s1 in configuration)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtStateMachine/setprop_on_ctor_test.py b/sources/pyside6/tests/QtStateMachine/setprop_on_ctor_test.py
new file mode 100644
index 000000000..48f397282
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/setprop_on_ctor_test.py
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtStateMachine import QEventTransition, QState
+
+
+class SetPropOnCtorTest(unittest.TestCase):
+ def testIt(self):
+ obj = QEventTransition(targetStates=[QState()])
+ self.assertEqual(len(obj.targetStates()), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtSvg/CMakeLists.txt b/sources/pyside6/tests/QtSvg/CMakeLists.txt
new file mode 100644
index 000000000..53d15e857
--- /dev/null
+++ b/sources/pyside6/tests/QtSvg/CMakeLists.txt
@@ -0,0 +1,2 @@
+PYSIDE_TEST(qsvggenerator_test.py)
+PYSIDE_TEST(qsvgrenderer_test.py)
diff --git a/sources/pyside6/tests/QtSvg/QtSvg.pyproject b/sources/pyside6/tests/QtSvg/QtSvg.pyproject
new file mode 100644
index 000000000..9bc41d710
--- /dev/null
+++ b/sources/pyside6/tests/QtSvg/QtSvg.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["qsvggenerator_test.py",
+ "qsvgrenderer_test.py"]
+}
diff --git a/sources/pyside6/tests/QtSvg/qsvggenerator_test.py b/sources/pyside6/tests/QtSvg/qsvggenerator_test.py
new file mode 100644
index 000000000..a06cefb37
--- /dev/null
+++ b/sources/pyside6/tests/QtSvg/qsvggenerator_test.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QBuffer
+from PySide6.QtSvg import QSvgGenerator
+
+
+class QSvgGeneratorTest(unittest.TestCase):
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountOfTOutputDevice(self):
+ generator = QSvgGenerator()
+ iodevice1 = QBuffer()
+ refcount1 = sys.getrefcount(iodevice1)
+
+ generator.setOutputDevice(iodevice1)
+
+ self.assertEqual(generator.outputDevice(), iodevice1)
+ self.assertEqual(sys.getrefcount(generator.outputDevice()), refcount1 + 1)
+
+ iodevice2 = QBuffer()
+ refcount2 = sys.getrefcount(iodevice2)
+
+ generator.setOutputDevice(iodevice2)
+
+ self.assertEqual(generator.outputDevice(), iodevice2)
+ self.assertEqual(sys.getrefcount(generator.outputDevice()), refcount2 + 1)
+ self.assertEqual(sys.getrefcount(iodevice1), refcount1)
+
+ del generator
+
+ self.assertEqual(sys.getrefcount(iodevice2), refcount2)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtSvg/qsvgrenderer_test.py b/sources/pyside6/tests/QtSvg/qsvgrenderer_test.py
new file mode 100644
index 000000000..b4422001f
--- /dev/null
+++ b/sources/pyside6/tests/QtSvg/qsvgrenderer_test.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QFile
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtSvg import QSvgRenderer
+
+
+class QSvgRendererTest(unittest.TestCase):
+
+ def testLoad(self):
+ tigerPath = os.path.join(os.path.dirname(__file__), 'tiger.svg')
+ app = QGuiApplication([])
+
+ fromFile = QSvgRenderer(tigerPath)
+ self.assertTrue(fromFile.isValid())
+
+ tigerFile = QFile(tigerPath)
+ tigerFile.open(QFile.ReadOnly)
+ tigerData = tigerFile.readAll()
+ fromContents = QSvgRenderer(tigerData)
+ self.assertTrue(fromContents.isValid())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtSvg/tiger.svg b/sources/pyside6/tests/QtSvg/tiger.svg
new file mode 100644
index 000000000..681fbd209
--- /dev/null
+++ b/sources/pyside6/tests/QtSvg/tiger.svg
@@ -0,0 +1,730 @@
+<?xml version="1.0"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ height="800">
+ <g transform="translate(200,200)" style="fill-opacity:1; fill:none;">
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-122.304 84.285C-122.304 84.285 -122.203 86.179 -123.027 86.16C-123.851 86.141 -140.305 38.066 -160.833 40.309C-160.833 40.309 -143.05 32.956 -122.304 84.285z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-118.774 81.262C-118.774 81.262 -119.323 83.078 -120.092 82.779C-120.86 82.481 -119.977 31.675 -140.043 26.801C-140.043 26.801 -120.82 25.937 -118.774 81.262z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-91.284 123.59C-91.284 123.59 -89.648 124.55 -90.118 125.227C-90.589 125.904 -139.763 113.102 -149.218 131.459C-149.218 131.459 -145.539 112.572 -91.284 123.59z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-94.093 133.801C-94.093 133.801 -92.237 134.197 -92.471 134.988C-92.704 135.779 -143.407 139.121 -146.597 159.522C-146.597 159.522 -149.055 140.437 -94.093 133.801z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-98.304 128.276C-98.304 128.276 -96.526 128.939 -96.872 129.687C-97.218 130.435 -147.866 126.346 -153.998 146.064C-153.998 146.064 -153.646 126.825 -98.304 128.276z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-109.009 110.072C-109.009 110.072 -107.701 111.446 -108.34 111.967C-108.979 112.488 -152.722 86.634 -166.869 101.676C-166.869 101.676 -158.128 84.533 -109.009 110.072z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-116.554 114.263C-116.554 114.263 -115.098 115.48 -115.674 116.071C-116.25 116.661 -162.638 95.922 -174.992 112.469C-174.992 112.469 -168.247 94.447 -116.554 114.263z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-119.154 118.335C-119.154 118.335 -117.546 119.343 -118.036 120.006C-118.526 120.669 -167.308 106.446 -177.291 124.522C-177.291 124.522 -173.066 105.749 -119.154 118.335z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-108.42 118.949C-108.42 118.949 -107.298 120.48 -107.999 120.915C-108.7 121.35 -148.769 90.102 -164.727 103.207C-164.727 103.207 -153.862 87.326 -108.42 118.949z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-128.2 90C-128.2 90 -127.6 91.8 -128.4 92C-129.2 92.2 -157.8 50.2 -177.001 57.8C-177.001 57.8 -161.8 46 -128.2 90z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-127.505 96.979C-127.505 96.979 -126.53 98.608 -127.269 98.975C-128.007 99.343 -164.992 64.499 -182.101 76.061C-182.101 76.061 -169.804 61.261 -127.505 96.979z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.172">
+ <path d="M-127.62 101.349C-127.62 101.349 -126.498 102.88 -127.199 103.315C-127.9 103.749 -167.969 72.502 -183.927 85.607C-183.927 85.607 -173.062 69.726 -127.62 101.349z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000">
+ <path d="M-129.83 103.065C-129.327 109.113 -128.339 115.682 -126.6 118.801C-126.6 118.801 -130.2 131.201 -121.4 144.401C-121.4 144.401 -121.8 151.601 -120.2 154.801C-120.2 154.801 -116.2 163.201 -111.4 164.001C-107.516 164.648 -98.793 167.717 -88.932 169.121C-88.932 169.121 -71.8 183.201 -75 196.001C-75 196.001 -75.4 212.401 -79 214.001C-79 214.001 -67.4 202.801 -77 219.601L-81.4 238.401C-81.4 238.401 -55.8 216.801 -71.4 235.201L-81.4 261.201C-81.4 261.201 -61.8 242.801 -69 251.201L-72.2 260.001C-72.2 260.001 -29 232.801 -59.8 262.401C-59.8 262.401 -51.8 258.801 -47.4 261.601C-47.4 261.601 -40.6 260.401 -41.4 262.001C-41.4 262.001 -62.2 272.401 -65.8 290.801C-65.8 290.801 -57.4 280.801 -60.6 291.601L-60.2 303.201C-60.2 303.201 -56.2 281.601 -56.6 319.201C-56.6 319.201 -37.4 301.201 -49 322.001L-49 338.801C-49 338.801 -33.8 322.401 -40.2 335.201C-40.2 335.201 -30.2 326.401 -34.2 341.601C-34.2 341.601 -35 352.001 -30.6 340.801C-30.6 340.801 -14.6 310.201 -20.6 336.401C-20.6 336.401 -21.4 355.601 -16.6 340.801C-16.6 340.801 -16.2 351.201 -7 358.401C-7 358.401 -8.2 307.601 4.6 343.601L8.6 360.001C8.6 360.001 11.4 350.801 11 345.601C11 345.601 25.8 329.201 19 353.601C19 353.601 34.2 330.801 31 344.001C31 344.001 23.4 360.001 25 364.801C25 364.801 41.8 330.001 43 328.401C43 328.401 41 370.802 51.8 334.801C51.8 334.801 57.4 346.801 54.6 351.201C54.6 351.201 62.6 343.201 61.8 340.001C61.8 340.001 66.4 331.801 69.2 345.401C69.2 345.401 71 354.801 72.6 351.601C72.6 351.601 76.6 375.602 77.8 352.801C77.8 352.801 79.4 339.201 72.2 327.601C72.2 327.601 73 324.401 70.2 320.401C70.2 320.401 83.8 342.001 76.6 313.201C76.6 313.201 87.801 321.201 89.001 321.201C89.001 321.201 75.4 298.001 84.2 302.801C84.2 302.801 79 292.401 97.001 304.401C97.001 304.401 81 288.401 98.601 298.001C98.601 298.001 106.601 304.401 99.001 294.401C99.001 294.401 84.6 278.401 106.601 296.401C106.601 296.401 118.201 312.801 119.001 315.601C119.001 315.601 109.001 286.401 104.601 283.601C104.601 283.601 113.001 247.201 154.201 262.801C154.201 262.801 161.001 280.001 165.401 261.601C165.401 261.601 178.201 255.201 189.401 282.801C189.401 282.801 193.401 269.201 192.601 266.401C192.601 266.401 199.401 267.601 198.601 266.401C198.601 266.401 211.801 270.801 213.001 270.001C213.001 270.001 219.801 276.801 220.201 273.201C220.201 273.201 229.401 276.001 227.401 272.401C227.401 272.401 236.201 288.001 236.601 291.601L239.001 277.601L241.001 280.401C241.001 280.401 242.601 272.801 241.801 271.601C241.001 270.401 261.801 278.401 266.601 299.201L268.601 307.601C268.601 307.601 274.601 292.801 273.001 288.801C273.001 288.801 278.201 289.601 278.601 294.001C278.601 294.001 282.601 270.801 277.801 264.801C277.801 264.801 282.201 264.001 283.401 267.601L283.401 260.401C283.401 260.401 290.601 261.201 290.601 258.801C290.601 258.801 295.001 254.801 297.001 259.601C297.001 259.601 284.601 224.401 303.001 243.601C303.001 243.601 310.201 254.401 306.601 235.601C303.001 216.801 299.001 215.201 303.801 214.801C303.801 214.801 304.601 211.201 302.601 209.601C300.601 208.001 303.801 209.601 303.801 209.601C303.801 209.601 308.601 213.601 303.401 191.601C303.401 191.601 309.801 193.201 297.801 164.001C297.801 164.001 300.601 161.601 296.601 153.201C296.601 153.201 304.601 157.601 307.401 156.001C307.401 156.001 307.001 154.401 303.801 150.401C303.801 150.401 282.201 95.6 302.601 117.601C302.601 117.601 314.451 131.151 308.051 108.351C308.051 108.351 298.94 84.341 299.717 80.045L-129.83 103.065z"/>
+ </g>
+ <g style="fill: #cc7226; stroke:#000000">
+ <path d="M299.717 80.245C300.345 80.426 302.551 81.55 303.801 83.2C303.801 83.2 310.601 94 305.401 75.6C305.401 75.6 296.201 46.8 305.001 58C305.001 58 311.001 65.2 307.801 51.6C303.936 35.173 301.401 28.8 301.401 28.8C301.401 28.8 313.001 33.6 286.201 -6L295.001 -2.4C295.001 -2.4 275.401 -42 253.801 -47.2L245.801 -53.2C245.801 -53.2 284.201 -91.2 271.401 -128C271.401 -128 264.601 -133.2 255.001 -124C255.001 -124 248.601 -119.2 242.601 -120.8C242.601 -120.8 211.801 -119.6 209.801 -119.6C207.801 -119.6 173.001 -156.8 107.401 -139.2C107.401 -139.2 102.201 -137.2 97.801 -138.4C97.801 -138.4 79.4 -154.4 30.6 -131.6C30.6 -131.6 20.6 -129.6 19 -129.6C17.4 -129.6 14.6 -129.6 6.6 -123.2C-1.4 -116.8 -1.8 -116 -3.8 -114.4C-3.8 -114.4 -20.2 -103.2 -25 -102.4C-25 -102.4 -36.6 -96 -41 -86L-44.6 -84.8C-44.6 -84.8 -46.2 -77.6 -46.6 -76.4C-46.6 -76.4 -51.4 -72.8 -52.2 -67.2C-52.2 -67.2 -61 -61.2 -60.6 -56.8C-60.6 -56.8 -62.2 -51.6 -63 -46.8C-63 -46.8 -70.2 -42 -69.4 -39.2C-69.4 -39.2 -77 -25.2 -75.8 -18.4C-75.8 -18.4 -82.2 -18.8 -85 -16.4C-85 -16.4 -85.8 -11.6 -87.4 -11.2C-87.4 -11.2 -90.2 -10 -87.8 -6C-87.8 -6 -89.4 -3.2 -89.8 -1.6C-89.8 -1.6 -89 1.2 -93.4 6.8C-93.4 6.8 -99.8 25.6 -97.8 30.8C-97.8 30.8 -97.4 35.6 -100.2 37.2C-100.2 37.2 -103.8 36.8 -95.4 48.8C-95.4 48.8 -94.6 50 -97.8 52.4C-97.8 52.4 -115 56 -117.4 72.4C-117.4 72.4 -131 87.2 -131 92.4C-131 94.705 -130.729 97.852 -130.03 102.465C-130.03 102.465 -130.6 110.801 -103 111.601C-75.4 112.401 299.717 80.245 299.717 80.245z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M-115.6 102.6C-140.6 63.2 -126.2 119.601 -126.2 119.601C-117.4 154.001 12.2 116.401 12.2 116.401C12.2 116.401 181.001 86 192.201 82C203.401 78 298.601 84.4 298.601 84.4L293.001 67.6C228.201 21.2 209.001 44.4 195.401 40.4C181.801 36.4 184.201 46 181.001 46.8C177.801 47.6 138.601 22.8 132.201 23.6C125.801 24.4 100.459 0.649 115.401 32.4C131.401 66.4 57 71.6 40.2 60.4C23.4 49.2 47.4 78.8 47.4 78.8C65.8 98.8 31.4 82 31.4 82C-3 69.2 -27 94.8 -30.2 95.6C-33.4 96.4 -38.2 99.6 -39 93.2C-39.8 86.8 -47.31 70.099 -79 96.4C-99 113.001 -112.8 91 -112.8 91L-115.6 102.6z"/>
+ </g>
+ <g style="fill: #e87f3a">
+ <path d="M133.51 25.346C127.11 26.146 101.743 2.407 116.71 34.146C133.31 69.346 58.31 73.346 41.51 62.146C24.709 50.946 48.71 80.546 48.71 80.546C67.11 100.546 32.709 83.746 32.709 83.746C-1.691 70.946 -25.691 96.546 -28.891 97.346C-32.091 98.146 -36.891 101.346 -37.691 94.946C-38.491 88.546 -45.87 72.012 -77.691 98.146C-98.927 115.492 -112.418 94.037 -112.418 94.037L-115.618 104.146C-140.618 64.346 -125.546 122.655 -125.546 122.655C-116.745 157.056 13.509 118.146 13.509 118.146C13.509 118.146 182.31 87.746 193.51 83.746C204.71 79.746 299.038 86.073 299.038 86.073L293.51 68.764C228.71 22.364 210.31 46.146 196.71 42.146C183.11 38.146 185.51 47.746 182.31 48.546C179.11 49.346 139.91 24.546 133.51 25.346z"/>
+ </g>
+ <g style="fill: #ea8c4d">
+ <path d="M134.819 27.091C128.419 27.891 103.685 3.862 118.019 35.891C134.219 72.092 59.619 75.092 42.819 63.892C26.019 52.692 50.019 82.292 50.019 82.292C68.419 102.292 34.019 85.492 34.019 85.492C-0.381 72.692 -24.382 98.292 -27.582 99.092C-30.782 99.892 -35.582 103.092 -36.382 96.692C-37.182 90.292 -44.43 73.925 -76.382 99.892C-98.855 117.983 -112.036 97.074 -112.036 97.074L-115.636 105.692C-139.436 66.692 -124.891 125.71 -124.891 125.71C-116.091 160.11 14.819 119.892 14.819 119.892C14.819 119.892 183.619 89.492 194.819 85.492C206.019 81.492 299.474 87.746 299.474 87.746L294.02 69.928C229.219 23.528 211.619 47.891 198.019 43.891C184.419 39.891 186.819 49.491 183.619 50.292C180.419 51.092 141.219 26.291 134.819 27.091z"/>
+ </g>
+ <g style="fill: #ec9961">
+ <path d="M136.128 28.837C129.728 29.637 104.999 5.605 119.328 37.637C136.128 75.193 60.394 76.482 44.128 65.637C27.328 54.437 51.328 84.037 51.328 84.037C69.728 104.037 35.328 87.237 35.328 87.237C0.928 74.437 -23.072 100.037 -26.272 100.837C-29.472 101.637 -34.272 104.837 -35.072 98.437C-35.872 92.037 -42.989 75.839 -75.073 101.637C-98.782 120.474 -111.655 100.11 -111.655 100.11L-115.655 107.237C-137.455 70.437 -124.236 128.765 -124.236 128.765C-115.436 163.165 16.128 121.637 16.128 121.637C16.128 121.637 184.928 91.237 196.129 87.237C207.329 83.237 299.911 89.419 299.911 89.419L294.529 71.092C229.729 24.691 212.929 49.637 199.329 45.637C185.728 41.637 188.128 51.237 184.928 52.037C181.728 52.837 142.528 28.037 136.128 28.837z"/>
+ </g>
+ <g style="fill: #eea575">
+ <path d="M137.438 30.583C131.037 31.383 106.814 7.129 120.637 39.383C137.438 78.583 62.237 78.583 45.437 67.383C28.637 56.183 52.637 85.783 52.637 85.783C71.037 105.783 36.637 88.983 36.637 88.983C2.237 76.183 -21.763 101.783 -24.963 102.583C-28.163 103.383 -32.963 106.583 -33.763 100.183C-34.563 93.783 -41.548 77.752 -73.763 103.383C-98.709 122.965 -111.273 103.146 -111.273 103.146L-115.673 108.783C-135.473 73.982 -123.582 131.819 -123.582 131.819C-114.782 166.22 17.437 123.383 17.437 123.383C17.437 123.383 186.238 92.983 197.438 88.983C208.638 84.983 300.347 91.092 300.347 91.092L295.038 72.255C230.238 25.855 214.238 51.383 200.638 47.383C187.038 43.383 189.438 52.983 186.238 53.783C183.038 54.583 143.838 29.783 137.438 30.583z"/>
+ </g>
+ <g style="fill: #f1b288">
+ <path d="M138.747 32.328C132.347 33.128 106.383 9.677 121.947 41.128C141.147 79.928 63.546 80.328 46.746 69.128C29.946 57.928 53.946 87.528 53.946 87.528C72.346 107.528 37.946 90.728 37.946 90.728C3.546 77.928 -20.454 103.528 -23.654 104.328C-26.854 105.128 -31.654 108.328 -32.454 101.928C-33.254 95.528 -40.108 79.665 -72.454 105.128C-98.636 125.456 -110.891 106.183 -110.891 106.183L-115.691 110.328C-133.691 77.128 -122.927 134.874 -122.927 134.874C-114.127 169.274 18.746 125.128 18.746 125.128C18.746 125.128 187.547 94.728 198.747 90.728C209.947 86.728 300.783 92.764 300.783 92.764L295.547 73.419C230.747 27.019 215.547 53.128 201.947 49.128C188.347 45.128 190.747 54.728 187.547 55.528C184.347 56.328 145.147 31.528 138.747 32.328z"/>
+ </g>
+ <g style="fill: #f3bf9c">
+ <path d="M140.056 34.073C133.655 34.873 107.313 11.613 123.255 42.873C143.656 82.874 64.855 82.074 48.055 70.874C31.255 59.674 55.255 89.274 55.255 89.274C73.655 109.274 39.255 92.474 39.255 92.474C4.855 79.674 -19.145 105.274 -22.345 106.074C-25.545 106.874 -30.345 110.074 -31.145 103.674C-31.945 97.274 -38.668 81.578 -71.145 106.874C-98.564 127.947 -110.509 109.219 -110.509 109.219L-115.709 111.874C-131.709 81.674 -122.273 137.929 -122.273 137.929C-113.473 172.329 20.055 126.874 20.055 126.874C20.055 126.874 188.856 96.474 200.056 92.474C211.256 88.474 301.22 94.437 301.22 94.437L296.056 74.583C231.256 28.183 216.856 54.874 203.256 50.874C189.656 46.873 192.056 56.474 188.856 57.274C185.656 58.074 146.456 33.273 140.056 34.073z"/>
+ </g>
+ <g style="fill: #f5ccb0">
+ <path d="M141.365 35.819C134.965 36.619 107.523 13.944 124.565 44.619C146.565 84.219 66.164 83.819 49.364 72.619C32.564 61.419 56.564 91.019 56.564 91.019C74.964 111.019 40.564 94.219 40.564 94.219C6.164 81.419 -17.836 107.019 -21.036 107.819C-24.236 108.619 -29.036 111.819 -29.836 105.419C-30.636 99.019 -37.227 83.492 -69.836 108.619C-98.491 130.438 -110.127 112.256 -110.127 112.256L-115.727 113.419C-130.128 85.019 -121.618 140.983 -121.618 140.983C-112.818 175.384 21.364 128.619 21.364 128.619C21.364 128.619 190.165 98.219 201.365 94.219C212.565 90.219 301.656 96.11 301.656 96.11L296.565 75.746C231.765 29.346 218.165 56.619 204.565 52.619C190.965 48.619 193.365 58.219 190.165 59.019C186.965 59.819 147.765 35.019 141.365 35.819z"/>
+ </g>
+ <g style="fill: #f8d8c4">
+ <path d="M142.674 37.565C136.274 38.365 108.832 15.689 125.874 46.365C147.874 85.965 67.474 85.565 50.674 74.365C33.874 63.165 57.874 92.765 57.874 92.765C76.274 112.765 41.874 95.965 41.874 95.965C7.473 83.165 -16.527 108.765 -19.727 109.565C-22.927 110.365 -27.727 113.565 -28.527 107.165C-29.327 100.765 -35.786 85.405 -68.527 110.365C-98.418 132.929 -109.745 115.293 -109.745 115.293L-115.745 114.965C-129.346 88.564 -120.963 144.038 -120.963 144.038C-112.163 178.438 22.673 130.365 22.673 130.365C22.673 130.365 191.474 99.965 202.674 95.965C213.874 91.965 302.093 97.783 302.093 97.783L297.075 76.91C232.274 30.51 219.474 58.365 205.874 54.365C192.274 50.365 194.674 59.965 191.474 60.765C188.274 61.565 149.074 36.765 142.674 37.565z"/>
+ </g>
+ <g style="fill: #fae5d7">
+ <path d="M143.983 39.31C137.583 40.11 110.529 17.223 127.183 48.11C149.183 88.91 68.783 87.31 51.983 76.11C35.183 64.91 59.183 94.51 59.183 94.51C77.583 114.51 43.183 97.71 43.183 97.71C8.783 84.91 -15.217 110.51 -18.417 111.31C-21.618 112.11 -26.418 115.31 -27.218 108.91C-28.018 102.51 -34.346 87.318 -67.218 112.11C-98.345 135.42 -109.363 118.329 -109.363 118.329L-115.764 116.51C-128.764 92.51 -120.309 147.093 -120.309 147.093C-111.509 181.493 23.983 132.11 23.983 132.11C23.983 132.11 192.783 101.71 203.983 97.71C215.183 93.71 302.529 99.456 302.529 99.456L297.583 78.074C232.783 31.673 220.783 60.11 207.183 56.11C193.583 52.11 195.983 61.71 192.783 62.51C189.583 63.31 150.383 38.51 143.983 39.31z"/>
+ </g>
+ <g style="fill: #fcf2eb">
+ <path d="M145.292 41.055C138.892 41.855 112.917 18.411 128.492 49.855C149.692 92.656 70.092 89.056 53.292 77.856C36.492 66.656 60.492 96.256 60.492 96.256C78.892 116.256 44.492 99.456 44.492 99.456C10.092 86.656 -13.908 112.256 -17.108 113.056C-20.308 113.856 -25.108 117.056 -25.908 110.656C-26.708 104.256 -32.905 89.232 -65.908 113.856C-98.273 137.911 -108.982 121.365 -108.982 121.365L-115.782 118.056C-128.582 94.856 -119.654 150.147 -119.654 150.147C-110.854 184.547 25.292 133.856 25.292 133.856C25.292 133.856 194.093 103.456 205.293 99.456C216.493 95.456 302.965 101.128 302.965 101.128L298.093 79.237C233.292 32.837 222.093 61.856 208.493 57.856C194.893 53.855 197.293 63.456 194.093 64.256C190.892 65.056 151.692 40.255 145.292 41.055z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M-115.8 119.601C-128.6 97.6 -119 153.201 -119 153.201C-110.2 187.601 26.6 135.601 26.6 135.601C26.6 135.601 195.401 105.2 206.601 101.2C217.801 97.2 303.401 102.8 303.401 102.8L298.601 80.4C233.801 34 223.401 63.6 209.801 59.6C196.201 55.6 198.601 65.2 195.401 66C192.201 66.8 153.001 42 146.601 42.8C140.201 43.6 114.981 19.793 129.801 51.6C152.028 99.307 69.041 89.227 54.6 79.6C37.8 68.4 61.8 98 61.8 98C80.2 118.001 45.8 101.2 45.8 101.2C11.4 88.4 -12.6 114.001 -15.8 114.801C-19 115.601 -23.8 118.801 -24.6 112.401C-25.4 106 -31.465 91.144 -64.6 115.601C-98.2 140.401 -108.6 124.401 -108.6 124.401L-115.8 119.601z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-74.2 149.601C-74.2 149.601 -81.4 161.201 -60.6 174.401C-60.6 174.401 -59.2 175.801 -77.2 171.601C-77.2 171.601 -83.4 169.601 -85 159.201C-85 159.201 -89.8 154.801 -94.6 149.201C-99.4 143.601 -74.2 149.601 -74.2 149.601z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M65.8 102C65.8 102 83.498 128.821 82.9 133.601C81.6 144.001 81.4 153.601 84.6 157.601C87.801 161.601 96.601 194.801 96.601 194.801C96.601 194.801 96.201 196.001 108.601 158.001C108.601 158.001 120.201 142.001 100.201 123.601C100.201 123.601 65 94.8 65.8 102z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-54.2 176.401C-54.2 176.401 -43 183.601 -57.4 214.801L-51 212.401C-51 212.401 -51.8 223.601 -55 226.001L-47.8 222.801C-47.8 222.801 -43 230.801 -47 235.601C-47 235.601 -30.2 243.601 -31 250.001C-31 250.001 -24.6 242.001 -28.6 235.601C-32.6 229.201 -39.8 233.201 -39 214.801L-47.8 218.001C-47.8 218.001 -42.2 209.201 -42.2 202.801L-50.2 205.201C-50.2 205.201 -34.731 178.623 -45.4 177.201C-51.4 176.401 -54.2 176.401 -54.2 176.401z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-21.8 193.201C-21.8 193.201 -19 188.801 -21.8 189.601C-24.6 190.401 -55.8 205.201 -61.8 214.801C-61.8 214.801 -27.4 190.401 -21.8 193.201z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-11.4 201.201C-11.4 201.201 -8.6 196.801 -11.4 197.601C-14.2 198.401 -45.4 213.201 -51.4 222.801C-51.4 222.801 -17 198.401 -11.4 201.201z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M1.8 186.001C1.8 186.001 4.6 181.601 1.8 182.401C-1 183.201 -32.2 198.001 -38.2 207.601C-38.2 207.601 -3.8 183.201 1.8 186.001z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-21.4 229.601C-21.4 229.601 -21.4 223.601 -24.2 224.401C-27 225.201 -63 242.801 -69 252.401C-69 252.401 -27 226.801 -21.4 229.601z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-20.2 218.801C-20.2 218.801 -19 214.001 -21.8 214.801C-23.8 214.801 -50.2 226.401 -56.2 236.001C-56.2 236.001 -26.6 214.401 -20.2 218.801z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-34.6 266.401L-44.6 274.001C-44.6 274.001 -34.2 266.401 -30.6 267.601C-30.6 267.601 -37.4 278.801 -38.2 284.001C-38.2 284.001 -27.8 271.201 -22.2 271.601C-22.2 271.601 -14.6 272.001 -14.6 282.801C-14.6 282.801 -9 272.401 -5.8 272.801C-5.8 272.801 -4.6 279.201 -5.8 286.001C-5.8 286.001 -1.8 278.401 2.2 280.001C2.2 280.001 8.6 278.001 7.8 289.601C7.8 289.601 7.8 300.001 7 302.801C7 302.801 12.6 276.401 15 276.001C15 276.001 23 274.801 27.8 283.601C27.8 283.601 23.8 276.001 28.6 278.001C28.6 278.001 39.4 279.601 42.6 286.401C42.6 286.401 35.8 274.401 41.4 277.601C41.4 277.601 48.2 277.601 49.4 284.001C49.4 284.001 57.8 305.201 59.8 306.801C59.8 306.801 52.2 285.201 53.8 285.201C53.8 285.201 51.8 273.201 57 288.001C57 288.001 53.8 274.001 59.4 274.801C65 275.601 69.4 285.601 77.8 283.201C77.8 283.201 87.401 288.801 89.401 219.601L-34.6 266.401z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-29.8 173.601C-29.8 173.601 -15 167.601 25 173.601C25 173.601 32.2 174.001 39 165.201C45.8 156.401 72.6 149.201 79 151.201L88.601 157.601L89.401 158.801C89.401 158.801 101.801 169.201 102.201 176.801C102.601 184.401 87.801 232.401 78.2 248.401C68.6 264.401 59 276.801 39.8 274.401C39.8 274.401 19 270.401 -6.6 274.401C-6.6 274.401 -35.8 272.801 -38.6 264.801C-41.4 256.801 -27.4 241.601 -27.4 241.601C-27.4 241.601 -23 233.201 -24.2 218.801C-25.4 204.401 -25 176.401 -29.8 173.601z"/>
+ </g>
+ <g style="fill: #e5668c">
+ <path d="M-7.8 175.601C0.6 194.001 -29 259.201 -29 259.201C-31 260.801 -16.34 266.846 -6.2 264.401C4.746 261.763 45 266.001 45 266.001C68.6 250.401 81.4 206.001 81.4 206.001C81.4 206.001 91.801 182.001 74.2 178.801C56.6 175.601 -7.8 175.601 -7.8 175.601z"/>
+ </g>
+ <g style="fill: #b23259">
+ <path d="M-9.831 206.497C-6.505 193.707 -4.921 181.906 -7.8 175.601C-7.8 175.601 54.6 182.001 65.8 161.201C70.041 153.326 84.801 184.001 84.4 193.601C84.4 193.601 21.4 208.001 6.6 196.801L-9.831 206.497z"/>
+ </g>
+ <g style="fill: #a5264c">
+ <path d="M-5.4 222.801C-5.4 222.801 -3.4 230.001 -5.8 234.001C-5.8 234.001 -7.4 234.801 -8.6 235.201C-8.6 235.201 -7.4 238.801 -1.4 240.401C-1.4 240.401 0.6 244.801 3 245.201C5.4 245.601 10.2 251.201 14.2 250.001C18.2 248.801 29.4 244.801 29.4 244.801C29.4 244.801 35 241.601 43.8 245.201C43.8 245.201 46.175 244.399 46.6 240.401C47.1 235.701 50.2 232.001 52.2 230.001C54.2 228.001 63.8 215.201 62.6 214.801C61.4 214.401 -5.4 222.801 -5.4 222.801z"/>
+ </g>
+ <g style="fill: #ff727f; stroke:#000000">
+ <path d="M-9.8 174.401C-9.8 174.401 -12.6 196.801 -9.4 205.201C-6.2 213.601 -7 215.601 -7.8 219.601C-8.6 223.601 -4.2 233.601 1.4 239.601L13.4 241.201C13.4 241.201 28.6 237.601 37.8 240.401C37.8 240.401 46.794 241.744 50.2 226.801C50.2 226.801 55 220.401 62.2 217.601C69.4 214.801 76.6 173.201 72.6 165.201C68.6 157.201 54.2 152.801 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-8.2 249.201C-8.2 249.201 -9 247.201 -13.4 246.801C-13.4 246.801 -35.8 243.201 -44.2 230.801C-44.2 230.801 -51 225.201 -46.6 236.801C-46.6 236.801 -36.2 257.201 -29.4 260.001C-29.4 260.001 -13 264.001 -8.2 249.201z"/>
+ </g>
+ <g style="fill: #cc3f4c">
+ <path d="M71.742 185.229C72.401 177.323 74.354 168.709 72.6 165.201C66.154 152.307 49.181 157.695 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401C-9.8 174.401 -11.545 188.364 -10.705 198.376C-10.705 198.376 26.6 186.801 27.4 192.401C27.4 192.401 29 189.201 38.2 189.201C47.4 189.201 70.142 188.029 71.742 185.229z"/>
+ </g>
+ <g style="stroke:#a51926; stroke-width:2">
+ <path d="M28.6 175.201C28.6 175.201 33.4 180.001 29.8 189.601C29.8 189.601 15.4 205.601 17.4 219.601"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-19.4 260.001C-19.4 260.001 -23.8 247.201 -15 254.001C-15 254.001 -10.2 256.001 -11.4 257.601C-12.6 259.201 -18.2 263.201 -19.4 260.001z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-14.36 261.201C-14.36 261.201 -17.88 250.961 -10.84 256.401C-10.84 256.401 -6.419 258.849 -7.96 259.281C-12.52 260.561 -7.96 263.121 -14.36 261.201z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-9.56 261.201C-9.56 261.201 -13.08 250.961 -6.04 256.401C-6.04 256.401 -1.665 258.711 -3.16 259.281C-6.52 260.561 -3.16 263.121 -9.56 261.201z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-2.96 261.401C-2.96 261.401 -6.48 251.161 0.56 256.601C0.56 256.601 4.943 258.933 3.441 259.481C0.48 260.561 3.441 263.321 -2.96 261.401z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M3.52 261.321C3.52 261.321 0 251.081 7.041 256.521C7.041 256.521 10.881 258.121 9.921 259.401C8.961 260.681 9.921 263.241 3.52 261.321z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M10.2 262.001C10.2 262.001 5.4 249.601 14.6 256.001C14.6 256.001 19.4 258.001 18.2 259.601C17 261.201 18.2 264.401 10.2 262.001z"/>
+ </g>
+ <g style="stroke:#a5264c; stroke-width:2">
+ <path d="M-18.2 244.801C-18.2 244.801 -5 242.001 1 245.201C1 245.201 7 246.401 8.2 246.001C9.4 245.601 12.6 245.201 12.6 245.201"/>
+ </g>
+ <g style="stroke:#a5264c; stroke-width:2">
+ <path d="M15.8 253.601C15.8 253.601 27.8 240.001 39.8 244.401C46.816 246.974 45.8 243.601 46.6 240.801C47.4 238.001 47.6 233.801 52.6 230.801"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M33 237.601C33 237.601 29 226.801 26.2 239.601C23.4 252.401 20.2 256.001 18.6 258.801C18.6 258.801 18.6 264.001 27 263.601C27 263.601 37.8 263.201 38.2 260.401C38.6 257.601 37 246.001 33 237.601z"/>
+ </g>
+ <g style="stroke:#a5264c; stroke-width:2">
+ <path d="M47 244.801C47 244.801 50.6 242.401 53 243.601"/>
+ </g>
+ <g style="stroke:#a5264c; stroke-width:2">
+ <path d="M53.5 228.401C53.5 228.401 56.4 223.501 61.2 222.701"/>
+ </g>
+ <g style="fill: #b2b2b2">
+ <path d="M-25.8 265.201C-25.8 265.201 -7.8 268.401 -3.4 266.801C-3.4 266.801 5.4 266.801 -3 268.801C-3 268.801 -15.8 268.801 -23.8 267.601C-23.8 267.601 -35.4 262.001 -25.8 265.201z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-11.8 172.001C-11.8 172.001 5.8 172.001 7.8 172.801C7.8 172.801 15 203.601 11.4 211.201C11.4 211.201 10.2 214.001 7.4 208.401C7.4 208.401 -11 175.601 -14.2 173.601C-17.4 171.601 -13 172.001 -11.8 172.001z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-88.9 169.301C-88.9 169.301 -80 171.001 -67.4 173.601C-67.4 173.601 -62.6 196.001 -59.4 200.801C-56.2 205.601 -59.8 205.601 -63.4 202.801C-67 200.001 -81.8 186.001 -83.8 181.601C-85.8 177.201 -88.9 169.301 -88.9 169.301z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-67.039 173.818C-67.039 173.818 -61.239 175.366 -60.23 177.581C-59.222 179.795 -61.432 183.092 -61.432 183.092C-61.432 183.092 -62.432 186.397 -63.634 184.235C-64.836 182.072 -67.708 174.412 -67.039 173.818z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-67 173.601C-67 173.601 -63.4 178.801 -59.8 178.801C-56.2 178.801 -55.818 178.388 -53 179.001C-48.4 180.001 -48.8 178.001 -42.2 179.201C-39.56 179.681 -37 178.801 -34.2 180.001C-31.4 181.201 -28.2 180.401 -27 178.401C-25.8 176.401 -21 172.201 -21 172.201C-21 172.201 -33.8 174.001 -36.6 174.801C-36.6 174.801 -59 176.001 -67 173.601z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-22.4 173.801C-22.4 173.801 -28.85 177.301 -29.25 179.701C-29.65 182.101 -24 185.801 -24 185.801C-24 185.801 -21.25 190.401 -20.65 188.001C-20.05 185.601 -21.6 174.201 -22.4 173.801z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-59.885 179.265C-59.885 179.265 -52.878 190.453 -52.661 179.242C-52.661 179.242 -52.104 177.984 -53.864 177.962C-59.939 177.886 -58.418 173.784 -59.885 179.265z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-52.707 179.514C-52.707 179.514 -44.786 190.701 -45.422 179.421C-45.422 179.421 -45.415 179.089 -47.168 178.936C-51.915 178.522 -51.57 174.004 -52.707 179.514z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-45.494 179.522C-45.494 179.522 -37.534 190.15 -38.203 180.484C-38.203 180.484 -38.084 179.251 -39.738 178.95C-43.63 178.244 -43.841 174.995 -45.494 179.522z"/>
+ </g>
+ <g style="fill: #ffffcc; stroke:#000000; stroke-width:0.5">
+ <path d="M-38.618 179.602C-38.618 179.602 -30.718 191.163 -30.37 181.382C-30.37 181.382 -28.726 180.004 -30.472 179.782C-36.29 179.042 -35.492 174.588 -38.618 179.602z"/>
+ </g>
+ <g style="fill: #e5e5b2">
+ <path d="M-74.792 183.132L-82.45 181.601C-85.05 176.601 -87.15 170.451 -87.15 170.451C-87.15 170.451 -80.8 171.451 -68.3 174.251C-68.3 174.251 -67.424 177.569 -65.952 183.364L-74.792 183.132z"/>
+ </g>
+ <g style="fill: #e5e5b2">
+ <path d="M-9.724 178.47C-11.39 175.964 -12.707 174.206 -13.357 173.8C-16.37 171.917 -12.227 172.294 -11.098 172.294C-11.098 172.294 5.473 172.294 7.356 173.047C7.356 173.047 7.88 175.289 8.564 178.68C8.564 178.68 -1.524 176.67 -9.724 178.47z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M43.88 40.321C71.601 44.281 97.121 8.641 98.881 -1.04C100.641 -10.72 90.521 -22.6 90.521 -22.6C91.841 -25.68 87.001 -39.76 81.721 -49C76.441 -58.24 60.54 -57.266 43 -58.24C27.16 -59.12 8.68 -35.8 7.36 -34.04C6.04 -32.28 12.2 6.001 13.52 11.721C14.84 17.441 12.2 43.841 12.2 43.841C46.44 34.741 16.16 36.361 43.88 40.321z"/>
+ </g>
+ <g style="fill: #ea8e51">
+ <path d="M8.088 -33.392C6.792 -31.664 12.84 5.921 14.136 11.537C15.432 17.153 12.84 43.073 12.84 43.073C45.512 34.193 16.728 35.729 43.944 39.617C71.161 43.505 96.217 8.513 97.945 -0.992C99.673 -10.496 89.737 -22.16 89.737 -22.16C91.033 -25.184 86.281 -39.008 81.097 -48.08C75.913 -57.152 60.302 -56.195 43.08 -57.152C27.528 -58.016 9.384 -35.12 8.088 -33.392z"/>
+ </g>
+ <g style="fill: #efaa7c">
+ <path d="M8.816 -32.744C7.544 -31.048 13.48 5.841 14.752 11.353C16.024 16.865 13.48 42.305 13.48 42.305C44.884 33.145 17.296 35.097 44.008 38.913C70.721 42.729 95.313 8.385 97.009 -0.944C98.705 -10.272 88.953 -21.72 88.953 -21.72C90.225 -24.688 85.561 -38.256 80.473 -47.16C75.385 -56.064 60.063 -55.125 43.16 -56.064C27.896 -56.912 10.088 -34.44 8.816 -32.744z"/>
+ </g>
+ <g style="fill: #f4c6a8">
+ <path d="M9.544 -32.096C8.296 -30.432 14.12 5.761 15.368 11.169C16.616 16.577 14.12 41.537 14.12 41.537C43.556 32.497 17.864 34.465 44.072 38.209C70.281 41.953 94.409 8.257 96.073 -0.895C97.737 -10.048 88.169 -21.28 88.169 -21.28C89.417 -24.192 84.841 -37.504 79.849 -46.24C74.857 -54.976 59.824 -54.055 43.24 -54.976C28.264 -55.808 10.792 -33.76 9.544 -32.096z"/>
+ </g>
+ <g style="fill: #f9e2d3">
+ <path d="M10.272 -31.448C9.048 -29.816 14.76 5.681 15.984 10.985C17.208 16.289 14.76 40.769 14.76 40.769C42.628 31.849 18.432 33.833 44.136 37.505C69.841 41.177 93.505 8.129 95.137 -0.848C96.769 -9.824 87.385 -20.84 87.385 -20.84C88.609 -23.696 84.121 -36.752 79.225 -45.32C74.329 -53.888 59.585 -52.985 43.32 -53.888C28.632 -54.704 11.496 -33.08 10.272 -31.448z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M44.2 36.8C69.4 40.4 92.601 8 94.201 -0.8C95.801 -9.6 86.601 -20.4 86.601 -20.4C87.801 -23.2 83.4 -36 78.6 -44.4C73.8 -52.8 59.346 -51.914 43.4 -52.8C29 -53.6 12.2 -32.4 11 -30.8C9.8 -29.2 15.4 5.6 16.6 10.8C17.8 16 15.4 40 15.4 40C40.9 31.4 19 33.2 44.2 36.8z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M90.601 2.8C90.601 2.8 62.8 10.4 51.2 8.8C51.2 8.8 35.4 2.2 26.6 24C26.6 24 23 31.2 21 33.2C19 35.2 90.601 2.8 90.601 2.8z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M94.401 0.6C94.401 0.6 65.4 12.8 55.4 12.4C55.4 12.4 39 7.8 30.6 22.4C30.6 22.4 22.2 31.6 19 33.2C19 33.2 18.6 34.8 25 30.8L35.4 36C35.4 36 50.2 45.6 59.8 29.6C59.8 29.6 63.8 18.4 63.8 16.4C63.8 14.4 85 8.8 86.601 8.4C88.201 8 94.801 3.8 94.401 0.6z"/>
+ </g>
+ <g style="fill: #99cc32">
+ <path d="M47 36.514C40.128 36.514 31.755 32.649 31.755 26.4C31.755 20.152 40.128 13.887 47 13.887C53.874 13.887 59.446 18.952 59.446 25.2C59.446 31.449 53.874 36.514 47 36.514z"/>
+ </g>
+ <g style="fill: #659900">
+ <path d="M43.377 19.83C38.531 20.552 33.442 22.055 33.514 21.839C35.054 17.22 41.415 13.887 47 13.887C51.296 13.887 55.084 15.865 57.32 18.875C57.32 18.875 52.004 18.545 43.377 19.83z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M55.4 19.6C55.4 19.6 51 16.4 51 18.6C51 18.6 54.6 23 55.4 19.6z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M45.4 27.726C42.901 27.726 40.875 25.7 40.875 23.2C40.875 20.701 42.901 18.675 45.4 18.675C47.9 18.675 49.926 20.701 49.926 23.2C49.926 25.7 47.9 27.726 45.4 27.726z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M-58.6 14.4C-58.6 14.4 -61.8 -6.8 -59.4 -11.2C-59.4 -11.2 -48.6 -21.2 -49 -24.8C-49 -24.8 -49.4 -42.8 -50.6 -43.6C-51.8 -44.4 -59.4 -50.4 -65.4 -44C-65.4 -44 -75.8 -26 -75 -19.6L-75 -17.6C-75 -17.6 -82.6 -18 -84.2 -16C-84.2 -16 -85.4 -10.8 -86.6 -10.4C-86.6 -10.4 -89.4 -8 -87.4 -5.2C-87.4 -5.2 -89.4 -2.8 -89 1.2L-81.4 5.2C-81.4 5.2 -79.4 19.6 -68.6 24.8C-63.764 27.129 -60.6 20.4 -58.6 14.4z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M-59.6 12.56C-59.6 12.56 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.48 -40.36 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.96 -59.6 12.56z"/>
+ </g>
+ <g style="fill: #eb955c">
+ <path d="M-51.05 -42.61C-52.14 -43.47 -59.63 -49.24 -65.48 -43C-65.48 -43 -75.62 -25.45 -74.84 -19.21L-74.84 -17.26C-74.84 -17.26 -82.25 -17.65 -83.81 -15.7C-83.81 -15.7 -84.98 -10.63 -86.15 -10.24C-86.15 -10.24 -88.88 -7.9 -86.93 -5.17C-86.93 -5.17 -88.88 -2.83 -88.49 1.07L-81.08 4.97C-81.08 4.97 -79.13 19.01 -68.6 24.08C-63.886 26.35 -60.8 19.79 -58.85 13.94C-58.85 13.94 -61.97 -6.73 -59.63 -11.02C-59.63 -11.02 -49.1 -20.77 -49.49 -24.28C-49.49 -24.28 -49.88 -41.83 -51.05 -42.61z"/>
+ </g>
+ <g style="fill: #f2b892">
+ <path d="M-51.5 -41.62C-52.48 -42.54 -59.86 -48.08 -65.56 -42C-65.56 -42 -75.44 -24.9 -74.68 -18.82L-74.68 -16.92C-74.68 -16.92 -81.9 -17.3 -83.42 -15.4C-83.42 -15.4 -84.56 -10.46 -85.7 -10.08C-85.7 -10.08 -88.36 -7.8 -86.46 -5.14C-86.46 -5.14 -88.36 -2.86 -87.98 0.94L-80.76 4.74C-80.76 4.74 -78.86 18.42 -68.6 23.36C-64.006 25.572 -61 19.18 -59.1 13.48C-59.1 13.48 -62.14 -6.66 -59.86 -10.84C-59.86 -10.84 -49.6 -20.34 -49.98 -23.76C-49.98 -23.76 -50.36 -40.86 -51.5 -41.62z"/>
+ </g>
+ <g style="fill: #f8dcc8">
+ <path d="M-51.95 -40.63C-52.82 -41.61 -60.09 -46.92 -65.64 -41C-65.64 -41 -75.26 -24.35 -74.52 -18.43L-74.52 -16.58C-74.52 -16.58 -81.55 -16.95 -83.03 -15.1C-83.03 -15.1 -84.14 -10.29 -85.25 -9.92C-85.25 -9.92 -87.84 -7.7 -85.99 -5.11C-85.99 -5.11 -87.84 -2.89 -87.47 0.81L-80.44 4.51C-80.44 4.51 -78.59 17.83 -68.6 22.64C-64.127 24.794 -61.2 18.57 -59.35 13.02C-59.35 13.02 -62.31 -6.59 -60.09 -10.66C-60.09 -10.66 -50.1 -19.91 -50.47 -23.24C-50.47 -23.24 -50.84 -39.89 -51.95 -40.63z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M-59.6 12.46C-59.6 12.46 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.16 -40.68 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.86 -59.6 12.46z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-62.7 6.2C-62.7 6.2 -84.3 -4 -85.2 -4.8C-85.2 -4.8 -76.1 3.4 -75.3 3.4C-74.5 3.4 -62.7 6.2 -62.7 6.2z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-79.8 0C-79.8 0 -61.4 3.6 -61.4 8C-61.4 10.912 -61.643 24.331 -67 22.8C-75.4 20.4 -71.8 6 -79.8 0z"/>
+ </g>
+ <g style="fill: #99cc32">
+ <path d="M-71.4 3.8C-71.4 3.8 -62.422 5.274 -61.4 8C-60.8 9.6 -60.137 17.908 -65.6 19C-70.152 19.911 -72.382 9.69 -71.4 3.8z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M14.595 46.349C14.098 44.607 15.409 44.738 17.2 44.2C19.2 43.6 31.4 39.8 32.2 37.2C33 34.6 46.2 39 46.2 39C48 39.8 52.4 42.4 52.4 42.4C57.2 43.6 63.8 44 63.8 44C66.2 45 69.6 47.8 69.6 47.8C84.2 58 96.601 50.8 96.601 50.8C116.601 44.2 110.601 27 110.601 27C107.601 18 110.801 14.6 110.801 14.6C111.001 10.8 118.201 17.2 118.201 17.2C120.801 21.4 121.601 26.4 121.601 26.4C129.601 37.6 126.201 19.8 126.201 19.8C126.401 18.8 123.601 15.2 123.601 14C123.601 12.8 121.801 9.4 121.801 9.4C118.801 6 121.201 -1 121.201 -1C123.001 -14.8 120.801 -13 120.801 -13C119.601 -14.8 110.401 -4.8 110.401 -4.8C108.201 -1.4 102.201 0.2 102.201 0.2C99.401 2 96.001 0.6 96.001 0.6C93.401 0.2 87.801 7.2 87.801 7.2C90.601 7 93.001 11.4 95.401 11.6C97.801 11.8 99.601 9.2 101.201 8.6C102.801 8 105.601 13.8 105.601 13.8C106.001 16.4 100.401 21.2 100.401 21.2C100.001 25.8 98.401 24.2 98.401 24.2C95.401 23.6 94.201 27.4 93.201 32C92.201 36.6 88.001 37 88.001 37C86.401 44.4 85.2 41.4 85.2 41.4C85 35.8 79 41.6 79 41.6C77.8 43.6 73.2 41.4 73.2 41.4C66.4 39.4 68.8 37.4 68.8 37.4C70.6 35.2 81.8 37.4 81.8 37.4C84 35.8 76 31.8 76 31.8C75.4 30 76.4 25.6 76.4 25.6C77.6 22.4 84.4 16.8 84.4 16.8C93.801 15.6 91.001 14 91.001 14C84.801 8.8 79 16.4 79 16.4C76.8 22.6 59.4 37.6 59.4 37.6C54.6 41 57.2 34.2 53.2 37.6C49.2 41 28.6 32 28.6 32C17.038 30.807 14.306 46.549 10.777 43.429C10.777 43.429 16.195 51.949 14.595 46.349z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M209.401 -120C209.401 -120 183.801 -112 181.001 -93.2C181.001 -93.2 178.601 -70.4 199.001 -52.8C199.001 -52.8 199.401 -46.4 201.401 -43.2C201.401 -43.2 199.801 -38.4 218.601 -46L245.801 -54.4C245.801 -54.4 252.201 -56.8 257.401 -65.6C262.601 -74.4 277.801 -93.2 274.201 -118.4C274.201 -118.4 275.401 -129.6 269.401 -130C269.401 -130 261.001 -131.6 253.801 -124C253.801 -124 247.001 -120.8 244.601 -121.2L209.401 -120z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M264.022 -120.99C264.022 -120.99 266.122 -129.92 261.282 -125.08C261.282 -125.08 254.242 -119.36 246.761 -119.36C246.761 -119.36 232.241 -117.16 227.841 -103.96C227.841 -103.96 223.881 -77.12 231.801 -71.4C231.801 -71.4 236.641 -63.92 243.681 -70.52C250.722 -77.12 266.222 -107.35 264.022 -120.99z"/>
+ </g>
+ <g style="fill: #323232">
+ <path d="M263.648 -120.632C263.648 -120.632 265.738 -129.376 260.986 -124.624C260.986 -124.624 254.074 -119.008 246.729 -119.008C246.729 -119.008 232.473 -116.848 228.153 -103.888C228.153 -103.888 224.265 -77.536 232.041 -71.92C232.041 -71.92 236.793 -64.576 243.705 -71.056C250.618 -77.536 265.808 -107.24 263.648 -120.632z"/>
+ </g>
+ <g style="fill: #666666">
+ <path d="M263.274 -120.274C263.274 -120.274 265.354 -128.832 260.69 -124.168C260.69 -124.168 253.906 -118.656 246.697 -118.656C246.697 -118.656 232.705 -116.536 228.465 -103.816C228.465 -103.816 224.649 -77.952 232.281 -72.44C232.281 -72.44 236.945 -65.232 243.729 -71.592C250.514 -77.952 265.394 -107.13 263.274 -120.274z"/>
+ </g>
+ <g style="fill: #999999">
+ <path d="M262.9 -119.916C262.9 -119.916 264.97 -128.288 260.394 -123.712C260.394 -123.712 253.738 -118.304 246.665 -118.304C246.665 -118.304 232.937 -116.224 228.777 -103.744C228.777 -103.744 225.033 -78.368 232.521 -72.96C232.521 -72.96 237.097 -65.888 243.753 -72.128C250.41 -78.368 264.98 -107.02 262.9 -119.916z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M262.526 -119.558C262.526 -119.558 264.586 -127.744 260.098 -123.256C260.098 -123.256 253.569 -117.952 246.633 -117.952C246.633 -117.952 233.169 -115.912 229.089 -103.672C229.089 -103.672 225.417 -78.784 232.761 -73.48C232.761 -73.48 237.249 -66.544 243.777 -72.664C250.305 -78.784 264.566 -106.91 262.526 -119.558z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M262.151 -119.2C262.151 -119.2 264.201 -127.2 259.801 -122.8C259.801 -122.8 253.401 -117.6 246.601 -117.6C246.601 -117.6 233.401 -115.6 229.401 -103.6C229.401 -103.6 225.801 -79.2 233.001 -74C233.001 -74 237.401 -67.2 243.801 -73.2C250.201 -79.2 264.151 -106.8 262.151 -119.2z"/>
+ </g>
+ <g style="fill: #992600">
+ <path d="M50.6 84C50.6 84 30.2 64.8 22.2 64C22.2 64 -12.2 60 -27 78C-27 78 -9.4 57.6 18.2 63.2C18.2 63.2 -3.4 58.8 -15.8 62C-15.8 62 -32.6 62 -42.2 76L-45 80.8C-45 80.8 -41 66 -22.6 60C-22.6 60 0.2 55.2 11 60C11 60 -10.6 53.2 -20.6 55.2C-20.6 55.2 -51 52.8 -63.8 79.2C-63.8 79.2 -59.8 64.8 -45 57.6C-45 57.6 -31.4 48.8 -11 51.6C-11 51.6 3.4 54.8 8.6 57.2C13.8 59.6 12.6 56.8 4.2 52C4.2 52 -1.4 42 -15.4 42.4C-15.4 42.4 -58.2 46 -68.6 58C-68.6 58 -55 46.8 -44.6 44C-44.6 44 -22.2 36 -13.8 36.8C-13.8 36.8 11 37.8 18.6 33.8C18.6 33.8 7.4 38.8 10.6 42C13.8 45.2 20.6 52.8 20.6 54C20.6 55.2 44.8 77.3 48.4 81.7L50.6 84z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M189 278C189 278 173.5 241.5 161 232C161 232 187 248 190.5 266C190.5 266 190.5 276 189 278z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M236 285.5C236 285.5 209.5 230.5 191 206.5C191 206.5 234.5 244 239.5 270.5L240 276L237 273.5C237 273.5 236.5 282.5 236 285.5z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M292.5 237C292.5 237 230 177.5 228.5 175C228.5 175 289 241 292 248.5C292 248.5 290 239.5 292.5 237z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M104 280.5C104 280.5 123.5 228.5 142.5 251C142.5 251 157.5 261 157 264C157 264 153 257.5 135 258C135 258 116 255 104 280.5z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M294.5 153C294.5 153 249.5 124.5 242 123C230.193 120.639 291.5 152 296.5 162.5C296.5 162.5 298.5 160 294.5 153z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M143.801 259.601C143.801 259.601 164.201 257.601 171.001 250.801L175.401 254.401L193.001 216.001L196.601 221.201C196.601 221.201 211.001 206.401 210.201 198.401C209.401 190.401 223.001 204.401 223.001 204.401C223.001 204.401 222.201 192.801 229.401 199.601C229.401 199.601 227.001 184.001 235.401 192.001C235.401 192.001 224.864 161.844 247.401 187.601C253.001 194.001 248.601 187.201 248.601 187.201C248.601 187.201 222.601 139.201 244.201 153.601C244.201 153.601 246.201 130.801 245.001 126.401C243.801 122.001 241.801 99.6 237.001 94.4C232.201 89.2 237.401 87.6 243.001 92.8C243.001 92.8 231.801 68.8 245.001 80.8C245.001 80.8 241.401 65.6 237.001 62.8C237.001 62.8 231.401 45.6 246.601 56.4C246.601 56.4 242.201 44 239.001 40.8C239.001 40.8 227.401 13.2 234.601 18L239.001 21.6C239.001 21.6 232.201 7.6 238.601 12C245.001 16.4 245.001 16 245.001 16C245.001 16 223.801 -17.2 244.201 0.4C244.201 0.4 236.042 -13.518 232.601 -20.4C232.601 -20.4 213.801 -40.8 228.201 -34.4L233.001 -32.8C233.001 -32.8 224.201 -42.8 216.201 -44.4C208.201 -46 218.601 -52.4 225.001 -50.4C231.401 -48.4 247.001 -40.8 247.001 -40.8C247.001 -40.8 259.801 -22 263.801 -21.6C263.801 -21.6 243.801 -29.2 249.801 -21.2C249.801 -21.2 264.201 -7.2 257.001 -7.6C257.001 -7.6 251.001 -0.4 255.801 8.4C255.801 8.4 237.342 -9.991 252.201 15.6L259.001 32C259.001 32 234.601 7.2 245.801 29.2C245.801 29.2 263.001 52.8 265.001 53.2C267.001 53.6 271.401 62.4 271.401 62.4L267.001 60.4L272.201 69.2C272.201 69.2 261.001 57.2 267.001 70.4L272.601 84.8C272.601 84.8 252.201 62.8 265.801 92.4C265.801 92.4 249.401 87.2 258.201 104.4C258.201 104.4 256.601 120.401 257.001 125.601C257.401 130.801 258.601 159.201 254.201 167.201C249.801 175.201 260.201 194.401 262.201 198.401C264.201 202.401 267.801 213.201 259.001 204.001C250.201 194.801 254.601 200.401 256.601 209.201C258.601 218.001 264.601 233.601 263.801 239.201C263.801 239.201 262.601 240.401 259.401 236.801C259.401 236.801 244.601 214.001 246.201 228.401C246.201 228.401 245.001 236.401 241.801 245.201C241.801 245.201 238.601 256.001 238.601 247.201C238.601 247.201 235.401 230.401 232.601 238.001C229.801 245.601 226.201 251.601 223.401 254.001C220.601 256.401 215.401 233.601 214.201 244.001C214.201 244.001 202.201 231.601 197.401 248.001L185.801 264.401C185.801 264.401 185.401 252.001 184.201 258.001C184.201 258.001 154.201 264.001 143.801 259.601z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M109.401 -97.2C109.401 -97.2 97.801 -105.2 93.801 -104.8C89.801 -104.4 121.401 -113.6 162.601 -86C162.601 -86 167.401 -83.2 171.001 -83.6C171.001 -83.6 174.201 -81.2 171.401 -77.6C171.401 -77.6 162.601 -68 173.801 -56.8C173.801 -56.8 192.201 -50 186.601 -58.8C186.601 -58.8 197.401 -54.8 199.801 -50.8C202.201 -46.8 201.001 -50.8 201.001 -50.8C201.001 -50.8 194.601 -58 188.601 -63.2C188.601 -63.2 183.401 -65.2 180.601 -73.6C177.801 -82 175.401 -92 179.801 -95.2C179.801 -95.2 175.801 -90.8 176.601 -94.8C177.401 -98.8 181.001 -102.4 182.601 -102.8C184.201 -103.2 200.601 -119 207.401 -119.4C207.401 -119.4 198.201 -118 195.201 -119C192.201 -120 165.601 -131.4 159.601 -132.6C159.601 -132.6 142.801 -139.2 154.801 -137.2C154.801 -137.2 190.601 -133.4 208.801 -120.2C208.801 -120.2 201.601 -128.6 183.201 -135.6C183.201 -135.6 161.001 -148.2 125.801 -143.2C125.801 -143.2 108.001 -140 100.201 -138.2C100.201 -138.2 97.601 -138.8 97.001 -139.2C96.401 -139.6 84.6 -148.6 57 -141.6C57 -141.6 40 -137 31.4 -132.2C31.4 -132.2 16.2 -131 12.6 -127.8C12.6 -127.8 -6 -113.2 -8 -112.4C-10 -111.6 -21.4 -104 -22.2 -103.6C-22.2 -103.6 2.4 -110.2 4.8 -112.6C7.2 -115 24.6 -117.6 27 -116.2C29.4 -114.8 37.8 -115.4 28.2 -114.8C28.2 -114.8 103.801 -100 104.601 -98C105.401 -96 109.401 -97.2 109.401 -97.2z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M180.801 -106.4C180.801 -106.4 170.601 -113.8 168.601 -113.8C166.601 -113.8 154.201 -124 150.001 -123.6C145.801 -123.2 133.601 -133.2 106.201 -125C106.201 -125 105.601 -127 109.201 -127.8C109.201 -127.8 115.601 -130 116.001 -130.6C116.001 -130.6 136.201 -134.8 143.401 -131.2C143.401 -131.2 152.601 -128.6 158.801 -122.4C158.801 -122.4 170.001 -119.2 173.201 -120.2C173.201 -120.2 182.001 -118 182.401 -116.2C182.401 -116.2 188.201 -113.2 186.401 -110.6C186.401 -110.6 186.801 -109 180.801 -106.4z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M168.33 -108.509C169.137 -107.877 170.156 -107.779 170.761 -106.97C170.995 -106.656 170.706 -106.33 170.391 -106.233C169.348 -105.916 168.292 -106.486 167.15 -105.898C166.748 -105.691 166.106 -105.873 165.553 -106.022C163.921 -106.463 162.092 -106.488 160.401 -105.8C158.416 -106.929 156.056 -106.345 153.975 -107.346C153.917 -107.373 153.695 -107.027 153.621 -107.054C150.575 -108.199 146.832 -107.916 144.401 -110.2C141.973 -110.612 139.616 -111.074 137.188 -111.754C135.37 -112.263 133.961 -113.252 132.341 -114.084C130.964 -114.792 129.507 -115.314 127.973 -115.686C126.11 -116.138 124.279 -116.026 122.386 -116.546C122.293 -116.571 122.101 -116.227 122.019 -116.254C121.695 -116.362 121.405 -116.945 121.234 -116.892C119.553 -116.37 118.065 -117.342 116.401 -117C115.223 -118.224 113.495 -117.979 111.949 -118.421C108.985 -119.269 105.831 -117.999 102.801 -119C106.914 -120.842 111.601 -119.61 115.663 -121.679C117.991 -122.865 120.653 -121.763 123.223 -122.523C123.71 -122.667 124.401 -122.869 124.801 -122.2C124.935 -122.335 125.117 -122.574 125.175 -122.546C127.625 -121.389 129.94 -120.115 132.422 -119.049C132.763 -118.903 133.295 -119.135 133.547 -118.933C135.067 -117.717 137.01 -117.82 138.401 -116.6C140.099 -117.102 141.892 -116.722 143.621 -117.346C143.698 -117.373 143.932 -117.032 143.965 -117.054C145.095 -117.802 146.25 -117.531 147.142 -117.227C147.48 -117.112 148.143 -116.865 148.448 -116.791C149.574 -116.515 150.43 -116.035 151.609 -115.852C151.723 -115.834 151.908 -116.174 151.98 -116.146C153.103 -115.708 154.145 -115.764 154.801 -114.6C154.936 -114.735 155.101 -114.973 155.183 -114.946C156.21 -114.608 156.859 -113.853 157.96 -113.612C158.445 -113.506 159.057 -112.88 159.633 -112.704C162.025 -111.973 163.868 -110.444 166.062 -109.549C166.821 -109.239 167.697 -109.005 168.33 -108.509z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M91.696 -122.739C89.178 -124.464 86.81 -125.57 84.368 -127.356C84.187 -127.489 83.827 -127.319 83.625 -127.441C82.618 -128.05 81.73 -128.631 80.748 -129.327C80.209 -129.709 79.388 -129.698 78.88 -129.956C76.336 -131.248 73.707 -131.806 71.2 -133C71.882 -133.638 73.004 -133.394 73.6 -134.2C73.795 -133.92 74.033 -133.636 74.386 -133.827C76.064 -134.731 77.914 -134.884 79.59 -134.794C81.294 -134.702 83.014 -134.397 84.789 -134.125C85.096 -134.078 85.295 -133.555 85.618 -133.458C87.846 -132.795 90.235 -133.32 92.354 -132.482C93.945 -131.853 95.515 -131.03 96.754 -129.755C97.006 -129.495 96.681 -129.194 96.401 -129C96.789 -129.109 97.062 -128.903 97.173 -128.59C97.257 -128.351 97.257 -128.049 97.173 -127.81C97.061 -127.498 96.782 -127.397 96.408 -127.346C95.001 -127.156 96.773 -128.536 96.073 -128.088C94.8 -127.274 95.546 -125.868 94.801 -124.6C94.521 -124.794 94.291 -125.012 94.401 -125.4C94.635 -124.878 94.033 -124.588 93.865 -124.272C93.48 -123.547 92.581 -122.132 91.696 -122.739z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M59.198 -115.391C56.044 -116.185 52.994 -116.07 49.978 -117.346C49.911 -117.374 49.688 -117.027 49.624 -117.054C48.258 -117.648 47.34 -118.614 46.264 -119.66C45.351 -120.548 43.693 -120.161 42.419 -120.648C42.095 -120.772 41.892 -121.284 41.591 -121.323C40.372 -121.48 39.445 -122.429 38.4 -123C40.736 -123.795 43.147 -123.764 45.609 -124.148C45.722 -124.166 45.867 -123.845 46 -123.845C46.136 -123.845 46.266 -124.066 46.4 -124.2C46.595 -123.92 46.897 -123.594 47.154 -123.848C47.702 -124.388 48.258 -124.198 48.798 -124.158C48.942 -124.148 49.067 -123.845 49.2 -123.845C49.336 -123.845 49.467 -124.156 49.6 -124.156C49.736 -124.155 49.867 -123.845 50 -123.845C50.136 -123.845 50.266 -124.066 50.4 -124.2C51.092 -123.418 51.977 -123.972 52.799 -123.793C53.837 -123.566 54.104 -122.418 55.178 -122.12C59.893 -120.816 64.03 -118.671 68.393 -116.584C68.7 -116.437 68.91 -116.189 68.8 -115.8C69.067 -115.8 69.38 -115.888 69.57 -115.756C70.628 -115.024 71.669 -114.476 72.366 -113.378C72.582 -113.039 72.253 -112.632 72.02 -112.684C67.591 -113.679 63.585 -114.287 59.198 -115.391z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M45.338 -71.179C43.746 -72.398 43.162 -74.429 42.034 -76.221C41.82 -76.561 42.094 -76.875 42.411 -76.964C42.971 -77.123 43.514 -76.645 43.923 -76.443C45.668 -75.581 47.203 -74.339 49.2 -74.2C51.19 -71.966 55.45 -71.581 55.457 -68.2C55.458 -67.341 54.03 -68.259 53.6 -67.4C51.149 -68.403 48.76 -68.3 46.38 -69.767C45.763 -70.148 46.093 -70.601 45.338 -71.179z"/>
+ </g>
+ <g style="fill: #cc7226">
+ <path d="M17.8 -123.756C17.935 -123.755 24.966 -123.522 24.949 -123.408C24.904 -123.099 17.174 -122.05 16.81 -122.22C16.646 -122.296 9.134 -119.866 9 -120C9.268 -120.135 17.534 -123.756 17.8 -123.756z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M33.2 -114C33.2 -114 18.4 -112.2 14 -111C9.6 -109.8 -9 -102.2 -12 -100.2C-12 -100.2 -25.4 -94.8 -42.4 -74.8C-42.4 -74.8 -34.8 -78.2 -32.6 -81C-32.6 -81 -19 -93.6 -19.2 -91C-19.2 -91 -7 -99.6 -7.6 -97.4C-7.6 -97.4 16.8 -108.6 14.8 -105.4C14.8 -105.4 36.4 -110 35.4 -108C35.4 -108 54.2 -103.6 51.4 -103.4C51.4 -103.4 45.6 -102.2 52 -98.6C52 -98.6 48.6 -94.2 43.2 -98.2C37.8 -102.2 40.8 -100 35.8 -99C35.8 -99 33.2 -98.2 28.6 -102.2C28.6 -102.2 23 -106.8 14.2 -103.2C14.2 -103.2 -16.4 -90.6 -18.4 -90C-18.4 -90 -22 -87.2 -24.4 -83.6C-24.4 -83.6 -30.2 -79.2 -33.2 -77.8C-33.2 -77.8 -46 -66.2 -47.2 -64.8C-47.2 -64.8 -50.6 -59.6 -51.4 -59.2C-51.4 -59.2 -45 -63 -43 -65C-43 -65 -29 -75 -23.6 -75.8C-23.6 -75.8 -19.2 -78.8 -18.4 -80.2C-18.4 -80.2 -4 -89.4 0.2 -89.4C0.2 -89.4 9.4 -84.2 11.8 -91.2C11.8 -91.2 17.6 -93 23.2 -91.8C23.2 -91.8 26.4 -94.4 25.6 -96.6C25.6 -96.6 27.2 -98.4 28.2 -94.6C28.2 -94.6 31.6 -91 36.4 -93C36.4 -93 40.4 -93.2 38.4 -90.8C38.4 -90.8 34 -87 22.2 -86.8C22.2 -86.8 9.8 -86.2 -6.6 -78.6C-6.6 -78.6 -36.4 -68.2 -45.6 -57.8C-45.6 -57.8 -52 -49 -57.4 -47.8C-57.4 -47.8 -63.2 -47 -69.2 -39.6C-69.2 -39.6 -59.4 -45.4 -50.4 -45.4C-50.4 -45.4 -46.4 -47.8 -50.2 -44.2C-50.2 -44.2 -53.8 -36.6 -52.2 -31.2C-52.2 -31.2 -52.8 -26 -53.6 -24.4C-53.6 -24.4 -61.4 -11.6 -61.4 -9.2C-61.4 -6.8 -60.2 3 -59.8 3.6C-59.4 4.2 -60.8 2 -57 4.4C-53.2 6.8 -50.4 8.4 -49.6 11.2C-48.8 14 -51.6 5.8 -51.8 4C-52 2.2 -56.2 -5 -55.4 -7.4C-55.4 -7.4 -54.4 -6.4 -53.6 -5C-53.6 -5 -54.2 -5.6 -53.6 -9.2C-53.6 -9.2 -52.8 -14.4 -51.4 -17.6C-50 -20.8 -48 -24.6 -47.6 -25.4C-47.2 -26.2 -47.2 -32 -45.8 -29.4L-42.4 -26.8C-42.4 -26.8 -45.2 -29.4 -43 -31.6C-43 -31.6 -44 -37.2 -42.2 -39.8C-42.2 -39.8 -35.2 -48.2 -33.6 -49.2C-32 -50.2 -33.4 -49.8 -33.4 -49.8C-33.4 -49.8 -27.4 -54 -33.2 -52.4C-33.2 -52.4 -37.2 -50.8 -40.2 -50.8C-40.2 -50.8 -47.8 -48.8 -43.8 -53C-39.8 -57.2 -29.8 -62.6 -26 -62.4L-25.2 -60.8L-14 -63.2L-15.2 -62.4C-15.2 -62.4 -15.4 -62.6 -11.2 -63C-7 -63.4 -1.2 -62 0.2 -63.8C1.6 -65.6 5 -66.6 4.6 -65.2C4.2 -63.8 4 -61.8 4 -61.8C4 -61.8 9 -67.6 8.4 -65.4C7.8 -63.2 -0.4 -58 -1.8 -51.8L8.6 -60L12.2 -63C12.2 -63 15.8 -60.8 16 -62.4C16.2 -64 20.8 -69.8 22 -69.6C23.2 -69.4 25.2 -72.2 25 -69.6C24.8 -67 32.4 -61.6 32.4 -61.6C32.4 -61.6 35.6 -63.4 37 -62C38.4 -60.6 42.6 -81.8 42.6 -81.8L67.6 -92.4L111.201 -95.8L94.201 -102.6L33.2 -114z"/>
+ </g>
+ <g style="stroke:#4c0000; stroke-width:2">
+ <path d="M51.4 85C51.4 85 36.4 68.2 28 65.6C28 65.6 14.6 58.8 -10 66.6"/>
+ </g>
+ <g style="stroke:#4c0000; stroke-width:2">
+ <path d="M24.8 64.2C24.8 64.2 -0.4 56.2 -15.8 60.4C-15.8 60.4 -34.2 62.4 -42.6 76.2"/>
+ </g>
+ <g style="stroke:#4c0000; stroke-width:2">
+ <path d="M21.2 63C21.2 63 4.2 55.8 -10.6 53.6C-10.6 53.6 -27.2 51 -43.8 58.2C-43.8 58.2 -56 64.2 -61.4 74.4"/>
+ </g>
+ <g style="stroke:#4c0000; stroke-width:2">
+ <path d="M22.2 63.4C22.2 63.4 6.8 52.4 5.8 51C5.8 51 -1.2 40 -14.2 39.6C-14.2 39.6 -35.6 40.4 -52.8 48.4"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M20.895 54.407C22.437 55.87 49.4 84.8 49.4 84.8C84.6 121.401 56.6 87.2 56.6 87.2C49 82.4 39.8 63.6 39.8 63.6C38.6 60.8 53.8 70.8 53.8 70.8C57.8 71.6 71.4 90.8 71.4 90.8C64.6 88.4 69.4 95.6 69.4 95.6C72.2 97.6 92.601 113.201 92.601 113.201C96.201 117.201 100.201 118.801 100.201 118.801C114.201 113.601 107.801 126.801 107.801 126.801C110.201 133.601 115.801 122.001 115.801 122.001C127.001 105.2 110.601 107.601 110.601 107.601C80.6 110.401 73.8 94.4 73.8 94.4C71.4 92 80.2 94.4 80.2 94.4C88.601 96.4 73 82 73 82C75.4 82 84.6 88.8 84.6 88.8C95.001 98 97.001 96 97.001 96C115.001 87.2 125.401 94.8 125.401 94.8C127.401 96.4 121.801 103.2 123.401 108.401C125.001 113.601 129.801 126.001 129.801 126.001C127.401 127.601 127.801 138.401 127.801 138.401C144.601 161.601 135.001 159.601 135.001 159.601C119.401 159.201 134.201 166.801 134.201 166.801C137.401 168.801 146.201 176.001 146.201 176.001C143.401 174.801 141.801 180.001 141.801 180.001C146.601 184.001 143.801 188.801 143.801 188.801C137.801 190.001 136.601 194.001 136.601 194.001C143.401 202.001 133.401 202.401 133.401 202.401C137.001 206.801 132.201 218.801 132.201 218.801C127.401 218.801 121.001 224.401 121.001 224.401C123.401 229.201 113.001 234.801 113.001 234.801C104.601 236.401 107.401 243.201 107.401 243.201C99.401 249.201 97.001 265.201 97.001 265.201C96.201 275.601 93.801 278.801 99.001 276.801C104.201 274.801 103.401 262.401 103.401 262.401C98.601 246.801 141.401 230.801 141.401 230.801C145.401 229.201 146.201 224.001 146.201 224.001C148.201 224.401 157.001 232.001 157.001 232.001C164.601 243.201 165.001 234.001 165.001 234.001C166.201 230.401 164.601 224.401 164.601 224.401C170.601 202.801 156.601 196.401 156.601 196.401C146.601 162.801 160.601 171.201 160.601 171.201C163.401 176.801 174.201 182.001 174.201 182.001L177.801 179.601C176.201 174.801 184.601 168.801 184.601 168.801C187.401 175.201 193.401 167.201 193.401 167.201C197.001 142.801 209.401 157.201 209.401 157.201C213.401 158.401 214.601 151.601 214.601 151.601C218.201 141.201 214.601 127.601 214.601 127.601C218.201 127.201 227.801 133.201 227.801 133.201C230.601 129.601 221.401 112.801 225.401 115.201C229.401 117.601 233.801 119.201 233.801 119.201C234.601 117.201 224.601 104.801 224.601 104.801C220.201 102 215.001 81.6 215.001 81.6C222.201 85.2 212.201 70 212.201 70C212.201 66.8 218.201 55.6 218.201 55.6C217.401 48.8 218.201 49.2 218.201 49.2C221.001 50.4 229.001 52 222.201 45.6C215.401 39.2 223.001 34.4 223.001 34.4C227.401 31.6 213.801 32 213.801 32C208.601 27.6 209.001 23.6 209.001 23.6C217.001 25.6 202.601 11.2 200.201 7.6C197.801 4 207.401 -1.2 207.401 -1.2C220.601 -4.8 209.001 -8 209.001 -8C189.401 -7.6 200.201 -18.4 200.201 -18.4C206.201 -18 204.601 -20.4 204.601 -20.4C199.401 -21.6 189.801 -28 189.801 -28C185.801 -31.6 189.401 -30.8 189.401 -30.8C206.201 -29.6 177.401 -40.8 177.401 -40.8C185.401 -40.8 167.401 -51.2 167.401 -51.2C165.401 -52.8 162.201 -60.4 162.201 -60.4C156.201 -65.6 151.401 -72.4 151.401 -72.4C151.001 -76.8 146.201 -81.6 146.201 -81.6C134.601 -95.2 129.001 -94.8 129.001 -94.8C114.201 -98.4 109.001 -97.6 109.001 -97.6L56.2 -93.2C29.8 -80.4 37.6 -59.4 37.6 -59.4C44 -51 53.2 -54.8 53.2 -54.8C57.8 -61 69.4 -58.8 69.4 -58.8C89.801 -55.6 87.201 -59.2 87.201 -59.2C84.801 -63.8 68.6 -70 68.4 -70.6C68.2 -71.2 59.4 -74.6 59.4 -74.6C56.4 -75.8 52 -85 52 -85C48.8 -88.4 64.6 -82.6 64.6 -82.6C63.4 -81.6 70.8 -77.6 70.8 -77.6C88.201 -78.6 98.801 -67.8 98.801 -67.8C109.601 -51.2 109.801 -59.4 109.801 -59.4C112.601 -68.8 100.801 -90 100.801 -90C101.201 -92 109.401 -85.4 109.401 -85.4C110.801 -87.4 111.601 -81.6 111.601 -81.6C111.801 -79.2 115.601 -71.2 115.601 -71.2C118.401 -58.2 122.001 -65.6 122.001 -65.6L126.601 -56.2C128.001 -53.6 122.001 -46 122.001 -46C121.801 -43.2 122.601 -43.4 117.001 -35.8C111.401 -28.2 114.801 -23.8 114.801 -23.8C113.401 -17.2 122.201 -17.6 122.201 -17.6C124.801 -15.4 128.201 -15.4 128.201 -15.4C130.001 -13.4 132.401 -14 132.401 -14C134.001 -17.8 140.201 -15.8 140.201 -15.8C141.601 -18.2 149.801 -18.6 149.801 -18.6C150.801 -21.2 151.201 -22.8 154.601 -23.4C158.001 -24 133.401 -67 133.401 -67C139.801 -67.8 131.601 -80.2 131.601 -80.2C129.401 -86.8 140.801 -72.2 143.001 -70.8C145.201 -69.4 146.201 -67.2 144.601 -67.4C143.001 -67.6 141.201 -65.4 142.601 -65.2C144.001 -65 157.001 -50 160.401 -39.8C163.801 -29.6 169.801 -25.6 176.001 -19.6C182.201 -13.6 181.401 10.6 181.401 10.6C181.001 19.4 187.001 30 187.001 30C189.001 33.8 184.801 52 184.801 52C182.801 54.2 184.201 55 184.201 55C185.201 56.2 192.001 69.4 192.001 69.4C190.201 69.2 193.801 72.8 193.801 72.8C199.001 78.8 192.601 75.8 192.601 75.8C186.601 74.2 193.601 84 193.601 84C194.801 85.8 185.801 81.2 185.801 81.2C176.601 80.6 188.201 87.8 188.201 87.8C196.801 95 185.401 90.6 185.401 90.6C180.801 88.8 184.001 95.6 184.001 95.6C187.201 97.2 204.401 104.2 204.401 104.2C204.801 108.001 201.801 113.001 201.801 113.001C202.201 117.001 200.001 120.401 200.001 120.401C198.801 128.601 198.201 129.401 198.201 129.401C194.001 129.601 186.601 143.401 186.601 143.401C184.801 146.001 174.601 158.001 174.601 158.001C172.601 165.001 154.601 157.801 154.601 157.801C148.001 161.201 150.001 157.801 150.001 157.801C149.601 155.601 154.401 149.601 154.401 149.601C161.401 147.001 158.801 136.201 158.801 136.201C162.801 134.801 151.601 132.001 151.801 130.801C152.001 129.601 157.801 128.201 157.801 128.201C165.801 126.201 161.401 123.801 161.401 123.801C160.801 119.801 163.801 114.201 163.801 114.201C175.401 113.401 163.801 97.2 163.801 97.2C153.001 89.6 152.001 83.8 152.001 83.8C164.601 75.6 156.401 63.2 156.601 59.6C156.801 56 158.001 34.4 158.001 34.4C156.001 28.2 153.001 14.6 153.001 14.6C155.201 9.4 162.601 -3.2 162.601 -3.2C165.401 -7.4 174.201 -12.2 172.001 -15.2C169.801 -18.2 162.001 -16.4 162.001 -16.4C154.201 -17.8 154.801 -12.6 154.801 -12.6C153.201 -11.6 152.401 -6.6 152.401 -6.6C151.68 1.333 142.801 7.6 142.801 7.6C131.601 13.8 140.801 17.8 140.801 17.8C146.801 24.4 137.001 24.6 137.001 24.6C126.001 22.8 134.201 33 134.201 33C145.001 45.8 142.001 48.6 142.001 48.6C131.801 49.6 144.401 58.8 144.401 58.8C144.401 58.8 143.601 56.8 143.801 58.6C144.001 60.4 147.001 64.6 147.801 66.6C148.601 68.6 144.601 68.8 144.601 68.8C145.201 78.4 129.801 74.2 129.801 74.2C129.801 74.2 129.801 74.2 128.201 74.4C126.601 74.6 115.401 73.8 109.601 71.6C103.801 69.4 97.001 69.4 97.001 69.4C97.001 69.4 93.001 71.2 85.4 71C77.8 70.8 69.8 73.6 69.8 73.6C65.4 73.2 74 68.8 74.2 69C74.4 69.2 80 63.6 72 64.2C50.203 65.835 39.4 55.6 39.4 55.6C37.4 54.2 34.8 51.4 34.8 51.4C24.8 49.4 36.2 63.8 36.2 63.8C37.4 65.2 36 66.2 36 66.2C35.2 64.6 27.4 59.2 27.4 59.2C24.589 58.227 23.226 56.893 20.895 54.407z"/>
+ </g>
+ <g style="fill: #4c0000">
+ <path d="M-3 42.8C-3 42.8 8.6 48.4 11.2 51.2C13.8 54 27.8 65.4 27.8 65.4C27.8 65.4 22.4 63.4 19.8 61.6C17.2 59.8 6.4 51.6 6.4 51.6C6.4 51.6 2.6 45.6 -3 42.8z"/>
+ </g>
+ <g style="fill: #99cc32">
+ <path d="M-61.009 11.603C-60.672 11.455 -61.196 8.743 -61.4 8.2C-62.422 5.474 -71.4 4 -71.4 4C-71.627 5.365 -71.682 6.961 -71.576 8.599C-71.576 8.599 -66.708 14.118 -61.009 11.603z"/>
+ </g>
+ <g style="fill: #659900">
+ <path d="M-61.009 11.403C-61.458 11.561 -61.024 8.669 -61.2 8.2C-62.222 5.474 -71.4 3.9 -71.4 3.9C-71.627 5.265 -71.682 6.861 -71.576 8.499C-71.576 8.499 -67.308 13.618 -61.009 11.403z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-65.4 11.546C-66.025 11.546 -66.531 10.406 -66.531 9C-66.531 7.595 -66.025 6.455 -65.4 6.455C-64.775 6.455 -64.268 7.595 -64.268 9C-64.268 10.406 -64.775 11.546 -65.4 11.546z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-65.4 9z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-111 109.601C-111 109.601 -116.6 119.601 -91.8 113.601C-91.8 113.601 -77.8 112.401 -75.4 110.001C-74.2 110.801 -65.834 113.734 -63 114.401C-56.2 116.001 -47.8 106 -47.8 106C-47.8 106 -43.2 95.5 -40.4 95.5C-37.6 95.5 -40.8 97.1 -40.8 97.1C-40.8 97.1 -47.4 107.201 -47 108.801C-47 108.801 -52.2 128.801 -68.2 129.601C-68.2 129.601 -84.35 130.551 -83 136.401C-83 136.401 -74.2 134.001 -71.8 136.401C-71.8 136.401 -61 136.001 -69 142.401L-75.8 154.001C-75.8 154.001 -75.66 157.919 -85.8 154.401C-95.6 151.001 -105.9 138.101 -105.9 138.101C-105.9 138.101 -121.85 123.551 -111 109.601z"/>
+ </g>
+ <g style="fill: #e59999">
+ <path d="M-112.2 113.601C-112.2 113.601 -114.2 123.201 -77.4 112.801C-77.4 112.801 -73 112.801 -70.6 113.601C-68.2 114.401 -56.2 117.201 -54.2 116.001C-54.2 116.001 -61.4 129.601 -73 128.001C-73 128.001 -86.2 129.601 -85.8 134.401C-85.8 134.401 -81.8 141.601 -77 144.001C-77 144.001 -74.2 146.401 -74.6 149.601C-75 152.801 -77.8 154.401 -79.8 155.201C-81.8 156.001 -85 152.801 -86.6 152.801C-88.2 152.801 -96.6 146.401 -101 141.601C-105.4 136.801 -113.8 124.801 -113.4 122.001C-113 119.201 -112.2 113.601 -112.2 113.601z"/>
+ </g>
+ <g style="fill: #b26565">
+ <path d="M-109 131.051C-106.4 135.001 -103.2 139.201 -101 141.601C-96.6 146.401 -88.2 152.801 -86.6 152.801C-85 152.801 -81.8 156.001 -79.8 155.201C-77.8 154.401 -75 152.801 -74.6 149.601C-74.2 146.401 -77 144.001 -77 144.001C-80.066 142.468 -82.806 138.976 -84.385 136.653C-84.385 136.653 -84.2 139.201 -89.4 138.401C-94.6 137.601 -99.8 134.801 -101.4 131.601C-103 128.401 -105.4 126.001 -103.8 129.601C-102.2 133.201 -99.8 136.801 -98.2 137.201C-96.6 137.601 -97 138.801 -99.4 138.401C-101.8 138.001 -104.6 137.601 -109 132.401z"/>
+ </g>
+ <g style="fill: #992600">
+ <path d="M-111.6 110.001C-111.6 110.001 -109.8 96.4 -108.6 92.4C-108.6 92.4 -109.4 85.6 -107 81.4C-104.6 77.2 -102.6 71 -99.6 65.6C-96.6 60.2 -96.4 56.2 -92.4 54.6C-88.4 53 -82.4 44.4 -79.6 43.4C-76.8 42.4 -77 43.2 -77 43.2C-77 43.2 -70.2 28.4 -56.6 32.4C-56.6 32.4 -72.8 29.6 -57 20.2C-57 20.2 -61.8 21.3 -58.5 14.3C-56.299 9.632 -56.8 16.4 -67.8 28.2C-67.8 28.2 -72.8 36.8 -78 39.8C-83.2 42.8 -95.2 49.8 -96.4 53.6C-97.6 57.4 -100.8 63.2 -102.8 64.8C-104.8 66.4 -107.6 70.6 -108 74C-108 74 -109.2 78 -110.6 79.2C-112 80.4 -112.2 83.6 -112.2 85.6C-112.2 87.6 -114.2 90.4 -114 92.8C-114 92.8 -113.2 111.801 -113.6 113.801L-111.6 110.001z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M-120.2 114.601C-120.2 114.601 -122.2 113.201 -126.6 119.201C-126.6 119.201 -119.3 152.201 -119.3 153.601C-119.3 153.601 -118.2 151.501 -119.5 144.301C-120.8 137.101 -121.7 124.401 -121.7 124.401L-120.2 114.601z"/>
+ </g>
+ <g style="fill: #992600">
+ <path d="M-98.6 54C-98.6 54 -116.2 57.2 -115.8 86.4L-116.6 111.201C-116.6 111.201 -117.8 85.6 -119 84C-120.2 82.4 -116.2 71.2 -119.4 77.2C-119.4 77.2 -133.4 91.2 -125.4 112.401C-125.4 112.401 -123.9 115.701 -126.9 111.101C-126.9 111.101 -131.5 98.5 -130.4 92.1C-130.4 92.1 -130.2 89.9 -128.3 87.1C-128.3 87.1 -119.7 75.4 -117 73.1C-117 73.1 -115.2 58.7 -99.8 53.5C-99.8 53.5 -94.1 51.2 -98.6 54z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M40.8 -12.2C41.46 -12.554 41.451 -13.524 42.031 -13.697C43.18 -14.041 43.344 -15.108 43.862 -15.892C44.735 -17.211 44.928 -18.744 45.51 -20.235C45.782 -20.935 45.809 -21.89 45.496 -22.55C44.322 -25.031 43.62 -27.48 42.178 -29.906C41.91 -30.356 41.648 -31.15 41.447 -31.748C40.984 -33.132 39.727 -34.123 38.867 -35.443C38.579 -35.884 39.104 -36.809 38.388 -36.893C37.491 -36.998 36.042 -37.578 35.809 -36.552C35.221 -33.965 36.232 -31.442 37.2 -29C36.418 -28.308 36.752 -27.387 36.904 -26.62C37.614 -23.014 36.416 -19.662 35.655 -16.188C35.632 -16.084 35.974 -15.886 35.946 -15.824C34.724 -13.138 33.272 -10.693 31.453 -8.312C30.695 -7.32 29.823 -6.404 29.326 -5.341C28.958 -4.554 28.55 -3.588 28.8 -2.6C25.365 0.18 23.115 4.025 20.504 7.871C20.042 8.551 20.333 9.76 20.884 10.029C21.697 10.427 22.653 9.403 23.123 8.557C23.512 7.859 23.865 7.209 24.356 6.566C24.489 6.391 24.31 5.972 24.445 5.851C27.078 3.504 28.747 0.568 31.2 -1.8C33.15 -2.129 34.687 -3.127 36.435 -4.14C36.743 -4.319 37.267 -4.07 37.557 -4.265C39.31 -5.442 39.308 -7.478 39.414 -9.388C39.464 -10.272 39.66 -11.589 40.8 -12.2z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M31.959 -16.666C32.083 -16.743 31.928 -17.166 32.037 -17.382C32.199 -17.706 32.602 -17.894 32.764 -18.218C32.873 -18.434 32.71 -18.814 32.846 -18.956C35.179 -21.403 35.436 -24.427 34.4 -27.4C35.424 -28.02 35.485 -29.282 35.06 -30.129C34.207 -31.829 34.014 -33.755 33.039 -35.298C32.237 -36.567 30.659 -37.811 29.288 -36.508C28.867 -36.108 28.546 -35.321 28.824 -34.609C28.888 -34.446 29.173 -34.3 29.146 -34.218C29.039 -33.894 28.493 -33.67 28.487 -33.398C28.457 -31.902 27.503 -30.391 28.133 -29.062C28.905 -27.433 29.724 -25.576 30.4 -23.8C29.166 -21.684 30.199 -19.235 28.446 -17.358C28.31 -17.212 28.319 -16.826 28.441 -16.624C28.733 -16.138 29.139 -15.732 29.625 -15.44C29.827 -15.319 30.175 -15.317 30.375 -15.441C30.953 -15.803 31.351 -16.29 31.959 -16.666z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M94.771 -26.977C96.16 -25.185 96.45 -22.39 94.401 -21C94.951 -17.691 98.302 -19.67 100.401 -20.2C100.292 -20.588 100.519 -20.932 100.802 -20.937C101.859 -20.952 102.539 -21.984 103.601 -21.8C104.035 -23.357 105.673 -24.059 106.317 -25.439C108.043 -29.134 107.452 -33.407 104.868 -36.653C104.666 -36.907 104.883 -37.424 104.759 -37.786C104.003 -39.997 101.935 -40.312 100.001 -41C98.824 -44.875 98.163 -48.906 96.401 -52.6C94.787 -52.85 94.089 -54.589 92.752 -55.309C91.419 -56.028 90.851 -54.449 90.892 -53.403C90.899 -53.198 91.351 -52.974 91.181 -52.609C91.105 -52.445 90.845 -52.334 90.845 -52.2C90.846 -52.065 91.067 -51.934 91.201 -51.8C90.283 -50.98 88.86 -50.503 88.565 -49.358C87.611 -45.648 90.184 -42.523 91.852 -39.322C92.443 -38.187 91.707 -36.916 90.947 -35.708C90.509 -35.013 90.617 -33.886 90.893 -33.03C91.645 -30.699 93.236 -28.96 94.771 -26.977z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M57.611 -8.591C56.124 -6.74 52.712 -4.171 55.629 -2.243C55.823 -2.114 56.193 -2.11 56.366 -2.244C58.387 -3.809 60.39 -4.712 62.826 -5.294C62.95 -5.323 63.224 -4.856 63.593 -5.017C65.206 -5.72 67.216 -5.662 68.4 -7C72.167 -6.776 75.732 -7.892 79.123 -9.2C80.284 -9.648 81.554 -10.207 82.755 -10.709C84.131 -11.285 85.335 -12.213 86.447 -13.354C86.58 -13.49 86.934 -13.4 87.201 -13.4C87.161 -14.263 88.123 -14.39 88.37 -15.012C88.462 -15.244 88.312 -15.64 88.445 -15.742C90.583 -17.372 91.503 -19.39 90.334 -21.767C90.049 -22.345 89.8 -22.963 89.234 -23.439C88.149 -24.35 87.047 -23.496 86 -23.8C85.841 -23.172 85.112 -23.344 84.726 -23.146C83.867 -22.707 82.534 -23.292 81.675 -22.854C80.313 -22.159 79.072 -21.99 77.65 -21.613C77.338 -21.531 76.56 -21.627 76.4 -21C76.266 -21.134 76.118 -21.368 76.012 -21.346C74.104 -20.95 72.844 -20.736 71.543 -19.044C71.44 -18.911 70.998 -19.09 70.839 -18.955C69.882 -18.147 69.477 -16.913 68.376 -16.241C68.175 -16.118 67.823 -16.286 67.629 -16.157C66.983 -15.726 66.616 -15.085 65.974 -14.638C65.645 -14.409 65.245 -14.734 65.277 -14.99C65.522 -16.937 66.175 -18.724 65.6 -20.6C67.677 -23.12 70.194 -25.069 72 -27.8C72.015 -29.966 72.707 -32.112 72.594 -34.189C72.584 -34.382 72.296 -35.115 72.17 -35.462C71.858 -36.316 72.764 -37.382 71.92 -38.106C70.516 -39.309 69.224 -38.433 68.4 -37C66.562 -36.61 64.496 -35.917 62.918 -37.151C61.911 -37.938 61.333 -38.844 60.534 -39.9C59.549 -41.202 59.884 -42.638 59.954 -44.202C59.96 -44.33 59.645 -44.466 59.645 -44.6C59.646 -44.735 59.866 -44.866 60 -45C59.294 -45.626 59.019 -46.684 58 -47C58.305 -48.092 57.629 -48.976 56.758 -49.278C54.763 -49.969 53.086 -48.057 51.194 -47.984C50.68 -47.965 50.213 -49.003 49.564 -49.328C49.132 -49.544 48.428 -49.577 48.066 -49.311C47.378 -48.807 46.789 -48.693 46.031 -48.488C44.414 -48.052 43.136 -46.958 41.656 -46.103C40.171 -45.246 39.216 -43.809 38.136 -42.489C37.195 -41.337 37.059 -38.923 38.479 -38.423C40.322 -37.773 41.626 -40.476 43.592 -40.15C43.904 -40.099 44.11 -39.788 44 -39.4C44.389 -39.291 44.607 -39.52 44.8 -39.8C45.658 -38.781 46.822 -38.444 47.76 -37.571C48.73 -36.667 50.476 -37.085 51.491 -36.088C53.02 -34.586 52.461 -31.905 54.4 -30.6C53.814 -29.287 53.207 -28.01 52.872 -26.583C52.59 -25.377 53.584 -24.18 54.795 -24.271C56.053 -24.365 56.315 -25.124 56.8 -26.2C57.067 -25.933 57.536 -25.636 57.495 -25.42C57.038 -23.033 56.011 -21.04 55.553 -18.609C55.494 -18.292 55.189 -18.09 54.8 -18.2C54.332 -14.051 50.28 -11.657 47.735 -8.492C47.332 -7.99 47.328 -6.741 47.737 -6.338C49.14 -4.951 51.1 -6.497 52.8 -7C53.013 -8.206 53.872 -9.148 55.204 -9.092C55.46 -9.082 55.695 -9.624 56.019 -9.754C56.367 -9.892 56.869 -9.668 57.155 -9.866C58.884 -11.061 60.292 -12.167 62.03 -13.356C62.222 -13.487 62.566 -13.328 62.782 -13.436C63.107 -13.598 63.294 -13.985 63.617 -14.17C63.965 -14.37 64.207 -14.08 64.4 -13.8C63.754 -13.451 63.75 -12.494 63.168 -12.292C62.393 -12.024 61.832 -11.511 61.158 -11.064C60.866 -10.871 60.207 -11.119 60.103 -10.94C59.505 -9.912 58.321 -9.474 57.611 -8.591z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M2.2 -58C2.2 -58 -7.038 -60.872 -18.2 -35.2C-18.2 -35.2 -20.6 -30 -23 -28C-25.4 -26 -36.6 -22.4 -38.6 -18.4L-49 -2.4C-49 -2.4 -34.2 -18.4 -31 -20.8C-31 -20.8 -23 -29.2 -26.2 -22.4C-26.2 -22.4 -40.2 -11.6 -39 -2.4C-39 -2.4 -44.6 12 -45.4 14C-45.4 14 -29.4 -18 -27 -19.2C-24.6 -20.4 -23.4 -20.4 -24.6 -16.8C-25.8 -13.2 -26.2 3.2 -29 5.2C-29 5.2 -21 -15.2 -21.8 -18.4C-21.8 -18.4 -18.6 -22 -16.2 -16.8L-17.4 -0.8L-13 11.2C-13 11.2 -15.4 0 -13.8 -15.6C-13.8 -15.6 -15.8 -26 -11.8 -20.4C-7.8 -14.8 1.8 -8.8 1.8 -4C1.8 -4 -3.4 -21.6 -12.6 -26.4L-16.6 -20.4L-17.8 -22.4C-17.8 -22.4 -21.4 -23.2 -17 -30C-12.6 -36.8 -13 -37.6 -13 -37.6C-13 -37.6 -6.6 -30.4 -5 -30.4C-5 -30.4 8.2 -38 9.4 -13.6C9.4 -13.6 16.2 -28 7 -34.8C7 -34.8 -7.8 -36.8 -6.6 -42L0.6 -54.4C4.2 -59.6 2.6 -56.8 2.6 -56.8z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-17.8 -41.6C-17.8 -41.6 -30.6 -41.6 -33.8 -36.4L-41 -26.8C-41 -26.8 -23.8 -36.8 -19.8 -38C-15.8 -39.2 -17.8 -41.6 -17.8 -41.6z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-57.8 -35.2C-57.8 -35.2 -59.8 -34 -60.2 -31.2C-60.6 -28.4 -63 -28 -62.2 -25.2C-61.4 -22.4 -59.4 -20 -59.4 -24C-59.4 -28 -57.8 -30 -57 -31.2C-56.2 -32.4 -54.6 -36.8 -57.8 -35.2z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-66.6 26C-66.6 26 -75 22 -78.2 18.4C-81.4 14.8 -80.948 19.966 -85.8 19.6C-91.647 19.159 -90.6 3.2 -90.6 3.2L-94.6 10.8C-94.6 10.8 -95.8 25.2 -87.8 22.8C-83.893 21.628 -82.6 23.2 -84.2 24C-85.8 24.8 -78.6 25.2 -81.4 26.8C-84.2 28.4 -69.8 23.2 -72.2 33.6L-66.6 26z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-79.2 40.4C-79.2 40.4 -94.6 44.8 -98.2 35.2C-98.2 35.2 -103 37.6 -100.8 40.6C-98.6 43.6 -97.4 44 -97.4 44C-97.4 44 -92 45.2 -92.6 46C-93.2 46.8 -95.6 50.2 -95.6 50.2C-95.6 50.2 -85.4 44.2 -79.2 40.4z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M149.201 118.601C148.774 120.735 147.103 121.536 145.201 122.201C143.284 121.243 140.686 118.137 138.801 120.201C138.327 119.721 137.548 119.661 137.204 118.999C136.739 118.101 137.011 117.055 136.669 116.257C136.124 114.985 135.415 113.619 135.601 112.201C137.407 111.489 138.002 109.583 137.528 107.82C137.459 107.563 137.03 107.366 137.23 107.017C137.416 106.694 137.734 106.467 138.001 106.2C137.866 106.335 137.721 106.568 137.61 106.548C137 106.442 137.124 105.805 137.254 105.418C137.839 103.672 139.853 103.408 141.201 104.6C141.457 104.035 141.966 104.229 142.401 104.2C142.351 103.621 142.759 103.094 142.957 102.674C143.475 101.576 145.104 102.682 145.901 102.07C146.977 101.245 148.04 100.546 149.118 101.149C150.927 102.162 152.636 103.374 153.835 105.115C154.41 105.949 154.65 107.23 154.592 108.188C154.554 108.835 153.173 108.483 152.83 109.412C152.185 111.16 154.016 111.679 154.772 113.017C154.97 113.366 154.706 113.67 154.391 113.768C153.98 113.896 153.196 113.707 153.334 114.16C154.306 117.353 151.55 118.031 149.201 118.601z"/>
+ </g>
+ <g style="fill: #ffffff">
+ <path d="M139.6 138.201C139.593 136.463 137.992 134.707 139.201 133.001C139.336 133.135 139.467 133.356 139.601 133.356C139.736 133.356 139.867 133.135 140.001 133.001C141.496 135.217 145.148 136.145 145.006 138.991C144.984 139.438 143.897 140.356 144.801 141.001C142.988 142.349 142.933 144.719 142.001 146.601C140.763 146.315 139.551 145.952 138.401 145.401C138.753 143.915 138.636 142.231 139.456 140.911C139.89 140.213 139.603 139.134 139.6 138.201z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-26.6 129.201C-26.6 129.201 -43.458 139.337 -29.4 124.001C-20.6 114.401 -10.6 108.801 -10.6 108.801C-10.6 108.801 -0.2 104.4 3.4 103.2C7 102 22.2 96.8 25.4 96.4C28.6 96 38.2 92 45 96C51.8 100 59.8 104.4 59.8 104.4C59.8 104.4 43.4 96 39.8 98.4C36.2 100.8 29 100.4 23 103.6C23 103.6 8.2 108.001 5 110.001C1.8 112.001 -8.6 123.601 -10.2 122.801C-11.8 122.001 -9.8 121.601 -8.6 118.801C-7.4 116.001 -9.4 114.401 -17.4 120.801C-25.4 127.201 -26.6 129.201 -26.6 129.201z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-19.195 123.234C-19.195 123.234 -17.785 110.194 -9.307 111.859C-9.307 111.859 -1.081 107.689 1.641 105.721C1.641 105.721 9.78 104.019 11.09 103.402C29.569 94.702 44.288 99.221 44.835 98.101C45.381 96.982 65.006 104.099 68.615 108.185C69.006 108.628 58.384 102.588 48.686 100.697C40.413 99.083 18.811 100.944 7.905 106.48C4.932 107.989 -4.013 113.773 -6.544 113.662C-9.075 113.55 -19.195 123.234 -19.195 123.234z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-23 148.801C-23 148.801 -38.2 146.401 -21.4 144.801C-21.4 144.801 -3.4 142.801 0.6 137.601C0.6 137.601 14.2 128.401 17 128.001C19.8 127.601 49.8 120.401 50.2 118.001C50.6 115.601 56.2 115.601 57.8 116.401C59.4 117.201 58.6 118.401 55.8 119.201C53 120.001 21.8 136.401 15.4 137.601C9 138.801 -2.6 146.401 -7.4 147.601C-12.2 148.801 -23 148.801 -23 148.801z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-3.48 141.403C-3.48 141.403 -12.062 140.574 -3.461 139.755C-3.461 139.755 5.355 136.331 7.403 133.668C7.403 133.668 14.367 128.957 15.8 128.753C17.234 128.548 31.194 124.861 31.399 123.633C31.604 122.404 65.67 109.823 70.09 113.013C73.001 115.114 63.1 113.437 53.466 117.847C52.111 118.467 18.258 133.054 14.981 133.668C11.704 134.283 5.765 138.174 3.307 138.788C0.85 139.403 -3.48 141.403 -3.48 141.403z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-11.4 143.601C-11.4 143.601 -6.2 143.201 -7.4 144.801C-8.6 146.401 -11 145.601 -11 145.601L-11.4 143.601z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-18.6 145.201C-18.6 145.201 -13.4 144.801 -14.6 146.401C-15.8 148.001 -18.2 147.201 -18.2 147.201L-18.6 145.201z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-29 146.801C-29 146.801 -23.8 146.401 -25 148.001C-26.2 149.601 -28.6 148.801 -28.6 148.801L-29 146.801z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-36.6 147.601C-36.6 147.601 -31.4 147.201 -32.6 148.801C-33.8 150.401 -36.2 149.601 -36.2 149.601L-36.6 147.601z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M1.8 108.001C1.8 108.001 6.2 108.001 5 109.601C3.8 111.201 0.6 110.801 0.6 110.801L1.8 108.001z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-8.2 113.601C-8.2 113.601 -1.694 111.46 -4.2 114.801C-5.4 116.401 -7.8 115.601 -7.8 115.601L-8.2 113.601z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-19.4 118.401C-19.4 118.401 -14.2 118.001 -15.4 119.601C-16.6 121.201 -19 120.401 -19 120.401L-19.4 118.401z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-27 124.401C-27 124.401 -21.8 124.001 -23 125.601C-24.2 127.201 -26.6 126.401 -26.6 126.401L-27 124.401z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-33.8 129.201C-33.8 129.201 -28.6 128.801 -29.8 130.401C-31 132.001 -33.4 131.201 -33.4 131.201L-33.8 129.201z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M5.282 135.598C5.282 135.598 12.203 135.066 10.606 137.195C9.009 139.325 5.814 138.26 5.814 138.26L5.282 135.598z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M15.682 130.798C15.682 130.798 22.603 130.266 21.006 132.395C19.409 134.525 16.214 133.46 16.214 133.46L15.682 130.798z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M26.482 126.398C26.482 126.398 33.403 125.866 31.806 127.995C30.209 130.125 27.014 129.06 27.014 129.06L26.482 126.398z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M36.882 121.598C36.882 121.598 43.803 121.066 42.206 123.195C40.609 125.325 37.414 124.26 37.414 124.26L36.882 121.598z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M9.282 103.598C9.282 103.598 16.203 103.066 14.606 105.195C13.009 107.325 9.014 107.06 9.014 107.06L9.282 103.598z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M19.282 100.398C19.282 100.398 26.203 99.866 24.606 101.995C23.009 104.125 18.614 103.86 18.614 103.86L19.282 100.398z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-3.4 140.401C-3.4 140.401 1.8 140.001 0.6 141.601C-0.6 143.201 -3 142.401 -3 142.401L-3.4 140.401z"/>
+ </g>
+ <g style="fill: #992600">
+ <path d="M-76.6 41.2C-76.6 41.2 -81 50 -81.4 53.2C-81.4 53.2 -80.6 44.4 -79.4 42.4C-78.2 40.4 -76.6 41.2 -76.6 41.2z"/>
+ </g>
+ <g style="fill: #992600">
+ <path d="M-95 55.2C-95 55.2 -98.2 69.6 -97.8 72.4C-97.8 72.4 -99 60.8 -98.6 59.6C-98.2 58.4 -95 55.2 -95 55.2z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-74.2 -19.4L-74.4 -16.2L-76.6 -16C-76.6 -16 -62.4 -3.4 -61.8 4.2C-61.8 4.2 -61 -4 -74.2 -19.4z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-70.216 -18.135C-70.647 -18.551 -70.428 -19.296 -70.836 -19.556C-71.645 -20.072 -69.538 -20.129 -69.766 -20.845C-70.149 -22.051 -69.962 -22.072 -70.084 -23.348C-70.141 -23.946 -69.553 -25.486 -69.168 -25.926C-67.722 -27.578 -69.046 -30.51 -67.406 -32.061C-67.102 -32.35 -66.726 -32.902 -66.441 -33.32C-65.782 -34.283 -64.598 -34.771 -63.648 -35.599C-63.33 -35.875 -63.531 -36.702 -62.962 -36.61C-62.248 -36.495 -61.007 -36.625 -61.052 -35.784C-61.165 -33.664 -62.494 -31.944 -63.774 -30.276C-63.323 -29.572 -63.781 -28.937 -64.065 -28.38C-65.4 -25.76 -65.211 -22.919 -65.385 -20.079C-65.39 -19.994 -65.697 -19.916 -65.689 -19.863C-65.336 -17.528 -64.752 -15.329 -63.873 -13.1C-63.507 -12.17 -63.036 -11.275 -62.886 -10.348C-62.775 -9.662 -62.672 -8.829 -63.08 -8.124C-61.045 -5.234 -62.354 -2.583 -61.185 0.948C-60.978 1.573 -59.286 3.487 -59.749 3.326C-62.262 2.455 -62.374 2.057 -62.551 1.304C-62.697 0.681 -63.027 -0.696 -63.264 -1.298C-63.328 -1.462 -63.499 -3.346 -63.577 -3.468C-65.09 -5.85 -63.732 -5.674 -65.102 -8.032C-66.53 -8.712 -67.496 -9.816 -68.619 -10.978C-68.817 -11.182 -67.674 -11.906 -67.855 -12.119C-68.947 -13.408 -70.1 -14.175 -69.764 -15.668C-69.609 -16.358 -69.472 -17.415 -70.216 -18.135z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-73.8 -16.4C-73.8 -16.4 -73.4 -9.6 -71 -8C-68.6 -6.4 -69.8 -7.2 -73 -8.4C-76.2 -9.6 -75 -10.4 -75 -10.4C-75 -10.4 -77.8 -10 -75.4 -8C-73 -6 -69.4 -3.6 -71 -3.6C-72.6 -3.6 -80.2 -7.6 -80.2 -10.4C-80.2 -13.2 -81.2 -17.3 -81.2 -17.3C-81.2 -17.3 -80.1 -18.1 -75.3 -18C-75.3 -18 -73.9 -17.3 -73.8 -16.4z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-74.6 2.2C-74.6 2.2 -83.12 -0.591 -101.6 2.8C-101.6 2.8 -92.569 0.722 -73.8 3C-63.5 4.25 -74.6 2.2 -74.6 2.2z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-72.502 2.129C-72.502 2.129 -80.748 -1.389 -99.453 0.392C-99.453 0.392 -90.275 -0.897 -71.774 2.995C-61.62 5.131 -72.502 2.129 -72.502 2.129z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-70.714 2.222C-70.714 2.222 -78.676 -1.899 -97.461 -1.514C-97.461 -1.514 -88.213 -2.118 -70.052 3.14C-60.086 6.025 -70.714 2.222 -70.714 2.222z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-69.444 2.445C-69.444 2.445 -76.268 -1.862 -93.142 -2.96C-93.142 -2.96 -84.803 -2.79 -68.922 3.319C-60.206 6.672 -69.444 2.445 -69.444 2.445z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M45.84 12.961C45.84 12.961 44.91 13.605 45.124 12.424C45.339 11.243 73.547 -1.927 77.161 -1.677C77.161 -1.677 46.913 11.529 45.84 12.961z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M42.446 13.6C42.446 13.6 41.57 14.315 41.691 13.121C41.812 11.927 68.899 -3.418 72.521 -3.452C72.521 -3.452 43.404 12.089 42.446 13.6z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M39.16 14.975C39.16 14.975 38.332 15.747 38.374 14.547C38.416 13.348 58.233 -2.149 68.045 -4.023C68.045 -4.023 50.015 4.104 39.16 14.975z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M36.284 16.838C36.284 16.838 35.539 17.532 35.577 16.453C35.615 15.373 53.449 1.426 62.28 -0.26C62.28 -0.26 46.054 7.054 36.284 16.838z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M4.6 164.801C4.6 164.801 -10.6 162.401 6.2 160.801C6.2 160.801 24.2 158.801 28.2 153.601C28.2 153.601 41.8 144.401 44.6 144.001C47.4 143.601 63.8 140.001 64.2 137.601C64.6 135.201 70.6 132.801 72.2 133.601C73.8 134.401 73.8 143.601 71 144.401C68.2 145.201 49.4 152.401 43 153.601C36.6 154.801 25 162.401 20.2 163.601C15.4 164.801 4.6 164.801 4.6 164.801z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M77.6 127.401C77.6 127.401 74.6 129.001 73.4 131.601C73.4 131.601 67 142.201 52.8 145.401C52.8 145.401 29.8 154.401 22 156.401C22 156.401 8.6 161.401 1.2 160.601C1.2 160.601 -5.8 160.801 0.4 162.401C0.4 162.401 20.6 160.401 24 158.601C24 158.601 39.6 153.401 42.6 150.801C45.6 148.201 63.8 143.201 66 141.201C68.2 139.201 78 130.801 77.6 127.401z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M18.882 158.911C18.882 158.911 24.111 158.685 22.958 160.234C21.805 161.784 19.357 160.91 19.357 160.91L18.882 158.911z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M11.68 160.263C11.68 160.263 16.908 160.037 15.756 161.586C14.603 163.136 12.155 162.263 12.155 162.263L11.68 160.263z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M1.251 161.511C1.251 161.511 6.48 161.284 5.327 162.834C4.174 164.383 1.726 163.51 1.726 163.51L1.251 161.511z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-6.383 162.055C-6.383 162.055 -1.154 161.829 -2.307 163.378C-3.46 164.928 -5.908 164.054 -5.908 164.054L-6.383 162.055z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M35.415 151.513C35.415 151.513 42.375 151.212 40.84 153.274C39.306 155.336 36.047 154.174 36.047 154.174L35.415 151.513z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M45.73 147.088C45.73 147.088 51.689 143.787 51.155 148.849C50.885 151.405 46.362 149.749 46.362 149.749L45.73 147.088z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M54.862 144.274C54.862 144.274 62.021 140.573 60.287 146.035C59.509 148.485 55.493 146.935 55.493 146.935L54.862 144.274z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M64.376 139.449C64.376 139.449 68.735 134.548 69.801 141.21C70.207 143.748 65.008 142.11 65.008 142.11L64.376 139.449z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M26.834 155.997C26.834 155.997 32.062 155.77 30.91 157.32C29.757 158.869 27.308 157.996 27.308 157.996L26.834 155.997z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M62.434 34.603C62.434 34.603 61.708 35.268 61.707 34.197C61.707 33.127 79.191 19.863 88.034 18.479C88.034 18.479 71.935 25.208 62.434 34.603z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M65.4 98.4C65.4 98.4 87.401 120.801 96.601 124.401C96.601 124.401 105.801 135.601 101.801 161.601C101.801 161.601 98.601 169.201 95.401 148.401C95.401 148.401 98.601 123.201 87.401 139.201C87.401 139.201 79 129.301 85.4 129.601C85.4 129.601 88.601 131.601 89.001 130.001C89.401 128.401 81.4 114.801 64.2 100.4C47 86 65.4 98.4 65.4 98.4z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M7 137.201C7 137.201 6.8 135.401 8.6 136.201C10.4 137.001 104.601 143.201 136.201 167.201C136.201 167.201 91.001 144.001 7 137.201z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M17.4 132.801C17.4 132.801 17.2 131.001 19 131.801C20.8 132.601 157.401 131.601 181.001 164.001C181.001 164.001 159.001 138.801 17.4 132.801z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M29 128.801C29 128.801 28.8 127.001 30.6 127.801C32.4 128.601 205.801 115.601 229.401 148.001C229.401 148.001 219.801 122.401 29 128.801z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M39 124.001C39 124.001 38.8 122.201 40.6 123.001C42.4 123.801 164.601 85.2 188.201 117.601C188.201 117.601 174.801 93 39 124.001z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-19 146.801C-19 146.801 -19.2 145.001 -17.4 145.801C-15.6 146.601 2.2 148.801 4.2 187.601C4.2 187.601 -3 145.601 -19 146.801z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-27.8 148.401C-27.8 148.401 -28 146.601 -26.2 147.401C-24.4 148.201 -10.2 143.601 -13 182.401C-13 182.401 -11.8 147.201 -27.8 148.401z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-35.8 148.801C-35.8 148.801 -36 147.001 -34.2 147.801C-32.4 148.601 -17 149.201 -29.4 171.601C-29.4 171.601 -19.8 147.601 -35.8 148.801z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M11.526 104.465C11.526 104.465 11.082 106.464 12.631 105.247C28.699 92.622 61.141 33.72 116.826 28.086C116.826 28.086 78.518 15.976 11.526 104.465z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M22.726 102.665C22.726 102.665 21.363 101.472 23.231 100.847C25.099 100.222 137.541 27.72 176.826 35.686C176.826 35.686 149.719 28.176 22.726 102.665z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M1.885 108.767C1.885 108.767 1.376 110.366 3.087 109.39C12.062 104.27 15.677 47.059 59.254 45.804C59.254 45.804 26.843 31.09 1.885 108.767z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-18.038 119.793C-18.038 119.793 -19.115 121.079 -17.162 120.825C-6.916 119.493 14.489 78.222 58.928 83.301C58.928 83.301 26.962 68.955 -18.038 119.793z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-6.8 113.667C-6.8 113.667 -7.611 115.136 -5.742 114.511C4.057 111.237 17.141 66.625 61.729 63.078C61.729 63.078 27.603 55.135 -6.8 113.667z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-25.078 124.912C-25.078 124.912 -25.951 125.954 -24.369 125.748C-16.07 124.669 1.268 91.24 37.264 95.354C37.264 95.354 11.371 83.734 -25.078 124.912z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-32.677 130.821C-32.677 130.821 -33.682 131.866 -32.091 131.748C-27.923 131.439 2.715 98.36 21.183 113.862C21.183 113.862 9.168 95.139 -32.677 130.821z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M36.855 98.898C36.855 98.898 35.654 97.543 37.586 97.158C39.518 96.774 160.221 39.061 198.184 51.927C198.184 51.927 172.243 41.053 36.855 98.898z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M3.4 163.201C3.4 163.201 3.2 161.401 5 162.201C6.8 163.001 22.2 163.601 9.8 186.001C9.8 186.001 19.4 162.001 3.4 163.201z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M13.8 161.601C13.8 161.601 13.6 159.801 15.4 160.601C17.2 161.401 35 163.601 37 202.401C37 202.401 29.8 160.401 13.8 161.601z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M20.6 160.001C20.6 160.001 20.4 158.201 22.2 159.001C24 159.801 48.6 163.201 72.2 195.601C72.2 195.601 36.6 158.801 20.6 160.001z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M28.225 157.972C28.225 157.972 27.788 156.214 29.678 156.768C31.568 157.322 52.002 155.423 90.099 189.599C90.099 189.599 43.924 154.656 28.225 157.972z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M38.625 153.572C38.625 153.572 38.188 151.814 40.078 152.368C41.968 152.922 76.802 157.423 128.499 192.399C128.499 192.399 54.324 150.256 38.625 153.572z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-1.8 142.001C-1.8 142.001 -2 140.201 -0.2 141.001C1.6 141.801 55 144.401 85.4 171.201C85.4 171.201 50.499 146.426 -1.8 142.001z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M-11.8 146.001C-11.8 146.001 -12 144.201 -10.2 145.001C-8.4 145.801 16.2 149.201 39.8 181.601C39.8 181.601 4.2 144.801 -11.8 146.001z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M49.503 148.962C49.503 148.962 48.938 147.241 50.864 147.655C52.79 148.068 87.86 150.004 141.981 181.098C141.981 181.098 64.317 146.704 49.503 148.962z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M57.903 146.562C57.903 146.562 57.338 144.841 59.264 145.255C61.19 145.668 96.26 147.604 150.381 178.698C150.381 178.698 73.317 143.904 57.903 146.562z"/>
+ </g>
+ <g style="fill: #ffffff; stroke:#000000; stroke-width:0.1">
+ <path d="M67.503 141.562C67.503 141.562 66.938 139.841 68.864 140.255C70.79 140.668 113.86 145.004 203.582 179.298C203.582 179.298 82.917 138.904 67.503 141.562z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-43.8 148.401C-43.8 148.401 -38.6 148.001 -39.8 149.601C-41 151.201 -43.4 150.401 -43.4 150.401L-43.8 148.401z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-13 162.401C-13 162.401 -7.8 162.001 -9 163.601C-10.2 165.201 -12.6 164.401 -12.6 164.401L-13 162.401z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-21.8 162.001C-21.8 162.001 -16.6 161.601 -17.8 163.201C-19 164.801 -21.4 164.001 -21.4 164.001L-21.8 162.001z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-117.169 150.182C-117.169 150.182 -112.124 151.505 -113.782 152.624C-115.439 153.744 -117.446 152.202 -117.446 152.202L-117.169 150.182z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-115.169 140.582C-115.169 140.582 -110.124 141.905 -111.782 143.024C-113.439 144.144 -115.446 142.602 -115.446 142.602L-115.169 140.582z"/>
+ </g>
+ <g style="fill: #000000">
+ <path d="M-122.369 136.182C-122.369 136.182 -117.324 137.505 -118.982 138.624C-120.639 139.744 -122.646 138.202 -122.646 138.202L-122.369 136.182z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-42.6 211.201C-42.6 211.201 -44.2 211.201 -48.2 213.201C-50.2 213.201 -61.4 216.801 -67 226.801C-67 226.801 -54.6 217.201 -42.6 211.201z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M45.116 303.847C45.257 304.105 45.312 304.525 45.604 304.542C46.262 304.582 47.495 304.883 47.37 304.247C46.522 299.941 45.648 295.004 41.515 293.197C40.876 292.918 39.434 293.331 39.36 294.215C39.233 295.739 39.116 297.088 39.425 298.554C39.725 299.975 41.883 299.985 42.8 298.601C43.736 300.273 44.168 302.116 45.116 303.847z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M34.038 308.581C34.786 309.994 34.659 311.853 36.074 312.416C36.814 312.71 38.664 311.735 38.246 310.661C37.444 308.6 37.056 306.361 35.667 304.55C35.467 304.288 35.707 303.755 35.547 303.427C34.953 302.207 33.808 301.472 32.4 301.801C31.285 304.004 32.433 306.133 33.955 307.842C34.091 307.994 33.925 308.37 34.038 308.581z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-5.564 303.391C-5.672 303.014 -5.71 302.551 -5.545 302.23C-5.014 301.197 -4.221 300.075 -4.558 299.053C-4.906 297.997 -6.022 298.179 -6.672 298.748C-7.807 299.742 -7.856 301.568 -8.547 302.927C-8.743 303.313 -8.692 303.886 -9.133 304.277C-9.607 304.698 -10.047 306.222 -9.951 306.793C-9.898 307.106 -10.081 317.014 -9.859 316.751C-9.24 316.018 -6.19 306.284 -6.121 305.392C-6.064 304.661 -5.332 304.196 -5.564 303.391z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-31.202 296.599C-28.568 294.1 -25.778 291.139 -26.22 287.427C-26.336 286.451 -28.111 286.978 -28.298 287.824C-29.1 291.449 -31.139 294.11 -33.707 296.502C-35.903 298.549 -37.765 304.893 -38 305.401C-34.303 300.145 -32.046 297.399 -31.202 296.599z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-44.776 290.635C-44.253 290.265 -44.555 289.774 -44.338 289.442C-43.385 287.984 -42.084 286.738 -42.066 285C-42.063 284.723 -42.441 284.414 -42.776 284.638C-43.053 284.822 -43.395 284.952 -43.503 285.082C-45.533 287.531 -46.933 290.202 -48.376 293.014C-48.559 293.371 -49.703 297.862 -49.39 297.973C-49.151 298.058 -47.431 293.877 -47.221 293.763C-45.958 293.077 -45.946 291.462 -44.776 290.635z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-28.043 310.179C-27.599 309.31 -26.023 308.108 -26.136 307.219C-26.254 306.291 -25.786 304.848 -26.698 305.536C-27.955 306.484 -31.404 307.833 -31.674 313.641C-31.7 314.212 -28.726 311.519 -28.043 310.179z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-13.6 293.001C-13.2 292.333 -12.492 292.806 -12.033 292.543C-11.385 292.171 -10.774 291.613 -10.482 290.964C-9.512 288.815 -7.743 286.995 -7.6 284.601C-9.091 283.196 -9.77 285.236 -10.4 286.201C-11.723 284.554 -12.722 286.428 -14.022 286.947C-14.092 286.975 -14.305 286.628 -14.38 286.655C-15.557 287.095 -16.237 288.176 -17.235 288.957C-17.406 289.091 -17.811 288.911 -17.958 289.047C-18.61 289.65 -19.583 289.975 -19.863 290.657C-20.973 293.364 -24.113 295.459 -26 303.001C-25.619 303.91 -21.488 296.359 -21.001 295.661C-20.165 294.465 -20.047 297.322 -18.771 296.656C-18.72 296.629 -18.534 296.867 -18.4 297.001C-18.206 296.721 -17.988 296.492 -17.6 296.601C-17.6 296.201 -17.734 295.645 -17.533 295.486C-16.296 294.509 -16.38 293.441 -15.6 292.201C-15.142 292.99 -14.081 292.271 -13.6 293.001z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M46.2 347.401C46.2 347.401 53.6 327.001 49.2 315.801C49.2 315.801 60.6 337.401 56 348.601C56 348.601 55.6 338.201 51.6 333.201C51.6 333.201 47.6 346.001 46.2 347.401z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M31.4 344.801C31.4 344.801 36.8 336.001 28.8 317.601C28.8 317.601 28 338.001 21.2 349.001C21.2 349.001 35.4 328.801 31.4 344.801z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M21.4 342.801C21.4 342.801 21.2 322.801 21.6 319.801C21.6 319.801 17.8 336.401 7.6 346.001C7.6 346.001 22 334.001 21.4 342.801z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M11.8 310.801C11.8 310.801 17.8 324.401 7.8 342.801C7.8 342.801 14.2 330.601 9.4 323.601C9.4 323.601 12 320.201 11.8 310.801z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-7.4 342.401C-7.4 342.401 -8.4 326.801 -6.6 324.601C-6.6 324.601 -6.4 318.201 -6.8 317.201C-6.8 317.201 -2.8 311.001 -2.6 318.401C-2.6 318.401 -1.2 326.201 1.6 330.801C1.6 330.801 5.2 336.201 5 342.601C5 342.601 -5 312.401 -7.4 342.401z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-11 314.801C-11 314.801 -17.6 325.601 -19.4 344.601C-19.4 344.601 -20.8 338.401 -17 324.001C-17 324.001 -12.8 308.601 -11 314.801z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-32.8 334.601C-32.8 334.601 -27.8 329.201 -26.4 324.201C-26.4 324.201 -22.8 308.401 -29.2 317.001C-29.2 317.001 -29 325.001 -37.2 332.401C-37.2 332.401 -32.4 330.001 -32.8 334.601z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-38.6 329.601C-38.6 329.601 -35.2 312.201 -34.4 311.401C-34.4 311.401 -32.6 308.001 -35.4 311.201C-35.4 311.201 -44.2 330.401 -48.2 337.001C-48.2 337.001 -40.2 327.801 -38.6 329.601z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-44.4 313.001C-44.4 313.001 -32.8 290.601 -54.6 316.401C-54.6 316.401 -43.6 306.601 -44.4 313.001z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M-59.8 298.401C-59.8 298.401 -55 279.601 -52.4 279.801C-52.4 279.801 -44.2 270.801 -50.8 281.401C-50.8 281.401 -56.8 291.001 -56.2 300.801C-56.2 300.801 -56.8 291.201 -59.8 298.401z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M270.5 287C270.5 287 258.5 277 256 273.5C256 273.5 269.5 292 269.5 299C269.5 299 272 291.5 270.5 287z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M276 265C276 265 255 250 251.5 242.5C251.5 242.5 278 272 278 276.5C278 276.5 278.5 267.5 276 265z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M293 111C293 111 281 103 279.5 105C279.5 105 290 111.5 292.5 120C292.5 120 291 111 293 111z"/>
+ </g>
+ <g style="fill: #cccccc">
+ <path d="M301.5 191.5L284 179.5C284 179.5 303 196.5 303.5 200.5L301.5 191.5z"/>
+ </g>
+ <g style="stroke:#000000">
+ <path d="M-89.25 169L-67.25 173.75"/>
+ </g>
+ <g style="stroke:#000000">
+ <path d="M-39 331C-39 331 -39.5 327.5 -48.5 338"/>
+ </g>
+ <g style="stroke:#000000">
+ <path d="M-33.5 336C-33.5 336 -31.5 329.5 -38 334"/>
+ </g>
+ <g style="stroke:#000000">
+ <path d="M20.5 344.5C20.5 344.5 22 333.5 10.5 346.5"/>
+ </g>
+</g>
+</svg>
+
diff --git a/sources/pyside6/tests/QtSvgWidgets/CMakeLists.txt b/sources/pyside6/tests/QtSvgWidgets/CMakeLists.txt
new file mode 100644
index 000000000..61952169a
--- /dev/null
+++ b/sources/pyside6/tests/QtSvgWidgets/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(qsvgwidget_test.py)
diff --git a/sources/pyside6/tests/QtSvgWidgets/QtSvgWidgets.pyproject b/sources/pyside6/tests/QtSvgWidgets/QtSvgWidgets.pyproject
new file mode 100644
index 000000000..6b441ea3e
--- /dev/null
+++ b/sources/pyside6/tests/QtSvgWidgets/QtSvgWidgets.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["qsvgwidget_test.py"]
+}
diff --git a/sources/pyside6/tests/QtSvgWidgets/qsvgwidget_test.py b/sources/pyside6/tests/QtSvgWidgets/qsvgwidget_test.py
new file mode 100644
index 000000000..552d6f49a
--- /dev/null
+++ b/sources/pyside6/tests/QtSvgWidgets/qsvgwidget_test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QFile, QFileInfo, QDir
+from PySide6.QtWidgets import QApplication
+from PySide6.QtSvgWidgets import QSvgWidget
+
+
+class QSvgWidgetTest(unittest.TestCase):
+
+ def testLoad(self):
+ directory = os.path.dirname(__file__)
+ tigerPath = QDir.cleanPath(f"{directory}/../QtSvg/tiger.svg")
+ self.assertTrue(QFileInfo.exists(tigerPath))
+
+ app = QApplication([])
+ fromFile = QSvgWidget()
+ fromFile.load(tigerPath)
+ self.assertTrue(fromFile.renderer().isValid())
+
+ tigerFile = QFile(tigerPath)
+ tigerFile.open(QFile.ReadOnly)
+ tigerData = tigerFile.readAll()
+ fromContents = QSvgWidget()
+ fromContents.load(tigerData)
+ self.assertTrue(fromContents.renderer().isValid())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtTest/CMakeLists.txt b/sources/pyside6/tests/QtTest/CMakeLists.txt
new file mode 100644
index 000000000..21a585ea4
--- /dev/null
+++ b/sources/pyside6/tests/QtTest/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(click_test.py)
+PYSIDE_TEST(eventfilter_test.py)
+# The test is currently permanently broken, needs to be fixed.
+#PYSIDE_TEST(touchevent_test.py)
+PYSIDE_TEST(qsignalspy_test.py)
+PYSIDE_TEST(qvalidator_test.py)
diff --git a/sources/pyside6/tests/QtTest/QtTest.pyproject b/sources/pyside6/tests/QtTest/QtTest.pyproject
new file mode 100644
index 000000000..151c0ef08
--- /dev/null
+++ b/sources/pyside6/tests/QtTest/QtTest.pyproject
@@ -0,0 +1,7 @@
+{
+ "files": ["click_test.py",
+ "eventfilter_test.py",
+ "qsignalspy_test.py",
+ "qvalidator_test.py",
+ "touchevent_test.py"]
+}
diff --git a/sources/pyside6/tests/QtTest/click_test.py b/sources/pyside6/tests/QtTest/click_test.py
new file mode 100644
index 000000000..da8b2dcf6
--- /dev/null
+++ b/sources/pyside6/tests/QtTest/click_test.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''QtTest mouse click functionalities'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QObject
+from PySide6.QtWidgets import QPushButton, QLineEdit
+from PySide6.QtTest import QTest
+
+from helper.usesqapplication import UsesQApplication
+
+
+class MouseClickTest(UsesQApplication):
+
+ def testBasic(self):
+ '''QTest.mouseClick with QCheckBox'''
+ button = QPushButton()
+ button.setCheckable(True)
+ button.setChecked(False)
+
+ QTest.mouseClick(button, Qt.LeftButton)
+ self.assertTrue(button.isChecked())
+
+ QTest.mouseClick(button, Qt.LeftButton)
+ self.assertFalse(button.isChecked())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtTest/eventfilter_test.py b/sources/pyside6/tests/QtTest/eventfilter_test.py
new file mode 100644
index 000000000..c57974c0d
--- /dev/null
+++ b/sources/pyside6/tests/QtTest/eventfilter_test.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests for QKeyEvent'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QObject, QEvent
+from PySide6.QtGui import QKeyEvent
+from PySide6.QtWidgets import QLineEdit
+from PySide6.QtTest import QTest
+
+from helper.usesqapplication import UsesQApplication
+
+
+class KeyEventFilter(QObject):
+
+ def __init__(self, widget, eventType, key):
+ super().__init__()
+
+ self.widget = widget
+ self.eventType = eventType
+ self.key = key
+
+ self.processed = False
+
+ def eventFilter(self, obj, event):
+ if self.widget == obj and event.type() == self.eventType and \
+ isinstance(event, QKeyEvent) and event.key() == self.key:
+ self.processed = True
+ return True
+
+ return False
+
+
+class EventFilterTest(UsesQApplication):
+
+ def testKeyEvent(self):
+ widget = QLineEdit()
+ key = Qt.Key_A
+ eventFilter = KeyEventFilter(widget, QEvent.KeyPress, key)
+ widget.installEventFilter(eventFilter)
+
+ QTest.keyClick(widget, key)
+
+ self.assertTrue(eventFilter.processed)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtTest/qsignalspy_test.py b/sources/pyside6/tests/QtTest/qsignalspy_test.py
new file mode 100644
index 000000000..06f05b4b8
--- /dev/null
+++ b/sources/pyside6/tests/QtTest/qsignalspy_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''QtTest QSignalSpy'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QObject, SIGNAL
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+from PySide6.QtTest import QTest, QSignalSpy
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QSignalSpyTest(UsesQApplication):
+
+ def setUp(self):
+ super().setUp()
+ self._model = QStandardItemModel(0, 1)
+ self._model.appendRow(QStandardItem('text1'))
+
+ def testStringBased(self):
+ s = SIGNAL('dataChanged(QModelIndex,QModelIndex,QList<int>)')
+ spy = QSignalSpy(self._model, s)
+ self._model.item(0, 0).setText('text2')
+ self.assertEqual(spy.count(), 1)
+
+ def testSignal(self):
+ spy = QSignalSpy(self._model.dataChanged)
+ self._model.item(0, 0).setText('text3')
+ self.assertEqual(spy.count(), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtTest/qvalidator_test.py b/sources/pyside6/tests/QtTest/qvalidator_test.py
new file mode 100644
index 000000000..2382b8605
--- /dev/null
+++ b/sources/pyside6/tests/QtTest/qvalidator_test.py
@@ -0,0 +1,122 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer, Qt
+from PySide6.QtGui import QValidator
+from PySide6.QtWidgets import QLineEdit
+from PySide6.QtTest import QTest
+from helper.usesqapplication import UsesQApplication
+
+
+class MyValidator1(QValidator):
+ def fixup(self, input):
+ return "fixed"
+
+ def validate(self, input, pos):
+ return (QValidator.Acceptable, "fixed", 1)
+
+
+class MyValidator2(QValidator):
+ def fixup(self, input):
+ return "fixed"
+
+ def validate(self, input, pos):
+ return (QValidator.Acceptable, "fixed")
+
+
+class MyValidator3(QValidator):
+ def fixup(self, input):
+ return "fixed"
+
+ def validate(self, input, pos):
+ return (QValidator.Acceptable,)
+
+
+class MyValidator4(QValidator):
+ def fixup(self, input):
+ return "fixed"
+
+ def validate(self, input, pos):
+ return QValidator.Acceptable
+
+
+class MyValidator5(QValidator):
+ def validate(self, input, pos):
+ if input.islower():
+ return (QValidator.Intermediate, input, pos)
+ else:
+ return (QValidator.Acceptable, input, pos)
+
+ def fixup(self, input):
+ return "22"
+
+
+class QValidatorTest(UsesQApplication):
+ def testValidator1(self):
+ line = QLineEdit()
+ line.setValidator(MyValidator1())
+ line.show()
+ line.setText("foo")
+
+ QTimer.singleShot(0, line.close)
+ self.app.exec()
+
+ self.assertEqual(line.text(), "fixed")
+ self.assertEqual(line.cursorPosition(), 1)
+
+ def testValidator2(self):
+ line = QLineEdit()
+ line.setValidator(MyValidator2())
+ line.show()
+ line.setText("foo")
+
+ QTimer.singleShot(0, line.close)
+ self.app.exec()
+
+ self.assertEqual(line.text(), "fixed")
+ self.assertEqual(line.cursorPosition(), 3)
+
+ def testValidator3(self):
+ line = QLineEdit()
+ line.setValidator(MyValidator3())
+ line.show()
+ line.setText("foo")
+
+ QTimer.singleShot(0, line.close)
+ self.app.exec()
+
+ self.assertEqual(line.text(), "foo")
+ self.assertEqual(line.cursorPosition(), 3)
+
+ def testValidator4(self):
+ line = QLineEdit()
+ line.setValidator(MyValidator4())
+ line.show()
+ line.setText("foo")
+
+ QTimer.singleShot(0, line.close)
+ self.app.exec()
+
+ self.assertEqual(line.text(), "foo")
+ self.assertEqual(line.cursorPosition(), 3)
+
+ def testValidator5(self):
+ line = QLineEdit()
+ line.show()
+ line.setValidator(MyValidator5())
+ line.setText("foo")
+ QTest.keyClick(line, Qt.Key_Return)
+ self.assertEqual(line.text(), "22")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtTest/touchevent_test.py b/sources/pyside6/tests/QtTest/touchevent_test.py
new file mode 100644
index 000000000..bc07c25ed
--- /dev/null
+++ b/sources/pyside6/tests/QtTest/touchevent_test.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtWidgets import QWidget
+from PySide6.QtCore import QPoint, QTimer, Qt, QEvent
+from PySide6.QtGui import QTouchDevice
+from PySide6.QtTest import QTest
+
+
+class MyWidget(QWidget):
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent)
+ self._sequence = []
+ # Fixme (Qt 5): The device needs to be registered (using
+ # QWindowSystemInterface::registerTouchDevice()) for the test to work
+ self._device = QTouchDevice()
+ self.setAttribute(Qt.WA_AcceptTouchEvents)
+ QTimer.singleShot(200, self.generateEvent)
+
+ def event(self, e):
+ self._sequence.append(e.type())
+ return QWidget.event(self, e)
+
+ def generateEvent(self):
+ o = QTest.touchEvent(self, self._device)
+ o.press(0, QPoint(10, 10))
+ o.commit()
+ del o
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ QTest.touchEvent(self, self._device).press(0, QPoint(10, 10))
+ QTest.touchEvent(self, self._device).stationary(0).press(1, QPoint(40, 10))
+ QTest.touchEvent(self, self._device).move(0, QPoint(12, 12)).move(1, QPoint(45, 5))
+ QTest.touchEvent(self, self._device).release(0, QPoint(12, 12)).release(1, QPoint(45, 5))
+ QTimer.singleShot(200, self.deleteLater)
+
+
+class TouchEventTest(UsesQApplication):
+ def testCreateEvent(self):
+ w = MyWidget()
+ w.show()
+ self.app.exec()
+ # same values as C++
+ self.assertEqual(w._sequence.count(QEvent.Type.TouchBegin), 2)
+ self.assertEqual(w._sequence.count(QEvent.Type.TouchUpdate), 2)
+ self.assertEqual(w._sequence.count(QEvent.Type.TouchEnd), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtTextToSpeech/CMakeLists.txt b/sources/pyside6/tests/QtTextToSpeech/CMakeLists.txt
new file mode 100644
index 000000000..6f5851587
--- /dev/null
+++ b/sources/pyside6/tests/QtTextToSpeech/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(qtexttospeech_test.py)
diff --git a/sources/pyside6/tests/QtTextToSpeech/QtTextToSpeech.pyproject b/sources/pyside6/tests/QtTextToSpeech/QtTextToSpeech.pyproject
new file mode 100644
index 000000000..eef38fc22
--- /dev/null
+++ b/sources/pyside6/tests/QtTextToSpeech/QtTextToSpeech.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["qtexttospeech_test.py"]
+}
diff --git a/sources/pyside6/tests/QtTextToSpeech/qtexttospeech_test.py b/sources/pyside6/tests/QtTextToSpeech/qtexttospeech_test.py
new file mode 100644
index 000000000..6ff66c047
--- /dev/null
+++ b/sources/pyside6/tests/QtTextToSpeech/qtexttospeech_test.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QTextToSpeech methods'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication
+
+try:
+ from PySide6.QtTextToSpeech import QTextToSpeech, QVoice
+except ImportError:
+ print("Skipping test due to missing QtTextToSpeech module")
+ sys.exit(0)
+
+
+class QTextToSpeechTestCase(UsesQApplication):
+ '''Tests related to QTextToSpeech'''
+ def testSay(self):
+ engines = QTextToSpeech.availableEngines()
+ if len(engines) > 1 and engines[0] == "mock":
+ engines[0], engines[1] = engines[1], engines[0]
+ if not engines:
+ print('No QTextToSpeech engines available')
+ else:
+ speech = QTextToSpeech(engines[0])
+ speech.stateChanged.connect(self._slotStateChanged)
+ speech.say("Hello, PySide6")
+ QTimer.singleShot(5000, self.app.quit)
+ self.app.exec()
+
+ def _slotStateChanged(self, state):
+ if (state == QTextToSpeech.State.Ready):
+ self.app.quit()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtUiTools/CMakeLists.txt b/sources/pyside6/tests/QtUiTools/CMakeLists.txt
new file mode 100644
index 000000000..08c6f1577
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(bug_360.py)
+PYSIDE_TEST(bug_376.py)
+PYSIDE_TEST(bug_392.py)
+PYSIDE_TEST(bug_426.py)
+PYSIDE_TEST(bug_552.py)
+PYSIDE_TEST(bug_797.py)
+PYSIDE_TEST(bug_909.py)
+PYSIDE_TEST(bug_913.py)
+PYSIDE_TEST(bug_958.py)
+PYSIDE_TEST(bug_965.py)
+PYSIDE_TEST(bug_1060.py)
+PYSIDE_TEST(uiloader_test.py)
+PYSIDE_TEST(ui_test.py)
diff --git a/sources/pyside6/tests/QtUiTools/QtUiTools.pyproject b/sources/pyside6/tests/QtUiTools/QtUiTools.pyproject
new file mode 100644
index 000000000..a83758b87
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/QtUiTools.pyproject
@@ -0,0 +1,28 @@
+{
+ "files": ["action.ui",
+ "bug_1060.py",
+ "bug_1060.ui",
+ "bug_360.py",
+ "bug_376.py",
+ "bug_392.py",
+ "bug_426.py",
+ "bug_426.ui",
+ "bug_552.py",
+ "bug_552.ui",
+ "bug_797.py",
+ "bug_909.py",
+ "bug_909.ui",
+ "bug_913.py",
+ "bug_913.ui",
+ "bug_958.py",
+ "bug_958.ui",
+ "bug_965.py",
+ "bug_965.ui",
+ "loadUiType_test.py",
+ "minimal.ui",
+ "pycustomwidget.ui",
+ "pycustomwidget2.ui",
+ "test.ui",
+ "ui_test.py",
+ "uiloader_test.py"]
+}
diff --git a/sources/pyside6/tests/QtUiTools/action.ui b/sources/pyside6/tests/QtUiTools/action.ui
new file mode 100644
index 000000000..9eda559de
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/action.ui
@@ -0,0 +1,16 @@
+<ui version="4.0">
+ <class>main_window</class>
+ <widget class="QMainWindow" name="main_window">
+ <widget class="QWidget" name="centralwidget"/>
+ <widget class="QMenuBar" name="menubar"/>
+ <widget class="QStatusBar" name="statusbar">
+ <action name="actionFoo">
+ <property name="text">
+ <string>foo</string>
+ </property>
+ </action>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/bug_1060.py b/sources/pyside6/tests/QtUiTools/bug_1060.py
new file mode 100644
index 000000000..52624a2a9
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_1060.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' unit test for BUG #1060 '''
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication
+from PySide6.QtUiTools import QUiLoader
+
+
+class MyQUiLoader(QUiLoader):
+ def __init__(self):
+ super().__init__()
+
+ def createWidget(self, *args):
+ return super(MyQUiLoader, self).createWidget(*args)
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ file = Path(__file__).resolve().parent / 'bug_1060.ui'
+ assert (file.is_file())
+ ui = MyQUiLoader().load(file)
+ ui.show()
diff --git a/sources/pyside6/tests/QtUiTools/bug_1060.ui b/sources/pyside6/tests/QtUiTools/bug_1060.ui
new file mode 100644
index 000000000..f4044a8c2
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_1060.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>100</width>
+ <height>100</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/bug_360.py b/sources/pyside6/tests/QtUiTools/bug_360.py
new file mode 100644
index 000000000..8ca764eae
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_360.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtWidgets import QFrame, QWidget
+from PySide6.QtUiTools import QUiLoader
+
+
+class MyQUiLoader(QUiLoader):
+ def __init__(self, baseinstance):
+ super().__init__()
+ self.baseinstance = baseinstance
+ self._widgets = []
+
+ def createWidget(self, className, parent=None, name=""):
+ widget = QUiLoader.createWidget(self, className, parent, name)
+ self._widgets.append(widget)
+ if parent is None:
+ return self.baseinstance
+ else:
+ setattr(self.baseinstance, name, widget)
+ return widget
+
+
+class ButTest(UsesQApplication):
+ def testCase(self):
+ w = QWidget()
+ loader = MyQUiLoader(w)
+
+ filePath = os.path.join(os.path.dirname(__file__), 'minimal.ui')
+ ui = loader.load(filePath)
+
+ self.assertEqual(len(loader._widgets), 1)
+ self.assertEqual(type(loader._widgets[0]), QFrame)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtUiTools/bug_376.py b/sources/pyside6/tests/QtUiTools/bug_376.py
new file mode 100644
index 000000000..eefc1fe05
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_376.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtWidgets import QFrame, QWidget
+from PySide6.QtUiTools import QUiLoader
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ w = QWidget()
+ loader = QUiLoader()
+
+ filePath = os.path.join(os.path.dirname(__file__), 'test.ui')
+ result = loader.load(filePath, w)
+ self.assertTrue(isinstance(result.child_object, QFrame))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtUiTools/bug_392.py b/sources/pyside6/tests/QtUiTools/bug_392.py
new file mode 100644
index 000000000..4d69fdbec
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_392.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtGui import QAction
+from PySide6.QtWidgets import QComboBox, QWidget
+from PySide6.QtUiTools import QUiLoader
+
+
+class MyWidget(QComboBox):
+ def __init__(self, parent=None):
+ QComboBox.__init__(self, parent)
+
+ def isPython(self):
+ return True
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ w = QWidget()
+ loader = QUiLoader()
+
+ filePath = os.path.join(os.path.dirname(__file__), 'action.ui')
+ result = loader.load(filePath, w)
+ self.assertTrue(isinstance(result.actionFoo, QAction))
+
+ def testPythonCustomWidgets(self):
+ w = QWidget()
+ loader = QUiLoader()
+ loader.registerCustomWidget(MyWidget)
+ self.assertTrue('MyWidget' in loader.availableWidgets())
+
+ filePath = os.path.join(os.path.dirname(__file__), 'pycustomwidget.ui')
+ result = loader.load(filePath, w)
+ self.assertTrue(isinstance(result.custom, MyWidget))
+ self.assertTrue(result.custom.isPython())
+
+ def testPythonCustomWidgetsTwice(self):
+ w = QWidget()
+ loader = QUiLoader()
+ loader.registerCustomWidget(MyWidget)
+ self.assertTrue('MyWidget' in loader.availableWidgets())
+
+ filePath = os.path.join(os.path.dirname(__file__), 'pycustomwidget2.ui')
+ result = loader.load(filePath, w)
+ self.assertTrue(isinstance(result.custom, MyWidget))
+ self.assertTrue(isinstance(result.custom2, MyWidget))
+ self.assertTrue(result.custom.isPython())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtUiTools/bug_426.py b/sources/pyside6/tests/QtUiTools/bug_426.py
new file mode 100644
index 000000000..3a568e4e2
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_426.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtGui import QAction, QActionGroup
+from PySide6.QtWidgets import QApplication, QWidget
+from PySide6.QtUiTools import QUiLoader
+
+
+class Window(object):
+ def __init__(self):
+ loader = QUiLoader()
+ filePath = os.path.join(os.path.dirname(__file__), 'bug_426.ui')
+ self.widget = loader.load(filePath)
+ self.group = QActionGroup(self.widget)
+ self.widget.show()
+ QTimer.singleShot(0, self.widget.close)
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ win = Window()
+ sys.exit(app.exec())
diff --git a/sources/pyside6/tests/QtUiTools/bug_426.ui b/sources/pyside6/tests/QtUiTools/bug_426.ui
new file mode 100644
index 000000000..99353cd2b
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_426.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/bug_552.py b/sources/pyside6/tests/QtUiTools/bug_552.py
new file mode 100644
index 000000000..06a6b72a4
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_552.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtWidgets import QApplication, QFrame, QWidget
+from PySide6.QtUiTools import QUiLoader
+
+
+class View_1(QWidget):
+
+ def __init__(self):
+ super().__init__()
+ loader = QUiLoader()
+ file = Path(__file__).resolve().parent / 'bug_552.ui'
+ assert (file.is_file())
+ widget = loader.load(os.fspath(file), self)
+ self.children = []
+ for child in widget.findChildren(QObject, None):
+ self.children.append(child)
+ self.t = widget.tabWidget
+ self.t.removeTab(0)
+
+
+app = QApplication([])
+window = View_1()
+window.show()
+
+# If it doesn't crash it works :-)
diff --git a/sources/pyside6/tests/QtUiTools/bug_552.ui b/sources/pyside6/tests/QtUiTools/bug_552.ui
new file mode 100644
index 000000000..f98da4421
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_552.ui
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="geometry">
+ <rect>
+ <x>130</x>
+ <y>80</y>
+ <width>139</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Tab 2</string>
+ </attribute>
+ </widget>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/bug_797.py b/sources/pyside6/tests/QtUiTools/bug_797.py
new file mode 100644
index 000000000..3dae7afb7
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_797.py
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtUiTools import QUiLoader
+from PySide6.QtCore import QFile
+from PySide6.QtWidgets import QApplication, QWidget
+
+
+app = QApplication([])
+loader = QUiLoader()
+file = Path(__file__).resolve().parent / 'bug_552.ui'
+assert (file.is_file())
+file = QFile(file)
+w = QWidget()
+# An exception can't be thrown
+mainWindow = loader.load(file, w)
diff --git a/sources/pyside6/tests/QtUiTools/bug_909.py b/sources/pyside6/tests/QtUiTools/bug_909.py
new file mode 100644
index 000000000..cd4d50a0b
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_909.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QFile
+from PySide6.QtWidgets import QTabWidget
+from PySide6.QtUiTools import QUiLoader
+
+from helper.usesqapplication import UsesQApplication
+
+
+class TestDestruction(UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testBug909(self):
+ file = Path(__file__).resolve().parent / 'bug_909.ui'
+ self.assertTrue(file.is_file())
+ fileName = QFile(file)
+ loader = QUiLoader()
+ main_win = loader.load(fileName)
+ self.assertEqual(sys.getrefcount(main_win), 2)
+ fileName.close()
+
+ tw = QTabWidget(main_win)
+ main_win.setCentralWidget(tw)
+ main_win.show()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtUiTools/bug_909.ui b/sources/pyside6/tests/QtUiTools/bug_909.ui
new file mode 100644
index 000000000..b07f62d05
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_909.ui
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget"/>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>25</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/bug_913.py b/sources/pyside6/tests/QtUiTools/bug_913.py
new file mode 100644
index 000000000..85df29d11
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_913.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication
+from PySide6.QtUiTools import QUiLoader
+
+
+class TestBug913 (unittest.TestCase):
+
+ def testIt(self):
+ app = QApplication([])
+
+ loader = QUiLoader()
+ file = Path(__file__).resolve().parent / 'bug_913.ui'
+ self.assertTrue(file.is_file())
+ widget = loader.load(file)
+ widget.tabWidget.currentIndex() # direct child is available as member
+ widget.le_first.setText('foo') # child of QTabWidget must also be available!
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtUiTools/bug_913.ui b/sources/pyside6/tests/QtUiTools/bug_913.ui
new file mode 100644
index 000000000..0fc95fd53
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_913.ui
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>First name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="le_first"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Last name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="le_last"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Tab 2</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/bug_958.py b/sources/pyside6/tests/QtUiTools/bug_958.py
new file mode 100644
index 000000000..2f8dfab62
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_958.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QMainWindow
+from PySide6.QtUiTools import QUiLoader
+from helper.timedqapplication import TimedQApplication
+
+
+class Gui_Qt(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ lLoader = QUiLoader()
+
+ # this used to cause a segfault because the old inject code used to destroy the parent layout
+ file = Path(__file__).resolve().parent / 'bug_958.ui'
+ assert (file.is_file())
+ self._cw = lLoader.load(file, self)
+
+ self.setCentralWidget(self._cw)
+
+
+class BugTest(TimedQApplication):
+ def testCase(self):
+ lMain = Gui_Qt()
+ lMain.show()
+ self.app.exec()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtUiTools/bug_958.ui b/sources/pyside6/tests/QtUiTools/bug_958.ui
new file mode 100644
index 000000000..57cdbddba
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_958.ui
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>customWidget</class>
+ <widget class="QWidget" name="customWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>626</width>
+ <height>578</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTableWidget" name="resultTable"/>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="actionLayout">
+ <item>
+ <widget class="QPushButton" name="processButton">
+ <property name="text">
+ <string>&amp;Berechnen</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/bug_965.py b/sources/pyside6/tests/QtUiTools/bug_965.py
new file mode 100644
index 000000000..2308cbeed
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_965.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtUiTools import QUiLoader
+
+from helper.usesqapplication import UsesQApplication
+
+
+class MyQUiLoader(QUiLoader):
+ def __init__(self):
+ super().__init__()
+
+ def createWidget(self, className, parent=None, name=""):
+ return None
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ loader = MyQUiLoader()
+ file = Path(__file__).resolve().parent / 'bug_965.ui'
+ self.assertTrue(file.is_file())
+ self.assertRaises(RuntimeError, loader.load, file)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtUiTools/bug_965.ui b/sources/pyside6/tests/QtUiTools/bug_965.ui
new file mode 100644
index 000000000..e324db829
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/bug_965.ui
@@ -0,0 +1,27 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="objectName" >
+ <string notr="true" >MainWindow</string>
+ </property>
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QMenuBar" name="menubar" />
+ <widget class="QWidget" name="centralwidget" />
+ <widget class="QStatusBar" name="statusbar" />
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/loadUiType_test.py b/sources/pyside6/tests/QtUiTools/loadUiType_test.py
new file mode 100644
index 000000000..b0842318c
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/loadUiType_test.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtWidgets import QWidget, QFrame, QPushButton
+from PySide6.QtUiTools import loadUiType
+
+
+class loadUiTypeTester(UsesQApplication):
+ def testFunction(self):
+ filePath = os.path.join(os.path.dirname(__file__), "minimal.ui")
+ loaded = loadUiType(filePath)
+ self.assertNotEqual(loaded, None)
+
+ # (<class '__main__.Ui_Form'>, <class 'PySide6.QtWidgets.QFrame'>)
+ generated, base = loaded
+
+ # Generated class contains retranslateUi method
+ self.assertTrue("retranslateUi" in dir(generated))
+
+ # Base class instance will be QFrame for this example
+ self.assertTrue(isinstance(base(), QFrame))
+
+ anotherFileName = os.path.join(os.path.dirname(__file__), "test.ui")
+ another = loadUiType(anotherFileName)
+ self.assertNotEqual(another, None)
+
+ generated, base = another
+ # Base class instance will be QWidget for this example
+ self.assertTrue(isinstance(base(), QWidget))
+
+ w = base()
+ ui = generated()
+ ui.setupUi(w)
+
+ self.assertTrue(isinstance(ui.child_object, QFrame))
+ self.assertTrue(isinstance(ui.grandson_object, QPushButton))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtUiTools/minimal.ui b/sources/pyside6/tests/QtUiTools/minimal.ui
new file mode 100644
index 000000000..c6bb70cda
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/minimal.ui
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QFrame" name="Form">
+ </widget>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/pycustomwidget.ui b/sources/pyside6/tests/QtUiTools/pycustomwidget.ui
new file mode 100644
index 000000000..c066153a0
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/pycustomwidget.ui
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qwidget</class>
+ <widget class="QWidget" name="qwidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string/>
+ </property>
+ <widget class="MyWidget" name="custom">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>79</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>MyWidget</class>
+ <extends>QComboBox</extends>
+ <header>customwidget</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/pycustomwidget2.ui b/sources/pyside6/tests/QtUiTools/pycustomwidget2.ui
new file mode 100644
index 000000000..8826ac1fb
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/pycustomwidget2.ui
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qwidget</class>
+ <widget class="QWidget" name="qwidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string/>
+ </property>
+
+ <widget class="MyWidget" name="custom">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>79</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+
+ <widget class="MyWidget" name="custom2">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>79</width>
+ <height>23</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>MyWidget</class>
+ <extends>QComboBox</extends>
+ <header>customwidget</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/test.ui b/sources/pyside6/tests/QtUiTools/test.ui
new file mode 100644
index 000000000..60afe22b3
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/test.ui
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>185</width>
+ <height>133</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <widget class="QFrame" name="child_object">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>181</width>
+ <height>131</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <widget class="QPushButton" name="grandson_object">
+ <property name="geometry">
+ <rect>
+ <x>50</x>
+ <y>60</y>
+ <width>80</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside6/tests/QtUiTools/ui_test.py b/sources/pyside6/tests/QtUiTools/ui_test.py
new file mode 100644
index 000000000..4e2fa808b
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/ui_test.py
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtUiTools import QUiLoader
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QUiLoaderCreation(UsesQApplication):
+
+ def testConstructor(self):
+ loader = QUiLoader()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtUiTools/uiloader_test.py b/sources/pyside6/tests/QtUiTools/uiloader_test.py
new file mode 100644
index 000000000..19e26912e
--- /dev/null
+++ b/sources/pyside6/tests/QtUiTools/uiloader_test.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtWidgets import QWidget
+from PySide6.QtUiTools import QUiLoader
+
+
+class OverridingLoader(QUiLoader):
+ def createWidget(self, class_name, parent=None, name=''):
+ if class_name == 'QWidget':
+ w = QWidget(parent)
+ w.setObjectName(name)
+ return w
+ return QUiLoader.createWidget(self, class_name, parent, name)
+
+
+class QUiLoaderTester(UsesQApplication):
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self._filePath = os.path.join(os.path.dirname(__file__), 'test.ui')
+
+ def testLoadFile(self):
+ loader = QUiLoader()
+ parent = QWidget()
+ w = loader.load(self._filePath, parent)
+ self.assertNotEqual(w, None)
+
+ self.assertEqual(len(parent.children()), 1)
+
+ child = w.findChild(QWidget, "child_object")
+ self.assertNotEqual(child, None)
+ self.assertEqual(w.findChild(QWidget, "grandson_object"), child.findChild(QWidget, "grandson_object"))
+
+ def testLoadFileOverride(self):
+ # PYSIDE-1070, override QUiLoader::createWidget() with parent=None crashes
+ loader = OverridingLoader()
+ w = loader.load(self._filePath)
+ self.assertNotEqual(w, None)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWebChannel/CMakeLists.txt b/sources/pyside6/tests/QtWebChannel/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtWebChannel/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtWebEngineCore/CMakeLists.txt b/sources/pyside6/tests/QtWebEngineCore/CMakeLists.txt
new file mode 100644
index 000000000..c855d119d
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineCore/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+PYSIDE_TEST(web_engine_custom_scheme.py)
+PYSIDE_TEST(qwebenginecookiestore_test.py)
diff --git a/sources/pyside6/tests/QtWebEngineCore/QtWebEngineCore.pyproject b/sources/pyside6/tests/QtWebEngineCore/QtWebEngineCore.pyproject
new file mode 100644
index 000000000..25923c2a8
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineCore/QtWebEngineCore.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["qwebenginecookiestore_test.py",
+ "web_engine_custom_scheme.py"]
+}
diff --git a/sources/pyside6/tests/QtWebEngineCore/qwebenginecookiestore_test.py b/sources/pyside6/tests/QtWebEngineCore/qwebenginecookiestore_test.py
new file mode 100644
index 000000000..a30c72a8e
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineCore/qwebenginecookiestore_test.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QUrl
+from PySide6.QtWidgets import QApplication
+from PySide6.QtWebEngineWidgets import QWebEngineView
+
+from helper.usesqapplication import UsesQApplication
+
+
+class TestQWebEngineCookieStore(UsesQApplication):
+ def testBasicFilter(self):
+ src_dir = Path(__file__).resolve().parent
+ html_path = src_dir / "resources" / "index.html"
+ view = QWebEngineView()
+ cookie_store = view.page().profile().cookieStore()
+ firstPartyUrlPaths = []
+
+ def cookie_filter(request):
+ nonlocal firstPartyUrlPaths
+ firstPartyUrlPaths.append(Path(request.firstPartyUrl.toLocalFile()))
+ return False
+
+ cookie_store.setCookieFilter(cookie_filter)
+ view.loadFinished.connect(self._slot_loaded)
+ view.load(QUrl.fromLocalFile(html_path))
+ view.show()
+ self.app.exec()
+
+ self.assertEqual(len(firstPartyUrlPaths), 2)
+ self.assertListEqual(firstPartyUrlPaths, [html_path, html_path])
+
+ def _slot_loaded(self):
+ QApplication.quit()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWebEngineCore/resources/index.html b/sources/pyside6/tests/QtWebEngineCore/resources/index.html
new file mode 100644
index 000000000..4c020b714
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineCore/resources/index.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <script type="text/javascript">
+function setCookie() {
+ document.cookie = "test1"
+ document.cookie = "test2"
+}
+</script>
+ </head>
+ <body onload="setCookie()">
+ </body>
+</html>
diff --git a/sources/pyside6/tests/QtWebEngineCore/web_engine_custom_scheme.py b/sources/pyside6/tests/QtWebEngineCore/web_engine_custom_scheme.py
new file mode 100644
index 000000000..10c8e88d7
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineCore/web_engine_custom_scheme.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QBuffer, Qt, QTimer
+from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout
+from PySide6.QtWebEngineWidgets import QWebEngineView
+from PySide6.QtWebEngineCore import (QWebEngineProfile,
+ QWebEngineUrlScheme,
+ QWebEngineUrlSchemeHandler)
+
+
+class TestSchemeHandler(QWebEngineUrlSchemeHandler):
+ def requestStarted(self, request):
+ if request.requestUrl() == "testpy:hello":
+ request.redirect("testpy:goodbye")
+ return
+
+ self.buffer = QBuffer()
+ self.buffer.setData(bytes("Really nice goodbye text.", "UTF-8"))
+ self.buffer.aboutToClose.connect(self.buffer.deleteLater)
+ request.reply(bytes("text/plain;charset=utf-8", "UTF-8"), self.buffer)
+
+
+class MainTest(unittest.TestCase):
+ def test_SchemeHandlerRedirect(self):
+ self._loaded = False
+ QApplication.setAttribute(Qt.AA_ShareOpenGLContexts)
+ app = QApplication([])
+
+ scheme_name = bytes("testpy", "UTF-8")
+ scheme = QWebEngineUrlScheme(scheme_name)
+ scheme.setSyntax(QWebEngineUrlScheme.Syntax.Path)
+ QWebEngineUrlScheme.registerScheme(scheme)
+ handler = TestSchemeHandler()
+ profile = QWebEngineProfile.defaultProfile()
+ profile.installUrlSchemeHandler(scheme_name, handler)
+
+ top_level_widget = QWidget()
+ top_level_widget.setWindowTitle('web_engine_custom_scheme.py')
+ top_level_widget.resize(400, 400)
+ layout = QVBoxLayout(top_level_widget)
+ view = QWebEngineView()
+ layout.addWidget(view)
+
+ view.loadFinished.connect(self._slot_loaded)
+ QTimer.singleShot(5000, app.quit)
+
+ top_level_widget.show()
+ view.load("testpy:hello")
+ app.exec()
+
+ self.assertTrue(self._loaded)
+ self.assertEqual(view.url(), "testpy:goodbye")
+
+ def _slot_loaded(self):
+ self._loaded = True
+ QApplication.quit()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWebEngineQuick/CMakeLists.txt b/sources/pyside6/tests/QtWebEngineQuick/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineQuick/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtWebEngineWidgets/CMakeLists.txt b/sources/pyside6/tests/QtWebEngineWidgets/CMakeLists.txt
new file mode 100644
index 000000000..ce2c6eeae
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineWidgets/CMakeLists.txt
@@ -0,0 +1,4 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+PYSIDE_TEST(pyside-474-qtwebengineview.py)
diff --git a/sources/pyside6/tests/QtWebEngineWidgets/QtWebEngineWidgets.pyproject b/sources/pyside6/tests/QtWebEngineWidgets/QtWebEngineWidgets.pyproject
new file mode 100644
index 000000000..e44646682
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineWidgets/QtWebEngineWidgets.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["pyside-474-qtwebengineview.py"]
+}
diff --git a/sources/pyside6/tests/QtWebEngineWidgets/fox.html b/sources/pyside6/tests/QtWebEngineWidgets/fox.html
new file mode 100644
index 000000000..da873b1cc
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineWidgets/fox.html
@@ -0,0 +1,7 @@
+<html>
+<title>Title</title>
+<meta name="description" content="PySide Test METADATA." />
+<body>
+<p>The quick <b>brown</b> fox <i>jumps</i> over the lazy dog.</p>
+</body>
+</html>
diff --git a/sources/pyside6/tests/QtWebEngineWidgets/pyside-474-qtwebengineview.py b/sources/pyside6/tests/QtWebEngineWidgets/pyside-474-qtwebengineview.py
new file mode 100644
index 000000000..3739e956a
--- /dev/null
+++ b/sources/pyside6/tests/QtWebEngineWidgets/pyside-474-qtwebengineview.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+from functools import partial
+import os
+import sys
+import unittest
+
+TEST_DIR = os.path.dirname(os.path.abspath(__file__))
+
+sys.path.append(os.path.dirname(TEST_DIR))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QSize, QUrl, Qt
+from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget
+from PySide6.QtWebEngineCore import QWebEnginePage
+from PySide6.QtWebEngineWidgets import QWebEngineView
+
+
+class MainTest(unittest.TestCase):
+
+ def test_WebEngineView_findText_exists(self):
+ app = QApplication.instance() or QApplication()
+ top_level = QWidget()
+ layout = QVBoxLayout(top_level)
+ self._view = QWebEngineView()
+ self._view.loadFinished.connect(self.loaded)
+ self._view.load(QUrl.fromLocalFile(os.path.join(TEST_DIR, "fox.html")))
+ self._view.setMinimumSize(QSize(400, 300))
+ self._callback_count = 0
+ layout.addWidget(self._view)
+ top_level.show()
+ app.exec()
+
+ def found_callback(self, found):
+ self.assertTrue(found)
+ self._callback_count += 1
+ if self._callback_count == 2:
+ QCoreApplication.quit()
+
+ def javascript_callback(self, result):
+ self.assertEqual(result, "Title")
+ self._callback_count += 1
+ if self._callback_count == 2:
+ QCoreApplication.quit()
+
+ def loaded(self, ok):
+ self.assertTrue(ok)
+ if not ok:
+ QCoreApplication.quit()
+ self._view.page().runJavaScript("document.title", 1,
+ partial(self.javascript_callback))
+ self._view.findText("fox", QWebEnginePage.FindFlag(0),
+ partial(self.found_callback))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWebSockets/CMakeLists.txt b/sources/pyside6/tests/QtWebSockets/CMakeLists.txt
new file mode 100644
index 000000000..2f7cb08b9
--- /dev/null
+++ b/sources/pyside6/tests/QtWebSockets/CMakeLists.txt
@@ -0,0 +1 @@
+# Please add some tests, here
diff --git a/sources/pyside6/tests/QtWidgets/CMakeLists.txt b/sources/pyside6/tests/QtWidgets/CMakeLists.txt
new file mode 100644
index 000000000..01b7d08ea
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/CMakeLists.txt
@@ -0,0 +1,134 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#Keep this in alphabetical sort
+
+PYSIDE_TEST(action_clear.py)
+PYSIDE_TEST(add_action_test.py)
+PYSIDE_TEST(api2_test.py)
+PYSIDE_TEST(application_test.py)
+PYSIDE_TEST(bug_172.py)
+PYSIDE_TEST(bug_243.py)
+PYSIDE_TEST(bug_307.py)
+PYSIDE_TEST(bug_338.py)
+PYSIDE_TEST(bug_389.py)
+PYSIDE_TEST(bug_400.py)
+PYSIDE_TEST(bug_429.py)
+PYSIDE_TEST(bug_430.py)
+PYSIDE_TEST(bug_433.py)
+PYSIDE_TEST(bug_467.py)
+PYSIDE_TEST(bug_480.py)
+PYSIDE_TEST(bug_512.py)
+PYSIDE_TEST(bug_525.py)
+PYSIDE_TEST(bug_546.py)
+PYSIDE_TEST(bug_547.py)
+PYSIDE_TEST(bug_549.py)
+PYSIDE_TEST(bug_569.py)
+PYSIDE_TEST(bug_575.py)
+PYSIDE_TEST(bug_576.py)
+PYSIDE_TEST(bug_585.py)
+PYSIDE_TEST(bug_589.py)
+PYSIDE_TEST(bug_635.py)
+PYSIDE_TEST(bug_640.py)
+PYSIDE_TEST(bug_653.py)
+PYSIDE_TEST(bug_662.py)
+PYSIDE_TEST(bug_667.py)
+PYSIDE_TEST(bug_668.py)
+PYSIDE_TEST(bug_674.py)
+PYSIDE_TEST(bug_675.py)
+PYSIDE_TEST(bug_688.py)
+PYSIDE_TEST(bug_693.py)
+PYSIDE_TEST(bug_696.py)
+PYSIDE_TEST(bug_711.py)
+PYSIDE_TEST(bug_722.py)
+PYSIDE_TEST(bug_728.py)
+PYSIDE_TEST(bug_736.py)
+PYSIDE_TEST(bug_750.py)
+PYSIDE_TEST(bug_778.py)
+PYSIDE_TEST(bug_793.py)
+PYSIDE_TEST(bug_811.py)
+PYSIDE_TEST(bug_834.py)
+PYSIDE_TEST(bug_836.py)
+PYSIDE_TEST(bug_844.py)
+PYSIDE_TEST(bug_854.py)
+PYSIDE_TEST(bug_860.py)
+PYSIDE_TEST(bug_862.py)
+PYSIDE_TEST(bug_871.py)
+PYSIDE_TEST(bug_879.py)
+PYSIDE_TEST(bug_919.py)
+PYSIDE_TEST(bug_921.py)
+PYSIDE_TEST(bug_941.py)
+PYSIDE_TEST(bug_964.py)
+PYSIDE_TEST(bug_967.py)
+PYSIDE_TEST(bug_972.py)
+PYSIDE_TEST(bug_979.py)
+PYSIDE_TEST(bug_988.py)
+PYSIDE_TEST(bug_998.py)
+PYSIDE_TEST(bug_1002.py)
+PYSIDE_TEST(bug_1006.py)
+PYSIDE_TEST(bug_1048.py)
+PYSIDE_TEST(bug_1077.py)
+PYSIDE_TEST(customproxywidget_test.py)
+PYSIDE_TEST(grandparent_method_test.py)
+PYSIDE_TEST(hashabletype_test.py)
+PYSIDE_TEST(keep_reference_test.py)
+PYSIDE_TEST(missing_symbols_test.py)
+PYSIDE_TEST(paint_event_test.py)
+PYSIDE_TEST(parent_method_test.py)
+PYSIDE_TEST(private_mangle_test.py)
+PYSIDE_TEST(python_properties_test.py)
+PYSIDE_TEST(qabstracttextdocumentlayout_test.py)
+PYSIDE_TEST(qaccessible_test.py)
+PYSIDE_TEST(qaction_test.py)
+PYSIDE_TEST(qapp_issue_585.py)
+PYSIDE_TEST(qapp_test.py)
+PYSIDE_TEST(qapplication_test.py)
+PYSIDE_TEST(qapplication_exit_segfault_test.py)
+PYSIDE_TEST(qdialog_test.py)
+PYSIDE_TEST(qdynamic_signal.py)
+# TODO: This passes, but requires manual button clicking (at least on mac)
+#PYSIDE_TEST(qfontdialog_test.py)
+PYSIDE_TEST(qformlayout_test.py)
+PYSIDE_TEST(qgraphicsitem_test.py)
+PYSIDE_TEST(qgraphicsitem_isblocked_test.py)
+PYSIDE_TEST(qgraphicsobjectreimpl_test.py)
+PYSIDE_TEST(qgraphicsproxywidget_test.py)
+PYSIDE_TEST(qgraphicsscene_test.py)
+PYSIDE_TEST(qinputdialog_get_test.py)
+PYSIDE_TEST(qkeysequenceedit_test.py)
+PYSIDE_TEST(qlabel_test.py)
+PYSIDE_TEST(qlayout_ref_test.py)
+PYSIDE_TEST(qlayout_test.py)
+PYSIDE_TEST(qlcdnumber_test.py)
+PYSIDE_TEST(qlistwidget_test.py)
+PYSIDE_TEST(qlistwidgetitem_test.py)
+PYSIDE_TEST(qmainwindow_test.py)
+PYSIDE_TEST(qmenu_test.py)
+PYSIDE_TEST(qmenuadd_test.py)
+PYSIDE_TEST(qobject_mi_test.py)
+PYSIDE_TEST(qpicture_test.py)
+PYSIDE_TEST(qpushbutton_test.py)
+PYSIDE_TEST(qsplitter_test.py)
+PYSIDE_TEST(qstyle_test.py)
+PYSIDE_TEST(qstyleoption_test.py)
+PYSIDE_TEST(qtableview_test.py)
+PYSIDE_TEST(qtabwidget_test.py)
+PYSIDE_TEST(qtabwidgetclear_test.py)
+PYSIDE_TEST(qtextedit_test.py)
+PYSIDE_TEST(qtextedit_signal_test.py)
+PYSIDE_TEST(qtreeview_test.py)
+PYSIDE_TEST(qtreewidget_test.py)
+PYSIDE_TEST(qtreewidgetitem_test.py)
+PYSIDE_TEST(qtoolbar_test.py)
+PYSIDE_TEST(qtoolbox_test.py)
+PYSIDE_TEST(qvariant_test.py)
+PYSIDE_TEST(qwidget_setlayout_test.py)
+PYSIDE_TEST(qwidget_test.py)
+PYSIDE_TEST(qcolormap_test.py)
+PYSIDE_TEST(reference_count_test.py)
+PYSIDE_TEST(signature_test.py)
+PYSIDE_TEST(standardpixmap_test.py)
+PYSIDE_TEST(test_module_template.py)
+PYSIDE_TEST(virtual_protected_inheritance_test.py)
+PYSIDE_TEST(virtual_pure_override_test.py)
+PYSIDE_TEST(wrong_return_test.py)
diff --git a/sources/pyside6/tests/QtWidgets/QtWidgets.pyproject b/sources/pyside6/tests/QtWidgets/QtWidgets.pyproject
new file mode 100644
index 000000000..36c000165
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/QtWidgets.pyproject
@@ -0,0 +1,130 @@
+{
+ "files": ["action_clear.py",
+ "add_action_test.py",
+ "api2_test.py",
+ "application_test.py",
+ "bug_1002.py",
+ "bug_1006.py",
+ "bug_1048.py",
+ "bug_1077.py",
+ "bug_172.py",
+ "bug_243.py",
+ "bug_307.py",
+ "bug_338.py",
+ "bug_389.py",
+ "bug_400.py",
+ "bug_429.py",
+ "bug_430.py",
+ "bug_433.py",
+ "bug_467.py",
+ "bug_480.py",
+ "bug_512.py",
+ "bug_525.py",
+ "bug_546.py",
+ "bug_547.py",
+ "bug_549.py",
+ "bug_569.py",
+ "bug_575.py",
+ "bug_576.py",
+ "bug_585.py",
+ "bug_589.py",
+ "bug_635.py",
+ "bug_640.py",
+ "bug_653.py",
+ "bug_662.py",
+ "bug_667.py",
+ "bug_668.py",
+ "bug_674.py",
+ "bug_675.py",
+ "bug_688.py",
+ "bug_693.py",
+ "bug_696.py",
+ "bug_711.py",
+ "bug_722.py",
+ "bug_728.py",
+ "bug_736.py",
+ "bug_750.py",
+ "bug_778.py",
+ "bug_793.py",
+ "bug_811.py",
+ "bug_834.py",
+ "bug_836.py",
+ "bug_844.py",
+ "bug_854.py",
+ "bug_860.py",
+ "bug_862.py",
+ "bug_871.py",
+ "bug_879.py",
+ "bug_919.py",
+ "bug_921.py",
+ "bug_941.py",
+ "bug_964.py",
+ "bug_967.py",
+ "bug_972.py",
+ "bug_979.py",
+ "bug_988.py",
+ "bug_998.py",
+ "customproxywidget_test.py",
+ "grandparent_method_test.py",
+ "hashabletype_test.py",
+ "import_test.py",
+ "keep_reference_test.py",
+ "missing_symbols_test.py",
+ "paint_event_test.py",
+ "parent_method_test.py",
+ "private_mangle_test.py",
+ "python_properties_test.py",
+ "qabstracttextdocumentlayout_test.py",
+ "qaccessible_test.py",
+ "qaction_test.py",
+ "qapp_issue_585.py",
+ "qapp_test.py",
+ "qapplication_exit_segfault_test.py",
+ "qapplication_test.py",
+ "qcolormap_test.py",
+ "qdynamic_signal.py",
+ "qfontdialog_test.py",
+ "qformlayout_test.py",
+ "qgraphicsitem_isblocked_test.py",
+ "qgraphicsitem_test.py",
+ "qgraphicsobjectreimpl_test.py",
+ "qgraphicsproxywidget_test.py",
+ "qgraphicsscene_test.py",
+ "qinputdialog_get_test.py",
+ "qkeysequenceedit_test.py",
+ "qlabel_test.py",
+ "qlayout_ref_test.py",
+ "qlayout_test.py",
+ "qlcdnumber_test.py",
+ "qlistwidget_test.py",
+ "qlistwidgetitem_test.py",
+ "qmainwindow_test.py",
+ "qmenu_test.py",
+ "qmenuadd_test.py",
+ "qobject_mi_test.py",
+ "qpicture_test.py",
+ "qpushbutton_test.py",
+ "qsplitter_test.py",
+ "qstyle_test.py",
+ "qstyleoption_test.py",
+ "qtableview_test.py",
+ "qtabwidget_test.py",
+ "qtabwidgetclear_test.py",
+ "qtextedit_signal_test.py",
+ "qtextedit_test.py",
+ "qtoolbar_test.py",
+ "qtoolbox_test.py",
+ "qtreeview_test.py",
+ "qtreewidget_test.py",
+ "qtreewidgetitem_test.py",
+ "qvariant_test.py",
+ "qwidget_setlayout_test.py",
+ "qwidget_test.py",
+ "reference_count_test.py",
+ "signature_test.py",
+ "standardpixmap_test.py",
+ "test_module_template.py",
+ "virtual_protected_inheritance_test.py",
+ "virtual_pure_override_test.py",
+ "wrong_return_test.py"]
+}
diff --git a/sources/pyside6/tests/QtWidgets/action_clear.py b/sources/pyside6/tests/QtWidgets/action_clear.py
new file mode 100644
index 000000000..5563a4899
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/action_clear.py
@@ -0,0 +1,68 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QMenu, QWidget, QMenuBar, QToolBar
+from helper.usesqapplication import UsesQApplication
+
+
+class TestQActionLifeCycle(UsesQApplication):
+ def actionDestroyed(self, act):
+ self._actionDestroyed = True
+
+ def testMenu(self):
+ self._actionDestroyed = False
+ w = QWidget()
+ menu = QMenu(w)
+ act = menu.addAction("MENU")
+ _ref = weakref.ref(act, self.actionDestroyed)
+ act = None
+ self.assertFalse(self._actionDestroyed)
+ menu.clear()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self._actionDestroyed)
+
+ def testMenuBar(self):
+ self._actionDestroyed = False
+ w = QWidget()
+ menuBar = QMenuBar(w)
+ act = menuBar.addAction("MENU")
+ _ref = weakref.ref(act, self.actionDestroyed)
+ act = None
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertFalse(self._actionDestroyed)
+ menuBar.clear()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self._actionDestroyed)
+
+ def testToolBar(self):
+ self._actionDestroyed = False
+ w = QWidget()
+ toolBar = QToolBar(w)
+ act = toolBar.addAction("MENU")
+ _ref = weakref.ref(act, self.actionDestroyed)
+ act = None
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertFalse(self._actionDestroyed)
+ toolBar.clear()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self._actionDestroyed)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/add_action_test.py b/sources/pyside6/tests/QtWidgets/add_action_test.py
new file mode 100644
index 000000000..3ca1660a9
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/add_action_test.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests for QMenuBar.addAction(identifier, callback) calls'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, SLOT
+from PySide6.QtGui import QAction
+from PySide6.QtWidgets import QMenuBar, QPushButton
+
+from helper.usesqapplication import UsesQApplication
+
+
+class AddActionTest(UsesQApplication):
+ '''QMenuBar addAction'''
+
+ def tearDown(self):
+ try:
+ del self.called
+ except AttributeError:
+ pass
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(AddActionTest, self).tearDown()
+
+ def _callback(self):
+ self.called = True
+
+ def testBasic(self):
+ '''QMenuBar.addAction(id, callback)'''
+ menubar = QMenuBar()
+ action = menubar.addAction("Accounts", self._callback)
+ action.activate(QAction.Trigger)
+ action.setShortcut(Qt.Key_A)
+ self.assertTrue(self.called)
+
+ def testWithCppSlot(self):
+ '''QMenuBar.addAction(id, object, slot)'''
+ menubar = QMenuBar()
+ widget = QPushButton()
+ widget.setCheckable(True)
+ widget.setChecked(False)
+ action = menubar.addAction("Accounts", widget, SLOT("toggle()"))
+ action.setShortcut(Qt.Key_A)
+ action.activate(QAction.Trigger)
+ self.assertTrue(widget.isChecked())
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/api2_test.py b/sources/pyside6/tests/QtWidgets/api2_test.py
new file mode 100644
index 000000000..e38672016
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/api2_test.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for PySide API2 support'''
+
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QIntValidator, QValidator
+from PySide6.QtWidgets import QWidget, QSpinBox, QApplication
+
+from helper.usesqapplication import UsesQApplication
+
+
+class WidgetValidatorQInt(QWidget, QIntValidator):
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent)
+ QIntValidator.__init__(self, parent)
+
+
+class WidgetValidatorQSpinBox(QSpinBox):
+ def __init__(self, parent=None):
+ QSpinBox.__init__(self, parent)
+
+ def fixup(self, text):
+ print("It was called!")
+
+
+class DoubleQObjectInheritanceTest(UsesQApplication):
+
+ def testDouble(self):
+ '''Double inheritance from QObject classes'''
+
+ obj = WidgetValidatorQInt()
+
+ # QIntValidator methods
+ state, string, number = obj.validate('Test', 0)
+ self.assertEqual(state, QValidator.Invalid)
+ state, string, number = obj.validate('33', 0)
+ self.assertEqual(state, QValidator.Acceptable)
+
+ def testQSpinBox(self):
+ obj = WidgetValidatorQSpinBox()
+
+ obj.setRange(1, 10)
+ obj.setValue(0)
+ self.assertEqual(obj.value(), 1)
+
+
+class QClipboardTest(UsesQApplication):
+
+ def testQClipboard(self):
+ # skip this test on macOS because the clipboard is not available during the ssh session
+ # this cause problems in the buildbot
+ if sys.platform == 'darwin':
+ return
+ clip = QApplication.clipboard()
+ clip.setText("Testing this thing!")
+
+ text, subtype = clip.text("")
+ self.assertEqual(subtype, "plain")
+ self.assertEqual(text, "Testing this thing!")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/application_test.py b/sources/pyside6/tests/QtWidgets/application_test.py
new file mode 100644
index 000000000..1b2477fd7
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/application_test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import TestObject
+from PySide6.QtWidgets import QApplication
+from PySide6 import __all__ as all
+
+
+class QApplicationInstance(unittest.TestCase):
+
+ def appDestroyed(self):
+ self.assertTrue(False)
+
+ def testInstanceObject(self):
+ self.assertEqual(type(qApp), type(None))
+ TestObject.createApp()
+ app1 = QApplication.instance()
+ app2 = QApplication.instance()
+ app1.setObjectName("MyApp")
+ self.assertEqual(app1, app2)
+ self.assertEqual(app2.objectName(), app1.objectName())
+ # We no longer support qApp when embedding
+ # if len(all) > 3:
+ # # an import triggers qApp initialization
+ # __import__("PySide6." + all[-1])
+ # self.assertEqual(app1, qApp)
+ app1.destroyed.connect(self.appDestroyed)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_1002.py b/sources/pyside6/tests/QtWidgets/bug_1002.py
new file mode 100644
index 000000000..98ae66c47
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_1002.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QWidget, QPushButton
+
+from helper.usesqapplication import UsesQApplication
+
+
+class TestBug1002 (UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReturnWindow(self):
+ widget = QWidget()
+ button = QPushButton(widget)
+ self.assertEqual(sys.getrefcount(widget), 2)
+ window = button.window()
+ self.assertEqual(sys.getrefcount(widget), 3)
+ self.assertEqual(sys.getrefcount(window), 3)
+
+ del widget
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_1006.py b/sources/pyside6/tests/QtWidgets/bug_1006.py
new file mode 100644
index 000000000..74bf5e2da
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_1006.py
@@ -0,0 +1,99 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import QDialog, QLabel, QGridLayout, QHBoxLayout, QWidget
+
+from helper.timedqapplication import TimedQApplication
+
+
+class LabelWindow(QDialog):
+ def __init__(self, parent):
+ super().__init__(parent)
+
+ self.test_layout = QGridLayout()
+ label = QLabel("Label")
+ self.test_layout.addWidget(label, 0, 0)
+ self.setLayout(self.test_layout)
+ self._destroyCalled = False
+
+ def replace(self, unit):
+ old_item = self.test_layout.itemAtPosition(0, 0)
+ old_label = old_item.widget()
+ ref = weakref.ref(old_item, self._destroyed)
+
+ self.test_layout.removeWidget(old_label)
+ unit.assertRaises(RuntimeError, old_item.widget)
+ del old_item
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ label = QLabel("Label New")
+ old_label.deleteLater()
+ label.setAlignment(Qt.AlignCenter)
+ self.test_layout.addWidget(label, 0, 0)
+
+ def _destroyed(self, obj):
+ self._destroyCalled = True
+
+
+class TestBug1006 (TimedQApplication):
+
+ def testLayoutItemLifeTime(self):
+ window = LabelWindow(None)
+ window.replace(self)
+ self.assertTrue(window._destroyCalled)
+ self.app.exec()
+
+ def testParentLayout(self):
+ def createLayout():
+ label = QLabel()
+ layout = QHBoxLayout()
+ layout.addWidget(label)
+
+ widget = QWidget()
+ widget.setLayout(layout)
+ return (layout, widget)
+ (layout, widget) = createLayout()
+ item = layout.itemAt(0)
+ self.assertTrue(isinstance(item.widget(), QWidget))
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRemoveOrphanWidget(self):
+ widget = QLabel()
+ layout = QHBoxLayout()
+ layout.addWidget(widget)
+ self.assertEqual(sys.getrefcount(widget), 3)
+
+ layout.removeWidget(widget)
+ widget.setObjectName("MyWidget")
+ self.assertEqual(sys.getrefcount(widget), 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRemoveChildWidget(self):
+ parent = QLabel()
+ widget = QLabel(parent)
+ self.assertEqual(sys.getrefcount(widget), 3)
+
+ layout = QHBoxLayout()
+ layout.addWidget(widget)
+ self.assertEqual(sys.getrefcount(widget), 3)
+
+ layout.removeWidget(widget)
+ widget.setObjectName("MyWidget")
+ self.assertEqual(sys.getrefcount(widget), 3)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_1048.py b/sources/pyside6/tests/QtWidgets/bug_1048.py
new file mode 100644
index 000000000..9d83e2f30
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_1048.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtWidgets import QApplication, QGridLayout, QWidget
+
+
+a = QApplication([])
+
+w = QWidget()
+l = QGridLayout(w)
+
+l.itemAtPosition(0, 0)
diff --git a/sources/pyside6/tests/QtWidgets/bug_1077.py b/sources/pyside6/tests/QtWidgets/bug_1077.py
new file mode 100644
index 000000000..c9559609f
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_1077.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' unit test for BUG #1077 '''
+
+import os
+import sys
+import time
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtGui import QSyntaxHighlighter
+from PySide6.QtWidgets import QApplication, QTextEdit, QWidget
+
+
+class Highlighter(QSyntaxHighlighter):
+ def __init__(self, parent, mode):
+ super().__init__(parent)
+ self.tstamp = time.time()
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+ python = QTextEdit()
+ python.setWindowTitle("python")
+ hl = Highlighter(python.document(), "python")
+ python.show()
+ text = hl.document()
diff --git a/sources/pyside6/tests/QtWidgets/bug_172.py b/sources/pyside6/tests/QtWidgets/bug_172.py
new file mode 100644
index 000000000..2637d6d61
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_172.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtWidgets import QApplication, QHBoxLayout, QVBoxLayout, QWidget
+
+
+if __name__ == '__main__':
+ app = QApplication([])
+
+ wdg = QWidget()
+
+ hbox = QHBoxLayout()
+
+ vbox = QVBoxLayout()
+ vbox.addLayout(hbox)
+
+ wdg.setLayout(vbox)
diff --git a/sources/pyside6/tests/QtWidgets/bug_243.py b/sources/pyside6/tests/QtWidgets/bug_243.py
new file mode 100644
index 000000000..af189837f
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_243.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 243: http://bugs.openbossa.org/show_bug.cgi?id=243'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QMainWindow, QLayout
+
+
+class QAppPresence(unittest.TestCase):
+
+ def testBug(self):
+ app = QApplication(sys.argv)
+ window = QMainWindow()
+ l = window.layout()
+ self.assertTrue(isinstance(l, QLayout))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_307.py b/sources/pyside6/tests/QtWidgets/bug_307.py
new file mode 100644
index 000000000..673d5183d
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_307.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import colorsys
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import SIGNAL
+from PySide6.QtWidgets import QPushButton, QApplication
+
+
+class Test (QApplication):
+ def __init__(self, argv):
+ super().__init__(argv)
+ self._called = False
+
+ def called(self):
+ self._called = True
+
+
+class QApplicationSignalsTest(unittest.TestCase):
+ def testQuit(self):
+ app = Test([])
+ button = QPushButton("BUTTON")
+ app.connect(button, SIGNAL("clicked()"), app.called)
+ button.click()
+ self.assertTrue(app._called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_338.py b/sources/pyside6/tests/QtWidgets/bug_338.py
new file mode 100644
index 000000000..695b4238a
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_338.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 338: http://bugs.openbossa.org/show_bug.cgi?id=338'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QGraphicsPolygonItem, QGraphicsScene
+
+
+class DiagramItem(QGraphicsPolygonItem):
+ def __init__(self, parent=None, scene=None):
+ super().__init__(parent, scene)
+
+ def itemChange(self, change, value):
+ return value
+
+
+class BugTest(unittest.TestCase):
+ def test(self):
+ app = QApplication(sys.argv)
+ scene = QGraphicsScene()
+ item = DiagramItem()
+ item2 = DiagramItem()
+ # this cause segfault
+ scene.addItem(item)
+ scene.addItem(item2)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_389.py b/sources/pyside6/tests/QtWidgets/bug_389.py
new file mode 100644
index 000000000..024908e85
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_389.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 389: http://bugs.openbossa.org/show_bug.cgi?id=389'''
+
+import sys
+import os
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QIcon
+from PySide6.QtWidgets import QStyle, QWidget
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ s = QWidget().style()
+ i = s.standardIcon(QStyle.SP_TitleBarMinButton)
+ self.assertEqual(type(i), QIcon)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_400.py b/sources/pyside6/tests/QtWidgets/bug_400.py
new file mode 100644
index 000000000..79dfa49fc
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_400.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 400: http://bugs.openbossa.org/show_bug.cgi?id=400'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtWidgets import QTreeWidgetItemIterator, QTreeWidgetItem, QTreeWidget
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ treeWidget = QTreeWidget()
+ treeWidget.setColumnCount(1)
+ items = []
+ for i in range(10):
+ items.append(QTreeWidgetItem(None, [f"item: {i}"]))
+
+ treeWidget.insertTopLevelItems(0, items)
+ _iter = QTreeWidgetItemIterator(treeWidget)
+ index = 0
+ while (_iter.value()):
+ item = _iter.value()
+ self.assertTrue(item is items[index])
+ index += 1
+ _iter += 1
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_429.py b/sources/pyside6/tests/QtWidgets/bug_429.py
new file mode 100644
index 000000000..e95c113f3
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_429.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication, QGraphicsScene, QLabel
+
+
+app = QApplication(sys.argv)
+scene = QGraphicsScene()
+label = QLabel("hello world")
+label.show()
+QTimer.singleShot(0, label.close)
+exit(app.exec())
diff --git a/sources/pyside6/tests/QtWidgets/bug_430.py b/sources/pyside6/tests/QtWidgets/bug_430.py
new file mode 100644
index 000000000..6ef9ec7f4
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_430.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QAbstractListModel, QModelIndex, QTimer
+from PySide6.QtWidgets import QApplication, QListView
+
+
+class ListModel(QAbstractListModel):
+ def rowCount(self, parent=QModelIndex()):
+ return 0
+
+
+if __name__ == '__main__':
+ app = QApplication([])
+ model = ListModel()
+ v = QListView()
+ v.setModel(model)
+ v.show()
+ QTimer.singleShot(0, v.close)
+ app.exec()
diff --git a/sources/pyside6/tests/QtWidgets/bug_433.py b/sources/pyside6/tests/QtWidgets/bug_433.py
new file mode 100644
index 000000000..c7fbe4b3e
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_433.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication, QGraphicsScene, QGraphicsView
+
+
+class Test(QGraphicsView):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.s = QGraphicsScene()
+ self.setScene(self.s)
+
+
+a = QApplication(sys.argv)
+t = Test()
+t.show()
+QTimer.singleShot(0, t.close)
+sys.exit(a.exec_())
diff --git a/sources/pyside6/tests/QtWidgets/bug_467.py b/sources/pyside6/tests/QtWidgets/bug_467.py
new file mode 100644
index 000000000..af383e811
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_467.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 367: http://bugs.openbossa.org/show_bug.cgi?id=467'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtWidgets import QMainWindow, QApplication
+
+
+class MyWidget(QMainWindow):
+ def __init__(self, parent=None):
+ QMainWindow.__init__(self, parent)
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ w = MyWidget()
+ widgets = QApplication.allWidgets()
+ self.assertTrue(w in widgets)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_480.py b/sources/pyside6/tests/QtWidgets/bug_480.py
new file mode 100644
index 000000000..2fc955561
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_480.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import (QApplication, QGridLayout, QLabel, QVBoxLayout,
+ QWidget)
+
+
+class BuggyWidget(QWidget):
+ def setup(self):
+ self.verticalLayout = QVBoxLayout(self)
+ self.gridLayout = QGridLayout()
+ self.lbl = QLabel(self)
+ self.gridLayout.addWidget(self.lbl, 0, 1, 1, 1)
+
+ # this cause a segfault during the ownership transfer
+ self.verticalLayout.addLayout(self.gridLayout)
+
+
+class LayoutTransferOwnerShip(unittest.TestCase):
+ def testBug(self):
+ app = QApplication([])
+ w = BuggyWidget()
+ w.setup()
+ w.show()
+ self.assertTrue(True)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_512.py b/sources/pyside6/tests/QtWidgets/bug_512.py
new file mode 100644
index 000000000..dab367727
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_512.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 512: http://bugs.openbossa.org/show_bug.cgi?id=512'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtWidgets import QGridLayout, QLabel, QWidget
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ w = QWidget(None)
+ lbl = QLabel("Hello", w)
+ g = QGridLayout()
+ g.addWidget(lbl, 0, 0)
+ w.setLayout(g)
+ w.show()
+
+ t = g.getItemPosition(0)
+ self.assertEqual(type(t), tuple)
+ self.assertEqual(t, (0, 0, 1, 1))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_525.py b/sources/pyside6/tests/QtWidgets/bug_525.py
new file mode 100644
index 000000000..3c49cd377
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_525.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication
+from PySide6.QtWidgets import QMenu
+
+
+class M2(QMenu):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setTitle(self.tr("M2"))
+
+
+class TestMenuDerivedClass(unittest.TestCase):
+ def aboutToShowHandler(self):
+ pass
+
+ def testConnectSignal(self):
+ app = QApplication([])
+ m2 = M2()
+ # Test if the aboutToShow signal was translated to correct type
+ m2.aboutToShow.connect(self.aboutToShowHandler)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_546.py b/sources/pyside6/tests/QtWidgets/bug_546.py
new file mode 100644
index 000000000..fcec2f6d7
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_546.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QCompleter, QPlainTextEdit
+
+
+class TestBug546(unittest.TestCase):
+
+ """Test to check a crash at exit"""
+ def testIt(self):
+ app = QApplication([])
+ textEdit = QPlainTextEdit()
+ completer = QCompleter(("foo", "bar"), textEdit)
+ completer.setWidget(textEdit)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_547.py b/sources/pyside6/tests/QtWidgets/bug_547.py
new file mode 100644
index 000000000..dcbe20ee8
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_547.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+""" Unittest for bug #547 """
+""" http://bugs.openbossa.org/show_bug.cgi?id=547 """
+
+import sys
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
+
+
+class MyMainWindow(unittest.TestCase):
+ app = QApplication(sys.argv)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCase1(self):
+ self._tree = QTreeWidget()
+ self._tree.setColumnCount(2)
+ self._i1 = None
+ self._i11 = None
+
+ self._updateTree()
+ self.assertEqual(sys.getrefcount(self._i1), 3)
+ self.assertEqual(sys.getrefcount(self._i11), 3)
+
+ self._i11.parent().setExpanded(True)
+ self._i11.setExpanded(True)
+
+ self._updateTree()
+ self.assertEqual(sys.getrefcount(self._i1), 3)
+ self.assertEqual(sys.getrefcount(self._i11), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCase2(self):
+ self._tree = QTreeWidget()
+ self._tree.setColumnCount(2)
+ self._i1 = None
+ self._i11 = None
+
+ self._updateTree()
+ self.assertEqual(sys.getrefcount(self._i1), 3)
+ self.assertEqual(sys.getrefcount(self._i11), 3)
+
+ self._i11.parent().setExpanded(True)
+ self._i11.setExpanded(True)
+
+ self.assertEqual(sys.getrefcount(self._i1), 3)
+ self.assertEqual(sys.getrefcount(self._i11), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def _updateTree(self):
+ self._tree.clear()
+ if self._i1 and self._i11:
+ self.assertEqual(sys.getrefcount(self._i1), 2)
+ self.assertEqual(sys.getrefcount(self._i11), 2)
+
+ self._i1 = QTreeWidgetItem(self._tree, ['1', ])
+ self.assertEqual(sys.getrefcount(self._i1), 3)
+ self._i11 = QTreeWidgetItem(self._i1, ['11', ])
+ self.assertEqual(sys.getrefcount(self._i11), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_549.py b/sources/pyside6/tests/QtWidgets/bug_549.py
new file mode 100644
index 000000000..8efa6e679
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_549.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QGraphicsWidget
+
+
+class TestBug549(unittest.TestCase):
+ def testBug(self):
+ app = QApplication([])
+ w = QGraphicsWidget()
+ w.setContentsMargins(1, 2, 3, 4)
+ self.assertEqual(w.getContentsMargins(), (1, 2, 3, 4))
+ w.setWindowFrameMargins(5, 6, 7, 8)
+ self.assertEqual(w.getWindowFrameMargins(), (5, 6, 7, 8))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_569.py b/sources/pyside6/tests/QtWidgets/bug_569.py
new file mode 100644
index 000000000..0f95aed02
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_569.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QTableWidgetItem, QListWidgetItem, QTreeWidgetItem
+
+
+class TestBug569(unittest.TestCase):
+
+ def testIt(self):
+ types = (QTableWidgetItem, QListWidgetItem, QTreeWidgetItem)
+ for t in types:
+ a = t()
+ a.__lt__ = lambda other: True
+ b = t()
+ b.__lt__ = lambda other: False
+ self.assertTrue(a < b)
+ self.assertFalse(b < a)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_575.py b/sources/pyside6/tests/QtWidgets/bug_575.py
new file mode 100644
index 000000000..f9a927817
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_575.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+""" Unittest for bug #575 """
+""" http://bugs.openbossa.org/show_bug.cgi?id=575 """
+
+import sys
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QPlainTextEdit, QTextEdit
+
+
+class Bug575(unittest.TestCase):
+ def testPropertyValues(self):
+ app = QApplication(sys.argv)
+ textEdit = QPlainTextEdit()
+ textEdit.insertPlainText("PySide INdT")
+ selection = QTextEdit.ExtraSelection()
+ selection.cursor = textEdit.textCursor()
+ selection.cursor.setPosition(2)
+ self.assertEqual(selection.cursor.position(), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_576.py b/sources/pyside6/tests/QtWidgets/bug_576.py
new file mode 100644
index 000000000..4a17e7aa8
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_576.py
@@ -0,0 +1,49 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+""" Unittest for bug #576 """
+""" http://bugs.openbossa.org/show_bug.cgi?id=576 """
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtWidgets import QApplication, QPushButton, QWidget
+
+
+class Bug576(unittest.TestCase):
+ def onButtonDestroyed(self, button):
+ self._destroyed = True
+ self.assertTrue(isinstance(button, QPushButton))
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testWidgetParent(self):
+ self._destroyed = False
+ app = QApplication(sys.argv)
+ w = QWidget()
+
+ b = QPushButton("test")
+ b.destroyed[QObject].connect(self.onButtonDestroyed)
+ self.assertEqual(sys.getrefcount(b), 2)
+ b.setParent(w)
+ self.assertEqual(sys.getrefcount(b), 3)
+ b.parent()
+ self.assertEqual(sys.getrefcount(b), 3)
+ b.setParent(None)
+ self.assertEqual(sys.getrefcount(b), 2)
+ del b
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self._destroyed)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_585.py b/sources/pyside6/tests/QtWidgets/bug_585.py
new file mode 100644
index 000000000..e26ca9ce0
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_585.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test bug 585: http://bugs.openbossa.org/show_bug.cgi?id=585'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
+
+
+class Bug585(unittest.TestCase):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testCase(self):
+ app = QApplication([])
+ self._tree = QTreeWidget()
+ self._tree.setColumnCount(2)
+ i1 = QTreeWidgetItem(self._tree, ['1', ])
+ i2 = QTreeWidgetItem(self._tree, ['2', ])
+ refCount = sys.getrefcount(i1)
+
+ # this function return None
+ # because the topLevelItem does not has a parent item
+ # but still have a TreeWidget as a parent
+ self._tree.topLevelItem(0).parent()
+
+ self.assertEqual(refCount, sys.getrefcount(i1))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_589.py b/sources/pyside6/tests/QtWidgets/bug_589.py
new file mode 100644
index 000000000..a19f544a5
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_589.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# trimmed down diagramscene.py to demonstrate crash in sizeHint()
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QGraphicsProxyWidget
+
+
+class CustomWidget(QGraphicsProxyWidget):
+ def itemChange(self, eventType, value):
+ QGraphicsProxyWidget.itemChange(self, eventType, value)
+
+
+class Bug589(unittest.TestCase):
+ def testCase(self):
+ widget = QGraphicsProxyWidget()
+ custom = CustomWidget()
+ custom.setParentItem(widget)
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_635.py b/sources/pyside6/tests/QtWidgets/bug_635.py
new file mode 100644
index 000000000..66a8c58c6
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_635.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 635: http://bugs.openbossa.org/show_bug.cgi?id=635'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QIcon
+from PySide6.QtWidgets import QApplication, QToolBar
+
+
+class testQToolBar(unittest.TestCase):
+ def callback(self):
+ self._called = True
+
+ def testAddAction(self):
+ bar = QToolBar()
+ self._called = False
+ a = bar.addAction("act1", self.callback)
+ a.trigger()
+ self.assertTrue(self._called)
+
+ def testAddActionWithIcon(self):
+ bar = QToolBar()
+ self._called = False
+ icon = QIcon()
+ a = bar.addAction(icon, "act1", self.callback)
+ a.trigger()
+ self.assertTrue(self._called)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_640.py b/sources/pyside6/tests/QtWidgets/bug_640.py
new file mode 100644
index 000000000..b2620b541
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_640.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QStyleOptionGraphicsItem
+
+
+class Bug640(unittest.TestCase):
+ def testIt(self):
+ option = QStyleOptionGraphicsItem()
+ a = option.state # crash!?
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_653.py b/sources/pyside6/tests/QtWidgets/bug_653.py
new file mode 100644
index 000000000..1cf8390df
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_653.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QWizard, QWizardPage
+
+
+class TestBug653(unittest.TestCase):
+ """Crash after calling QWizardPage.wizard()"""
+ def testIt(self):
+ app = QApplication([])
+
+ wizard = QWizard()
+ page = QWizardPage()
+ wizard.addPage(page)
+ page.wizard() # crash here if the bug still exists due to a circular dependency
+ wizard.show()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_662.py b/sources/pyside6/tests/QtWidgets/bug_662.py
new file mode 100644
index 000000000..e3a3130d0
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_662.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 662: http://bugs.openbossa.org/show_bug.cgi?id=662'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+from PySide6.QtGui import QTextCharFormat
+from PySide6.QtWidgets import QTextEdit, QApplication
+import sys
+
+
+class testQTextBlock(unittest.TestCase):
+
+ def testIterator(self):
+ edit = QTextEdit()
+ cursor = edit.textCursor()
+ fmt = QTextCharFormat()
+ frags = []
+ for i in range(10):
+ fmt.setFontPointSize(i + 10)
+ frags.append(f"block{i}")
+ cursor.insertText(frags[i], fmt)
+
+ doc = edit.document()
+ block = doc.begin()
+
+ index = 0
+ for i in block:
+ self.assertEqual(i.fragment().text(), frags[index])
+ index += 1
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_667.py b/sources/pyside6/tests/QtWidgets/bug_667.py
new file mode 100644
index 000000000..be6700d83
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_667.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QTimer, QPointF
+from PySide6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem
+
+
+class Ball(QGraphicsEllipseItem):
+ def __init__(self, d, parent=None):
+ super().__init__(0, 0, d, d, parent)
+ self.vel = QPointF(0, 0) # commenting this out prevents the crash
+
+
+class Foo(QGraphicsView):
+ def __init__(self):
+ super().__init__(None)
+ self.scene = QGraphicsScene(self.rect())
+ self.setScene(self.scene)
+ self.scene.addItem(Ball(10))
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ w = Foo()
+ w.show()
+ w.raise_()
+ QTimer.singleShot(0, w.close)
+ sys.exit(app.exec())
diff --git a/sources/pyside6/tests/QtWidgets/bug_668.py b/sources/pyside6/tests/QtWidgets/bug_668.py
new file mode 100644
index 000000000..0c22436b3
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_668.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QDir, QModelIndex, QTimer
+from PySide6.QtWidgets import QApplication, QFileSystemModel, QMainWindow, QTreeView
+
+
+class A(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ a = QFileSystemModel(self)
+ a.setRootPath(QDir.homePath())
+
+ v = QTreeView(self)
+ v.setModel(a)
+ self.setCentralWidget(v)
+ # Test index() method (see PYSIDE-570, PYSIDE-331)
+ index = a.index(0, 0, QModelIndex())
+
+
+app = QApplication([])
+m = A()
+m.show()
+QTimer.singleShot(0, m.close)
+app.exec()
diff --git a/sources/pyside6/tests/QtWidgets/bug_674.py b/sources/pyside6/tests/QtWidgets/bug_674.py
new file mode 100644
index 000000000..901b29275
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_674.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QGraphicsScene
+
+
+class TestBug679(unittest.TestCase):
+ '''QGraphicsScene::clear() is missing'''
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testIt(self):
+ app = QApplication([])
+
+ scene = QGraphicsScene()
+ hello = scene.addText("Hello")
+ scene.addText("World")
+
+ self.assertEqual(sys.getrefcount(hello), 3)
+ scene.clear()
+ self.assertEqual(sys.getrefcount(hello), 2)
+ self.assertEqual(len(scene.items()), 0)
+ self.assertRaises(RuntimeError, hello.isVisible) # the C++ object was deleted
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_675.py b/sources/pyside6/tests/QtWidgets/bug_675.py
new file mode 100644
index 000000000..221df88b0
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_675.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtWidgets import (QApplication, QGraphicsLinearLayout,
+ QGraphicsScene, QGraphicsView, QTextEdit)
+
+
+app = QApplication([])
+
+scene = QGraphicsScene()
+
+# don't segfault due to lack of keepReferenceCall
+textEdit = scene.addWidget(QTextEdit())
+
+layout = QGraphicsLinearLayout()
+layout.addItem(textEdit)
+
+view = QGraphicsView(scene)
+view.show()
diff --git a/sources/pyside6/tests/QtWidgets/bug_688.py b/sources/pyside6/tests/QtWidgets/bug_688.py
new file mode 100644
index 000000000..3180d08bf
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_688.py
@@ -0,0 +1,98 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test bug 688: http://bugs.openbossa.org/show_bug.cgi?id=688'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QTextFrame, QTextCursor, QTextCharFormat, QFont, QTextFrameFormat
+from PySide6.QtWidgets import QTextEdit
+
+
+class BugTest(UsesQApplication):
+ def testCase(self):
+ editor = QTextEdit()
+ cursor = QTextCursor(editor.textCursor())
+ cursor.movePosition(QTextCursor.Start)
+
+ mainFrame = cursor.currentFrame()
+
+ plainCharFormat = QTextCharFormat()
+ boldCharFormat = QTextCharFormat()
+ boldCharFormat.setFontWeight(QFont.Bold)
+ cursor.insertText("""
+ Text documents are represented by the
+ QTextDocument class, rather than by QString objects.
+ Each QTextDocument object contains information about
+ the document's internal representation, its structure,
+ and keeps track of modifications to provide undo/redo
+ facilities. This approach allows features such as the
+ layout management to be delegated to specialized
+ classes, but also provides a focus for the framework.""",
+ plainCharFormat)
+
+ frameFormat = QTextFrameFormat()
+ frameFormat.setMargin(32)
+ frameFormat.setPadding(8)
+ frameFormat.setBorder(4)
+ cursor.insertFrame(frameFormat)
+
+ cursor.insertText("""
+ Documents are either converted from external sources
+ or created from scratch using Qt. The creation process
+ can done by an editor widget, such as QTextEdit, or by
+ explicit calls to the Scribe API.""",
+ boldCharFormat)
+
+ cursor = mainFrame.lastCursorPosition()
+ cursor.insertText("""
+ There are two complementary ways to visualize the
+ contents of a document: as a linear buffer that is
+ used by editors to modify the contents, and as an
+ object hierarchy containing structural information
+ that is useful to layout engines. In the hierarchical
+ model, the objects generally correspond to visual
+ elements such as frames, tables, and lists. At a lower
+ level, these elements describe properties such as the
+ style of text used and its alignment. The linear
+ representation of the document is used for editing and
+ manipulation of the document's contents.""",
+ plainCharFormat)
+
+ frame = cursor.currentFrame()
+
+ items = []
+
+ # test iterator
+ for i in frame:
+ items.append(i)
+
+ # test __iadd__
+ b = frame.begin()
+ i = 0
+ while not b.atEnd():
+ self.assertEqual(b, items[i])
+ self.assertTrue(b.parentFrame(), items[i].parentFrame())
+ b.__iadd__(1)
+ i += 1
+
+ # test __isub__
+ b = frame.end()
+ i = 0
+ while i > 0:
+ self.assertEqual(b, items[i])
+ self.assertTrue(b.parentFrame(), items[i].parentFrame())
+ b.__isub__(1)
+ i -= 1
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_693.py b/sources/pyside6/tests/QtWidgets/bug_693.py
new file mode 100644
index 000000000..95981e272
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_693.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QAbstractListModel, QLine
+from PySide6.QtWidgets import QApplication, QListView
+
+
+class MyModel (QAbstractListModel):
+
+ stupidLine = QLine(0, 0, 10, 10)
+
+ def rowCount(self, parent):
+ return 1
+
+ def data(self, index, role):
+ return self.stupidLine
+
+
+class TestBug693(unittest.TestCase):
+ def testIt(self):
+ app = QApplication([])
+ model = MyModel()
+ view = QListView()
+ view.setModel(model)
+ view.show()
+
+ # This must NOT throw the exception:
+ # RuntimeError: Internal C++ object (PySide6.QtCore.QLine) already deleted.
+ MyModel.stupidLine.isNull()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_696.py b/sources/pyside6/tests/QtWidgets/bug_696.py
new file mode 100644
index 000000000..19e9978a6
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_696.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtWidgets import QMainWindow, QMenu, QApplication
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, *args):
+ self._menu = QMenu(self.dontexist) # attribute called with invalid C++ object
+
+
+class MainWindow2(QMainWindow):
+ def __init__(self):
+ self.show()
+
+
+class Bug696(UsesQApplication):
+ def testContructorInitialization(self):
+ self.assertRaises(AttributeError, MainWindow)
+
+ def testContructorInitializationAndCPPFunction(self):
+ self.assertRaises(RuntimeError, MainWindow2)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_711.py b/sources/pyside6/tests/QtWidgets/bug_711.py
new file mode 100644
index 000000000..fed330fb9
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_711.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QAction
+from PySide6.QtWidgets import QToolBar, QApplication, QToolButton
+
+
+class TestLabelPixmap(unittest.TestCase):
+ def testReference(self):
+ toolbar = QToolBar()
+
+ for i in range(20):
+ toolbar.addAction(QAction(f"Action {i}"))
+
+ buttons = toolbar.findChildren(QToolButton, "")
+ toolbar.clear()
+
+ for b in buttons:
+ self.assertRaises(RuntimeError, b.objectName)
+
+
+if __name__ == '__main__':
+ app = QApplication([])
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_722.py b/sources/pyside6/tests/QtWidgets/bug_722.py
new file mode 100644
index 000000000..dc20e14cf
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_722.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtWidgets import QDoubleSpinBox, QGraphicsBlurEffect
+
+
+class TestSignalConnection(UsesQApplication):
+ def testFloatSignal(self):
+ foo1 = QDoubleSpinBox()
+ foo2 = QDoubleSpinBox()
+ foo1.valueChanged[float].connect(foo2.setValue)
+ foo2.valueChanged[float].connect(foo1.setValue)
+ foo1.setValue(0.42)
+ self.assertEqual(foo1.value(), foo2.value())
+
+ def testQRealSignal(self):
+ foo1 = QDoubleSpinBox()
+ effect = QGraphicsBlurEffect()
+ effect.blurRadiusChanged['qreal'].connect(foo1.setValue) # check if qreal is a valid type
+ effect.setBlurRadius(0.42)
+ self.assertAlmostEqual(foo1.value(), effect.blurRadius())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_728.py b/sources/pyside6/tests/QtWidgets/bug_728.py
new file mode 100644
index 000000000..531adbb25
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_728.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtWidgets import QApplication, QDialog, QFileDialog
+from PySide6.QtCore import QDir, QTimer
+
+
+# Periodically check for the file dialog to appear and close it
+dialog = None
+
+
+def timerHandler():
+ global dialog
+ if dialog is not None:
+ dialog.reject()
+ else:
+ for widget in QApplication.topLevelWidgets():
+ if isinstance(widget, QDialog) and widget.isVisible():
+ dialog = widget
+
+
+app = QApplication([])
+QTimer.singleShot(30000, app.quit) # emergency
+timer = QTimer()
+timer.setInterval(50)
+timer.timeout.connect(timerHandler)
+timer.start()
+
+# This test for a dead lock in QFileDialog.getOpenFileNames, the test fail with a timeout if the dead lock exists.
+QFileDialog.getOpenFileNames(None, "caption", QDir.homePath(), None, "", QFileDialog.DontUseNativeDialog)
diff --git a/sources/pyside6/tests/QtWidgets/bug_736.py b/sources/pyside6/tests/QtWidgets/bug_736.py
new file mode 100644
index 000000000..af4bcbda8
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_736.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import QApplication, QSlider
+
+
+class TestBug736 (unittest.TestCase):
+
+ def testIt(self):
+ app = QApplication([])
+ slider = QSlider(Qt.Horizontal)
+ slider2 = QSlider(Qt.Horizontal)
+
+ slider2.setMaximum(10)
+ slider.valueChanged[int].connect(slider2.setMaximum)
+ slider.valueChanged[int].emit(100)
+ self.assertEqual(slider2.maximum(), 100)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_750.py b/sources/pyside6/tests/QtWidgets/bug_750.py
new file mode 100644
index 000000000..999f6a3db
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_750.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import QTimer
+from PySide6.QtGui import QPainter, QFont, QFontInfo
+from PySide6.QtWidgets import QWidget
+
+
+class MyWidget(QWidget):
+ def paintEvent(self, e):
+ p = QPainter(self)
+ self._info = p.fontInfo()
+ self._app.quit()
+
+
+class TestQPainter(UsesQApplication):
+ def testFontInfo(self):
+ w = MyWidget()
+ w._app = self.app
+ w._info = None
+ QTimer.singleShot(300, w.show)
+ self.app.exec()
+ self.assertTrue(w._info)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_778.py b/sources/pyside6/tests/QtWidgets/bug_778.py
new file mode 100644
index 000000000..1a7def6c7
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_778.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtWidgets import QTreeWidget, QTreeWidgetItem, QTreeWidgetItemIterator
+
+
+class QTreeWidgetItemIteratorTest(UsesQApplication):
+ def testWidgetIterator(self):
+ treeWidget = QTreeWidget()
+ treeWidget.setColumnCount(1)
+ items = []
+ for i in range(10):
+ items.append(QTreeWidgetItem(None, [f'item: {i}']))
+ treeWidget.insertTopLevelItems(0, items)
+
+ index = 0
+ for it in QTreeWidgetItemIterator(treeWidget):
+ self.assertEqual(it.value().text(0), f'item: {index}')
+ index += 1
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_793.py b/sources/pyside6/tests/QtWidgets/bug_793.py
new file mode 100644
index 000000000..94f42a5d3
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_793.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QWidget, QApplication
+
+
+class TestW1(QWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ TestW2(parent, self)
+
+
+class TestW2(QWidget):
+ def __init__(self, ancestor, parent=None):
+ super().__init__(parent)
+ self.ancestor_ref = ancestor
+
+
+class Test(QWidget):
+ def __init__(self):
+ super().__init__()
+ TestW1(self)
+
+
+class TestQApplicationDestrcutor(unittest.TestCase):
+ def testDestructor(self):
+ w = Test()
+ w.show()
+ QTimer.singleShot(0, w.close)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ unittest.main()
+ sys.exit(app.exec())
diff --git a/sources/pyside6/tests/QtWidgets/bug_811.py b/sources/pyside6/tests/QtWidgets/bug_811.py
new file mode 100644
index 000000000..b3537e1f7
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_811.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtGui import QTextBlockUserData, QTextCursor
+from PySide6.QtWidgets import QTextEdit
+
+
+class TestUserData(QTextBlockUserData):
+ def __init__(self, data):
+ super().__init__()
+ self.data = data
+
+
+class TestUserDataRefCount(UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefcount(self):
+ textedit = QTextEdit()
+ textedit.setReadOnly(True)
+ doc = textedit.document()
+ cursor = QTextCursor(doc)
+ cursor.insertText("PySide Rocks")
+ ud = TestUserData({"Life": 42})
+ self.assertEqual(sys.getrefcount(ud), 2)
+ cursor.block().setUserData(ud)
+ self.assertEqual(sys.getrefcount(ud), 3)
+ ud2 = cursor.block().userData()
+ self.assertEqual(sys.getrefcount(ud), 4)
+ self.udata = weakref.ref(ud, None)
+ del ud, ud2
+ self.assertEqual(sys.getrefcount(self.udata()), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_834.py b/sources/pyside6/tests/QtWidgets/bug_834.py
new file mode 100644
index 000000000..685f17e56
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_834.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QTimer, Qt
+from PySide6.QtWidgets import QApplication, QDockWidget, QMainWindow
+
+
+class Window(QMainWindow):
+ def childEvent(self, event):
+ super(Window, self).childEvent(event)
+
+
+app = QApplication([])
+window = Window()
+
+dock1 = QDockWidget()
+dock2 = QDockWidget()
+window.addDockWidget(Qt.LeftDockWidgetArea, dock1)
+window.addDockWidget(Qt.LeftDockWidgetArea, dock2)
+window.tabifyDockWidget(dock1, dock2)
+
+window.show()
+QTimer.singleShot(0, window.close)
+app.exec()
diff --git a/sources/pyside6/tests/QtWidgets/bug_836.py b/sources/pyside6/tests/QtWidgets/bug_836.py
new file mode 100644
index 000000000..c2d3d5609
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_836.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication, QFrame
+
+
+class Mixin1(object):
+ pass
+
+
+class Mixin2(object):
+ pass
+
+
+class Mixin3(object):
+ pass
+
+
+class MainWindow(Mixin1, Mixin2, Mixin3, QFrame):
+ def __init__(self):
+ super().__init__()
+
+
+def main():
+ app = QApplication([])
+ # if it doesn't crash it should pass
+ w = MainWindow()
+ w.show()
+ QTimer.singleShot(0, w.close)
+ app.exec()
+
+
+if __name__ == "__main__":
+ main()
+
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_844.py b/sources/pyside6/tests/QtWidgets/bug_844.py
new file mode 100644
index 000000000..913b4235c
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_844.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import sys
+import os
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtWidgets import QApplication, QLabel
+from PySide6.QtCore import QObject, QTimer
+
+
+class QtKeyPressListener(QObject):
+ def __init__(self, obj):
+ super().__init__()
+ obj.installEventFilter(self)
+
+ def eventFilter(self, obj, event):
+ # This used to crash here due to a misbehaviour of type discovery!
+ return QObject.eventFilter(self, obj, event)
+
+
+app = QApplication([])
+key_listener = QtKeyPressListener(app)
+w = QLabel('Hello')
+w.show()
+QTimer.singleShot(0, w.close)
+app.exec()
diff --git a/sources/pyside6/tests/QtWidgets/bug_854.py b/sources/pyside6/tests/QtWidgets/bug_854.py
new file mode 100644
index 000000000..1dbfd4b3a
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_854.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QTableView, QApplication
+from PySide6.QtCore import QAbstractItemModel, QModelIndex
+
+from helper.usesqapplication import UsesQApplication
+
+
+class VirtualList(QAbstractItemModel):
+ def __getitem__(self, index):
+ self._getItemCalled = True
+ pass
+
+ def rowCount(self, parent):
+ return 5000
+
+ def columnCount(self, parent):
+ return 3
+
+ def index(self, row, column, parent):
+ return self.createIndex(row, column)
+
+ def parent(self, index):
+ return QModelIndex()
+
+ def data(self, index, role):
+ row = index.row()
+ col = index.column()
+ return f"({row}, {col})"
+
+
+class TestQAbstractItemModel(UsesQApplication):
+ def testSetModel(self):
+ model = VirtualList()
+ model._getItemCalled = False
+ table = QTableView()
+ table.setModel(model)
+ table.show()
+ self.assertFalse(model._getItemCalled)
+
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_860.py b/sources/pyside6/tests/QtWidgets/bug_860.py
new file mode 100644
index 000000000..779feaa14
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_860.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QSignalMapper
+from PySide6.QtWidgets import QCheckBox
+
+from helper.usesqapplication import UsesQApplication
+
+
+class MultipleSlotTest(UsesQApplication):
+ def cb_changed(self, i):
+ self._changed = True
+
+ def cb_changedVoid(self):
+ self._changed = True
+
+ def testSignalMapper(self):
+ checkboxMapper = QSignalMapper()
+ box = QCheckBox('check me')
+ box.stateChanged.connect(checkboxMapper.map)
+
+ checkboxMapper.setMapping(box, box.text())
+ checkboxMapper.mappedString[str].connect(self.cb_changed)
+ self._changed = False
+ box.setChecked(True)
+ self.assertTrue(self._changed)
+
+ def testSimpleSignal(self):
+ box = QCheckBox('check me')
+ box.stateChanged[int].connect(self.cb_changedVoid)
+ self._changed = False
+ box.setChecked(True)
+ self.assertTrue(self._changed)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_862.py b/sources/pyside6/tests/QtWidgets/bug_862.py
new file mode 100644
index 000000000..49d9e24b2
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_862.py
@@ -0,0 +1,78 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+
+#
+# Test for bug 862, original description was:
+#
+# print seems to be broken at least for QGraphicsItems-derived objects. The
+# attached code shows:
+#
+# <__main__.MyQObject object at 0xf99f38>
+# <__main__.MyQWidget object at 0xf99f38>
+# <PySide.QtGui.MyQGraphicsObject (this = 0x11c0d60 , parent = 0x0 , pos =
+# QPointF(0, 0) , z = 0 , flags = ( ) ) at 0xf99f38>
+# <PySide.QtGui.QGraphicsItem (this = 0x11c2e60 , parent = 0x0 , pos = QPointF(0,
+# 0) , z = 0 , flags = ( ) ) at 0xf99f38>
+#
+# Where it should be showing something like:
+#
+# <__main__.MyQObject object at 0x7f55cf226c20>
+# <__main__.MyQWidget object at 0x7f55cf226c20>
+# <__main__.MyQGraphicsObject object at 0x7f55cf226c20>
+# <__main__.MyQGraphicsItem object at 0x7f55cf226c20>
+#
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtWidgets import QApplication, QGraphicsItem, QGraphicsWidget, QGraphicsObject, QWidget
+import PySide6.QtCore
+
+
+class MyQObject(QObject):
+ def __init__(self):
+ super().__init__()
+
+
+class MyQWidget(QWidget):
+ def __init__(self):
+ super().__init__()
+
+
+class MyQGraphicsObject(QGraphicsObject):
+ def __init__(self):
+ super().__init__()
+
+
+class MyQGraphicsItem(QGraphicsItem):
+ def __init__(self):
+ super().__init__()
+
+
+class TestRepr (unittest.TestCase):
+
+ def testIt(self):
+
+ app = QApplication([])
+
+ self.assertEqual("<__main__.MyQObject(0x", repr(MyQObject())[:22])
+ self.assertEqual("<__main__.MyQWidget(0x", repr(MyQWidget())[:22])
+ self.assertEqual("<__main__.MyQGraphicsObject(0x", repr(MyQGraphicsObject())[:30])
+ self.assertEqual("<__main__.MyQGraphicsItem(0x", repr(MyQGraphicsItem())[:28])
+
+ self.assertEqual("<PySide6.QtCore.QObject(0x", repr(QObject())[:26])
+ self.assertEqual("<PySide6.QtCore.QObject(0x", repr(PySide6.QtCore.QObject())[:26])
+ self.assertEqual("<PySide6.QtWidgets.QWidget(0x", repr(QWidget())[:29])
+ self.assertEqual("<PySide6.QtWidgets.QGraphicsWidget(0x", repr(QGraphicsWidget())[:37])
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_871.py b/sources/pyside6/tests/QtWidgets/bug_871.py
new file mode 100644
index 000000000..4ee9b575a
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_871.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtGui import QValidator, QIntValidator
+from PySide6.QtWidgets import QLineEdit
+
+'''Bug #871 - http://bugs.pyside.org/show_bug.cgi?id=871'''
+
+
+class BlankIntValidator(QIntValidator):
+ def validate(self, input, pos):
+ if input == '':
+ return QValidator.Acceptable, input, pos
+ else:
+ return QIntValidator.validate(self, input, pos)
+
+
+class Bug871Test(UsesQApplication):
+ def testWithoutValidator(self):
+ edit = QLineEdit()
+ self.assertEqual(edit.text(), '')
+ edit.insert('1')
+ self.assertEqual(edit.text(), '1')
+ edit.insert('a')
+ self.assertEqual(edit.text(), '1a')
+ edit.insert('2')
+ self.assertEqual(edit.text(), '1a2')
+
+ def testWithIntValidator(self):
+ edit = QLineEdit()
+ edit.setValidator(BlankIntValidator(edit))
+ self.assertEqual(edit.text(), '')
+ edit.insert('1')
+ self.assertEqual(edit.text(), '1')
+ edit.insert('a')
+ self.assertEqual(edit.text(), '1')
+ edit.insert('2')
+ self.assertEqual(edit.text(), '12')
+
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/bug_879.py b/sources/pyside6/tests/QtWidgets/bug_879.py
new file mode 100644
index 000000000..31c656543
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_879.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QTimer, QEvent, Qt
+from PySide6.QtWidgets import QApplication, QSpinBox
+from PySide6.QtGui import QKeyEvent
+
+
+class MySpinBox(QSpinBox):
+
+ def validate(self, text, pos):
+ return QSpinBox.validate(self, text, pos)
+
+
+class TestBug879 (unittest.TestCase):
+
+ def testIt(self):
+ app = QApplication([])
+ self.box = MySpinBox()
+ self.box.show()
+
+ QTimer.singleShot(0, self.sendKbdEvent)
+ QTimer.singleShot(100, app.quit)
+ app.exec()
+
+ self.assertEqual(self.box.text(), '0')
+
+ def sendKbdEvent(self):
+ ev = QKeyEvent(QEvent.KeyPress, Qt.Key_A, Qt.NoModifier, 'a')
+ QCoreApplication.sendEvent(self.box, ev)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_919.py b/sources/pyside6/tests/QtWidgets/bug_919.py
new file mode 100644
index 000000000..67387ed26
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_919.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.timedqapplication import TimedQApplication
+from PySide6.QtCore import Signal, QTimer
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import QPushButton, QStyleOptionButton, QApplication, QStyle
+
+
+class MyWidget(QPushButton):
+ def __init__(self, parent=None):
+ QPushButton.__init__(self, parent)
+ self._painted = False
+
+ def _emitPainted(self):
+ self.paintReceived.emit()
+
+ def paintEvent(self, e):
+ p = QPainter(self)
+ style = QApplication.style()
+ option = QStyleOptionButton()
+ style.drawControl(QStyle.CE_PushButton, option, p)
+ self._painted = True
+ QTimer.singleShot(0, self._emitPainted)
+
+ paintReceived = Signal()
+
+
+class TestBug919(TimedQApplication):
+ def setUp(self):
+ TimedQApplication.setUp(self, 2000)
+
+ def testFontInfo(self):
+ w = MyWidget()
+ w.paintReceived.connect(self.app.quit)
+ w.show()
+ self.app.exec()
+ self.assertTrue(w._painted)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_921.py b/sources/pyside6/tests/QtWidgets/bug_921.py
new file mode 100644
index 000000000..dafc1faef
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_921.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Qt
+from PySide6.QtWidgets import QMainWindow
+from helper.timedqapplication import TimedQApplication
+
+
+class Signaller(QObject):
+ s1 = Signal()
+ s2 = Signal()
+ s3 = Signal()
+
+
+class Window(object):
+
+ def __init__(self, s):
+ self._window = QMainWindow()
+ self._window.setAttribute(Qt.WA_DeleteOnClose, True)
+ self._window.setWindowTitle("Demo!")
+
+ self._s = s
+ self._s.s1.connect(self._on_signal)
+ self._s.s2.connect(self._on_signal)
+
+ def show(self):
+ self._window.show()
+
+ def _on_signal(self):
+ self._window.setWindowTitle("Signaled!")
+
+
+class TestTimedApp(TimedQApplication):
+ def testSignals(self):
+ s = Signaller()
+ w = Window(s)
+ w.show()
+
+ def midleFunction():
+ def internalFunction():
+ pass
+ s.s3.connect(internalFunction)
+
+ midleFunction()
+ self.app.exec()
+ del w
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ s.s1.emit()
+ s.s2.emit()
+ s.s3.emit()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_941.py b/sources/pyside6/tests/QtWidgets/bug_941.py
new file mode 100644
index 000000000..336aa2f58
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_941.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import QApplication, QHeaderView
+
+
+def foo(a, b):
+ pass
+
+
+class TestBug941 (unittest.TestCase):
+
+ def testIt(self):
+ app = QApplication([])
+ view = QHeaderView(Qt.Horizontal)
+ self.assertTrue(view.sortIndicatorChanged.connect(foo))
+ view.sortIndicatorChanged.emit(0, Qt.Vertical) # this can't raise an exception!
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_964.py b/sources/pyside6/tests/QtWidgets/bug_964.py
new file mode 100644
index 000000000..86bbddf16
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_964.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QStringListModel, Qt
+from PySide6.QtWidgets import QAbstractItemView, QApplication, QListView
+
+
+class TestBug964 (unittest.TestCase):
+
+ def testIt(self):
+ app = QApplication([])
+ model = QStringListModel(["1", "2"])
+ view = QListView()
+ view.setModel(model)
+ view.setCurrentIndex(model.index(0, 0))
+ newCursor = view.moveCursor(QAbstractItemView.MoveDown, Qt.NoModifier)
+ self.assertEqual(newCursor.row(), 1)
+ self.assertEqual(newCursor.column(), 0)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_967.py b/sources/pyside6/tests/QtWidgets/bug_967.py
new file mode 100644
index 000000000..03af030ca
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_967.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QComboBox
+
+
+class TestBug967 (unittest.TestCase):
+
+ def callback(self, arg):
+ self.arg = arg
+
+ def testIt(self):
+ self.arg = None
+ app = QApplication([])
+ obj = QComboBox()
+ obj.currentIndexChanged.connect(self.callback)
+ obj.currentIndexChanged.emit(5)
+ self.assertEqual(self.arg, 5)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_972.py b/sources/pyside6/tests/QtWidgets/bug_972.py
new file mode 100644
index 000000000..895cea128
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_972.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QSizeF
+from PySide6.QtWidgets import QGraphicsProxyWidget, QSizePolicy, QPushButton, QGraphicsScene, QGraphicsView
+
+from helper.timedqapplication import TimedQApplication
+
+
+def createItem(minimum, preferred, maximum, name):
+ w = QGraphicsProxyWidget()
+
+ w.setWidget(QPushButton(name))
+ w.setMinimumSize(minimum)
+ w.setPreferredSize(preferred)
+ w.setMaximumSize(maximum)
+ w.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+
+ return w
+
+
+class TestBug972 (TimedQApplication):
+
+ # Test if the function QGraphicsProxyWidget.setWidget have the correct behavior
+ def testIt(self):
+ scene = QGraphicsScene()
+
+ minSize = QSizeF(30, 100)
+ prefSize = QSizeF(210, 100)
+ maxSize = QSizeF(300, 100)
+
+ a = createItem(minSize, prefSize, maxSize, "A")
+ b = createItem(minSize, prefSize, maxSize, "B")
+ c = createItem(minSize, prefSize, maxSize, "C")
+ d = createItem(minSize, prefSize, maxSize, "D")
+
+ view = QGraphicsView(scene)
+ view.show()
+ self.app.exec()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_979.py b/sources/pyside6/tests/QtWidgets/bug_979.py
new file mode 100644
index 000000000..a6c17385e
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_979.py
@@ -0,0 +1,21 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtWidgets import QDialog
+from import_test import PysideImportTest2
+
+
+class PysideImportTest1(QDialog, PysideImportTest2):
+ pass
+
+
+if __name__ == '__main__':
+ quit()
diff --git a/sources/pyside6/tests/QtWidgets/bug_988.py b/sources/pyside6/tests/QtWidgets/bug_988.py
new file mode 100644
index 000000000..f82ba6d27
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_988.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QTabWidget
+
+
+class TestBug988 (unittest.TestCase):
+
+ def callback(self, arg):
+ self.arg = arg
+
+ def testIt(self):
+ self.arg = None
+ app = QApplication([])
+ obj = QTabWidget()
+ obj.currentChanged.connect(self.callback)
+ obj.currentChanged.emit(5)
+ self.assertEqual(self.arg, 5)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/bug_998.py b/sources/pyside6/tests/QtWidgets/bug_998.py
new file mode 100644
index 000000000..0f6311515
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/bug_998.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication
+
+
+class TestBug998 (unittest.TestCase):
+ def testNoFocusWindow(self):
+ widget = QApplication.focusWidget()
+ self.assertTrue(widget == None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/customproxywidget_test.py b/sources/pyside6/tests/QtWidgets/customproxywidget_test.py
new file mode 100644
index 000000000..f7a1a1b1d
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/customproxywidget_test.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import Qt, QTimer
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import QLabel
+from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem, QGraphicsProxyWidget
+
+
+class CustomProxy(QGraphicsProxyWidget):
+ def __init__(self, parent=None, wFlags=0):
+ QGraphicsProxyWidget.__init__(self, parent, wFlags)
+
+
+class CustomProxyWidgetTest(UsesQApplication):
+ def testCustomProxyWidget(self):
+ scene = QGraphicsScene()
+
+ proxy = CustomProxy(None, Qt.Window)
+ widget = QLabel('Widget')
+ proxy.setWidget(widget)
+ proxy.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
+ scene.addItem(proxy)
+ scene.setSceneRect(scene.itemsBoundingRect())
+
+ view = QGraphicsView(scene)
+ view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
+ view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
+ view.show()
+
+ timer = QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/grandparent_method_test.py b/sources/pyside6/tests/QtWidgets/grandparent_method_test.py
new file mode 100644
index 000000000..ef848e22d
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/grandparent_method_test.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Tests for calling methods further than the direct parent'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QPushButton, QWidget
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Dummy(QPushButton):
+
+ def show(self):
+ QWidget.show(self)
+ self.called = True
+
+
+class GrandParentMethod(UsesQApplication):
+ def testMethod(self):
+ obj = Dummy()
+ obj.show()
+ self.assertTrue(obj.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/hashabletype_test.py b/sources/pyside6/tests/QtWidgets/hashabletype_test.py
new file mode 100644
index 000000000..f12cceb5a
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/hashabletype_test.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for __hash__'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QTreeWidgetItem
+from helper.usesqapplication import UsesQApplication
+
+
+class HashableTest(UsesQApplication):
+
+ def testQTreeWidgetItemHash(self):
+ h = {}
+ obj = QTreeWidgetItem()
+ h[obj] = 2
+ self.assertTrue(h.get(obj), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/import_test.py b/sources/pyside6/tests/QtWidgets/import_test.py
new file mode 100644
index 000000000..0b60241f0
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/import_test.py
@@ -0,0 +1,2 @@
+class PysideImportTest2(object):
+ pass
diff --git a/sources/pyside6/tests/QtWidgets/keep_reference_test.py b/sources/pyside6/tests/QtWidgets/keep_reference_test.py
new file mode 100644
index 000000000..9d21c4580
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/keep_reference_test.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QAbstractTableModel
+from PySide6.QtWidgets import QTableView
+
+
+class TestModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ QAbstractTableModel.__init__(self, parent)
+
+ def rowCount(self, parent):
+ return 0
+
+ def columnCount(self, parent):
+ return 0
+
+ def data(self, index, role):
+ return None
+
+
+class KeepReferenceTest(UsesQApplication):
+
+ def testModelWithoutParent(self):
+ view = QTableView()
+ model = TestModel()
+ view.setModel(model)
+ samemodel = view.model()
+ self.assertEqual(model, samemodel)
+
+ def testModelWithParent(self):
+ view = QTableView()
+ model = TestModel(None)
+ view.setModel(model)
+ samemodel = view.model()
+ self.assertEqual(model, samemodel)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceCounting(self):
+ '''Tests reference count of model object referred by view objects.'''
+ model1 = TestModel()
+ refcount1 = sys.getrefcount(model1)
+ view1 = QTableView()
+ view1.setModel(model1)
+ self.assertEqual(sys.getrefcount(view1.model()), refcount1 + 1)
+
+ view2 = QTableView()
+ view2.setModel(model1)
+ self.assertEqual(sys.getrefcount(view2.model()), refcount1 + 2)
+
+ model2 = TestModel()
+ view2.setModel(model2)
+ self.assertEqual(sys.getrefcount(view1.model()), refcount1 + 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceCountingWhenDeletingReferrer(self):
+ '''Tests reference count of model object referred by deceased view object.'''
+ model = TestModel()
+ refcount1 = sys.getrefcount(model)
+ view = QTableView()
+ view.setModel(model)
+ self.assertEqual(sys.getrefcount(view.model()), refcount1 + 1)
+
+ del view
+ self.assertEqual(sys.getrefcount(model), refcount1)
+
+ def testReferreedObjectSurvivalAfterContextEnd(self):
+ '''Model object assigned to a view object must survive after getting out of context.'''
+ def createModelAndSetToView(view):
+ model = TestModel()
+ model.setObjectName('created model')
+ view.setModel(model)
+ view = QTableView()
+ createModelAndSetToView(view)
+ model = view.model()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/missing_symbols_test.py b/sources/pyside6/tests/QtWidgets/missing_symbols_test.py
new file mode 100644
index 000000000..076c9e7e1
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/missing_symbols_test.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''(Very) Simple test case for missing names from QtGui and QtWidgets'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6 import QtGui
+from PySide6 import QtWidgets
+
+
+class MissingClasses(unittest.TestCase):
+ def testQDrag(self): # Bug 222
+ getattr(QtGui, 'QDrag')
+
+ def testQDropEvent(self): # Bug 255
+ getattr(QtGui, 'QDropEvent')
+
+
+class MissingMembers(unittest.TestCase):
+
+ def testQFontMetricsSize(self): # Bug 223
+ QtGui.QFontMetrics.size
+
+ def testQLayoutSetSpacing(self): # Bug 231
+ QtWidgets.QLayout.setSpacing
+
+ def testQImageLoad(self): # Bug 257
+ QtGui.QImage.load
+
+ def testQStandardItemModelinsertRow(self): # Bug 227
+ QtGui.QStandardItemModel.insertRow
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/paint_event_test.py b/sources/pyside6/tests/QtWidgets/paint_event_test.py
new file mode 100644
index 000000000..d995c2a37
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/paint_event_test.py
@@ -0,0 +1,68 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test paint event override in python'''
+
+import gc
+import os
+import sys
+import unittest
+
+from textwrap import dedent
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication, QWidget
+
+from helper.usesqapplication import UsesQApplication
+
+
+class MyWidget(QWidget):
+ '''Sample widget'''
+
+ def __init__(self, app):
+ # Creates a new widget
+ assert (app)
+
+ super().__init__()
+ self.app = app
+ self.paint_event_called = False
+
+ def paintEvent(self, event):
+ # Empty paint event method
+ super().paintEvent(event)
+ self.paint_event_called = True
+ QTimer.singleShot(20, self.close)
+
+
+class PaintEventOverride(UsesQApplication):
+ '''Test case for overriding QWidget.paintEvent'''
+
+ qapplication = True
+
+ def setUp(self):
+ # Acquire resources
+ super(PaintEventOverride, self).setUp()
+ self.widget = MyWidget(self.app)
+
+ def tearDown(self):
+ # Release resources
+ del self.widget
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(PaintEventOverride, self).tearDown()
+
+ def testPaintEvent(self):
+ # Test QWidget.paintEvent override
+ self.widget.show()
+ self.widget.setWindowTitle("paint_event_test")
+ self.app.exec()
+ self.assertTrue(self.widget.paint_event_called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/parent_method_test.py b/sources/pyside6/tests/QtWidgets/parent_method_test.py
new file mode 100644
index 000000000..0ab09eead
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/parent_method_test.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimer, QThread
+from PySide6.QtWidgets import QTableView, QWidget
+
+
+class Foo(QTableView):
+ def __init__(self, parent=None):
+ QTableView.__init__(self, parent)
+
+
+from helper.usesqapplication import UsesQApplication
+
+
+class TestParentType(UsesQApplication):
+
+ def testParentType(self):
+ # Test the problem with calling QObject.parent from a QWidget
+ # when the parent is a python class derived from a QWidget-derived
+ # class. The method was returning the last C++ class in the hierarchy
+ parent = Foo()
+ w2 = QWidget(parent)
+ self.assertTrue(isinstance(w2.parentWidget(), Foo))
+ self.assertTrue(isinstance(w2.parent(), Foo))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/private_mangle_test.py b/sources/pyside6/tests/QtWidgets/private_mangle_test.py
new file mode 100644
index 000000000..67ad14d68
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/private_mangle_test.py
@@ -0,0 +1,94 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+This is the example from https://bugreports.qt.io/browse/PYSIDE-772
+with no interaction as a unittest.
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Signal
+from PySide6.QtWidgets import QApplication, QWidget
+from PySide6 import QtWidgets
+
+
+class Harness(QWidget):
+ clicked = Signal()
+
+ def __init__(self):
+ super().__init__()
+ self.clicked.connect(self.method)
+ self.clicked.connect(self._method)
+ self.clicked.connect(self.__method)
+
+ def method(self): # Public method
+ self.method_result = self.sender()
+
+ def _method(self): # Private method
+ self.method__result = self.sender()
+
+ def __method(self): # Name mangled method
+ self.method___result = self.sender()
+
+
+class _Under(QWidget):
+ clicked = Signal()
+
+ def __init__(self):
+ super().__init__()
+ self.clicked.connect(self.method)
+ self.clicked.connect(self._method)
+ self.clicked.connect(self.__method)
+
+ def method(self): # Public method
+ self.method_result = self.sender()
+
+ def _method(self): # Private method
+ self.method__result = self.sender()
+
+ def __method(self): # Name mangled method
+ self.method___result = self.sender()
+
+
+class TestMangle(unittest.TestCase):
+
+ def setUp(self):
+ QApplication()
+
+ def tearDown(self):
+ qApp.shutdown()
+
+ def testPrivateMangle(self):
+ harness = Harness()
+ harness.clicked.emit()
+ self.assertEqual(harness.method_result, harness)
+ self.assertEqual(harness.method__result, harness)
+ self.assertEqual(harness.method___result, harness)
+ self.assertTrue("method" in type(harness).__dict__)
+ self.assertTrue("_method" in type(harness).__dict__)
+ self.assertFalse("__method" in type(harness).__dict__)
+ self.assertTrue("_Harness__method" in type(harness).__dict__)
+
+ def testPrivateMangleUnder(self):
+ harness = _Under()
+ harness.clicked.emit()
+ self.assertEqual(harness.method_result, harness)
+ self.assertEqual(harness.method__result, harness)
+ self.assertEqual(harness.method___result, harness)
+ # make sure that we skipped over the underscore in "_Under"
+ self.assertTrue("method" in type(harness).__dict__)
+ self.assertTrue("_method" in type(harness).__dict__)
+ self.assertFalse("__method" in type(harness).__dict__)
+ self.assertTrue("_Under__method" in type(harness).__dict__)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/python_properties_test.py b/sources/pyside6/tests/QtWidgets/python_properties_test.py
new file mode 100644
index 000000000..ee8a38014
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/python_properties_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QLocale
+from PySide6.QtWidgets import QGraphicsItem, QStyleOptionViewItem
+
+
+class Properties(unittest.TestCase):
+
+ def testStaticProperty(self):
+ self.assertEqual(QGraphicsItem.UserType, 65536)
+
+ def testInstanceProperty(self):
+ p = QStyleOptionViewItem()
+ self.assertTrue(isinstance(p.locale, QLocale))
+
+ # PSYIDE-304, can assign to a "const QWidget *" field
+ p.widget = None
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qabstracttextdocumentlayout_test.py b/sources/pyside6/tests/QtWidgets/qabstracttextdocumentlayout_test.py
new file mode 100644
index 000000000..1ae3b0a35
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qabstracttextdocumentlayout_test.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QSizeF, QTimer
+from PySide6.QtGui import QTextFormat, QTextCharFormat, QPyTextObject
+from PySide6.QtWidgets import QTextEdit
+from helper.usesqapplication import UsesQApplication
+
+
+class Foo(QPyTextObject):
+ called = False
+
+ def intrinsicSize(self, doc, posInDocument, format):
+ Foo.called = True
+ return QSizeF(10, 10)
+
+ def drawObject(self, painter, rect, doc, posInDocument, format):
+ pass
+
+
+class QAbstractTextDocumentLayoutTest(UsesQApplication):
+
+ objectType = QTextFormat.UserObject + 1
+
+ def foo(self):
+ fmt = QTextCharFormat()
+ fmt.setObjectType(QAbstractTextDocumentLayoutTest.objectType)
+
+ cursor = self.textEdit.textCursor()
+ cursor.insertText(chr(0xfffc), fmt)
+ self.textEdit.setTextCursor(cursor)
+ self.textEdit.close()
+
+ def testIt(self):
+
+ self.textEdit = QTextEdit()
+ self.textEdit.show()
+
+ interface = Foo()
+ self.textEdit.document().documentLayout().registerHandler(QAbstractTextDocumentLayoutTest.objectType, interface)
+
+ QTimer.singleShot(0, self.foo)
+ self.app.exec()
+
+ self.assertTrue(Foo.called)
+
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qaccessible_test.py b/sources/pyside6/tests/QtWidgets/qaccessible_test.py
new file mode 100644
index 000000000..021cf9c6b
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qaccessible_test.py
@@ -0,0 +1,138 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QAccessible::installFactory().'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, Qt
+from PySide6.QtGui import QAccessible, QAccessibleInterface, QColor
+from PySide6.QtWidgets import QWidget, QLineEdit, QVBoxLayout
+
+from helper.usesqapplication import UsesQApplication
+
+
+class LineEditAccessible(QAccessibleInterface):
+ """Mimick a QAccessibleInterface implementation for QLineEdit."""
+
+ instance_count = 0
+
+ def __init__(self, widget):
+ super().__init__()
+ LineEditAccessible.instance_count += 1
+ self._widget = widget
+ self._name = self._widget.objectName()
+ print('LineEditAccessible', self._name)
+
+ def __del__(self):
+ LineEditAccessible.instance_count -= 1
+ print('~LineEditAccessible', self._name)
+
+ def actionInterface(self):
+ return None
+
+ def backgroundColor(self):
+ return QColor(Qt.white)
+
+ def child(self, index):
+ return None
+
+ def childAt(self, x, y):
+ return None
+
+ def childCount(self):
+ return 0
+
+ def focusChild(self):
+ return None
+
+ def foregroundColor(self):
+ return QColor(Qt.black)
+
+ def indexOfChild(self, child):
+ return -1
+
+ def isValid(self):
+ return True
+
+ def object(self):
+ return self._widget
+
+ def parent(self):
+ return None
+
+ def rect(self):
+ return self._widget.geometry()
+
+ def role(self):
+ return QAccessible.EditableText
+
+ def setText(self, t, text):
+ pass
+
+ def state(self):
+ return QAccessible.State()
+
+ def tableCellInterface(self):
+ return None
+
+ def tableInterface(self):
+ return None
+
+ def text(self, t):
+ return self._widget.text() if t == QAccessible.Value else ''
+
+ def textInterface(self):
+ return None
+
+ def valueInterface(self):
+ return None
+
+ def window(self):
+ return self._widget.window().windowHandle()
+
+
+def accessible_factory(key, obj):
+ """Factory function for QAccessibleInterface for QLineEdit's."""
+ if obj.metaObject().className() == 'QLineEdit':
+ return LineEditAccessible(obj)
+ return None
+
+
+class Window(QWidget):
+ """Test window with 2 QLineEdit's."""
+ def __init__(self):
+ super().__init__()
+ self.setObjectName('top')
+ layout = QVBoxLayout(self)
+ self.m_line_edit1 = QLineEdit("bla")
+ layout.addWidget(self.m_line_edit1)
+ self.m_line_edit2 = QLineEdit("bla")
+ layout.addWidget(self.m_line_edit2)
+
+
+class QAccessibleTest(UsesQApplication):
+ """Test that LineEditAccessible instances are created for QLineEdit's."""
+
+ def setUp(self):
+ super().setUp()
+ QAccessible.installFactory(accessible_factory)
+ window = Window()
+
+ def testLineEdits(self):
+ window = Window()
+ window.show()
+ while not window.windowHandle().isExposed():
+ QCoreApplication.processEvents()
+ self.assertEqual(LineEditAccessible.instance_count, 2)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qaction_test.py b/sources/pyside6/tests/QtWidgets/qaction_test.py
new file mode 100644
index 000000000..a0049421f
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qaction_test.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QAction
+from PySide6.QtWidgets import QWidget, QMenu
+from helper.usesqapplication import UsesQApplication
+
+
+class QPainterDrawText(UsesQApplication):
+
+ def _cb(self):
+ self._called = True
+
+ def testSignal(self):
+ o = QWidget()
+ act = QAction(o)
+ self._called = False
+ act.triggered.connect(self._cb)
+ act.trigger()
+ self.assertTrue(self._called)
+
+ def testNewCtor(self):
+ o = QWidget()
+ self._called = False
+ myAction = QAction("&Quit", o, triggered=self._cb)
+ myAction.trigger()
+ self.assertTrue(self._called)
+
+
+class SetShortcutTest(UsesQApplication):
+
+ def testSetShortcut(self):
+ # Somehow an exception was leaking from the constructor
+ # and appearing in setShortcut.
+ o = QWidget()
+ action = QAction('aaaa', o)
+ shortcut = 'Ctrl+N'
+ action.setShortcut(shortcut)
+ s2 = action.shortcut()
+ self.assertEqual(s2, shortcut)
+
+ def testMenu(self):
+ # Test the setMenu()/menu() old functionality removed in Qt6
+ # that was added via helper functions.
+ menu = QMenu("menu")
+ action = QAction("action")
+
+ # Using QAction::setMenu(QObject*)
+ action.setMenu(menu)
+
+ self.assertEqual(action.menu(), menu)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qapp_issue_585.py b/sources/pyside6/tests/QtWidgets/qapp_issue_585.py
new file mode 100644
index 000000000..0b5453af5
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qapp_issue_585.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+The bug was caused by this commit:
+"Support the qApp macro correctly, final version incl. debug"
+e30e0c161b2b4d50484314bf006e9e5e8ff6b380
+2017-10-27
+
+The bug was first solved by this commit:
+"Fix qApp macro refcount"
+b811c874dedd14fd8b072bc73761d39255216073
+2018-03-21
+
+This test triggers the refcounting bug of qApp, issue PYSIDE-585.
+Finally, the real patch included more changes, because another error
+was in the ordering of shutdown calls. It was found using the following
+Python configuration:
+
+ In Python 3.6 create a directory 'debug' and cd into it.
+
+ ../configure --with-pydebug --prefix=$HOME/pydebug/ --enable-shared
+
+Then a lot more refcounting errors show up, which are due to a bug in
+the code position of the shutdown procedure.
+The reason for the initial refcount bug was that the shutdown code is once
+more often called than the creation of the qApp wrapper.
+Finally, it was easiest and more intuitive to simply make the refcount of
+qApp_content equal to that of Py_None, which is also not supposed to be
+garbage-collected.
+
+For some reason, the test does not work as a unittest because it creates
+no crash. We leave it this way.
+"""
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication
+
+
+app_instance = QApplication([])
+# If the following line is commented, application doesn't crash on exit anymore.
+app_instance2 = app_instance
+QTimer.singleShot(0, qApp.quit)
+app_instance.exec_()
diff --git a/sources/pyside6/tests/QtWidgets/qapp_test.py b/sources/pyside6/tests/QtWidgets/qapp_test.py
new file mode 100644
index 000000000..5a66b8e33
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qapp_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test the presence of qApp Macro'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication
+
+
+class QAppPresence(unittest.TestCase):
+
+ def testQApp(self):
+ # QtGui.qApp variable is instance of QApplication
+ self.assertTrue(isinstance(qApp, QApplication))
+
+
+def main():
+ app = QApplication([])
+ unittest.main()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/sources/pyside6/tests/QtWidgets/qapplication_exit_segfault_test.py b/sources/pyside6/tests/QtWidgets/qapplication_exit_segfault_test.py
new file mode 100644
index 000000000..8bb47bc1c
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qapplication_exit_segfault_test.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QSpinBox
+
+
+class QApplicationDelete(unittest.TestCase):
+ '''Test for segfault when deleting a QApplication before a QWidget'''
+
+ def testQPushButton(self):
+ # QApplication deleted before QPushButton
+ a = QApplication([])
+ b = QPushButton('aaaa')
+ del a
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qapplication_test.py b/sources/pyside6/tests/QtWidgets/qapplication_test.py
new file mode 100644
index 000000000..7c5b61fd9
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qapplication_test.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication
+
+
+class TestQApplication(unittest.TestCase):
+ def testNoArguments(self):
+ app = QApplication()
+ self.assertIsInstance(app, QApplication)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qcolormap_test.py b/sources/pyside6/tests/QtWidgets/qcolormap_test.py
new file mode 100644
index 000000000..f63a9486f
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qcolormap_test.py
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QColormap
+from helper.usesqapplication import UsesQApplication
+
+
+class QColormapTest(UsesQApplication):
+
+ def testQColormap(self):
+ qc = QColormap.instance()
+ self.assertEqual(qc.size(), -1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qdialog_test.py b/sources/pyside6/tests/QtWidgets/qdialog_test.py
new file mode 100644
index 000000000..cb85ce7e2
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qdialog_test.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Slot, QTimer
+from PySide6.QtWidgets import QDialog, QMainWindow
+from helper.timedqapplication import TimedQApplication
+
+
+class Window(QMainWindow):
+ def __init__(self):
+ super().__init__()
+ self.setWindowTitle("Main")
+ self.dialog = None
+
+ @Slot()
+ def execDialog(self):
+ dialog = QDialog(self)
+ self.dialog = weakref.ref(dialog)
+ dialog.setWindowTitle("Dialog")
+ dialog.setMinimumWidth(200)
+ QTimer.singleShot(500, dialog.reject)
+ dialog.exec()
+ self.close()
+
+
+class DialogExecTest(TimedQApplication):
+ """Test whether the parent-child relationship (dialog/main window) is removed when
+ using QDialog.exec() (instead show()), preventing the dialog from leaking."""
+
+ def setUp(self):
+ super().setUp(10000)
+ self._window = Window()
+
+ def testExec(self):
+ self._window.show()
+ QTimer.singleShot(500, self._window.execDialog)
+ self.app.exec()
+ self.assertTrue(self._window.dialog() is None)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qdynamic_signal.py b/sources/pyside6/tests/QtWidgets/qdynamic_signal.py
new file mode 100644
index 000000000..83d6af383
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qdynamic_signal.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtWidgets import QInputDialog
+
+from helper.usesqapplication import UsesQApplication
+
+
+class DynamicSignalTest(UsesQApplication):
+
+ def cb(self, obj):
+ self._called = True
+
+ def testQDialog(self):
+ dlg = QInputDialog()
+ dlg.setInputMode(QInputDialog.TextInput)
+ lst = dlg.children()
+ self.assertTrue(len(lst))
+ obj = lst[0]
+ self._called = False
+ obj.destroyed[QObject].connect(self.cb)
+ obj = None
+ del dlg
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self._called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qfontdialog_test.py b/sources/pyside6/tests/QtWidgets/qfontdialog_test.py
new file mode 100644
index 000000000..764329732
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qfontdialog_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QFont
+from PySide6.QtWidgets import QFontDialog
+from helper.timedqapplication import TimedQApplication
+
+
+class TestFontDialog(TimedQApplication):
+
+ def testGetFont(self):
+ QFontDialog.getFont()
+
+ def testGetFontQDialog(self):
+ QFontDialog.getFont(QFont("FreeSans", 10))
+
+ def testGetFontQDialogQString(self):
+ QFontDialog.getFont(QFont("FreeSans", 10), None, "Select font")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qformlayout_test.py b/sources/pyside6/tests/QtWidgets/qformlayout_test.py
new file mode 100644
index 000000000..f87ea6935
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qformlayout_test.py
@@ -0,0 +1,99 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QFormLayout, QWidget, QLabel, QMainWindow
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QFormLayoutTest(UsesQApplication):
+
+ def testGetItemPosition(self):
+ formlayout = QFormLayout()
+
+ row, role = formlayout.getItemPosition(0)
+ self.assertTrue(isinstance(row, int))
+ self.assertTrue(isinstance(role, QFormLayout.ItemRole))
+ self.assertEqual(row, -1)
+
+ widget = QWidget()
+ formlayout.addRow(widget)
+ row, role = formlayout.getItemPosition(0)
+ self.assertTrue(isinstance(row, int))
+ self.assertTrue(isinstance(role, QFormLayout.ItemRole))
+ self.assertEqual(row, 0)
+ self.assertEqual(role, QFormLayout.SpanningRole)
+
+ def testGetWidgetPosition(self):
+ formlayout = QFormLayout()
+ widget = QWidget()
+
+ row, role = formlayout.getWidgetPosition(widget)
+ self.assertTrue(isinstance(row, int))
+ self.assertTrue(isinstance(role, QFormLayout.ItemRole))
+ self.assertEqual(row, -1)
+
+ formlayout.addRow(widget)
+ row, role = formlayout.getWidgetPosition(widget)
+ self.assertTrue(isinstance(row, int))
+ self.assertTrue(isinstance(role, QFormLayout.ItemRole))
+ self.assertEqual(row, 0)
+ self.assertEqual(role, QFormLayout.SpanningRole)
+
+ def testGetLayoutPosition(self):
+ formlayout = QFormLayout()
+ layout = QFormLayout()
+
+ row, role = formlayout.getLayoutPosition(layout)
+ self.assertTrue(isinstance(row, int))
+ self.assertTrue(isinstance(role, QFormLayout.ItemRole))
+ self.assertEqual(row, -1)
+
+ formlayout.addRow(layout)
+ row, role = formlayout.getLayoutPosition(layout)
+ self.assertTrue(isinstance(row, int))
+ self.assertTrue(isinstance(role, QFormLayout.ItemRole))
+ self.assertEqual(row, 0)
+ self.assertEqual(role, QFormLayout.SpanningRole)
+
+ def testTakeRow(self):
+ window = QMainWindow()
+ window.setCentralWidget(QWidget())
+ formlayout = QFormLayout(window.centralWidget())
+
+ widget_label = "blub"
+ widget = QLabel(widget_label)
+
+ self.assertEqual(formlayout.count(), 0)
+ formlayout.addRow(widget)
+ self.assertEqual(formlayout.count(), 1)
+ self.assertEqual(formlayout.itemAt(0).widget(), widget)
+
+ widget_id = id(widget)
+
+ # Now there are no more references to the original widget on the
+ # Python side. Assert that this does not break the references to
+ # the widget on the C++ side so that "taking" the row will work.
+ del widget
+
+ takeRowResult = formlayout.takeRow(0)
+ self.assertEqual(formlayout.count(), 0)
+
+ widget = takeRowResult.fieldItem.widget()
+
+ self.assertIsNotNone(widget)
+ self.assertEqual(widget_id, id(widget))
+ self.assertEqual(widget.text(), widget_label)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qgraphicsitem_isblocked_test.py b/sources/pyside6/tests/QtWidgets/qgraphicsitem_isblocked_test.py
new file mode 100644
index 000000000..cb4115b55
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qgraphicsitem_isblocked_test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QRectF
+from PySide6.QtWidgets import QGraphicsItem
+from PySide6.QtGui import QColor
+from helper.usesqapplication import UsesQApplication
+
+
+class Item(QGraphicsItem):
+
+ def __init__(self):
+ super().__init__()
+
+ def boundingRect(self):
+ return QRectF(0, 0, 100, 100)
+
+ def paint(self, painter, option, widget):
+ painter.setBrush(QColor(255, 255, 255))
+ painter.drawRect(0, 0, 100, 100)
+
+
+class QGraphicsViewIsBlockedTest(UsesQApplication):
+
+ def testIsBlockedByModalPanel(self):
+ (first, second) = Item().isBlockedByModalPanel()
+ self.assertFalse(first)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qgraphicsitem_test.py b/sources/pyside6/tests/QtWidgets/qgraphicsitem_test.py
new file mode 100644
index 000000000..1114ad4fe
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qgraphicsitem_test.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test cases related to QGraphicsItem and subclasses'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QPolygonF, QColor, QBrush
+from PySide6.QtWidgets import QGraphicsScene
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QColorOnSetBrush(UsesQApplication):
+ '''Test case for passing a QColor directly to setBrush'''
+
+ def setUp(self):
+ # Acquire resources
+ super(QColorOnSetBrush, self).setUp()
+
+ self.scene = QGraphicsScene()
+ poly = QPolygonF()
+ self.item = self.scene.addPolygon(poly)
+ self.color = QColor('black')
+
+ def tearDown(self):
+ # Release resources
+ del self.color
+ del self.item
+ del self.scene
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QColorOnSetBrush, self).tearDown()
+
+ def testQColor(self):
+ # QGraphicsAbstractShapeItem.setBrush(QColor)
+ self.item.setBrush(self.color)
+ self.assertEqual(QBrush(self.color), self.item.brush())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qgraphicsobjectreimpl_test.py b/sources/pyside6/tests/QtWidgets/qgraphicsobjectreimpl_test.py
new file mode 100644
index 000000000..a3d28b4d3
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qgraphicsobjectreimpl_test.py
@@ -0,0 +1,62 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test cases related to QGraphicsItem and subclasses'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QGraphicsObject, QGraphicsWidget
+from PySide6.QtCore import QRectF
+
+from helper.usesqapplication import UsesQApplication
+
+
+class GObjA(QGraphicsObject):
+ def paint(self, *args):
+ pass
+
+ def boundingRect(self):
+ return QRectF()
+
+ def itemChange(self, *args):
+ return QGraphicsObject.itemChange(self, *args)
+
+
+class GObjB(QGraphicsObject):
+ def paint(self, *args):
+ pass
+
+ def boundingRect(self):
+ return QRectF()
+
+
+class QGraphicsObjectReimpl(UsesQApplication):
+ '''Test case for reimplementing QGraphicsObject'''
+
+ def testReimplementationTypes(self):
+ w = QGraphicsWidget()
+
+ # PYSIDE-86:
+ # This case failed because GObjA was reimplementing
+ # the method itemChange() from QGraphicsItem,
+ # and then the QVariant was not associated with
+ # a QGraphicsItem but a QObjectItem because the base
+ # class was a QObject.
+ gobjA = GObjA()
+ gobjA.setParentItem(w)
+ self.assertIs(type(w), type(gobjA.parentItem()))
+
+ gobjB = GObjB()
+ gobjB.setParentItem(w)
+ self.assertIs(type(w), type(gobjB.parentItem()))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qgraphicsproxywidget_test.py b/sources/pyside6/tests/QtWidgets/qgraphicsproxywidget_test.py
new file mode 100644
index 000000000..dee616bbe
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qgraphicsproxywidget_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import Qt, QTimer
+from PySide6.QtGui import QPainter
+from PySide6.QtWidgets import QLabel
+from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem, QGraphicsProxyWidget
+
+
+class QGraphicsProxyWidgetTest(UsesQApplication):
+ def testQGraphicsProxyWidget(self):
+ scene = QGraphicsScene()
+
+ proxy = QGraphicsProxyWidget(None, Qt.Window)
+ widget = QLabel('Widget')
+ proxy.setWidget(widget)
+ proxy.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
+ scene.addItem(proxy)
+ scene.setSceneRect(scene.itemsBoundingRect())
+
+ view = QGraphicsView(scene)
+ view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
+ view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
+ view.show()
+
+ timer = QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qgraphicsscene_test.py b/sources/pyside6/tests/QtWidgets/qgraphicsscene_test.py
new file mode 100644
index 000000000..86604f27b
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qgraphicsscene_test.py
@@ -0,0 +1,213 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Basic test cases for QGraphicsScene'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QPointF
+from PySide6.QtGui import QPolygonF, QPixmap, QPainterPath, QTransform, QWindow
+from PySide6.QtWidgets import QApplication, QPushButton
+from PySide6.QtWidgets import QGraphicsScene
+from PySide6.QtWidgets import QGraphicsEllipseItem, QGraphicsLineItem
+from PySide6.QtWidgets import QGraphicsPathItem, QGraphicsPixmapItem
+from PySide6.QtWidgets import QGraphicsPolygonItem, QGraphicsRectItem
+from PySide6.QtWidgets import QGraphicsSimpleTextItem, QGraphicsTextItem
+from PySide6.QtWidgets import QGraphicsProxyWidget, QGraphicsView
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Constructor(unittest.TestCase):
+ '''QGraphicsScene constructor'''
+
+ def testConstructor(self):
+ # QGraphicsScene constructor
+ obj = QGraphicsScene()
+ self.assertTrue(isinstance(obj, QGraphicsScene))
+
+# Test for PYSIDE-868: Test whether painter.device() can be accessed
+# correctly. This was crashing when the underlying QPaintDevice was a
+# QWidget due to handling multiple inheritance incorrectly.
+
+
+class CustomScene(QGraphicsScene):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.dpi = 0
+
+ def drawBackground(self, painter, rect):
+ self.dpi = painter.device().physicalDpiX()
+
+ def drawForeground(self, painter, rect):
+ self.dpi = painter.device().physicalDpiX()
+
+
+class ConstructorWithRect(unittest.TestCase):
+ '''QGraphicsScene qrect constructor and related sizes'''
+
+ def setUp(self):
+ # Acquire resources
+ # PyQt4 doesn't accept a QRect as argument to constructor
+ self.scene = QGraphicsScene(0, 200, 150, 175)
+
+ def tearDown(self):
+ # Release resources
+ del self.scene
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testHeight(self):
+ # QGraphicsScene.height()
+ self.assertEqual(self.scene.height(), 175)
+
+ def testWidth(self):
+ # QGraphicsScene.width()
+ self.assertEqual(self.scene.width(), 150)
+
+
+class AddItem(UsesQApplication):
+ '''Tests for QGraphicsScene.add*'''
+
+ qapplication = True
+
+ def setUp(self):
+ # Acquire resources
+ super(AddItem, self).setUp()
+ self.scene = QGraphicsScene()
+ # While the scene does not inherits from QWidget, requires
+ # an application to make the internals work.
+
+ def tearDown(self):
+ # Release resources
+ del self.scene
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(AddItem, self).tearDown()
+
+ def testEllipse(self):
+ # QGraphicsScene.addEllipse
+ item = self.scene.addEllipse(100, 100, 100, 100)
+ self.assertTrue(isinstance(item, QGraphicsEllipseItem))
+
+ def testLine(self):
+ # QGraphicsScene.addLine
+ item = self.scene.addLine(100, 100, 200, 200)
+ self.assertTrue(isinstance(item, QGraphicsLineItem))
+
+ def testPath(self):
+ # QGraphicsScene.addPath
+ item = self.scene.addPath(QPainterPath())
+ self.assertTrue(isinstance(item, QGraphicsPathItem))
+
+ def testPixmap(self):
+ # QGraphicsScene.addPixmap
+ item = self.scene.addPixmap(QPixmap())
+ self.assertTrue(isinstance(item, QGraphicsPixmapItem))
+
+ def testPolygon(self):
+ # QGraphicsScene.addPolygon
+ points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)]
+ item = self.scene.addPolygon(QPolygonF(points))
+ self.assertTrue(isinstance(item, QGraphicsPolygonItem))
+
+ def testRect(self):
+ # QGraphicsScene.addRect
+ item = self.scene.addRect(100, 100, 100, 100)
+ self.assertTrue(isinstance(item, QGraphicsRectItem))
+
+ def testSimpleText(self):
+ # QGraphicsScene.addSimpleText
+ item = self.scene.addSimpleText('Monty Python 42')
+ self.assertTrue(isinstance(item, QGraphicsSimpleTextItem))
+
+ def testText(self):
+ # QGraphicsScene.addText
+ item = self.scene.addText('Monty Python 42')
+ self.assertTrue(isinstance(item, QGraphicsTextItem))
+
+ def testWidget(self):
+ # QGraphicsScene.addWidget
+ # XXX: printing some X11 error when using under PyQt4
+ item = self.scene.addWidget(QPushButton())
+ self.assertTrue(isinstance(item, QGraphicsProxyWidget))
+
+
+class ItemRetrieve(UsesQApplication):
+ '''Tests for QGraphicsScene item retrieval methods'''
+
+ qapplication = True
+
+ def setUp(self):
+ # Acquire resources
+ super(ItemRetrieve, self).setUp()
+ self.scene = QGraphicsScene()
+
+ self.topleft = QGraphicsRectItem(0, 0, 100, 100)
+ self.topright = QGraphicsRectItem(100, 0, 100, 100)
+ self.bottomleft = QGraphicsRectItem(0, 100, 100, 100)
+ self.bottomright = QGraphicsRectItem(100, 100, 100, 100)
+
+ self.items = [self.topleft, self.topright, self.bottomleft,
+ self.bottomright]
+
+ for item in self.items:
+ self.scene.addItem(item)
+
+ def tearDown(self):
+ # Release resources
+ del self.scene
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(ItemRetrieve, self).tearDown()
+
+ def testItems(self):
+ # QGraphicsScene.items()
+ items = self.scene.items()
+ for i in items:
+ self.assertTrue(i in self.items)
+
+ def testItemAt(self):
+ # QGraphicsScene.itemAt()
+ self.assertEqual(self.scene.itemAt(50, 50, QTransform()), self.topleft)
+ self.assertEqual(self.scene.itemAt(150, 50, QTransform()), self.topright)
+ self.assertEqual(self.scene.itemAt(50, 150, QTransform()), self.bottomleft)
+ self.assertEqual(self.scene.itemAt(150, 150, QTransform()), self.bottomright)
+
+
+class TestGraphicsGroup(UsesQApplication):
+ def testIt(self):
+ scene = QGraphicsScene()
+ i1 = QGraphicsRectItem()
+ scene.addItem(i1)
+ i2 = QGraphicsRectItem(i1)
+ i3 = QGraphicsRectItem()
+ i4 = QGraphicsRectItem()
+ group = scene.createItemGroup((i2, i3, i4))
+ scene.removeItem(i1)
+ del i1 # this shouldn't delete i2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertEqual(i2.scene(), scene)
+ scene.destroyItemGroup(group)
+ self.assertRaises(RuntimeError, group.type)
+
+ def testCustomScene(self): # For PYSIDE-868, see above
+ scene = CustomScene()
+ view = QGraphicsView(scene)
+ view.show()
+ while scene.dpi == 0:
+ QApplication.processEvents()
+ view.hide()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qinputdialog_get_test.py b/sources/pyside6/tests/QtWidgets/qinputdialog_get_test.py
new file mode 100644
index 000000000..260653ae7
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qinputdialog_get_test.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication, QInputDialog, QDialog
+from helper.usesqapplication import UsesQApplication
+
+
+def close_dialog():
+ for w in QApplication.topLevelWidgets():
+ if isinstance(w, QDialog):
+ w.reject()
+
+
+class TestInputDialog(UsesQApplication):
+
+ def testGetDouble(self):
+ QTimer.singleShot(500, close_dialog)
+ self.assertEqual(QInputDialog.getDouble(None, "title", "label"), (0.0, False))
+
+ def testGetInt(self):
+ QTimer.singleShot(500, close_dialog)
+ self.assertEqual(QInputDialog.getInt(None, "title", "label"), (0, False))
+
+ def testGetItem(self):
+ QTimer.singleShot(500, close_dialog)
+ (item, bool) = QInputDialog.getItem(None, "title", "label", ["1", "2", "3"])
+ self.assertEqual(str(item), "1")
+
+ def testGetText(self):
+ QTimer.singleShot(500, close_dialog)
+ (text, bool) = QInputDialog.getText(None, "title", "label")
+ self.assertEqual(str(text), "")
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qkeysequenceedit_test.py b/sources/pyside6/tests/QtWidgets/qkeysequenceedit_test.py
new file mode 100644
index 000000000..bcb4c7a61
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qkeysequenceedit_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QKeySequenceEdit.'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QKeySequenceEdit
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QKeySequenceEditTest(UsesQApplication):
+ def testKeySequence(self):
+ keySequenceEdit = QKeySequenceEdit()
+ keySequenceEdit.show()
+ QTimer.singleShot(0, keySequenceEdit.close)
+ self.app.exec()
+ print(keySequenceEdit.keySequence())
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qlabel_test.py b/sources/pyside6/tests/QtWidgets/qlabel_test.py
new file mode 100644
index 000000000..aba90b7b8
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qlabel_test.py
@@ -0,0 +1,77 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QLabel'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QLabel
+from shiboken6 import Shiboken
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QLabelTest(UsesQApplication):
+ '''Test case for calling QLabel.setPixmap'''
+
+ def setUp(self):
+ super(QLabelTest, self).setUp()
+ self.label = QLabel()
+
+ def tearDown(self):
+ del self.label
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QLabelTest, self).tearDown()
+
+ def testSetPixmap(self):
+
+ p1 = QPixmap(5, 5)
+ p2 = QPixmap(10, 10)
+
+ self.label.setPixmap(p1)
+ self.assertIsNotNone(self.label.pixmap())
+
+ # PYSIDE-150:
+ # When a new QPixmap is assigned to a QLabel,
+ # the previous one needs to be cleared.
+ # This means we should not keep a copy of the QPixmap
+ # on Python-side.
+
+ # Getting pointer to the QPixmap
+ ret_p = self.label.pixmap()
+ self.assertIsNot(p1, ret_p)
+ # Save the address of the pointer
+ ret_p_addr = Shiboken.getCppPointer(ret_p)
+ # Remove the QPixmap
+ del ret_p
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # Set new QPixmap
+ self.label.setPixmap(p2)
+
+ # There should be no pointers remaining with the same
+ # address that our QPixmap p1 because it was deleted
+ # using `del ret_p`
+ self.assertTrue(all(Shiboken.getCppPointer(o) != ret_p_addr
+ for o in Shiboken.getAllValidWrappers()))
+
+ # Test for PYSIDE-1673, QObject.property() returning a QFlags<> property.
+ def testQObjectProperty(self):
+ a = self.label.property("alignment")
+ self.assertEqual(type(a), Qt.Alignment)
+ print("alignment=", a)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qlayout_ref_test.py b/sources/pyside6/tests/QtWidgets/qlayout_ref_test.py
new file mode 100644
index 000000000..df9bd7f90
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qlayout_ref_test.py
@@ -0,0 +1,171 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QLayout handling of child widgets references'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QGridLayout, QWidget
+from PySide6.QtWidgets import QStackedLayout, QFormLayout
+from PySide6.QtWidgets import QApplication, QPushButton, QLabel
+
+from helper.usesqapplication import UsesQApplication
+
+
+class SaveReference(UsesQApplication):
+ '''Test case to check if QLayout-derived classes increment the refcount
+ of widgets passed to addWidget()'''
+
+ # Adding here as nose can't see the qapplication attrib we inherit
+ qapplication = True
+
+ def setUp(self):
+ # Acquire resources
+ super(SaveReference, self).setUp()
+ self.widget1 = QPushButton('click me')
+ self.widget2 = QLabel('aaa')
+
+ def tearDown(self):
+ # Release resources
+ del self.widget2
+ del self.widget1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(SaveReference, self).tearDown()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def checkLayoutReference(self, layout):
+ # Checks the reference cound handling of layout.addWidget
+ self.assertEqual(sys.getrefcount(self.widget1), 2)
+ layout.addWidget(self.widget1)
+ self.assertEqual(sys.getrefcount(self.widget1), 3)
+
+ self.assertEqual(sys.getrefcount(self.widget2), 2)
+ layout.addWidget(self.widget2)
+ self.assertEqual(sys.getrefcount(self.widget2), 3)
+
+ # Check if doesn't mess around with previous widget refcount
+ self.assertEqual(sys.getrefcount(self.widget1), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testMoveLayout(self):
+ l = QHBoxLayout()
+ self.assertEqual(sys.getrefcount(self.widget1), 2)
+ l.addWidget(self.widget1)
+ self.assertEqual(sys.getrefcount(self.widget1), 3)
+
+ w = QWidget()
+ w.setLayout(l)
+ self.assertEqual(sys.getrefcount(self.widget1), 3)
+
+ def testHBoxReference(self):
+ # QHBoxLayout.addWidget reference count
+ w = QWidget()
+ self.checkLayoutReference(QHBoxLayout(w))
+
+ def testVBoxReference(self):
+ # QVBoxLayout.addWidget reference count
+ w = QWidget()
+ self.checkLayoutReference(QVBoxLayout(w))
+
+ def testGridReference(self):
+ # QGridLayout.addWidget reference count
+ w = QWidget()
+ self.checkLayoutReference(QGridLayout(w))
+
+ def testFormReference(self):
+ # QFormLayout.addWidget reference count
+ w = QWidget()
+ self.checkLayoutReference(QFormLayout(w))
+
+ def testStackedReference(self):
+ # QStackedLayout.addWidget reference count
+ w = QWidget()
+ self.checkLayoutReference(QStackedLayout(w))
+
+
+class MultipleAdd(UsesQApplication):
+ '''Test case to check if refcount is incremented only once when multiple
+ calls to addWidget are made with the same widget'''
+
+ qapplication = True
+
+ def setUp(self):
+ # Acquire resources
+ super(MultipleAdd, self).setUp()
+ self.widget = QPushButton('click me')
+ self.win = QWidget()
+ self.layout = QHBoxLayout(self.win)
+
+ def tearDown(self):
+ # Release resources
+ del self.widget
+ del self.layout
+ del self.win
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(MultipleAdd, self).tearDown()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCount(self):
+ # Multiple QLayout.addWidget calls on the same widget
+ self.assertEqual(sys.getrefcount(self.widget), 2)
+ self.layout.addWidget(self.widget)
+ self.assertEqual(sys.getrefcount(self.widget), 3)
+ self.layout.addWidget(self.widget)
+ self.assertEqual(sys.getrefcount(self.widget), 3)
+ self.layout.addWidget(self.widget)
+ self.assertEqual(sys.getrefcount(self.widget), 3)
+
+
+class InternalAdd(UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testInternalRef(self):
+ mw = QWidget()
+ w = QWidget()
+ ow = QWidget()
+
+ topLayout = QGridLayout()
+
+ # unique reference
+ self.assertEqual(sys.getrefcount(w), 2)
+ self.assertEqual(sys.getrefcount(ow), 2)
+
+ topLayout.addWidget(w, 0, 0)
+ topLayout.addWidget(ow, 1, 0)
+
+ # layout keep the referemce
+ self.assertEqual(sys.getrefcount(w), 3)
+ self.assertEqual(sys.getrefcount(ow), 3)
+
+ mainLayout = QGridLayout()
+
+ mainLayout.addLayout(topLayout, 1, 0, 1, 4)
+
+ # the same reference
+ self.assertEqual(sys.getrefcount(w), 3)
+ self.assertEqual(sys.getrefcount(ow), 3)
+
+ mw.setLayout(mainLayout)
+
+ # now trasfer the ownership to mw
+ self.assertEqual(sys.getrefcount(w), 3)
+ self.assertEqual(sys.getrefcount(ow), 3)
+
+ del mw
+
+ # remove the ref and invalidate the widget
+ self.assertEqual(sys.getrefcount(w), 2)
+ self.assertEqual(sys.getrefcount(ow), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qlayout_test.py b/sources/pyside6/tests/QtWidgets/qlayout_test.py
new file mode 100644
index 000000000..cc41f78b1
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qlayout_test.py
@@ -0,0 +1,139 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import (QFormLayout, QHBoxLayout, QLayout, QPushButton,
+ QSpacerItem, QWidget, QWidgetItem)
+
+
+class MyLayout(QLayout):
+ def __init__(self, parent=None):
+ QLayout.__init__(self, parent)
+ self._list = []
+
+ def addItem(self, item):
+ self.add(item)
+
+ def addWidget(self, widget):
+ self.add(QWidgetItem(widget))
+
+ def itemAt(self, index):
+ if index < len(self._list):
+ return self._list[index]
+
+ return None
+
+ def count(self):
+ return len(self._list)
+
+ def add(self, item):
+ self._list.append(item)
+
+
+class MissingItemAtLayout(QLayout):
+ def __init__(self, parent=None):
+ QLayout.__init__(self, parent)
+ self._list = []
+
+ def addItem(self, item):
+ self.add(item)
+
+ def addWidget(self, widget):
+ self.add(QWidgetItem(widget))
+
+ def count(self):
+ return len(self._list)
+
+ def add(self, item):
+ self._list.append(item)
+
+# Test if a layout implemented in python, the QWidget.setLayout works
+# fine because this implement som layout functions used in glue code of
+# QWidget, then in c++ when call a virtual function this need call the QLayout
+# function implemented in python
+
+
+class QLayoutTest(UsesQApplication):
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testOwnershipTransfer(self):
+ b = QPushButton("teste")
+ l = MyLayout()
+
+ l.addWidget(b)
+
+ self.assertEqual(sys.getrefcount(b), 2)
+
+ w = QWidget()
+
+ # transfer ref
+ w.setLayout(l)
+
+ self.assertEqual(sys.getrefcount(b), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceTransfer(self):
+ b = QPushButton("teste")
+ l = QHBoxLayout()
+
+ # keep ref
+ l.addWidget(b)
+ self.assertEqual(sys.getrefcount(b), 3)
+
+ w = QWidget()
+
+ # transfer ref
+ w.setLayout(l)
+
+ self.assertEqual(sys.getrefcount(b), 3)
+
+ # release ref
+ del w
+
+ self.assertEqual(sys.getrefcount(b), 2)
+
+ def testMissingFunctions(self):
+ w = QWidget()
+ b = QPushButton("test")
+ l = MissingItemAtLayout()
+
+ l.addWidget(b)
+
+ self.assertRaises(RuntimeError, w.setLayout, l)
+
+ def testQFormLayout(self):
+ w = QWidget()
+ formLayout = QFormLayout()
+ spacer = QSpacerItem(100, 30)
+ formLayout.setItem(0, QFormLayout.SpanningRole, spacer)
+ w.setLayout(formLayout)
+ w.show()
+ QTimer.singleShot(10, w.close)
+ self.app.exec()
+ del w
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
+ self.assertRaises(RuntimeError, spacer.isEmpty)
+
+ def testConstructorProperties(self):
+ """PYSIDE-1986, test passing properties to the constructor of
+ QHBoxLayout, which does not have default arguments."""
+ layout = QHBoxLayout(objectName="layout", spacing=30)
+ self.assertEqual(layout.spacing(), 30)
+ self.assertEqual(layout.objectName(), "layout")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qlcdnumber_test.py b/sources/pyside6/tests/QtWidgets/qlcdnumber_test.py
new file mode 100644
index 000000000..bc186f755
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qlcdnumber_test.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QLCDNumber
+
+
+class QLCDNumberOverflow(unittest.TestCase):
+ '''Test case for unhandled overflow on QLCDNumber() numDigits argument (see bug #215).'''
+
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
+ def setUp(self):
+ self.app = QApplication([])
+
+ def testnumDigitsOverflow(self):
+ # NOTE: PyQt4 raises TypeError, but boost.python raises OverflowError
+ self.assertRaises(OverflowError, QLCDNumber, 840835495615213080)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qlistwidget_test.py b/sources/pyside6/tests/QtWidgets/qlistwidget_test.py
new file mode 100644
index 000000000..377e63ffb
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qlistwidget_test.py
@@ -0,0 +1,77 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimer, Qt
+from PySide6.QtWidgets import QListWidget, QListWidgetItem
+from helper.usesqapplication import UsesQApplication
+
+
+class QListWidgetTest(UsesQApplication):
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def populateList(self, lst):
+ o = QObject()
+ o.setObjectName("obj")
+
+ item = QListWidgetItem("item0")
+ item.setData(Qt.UserRole, o)
+ # item._data = o
+ self.assertTrue(sys.getrefcount(o), 3)
+ self.assertTrue(sys.getrefcount(item), 2)
+ lst.addItem(item)
+ self.assertTrue(sys.getrefcount(item), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def checkCurrentItem(self, lst):
+ item = lst.currentItem()
+ self.assertTrue(sys.getrefcount(item), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def checkItemData(self, lst):
+ item = lst.currentItem()
+ o = item.data(Qt.UserRole)
+ self.assertTrue(sys.getrefcount(o), 4)
+ self.assertEqual(o, item._data)
+ self.assertTrue(sys.getrefcount(o), 2)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testConstructorWithParent(self):
+ lst = QListWidget()
+ self.populateList(lst)
+ self.checkCurrentItem(lst)
+ i = lst.item(0)
+ self.assertTrue(sys.getrefcount(i), 3)
+
+ del lst
+ self.assertTrue(sys.getrefcount(i), 2)
+ del i
+
+ def testIt(self):
+ lst = QListWidget()
+ lst.show()
+ slot = lambda: lst.removeItemWidget(lst.currentItem())
+ lst.addItem(QListWidgetItem("foo"))
+ QTimer.singleShot(0, slot)
+ QTimer.singleShot(0, lst.close)
+ self.app.exec()
+ self.assertEqual(lst.count(), 1)
+
+ def testClear(self):
+ lst = QListWidget()
+ lst.addItem("foo")
+ item = lst.item(0)
+ self.assertIsNone(lst.clear())
+ self.assertRaises(RuntimeError, lambda: item.text())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qlistwidgetitem_test.py b/sources/pyside6/tests/QtWidgets/qlistwidgetitem_test.py
new file mode 100644
index 000000000..a85c1b48f
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qlistwidgetitem_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QListWidget, QListWidgetItem
+from helper.usesqapplication import UsesQApplication
+
+
+class QListWidgetItemConstructor(UsesQApplication):
+
+ def setUp(self):
+ super(QListWidgetItemConstructor, self).setUp()
+ self.widgetList = QListWidget()
+
+ def tearDown(self):
+ del self.widgetList
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QListWidgetItemConstructor, self).tearDown()
+
+ def testConstructorWithParent(self):
+ # Bug 235 - QListWidgetItem constructor not saving ownership
+ QListWidgetItem(self.widgetList)
+ item = self.widgetList.item(0)
+ self.assertEqual(item.listWidget(), self.widgetList)
+
+ def testConstructorWithNone(self):
+ # Bug 452 - QListWidgetItem() not casting NoneType to null correctly.
+ item = QListWidgetItem(None, 123)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qmainwindow_test.py b/sources/pyside6/tests/QtWidgets/qmainwindow_test.py
new file mode 100644
index 000000000..2f245c8ff
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qmainwindow_test.py
@@ -0,0 +1,97 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QMainWindow, QPushButton, QToolButton, QWidget
+from helper.usesqapplication import UsesQApplication
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+
+ self.createToolbar()
+
+ def createToolbar(self):
+ pointerButton = QToolButton()
+ pointerToolbar = self.addToolBar("Pointer type")
+ pointerToolbar.addWidget(pointerButton)
+
+
+class MyButton(QPushButton):
+ def __init__(self, parent=None):
+ super().__init__()
+ self._called = False
+
+ def myCallback(self):
+ self._called = True
+
+
+class TestMainWindow(UsesQApplication):
+
+ def testCreateToolbar(self):
+ w = MainWindow()
+ w.show()
+ QTimer.singleShot(1000, self.app.quit)
+ self.app.exec()
+
+ def objDel(self, obj):
+ self.app.quit()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountToNull(self):
+ w = QMainWindow()
+ c = QWidget()
+ self.assertEqual(sys.getrefcount(c), 2)
+ w.setCentralWidget(c)
+ self.assertEqual(sys.getrefcount(c), 3)
+ wr = weakref.ref(c, self.objDel)
+ w.setCentralWidget(None)
+ c = None
+ self.app.exec()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCountToAnother(self):
+ w = QMainWindow()
+ c = QWidget()
+ self.assertEqual(sys.getrefcount(c), 2)
+ w.setCentralWidget(c)
+ self.assertEqual(sys.getrefcount(c), 3)
+
+ c2 = QWidget()
+ w.setCentralWidget(c2)
+ self.assertEqual(sys.getrefcount(c2), 3)
+
+ wr = weakref.ref(c, self.objDel)
+ w.setCentralWidget(None)
+ c = None
+
+ self.app.exec()
+
+ def testSignalDisconect(self):
+ w = QMainWindow()
+ b = MyButton("button")
+ b.clicked.connect(b.myCallback)
+ w.setCentralWidget(b)
+
+ b = MyButton("button")
+ b.clicked.connect(b.myCallback)
+ w.setCentralWidget(b)
+
+ b.click()
+ self.assertEqual(b._called, True)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qmenu_test.py b/sources/pyside6/tests/QtWidgets/qmenu_test.py
new file mode 100644
index 000000000..a6976a637
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qmenu_test.py
@@ -0,0 +1,76 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QMenu
+from PySide6.QtGui import QKeySequence, QIcon
+from PySide6.QtCore import SLOT
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QMenuAddAction(UsesQApplication):
+
+ def setUp(self):
+ super(QMenuAddAction, self).setUp()
+ self.menu = QMenu()
+
+ def tearDown(self):
+ del self.menu
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QMenuAddAction, self).tearDown()
+
+ def testAddActionWithoutKeySequenceCallable(self):
+ # bug #280
+ action = self.menu.addAction(self.app.tr('aaa'), lambda: 1)
+
+ def testAddActionKeySequenceCallable(self):
+ # bug #228
+ action = self.menu.addAction(self.app.tr('aaa'), lambda: 1,
+ QKeySequence(self.app.tr('Ctrl+O')))
+
+ def testAddActionKeySequenceSlot(self):
+ action = self.menu.addAction('Quit', self.app, SLOT('quit()'),
+ QKeySequence('Ctrl+O'))
+
+
+class QMenuAddActionWithIcon(UsesQApplication):
+
+ def setUp(self):
+ super(QMenuAddActionWithIcon, self).setUp()
+ self.menu = QMenu()
+ self.icon = QIcon()
+
+ def tearDown(self):
+ del self.menu
+ del self.icon
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QMenuAddActionWithIcon, self).tearDown()
+
+ def testAddActionWithoutKeySequenceCallable(self):
+ # bug #280
+ action = self.menu.addAction(self.icon, self.app.tr('aaa'), lambda: 1)
+
+ def testAddActionKeySequenceCallable(self):
+ # bug #228
+ action = self.menu.addAction(self.icon, self.app.tr('aaa'), lambda: 1,
+ QKeySequence(self.app.tr('Ctrl+O')))
+
+ def testAddActionKeySequenceSlot(self):
+ action = self.menu.addAction(self.icon, 'Quit', self.app, SLOT('quit()'),
+ QKeySequence('Ctrl+O'))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qmenuadd_test.py b/sources/pyside6/tests/QtWidgets/qmenuadd_test.py
new file mode 100644
index 000000000..5b42e755f
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qmenuadd_test.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test the QMenu.addAction() method'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QMenu
+from helper.usesqapplication import UsesQApplication
+
+
+class QMenuAddAction(UsesQApplication):
+
+ def openFile(self, *args):
+ self.arg = args
+
+ def testQMenuAddAction(self):
+ fileMenu = QMenu("&File")
+
+ addNewAction = fileMenu.addAction("&Open...", self.openFile)
+ addNewAction.trigger()
+ self.assertEqual(self.arg, ())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qobject_mi_test.py b/sources/pyside6/tests/QtWidgets/qobject_mi_test.py
new file mode 100644
index 000000000..d90961495
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qobject_mi_test.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for multiple inheritance from 2 QObjects'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+from PySide6.QtGui import QIntValidator, QValidator
+from PySide6.QtWidgets import QWidget
+
+from helper.usesqapplication import UsesQApplication
+
+
+class WidgetValidator(QWidget, QIntValidator):
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent)
+ QIntValidator.__init__(self, parent)
+
+
+class DoubleQObjectInheritanceTest(UsesQApplication):
+
+ def testDouble(self):
+ '''Double inheritance from QObject classes'''
+
+ obj = WidgetValidator()
+
+ # QObject methods
+ obj.setObjectName('aaaa')
+ self.assertEqual(obj.objectName(), 'aaaa')
+
+ # QWidget methods
+ obj.setVisible(False)
+ self.assertFalse(obj.isVisible())
+
+ # QIntValidator methods
+ state, string, number = obj.validate('aaaa', 0)
+ self.assertEqual(state, QValidator.Invalid)
+ state, string, number = obj.validate('33', 0)
+ self.assertEqual(state, QValidator.Acceptable)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qpicture_test.py b/sources/pyside6/tests/QtWidgets/qpicture_test.py
new file mode 100644
index 000000000..b81713b57
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qpicture_test.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import QTimer
+from PySide6.QtGui import QPicture, QPainter
+from PySide6.QtWidgets import QWidget
+
+
+class MyWidget(QWidget):
+ def paintEvent(self, e):
+ with QPainter(self) as p:
+ p.drawPicture(0, 0, self._picture)
+ self._app.quit()
+
+
+class QPictureTest(UsesQApplication):
+ def testFromData(self):
+ picture = QPicture()
+ with QPainter(picture) as painter:
+ painter.drawEllipse(10, 20, 80, 70)
+
+ data = picture.data()
+ picture2 = QPicture()
+ picture2.setData(data)
+
+ self.assertEqual(picture2.data(), picture.data())
+
+ w = MyWidget()
+ w._picture = picture2
+ w._app = self.app
+
+ QTimer.singleShot(300, w.show)
+ self.app.exec()
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qpushbutton_test.py b/sources/pyside6/tests/QtWidgets/qpushbutton_test.py
new file mode 100644
index 000000000..bfc04130e
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qpushbutton_test.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtWidgets import QPushButton, QMenu, QWidget
+from PySide6.QtCore import QTimer, Qt
+
+
+class MyWidget(QWidget):
+ def __init__(self):
+ super().__init__()
+
+ m = QMenu(self)
+ b = QPushButton("Hello", self)
+ b.setMenu(m)
+
+
+class QPushButtonTest(UsesQApplication):
+ def createMenu(self, button):
+ m = QMenu()
+ button.setMenu(m)
+
+ def testSetMenu(self):
+ w = MyWidget()
+ w.show()
+
+ timer = QTimer.singleShot(100, self.app.quit)
+ self.app.exec()
+
+ def buttonCb(self, checked):
+ self._clicked = True
+
+ def testBoolinSignal(self):
+ b = QPushButton()
+ b.setCheckable(True)
+ b.setShortcut(Qt.Key_A)
+ self._clicked = False
+ b.toggled[bool].connect(self.buttonCb)
+ b.toggle()
+ self.assertTrue(self._clicked)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qsplitter_test.py b/sources/pyside6/tests/QtWidgets/qsplitter_test.py
new file mode 100644
index 000000000..ae383f425
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qsplitter_test.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QSplitter
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QSplitterTest(UsesQApplication):
+
+ def testGetRange(self):
+ splitter = QSplitter()
+ _min, _max = splitter.getRange(0)
+ self.assertTrue(isinstance(_min, int))
+ self.assertTrue(isinstance(_max, int))
+
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qstyle_test.py b/sources/pyside6/tests/QtWidgets/qstyle_test.py
new file mode 100644
index 000000000..5a9b29dc6
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qstyle_test.py
@@ -0,0 +1,76 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import sys
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtGui import QWindow
+from PySide6.QtWidgets import (QApplication, QFontComboBox, QLabel, QProxyStyle,
+ QStyleFactory, QWidget)
+
+
+class ProxyStyle(QProxyStyle):
+
+ def __init__(self, style):
+ QProxyStyle.__init__(self, style)
+ self.polished = 0
+
+ def polish(self, widget):
+ self.polished = self.polished + 1
+ super(ProxyStyle, self).polish(widget)
+
+
+class SetStyleTest(UsesQApplication):
+ '''Tests setting the same QStyle for all objects in a UI hierarchy.'''
+
+ def testSetStyle(self):
+ '''All this test have to do is not break with some invalid Python wrapper.'''
+
+ def setStyleHelper(widget, style):
+ widget.setStyle(style)
+ widget.setPalette(style.standardPalette())
+ for child in widget.children():
+ if isinstance(child, QWidget):
+ setStyleHelper(child, style)
+
+ container = QWidget()
+ # QFontComboBox is used because it has an QLineEdit created in C++ inside it,
+ # and if the QWidget.setStyle(style) steals the ownership of the style
+ # for the C++ originated widget everything will break.
+ fontComboBox = QFontComboBox(container)
+ label = QLabel(container)
+ label.setText('Label')
+ style = QStyleFactory.create(QStyleFactory.keys()[0])
+ setStyleHelper(container, style)
+
+ def testSetProxyStyle(self):
+ label = QLabel("QtWidgets/ProxyStyle test")
+ baseStyle = QStyleFactory.create(QApplication.instance().style().objectName())
+ self.assertTrue(baseStyle)
+ proxyStyle = ProxyStyle(baseStyle)
+ label.setStyle(proxyStyle)
+ label.show()
+ while not label.windowHandle().isExposed():
+ QApplication.instance().processEvents()
+ self.assertTrue(proxyStyle.polished > 0)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testSetStyleOwnership(self):
+ style = QStyleFactory.create(QStyleFactory.keys()[0])
+ self.assertEqual(sys.getrefcount(style), 2)
+ QApplication.instance().setStyle(style)
+ self.assertEqual(sys.getrefcount(style), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qstyleoption_test.py b/sources/pyside6/tests/QtWidgets/qstyleoption_test.py
new file mode 100644
index 000000000..06798b9e9
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qstyleoption_test.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import sys
+import os
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtWidgets import (QApplication, QCommonStyle, QPushButton)
+
+
+text = ''
+
+
+class Style(QCommonStyle):
+
+ def drawControl(self, element, option, painter, widget=None):
+ # This should be a QStyleOptionButton with a "text" field
+ global text
+ text = option.text
+
+
+class StyleOptionTest(UsesQApplication):
+ '''PYSIDE-1909: Test cast to derived style option classes.'''
+
+ def testStyle(self):
+ global text
+ button = QPushButton("Hello World")
+ button.setStyle(Style())
+ button.show()
+ while not text:
+ QApplication.processEvents()
+ self.assertEqual(text, button.text())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtableview_test.py b/sources/pyside6/tests/QtWidgets/qtableview_test.py
new file mode 100644
index 000000000..c43666f23
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtableview_test.py
@@ -0,0 +1,28 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QAbstractTableModel
+from PySide6.QtWidgets import QTableWidget
+from helper.usesqapplication import UsesQApplication
+
+
+class QPenTest(UsesQApplication):
+
+ def testItemModel(self):
+ tv = QTableWidget()
+
+ self.assertEqual(type(tv.model()), QAbstractTableModel)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qtabwidget_test.py b/sources/pyside6/tests/QtWidgets/qtabwidget_test.py
new file mode 100644
index 000000000..8db45f24b
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtabwidget_test.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QPushButton, QTabWidget
+from helper.timedqapplication import TimedQApplication
+
+
+def makeBug643(tab):
+ button = QPushButton('Foo')
+ tab.insertTab(0, button, 'Foo')
+
+
+class RemoveTabMethod(TimedQApplication):
+ def setUp(self):
+ TimedQApplication.setUp(self)
+ self.tab = QTabWidget()
+
+ def tearDown(self):
+ del self.tab
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ TimedQApplication.tearDown(self)
+
+ def testRemoveTabPresence(self):
+ self.assertTrue(getattr(self.tab, 'removeTab'))
+
+ def testInsertTab(self):
+ makeBug643(self.tab)
+ self.assertEqual(self.tab.count(), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtabwidgetclear_test.py b/sources/pyside6/tests/QtWidgets/qtabwidgetclear_test.py
new file mode 100644
index 000000000..49e16e8d2
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtabwidgetclear_test.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QMainWindow, QTabWidget, QTextEdit, QSplitter
+from helper.usesqapplication import UsesQApplication
+
+
+class TabWidgetClear(QMainWindow):
+ def __init__(self):
+ super().__init__()
+ self.tabWidget = QTabWidget(self)
+ self.setCentralWidget(self.tabWidget)
+ self.editBox = QTextEdit(self)
+ self.tabWidget.addTab(self.getSplitter(), 'Test')
+
+ def getSplitter(self):
+ splitter = QSplitter()
+ splitter.addWidget(self.editBox)
+ return splitter
+
+ def toggle(self):
+ self.tabWidget.clear()
+ self.getSplitter()
+
+
+class TestTabWidgetClear(UsesQApplication):
+
+ def testClear(self):
+ self.window = TabWidgetClear()
+ self.window.show()
+ try:
+ self.window.toggle()
+ except RuntimeError as e:
+ # This should never happened, PYSIDE-213
+ raise e
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtextedit_signal_test.py b/sources/pyside6/tests/QtWidgets/qtextedit_signal_test.py
new file mode 100644
index 000000000..16929f0f2
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtextedit_signal_test.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Signal, Slot
+from PySide6.QtWidgets import QMainWindow, QPushButton, QTextEdit
+from helper.usesqapplication import UsesQApplication
+
+
+class MyWindow(QMainWindow):
+ appendText = Signal(str)
+
+ @Slot()
+ def onButtonPressed(self):
+ self.appendText.emit("PySide")
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self.textEdit = QTextEdit()
+ self.btn = QPushButton("ClickMe")
+ self.btn.clicked.connect(self.onButtonPressed)
+ self.appendText.connect(self.textEdit.append)
+
+ def start(self):
+ self.btn.click()
+
+ def text(self):
+ return self.textEdit.toPlainText()
+
+
+class testSignalWithCPPSlot(UsesQApplication):
+
+ def testEmission(self):
+ w = MyWindow()
+ w.start()
+ self.assertEqual(w.text(), "PySide")
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qtextedit_test.py b/sources/pyside6/tests/QtWidgets/qtextedit_test.py
new file mode 100644
index 000000000..b82350293
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtextedit_test.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QTextEdit and ownership problems.'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QTextEdit
+
+from helper.usesqapplication import UsesQApplication
+
+
+class DontTouchReference(UsesQApplication):
+ '''Check if the QTextTable returned by QTextCursor.insertTable() is not
+ referenced by the QTextCursor that returns it.'''
+
+ def setUp(self):
+ super(DontTouchReference, self).setUp()
+ self.editor = QTextEdit()
+ self.cursor = self.editor.textCursor()
+ self.table = self.cursor.insertTable(1, 1)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testQTextTable(self):
+ # methods which return QTextTable should not increment its reference
+ self.assertEqual(sys.getrefcount(self.table), 2)
+ f = self.cursor.currentFrame()
+ del f
+ self.assertEqual(sys.getrefcount(self.table), 2)
+ # destroying the cursor should not raise any "RuntimeError: internal
+ # C++ object already deleted." when accessing the QTextTable
+ del self.cursor
+ self.assertEqual(sys.getrefcount(self.table), 2)
+ cell = self.table.cellAt(0, 0)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtoolbar_test.py b/sources/pyside6/tests/QtWidgets/qtoolbar_test.py
new file mode 100644
index 000000000..6fa5865cf
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtoolbar_test.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QToolbar'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QAction
+from PySide6.QtWidgets import QToolBar, QMainWindow
+
+from helper.usesqapplication import UsesQApplication
+
+
+class AddActionText(UsesQApplication):
+ '''Test case for calling QToolbar.addAction passing a text'''
+
+ def setUp(self):
+ # Acquire resources
+ super(AddActionText, self).setUp()
+ self.window = QMainWindow()
+ self.toolbar = QToolBar()
+ self.window.addToolBar(self.toolbar)
+
+ def tearDown(self):
+ # Release resources
+ super(AddActionText, self).tearDown()
+ del self.toolbar
+ del self.window
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testText(self):
+ # QToolBar.addAction(text) - add a QToolButton
+ self.toolbar.addAction('aaaa')
+ self.assertEqual(len(self.toolbar.actions()), 1)
+ action = self.toolbar.actions()[0]
+ self.assertTrue(isinstance(action, QAction))
+ self.assertEqual(action.text(), 'aaaa')
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtoolbox_test.py b/sources/pyside6/tests/QtWidgets/qtoolbox_test.py
new file mode 100644
index 000000000..d069416b7
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtoolbox_test.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QIcon
+from PySide6.QtWidgets import QToolBox, QWidget
+
+from helper.usesqapplication import UsesQApplication
+
+
+class OwnershipControl(UsesQApplication):
+
+ def setUp(self):
+ super(OwnershipControl, self).setUp()
+ self.toolbox = QToolBox()
+
+ def tearDown(self):
+ del self.toolbox
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(OwnershipControl, self).tearDown()
+
+ def testAddItem(self):
+ # Was losing ownership of the widget.
+ index = self.toolbox.addItem(QWidget(), 'item')
+ item = self.toolbox.widget(index)
+ self.assertTrue(isinstance(item, QWidget))
+
+ def testAddItemWithIcon(self):
+ index = self.toolbox.addItem(QWidget(), QIcon(), 'item')
+ item = self.toolbox.widget(index)
+ self.assertTrue(isinstance(item, QWidget))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtreeview_test.py b/sources/pyside6/tests/QtWidgets/qtreeview_test.py
new file mode 100644
index 000000000..fd535bfad
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtreeview_test.py
@@ -0,0 +1,84 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QStandardItemModel
+from PySide6.QtWidgets import (QWidget, QTreeView, QVBoxLayout,
+ QStyledItemDelegate, QHeaderView)
+from PySide6.QtCore import Qt
+from helper.usesqapplication import UsesQApplication
+
+
+class Widget(QWidget):
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent)
+ self.treeView = QTreeView(self)
+ layout = QVBoxLayout()
+ layout.addWidget(self.treeView)
+ self.setLayout(layout)
+ self.treeView.setModel(QStandardItemModel())
+
+ self.treeView.model().setHorizontalHeaderLabels(('3', '1', '5'))
+
+
+class QWidgetTest(UsesQApplication):
+
+ def testDelegates(self):
+ widget = Widget()
+ t = widget.treeView
+
+ # When calling setItemDelegateForColumn using a separate variable
+ # for the second argument (QAbstractItemDelegate), there was no problem
+ # on keeping the reference to this object, since the variable was kept
+ # alive (case A)
+ # Contrary, when instantiating this argument on the function call
+ # Using QStyledItemDelegate inside the call the reference of the
+ # object was lost, causing a segfault. (case B)
+
+ # Case A
+ d = QStyledItemDelegate()
+ # Using QStyledItemDelegate from a variable so we keep the reference alive
+ # and we encounter no segfault.
+ t.setItemDelegateForColumn(0, d)
+ # This raised the Segmentation Fault too, because manually destroying
+ # the object caused a missing refrence.
+ del d
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ # Getting the delegates
+ a = t.itemDelegateForColumn(0)
+ self.assertIsInstance(a, QStyledItemDelegate)
+
+ # Case B
+ t.setItemDelegateForColumn(1, QStyledItemDelegate())
+
+ # Getting the delegates
+ b = t.itemDelegateForColumn(1)
+ self.assertIsInstance(b, QStyledItemDelegate)
+
+ # Test for Rows
+ t.setItemDelegateForRow(0, QStyledItemDelegate())
+ self.assertIsInstance(t.itemDelegateForRow(0), QStyledItemDelegate)
+
+ # Test for general delegate
+ t.setItemDelegate(QStyledItemDelegate())
+ self.assertIsInstance(t.itemDelegate(), QStyledItemDelegate)
+
+ def testHeader(self):
+ tree = QTreeView()
+ tree.setHeader(QHeaderView(Qt.Horizontal))
+ self.assertIsNotNone(tree.header())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtreewidget_test.py b/sources/pyside6/tests/QtWidgets/qtreewidget_test.py
new file mode 100644
index 000000000..6c2db32b9
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtreewidget_test.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QTreeWidget, QTreeWidgetItem, QPushButton
+from helper.usesqapplication import UsesQApplication
+
+
+class QTreeWidgetTest(UsesQApplication):
+
+ # PYSIDE-73:
+ # There was a problem when adding items to a QTreeWidget
+ # when the Widget was being build on the method call instead
+ # of as a separate variable.
+ # The problem was there was not ownership transfer, so the
+ # QTreeWidget did not own the QWidget element
+ def testSetItemWidget(self):
+
+ treeWidget = QTreeWidget()
+ treeWidget.setColumnCount(2)
+
+ item = QTreeWidgetItem(['text of column 0', ''])
+ treeWidget.insertTopLevelItem(0, item)
+ # Adding QPushButton inside the method
+ treeWidget.setItemWidget(item, 1,
+ QPushButton('Push button on column 1'))
+
+ # Getting the widget back
+ w = treeWidget.itemWidget(treeWidget.itemAt(0, 1), 1)
+ self.assertIsInstance(w, QPushButton)
+
+ p = QPushButton('New independent button')
+ # Adding QPushButton object from variable
+ treeWidget.setItemWidget(item, 0, p)
+ w = treeWidget.itemWidget(treeWidget.itemAt(0, 0), 0)
+ self.assertIsInstance(w, QPushButton)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qtreewidgetitem_test.py b/sources/pyside6/tests/QtWidgets/qtreewidgetitem_test.py
new file mode 100644
index 000000000..432aba2ed
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qtreewidgetitem_test.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+Unit tests for QTreeWidgetItem
+------------------------------
+
+This test is actually meant for all types which provide `tp_richcompare`
+but actually define something without providing `==` or `!=` operators.
+QTreeWidgetItem for instance defines `<` only.
+
+PYSIDE-74: We redirect to type `object`s handling which is anyway the default
+ when `tp_richcompare` is undefined.
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
+
+
+class QTreeWidgetItemTest(unittest.TestCase):
+ def testClass(self):
+ app = QApplication([])
+ treewidget = QTreeWidget()
+ item = QTreeWidgetItem(["Words and stuff"])
+ item2 = QTreeWidgetItem(["More words!"])
+ treewidget.insertTopLevelItem(0, item)
+
+ dummy_list = ["Numbers", "Symbols", "Spam"]
+ self.assertFalse(item in dummy_list)
+ self.assertTrue(item not in dummy_list)
+ self.assertFalse(item == item2)
+ self.assertTrue(item != item2)
+
+
+if __name__ == "__main__":
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qvariant_test.py b/sources/pyside6/tests/QtWidgets/qvariant_test.py
new file mode 100644
index 000000000..fe0266309
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qvariant_test.py
@@ -0,0 +1,142 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QObject
+from PySide6.QtWidgets import (QComboBox, QGraphicsScene,
+ QGraphicsRectItem)
+
+from helper.usesqapplication import UsesQApplication
+
+
+class MyDiagram(QGraphicsScene):
+ pass
+
+
+class MyItem(QGraphicsRectItem):
+ def itemChange(self, change, value):
+ return value
+
+
+class Sequence(object):
+ # Having the __getitem__ method on a class transform the Python
+ # type to a PySequence.
+ # Before the patch: aa75437f9119d997dd290471ac3e2cc88ca88bf1
+ # "Fix QVariant conversions when using PySequences"
+ # one could not use an object from this class, because internally
+ # we were requiring that the PySequence was finite.
+ def __getitem__(self, key):
+ raise IndexError()
+
+
+class QGraphicsSceneOnQVariantTest(UsesQApplication):
+ """Test storage ot QGraphicsScene into QVariants"""
+ def setUp(self):
+ super(QGraphicsSceneOnQVariantTest, self).setUp()
+ self.s = MyDiagram()
+ self.i = MyItem()
+ self.combo = QComboBox()
+
+ def tearDown(self):
+ del self.s
+ del self.i
+ del self.combo
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(QGraphicsSceneOnQVariantTest, self).tearDown()
+
+ def testIt(self):
+ self.s.addItem(self.i)
+ self.assertEqual(len(self.s.items()), 1)
+
+ def testSequence(self):
+ # PYSIDE-641
+ self.combo.addItem("test", userData=Sequence())
+ self.assertTrue(isinstance(self.combo.itemData(0), Sequence))
+
+
+class QVariantConversionTest(UsesQApplication):
+ """
+ Tests conversion from QVariant to supported type held by QVariant
+ """
+ def setUp(self):
+ super(QVariantConversionTest, self).setUp()
+ self.obj = QObject()
+
+ def tearDown(self):
+ del self.obj
+ super(QVariantConversionTest, self).tearDown()
+
+ def testEnum(self):
+ """
+ PYSIDE-1798: Test enum is obtained correctly when return through QVariant
+ """
+ self.obj.setProperty("test", Qt.SolidLine)
+ self.assertTrue(isinstance(self.obj.property("test"), Qt.PenStyle))
+ self.assertEqual(self.obj.property("test"), Qt.SolidLine)
+
+ def testString(self):
+ self.obj.setProperty("test", "test")
+ self.assertEqual(self.obj.property("test"), "test")
+ self.assertTrue(isinstance(self.obj.property("test"), str))
+
+ def testBytes(self):
+ byte_message = bytes("test", 'utf-8')
+ self.obj.setProperty("test", byte_message)
+ self.assertEqual(self.obj.property("test"), byte_message)
+ self.assertTrue(isinstance(self.obj.property("test"), bytes))
+
+ def testBasicTypes(self):
+ #bool
+ self.obj.setProperty("test", True)
+ self.assertEqual(self.obj.property("test"), True)
+ self.assertTrue(isinstance(self.obj.property("test"), bool))
+ #long
+ self.obj.setProperty("test", 2)
+ self.assertEqual(self.obj.property("test"), 2)
+ self.assertTrue(isinstance(self.obj.property("test"), int))
+ #float
+ self.obj.setProperty("test", 2.5)
+ self.assertEqual(self.obj.property("test"), 2.5)
+ self.assertTrue(isinstance(self.obj.property("test"), float))
+ #None
+ self.obj.setProperty("test", None)
+ self.assertEqual(self.obj.property("test"), None)
+
+ def testContainerTypes(self):
+ #list
+ self.obj.setProperty("test", [1, 2, 3])
+ self.assertEqual(self.obj.property("test"), [1, 2, 3])
+ self.assertTrue(isinstance(self.obj.property("test"), list))
+ #dict
+ self.obj.setProperty("test", {1: "one"})
+ self.assertEqual(self.obj.property("test"), {1: "one"})
+ self.assertTrue(isinstance(self.obj.property("test"), dict))
+
+ def testPyObject(self):
+ class Test:
+ pass
+ test = Test()
+ self.obj.setProperty("test", test)
+ self.assertEqual(self.obj.property("test"), test)
+ self.assertTrue(isinstance(self.obj.property("test"), Test))
+
+ def testQMetaPropertyWrite(self):
+ combo_box = QComboBox()
+ meta_obj = combo_box.metaObject()
+ i = meta_obj.indexOfProperty("sizeAdjustPolicy")
+ success = meta_obj.property(i).write(combo_box, QComboBox.SizeAdjustPolicy.AdjustToContents)
+ self.assertTrue(success)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/qwidget_setlayout_test.py b/sources/pyside6/tests/QtWidgets/qwidget_setlayout_test.py
new file mode 100644
index 000000000..1d9128789
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qwidget_setlayout_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QApplication, QHBoxLayout
+from helper.usesqapplication import UsesQApplication
+
+
+class QWidgetTest(UsesQApplication):
+
+ def test_setLayout(self):
+ layout = QVBoxLayout()
+ btn1 = QPushButton("button_v1")
+ layout.addWidget(btn1)
+
+ btn2 = QPushButton("button_v2")
+ layout.addWidget(btn2)
+
+ layout2 = QHBoxLayout()
+
+ btn1 = QPushButton("button_h1")
+ layout2.addWidget(btn1)
+
+ btn2 = QPushButton("button_h2")
+ layout2.addWidget(btn2)
+
+ layout.addLayout(layout2)
+
+ widget = QWidget()
+ widget.setLayout(layout)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/qwidget_test.py b/sources/pyside6/tests/QtWidgets/qwidget_test.py
new file mode 100644
index 000000000..2d503f0d4
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/qwidget_test.py
@@ -0,0 +1,61 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import sys
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QWidget, QMainWindow
+from helper.usesqapplication import UsesQApplication
+
+
+class QWidgetInherit(QMainWindow):
+ def __init__(self):
+ QWidget.__init__(self) # Intended: Initialize QWidget instead of base
+
+
+class NativeEventTestWidget(QWidget):
+
+ nativeEventCount = 0
+
+ def __init__(self):
+ super().__init__()
+
+ def nativeEvent(self, eventType, message):
+ self.nativeEventCount = self.nativeEventCount + 1
+ return [False, 0]
+
+
+class QWidgetTest(UsesQApplication):
+
+ def testInheritance(self):
+ self.assertRaises(TypeError, QWidgetInherit)
+
+
+class QWidgetVisible(UsesQApplication):
+
+ def testBasic(self):
+ # Also related to bug #244, on existence of setVisible'''
+ widget = NativeEventTestWidget()
+ self.assertTrue(not widget.isVisible())
+ widget.setVisible(True)
+ self.assertTrue(widget.isVisible())
+ self.assertTrue(widget.winId() != 0)
+ # skip this test on macOS since no native events are received
+ if sys.platform == 'darwin':
+ return
+ for i in range(10):
+ if widget.nativeEventCount > 0:
+ break
+ self.app.processEvents()
+ self.assertTrue(widget.nativeEventCount > 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/reference_count_test.py b/sources/pyside6/tests/QtWidgets/reference_count_test.py
new file mode 100644
index 000000000..b7d3908dd
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/reference_count_test.py
@@ -0,0 +1,84 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for Reference count when the object is created in c++ side'''
+
+import gc
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Qt, QPointF
+from PySide6.QtGui import QPolygonF
+from PySide6.QtWidgets import QApplication, QGraphicsScene, QGraphicsRectItem, QGraphicsPolygonItem, QGraphicsRectItem
+
+from helper.usesqapplication import UsesQApplication
+
+destroyedRect = False
+destroyedPol = False
+
+
+def rect_del(o):
+ global destroyedRect
+ destroyedRect = True
+
+
+def pol_del(o):
+ global destroyedPol
+ destroyedPol = True
+
+
+class ReferenceCount(UsesQApplication):
+
+ def setUp(self):
+ super(ReferenceCount, self).setUp()
+ self.scene = QGraphicsScene()
+
+ def tearDown(self):
+ super(ReferenceCount, self).tearDown()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def beforeTest(self):
+ points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)]
+ pol = self.scene.addPolygon(QPolygonF(points))
+ self.assertTrue(isinstance(pol, QGraphicsPolygonItem))
+ self.wrp = weakref.ref(pol, pol_del)
+
+ # refcount need be 3 because one ref for QGraphicsScene, and one to rect obj
+ self.assertEqual(sys.getrefcount(pol), 3)
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testReferenceCount(self):
+ global destroyedRect
+ global destroyedPol
+
+ self.beforeTest()
+
+ rect = self.scene.addRect(10.0, 10.0, 10.0, 10.0)
+ self.assertTrue(isinstance(rect, QGraphicsRectItem))
+
+ self.wrr = weakref.ref(rect, rect_del)
+
+ # refcount need be 3 because one ref for QGraphicsScene, and one to rect obj
+ self.assertEqual(sys.getrefcount(rect), 3)
+
+ del rect
+ # not destroyed because one ref continue in QGraphicsScene
+ self.assertEqual(destroyedRect, False)
+ self.assertEqual(destroyedPol, False)
+
+ del self.scene
+
+ # QGraphicsScene was destroyed and this destroy internal ref to rect
+ self.assertEqual(destroyedRect, True)
+ self.assertEqual(destroyedPol, True)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/sample.png b/sources/pyside6/tests/QtWidgets/sample.png
new file mode 100644
index 000000000..60450f0dc
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/sample.png
Binary files differ
diff --git a/sources/pyside6/tests/QtWidgets/signature_test.py b/sources/pyside6/tests/QtWidgets/signature_test.py
new file mode 100644
index 000000000..f156b6717
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/signature_test.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import inspect
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6.QtCore
+import PySide6.QtWidgets
+from PySide6.support.signature import get_signature
+
+
+class PySideSignatureTest(unittest.TestCase):
+ def testSignatureExist(self):
+ t1 = type(get_signature(PySide6.QtCore.QObject.children))
+ self.assertEqual(t1, inspect.Signature)
+ t2 = type(get_signature(PySide6.QtCore.QObject.__dict__["children"]))
+ self.assertEqual(t2, t1)
+ obj = PySide6.QtWidgets.QApplication.palette
+ t3 = type(get_signature(obj))
+ self.assertEqual(t3, list)
+ self.assertEqual(len(get_signature(obj)), 3)
+ for thing in get_signature(obj):
+ self.assertEqual(type(thing), inspect.Signature)
+ sm = PySide6.QtWidgets.QApplication.__dict__["palette"]
+ # PYSIDE-1436: staticmethod is a callable since Python 3.10
+ # Instead of checking callable(sm), we check the type:
+ self.assertEqual(type(sm), staticmethod)
+ self.assertTrue(get_signature(sm) is not None)
+
+ def testSignatureIsCached(self):
+ # see if we get the same object
+ ob1 = get_signature(PySide6.QtCore.QObject.children)
+ ob2 = get_signature(PySide6.QtCore.QObject.children)
+ self.assertTrue(ob1 is ob2)
+ # same with multi signature
+ ob1 = get_signature(PySide6.QtWidgets.QApplication.palette)
+ ob2 = get_signature(PySide6.QtWidgets.QApplication.palette)
+ self.assertTrue(ob1 is ob2)
+
+ def testModuleIsInitialized(self):
+ self.assertTrue(get_signature(PySide6.QtWidgets.QApplication) is not None)
+
+ def test_NotCalled_is_callable_and_correct(self):
+ # A signature that has a default value with some "Default(...)"
+ # wrapper is callable and creates an object of the right type.
+ sig = get_signature(PySide6.QtCore.QByteArray().toPercentEncoding)
+ called_default = sig.parameters["exclude"].default()
+ self.assertEqual(type(called_default), PySide6.QtCore.QByteArray)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/QtWidgets/standardpixmap_test.py b/sources/pyside6/tests/QtWidgets/standardpixmap_test.py
new file mode 100644
index 000000000..564f3ff2e
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/standardpixmap_test.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QStyle
+
+from helper.usesqapplication import UsesQApplication
+
+
+class StandardPixmapTest(UsesQApplication):
+ def testDefaultOptions(self): # Bug 253
+ pixmap = self.app.style().standardPixmap(QStyle.SP_DirClosedIcon)
+ self.assertTrue(isinstance(pixmap, QPixmap))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/test_module_template.py b/sources/pyside6/tests/QtWidgets/test_module_template.py
new file mode 100644
index 000000000..92661cdff
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/test_module_template.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1] / "util"))
+from init_paths import init_test_paths
+init_test_paths()
+
+from PySide6.QtWidgets import QWidget
+from PySide6.QtCore import QObject
+
+
+class MyQObject(QObject):
+ pass
+
+
+class MyQWidget(QWidget):
+ pass
+
+
+class Sentinel():
+ value = 10
+
diff --git a/sources/pyside6/tests/QtWidgets/virtual_protected_inheritance_test.py b/sources/pyside6/tests/QtWidgets/virtual_protected_inheritance_test.py
new file mode 100644
index 000000000..911fed475
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/virtual_protected_inheritance_test.py
@@ -0,0 +1,84 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for overriding inherited protected virtual methods'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimerEvent
+from PySide6.QtWidgets import QApplication, QSpinBox
+
+from helper.usesqapplication import UsesQApplication
+
+
+class MySpinButton(QSpinBox):
+ '''Simple example class of overriding QObject.timerEvent'''
+
+ def __init__(self, max_runs=5, app=None):
+ # Creates a new spinbox that will run <max_runs> and quit <app>
+ super().__init__()
+
+ if app is None:
+ app = QApplication([])
+
+ self.app = app
+ self.max_runs = max_runs
+ self.runs = 0
+
+ def timerEvent(self, event):
+ # Timer event method
+ self.runs += 1
+
+ self.setValue(self.runs)
+
+ if self.runs == self.max_runs:
+ self.app.quit()
+
+ if not isinstance(event, QTimerEvent):
+ raise TypeError('Invalid event type. Must be TimerEvent')
+
+
+class TimerEventTest(UsesQApplication):
+ '''Test case for running QObject.timerEvent from inherited class'''
+
+ qapplication = True
+
+ def setUp(self):
+ # Acquire resources
+ super(TimerEventTest, self).setUp()
+ self.widget = MySpinButton(app=self.app)
+
+ def tearDown(self):
+ # Release resources
+ del self.widget
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(TimerEventTest, self).tearDown()
+
+ def testMethod(self):
+ # QWidget.timerEvent overrinding (protected inherited)
+ timer_id = self.widget.startTimer(0)
+
+ self.app.exec()
+
+ self.widget.killTimer(timer_id)
+
+ self.assertTrue(self.widget.runs >= self.widget.max_runs)
+
+
+if __name__ == '__main__':
+ unittest.main()
+ #app = QApplication([])
+ #widget = MySpinButton(app=app)
+ #widget.startTimer(500)
+ #widget.show()
+ #app.exec()
+
diff --git a/sources/pyside6/tests/QtWidgets/virtual_pure_override_test.py b/sources/pyside6/tests/QtWidgets/virtual_pure_override_test.py
new file mode 100644
index 000000000..b7d1e4f3f
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/virtual_pure_override_test.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QGraphicsScene, QGraphicsRectItem, QGraphicsView, QApplication
+from PySide6.QtGui import QBrush, QColor
+from PySide6.QtCore import QTimer
+from helper.usesqapplication import UsesQApplication
+
+qgraphics_item_painted = False
+
+
+class RoundRectItem(QGraphicsRectItem):
+
+ def __init__(self, x, y, w, h):
+ QGraphicsRectItem.__init__(self, x, y, w, h)
+
+ def paint(self, painter, qstyleoptiongraphicsitem, qwidget):
+ global qgraphics_item_painted
+ qgraphics_item_painted = True
+ view = self.scene().views()[0]
+ QTimer.singleShot(20, view.close)
+
+
+class QGraphicsItemTest(UsesQApplication):
+
+ def createRoundRect(self, scene):
+ item = RoundRectItem(10, 10, 100, 100)
+ item.setBrush(QBrush(QColor(255, 0, 0)))
+ scene.addItem(item)
+ return item
+
+ def quit_app(self):
+ self.app.quit()
+
+ def test_setParentItem(self):
+ global qgraphics_item_painted
+
+ scene = QGraphicsScene()
+ scene.addText("test")
+ view = QGraphicsView(scene)
+ view.setWindowTitle("virtual_pure_override_test")
+
+ rect = self.createRoundRect(scene)
+ view.show()
+ self.app.exec()
+ self.assertTrue(qgraphics_item_painted)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/QtWidgets/wrong_return_test.py b/sources/pyside6/tests/QtWidgets/wrong_return_test.py
new file mode 100644
index 000000000..009078ac1
--- /dev/null
+++ b/sources/pyside6/tests/QtWidgets/wrong_return_test.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for Virtual functions with wrong return type'''
+
+import os
+import sys
+import unittest
+import warnings
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QWidget
+from helper.usesqapplication import UsesQApplication
+
+
+warnings.simplefilter('error')
+
+
+class MyWidget(QWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def sizeHint(self):
+ pass
+
+
+class testCase(UsesQApplication):
+
+ def testVirtualReturn(self):
+ w = MyWidget()
+ self.assertWarns(RuntimeWarning, w.show)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/QtXml/CMakeLists.txt b/sources/pyside6/tests/QtXml/CMakeLists.txt
new file mode 100644
index 000000000..feb230af3
--- /dev/null
+++ b/sources/pyside6/tests/QtXml/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(qdomdocument_test.py)
diff --git a/sources/pyside6/tests/QtXml/QtXml.pyproject b/sources/pyside6/tests/QtXml/QtXml.pyproject
new file mode 100644
index 000000000..a0c8a9630
--- /dev/null
+++ b/sources/pyside6/tests/QtXml/QtXml.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["qdomdocument_test.py"]
+}
diff --git a/sources/pyside6/tests/QtXml/qdomdocument_test.py b/sources/pyside6/tests/QtXml/qdomdocument_test.py
new file mode 100644
index 000000000..cfc1c543d
--- /dev/null
+++ b/sources/pyside6/tests/QtXml/qdomdocument_test.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QByteArray
+from PySide6.QtXml import QDomDocument, QDomElement
+
+
+class QDomDocumentTest(unittest.TestCase):
+
+ def setUp(self):
+ self.dom = QDomDocument()
+
+ self.goodXmlData = QByteArray(bytes('''
+ <typesystem package="PySide6.QtXml">
+ <value-type name="QDomDocument"/>
+ <value-type name="QDomElement"/>
+ </typesystem>
+ ''', "UTF-8"))
+
+ self.badXmlData = QByteArray(bytes('''
+ <typesystem package="PySide6.QtXml">
+ <value-type name="QDomDocument">
+ </typesystem>
+ ''', "UTF-8"))
+
+ def tearDown(self):
+ del self.dom
+ del self.goodXmlData
+ del self.badXmlData
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testQDomDocumentSetContentWithBadXmlData(self):
+ '''Sets invalid xml as the QDomDocument contents.'''
+ ok, errorStr, errorLine, errorColumn = self.dom.setContent(self.badXmlData, True)
+ self.assertFalse(ok)
+ self.assertEqual(errorStr, 'Opening and ending tag mismatch.')
+ self.assertEqual(errorLine, 4)
+
+ def testQDomDocumentSetContentWithGoodXmlData(self):
+ '''Sets valid xml as the QDomDocument contents.'''
+ ok, errorStr, errorLine, errorColumn = self.dom.setContent(self.goodXmlData, True)
+ self.assertTrue(ok)
+ self.assertEqual(errorStr, '')
+ self.assertEqual(errorLine, 0)
+ self.assertEqual(errorColumn, 0)
+
+ def testQDomDocumentData(self):
+ '''Checks the QDomDocument elements for the valid xml contents.'''
+
+ def checkAttribute(element, attribute, value):
+ self.assertTrue(isinstance(root, QDomElement))
+ self.assertFalse(element.isNull())
+ self.assertTrue(element.hasAttribute(attribute))
+ self.assertEqual(element.attribute(attribute), value)
+
+ ok, errorStr, errorLine, errorColumn = self.dom.setContent(self.goodXmlData, True)
+ root = self.dom.documentElement()
+ self.assertEqual(root.tagName(), 'typesystem')
+ checkAttribute(root, 'package', 'PySide6.QtXml')
+
+ child = root.firstChildElement('value-type')
+ checkAttribute(child, 'name', 'QDomDocument')
+
+ child = child.nextSiblingElement('value-type')
+ checkAttribute(child, 'name', 'QDomElement')
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/init_paths.py b/sources/pyside6/tests/init_paths.py
new file mode 100644
index 000000000..e69ec1c15
--- /dev/null
+++ b/sources/pyside6/tests/init_paths.py
@@ -0,0 +1,78 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+
+SRC_DIR = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(os.path.join(os.path.dirname(os.path.dirname(SRC_DIR)),
+ 'shiboken6', 'tests'))
+from shiboken_paths import (get_dir_env_var, get_build_dir, add_python_dirs,
+ add_lib_dirs, shiboken_paths)
+
+
+def _get_qt_dir():
+ """Retrieve the location of Qt."""
+ result = None
+ try:
+ result = get_dir_env_var('QT_DIR')
+ except Exception:
+ # This is just a convenience for command line invocation independent
+ # of ctest. Normally, QT_DIR should be set to avoid repetitive patch
+ # searches.
+ print('The environment variable QT_DIR is not set; falling back to path search',
+ file=sys.stderr)
+ qmake = 'qmake.exe' if sys.platform == 'win32' else 'qmake'
+ for path in os.environ.get('PATH').split(os.pathsep):
+ if path and os.path.isfile(os.path.join(path, qmake)):
+ result = os.path.dirname(path)
+ break
+ if not result:
+ raise ValueError('Unable to locate Qt. Please set the environment variable QT_DIR')
+ print(f"Qt as determined by path search: {result}", file=sys.stderr)
+ return result
+
+
+def _get_qt_lib_dir():
+ """Retrieve the location of the Qt library directory."""
+ sub_dir = 'bin' if sys.platform == 'win32' else 'lib'
+ return os.path.join(_get_qt_dir(), sub_dir) # For testbinding
+
+
+def _init_test_paths(shiboken_tests=False, testbindings_module=False):
+ """Sets the correct import paths (Python modules and C++ library paths)
+ for PySide tests and shiboken6 tests using depending on the environment
+ variables BUILD_DIR and QT_DIR pointing to the build directory and
+ Qt directory, respectively."""
+ src_dir = os.path.dirname(os.path.abspath(__file__))
+
+ python_dirs = [os.path.join(src_dir, 'util')] # Helper module
+
+ pyside_build_dir = os.path.join(get_build_dir(), 'pyside6')
+ python_dirs.append(pyside_build_dir) # for PySide6
+ lib_dirs = [os.path.join(pyside_build_dir, 'libpyside'),
+ os.path.join(pyside_build_dir, 'libpysideqml')]
+
+ if testbindings_module:
+ python_dirs.append(os.path.join(pyside_build_dir,
+ 'tests', 'pysidetest'))
+ lib_dirs.append(_get_qt_lib_dir())
+
+ shiboken_path_tuple = shiboken_paths(shiboken_tests)
+ python_dirs.extend(shiboken_path_tuple[0])
+ lib_dirs.extend(shiboken_path_tuple[1])
+
+ add_python_dirs(python_dirs)
+ add_lib_dirs(lib_dirs)
+
+
+def init_test_paths(testbindings_module=False):
+ """Sets the correct import paths for PySide6 tests, optionally including
+ testbindings."""
+ _init_test_paths(False, testbindings_module)
+
+
+def init_all_test_paths():
+ """Sets the correct import paths for PySide6 and shiboken6 tests
+ (for registry checking only)."""
+ _init_test_paths(True, True)
diff --git a/sources/pyside6/tests/mac/CMakeLists.txt b/sources/pyside6/tests/mac/CMakeLists.txt
new file mode 100644
index 000000000..e1eb1a2fd
--- /dev/null
+++ b/sources/pyside6/tests/mac/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(qmacstyle_test.py)
diff --git a/sources/pyside6/tests/mac/qmacstyle_test.py b/sources/pyside6/tests/mac/qmacstyle_test.py
new file mode 100644
index 000000000..18fc64286
--- /dev/null
+++ b/sources/pyside6/tests/mac/qmacstyle_test.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# Qt5: this is gone: from PySide6.QtGui import QMacStyle
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QApplication, QLabel, QStyleFactory
+from PySide6.QtCore import QObject
+
+from helper.usesqapplication import UsesQApplication
+
+
+class QMacStyleTest(UsesQApplication):
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self.QMacStyle = type(QStyleFactory.create('Macintosh'))
+
+ def testWidgetStyle(self):
+ w = QLabel('Hello')
+ self.assertTrue(isinstance(w.style(), self.QMacStyle))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/manually/README.txt b/sources/pyside6/tests/manually/README.txt
new file mode 100644
index 000000000..da20e3824
--- /dev/null
+++ b/sources/pyside6/tests/manually/README.txt
@@ -0,0 +1,5 @@
+To run these tests is necessary some manuall input (most of then not supported by QTest[1]),
+because of that this is not part of automatic test context.
+
+
+[1]http://bugreports.qt.nokia.com/browse/QTBUG-13397
diff --git a/sources/pyside6/tests/manually/bug_841.py b/sources/pyside6/tests/manually/bug_841.py
new file mode 100644
index 000000000..3911244ce
--- /dev/null
+++ b/sources/pyside6/tests/manually/bug_841.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import sys
+
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+from PySide6.QtWidgets import QMainWindow, QTreeView, QAbstractItemView, QApplication, QMessageBox
+
+
+class Item(QStandardItem):
+ def __init__(self, text):
+ super().__init__()
+ self.setText(text)
+ self.setDragEnabled(True)
+ self.setDropEnabled(True)
+
+ def clone(self):
+ ret = Item(self.text())
+ return ret
+
+
+class Project(QStandardItemModel):
+ def __init__(self):
+ super().__init__()
+ self.setItemPrototype(Item("Prototype"))
+ # add some items so we have stuff to move around
+ self.appendRow(Item("ABC"))
+ self.appendRow(Item("DEF"))
+ self.appendRow(Item("GHI"))
+
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super().__init__()
+
+ self.model = Project()
+ self.view = QTreeView(self)
+ self.view.setModel(self.model)
+ self.view.setDragEnabled(True)
+ self.view.setDragDropMode(QAbstractItemView.InternalMove)
+ self.setCentralWidget(self.view)
+
+ def mousePressEvent(self, e):
+ print(e.x(), e.y())
+ return QMainWindow.mousePressEvent(self, e)
+
+
+def main():
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ QMessageBox.information(None, "Info", "Just drag and drop the items.")
+ sys.exit(app.exec())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/sources/pyside6/tests/manually/lazytiming.py b/sources/pyside6/tests/manually/lazytiming.py
new file mode 100644
index 000000000..59f75bc46
--- /dev/null
+++ b/sources/pyside6/tests/manually/lazytiming.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+Time a repeated Python run
+--------------------------
+
+Usage: python3 lazytiming.py # uses PySide6
+ python3 lazytiming.py <any arg> # uses PyQt6
+
+It runs the same python for the testing.
+
+Actually comparing PySide6 and PyQt6 in action:
+
+ PYSIDE6_OPTION_LAZY=0 python3 sources/pyside6/tests/manually/lazytiming.py # normal
+ PYSIDE6_OPTION_LAZY=1 python3 sources/pyside6/tests/manually/lazytiming.py # faster
+ python3 sources/pyside6/tests/manually/lazytiming.py xxx # PyQt
+"""
+import subprocess
+import sys
+
+from timeit import default_timer as timer
+
+repeats = 100
+test1 = "PySide6"
+test2 = "PyQt6"
+
+test = test2 if sys.argv[1:] else test1
+cmd = [sys.executable, "-c", f"from {test} import QtCore, QtGui, QtWidgets"]
+
+print(f"{repeats} * {test}")
+
+subprocess.call(cmd) # warmup
+start_time = timer()
+for idx in range(repeats):
+ subprocess.call(cmd)
+stop_time = timer()
+print(f"time per run = {(stop_time - start_time) / repeats}")
diff --git a/sources/pyside6/tests/pysidetest/CMakeLists.txt b/sources/pyside6/tests/pysidetest/CMakeLists.txt
new file mode 100644
index 000000000..38f42f342
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/CMakeLists.txt
@@ -0,0 +1,171 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+project(pysidetest)
+project(testbinding)
+
+cmake_minimum_required(VERSION 3.18)
+
+set(QT_USE_QTCORE 1)
+# no more supported: include(${QT_USE_FILE})
+
+# removed after qtbase/054b66a65748c9ebfafeca88bf31669a24994237, is this required?
+# add_definitions(${Qt${QT_MAJOR_VERSION}Core_DEFINITIONS})
+
+set(CMAKE_AUTOMOC ON)
+
+add_definitions(-DQT_SHARED)
+add_definitions(-DRXX_ALLOCATOR_INIT_0)
+
+find_package(Qt6 REQUIRED COMPONENTS Widgets)
+
+set(pysidetest_SRC
+containertest.cpp containertest.h
+flagstest.cpp flagstest.h
+hiddenobject.cpp hiddenobject.h
+pysidetest_global.h
+pysidetest_macros.h
+sharedpointertestbench.cpp sharedpointertestbench.h
+testobject.cpp testobject.h
+testview.cpp testview.h
+testqvariantenum.cpp testqvariantenum.h
+)
+
+set(testbinding_SRC
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/containertest_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/flagsnamespace_classforenum_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/testobject_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/intvalue_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/pysidecpp_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/pysidecpp_testobjectwithnamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/pysidecpp_testobject2withnamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/pysidecpp2_testobjectwithoutnamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/qsharedpointer_qobject_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/qsharedpointer_int_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/sharedpointertestbench_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/testview_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/testbinding_module_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/testqvariantenum_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/testbinding/qvariantholder_wrapper.cpp
+)
+
+# Get per module include dirs.
+# There are usually 3 paths there:
+# ./qt/include/; ./qt/include/QtCore ; ./qt/mkspecs/linux-g++
+# on framework build they are:
+# ./qt/lib/QtCore.framework; ./qt/lib/QtCore.framework/Headers ; ./qt/mkspecs/macx-clang
+# Thus we use the second direct path, which contains the actual header files.
+
+set(Qt6Core_DIRECT_INCLUDE_DIR ${Qt6Core_INCLUDE_DIRS})
+set(Qt6Gui_DIRECT_INCLUDE_DIR ${Qt6Gui_INCLUDE_DIRS})
+set(Qt6Widgets_DIRECT_INCLUDE_DIR ${Qt6Widgets_INCLUDE_DIRS})
+
+# Adjust include headers paths for frameworks.
+set(shiboken_framework_include_dirs_option "")
+if(CMAKE_HOST_APPLE AND QtCore_is_framework)
+ set(shiboken_framework_include_dirs "${QT_FRAMEWORK_INCLUDE_DIR}")
+ set(shiboken_framework_include_dirs_option "--framework-include-paths=${shiboken_framework_include_dirs}")
+endif()
+
+make_path(testbinding_include_dirs ${pyside6_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../shiboken6/libshiboken
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../PySide6
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../libpyside
+ ${QT_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_DIRECT_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Gui_DIRECT_INCLUDE_DIR}
+ ${Qt${QT_MAJOR_VERSION}Widgets_DIRECT_INCLUDE_DIR}
+ )
+
+make_path(testbinding_typesystem_path ${pyside6_SOURCE_DIR}
+ ${pyside6_BINARY_DIR})
+
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${testbinding_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ ${GENERATOR_EXTRA_FLAGS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/pysidetest_global.h
+ --include-paths=${testbinding_include_dirs}
+ ${shiboken_framework_include_dirs_option}
+ --typesystem-paths=${testbinding_typesystem_path}
+ --output-directory=${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_pysidetest.xml
+ --api-version=${SUPPORTED_QT_VERSION}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for test binding..."
+)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS}
+ ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS}
+ ${pyside6_SOURCE_DIR}
+ ${QtCore_GEN_DIR}
+ ${QtGui_GEN_DIR}
+ ${QtWidgets_GEN_DIR}
+ ${libpyside_SOURCE_DIR})
+
+add_library(pysidetest SHARED ${pysidetest_SRC})
+set_target_properties(pysidetest PROPERTIES
+ DEFINE_SYMBOL BUILD_PYSIDETEST)
+
+target_link_libraries(pysidetest
+ Shiboken6::libshiboken
+ Qt::Core Qt::Gui Qt::Widgets)
+
+add_library(testbinding MODULE ${testbinding_SRC})
+set_property(TARGET testbinding PROPERTY PREFIX "")
+set_property(TARGET testbinding PROPERTY OUTPUT_NAME "testbinding${SHIBOKEN_PYTHON_EXTENSION_SUFFIX}")
+if(WIN32)
+ set_property(TARGET testbinding PROPERTY SUFFIX ".pyd")
+endif()
+
+target_link_libraries(testbinding
+ pysidetest
+ pyside6
+ Shiboken6::libshiboken
+ Qt::Core Qt::Gui Qt::Widgets)
+
+add_dependencies(testbinding pyside6 QtCore QtGui QtWidgets pysidetest)
+create_generator_target(testbinding)
+
+PYSIDE_TEST(constructor_properties_test.py)
+PYSIDE_TEST(container_test.py)
+PYSIDE_TEST(decoratedslot_test.py)
+PYSIDE_TEST(delegatecreateseditor_test.py)
+PYSIDE_TEST(all_modules_load_test.py)
+PYSIDE_TEST(bug_1016.py)
+PYSIDE_TEST(enum_test.py)
+PYSIDE_TEST(homonymoussignalandmethod_test.py)
+PYSIDE_TEST(iterable_test.py)
+PYSIDE_TEST(list_signal_test.py)
+PYSIDE_TEST(mixin_signal_slots_test.py)
+PYSIDE_TEST(modelview_test.py)
+PYSIDE_TEST(multiple_inheritance_test.py)
+PYSIDE_TEST(new_inherited_functions_test.py)
+PYSIDE_TEST(notify_id.py)
+PYSIDE_TEST(properties_test.py)
+PYSIDE_TEST(property_python_test.py)
+PYSIDE_TEST(snake_case_test.py)
+PYSIDE_TEST(true_property_test.py)
+PYSIDE_TEST(qapp_like_a_macro_test.py)
+PYSIDE_TEST(qvariant_test.py)
+PYSIDE_TEST(repr_test.py)
+PYSIDE_TEST(shared_pointer_test.py)
+PYSIDE_TEST(signal_tp_descr_get_test.py)
+PYSIDE_TEST(signal_slot_warning.py)
+PYSIDE_TEST(signalandnamespace_test.py)
+PYSIDE_TEST(signalemissionfrompython_test.py)
+PYSIDE_TEST(signalinstance_equality_test.py)
+PYSIDE_TEST(signalwithdefaultvalue_test.py)
+PYSIDE_TEST(typedef_signal_test.py)
+PYSIDE_TEST(version_test.py)
+PYSIDE_TEST(mock_as_slot_test.py)
+PYSIDE_TEST(pyenum_relax_options_test.py)
diff --git a/sources/pyside6/tests/pysidetest/all_modules_load_test.py b/sources/pyside6/tests/pysidetest/all_modules_load_test.py
new file mode 100644
index 000000000..454c2b14f
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/all_modules_load_test.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+
+# Note:
+# "from PySide6 import *" can only be used at module level.
+# It is also really not recommended to use. But for testing,
+# the "__all__" variable is a great feature!
+
+
+class AllModulesImportTest(unittest.TestCase):
+ def testAllModulesCanImport(self):
+ # would also work: exec("from PySide6 import *")
+ for name in PySide6.__all__:
+ exec(f"import PySide6.{name}")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/bug_1016.py b/sources/pyside6/tests/pysidetest/bug_1016.py
new file mode 100644
index 000000000..219384e66
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/bug_1016.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+import shiboken6
+from testbinding import getHiddenObject
+
+
+class TestBug1016 (unittest.TestCase):
+
+ def testIt(self):
+ obj = getHiddenObject()
+ self.assertEqual(obj.callMe(), None)
+ self.assertTrue(obj.wasCalled())
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/constructor_properties_test.py b/sources/pyside6/tests/pysidetest/constructor_properties_test.py
new file mode 100644
index 000000000..ec6e39821
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/constructor_properties_test.py
@@ -0,0 +1,127 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QColor, QAction
+from PySide6.QtWidgets import QApplication, QLabel, QFrame
+
+is_pypy = hasattr(sys, "pypy_version_info")
+if not is_pypy:
+ from PySide6.support import feature
+
+
+class ConstructorPropertiesTest(unittest.TestCase):
+
+ def setUp(self):
+ qApp or QApplication()
+ if not is_pypy:
+ feature.reset()
+
+ def tearDown(self):
+ if not is_pypy:
+ feature.reset()
+ qApp.shutdown()
+
+ # PYSIDE-1019: First property extension was support by the constructor.
+ def testCallConstructor(self):
+ label = QLabel(
+ frameStyle=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
+ lineWidth=2, # QFrame property
+ text="first line\nsecond line", # QLabel property
+ alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
+ )
+ self.assertEqual(label.lineWidth(), 2)
+ self.assertRaises(AttributeError, lambda: QLabel(
+ somethingelse=42,
+ ))
+
+ # PYSIDE-1705: The same with snake_case
+ @unittest.skipIf(is_pypy, "feature switching is not yet possible in PyPy")
+ def testCallConstructor_snake(self):
+ from __feature__ import snake_case
+
+ label = QLabel(
+ frame_style=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
+ line_width=2, # QFrame property
+ text="first line\nsecond line", # QLabel property
+ alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
+ )
+ self.assertEqual(label.line_width(), 2)
+ self.assertRaises(AttributeError, lambda: QLabel(
+ lineWidth=2, # QFrame property
+ ))
+
+ # PYSIDE-1705: The same with true_property
+ @unittest.skipIf(is_pypy, "feature switching is not yet possible in PyPy")
+ def testCallConstructor_prop(self):
+ from __feature__ import true_property
+
+ label = QLabel(
+ frameStyle=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
+ lineWidth=2, # QFrame property
+ text="first line\nsecond line", # QLabel property
+ alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
+ )
+ self.assertEqual(label.lineWidth, 2)
+ self.assertRaises(AttributeError, lambda: QLabel(
+ line_width=2, # QFrame property
+ ))
+
+ # PYSIDE-1705: The same with snake_case and true_property
+ @unittest.skipIf(is_pypy, "feature switching is not yet possible in PyPy")
+ def testCallConstructor_prop_snake(self):
+ from __feature__ import snake_case, true_property
+
+ label = QLabel(
+ frame_style=QFrame.Panel | QFrame.Sunken, # QFrame attr, no property
+ line_width=2, # QFrame property
+ text="first line\nsecond line", # QLabel property
+ alignment=Qt.AlignBottom | Qt.AlignRight # QLabel property
+ )
+ self.assertEqual(label.line_width, 2)
+ self.assertRaises(AttributeError, lambda: QLabel(
+ lineWidth=2, # QFrame property
+ ))
+
+
+class DiverseKeywordsTest(UsesQApplication):
+
+ def testDuplicateKeyword(self):
+ r, g, b, a = 1, 2, 3, 4
+ with self.assertRaises(TypeError) as cm:
+ QColor(r, g, b, a, a=0)
+ self.assertTrue("multiple" in cm.exception.args[0])
+
+ # PYSIDE-1305: Handle keyword args correctly.
+ def testUndefinedKeyword(self):
+ r, g, b, a = 1, 2, 3, 4
+ # From the jira issue:
+ with self.assertRaises(AttributeError) as cm:
+ QColor(r, g, b, a, alpha=0)
+ self.assertTrue("unsupported" in cm.exception.args[0])
+
+ # PYSIDE-1305: Handle keyword args correctly.
+ def testUndefinedConstructorKeyword(self):
+ # make sure that the given attribute lands in the constructor
+ x = QAction(autoRepeat=False)
+ self.assertEqual(x.autoRepeat(), False)
+ x = QAction(autoRepeat=True)
+ self.assertEqual(x.autoRepeat(), True)
+ # QAction derives from QObject, and so the missing attributes
+ # in the constructor are reported as AttributeError.
+ with self.assertRaises(AttributeError):
+ QAction(some_other_name=42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/container_test.py b/sources/pyside6/tests/pysidetest/container_test.py
new file mode 100644
index 000000000..c83e1f26c
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/container_test.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import ContainerTest
+
+
+EXPECTED_DICT = {1: ["v1"], 2: ["v2_1", "v2_2"],
+ 3: ["v3"],
+ 4: ["v4_1", "v4_2"]}
+
+
+EXPECTED_LIST = [1, 2]
+
+
+def sort_values(m):
+ """Sort value lists in dicts since passing through a QMultiMap changes the order"""
+ result = {}
+ for key, values in m.items():
+ result[key] = sorted(values)
+ return result
+
+
+class ContainerTestTest(unittest.TestCase):
+
+ def testMultiMap(self):
+ m1 = ContainerTest.createMultiMap()
+ self.assertEqual(sort_values(m1), EXPECTED_DICT)
+ m2 = ContainerTest.passThroughMultiMap(m1)
+ self.assertEqual(sort_values(m2), EXPECTED_DICT)
+
+ def testMultiHash(self):
+ m1 = ContainerTest.createMultiHash()
+ self.assertEqual(sort_values(m1), EXPECTED_DICT)
+ m2 = ContainerTest.passThroughMultiHash(m1)
+ self.assertEqual(sort_values(m2), EXPECTED_DICT)
+
+ def testList(self):
+ l1 = ContainerTest.createList()
+ self.assertEqual(l1, EXPECTED_LIST)
+ l2 = ContainerTest.passThroughList(l1)
+ self.assertEqual(l2, EXPECTED_LIST)
+
+ def testSet(self):
+ s1 = ContainerTest.createSet() # Order is not predictable
+ s2 = ContainerTest.passThroughSet(s1)
+ self.assertEqual(sorted(list(s1)), sorted(list(s2)))
+
+ # Since lists are iterable, it should be possible to pass them to set API
+ l2 = ContainerTest.passThroughSet(EXPECTED_LIST)
+ self.assertEqual(sorted(list(l2)), EXPECTED_LIST)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/containertest.cpp b/sources/pyside6/tests/pysidetest/containertest.cpp
new file mode 100644
index 000000000..da8729af3
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/containertest.cpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "containertest.h"
+
+using namespace Qt::StringLiterals;
+
+ContainerTest::ContainerTest() = default;
+
+QMultiMap<int, QString> ContainerTest::createMultiMap()
+{
+ static const QMultiMap<int, QString>
+ result{{1, u"v1"_s},
+ {2, u"v2_1"_s}, {2, u"v2_2"_s},
+ {3, u"v3"_s},
+ {4, u"v4_1"_s}, {4, u"v4_2"_s}};
+ return result;
+}
+
+QMultiMap<int, QString> ContainerTest::passThroughMultiMap(const QMultiMap<int, QString> &in)
+{
+ return in;
+}
+
+QMultiHash<int, QString> ContainerTest::createMultiHash()
+{
+ static const QMultiHash<int, QString>
+ result{{1, u"v1"_s},
+ {2, u"v2_1"_s}, {2, u"v2_2"_s},
+ {3, u"v3"_s},
+ {4, u"v4_1"_s}, {4, u"v4_2"_s}};
+ return result;
+
+}
+
+QMultiHash<int, QString> ContainerTest::passThroughMultiHash(const QMultiHash<int, QString> &in)
+{
+ return in;
+}
+
+QList<int> ContainerTest::createList()
+{
+ return {1, 2};
+}
+
+QList<int> ContainerTest::passThroughList(const QList<int> &list)
+{
+ return list;
+}
+
+QSet<int> ContainerTest::createSet()
+{
+ return {1, 2};
+}
+
+QSet<int> ContainerTest::passThroughSet(const QSet<int> &set)
+{
+ return set;
+}
diff --git a/sources/pyside6/tests/pysidetest/containertest.h b/sources/pyside6/tests/pysidetest/containertest.h
new file mode 100644
index 000000000..068fb3c19
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/containertest.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "pysidetest_macros.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QMultiMap>
+#include <QtCore/QMultiHash>
+#include <QtCore/QSet>
+#include <QtCore/QString>
+
+class PYSIDETEST_API ContainerTest
+{
+public:
+ ContainerTest();
+
+ static QMultiMap<int, QString> createMultiMap();
+
+ static QMultiMap<int, QString> passThroughMultiMap(const QMultiMap<int, QString> &in);
+
+ static QMultiHash<int, QString> createMultiHash();
+
+ static QMultiHash<int, QString> passThroughMultiHash(const QMultiHash<int, QString> &in);
+
+ static QList<int> createList();
+ static QList<int> passThroughList(const QList<int> &list);
+
+ static QSet<int> createSet();
+ static QSet<int> passThroughSet(const QSet<int> &set);
+};
diff --git a/sources/pyside6/tests/pysidetest/curr_errors.txt b/sources/pyside6/tests/pysidetest/curr_errors.txt
new file mode 100644
index 000000000..a02da203d
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/curr_errors.txt
@@ -0,0 +1,12 @@
+Generating class model... [OK]
+Generating enum model... [OK]
+Generating namespace model... [OK]
+Resolving typedefs... [OK]
+Fixing class inheritance... [OK]
+Detecting inconsistencies in class model... [OK]
+[OK]
+ type 'QPyTextObject' is specified in typesystem, but not defined. This could potentially lead to compilation errors.
+
+
+
+Done, 1 warnings (1051 known issues)
diff --git a/sources/pyside6/tests/pysidetest/decoratedslot_test.py b/sources/pyside6/tests/pysidetest/decoratedslot_test.py
new file mode 100644
index 000000000..3ec9ac9e3
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/decoratedslot_test.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from PySide6.QtCore import QObject
+from testbinding import TestObject
+
+
+class Receiver(QObject):
+ def __init__(self):
+ super().__init__()
+ self.called = False
+
+ def ReceiverDecorator(func):
+ def decoratedFunction(self, *args, **kw):
+ func(self, *args, **kw)
+ return decoratedFunction
+
+ # This method with the same name of the internal decorated function
+ # is here to test the binding capabilities.
+ def decoratedFunction(self):
+ pass
+
+ @ReceiverDecorator
+ def slot(self):
+ self.called = True
+
+
+class DecoratedSlotTest(unittest.TestCase):
+
+ def testCallingOfDecoratedSlot(self):
+ obj = TestObject(0)
+ receiver = Receiver()
+ obj.staticMethodDouble.connect(receiver.slot)
+ obj.emitStaticMethodDoubleSignal()
+ self.assertTrue(receiver.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/delegatecreateseditor_test.py b/sources/pyside6/tests/pysidetest/delegatecreateseditor_test.py
new file mode 100644
index 000000000..8964ec1ed
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/delegatecreateseditor_test.py
@@ -0,0 +1,81 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from helper.usesqapplication import UsesQApplication
+from testbinding import TestView
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+from PySide6.QtWidgets import (QAbstractItemDelegate, QComboBox,
+ QSpinBox, QStyledItemDelegate,
+ QStyleOptionViewItem, QWidget)
+
+id_text = 'This is me'
+
+
+class DelegateDoesntKeepReferenceToEditor(QAbstractItemDelegate):
+ def createEditor(self, parent, option, index):
+ comboBox = QComboBox(parent)
+ comboBox.addItem(id_text)
+ return comboBox
+
+
+class DelegateKeepsReferenceToEditor(QAbstractItemDelegate):
+ def __init__(self, parent=None):
+ QAbstractItemDelegate.__init__(self, parent)
+ self.comboBox = QComboBox()
+ self.comboBox.addItem(id_text)
+
+ def createEditor(self, parent, option, index):
+ self.comboBox.setParent(parent)
+ return self.comboBox
+
+
+class EditorCreatedByDelegateTest(UsesQApplication):
+
+ def testDelegateDoesntKeepReferenceToEditor(self):
+ view = TestView(None)
+ delegate = DelegateDoesntKeepReferenceToEditor()
+ view.setItemDelegate(delegate)
+ editor = view.getEditorWidgetFromItemDelegate()
+ self.assertEqual(type(editor), QComboBox)
+ self.assertEqual(editor.count(), 1)
+ self.assertEqual(editor.itemData(0, Qt.DisplayRole), id_text)
+ editor.metaObject()
+
+ def testDelegateKeepsReferenceToEditor(self):
+ view = TestView(None)
+ delegate = DelegateKeepsReferenceToEditor()
+ view.setItemDelegate(delegate)
+ editor = view.getEditorWidgetFromItemDelegate()
+ self.assertEqual(type(editor), QComboBox)
+ self.assertEqual(editor.count(), 1)
+ self.assertEqual(editor.itemData(0, Qt.DisplayRole), id_text)
+ editor.metaObject()
+
+ def testIntDelegate(self):
+ """PYSIDE-1250: When creating a QVariant, use int instead of long long
+ for anything that fits into a int. Verify by checking that a spin
+ box is created as item view editor for int."""
+ item = QStandardItem()
+ item.setData(123123, Qt.EditRole) # <-- QVariant conversion here
+ model = QStandardItemModel()
+ model.appendRow(item)
+ style_option = QStyleOptionViewItem()
+ delegate = QStyledItemDelegate()
+ editor = delegate.createEditor(None, style_option, model.index(0, 0))
+ self.assertEqual(type(editor), QSpinBox)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/enum_test.py b/sources/pyside6/tests/pysidetest/enum_test.py
new file mode 100644
index 000000000..832834530
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/enum_test.py
@@ -0,0 +1,186 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from PySide6.QtCore import Qt
+from testbinding import Enum1, TestObjectWithoutNamespace
+
+import dis
+
+
+class ListConnectionTest(unittest.TestCase):
+
+ def testEnumVisibility(self):
+ self.assertEqual(Enum1.Option1, 1)
+ self.assertEqual(Enum1.Option2, 2)
+ self.assertEqual(TestObjectWithoutNamespace.Enum2.Option3, 3)
+ self.assertEqual(TestObjectWithoutNamespace.Enum2.Option4, 4)
+
+ def testFlagComparisonOperators(self): # PYSIDE-1696, compare to self
+ f1 = Qt.AlignHCenter | Qt.AlignBottom
+ f2 = Qt.AlignHCenter | Qt.AlignBottom
+ self.assertTrue(f1 == f1)
+ self.assertTrue(f1 <= f1)
+ self.assertTrue(f1 >= f1)
+ self.assertFalse(f1 != f1)
+ self.assertFalse(f1 < f1)
+ self.assertFalse(f1 > f1)
+
+ self.assertTrue(f1 == f2)
+ self.assertTrue(f1 <= f2)
+ self.assertTrue(f1 >= f2)
+ self.assertFalse(f1 != f2)
+ self.assertFalse(f1 < f2)
+ self.assertFalse(f1 > f2)
+
+ self.assertTrue(Qt.AlignHCenter < Qt.AlignBottom)
+ self.assertFalse(Qt.AlignHCenter > Qt.AlignBottom)
+ self.assertFalse(Qt.AlignBottom < Qt.AlignHCenter)
+ self.assertTrue(Qt.AlignBottom > Qt.AlignHCenter)
+
+
+# PYSIDE-1735: We are testing that opcodes do what they are supposed to do.
+# This is needed in the PyEnum forgiveness mode where we need
+# to introspect the code if an Enum was called with no args.
+class InvestigateOpcodesTest(unittest.TestCase):
+
+ def probe_function1(self):
+ x = Qt.Alignment
+
+ def probe_function2(self):
+ x = Qt.Alignment()
+
+ @staticmethod
+ def read_code(func, **kw):
+ return list(instr[:3] for instr in dis.Bytecode(func, **kw))
+
+ @staticmethod
+ def get_sizes(func, **kw):
+ ops = list((instr.opname, instr.offset) for instr in dis.Bytecode(func, **kw))
+ res = []
+ for idx in range(1, len(ops)):
+ res.append((ops[idx - 1][0], ops[idx][1] - ops[idx - 1][1]))
+ return sorted(res, key=lambda x: (x[1], x[0]))
+
+ _sin = sys.implementation.name
+
+ @unittest.skipIf(hasattr(sys.flags, "nogil"), f"{_sin} has different opcodes")
+ def testByteCode(self):
+ import dis
+ # opname, opcode, arg
+ result_1 = [('LOAD_GLOBAL', 116, 0),
+ ('LOAD_ATTR', 106, 1),
+ ('STORE_FAST', 125, 1),
+ ('LOAD_CONST', 100, 0),
+ ('RETURN_VALUE', 83, None)]
+
+ result_2 = [('LOAD_GLOBAL', 116, 0),
+ ('LOAD_METHOD', 160, 1),
+ ('CALL_METHOD', 161, 0),
+ ('STORE_FAST', 125, 1),
+ ('LOAD_CONST', 100, 0),
+ ('RETURN_VALUE', 83, None)]
+
+ if sys.version_info[:2] <= (3, 6):
+
+ result_2 = [('LOAD_GLOBAL', 116, 0),
+ ('LOAD_ATTR', 106, 1),
+ ('CALL_FUNCTION', 131, 0),
+ ('STORE_FAST', 125, 1),
+ ('LOAD_CONST', 100, 0),
+ ('RETURN_VALUE', 83, None)]
+
+ if sys.version_info[:2] == (3, 11):
+ # Note: Python 3.11 is a bit more complex because it can optimize itself.
+ # Opcodes are a bit different, and a hidden second code object is used.
+ # We investigate this a bit, because we want to be warned when things change.
+ QUICKENING_WARMUP_DELAY = 8
+
+ result_1 = [('RESUME', 151, 0),
+ ('LOAD_GLOBAL', 116, 0),
+ ('LOAD_ATTR', 106, 1),
+ ('STORE_FAST', 125, 1),
+ ('LOAD_CONST', 100, 0),
+ ('RETURN_VALUE', 83, None)]
+
+ result_2 = [('RESUME', 151, 0),
+ ('LOAD_GLOBAL', 116, 1),
+ ('LOAD_ATTR', 106, 1),
+ ('PRECALL', 166, 0),
+ ('CALL', 171, 0),
+ ('STORE_FAST', 125, 1),
+ ('LOAD_CONST', 100, 0),
+ ('RETURN_VALUE', 83, None)]
+
+ sizes_2 = [('LOAD_CONST', 2),
+ ('RESUME', 2),
+ ('STORE_FAST', 2),
+ ('PRECALL', 4),
+ ('CALL', 10),
+ ('LOAD_ATTR', 10),
+ ('LOAD_GLOBAL', 12)]
+
+ self.assertEqual(self.read_code(self.probe_function2, adaptive=True), result_2)
+ self.assertEqual(self.get_sizes(self.probe_function2, adaptive=True), sizes_2)
+
+ @staticmethod
+ def code_quicken(f, times):
+ # running the code triggers acceleration after some runs.
+ for _ in range(times):
+ f()
+
+ code_quicken(self.probe_function2, QUICKENING_WARMUP_DELAY - 1)
+ self.assertEqual(self.read_code(self.probe_function2, adaptive=True), result_2)
+ self.assertEqual(self.get_sizes(self.probe_function2, adaptive=True), sizes_2)
+
+ result_3 = [('RESUME_QUICK', 150, 0),
+ ('LOAD_GLOBAL_MODULE', 55, 1),
+ ('LOAD_ATTR_ADAPTIVE', 39, 1),
+ ('PRECALL_ADAPTIVE', 64, 0),
+ ('CALL_ADAPTIVE', 22, 0),
+ ('STORE_FAST', 125, 1),
+ ('LOAD_CONST', 100, 0),
+ ('RETURN_VALUE', 83, None)]
+
+ sizes_3 = [('LOAD_CONST', 2),
+ ('RESUME_QUICK', 2),
+ ('STORE_FAST', 2),
+ ('PRECALL_ADAPTIVE', 4),
+ ('CALL_ADAPTIVE', 10),
+ ('LOAD_ATTR_ADAPTIVE', 10),
+ ('LOAD_GLOBAL_MODULE', 12)]
+
+ code_quicken(self.probe_function2, 1)
+ self.assertEqual(self.read_code(self.probe_function2, adaptive=True), result_3)
+ self.assertEqual(self.get_sizes(self.probe_function2, adaptive=True), sizes_3)
+
+ if sys.version_info[:2] >= (3, 12):
+
+ result_1 = [('RESUME', 151, 0),
+ ('LOAD_GLOBAL', 116, 0),
+ ('LOAD_ATTR', 106, 2),
+ ('STORE_FAST', 125, 1),
+ ('RETURN_CONST', 121, 0)]
+
+ result_2 = [('RESUME', 151, 0),
+ ('LOAD_GLOBAL', 116, 1),
+ ('LOAD_ATTR', 106, 2),
+ ('CALL', 171, 0),
+ ('STORE_FAST', 125, 1),
+ ('RETURN_CONST', 121, 0)]
+
+ self.assertEqual(self.read_code(self.probe_function1), result_1)
+ self.assertEqual(self.read_code(self.probe_function2), result_2)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/flagstest.cpp b/sources/pyside6/tests/pysidetest/flagstest.cpp
new file mode 100644
index 000000000..ac6c3b3b1
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/flagstest.cpp
@@ -0,0 +1,11 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "flagstest.h"
+
+namespace FlagsNamespace
+{
+ ClassForEnum::ClassForEnum(FlagsNamespace::Options) {}
+
+ ClassForEnum::~ClassForEnum() = default;
+}
diff --git a/sources/pyside6/tests/pysidetest/flagstest.h b/sources/pyside6/tests/pysidetest/flagstest.h
new file mode 100644
index 000000000..b5c73c9bd
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/flagstest.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "pysidetest_macros.h"
+
+#include <QtCore/QObject>
+
+namespace FlagsNamespace
+{
+
+enum Option {
+ NoOptions = 0x0,
+ ShowTabs = 0x1,
+ ShowAll = 0x2,
+ SqueezeBlank = 0x4
+};
+Q_DECLARE_FLAGS(Options, Option)
+Q_DECLARE_OPERATORS_FOR_FLAGS(Options)
+
+class PYSIDETEST_API ClassForEnum : public QObject
+{
+ Q_OBJECT
+public:
+ Q_DISABLE_COPY_MOVE(ClassForEnum)
+
+ ClassForEnum(FlagsNamespace::Options opt = FlagsNamespace::Option::NoOptions);
+ virtual ~ClassForEnum() override;
+};
+
+} // namespace FlagsNamespace
diff --git a/sources/pyside6/tests/pysidetest/hiddenobject.cpp b/sources/pyside6/tests/pysidetest/hiddenobject.cpp
new file mode 100644
index 000000000..d4feabb66
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/hiddenobject.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "hiddenobject.h"
+
+void HiddenObject::callMe()
+{
+ m_called = true;
+}
+
+bool HiddenObject::wasCalled() const
+{
+ return m_called;
+}
+
+QObject *getHiddenObject()
+{
+ return new HiddenObject();
+}
diff --git a/sources/pyside6/tests/pysidetest/hiddenobject.h b/sources/pyside6/tests/pysidetest/hiddenobject.h
new file mode 100644
index 000000000..f399be985
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/hiddenobject.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef HIDDENOBJECT_H
+#define HIDDENOBJECT_H
+
+#include "pysidetest_macros.h"
+
+#include <QtCore/QObject>
+
+// This class shouldn't be exported!
+class HiddenObject : public QObject
+{
+ Q_OBJECT
+public:
+ HiddenObject() noexcept = default;
+ Q_INVOKABLE void callMe();
+public Q_SLOTS:
+ bool wasCalled() const;
+private:
+ bool m_called = false;
+};
+
+// Return a instance of HiddenObject
+PYSIDETEST_API QObject* getHiddenObject();
+
+#endif
diff --git a/sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py b/sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py
new file mode 100644
index 000000000..b58232a1b
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/homonymoussignalandmethod_test.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import TestObject
+from PySide6.QtCore import QObject, Signal, SignalInstance
+
+'''Tests the behaviour of homonymous signals and slots.'''
+
+
+class HomonymousSignalAndMethodTest(unittest.TestCase):
+
+ def setUp(self):
+ self.value = 123
+ self.called = False
+ self.obj = TestObject(self.value)
+
+ def tearDown(self):
+ del self.value
+ del self.called
+ del self.obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testIdValueSignalEmission(self):
+ def callback(idValue):
+ self.assertEqual(idValue, self.value)
+ self.obj.idValue.connect(callback)
+ self.obj.emitIdValueSignal()
+
+ def testStaticMethodDoubleSignalEmission(self):
+ def callback():
+ self.called = True
+ self.obj.staticMethodDouble.connect(callback)
+ self.obj.emitStaticMethodDoubleSignal()
+ self.assertTrue(self.called)
+
+ def testSignalNotCallable(self):
+ self.assertRaises(TypeError, self.obj.justASignal)
+
+ def testCallingInstanceMethodWithArguments(self):
+ self.assertRaises(TypeError, TestObject.idValue, 1)
+
+ def testCallingInstanceMethodWithoutArguments(self):
+ self.assertRaises(TypeError, TestObject.idValue)
+
+ def testHomonymousSignalAndMethod(self):
+ self.assertEqual(self.obj.idValue(), self.value)
+
+ def testHomonymousSignalAndStaticMethod(self):
+ self.assertEqual(TestObject.staticMethodDouble(3), 6)
+
+ def testHomonymousSignalAndStaticMethodFromInstance(self):
+ self.assertEqual(self.obj.staticMethodDouble(4), 8)
+
+
+# PYSIDE-1730: Homonymous Methods with multiple inheritance
+
+class Q(QObject):
+ signal = Signal()
+
+ def method(self):
+ msg = 'Q::method'
+ print(msg)
+ return msg
+
+
+class M:
+
+ def signal(self):
+ msg = 'M::signal'
+ print(msg)
+ return msg
+
+ def method(self):
+ msg = 'M::method'
+ print(msg)
+ return msg
+
+
+class C(M, Q):
+
+ def __init__(self):
+ Q.__init__(self)
+ M.__init__(self)
+
+
+class HomonymousMultipleInheritanceTest(unittest.TestCase):
+
+ def testHomonymousMultipleInheritance(self):
+ c = C()
+ self.assertEqual(c.method(), "M::method") # okay
+ self.assertEqual(c.signal(), "M::signal") # problem on PySide6 6.2.2
+ self.assertEqual(type(c.signal), SignalInstance)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/iterable_test.py b/sources/pyside6/tests/pysidetest/iterable_test.py
new file mode 100644
index 000000000..bdb2ae7be
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/iterable_test.py
@@ -0,0 +1,68 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+iterable_test.py
+
+This test checks that the Iterable protocol is implemented correctly.
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+from PySide6 import QtCore, QtGui
+
+try:
+ import numpy as np
+ have_numpy = True
+except ImportError:
+ have_numpy = False
+
+
+class PySequenceTest(unittest.TestCase):
+
+ def test_iterable(self):
+ def gen(lis):
+ for item in lis:
+ if item == "crash":
+ raise IndexError
+ yield item
+ # testing "pyseq_to_cpplist_conversion"
+ testfunc = QtCore.QUrl.fromStringList
+ # use a generator (iterable)
+ self.assertEqual(testfunc(gen(["asd", "ghj"])),
+ [PySide6.QtCore.QUrl('asd'), PySide6.QtCore.QUrl('ghj')])
+ # use an iterator
+ self.assertEqual(testfunc(iter(["asd", "ghj"])),
+ [PySide6.QtCore.QUrl('asd'), PySide6.QtCore.QUrl('ghj')])
+ self.assertRaises(IndexError, testfunc, gen(["asd", "crash", "ghj"]))
+ # testing QMatrix4x4
+ testfunc = QtGui.QMatrix4x4
+ self.assertEqual(testfunc(gen(range(16))), testfunc(range(16)))
+ # Note: The errormessage needs to be improved!
+ # We should better get a ValueError
+ self.assertRaises((TypeError, ValueError), testfunc, gen(range(15)))
+ # All other matrix sizes:
+ testfunc = QtGui.QMatrix2x2
+ self.assertEqual(testfunc(gen(range(4))), testfunc(range(4)))
+ testfunc = QtGui.QMatrix2x3
+ self.assertEqual(testfunc(gen(range(6))), testfunc(range(6)))
+
+ @unittest.skipUnless(have_numpy, "requires numpy")
+ def test_iterable_numpy(self):
+ # Demo for numpy: We create a unit matrix.
+ num_mat = np.eye(4)
+ num_mat.shape = 16
+ unit = QtGui.QMatrix4x4(num_mat)
+ self.assertEqual(unit, QtGui.QMatrix4x4())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/list_signal_test.py b/sources/pyside6/tests/pysidetest/list_signal_test.py
new file mode 100644
index 000000000..da4bc298d
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/list_signal_test.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import TestObject
+from PySide6.QtCore import QObject
+
+
+class ListConnectionTest(unittest.TestCase):
+
+ def childrenChanged(self, children):
+ self._child = children[0]
+
+ def testConnection(self):
+ o = TestObject(0)
+ c = QObject()
+ c.setObjectName("child")
+ self._child = None
+ o.childrenChanged.connect(self.childrenChanged)
+ o.addChild(c)
+ self.assertEqual(self._child.objectName(), "child")
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/mixin_signal_slots_test.py b/sources/pyside6/tests/pysidetest/mixin_signal_slots_test.py
new file mode 100644
index 000000000..1d536c0ae
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/mixin_signal_slots_test.py
@@ -0,0 +1,205 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' PYSIDE-315: https://bugreports.qt.io/browse/PYSIDE-315
+ Test that all signals and slots of a class (including any mixin classes)
+ are registered at type parsing time. Also test that the signal and slot
+ indices do not change after signal connection or emission. '''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Slot
+
+
+class Mixin(object):
+ mixinSignal = Signal()
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+
+class MixinTwo(Mixin):
+ mixinTwoSignal = Signal()
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.mixinTwoSlotCalled = False
+
+ @Slot()
+ def mixinTwoSlot(self):
+ self.mixinTwoSlotCalled = True
+
+
+class MixinThree(object):
+ mixinThreeSignal = Signal()
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.mixinThreeSlotCalled = False
+
+ @Slot()
+ def mixinThreeSlot(self):
+ self.mixinThreeSlotCalled = True
+
+
+class Derived(Mixin, QObject):
+ derivedSignal = Signal(str)
+
+ def __init__(self):
+ super().__init__()
+ self.derivedSlotCalled = False
+ self.derivedSlotString = ''
+
+ @Slot(str)
+ def derivedSlot(self, theString):
+ self.derivedSlotCalled = True
+ self.derivedSlotString = theString
+
+
+class MultipleDerived(MixinTwo, MixinThree, Mixin, QObject):
+ derivedSignal = Signal(str)
+
+ def __init__(self):
+ super().__init__()
+ self.derivedSlotCalled = False
+ self.derivedSlotString = ''
+
+ @Slot(str)
+ def derivedSlot(self, theString):
+ self.derivedSlotCalled = True
+ self.derivedSlotString = theString
+
+
+class MixinTest(unittest.TestCase):
+ def testMixinSignalSlotRegistration(self):
+ obj = Derived()
+ m = obj.metaObject()
+
+ # Should contain 2 signals and 1 slot immediately after type parsing
+ self.assertEqual(m.methodCount() - m.methodOffset(), 3)
+
+ # Save method indices to check that they do not change
+ methodIndices = {}
+ for i in range(m.methodOffset(), m.methodCount()):
+ signature = m.method(i).methodSignature()
+ methodIndices[signature] = i
+
+ # Check derivedSignal emission
+ obj.derivedSignal.connect(obj.derivedSlot)
+ obj.derivedSignal.emit('emit1')
+ self.assertTrue(obj.derivedSlotCalled)
+ obj.derivedSlotCalled = False
+
+ # Check derivedSignal emission after mixingSignal connection
+ self.outsideSlotCalled = False
+
+ @Slot()
+ def outsideSlot():
+ self.outsideSlotCalled = True
+
+ obj.mixinSignal.connect(outsideSlot)
+ obj.derivedSignal.emit('emit2')
+ self.assertTrue(obj.derivedSlotCalled)
+ self.assertFalse(self.outsideSlotCalled)
+ obj.derivedSlotCalled = False
+
+ # Check mixinSignal emission
+ obj.mixinSignal.emit()
+ self.assertTrue(self.outsideSlotCalled)
+ self.assertFalse(obj.derivedSlotCalled)
+ self.outsideSlotCalled = False
+
+ # Check that method indices haven't changed.
+ # Make sure to requery for the meta object, to check that a new one was not
+ # created as a child of the old one.
+ m = obj.metaObject()
+ self.assertEqual(m.methodCount() - m.methodOffset(), 3)
+ for i in range(m.methodOffset(), m.methodCount()):
+ signature = m.method(i).methodSignature()
+ self.assertEqual(methodIndices[signature], i)
+
+ def testMixinSignalSlotRegistrationWithMultipleInheritance(self):
+ obj = MultipleDerived()
+ m = obj.metaObject()
+
+ # Should contain 4 signals and 3 slots immediately after type parsing
+ self.assertEqual(m.methodCount() - m.methodOffset(), 7)
+
+ # Save method indices to check that they do not change
+ methodIndices = {}
+ for i in range(m.methodOffset(), m.methodCount()):
+ signature = m.method(i).methodSignature()
+ methodIndices[signature] = i
+
+ # Check derivedSignal emission
+ obj.derivedSignal.connect(obj.derivedSlot)
+ obj.derivedSignal.emit('emit1')
+ self.assertTrue(obj.derivedSlotCalled)
+ self.assertFalse(obj.mixinTwoSlotCalled)
+ self.assertFalse(obj.mixinThreeSlotCalled)
+ obj.derivedSlotCalled = False
+
+ # Check derivedSignal emission after mixinThreeSignal connection
+ self.outsideSlotCalled = False
+
+ @Slot()
+ def outsideSlot():
+ self.outsideSlotCalled = True
+
+ obj.mixinThreeSignal.connect(obj.mixinThreeSlot)
+ obj.mixinThreeSignal.connect(outsideSlot)
+ obj.derivedSignal.emit('emit2')
+ self.assertTrue(obj.derivedSlotCalled)
+ self.assertFalse(obj.mixinTwoSlotCalled)
+ self.assertFalse(obj.mixinThreeSlotCalled)
+ self.assertFalse(self.outsideSlotCalled)
+ obj.derivedSlotCalled = False
+
+ # Check mixinThreeSignal emission
+ obj.mixinThreeSignal.emit()
+ self.assertTrue(self.outsideSlotCalled)
+ self.assertTrue(obj.mixinThreeSlotCalled)
+ self.assertFalse(obj.derivedSlotCalled)
+ self.assertFalse(obj.mixinTwoSlotCalled)
+ self.outsideSlotCalled = False
+ obj.mixinThreeSlotCalled = False
+
+ # Check mixinTwoSignal emission
+ obj.mixinTwoSignal.connect(obj.mixinTwoSlot)
+ obj.mixinTwoSignal.emit()
+ self.assertTrue(obj.mixinTwoSlotCalled)
+ self.assertFalse(obj.mixinThreeSlotCalled)
+ self.assertFalse(obj.derivedSlotCalled)
+ self.assertFalse(self.outsideSlotCalled)
+ obj.mixinTwoSlotCalled = False
+
+ # Check mixinSignal emission
+ obj.mixinSignal.connect(outsideSlot)
+ obj.mixinSignal.emit()
+ self.assertTrue(self.outsideSlotCalled)
+ self.assertFalse(obj.mixinTwoSlotCalled)
+ self.assertFalse(obj.mixinThreeSlotCalled)
+ self.assertFalse(obj.derivedSlotCalled)
+ self.outsideSlotCalled = False
+
+ # Check that method indices haven't changed.
+ # Make sure to requery for the meta object, to check that a new one was not
+ # created as a child of the old one.
+ m = obj.metaObject()
+ self.assertEqual(m.methodCount() - m.methodOffset(), 7)
+ for i in range(m.methodOffset(), m.methodCount()):
+ signature = m.method(i).methodSignature()
+ self.assertEqual(methodIndices[signature], i)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/mock_as_slot_test.py b/sources/pyside6/tests/pysidetest/mock_as_slot_test.py
new file mode 100644
index 000000000..39f52adea
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/mock_as_slot_test.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+""" PYSIDE-1755: https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1755
+ Tests that a unittest.mock.MagicMock() can be used as a slot for quick
+ prototyping. """
+
+import os
+import sys
+import unittest
+from unittest.mock import MagicMock
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class MockAsSlot(unittest.TestCase):
+ def testMockAsSlot(self):
+ obj = QObject()
+ mock = MagicMock()
+ obj.objectNameChanged.connect(mock)
+
+ obj.objectNameChanged.emit("test")
+ mock.assert_called_once()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/modelview_test.py b/sources/pyside6/tests/pysidetest/modelview_test.py
new file mode 100644
index 000000000..53231aebe
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/modelview_test.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import TestView
+from PySide6.QtCore import QAbstractListModel, QObject, QModelIndex
+
+'''Tests model/view relationship.'''
+
+object_name = 'test object'
+
+
+class MyObject(QObject):
+ pass
+
+
+class ListModelKeepsReference(QAbstractListModel):
+ def __init__(self, parent=None):
+ QAbstractListModel.__init__(self, parent)
+ self.obj = MyObject()
+ self.obj.setObjectName(object_name)
+
+ def rowCount(self, parent=QModelIndex()):
+ return 1
+
+ def data(self, index, role):
+ return self.obj
+
+
+class ListModelDoesntKeepsReference(QAbstractListModel):
+ def rowCount(self, parent=QModelIndex()):
+ return 1
+
+ def data(self, index, role):
+ obj = MyObject()
+ obj.setObjectName(object_name)
+ return obj
+
+
+class ListModelThatReturnsString(QAbstractListModel):
+ def rowCount(self, parent=QModelIndex()):
+ return 1
+
+ def data(self, index, role):
+ self.obj = 'string'
+ return self.obj
+
+
+class ModelViewTest(unittest.TestCase):
+
+ def testListModelDoesntKeepsReference(self):
+ model = ListModelDoesntKeepsReference()
+ view = TestView(model)
+ obj = view.getData()
+ self.assertEqual(type(obj), MyObject)
+ self.assertEqual(obj.objectName(), object_name)
+ obj.metaObject()
+
+ def testListModelKeepsReference(self):
+ model = ListModelKeepsReference()
+ view = TestView(model)
+ obj = view.getData()
+ self.assertEqual(type(obj), MyObject)
+ self.assertEqual(obj.objectName(), object_name)
+
+ def testListModelThatReturnsString(self):
+ model = ListModelThatReturnsString()
+ view = TestView(model)
+ obj = view.getData()
+ self.assertEqual(type(obj), str)
+ self.assertEqual(obj, 'string')
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/multiple_inheritance_test.py b/sources/pyside6/tests/pysidetest/multiple_inheritance_test.py
new file mode 100644
index 000000000..49550ba55
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/multiple_inheritance_test.py
@@ -0,0 +1,189 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+from PySide6 import QtCore, QtGui, QtWidgets
+from PySide6.QtWidgets import QMainWindow, QLabel, QWidget
+
+
+def xprint(*args, **kw):
+ if "-v" in sys.argv:
+ print(*args, **kw)
+
+
+# This is the original testcase of PYSIDE-1564
+class Age(object):
+ def __init__(self, age=0, **kwds):
+ super().__init__(**kwds)
+
+ self.age = age
+
+
+class Person(QtCore.QObject, Age):
+ def __init__(self, name, **kwds):
+ super().__init__(**kwds)
+
+ self.name = name
+
+
+class OriginalMultipleInheritanceTest(unittest.TestCase):
+
+ def testIt(self):
+ xprint()
+ p = Person("Joe", age=38)
+ xprint(f"p.age = {p.age}")
+ # This would crash if MI does not work.
+
+# More tests follow:
+
+
+# mro ('C', 'A', 'QObject', 'Object', 'B', 'object')
+class A(QtCore.QObject):
+ def __init__(self, anna=77, **kw):
+ xprint(f'A: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('A: after init')
+
+
+class B:
+ def __init__(self, otto=6, age=7, **kw):
+ xprint(f'B: before init kw = {kw}')
+ if "killme" in kw:
+ raise AssertionError("asdf")
+ super().__init__(**kw)
+ self.age = age
+ xprint('B: after init')
+
+
+class C(A, B):
+ def __init__(self, **kw):
+ xprint(f'C: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('C: after init')
+
+
+# mro ('F', 'D', 'QCursor', 'E', 'QLabel', 'QFrame', 'QWidget', 'QObject',
+# 'QPaintDevice', 'Object', 'object')
+class D(QtGui.QCursor):
+ def __init__(self, anna=77, **kw):
+ xprint(f'D: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('D: after init')
+
+
+class E:
+ def __init__(self, age=7, **kw):
+ xprint(f'E: before init kw = {kw}')
+ super().__init__(**kw)
+ self.age = age
+ xprint('E: after init')
+
+
+class F(D, E, QtWidgets.QLabel):
+ def __init__(self, **kw):
+ xprint(f'F: before init kw = {kw}')
+ super().__init__(**kw)
+ xprint('F: after init')
+
+
+# mro ('I', 'G', 'QTextDocument', 'H', 'QLabel', 'QFrame', 'QWidget', 'QObject',
+# 'QPaintDevice', 'Object', 'object')
+# Similar, but this time we want to reach `H` without support from `super`.
+class G(QtGui.QTextDocument):
+ pass
+
+
+class H:
+ def __init__(self, age=7, **kw):
+ xprint(f'H: before init kw = {kw}')
+ super().__init__(**kw)
+ self.age = age
+ xprint('H: after init')
+
+
+class II(G, H, QtWidgets.QLabel):
+ pass
+
+
+# PYSIDE-2294: Friedemann's test adapted.
+# We need to ignore positional args in mixin classes.
+class Ui_X_MainWindow(object): # Emulating uic
+ def setupUi(self, MainWindow):
+ MainWindow.resize(400, 300)
+ self.lbl = QLabel(self)
+
+
+class MainWindow(QMainWindow, Ui_X_MainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setupUi(self)
+
+
+class AdditionalMultipleInheritanceTest(UsesQApplication):
+
+ def testABC(self):
+ xprint()
+ res = C(otto=3, anna=5)
+ self.assertEqual(res.age, 7)
+ xprint()
+ with self.assertRaises(AssertionError):
+ res = C(killme=42)
+ xprint()
+
+ def testDEF(self):
+ xprint()
+ res = F(anna=5)
+ self.assertEqual(res.age, 7)
+ xprint()
+
+ def testGHI(self):
+ xprint()
+ res = II(age=7)
+ self.assertEqual(res.age, 7)
+ xprint()
+
+ def testParentDoesNotCrash(self):
+ # This crashed with
+ # TypeError: object.__init__() takes exactly one argument (the instance to initialize)
+ MainWindow()
+
+
+# PYSIDE-2654: Additional missing init test.
+# This must work if no __init__ is defined (Ui_Form)
+class Ui_Form(object):
+ pass
+
+
+class Mixin:
+ def __init__(self, **kwargs) -> None:
+ super().__init__(**kwargs)
+
+
+class Card(Mixin, QWidget):
+ def __init__(self, parent=None) -> None:
+ super().__init__(parent=parent)
+
+
+class Demo(Card, Ui_Form):
+ def __init__(self) -> None:
+ super().__init__()
+
+
+class MissingInitFunctionTest(UsesQApplication):
+ def testMissing(self):
+ Demo()
+ # Tests if this works. Would crash without the extra
+ # check for object.__init__
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/new_inherited_functions_test.py b/sources/pyside6/tests/pysidetest/new_inherited_functions_test.py
new file mode 100644
index 000000000..924a2eea7
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/new_inherited_functions_test.py
@@ -0,0 +1,159 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6 import *
+from PySide6.support.signature import get_signature
+for modname, mod in sys.modules.items():
+ # Python 2 leaves "None" in the dict.
+ if modname.startswith("PySide6.") and mod is not None:
+ print("importing", modname)
+ exec("import " + modname)
+
+# This test tests the existence and callability of the newly existing functions,
+# after the inheritance was made complete in the course of PYSIDE-331.
+
+new_functions = """
+ PySide6.QtCore.QAbstractItemModel().parent()
+ PySide6.QtCore.QAbstractListModel().parent()
+ PySide6.QtCore.QAbstractTableModel().parent()
+ PySide6.QtCore.QFile().resize(qint64)
+ m = PySide6.QtCore.QMutex(); m.tryLock(); m.unlock() # prevent a message "QMutex: destroying locked mutex"
+ PySide6.QtCore.QSortFilterProxyModel().parent()
+ PySide6.QtCore.QTemporaryFile(tfarg).open(openMode)
+"""
+
+new_functions += """
+ PySide6.QtGui.QStandardItemModel().insertColumn(int,qModelIndex)
+ PySide6.QtGui.QStandardItemModel().parent()
+ # PySide6.QtGui.QTextList(qTextDocument).setFormat(qTextFormat) # Segmentation fault: 11
+ # PySide6.QtGui.QTextTable(qTextDocument).setFormat(qTextFormat) # Segmentation fault: 11
+""" if "PySide6.QtGui" in sys.modules else ""
+
+new_functions += """
+ PySide6.QtWidgets.QAbstractItemView().update()
+ PySide6.QtWidgets.QApplication.palette()
+ PySide6.QtWidgets.QApplication.setFont(qFont)
+ PySide6.QtWidgets.QApplication.setPalette(qPalette)
+ PySide6.QtWidgets.QBoxLayout(direction).addWidget(qWidget)
+ PySide6.QtWidgets.QColorDialog().open()
+ PySide6.QtWidgets.QFileDialog().open()
+ PySide6.QtWidgets.QFileSystemModel().index(int,int,qModelIndex)
+ PySide6.QtWidgets.QFileSystemModel().parent()
+ PySide6.QtWidgets.QFontDialog().open()
+ PySide6.QtWidgets.QGestureEvent([]).accept()
+ PySide6.QtWidgets.QGestureEvent([]).ignore()
+ PySide6.QtWidgets.QGestureEvent([]).isAccepted()
+ PySide6.QtWidgets.QGestureEvent([]).setAccepted(bool)
+ # PySide6.QtWidgets.QGraphicsView().render(qPaintDevice,qPoint,qRegion,renderFlags) # QPaintDevice: NotImplementedError
+ PySide6.QtWidgets.QGridLayout().addWidget(qWidget)
+ PySide6.QtWidgets.QInputDialog().open()
+ PySide6.QtWidgets.QLineEdit().addAction(qAction)
+ PySide6.QtWidgets.QMessageBox().open()
+ PySide6.QtWidgets.QPlainTextEdit().find(findStr)
+ PySide6.QtWidgets.QProgressDialog().open()
+ PySide6.QtWidgets.QStackedLayout().widget()
+ # PySide6.QtWidgets.QStylePainter().begin(qPaintDevice) # QPaintDevice: NotImplementedError
+ PySide6.QtWidgets.QTextEdit().find(findStr)
+ PySide6.QtWidgets.QWidget.find(quintptr)
+""" if "PySide6.QtWidgets" in sys.modules else ""
+
+new_functions += """
+ # PySide6.QtPrintSupport.QPageSetupDialog().open() # Segmentation fault: 11
+ # PySide6.QtPrintSupport.QPrintDialog().open() # opens the dialog, but works
+ PySide6.QtPrintSupport.QPrintDialog().printer()
+ PySide6.QtPrintSupport.QPrintPreviewDialog().open() # note: this prints something, but really shouldn't ;-)
+""" if "PySide6.QtPrintSupport" in sys.modules else ""
+
+new_functions += """
+ PySide6.QtHelp.QHelpContentModel().parent()
+ # PySide6.QtHelp.QHelpIndexModel().createIndex(int,int,quintptr) # returned NULL without setting an error
+ # PySide6.QtHelp.QHelpIndexModel().createIndex(int,int,object()) # returned NULL without setting an error
+""" if "PySide6.QtHelp" in sys.modules else ""
+
+new_functions += """
+ PySide6.QtQuick.QQuickPaintedItem().update()
+""" if "PySide6.QtQuick" in sys.modules else ""
+
+
+class MainTest(unittest.TestCase):
+
+ def testNewInheriedFunctionsExist(self):
+ """
+ Run all new method signarures
+ """
+ for app in "QtWidgets.QApplication", "QtGui.QGuiApplication", "QtCore.QCoreApplication":
+ try:
+ exec(f"qApp = PySide6.{app}([]) or PySide6.{app}.instance()")
+ break
+ except AttributeError:
+ continue
+ bool = True
+ int = 42
+ qint64 = 42
+ tfarg = os.path.join(PySide6.QtCore.QDir.tempPath(), "XXXXXX.tmp")
+ findStr = 'bla'
+ orientation = PySide6.QtCore.Qt.Orientations()
+ openMode = PySide6.QtCore.QIODevice.OpenMode(PySide6.QtCore.QIODevice.ReadOnly)
+ qModelIndex = PySide6.QtCore.QModelIndex()
+ transformationMode = PySide6.QtCore.Qt.TransformationMode()
+ qObject = PySide6.QtCore.QObject()
+ qPoint = PySide6.QtCore.QPoint()
+ try:
+ PySide6.QtGui
+ #qPaintDevice = PySide6.QtGui.QPaintDevice() # NotImplementedError
+ qTextDocument = PySide6.QtGui.QTextDocument()
+ qTextFormat = PySide6.QtGui.QTextFormat()
+ quintptr = 42
+ qFont = PySide6.QtGui.QFont()
+ qPalette = PySide6.QtGui.QPalette()
+ except AttributeError:
+ pass
+ try:
+ PySide6.QtWidgets
+ direction = PySide6.QtWidgets.QBoxLayout.Direction()
+ qWidget = PySide6.QtWidgets.QWidget()
+ qStyleOptionFrame = PySide6.QtWidgets.QStyleOptionFrame()
+ qAction = PySide6.QtGui.QAction(qObject)
+ renderFlags = PySide6.QtWidgets.QWidget.RenderFlags
+ except AttributeError:
+ pass
+
+ for func in new_functions.splitlines():
+ func = func.strip()
+ if func.startswith("#"):
+ # this is a crashing or otherwise untestable function
+ print(func)
+ continue
+ try:
+ exec(func)
+ except NotImplementedError:
+ print(func, "# raises NotImplementedError")
+ else:
+ print(func)
+
+ def testQAppSignatures(self):
+ """
+ Verify that qApp.palette owns three signatures, especially
+ palette() without argument.
+ """
+ try:
+ qApp = (PySide6.QtWidgets.QApplication.instance() or
+ PySide6.QtWidgets.QApplication([]))
+ except AttributeError:
+ unittest.TestCase().skipTest("this test makes only sense if QtWidgets is available.")
+
+ sigs = get_signature(PySide6.QtWidgets.QApplication.palette)
+ self.assertEqual(len(sigs), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/notify_id.py b/sources/pyside6/tests/pysidetest/notify_id.py
new file mode 100644
index 000000000..0c4f39f66
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/notify_id.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Property, Slot
+
+'''Tests that the signal notify id of a property is correct, aka corresponds to the initially set
+notify method.'''
+
+
+class Foo(QObject):
+ def __init__(self):
+ super().__init__()
+ self._prop = "Empty"
+
+ def getProp(self):
+ return self._prop
+
+ def setProp(self, value):
+ if value != self._prop:
+ self._prop = value
+ self.propChanged.emit()
+
+ # Inside the dynamic QMetaObject, the methods have to be sorted, so that this slot comes
+ # after any signals. That means the property notify id has to be updated, to have the correct
+ # relative method id.
+ @Slot()
+ def randomSlot():
+ pass
+
+ propChanged = Signal()
+ prop = Property(str, getProp, setProp, notify=propChanged)
+
+
+class NotifyIdSignal(unittest.TestCase):
+ def setUp(self):
+ self.obj = Foo()
+
+ def tearDown(self):
+ del self.obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testSignalEmission(self):
+ metaObject = self.obj.metaObject()
+ propertyIndex = metaObject.indexOfProperty("prop")
+ property = metaObject.property(propertyIndex)
+
+ signalIndex = property.notifySignalIndex()
+ signal = metaObject.method(signalIndex)
+ signalName = signal.name()
+ self.assertEqual(signalName, "propChanged")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/properties_test.py b/sources/pyside6/tests/pysidetest/properties_test.py
new file mode 100644
index 000000000..8eb7812d1
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/properties_test.py
@@ -0,0 +1,108 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QStringListModel, Signal, Property, Slot
+
+"""Tests PySide6.QtCore.Property()"""
+
+
+class TestObject(QObject):
+
+ valueChanged = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._value = -1
+ self.valueChanged.connect(self._changed)
+ self.getter_called = 0
+ self.setter_called = 0
+ self.changed_emitted = 0
+
+ @Slot(int)
+ def _changed(self):
+ self.changed_emitted += 1
+
+ def getValue(self):
+ self.getter_called += 1
+ return self._value
+
+ def setValue(self, value):
+ self.setter_called += 1
+ if (self._value != value):
+ self._value = value
+ self.valueChanged.emit()
+
+ value = Property(int, fget=getValue, fset=setValue,
+ notify=valueChanged)
+
+
+class TestDerivedObject(QStringListModel):
+
+ valueChanged = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._value = -1
+ self.valueChanged.connect(self._changed)
+ self.getter_called = 0
+ self.setter_called = 0
+ self.changed_emitted = 0
+
+ @Slot(int)
+ def _changed(self):
+ self.changed_emitted += 1
+
+ def getValue(self):
+ self.getter_called += 1
+ return self._value
+
+ def setValue(self, value):
+ self.setter_called += 1
+ if (self._value != value):
+ self._value = value
+ self.valueChanged.emit()
+
+ value = Property(int, fget=getValue, fset=setValue,
+ notify=valueChanged)
+
+
+class PropertyTest(unittest.TestCase):
+
+ def test1Object(self):
+ """Basic property test."""
+ testObject = TestObject()
+ v = testObject.value
+ self.assertEqual(v, -1)
+ self.assertEqual(testObject.getter_called, 1)
+ testObject.value = 42
+ v = testObject.value
+ self.assertEqual(v, 42)
+ self.assertEqual(testObject.changed_emitted, 1)
+ self.assertEqual(testObject.setter_called, 1)
+ self.assertEqual(testObject.getter_called, 2)
+
+ def test2DerivedObject(self):
+ """PYSIDE-1255: Run the same test for a class inheriting QObject."""
+ testObject = TestDerivedObject()
+ v = testObject.value
+ self.assertEqual(v, -1)
+ self.assertEqual(testObject.getter_called, 1)
+ testObject.value = 42
+ v = testObject.value
+ self.assertEqual(v, 42)
+ self.assertEqual(testObject.changed_emitted, 1)
+ self.assertEqual(testObject.setter_called, 1)
+ self.assertEqual(testObject.getter_called, 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/property_python_test.py b/sources/pyside6/tests/pysidetest/property_python_test.py
new file mode 100644
index 000000000..1209aad4f
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/property_python_test.py
@@ -0,0 +1,222 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+Test for PySide's Property
+==========================
+
+This test is copied from Python's `test_property.py` and adapted to
+the PySide Property implementation.
+
+This test is to ensure maximum compatibility.
+"""
+
+# Test case for property
+# more tests are in test_descr
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import Property, QObject
+
+# This are the original imports.
+import sys
+import unittest
+has_test = False
+try:
+ from test import support
+ has_test = True
+except ImportError:
+ pass
+
+
+class PropertyBase(Exception):
+ pass
+
+
+class PropertyGet(PropertyBase):
+ pass
+
+
+class PropertySet(PropertyBase):
+ pass
+
+
+class PropertyDel(PropertyBase):
+ pass
+
+
+class BaseClass(QObject):
+ def __init__(self):
+ super().__init__()
+
+ self._spam = 5
+
+ @Property(object)
+ def spam(self):
+ """BaseClass.getter"""
+ return self._spam
+
+ @spam.setter
+ def spam(self, value):
+ self._spam = value
+
+ @spam.deleter
+ def spam(self):
+ del self._spam
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+
+class SubClass(BaseClass):
+
+ @BaseClass.spam.getter
+ def spam(self):
+ """SubClass.getter"""
+ raise PropertyGet(self._spam)
+
+ @spam.setter
+ def spam(self, value):
+ raise PropertySet(self._spam)
+
+ @spam.deleter
+ def spam(self):
+ raise PropertyDel(self._spam)
+
+
+class PropertyDocBase(object):
+ _spam = 1
+
+ def _get_spam(self):
+ return self._spam
+ spam = Property(object, _get_spam, doc="spam spam spam")
+
+
+class PropertyDocSub(PropertyDocBase):
+ @PropertyDocBase.spam.getter
+ def spam(self):
+ """The decorator does not use this doc string"""
+ return self._spam
+
+
+class PropertySubNewGetter(BaseClass):
+ @BaseClass.spam.getter
+ def spam(self):
+ """new docstring"""
+ return 5
+
+
+class PropertyNewGetter(QObject):
+ def __init__(self):
+ super().__init__()
+
+ @Property(object)
+ def spam(self):
+ """original docstring"""
+ return 1
+
+ @spam.getter
+ def spam(self):
+ """new docstring"""
+ return 8
+
+
+class PropertyTests(unittest.TestCase):
+ def test_property_decorator_baseclass(self):
+ # see #1620
+ base = BaseClass()
+ self.assertEqual(base.spam, 5)
+ self.assertEqual(base._spam, 5)
+ base.spam = 10
+ self.assertEqual(base.spam, 10)
+ self.assertEqual(base._spam, 10)
+ delattr(base, "spam")
+ self.assertTrue(not hasattr(base, "spam"))
+ self.assertTrue(not hasattr(base, "_spam"))
+ base.spam = 20
+ self.assertEqual(base.spam, 20)
+ self.assertEqual(base._spam, 20)
+
+ def test_property_decorator_subclass(self):
+ # see #1620
+ sub = SubClass()
+ self.assertRaises(PropertyGet, getattr, sub, "spam")
+ self.assertRaises(PropertySet, setattr, sub, "spam", None)
+ self.assertRaises(PropertyDel, delattr, sub, "spam")
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ def test_property_decorator_subclass_doc(self):
+ sub = SubClass()
+ self.assertEqual(sub.__class__.spam.__doc__, "SubClass.getter")
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ def test_property_decorator_baseclass_doc(self):
+ base = BaseClass()
+ self.assertEqual(base.__class__.spam.__doc__, "BaseClass.getter")
+
+ def test_property_decorator_doc(self):
+ base = PropertyDocBase()
+ sub = PropertyDocSub()
+ self.assertEqual(base.__class__.spam.__doc__, "spam spam spam")
+ self.assertEqual(sub.__class__.spam.__doc__, "spam spam spam")
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ def test_property_getter_doc_override(self):
+ newgettersub = PropertySubNewGetter()
+ self.assertEqual(newgettersub.spam, 5)
+ self.assertEqual(newgettersub.__class__.spam.__doc__, "new docstring")
+ newgetter = PropertyNewGetter()
+ self.assertEqual(newgetter.spam, 8)
+ self.assertEqual(newgetter.__class__.spam.__doc__, "new docstring")
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ def test_property_builtin_doc_writable(self):
+ p = Property(object, doc='basic')
+ self.assertEqual(p.__doc__, 'basic')
+ p.__doc__ = 'extended'
+ self.assertEqual(p.__doc__, 'extended')
+
+ @unittest.skipIf(sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+ def test_property_decorator_doc_writable(self):
+ class PropertyWritableDoc(object):
+
+ @Property(object)
+ def spam(self):
+ """Eggs"""
+ return "eggs"
+
+ sub = PropertyWritableDoc()
+ self.assertEqual(sub.__class__.spam.__doc__, 'Eggs')
+ sub.__class__.spam.__doc__ = 'Spam'
+ self.assertEqual(sub.__class__.spam.__doc__, 'Spam')
+
+ if has_test: # This test has no support in Python 2
+ @support.refcount_test
+ def test_refleaks_in___init__(self):
+ gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount')
+ fake_prop = Property(object, 'fget', 'fset', "freset", 'fdel', 'doc')
+ refs_before = gettotalrefcount()
+ for i in range(100):
+ fake_prop.__init__(object, 'fget', 'fset', "freset", 'fdel', 'doc')
+ self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10)
+
+
+# Note: We ignore the whole subclass tests concerning __doc__ strings.
+# See the original Python test starting with:
+# "Issue 5890: subclasses of property do not preserve method __doc__ strings"
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py b/sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py
new file mode 100644
index 000000000..625f9cdc5
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/pyenum_relax_options_test.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+PYSIDE-1735: Testing different relax options for Enums
+
+This test uses different configurations and initializes QtCore with it.
+Because re-initialization is not possible, the test uses a subprocess
+for it. This makes the test pretty slow.
+
+Maybe we should implement a way to re-initialize QtCore enums without
+using subprocess, just to speed this up??
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import subprocess
+import tempfile
+from textwrap import dedent
+
+
+def runtest(program):
+ passed_path = os.fspath(Path(__file__).resolve().parents[1])
+ with tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".py") as fp:
+ preamble = dedent(f"""
+ import os
+ import sys
+ from pathlib import Path
+ sys.path.append({passed_path!r})
+ from init_paths import init_test_paths
+ init_test_paths(False)
+ """)
+ print(preamble, program, file=fp)
+ fp.close()
+ try:
+ subprocess.run([sys.executable, fp.name], check=True, capture_output=True)
+ return True
+ except subprocess.CalledProcessError as e:
+ print(f"\ninfo: {e.__class__.__name__}: {e.stderr}")
+ return False
+ finally:
+ os.unlink(fp.name)
+
+
+def testprog2(option):
+ return runtest(dedent(f"""
+ sys.pyside6_option_python_enum = {option}
+ from PySide6 import QtCore
+ from enum import IntEnum
+ assert(issubclass(QtCore.Qt.DateFormat, IntEnum))
+ """))
+
+
+def testprog4(option):
+ return runtest(dedent(f"""
+ sys.pyside6_option_python_enum = {option}
+ from PySide6 import QtCore
+ QtCore.QtDebugMsg
+ """))
+
+
+def testprog8_16(option):
+ # this test needs flag 16, or the effect would be hidden by forgiving mode
+ return runtest(dedent(f"""
+ sys.pyside6_option_python_enum = {option}
+ from PySide6 import QtCore
+ QtCore.Qt.AlignTop
+ """))
+
+
+def testprog32(option):
+ return runtest(dedent(f"""
+ sys.pyside6_option_python_enum = {option}
+ from PySide6 import QtCore
+ QtCore.Qt.Alignment
+ """))
+
+
+def testprog64(option):
+ return runtest(dedent(f"""
+ sys.pyside6_option_python_enum = {option}
+ from PySide6 import QtCore
+ QtCore.Qt.AlignmentFlag()
+ """))
+
+
+def testprog128(option):
+ return runtest(dedent(f"""
+ sys.pyside6_option_python_enum = {option}
+ from PySide6 import QtCore
+ QtCore.Qt.Key(1234567)
+ """))
+
+
+class TestPyEnumRelaxOption(unittest.TestCase):
+ """
+ This test is a bit involved, because we cannot unload QtCore after it is loaded once.
+ We use subprocess to test different cases, anyway.
+ """
+
+ def test_enumIsIntEnum(self):
+ self.assertTrue(testprog2(2))
+ self.assertFalse(testprog2(4))
+
+ def test_globalDefault(self):
+ self.assertTrue(testprog4(4))
+ self.assertFalse(testprog4(1))
+ self.assertTrue(testprog4(12))
+
+ def test_localDefault(self):
+ self.assertTrue(testprog8_16(8 + 16))
+ self.assertFalse(testprog8_16(0 + 16))
+
+ def test_fakeRenames(self):
+ self.assertTrue(testprog32(1))
+ self.assertFalse(testprog32(32))
+
+ def test_zeroDefault(self):
+ self.assertTrue(testprog64(1))
+ self.assertFalse(testprog64(64))
+
+ def test_Missing(self):
+ self.assertTrue(testprog128(1))
+ self.assertFalse(testprog128(128))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/pysidetest.pyproject b/sources/pyside6/tests/pysidetest/pysidetest.pyproject
new file mode 100644
index 000000000..032d31c6f
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/pysidetest.pyproject
@@ -0,0 +1,33 @@
+{
+ "files": ["all_modules_load_test.py",
+ "bug_1016.py",
+ "constructor_properties_test.py",
+ "container_test.py",
+ "decoratedslot_test.py",
+ "delegatecreateseditor_test.py",
+ "enum_test.py",
+ "homonymoussignalandmethod_test.py",
+ "iterable_test.py",
+ "list_signal_test.py",
+ "mixin_signal_slots_test.py",
+ "mock_as_slot_test.py",
+ "modelview_test.py",
+ "new_inherited_functions_test.py",
+ "notify_id.py",
+ "properties_test.py",
+ "property_python_test.py",
+ "pyenum_relax_options_test.py",
+ "qapp_like_a_macro_test.py",
+ "qvariant_test.py",
+ "repr_test.py",
+ "shared_pointer_test.py",
+ "signal_slot_warning.py",
+ "signal_tp_descr_get_test.py",
+ "signalandnamespace_test.py",
+ "signalemissionfrompython_test.py",
+ "signalinstance_equality_test.py",
+ "signalwithdefaultvalue_test.py",
+ "typedef_signal_test.py",
+ "version_test.py",
+ "typesystem_pysidetest.xml"]
+}
diff --git a/sources/pyside6/tests/pysidetest/pysidetest_global.h b/sources/pyside6/tests/pysidetest/pysidetest_global.h
new file mode 100644
index 000000000..6f784dc58
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/pysidetest_global.h
@@ -0,0 +1,16 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PYSIDETEST_GLOBAL_H
+#define PYSIDETEST_GLOBAL_H
+
+// PySide global.h file
+#include "containertest.h"
+#include "testobject.h"
+#include "testview.h"
+#include "flagstest.h"
+#include "hiddenobject.h"
+#include "sharedpointertestbench.h"
+#include "testqvariantenum.h"
+
+#endif // PYSIDETEST_GLOBAL_H
diff --git a/sources/pyside6/tests/pysidetest/pysidetest_macros.h b/sources/pyside6/tests/pysidetest/pysidetest_macros.h
new file mode 100644
index 000000000..29bd0dc39
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/pysidetest_macros.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PYSIDETEST_MACROS_H
+#define PYSIDETEST_MACROS_H
+
+#include <pysidemacros.h>
+
+#define PYSIDETEST_EXPORT PYSIDE_EXPORT
+#define PYSIDETEST_IMPORT PYSIDE_IMPORT
+
+#ifdef BUILD_PYSIDETEST
+# define PYSIDETEST_API PYSIDETEST_EXPORT
+#else
+# define PYSIDETEST_API PYSIDETEST_IMPORT
+#endif
+
+#endif // PYSIDETEST_MACROS_H
diff --git a/sources/pyside6/tests/pysidetest/qapp_like_a_macro_test.py b/sources/pyside6/tests/pysidetest/qapp_like_a_macro_test.py
new file mode 100644
index 000000000..2a3f34014
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/qapp_like_a_macro_test.py
@@ -0,0 +1,68 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6
+
+# This test tests the new "macro" feature of qApp.
+# It also uses the qApp variable to finish the instance and start over.
+
+# Note: this test makes qapplication_singleton_test.py obsolete.
+
+
+class qAppMacroTest(unittest.TestCase):
+ _test_1093_is_first = True
+
+ def test_qApp_is_like_a_macro_and_can_restart(self):
+ self._test_1093_is_first = False
+ from PySide6 import QtCore
+ try:
+ from PySide6 import QtGui, QtWidgets
+ except ImportError:
+ QtWidgets = QtGui = QtCore
+ # qApp is in the builtins
+ self.assertEqual(bool(qApp), False)
+ # and the type is None
+ self.assertTrue(qApp is None)
+ # now we create an application for all cases
+ classes = (QtCore.QCoreApplication,
+ QtGui.QGuiApplication,
+ QtWidgets.QApplication)
+ fil = sys.stderr
+ for klass in classes:
+ print("CREATED", klass([]), file=fil)
+ fil.flush()
+ qApp.shutdown()
+ print("DELETED qApp", qApp, file=fil)
+ fil.flush()
+ # creating without deletion raises:
+ QtCore.QCoreApplication([])
+ with self.assertRaises(RuntimeError):
+ QtCore.QCoreApplication([])
+ self.assertEqual(QtCore.QCoreApplication.instance(), qApp)
+
+ def test_1093(self):
+ # Test that without creating a QApplication staticMetaObject still exists.
+ # Please see https://bugreports.qt.io/browse/PYSIDE-1093 for explanation.
+ # Note: This test must run first, otherwise we would be mislead!
+ assert self._test_1093_is_first
+ from PySide6 import QtCore
+ self.assertTrue(QtCore.QObject.staticMetaObject is not None)
+ app = QtCore.QCoreApplication.instance()
+ self.assertTrue(QtCore.QObject.staticMetaObject is not None)
+ if app is None:
+ app = QtCore.QCoreApplication([])
+ self.assertTrue(QtCore.QObject.staticMetaObject is not None)
+ qApp.shutdown()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/qvariant_test.py b/sources/pyside6/tests/pysidetest/qvariant_test.py
new file mode 100644
index 000000000..faefc8169
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/qvariant_test.py
@@ -0,0 +1,67 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import enum
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import TestObject, TestQVariantEnum
+from PySide6.QtCore import Qt, QKeyCombination
+from PySide6.QtGui import QKeySequence, QAction
+
+from helper.usesqapplication import UsesQApplication
+
+
+class PyTestQVariantEnum(TestQVariantEnum):
+ def __init__(self, var_enum):
+ super().__init__(var_enum)
+
+ def getRValEnum(self):
+ return Qt.Orientation.Vertical
+
+ def channelingEnum(self, rval_enum):
+ return (isinstance(rval_enum, enum.Enum)
+ and rval_enum == Qt.Orientation.Vertical)
+
+
+class QVariantTest(UsesQApplication):
+
+ def testQKeySequenceQVariantOperator(self):
+ # bug #775
+ ks = QKeySequence(Qt.ShiftModifier, Qt.ControlModifier, Qt.Key_P, Qt.Key_R)
+ self.assertEqual(TestObject.checkType(ks), 4107)
+
+ def testQKeySequenceMoreVariations(self):
+ QAction().setShortcut(Qt.CTRL | Qt.Key_B)
+ QAction().setShortcut(Qt.CTRL | Qt.ALT | Qt.Key_B)
+ QAction().setShortcut(Qt.CTRL | Qt.AltModifier | Qt.Key_B)
+ QAction().setShortcut(QKeySequence(QKeyCombination(Qt.CTRL | Qt.Key_B)))
+ QKeySequence(Qt.CTRL | Qt.Key_Q)
+
+ def testEnum(self):
+ # Testing C++ class
+ testqvariant = TestQVariantEnum(Qt.CheckState.Checked)
+ self.assertEqual(testqvariant.getLValEnum(), Qt.CheckState.Checked)
+ self.assertIsInstance(testqvariant.getLValEnum(), enum.Enum)
+ # in the case where we return a QVariant of C++ enum, it returns a
+ # QVariant(int) to Python unless explicitly handled manually by Shiboken
+ self.assertEqual(testqvariant.getRValEnum(), 1)
+ self.assertEqual(testqvariant.isEnumChanneled(), False)
+
+ # Testing Python child class
+ pytestqvariant = PyTestQVariantEnum(Qt.CheckState.Checked)
+ self.assertEqual(pytestqvariant.isEnumChanneled(), True)
+ # check toInt() conversion works for PyObjectWrapper
+ self.assertEqual(PyTestQVariantEnum.getNumberFromQVarEnum(Qt.Orientation.Vertical), 2)
+ # check toInt() conversion for IntEnum
+ self.assertEqual(PyTestQVariantEnum.getNumberFromQVarEnum(Qt.GestureType.TapGesture), 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/repr_test.py b/sources/pyside6/tests/pysidetest/repr_test.py
new file mode 100644
index 000000000..863f17657
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/repr_test.py
@@ -0,0 +1,64 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# Copyright (C) 2019 Andreas Beckermann
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import PySideCPP, TestObject
+
+
+class QObjectDerivedReprTest(unittest.TestCase):
+ """Test the __repr__ implementation of QObject derived classes"""
+
+ def testReprWithoutNamespace(self):
+ """Test that classes outside a namespace that have a operator<<(QDebug,...) defined use that
+ for __repr__"""
+ t = TestObject(123)
+
+ # We don't define __str__, so str(q) should call __repr__
+ self.assertEqual(t.__repr__(), str(t))
+
+ # __repr__ should use the operator<<(QDebug,...) implementation
+ self.assertIn('TestObject(id=123)', str(t))
+
+ def testReprWithNamespace(self):
+ """Test that classes inside a namespace that have a operator<<(QDebug,...) defined use that
+ for __repr__"""
+ t = PySideCPP.TestObjectWithNamespace(None)
+
+ # We don't define __str__, so str(q) should call __repr__
+ self.assertEqual(t.__repr__(), str(t))
+
+ # __repr__ should use the operator<<(QDebug,...) implementation
+ self.assertIn('TestObjectWithNamespace("TestObjectWithNamespace")', str(t))
+
+ def testReprInject(self):
+ """Test that injecting __repr__ via typesystem overrides the operator<<(QDebug, ...)"""
+ t = PySideCPP.TestObject2WithNamespace(None)
+
+ # We don't define __str__, so str(q) should call __repr__
+ self.assertEqual(t.__repr__(), str(t))
+
+ # __repr__ should use the operator<<(QDebug,...) implementation
+ self.assertEqual(str(t), "TestObject2WithNamespace(injected_repr)")
+
+ def testLatin1StringField(self):
+ self.assertEqual(TestObject.LATIN1_TEST_FIELD, "test")
+
+ def testLatin1Setter(self):
+ to = TestObject(123)
+ value = "test"
+ to.setQLatin1String(value)
+ self.assertEqual(to.qLatin1String(), value)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/shared_pointer_test.py b/sources/pyside6/tests/pysidetest/shared_pointer_test.py
new file mode 100644
index 000000000..6f49d69b1
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/shared_pointer_test.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from PySide6.QtCore import QObject
+
+from testbinding import SharedPointerTestbench, QSharedPointer_QObject
+
+
+def create_qobject(name):
+ result = QObject()
+ result.setObjectName(name)
+ return result
+
+
+class SharedPointerTests(unittest.TestCase):
+
+ def testObjSharedPointer(self):
+ p = SharedPointerTestbench.createSharedPointerQObject()
+ self.assertEqual(p.objectName(), "TestObject")
+ SharedPointerTestbench.printSharedPointerQObject(p)
+ p = SharedPointerTestbench.createSharedPointerConstQObject()
+ SharedPointerTestbench.printSharedPointerConstQObject(p)
+
+ def testIntSharedPointer(self):
+ p = SharedPointerTestbench.createSharedPointerInt(42)
+ SharedPointerTestbench.printSharedPointerInt(p)
+
+ def testConstruction(self):
+ name1 = "CreatedQObject1"
+ p1 = QSharedPointer_QObject(create_qobject(name1))
+ self.assertTrue(p1)
+ self.assertEqual(p1.objectName(), name1)
+
+ p1.reset()
+ self.assertFalse(p1)
+
+ name2 = "CreatedQObject2"
+ p1.reset(create_qobject(name2))
+ self.assertTrue(p1)
+ self.assertEqual(p1.objectName(), name2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/sharedpointertestbench.cpp b/sources/pyside6/tests/pysidetest/sharedpointertestbench.cpp
new file mode 100644
index 000000000..44c2a4fe0
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/sharedpointertestbench.cpp
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "sharedpointertestbench.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QDebug>
+
+using namespace Qt::StringLiterals;
+
+SharedPointerTestbench::SharedPointerTestbench() = default;
+
+QSharedPointer<int> SharedPointerTestbench::createSharedPointerInt(int v)
+{
+ return QSharedPointer<int>(new int(v));
+}
+
+void SharedPointerTestbench::printSharedPointerInt(const QSharedPointer<int> &p)
+{
+ qDebug() << __FUNCTION__ << *p;
+}
+
+QSharedPointer<QObject> SharedPointerTestbench::createSharedPointerQObject()
+{
+ QSharedPointer<QObject> result(new QObject);
+ result->setObjectName(u"TestObject"_s);
+ return result;
+}
+
+void SharedPointerTestbench::printSharedPointerQObject(const QSharedPointer<QObject> &p)
+{
+ qDebug() << __FUNCTION__ << p.data();
+}
+
+QSharedPointer<const QObject> SharedPointerTestbench::createSharedPointerConstQObject()
+{
+ auto *o = new QObject;
+ o->setObjectName(u"ConstTestObject"_s);
+ QSharedPointer<const QObject> result(o);
+ return result;
+}
+
+void SharedPointerTestbench::printSharedPointerConstQObject(const QSharedPointer<const QObject> &p)
+{
+ qDebug() << __FUNCTION__ << p.data();
+}
diff --git a/sources/pyside6/tests/pysidetest/sharedpointertestbench.h b/sources/pyside6/tests/pysidetest/sharedpointertestbench.h
new file mode 100644
index 000000000..b23fd1b6c
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/sharedpointertestbench.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SHAREDPOINTERTESTBENCH_H
+#define SHAREDPOINTERTESTBENCH_H
+
+#include "pysidetest_macros.h"
+
+#include <QtCore/QSharedPointer>
+
+QT_FORWARD_DECLARE_CLASS(QObject)
+
+class PYSIDETEST_API SharedPointerTestbench
+{
+public:
+ SharedPointerTestbench();
+
+ static QSharedPointer<int> createSharedPointerInt(int v);
+ static void printSharedPointerInt(const QSharedPointer<int> &p);
+
+ static QSharedPointer<QObject> createSharedPointerQObject();
+ static void printSharedPointerQObject(const QSharedPointer<QObject> &p);
+
+ static QSharedPointer<const QObject> createSharedPointerConstQObject();
+ static void printSharedPointerConstQObject(const QSharedPointer<const QObject> &p);
+
+};
+
+#endif // SHAREDPOINTERTESTBENCH_H
diff --git a/sources/pyside6/tests/pysidetest/signal_slot_warning.py b/sources/pyside6/tests/pysidetest/signal_slot_warning.py
new file mode 100644
index 000000000..b94281643
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/signal_slot_warning.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' PYSIDE-315: https://bugreports.qt.io/browse/PYSIDE-315
+ Test that creating a signal in the wrong order triggers a warning. '''
+
+import os
+import sys
+import unittest
+import warnings
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+import PySide6.QtCore as QtCore
+
+
+class Whatever(QtCore.QObject):
+ echoSignal = QtCore.Signal(str)
+
+ def __init__(self):
+ super().__init__()
+ self.echoSignal.connect(self.mySlot)
+
+ def mySlot(self, v):
+ pass
+
+
+class WarningTest(unittest.TestCase):
+ def testSignalSlotWarning(self):
+ # we create an object. This gives no warning.
+ obj = Whatever()
+ # then we insert a signal after slots have been created.
+ setattr(Whatever, "foo", QtCore.Signal())
+ with warnings.catch_warnings(record=True) as w:
+ # Cause all warnings to always be triggered.
+ warnings.simplefilter("always")
+ # Trigger a warning.
+ obj.foo.connect(obj.mySlot)
+ # Verify some things
+ assert issubclass(w[-1].category, RuntimeWarning)
+ assert "*** Sort Warning ***" in str(w[-1].message)
+ # note that this warning cannot be turned into an error (too hard)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/signal_tp_descr_get_test.py b/sources/pyside6/tests/pysidetest/signal_tp_descr_get_test.py
new file mode 100644
index 000000000..6025d119d
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/signal_tp_descr_get_test.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""
+PYSIDE-68: Test that signals have a `__get__` function after all.
+
+We supply a `tp_descr_get` slot for the signal type.
+That creates the `__get__` method via `PyType_Ready`.
+
+The original test script was converted to a unittest.
+See https://bugreports.qt.io/browse/PYSIDE-68 .
+
+Created: 16 May '12 21:25
+Updated: 17 Sep '20 17:02
+
+This fix was over 8 years late. :)
+"""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+def emit_upon_success(signal):
+ def f_(f):
+ def f__(self):
+ result = f(self)
+ s = signal.__get__(self)
+ print(result)
+ return result
+ return f__
+ return f_
+
+
+class Foo(QObject):
+ SIG = Signal()
+
+ @emit_upon_success(SIG)
+ def do_something(self):
+ print("hooka, it worrrks")
+ return 42
+
+
+class UnderUnderGetUnderUnderTest(unittest.TestCase):
+ def test_tp_descr_get(self):
+ foo = Foo()
+ ret = foo.do_something()
+ self.assertEqual(ret, 42)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/signalandnamespace_test.py b/sources/pyside6/tests/pysidetest/signalandnamespace_test.py
new file mode 100644
index 000000000..3e91ca338
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/signalandnamespace_test.py
@@ -0,0 +1,103 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import PySideCPP, TestObjectWithoutNamespace
+
+
+class ModelViewTest(unittest.TestCase):
+
+ def callback(self, o):
+ self._called = o
+
+ def testWithoutNamespace(self):
+ self._called = None
+ o = PySideCPP.TestObjectWithNamespace(None)
+ o.emitSignal.connect(self.callback)
+ o.emitSignal.emit(o)
+ self.assertTrue(o == self._called)
+
+ self._called = None
+ o = PySideCPP.TestObjectWithNamespace(None)
+ o.emitSignal.connect(self.callback)
+ o.callSignal(o)
+ self.assertTrue(o == self._called)
+
+ def testWithNamespace(self):
+ self._called = None
+ o = PySideCPP.TestObjectWithNamespace(None)
+ o.emitSignalWithNamespace.connect(self.callback)
+ o.emitSignalWithNamespace.emit(o)
+ self.assertTrue(o == self._called)
+
+ self._called = None
+ o = PySideCPP.TestObjectWithNamespace(None)
+ o.emitSignalWithNamespace.connect(self.callback)
+ o.callSignalWithNamespace(o)
+ self.assertTrue(o == self._called)
+
+ def testWithoutNamespace1(self):
+ self._called = None
+ o = TestObjectWithoutNamespace(None)
+ o.emitSignal.connect(self.callback)
+ o.emitSignal.emit(o)
+ self.assertTrue(o == self._called)
+
+ self._called = None
+ o = TestObjectWithoutNamespace(None)
+ o.emitSignal.connect(self.callback)
+ o.callSignal(o)
+ self.assertTrue(o == self._called)
+
+ def testWithNamespace1(self):
+ self._called = None
+ o = TestObjectWithoutNamespace(None)
+ o.emitSignalWithNamespace.connect(self.callback)
+ o.emitSignalWithNamespace.emit(o)
+ self.assertTrue(o == self._called)
+
+ self._called = None
+ o = TestObjectWithoutNamespace(None)
+ o.emitSignalWithNamespace.connect(self.callback)
+ o.callSignalWithNamespace(o)
+ self.assertTrue(o == self._called)
+
+ def testTypedfWithouNamespace(self):
+ self._called = None
+ o = PySideCPP.TestObjectWithNamespace(None)
+ o.emitSignalWithTypedef.connect(self.callback)
+ o.emitSignalWithTypedef.emit(10)
+ self.assertEqual(10, self._called)
+
+ self._called = None
+ o = PySideCPP.TestObjectWithNamespace(None)
+ o.emitSignalWithTypedef.connect(self.callback)
+ o.callSignalWithTypedef(10)
+ self.assertEqual(10, self._called)
+
+ def testTypedefWithNamespace(self):
+ self._called = None
+ o = TestObjectWithoutNamespace(None)
+ o.emitSignalWithTypedef.connect(self.callback)
+ o.emitSignalWithTypedef.emit(10)
+ self.assertEqual(10, self._called)
+
+ self._called = None
+ o = TestObjectWithoutNamespace(None)
+ o.emitSignalWithTypedef.connect(self.callback)
+ o.callSignalWithTypedef(10)
+ self.assertEqual(10, self._called)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py b/sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py
new file mode 100644
index 000000000..70c9e0082
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import TestObject
+from PySide6.QtCore import QObject, SIGNAL
+
+'''Tests the behaviour of signals with default values when emitted from Python.'''
+
+
+class SignalEmissionFromPython(unittest.TestCase):
+
+ def setUp(self):
+ self.obj1 = TestObject(0)
+ self.obj2 = TestObject(0)
+ self.one_called = 0
+ self.two_called = 0
+
+ def tearDown(self):
+ del self.obj1
+ del self.obj2
+ del self.one_called
+ del self.two_called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testConnectNewStyleEmitVoidSignal(self):
+ def callbackOne():
+ self.one_called += 1
+ self.obj2.signalWithDefaultValue.emit()
+
+ def callbackTwo():
+ self.two_called += 1
+ self.obj1.signalWithDefaultValue.connect(callbackOne)
+ self.obj2.signalWithDefaultValue.connect(callbackTwo)
+ self.obj1.emitSignalWithDefaultValue_void()
+ self.obj2.emitSignalWithDefaultValue_void()
+ self.assertEqual(self.one_called, 1)
+ self.assertEqual(self.two_called, 2)
+
+ def testConnectOldStyleEmitVoidSignal(self):
+ def callbackOne():
+ self.one_called += 1
+ self.obj2.signalWithDefaultValue.emit()
+
+ def callbackTwo():
+ self.two_called += 1
+ self.obj1.signalWithDefaultValue.connect(callbackOne)
+ self.obj2.signalWithDefaultValue.connect(callbackTwo)
+ self.obj1.emitSignalWithDefaultValue_void()
+ self.obj2.emitSignalWithDefaultValue_void()
+ self.assertEqual(self.one_called, 1)
+ self.assertEqual(self.two_called, 2)
+
+ def testConnectNewStyleEmitBoolSignal(self):
+ def callbackOne():
+ self.one_called += 1
+ self.obj2.signalWithDefaultValue[bool].emit(True)
+
+ def callbackTwo():
+ self.two_called += 1
+ self.obj1.signalWithDefaultValue.connect(callbackOne)
+ self.obj2.signalWithDefaultValue.connect(callbackTwo)
+ self.obj1.emitSignalWithDefaultValue_void()
+ self.obj2.emitSignalWithDefaultValue_void()
+ self.assertEqual(self.one_called, 1)
+ self.assertEqual(self.two_called, 2)
+
+ def testConnectOldStyleEmitBoolSignal(self):
+ def callbackOne():
+ self.one_called += 1
+ self.obj2.signalWithDefaultValue[bool].emit(True)
+
+ def callbackTwo():
+ self.two_called += 1
+ self.obj1.signalWithDefaultValue.connect(callbackOne)
+ self.obj2.signalWithDefaultValue.connect(callbackTwo)
+ self.obj1.emitSignalWithDefaultValue_void()
+ self.obj2.emitSignalWithDefaultValue_void()
+ self.assertEqual(self.one_called, 1)
+ self.assertEqual(self.two_called, 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/pysidetest/signalinstance_equality_test.py b/sources/pyside6/tests/pysidetest/signalinstance_equality_test.py
new file mode 100644
index 000000000..5faaa38d4
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/signalinstance_equality_test.py
@@ -0,0 +1,85 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from helper.usesqapplication import UsesQApplication
+
+from PySide6.QtCore import QFile, QObject, QTimer, Signal, SignalInstance, Slot
+from PySide6.QtWidgets import QSlider
+
+
+class C(QObject):
+ custom_signal = Signal()
+
+
+class D(C):
+ pass
+
+
+class TestSignalInstance(unittest.TestCase):
+ def test_signal_instances_are_equal(self):
+ o = QTimer()
+ self.assertTrue(o.timeout == o.timeout)
+
+ def test_inherited_signal_instances_are_equal(self):
+ o = QFile()
+ self.assertTrue(o.readyRead == o.readyRead)
+
+ def test_custom_signal_instances_are_equal(self):
+ o = C()
+ self.assertTrue(o.custom_signal == o.custom_signal)
+
+ def test_custom_inherited_signal_instances_are_equal(self):
+ o = D()
+ self.assertTrue(o.custom_signal == o.custom_signal)
+
+ # additional tests of old errors from 2010 or so
+ def test_uninitialized_SignalInstance(self):
+ # This will no longer crash
+ print(SignalInstance())
+ with self.assertRaises(RuntimeError):
+ SignalInstance().connect(lambda: None)
+ with self.assertRaises(RuntimeError):
+ SignalInstance().disconnect()
+ with self.assertRaises(RuntimeError):
+ SignalInstance().emit()
+
+
+class MyWidget(QSlider):
+ valueChanged = Signal(tuple)
+
+ def __init__(self):
+ super().__init__()
+ self.valueChanged.connect(self._on_change)
+
+ def setValue(self, value):
+ self.valueChanged.emit(value)
+
+ @Slot()
+ def _on_change(self, new_value):
+ print("new_value:", new_value)
+ global result
+ result = new_value
+
+
+class TestRightOrder(UsesQApplication):
+ def test_rightOrder(self):
+ wdg = MyWidget()
+
+ # PYSIDE-1751: Fixes the wrong behavior we got on >=6.2
+ # PySide <=6.1.3 prints "new_value: (30, 40)"
+ # PySide >=6.2 prints "new_value: 0"
+ wdg.setValue((30, 40))
+ self.assertEqual(result, (30, 40))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py b/sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py
new file mode 100644
index 000000000..744b8c503
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/signalwithdefaultvalue_test.py
@@ -0,0 +1,96 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from testbinding import TestObject
+from PySide6.QtCore import Qt
+
+'''Tests the behaviour of signals with default values.'''
+
+
+class SignalWithDefaultValueTest(unittest.TestCase):
+
+ def setUp(self):
+ self.obj = TestObject(0)
+ self.void_called = False
+ self.bool_called = False
+
+ def tearDown(self):
+ del self.obj
+ del self.void_called
+ del self.bool_called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testConnectNewStyleEmitVoidSignal(self):
+ def callbackVoid():
+ self.void_called = True
+
+ def callbackBool(value):
+ self.bool_called = True
+ self.obj.signalWithDefaultValue.connect(callbackVoid)
+ self.obj.signalWithDefaultValue[bool].connect(callbackBool)
+ self.obj.emitSignalWithDefaultValue_void()
+ self.assertTrue(self.void_called)
+ self.assertTrue(self.bool_called)
+
+ def testConnectNewStyleEmitBoolSignal(self):
+ def callbackVoid():
+ self.void_called = True
+
+ def callbackBool(value):
+ self.bool_called = True
+ self.obj.signalWithDefaultValue.connect(callbackVoid)
+ self.obj.signalWithDefaultValue[bool].connect(callbackBool)
+ self.obj.emitSignalWithDefaultValue_bool()
+ self.assertTrue(self.void_called)
+ self.assertTrue(self.bool_called)
+
+ def testFlagsSignal(self):
+ test_value = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBottom
+
+ def callbackAlignmentFlags(alignment):
+ self.alignment_flags_called = alignment
+
+ self.obj.flagsSignal.connect(callbackAlignmentFlags)
+ self.obj.emitFlagsSignal(test_value)
+ self.assertTrue(self.alignment_flags_called)
+ self.assertEqual(self.alignment_flags_called, test_value)
+
+ def testConnectOldStyleEmitVoidSignal(self):
+ def callbackVoid():
+ self.void_called = True
+
+ def callbackBool(value):
+ self.bool_called = True
+ self.obj.signalWithDefaultValue.connect(callbackVoid)
+ self.obj.signalWithDefaultValue.connect(callbackBool)
+ self.obj.emitSignalWithDefaultValue_void()
+ self.assertTrue(self.void_called)
+ self.assertTrue(self.bool_called)
+
+ def testConnectOldStyleEmitBoolSignal(self):
+ def callbackVoid():
+ self.void_called = True
+
+ def callbackBool(value):
+ self.bool_called = True
+ self.obj.signalWithDefaultValue.connect(callbackVoid)
+ self.obj.signalWithDefaultValue.connect(callbackBool)
+ self.obj.emitSignalWithDefaultValue_bool()
+ self.assertTrue(self.void_called)
+ self.assertTrue(self.bool_called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/snake_case_sub.py b/sources/pyside6/tests/pysidetest/snake_case_sub.py
new file mode 100644
index 000000000..4a482c35a
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/snake_case_sub.py
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+"""
+PYSIDE-2029: Tests that snake_case is isolated from imported modules
+"""
+
+from PySide6.QtWidgets import QWidget
+
+
+def test_no_snake_case():
+ print(__name__)
+ widget = QWidget()
+ check = widget.sizeHint
diff --git a/sources/pyside6/tests/pysidetest/snake_case_test.py b/sources/pyside6/tests/pysidetest/snake_case_test.py
new file mode 100644
index 000000000..14e035773
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/snake_case_test.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+"""
+PYSIDE-2029: Tests that snake_case is isolated from imported modules
+"""
+is_pypy = hasattr(sys, "pypy_version_info")
+
+from PySide6.QtCore import QSize
+from PySide6.QtWidgets import QWidget, QSpinBox
+if not is_pypy:
+ from __feature__ import snake_case
+from helper.usesqapplication import UsesQApplication
+
+import snake_case_sub
+
+@unittest.skipIf(is_pypy, "__feature__ cannot yet be used with PyPy")
+class SnakeCaseNoPropagateTest(UsesQApplication):
+
+ def testSnakeCase(self):
+ # this worked
+ widget = QWidget()
+ check = widget.size_hint
+
+ snake_case_sub.test_no_snake_case()
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/symbols.filter b/sources/pyside6/tests/pysidetest/symbols.filter
new file mode 100644
index 000000000..af6c744dd
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/symbols.filter
@@ -0,0 +1,7 @@
+{
+local:
+_ZSt*;
+_ZNSt*;
+_ZNSs*;
+_ZNKSt*;
+};
diff --git a/sources/pyside6/tests/pysidetest/testobject.cpp b/sources/pyside6/tests/pysidetest/testobject.cpp
new file mode 100644
index 000000000..fe4ec98f7
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testobject.cpp
@@ -0,0 +1,73 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "testobject.h"
+
+#include <QtCore/QDebug>
+
+void TestObject::emitIdValueSignal()
+{
+ emit idValue(m_idValue);
+}
+
+void TestObject::emitStaticMethodDoubleSignal()
+{
+ emit staticMethodDouble();
+}
+
+void TestObject::emitSignalWithDefaultValue_void()
+{
+ emit signalWithDefaultValue();
+}
+
+void TestObject::emitSignalWithDefaultValue_bool()
+{
+ emit signalWithDefaultValue(true);
+}
+
+void TestObject::emitSignalWithTypedefValue(int value)
+{
+ emit signalWithTypedefValue(TypedefValue(value));
+}
+
+void TestObject::emitSignalWithContainerTypedefValue(const IntList &il)
+{
+ emit signalWithContainerTypedefValue(il);
+}
+
+void TestObject::emitFlagsSignal(Qt::Alignment alignment)
+{
+ emit flagsSignal(alignment);
+}
+
+void TestObject::setQLatin1String(QLatin1String v)
+{
+ m_qLatin1String = v;
+}
+
+QString TestObject::qLatin1String() const
+{
+ return m_qLatin1String;
+}
+
+QDebug operator<<(QDebug dbg, TestObject& testObject)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "TestObject(id=" << testObject.idValue() << ") ";
+ return dbg;
+}
+
+namespace PySideCPP {
+ QDebug operator<<(QDebug dbg, TestObjectWithNamespace& testObject)
+ {
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "TestObjectWithNamespace(" << testObject.name() << ") ";
+ return dbg;
+ }
+ QDebug operator<<(QDebug dbg, TestObject2WithNamespace& testObject)
+ {
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "TestObject2WithNamespace(" << testObject.name() << ") ";
+ return dbg;
+ }
+}
diff --git a/sources/pyside6/tests/pysidetest/testobject.h b/sources/pyside6/tests/pysidetest/testobject.h
new file mode 100644
index 000000000..a095a382e
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testobject.h
@@ -0,0 +1,140 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TESTOBJECT_H
+#define TESTOBJECT_H
+
+#include "pysidetest_macros.h"
+
+#include <QtWidgets/QApplication>
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+#include <QtCore/QMetaType>
+#include <QtCore/QVariant>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+using IntList = QList<int>;
+
+class IntValue
+{
+public:
+
+ IntValue(int val): value(val){};
+ IntValue() : value(0) {};
+ int value;
+};
+
+using TypedefValue = IntValue;
+
+class PYSIDETEST_API TestObject : public QObject
+{
+ Q_OBJECT
+public:
+ static void createApp() { int argc=0; new QApplication(argc, nullptr); };
+ static int checkType(const QVariant& var) { return var.metaType().id(); }
+
+ TestObject(int idValue, QObject* parent = nullptr) : QObject(parent), m_idValue(idValue) {}
+ int idValue() const { return m_idValue; }
+ static int staticMethodDouble(int value) { return value * 2; }
+ void addChild(QObject* c) { m_children.append(c); emit childrenChanged(m_children); }
+
+ void emitIdValueSignal();
+ void emitStaticMethodDoubleSignal();
+
+ void emitSignalWithDefaultValue_void();
+ void emitSignalWithDefaultValue_bool();
+
+ void emitSignalWithTypedefValue(int value);
+ void emitSignalWithContainerTypedefValue(const IntList &il);
+
+ void emitFlagsSignal(Qt::Alignment alignment);
+
+ static constexpr auto LATIN1_TEST_FIELD = QLatin1StringView("test");
+
+ void setQLatin1String(QLatin1String v);
+ QString qLatin1String() const;
+
+signals:
+ void idValue(int newValue);
+ void justASignal();
+ void staticMethodDouble();
+ void childrenChanged(const QList<QObject*>&);
+ void signalWithDefaultValue(bool value = false);
+ void signalWithTypedefValue(TypedefValue value);
+ void signalWithContainerTypedefValue(const IntList &il);
+ void flagsSignal(Qt::Alignment alignment);
+
+private:
+ int m_idValue;
+ QList<QObject*> m_children;
+ QString m_qLatin1String;
+};
+
+PYSIDETEST_API QDebug operator<<(QDebug dbg, TestObject &testObject);
+
+using PySideInt = int;
+
+namespace PySideCPP {
+
+class PYSIDETEST_API TestObjectWithNamespace : public QObject
+{
+ Q_OBJECT
+public:
+ TestObjectWithNamespace(QObject* parent) : QObject(parent) {}
+ QString name() { return QStringLiteral("TestObjectWithNamespace"); }
+
+ void callSignal(TestObjectWithNamespace* obj) { emit emitSignal(obj); }
+ void callSignalWithNamespace(TestObjectWithNamespace* obj) { emit emitSignalWithNamespace(obj); }
+ void callSignalWithTypedef(int val) { emit emitSignalWithTypedef(val); }
+
+signals:
+ void emitSignal(TestObjectWithNamespace* obj);
+ void emitSignalWithNamespace(PySideCPP::TestObjectWithNamespace* obj);
+ void emitSignalWithTypedef(PySideInt val);
+};
+
+PYSIDETEST_API QDebug operator<<(QDebug dbg, TestObjectWithNamespace &testObject);
+
+class PYSIDETEST_API TestObject2WithNamespace : public QObject
+{
+ Q_OBJECT
+public:
+ TestObject2WithNamespace(QObject* parent) : QObject(parent) {}
+ QString name() { return QStringLiteral("TestObject2WithNamespace"); }
+};
+
+PYSIDETEST_API QDebug operator<<(QDebug dbg, TestObject2WithNamespace& testObject);
+
+} // Namespace PySideCPP
+
+namespace PySideCPP2 {
+
+enum Enum1 { Option1 = 1, Option2 = 2 };
+
+using PySideLong = long;
+
+class PYSIDETEST_API TestObjectWithoutNamespace : public QObject
+{
+ Q_OBJECT
+public:
+ enum Enum2 { Option3 = 3, Option4 = 4};
+ TestObjectWithoutNamespace(QObject* parent) : QObject(parent) {}
+ QString name() { return QStringLiteral("TestObjectWithoutNamespace"); }
+
+ void callSignal(TestObjectWithoutNamespace* obj) { emitSignal(obj); }
+ void callSignalWithNamespace(TestObjectWithoutNamespace* obj) { emitSignalWithNamespace(obj); }
+ void callSignalWithTypedef(long val) { emitSignalWithTypedef(val); }
+
+signals:
+ void emitSignal(TestObjectWithoutNamespace* obj);
+ void emitSignalWithNamespace(PySideCPP2::TestObjectWithoutNamespace* obj);
+ void emitSignalWithTypedef(PySideLong val);
+};
+
+
+} // Namespace PySideCPP2
+
+#endif // TESTOBJECT_H
+
diff --git a/sources/pyside6/tests/pysidetest/testqvariantenum.cpp b/sources/pyside6/tests/pysidetest/testqvariantenum.cpp
new file mode 100644
index 000000000..7135e422a
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testqvariantenum.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "testqvariantenum.h"
+
+QVariant TestQVariantEnum::getLValEnum() const
+{
+ return this->m_enum;
+}
+
+QVariant TestQVariantEnum::getRValEnum() const
+{
+ return QVariant(Qt::Orientation::Horizontal);
+}
+
+int TestQVariantEnum::getNumberFromQVarEnum(QVariant variantEnum)
+{
+ return variantEnum.toInt();
+}
+
+bool TestQVariantEnum::channelingEnum([[maybe_unused]] QVariant rvalEnum) const
+{
+ return false;
+}
+
+bool TestQVariantEnum::isEnumChanneled() const
+{
+ return this->channelingEnum(this->getRValEnum());
+}
diff --git a/sources/pyside6/tests/pysidetest/testqvariantenum.h b/sources/pyside6/tests/pysidetest/testqvariantenum.h
new file mode 100644
index 000000000..4b729e3dd
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testqvariantenum.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TESTQVARIANT_H
+#define TESTQVARIANT_H
+
+#include "pysidetest_macros.h"
+
+#include <QtCore/QVariant>
+
+class PYSIDETEST_API TestQVariantEnum
+{
+public:
+ TestQVariantEnum(QVariant lvalue_enum) : m_enum(lvalue_enum) {}
+ QVariant getLValEnum() const;
+ static int getNumberFromQVarEnum(QVariant variantEnum = QVariant());
+ bool isEnumChanneled() const;
+ virtual QVariant getRValEnum() const;
+ virtual bool channelingEnum(QVariant rvalEnum) const;
+ virtual ~TestQVariantEnum() = default;
+private:
+ QVariant m_enum;
+};
+
+class PYSIDETEST_API QVariantHolder // modeled after Q3DParameter, test QVariant conversion
+{
+public:
+ void setValue(QVariant v) { m_variant = v; }
+ QVariant value() const { return m_variant; }
+
+private:
+ QVariant m_variant;
+};
+
+#endif // TESTQVARIANT_H
diff --git a/sources/pyside6/tests/pysidetest/testview.cpp b/sources/pyside6/tests/pysidetest/testview.cpp
new file mode 100644
index 000000000..362239112
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testview.cpp
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "testview.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QAbstractListModel>
+#include <QtWidgets/QAbstractItemDelegate>
+#include <QtWidgets/QWidget>
+
+QVariant
+TestView::getData()
+{
+ QModelIndex index;
+ return m_model->data(index);
+}
+
+QWidget*
+TestView::getEditorWidgetFromItemDelegate() const
+{
+ if (m_delegate == nullptr)
+ return nullptr;
+
+ QModelIndex index;
+ QStyleOptionViewItem options;
+ return m_delegate->createEditor(nullptr, options, index);
+}
diff --git a/sources/pyside6/tests/pysidetest/testview.h b/sources/pyside6/tests/pysidetest/testview.h
new file mode 100644
index 000000000..746def83e
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/testview.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef TESTVIEW_H
+#define TESTVIEW_H
+
+#include "pysidetest_macros.h"
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+class QWidget;
+class QAbstractListModel;
+class QAbstractItemDelegate;
+QT_END_NAMESPACE
+
+class PYSIDETEST_API TestView : public QObject
+{
+ Q_OBJECT
+public:
+ TestView(QAbstractListModel* model, QObject* parent = nullptr) :
+ QObject(parent), m_model(model) {}
+ QAbstractListModel* model() { return m_model; }
+ QVariant getData();
+
+ void setItemDelegate(QAbstractItemDelegate* delegate) { m_delegate = delegate; }
+ QWidget* getEditorWidgetFromItemDelegate() const;
+
+private:
+ QAbstractListModel* m_model;
+ QAbstractItemDelegate* m_delegate = nullptr;
+};
+
+#endif // TESTVIEW_H
+
diff --git a/sources/pyside6/tests/pysidetest/true_property_test.py b/sources/pyside6/tests/pysidetest/true_property_test.py
new file mode 100644
index 000000000..62f6505dc
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/true_property_test.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+"""
+PYSIDE-2042: Tests true_property with inheritance
+"""
+is_pypy = hasattr(sys, "pypy_version_info")
+
+from PySide6.QtCore import QSize
+from PySide6.QtWidgets import QWidget, QSpinBox
+if not is_pypy:
+ from __feature__ import true_property
+from helper.usesqapplication import UsesQApplication
+
+
+@unittest.skipIf(is_pypy, "__feature__ cannot yet be used with PyPy")
+class TruePropertyInheritanceTest(UsesQApplication):
+
+ def testTrueProperty(self):
+ # this worked
+ widget = QWidget()
+ check = widget.sizeHint
+ self.assertEqual(type(check), QSize)
+
+ # PYSIDE-2042: inheritance did not work
+ spin_box = QSpinBox()
+ check = spin_box.sizeHint
+ self.assertEqual(type(check), QSize)
+
+ def testHiddenMethods(self):
+ # PYSIDE-1889: setVisible is no longer a meta function but comes from the Property
+ widget = QWidget()
+ self.assertTrue("visible" in QWidget.__dict__)
+ self.assertFalse("isVisible" in QWidget.__dict__)
+ self.assertFalse("setVisible" in QWidget.__dict__)
+ self.assertTrue(hasattr(widget, "isVisible"))
+ self.assertTrue(hasattr(widget, "setVisible"))
+ self.assertEqual(widget.isVisible, QWidget.visible.fget)
+ self.assertEqual(widget.setVisible, QWidget.visible.fset)
+
+ # This works with inheritance as well:
+ class SubClass(QWidget):
+ pass
+ sub_widget = SubClass()
+ self.assertEqual(sub_widget.isVisible, QWidget.visible.fget)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/typedef_signal_test.py b/sources/pyside6/tests/pysidetest/typedef_signal_test.py
new file mode 100644
index 000000000..d0bdc880b
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/typedef_signal_test.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from PySide6.QtCore import QObject, Slot
+from testbinding import TestObject
+
+
+class Receiver(QObject):
+
+ def __init__(self):
+ super().__init__()
+ self.received = None
+
+ def slot(self, value):
+ self.received = value
+
+ @Slot("IntList")
+ def containerSlot(self, value):
+ self.received = value
+
+
+class TypedefSignal(unittest.TestCase):
+
+ def testTypedef(self):
+ obj = TestObject(0)
+ receiver = Receiver()
+
+ obj.signalWithTypedefValue.connect(receiver.slot)
+ obj.emitSignalWithTypedefValue(2)
+ self.assertEqual(receiver.received.value, 2)
+
+ def testContainerTypedef(self):
+ obj = TestObject(0)
+ receiver = Receiver()
+
+ test_list = [1, 2]
+ obj.signalWithContainerTypedefValue.connect(receiver.containerSlot)
+ obj.emitSignalWithContainerTypedefValue(test_list)
+ self.assertEqual(receiver.received, test_list)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml b/sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml
new file mode 100644
index 000000000..592d90a83
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/typesystem_pysidetest.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<typesystem package="testbinding">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+ <value-type name="IntValue"/>
+ <primitive-type name="TypedefValue">
+ <!--
+ A conversion rule is used here because ApiExtractor can't associate
+ a primitive typedef to a non-primitive type. That would be a good
+ improvement to ApiExtractor.
+ -->
+ <conversion-rule>
+ <native-to-target>
+ return %CONVERTTOPYTHON[IntValue](%in);
+ </native-to-target>
+ <target-to-native>
+ <add-conversion type="IntValue">
+ IntValue value = %CONVERTTOCPP[IntValue](%in);
+ %out = %OUTTYPE(value);
+ </add-conversion>
+ </target-to-native>
+ </conversion-rule>
+ </primitive-type>
+ <object-type name="TestObject" />
+
+ <primitive-type name="PySideInt"/>
+ <primitive-type name="PySideCPP2::PySideLong"/>
+ <!--<primitive-type name="PySideLong"/>-->
+
+ <function signature="getHiddenObject()" />
+
+ <inject-code position="end">
+ Shiboken::Conversions::registerConverterName(Shiboken::Conversions::PrimitiveTypeConverter&lt;long&gt;(), "PySideLong");
+ Shiboken::Conversions::registerConverterName(Shiboken::Conversions::PrimitiveTypeConverter&lt;long&gt;(), "PySideCPP2::PySideLong");
+ qRegisterMetaType&lt;PySideInt>("PySideInt");
+ qRegisterMetaType&lt;PySideCPP2::PySideLong>("PySideLong");
+ </inject-code>
+
+ <object-type name="ContainerTest"/>
+
+ <namespace-type name="PySideCPP">
+ <object-type name="TestObjectWithNamespace"/>
+ <object-type name="TestObject2WithNamespace">
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = Shiboken::String::fromCString("TestObject2WithNamespace(injected_repr)");
+ </inject-code>
+ </add-function>
+ </object-type>
+ </namespace-type>
+
+ <namespace-type name="PySideCPP2" generate="no">
+ <enum-type name="Enum1" />
+ <object-type name="TestObjectWithoutNamespace">
+ <enum-type name="Enum2" />
+ </object-type>
+ </namespace-type>
+
+ <object-type name="TestView" >
+ <modify-function signature="TestView(QAbstractListModel*,QObject*)">
+ <modify-argument index="1">
+ <reference-count action="set"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+
+ <value-type name="TestQVariantEnum"/>
+
+ <namespace-type name="FlagsNamespace" visible="no">
+ <enum-type name="Option" flags="Options"/>
+ <object-type name="ClassForEnum" />
+ </namespace-type>
+
+ <object-type name="SharedPointerTestbench"/>
+
+ <value-type name="QVariantHolder"/>
+
+ <smart-pointer-type name="QSharedPointer" type="shared" getter="data"
+ reset-method="reset"/>
+
+</typesystem>
diff --git a/sources/pyside6/tests/pysidetest/version_test.py b/sources/pyside6/tests/pysidetest/version_test.py
new file mode 100644
index 000000000..f47ffc6d0
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/version_test.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6 import __version_info__, __version__
+
+
+class CheckForVariablesTest(unittest.TestCase):
+ def testVesions(self):
+ version_tuple = (__version_info__[0], __version_info__[1], __version_info__[2])
+ self.assertTrue(version_tuple >= (1, 0, 0))
+
+ self.assertTrue(version_tuple < (99, 99, 99))
+ self.assertTrue(__version__)
+
+ self.assertTrue(__version_info__ >= (4, 5, 0))
+ self.assertTrue(__version__)
+
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/sources/pyside6/tests/registry/CMakeLists.txt b/sources/pyside6/tests/registry/CMakeLists.txt
new file mode 100644
index 000000000..02622109a
--- /dev/null
+++ b/sources/pyside6/tests/registry/CMakeLists.txt
@@ -0,0 +1,4 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+PYSIDE_TEST(existence_test.py)
diff --git a/sources/pyside6/tests/registry/existence_test.py b/sources/pyside6/tests/registry/existence_test.py
new file mode 100644
index 000000000..5540b6e04
--- /dev/null
+++ b/sources/pyside6/tests/registry/existence_test.py
@@ -0,0 +1,229 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+existence_test.py
+-----------------
+
+A test that checks all function signatures if they still exist.
+
+Definition of the rules used:
+=============================
+
+Any entry
+---------
+
+ Exists in file Exists in Binary Result
+ + + ok
+ + - error
+ - + ok
+
+List entry
+----------
+
+ Arity in file Arity in Binary Result
+ n n ok
+ n < n error
+ n > n ok
+
+"""
+
+import os
+import re
+import sys
+from textwrap import dedent
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from init_platform import enum_all, generate_all
+from util import (isolate_warnings, check_warnings, suppress_warnings, warn,
+ is_ci, qt_version, get_script_dir, get_effective_refpath,
+ get_refpath, import_refmodule)
+from PySide6 import *
+
+refPath = get_refpath()
+effectiveRefPath = get_effective_refpath()
+pyc = os.path.splitext(effectiveRefPath)[0] + ".pyc"
+if os.path.exists(pyc) and not os.path.exists(effectiveRefPath):
+ # on Python2 the pyc file would be imported
+ os.unlink(pyc)
+
+if refPath != effectiveRefPath:
+ print("*** Falling back to ", effectiveRefPath, " since expected ",
+ refPath, " does not exist")
+
+script_dir = get_script_dir()
+shortpath = os.path.relpath(effectiveRefPath, script_dir)
+try:
+ sig_exists = import_refmodule()
+ print("found:", shortpath)
+ have_refmodule = True
+except ImportError:
+ print("*** not found:", shortpath)
+ have_refmodule = False
+except SyntaxError:
+ print("*** not a python file, removed:", shortpath)
+ os.unlink(effectiveRefPath)
+ have_refmodule = False
+except NameError as e:
+ if "recreate" in e.args[0]:
+ print("*** explicit request to recreate:", shortpath)
+ else:
+ print("*** unexpected NameError:", e, "- creating", shortpath)
+ os.unlink(effectiveRefPath)
+ have_refmodule = False
+dict_name = "sig_dict"
+if have_refmodule and not hasattr(sig_exists, dict_name):
+ print(f"*** wrong module without '{dict_name}', removed: {shortpath}")
+ os.unlink(effectiveRefPath)
+ have_refmodule = False
+
+
+class TestUnrecognizedOffending(unittest.TestCase):
+ """
+ We run the signature generation on all modules and raise an error
+ if a warning was issued. This is better than turning warnings into
+ errors because that would stop early before we have all warnings.
+ """
+ def test_signatures_recognized(self):
+ with isolate_warnings():
+ found_sigs = enum_all()
+ if check_warnings():
+ raise RuntimeError("There are errors, see above.")
+
+
+@unittest.skipIf(not have_refmodule,
+ "not activated for this platform or version")
+class TestSignaturesExists(unittest.TestCase):
+ """
+ This is the current simple attempt to support a signature self test.
+ You can activate it for your platform by supplying your own reference
+ file. Simply run init_platform.py and add the generated file to the
+ repository.
+ """
+
+ @staticmethod
+ def _do_the_test(found_sigs):
+
+ def multi_signature_msg(key, actual, expect):
+ len_act = len(actual) if type(actual) is list else 1
+ len_exp = len(expect) if type(expect) is list else 1
+ return (f"multi-signature count mismatch for '{key}'. "
+ f"Actual {len_act} {actual} vs. expected {len_exp} {expect}")
+
+ for key, value in sig_exists.sig_dict.items():
+ name = key.rsplit(".", 1)[-1]
+ if name in ("next", "__next__"): # ignore problematic cases
+ continue
+ if "<" in key:
+ # Skip over remaining crap in "<...>"
+ continue
+ if key.startswith("sample.SampleNamespace"):
+ # We cannot work with sample namespaces after the change to __qualname__.
+ continue
+ if (key.startswith("smart.SharedPtr") or
+ re.match(r"PySide6\..*?\.QSharedPointer_", key)):
+ # These mangled names are not supported.
+ # We should fix them.
+ continue
+ if key not in found_sigs:
+ warn(f"missing key: '{key} value={value}'", stacklevel=3)
+ else:
+ found_val = found_sigs[key]
+ if type(value) is list and (
+ type(found_val) is tuple or
+ len(found_val) < len(value)):
+ # We check that nothing got lost. But it is ok when an older
+ # registry file does not know all variants, yet!
+ warn(multi_signature_msg(key, found_val, value), stacklevel=3)
+
+ def test_signatures(self):
+ found_sigs = enum_all()
+ with isolate_warnings():
+ self._do_the_test(found_sigs)
+ if is_ci and check_warnings():
+ raise RuntimeError("There are errors, see above.")
+
+ def test_error_is_raised(self):
+ found_sigs = enum_all()
+ # Make sure that errors are actually raised.
+ search = list(found_sigs.keys())
+ pos = 42 # arbitrary and historycal, could be 0 as well
+
+ # We try all variants:
+ while type(found_sigs[search[pos]]) is not tuple:
+ pos += 1
+ tuple_key = search[pos]
+ while type(found_sigs[search[pos]]) is not list:
+ pos += 1
+ list_key = search[pos]
+
+ test_sigs = found_sigs.copy()
+ test_sigs.pop(tuple_key)
+ with isolate_warnings(), suppress_warnings():
+ self._do_the_test(test_sigs)
+ self.assertTrue(check_warnings(), "you warn about too few entries")
+
+ test_sigs = found_sigs.copy()
+ test_sigs["whatnot"] = ("nothing", "real")
+ with isolate_warnings(), suppress_warnings():
+ self._do_the_test(test_sigs)
+ self.assertFalse(check_warnings(), "you ignore too many entries")
+
+ test_sigs = found_sigs.copy()
+ repl = test_sigs[list_key]
+ repl.pop(0)
+ test_sigs[list_key] = repl
+ with isolate_warnings(), suppress_warnings():
+ self._do_the_test(test_sigs)
+ # An arity that is now missing is an error.
+ self.assertTrue(check_warnings(), "you warn when arity got smaller")
+
+ test_sigs = found_sigs.copy()
+ repl = test_sigs[list_key]
+ repl = repl[0]
+ assert type(repl) is tuple
+ test_sigs[list_key] = repl
+ with isolate_warnings(), suppress_warnings():
+ self._do_the_test(test_sigs)
+ # An arity that is now missing is an error.
+ self.assertTrue(check_warnings(), "you warn when list degraded to tuple")
+
+ test_sigs = found_sigs.copy()
+ repl = test_sigs[list_key]
+ repl = repl + repl
+ test_sigs[list_key] = repl
+ with isolate_warnings(), suppress_warnings():
+ self._do_the_test(test_sigs)
+ # More arities are ignored, because we might test an older version.
+ self.assertFalse(check_warnings(), "you ignore when arity got bigger")
+
+
+tested_versions = (5, 6), (5, 9), (5, 11), (5, 12), (5, 14)
+
+if not have_refmodule and is_ci and qt_version()[:2] in tested_versions:
+ class TestFor_CI_Init(unittest.TestCase):
+ """
+ This helper class generates the reference file for CI.
+ It creates an output listing that can be used to check
+ the result back in.
+ """
+ generate_all()
+ sys.stderr.flush()
+ print("BEGIN_FILE", shortpath, file=sys.stderr)
+ with open(refPath) as f:
+ print(f.read(), file=sys.stderr)
+ print("END_FILE", shortpath, file=sys.stderr)
+ sys.stderr.flush()
+ raise RuntimeError(dedent("""
+ {line}
+ ** This is the initial call. You should check this file in:
+ ** {}
+ **""").format(shortpath, line=79 * "*"))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/registry/init_platform.py b/sources/pyside6/tests/registry/init_platform.py
new file mode 100644
index 000000000..8abf30216
--- /dev/null
+++ b/sources/pyside6/tests/registry/init_platform.py
@@ -0,0 +1,210 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+init_platform.py
+
+Existence registry
+==================
+
+This is a registry for all existing function signatures.
+One file is generated with all signatures of a platform and version.
+
+The scope has been extended to generate all signatures from the
+shiboken and pysidetest projects.
+"""
+
+import sys
+import os
+from contextlib import contextmanager
+from textwrap import dedent
+from util import get_refpath, get_script_dir
+
+
+def qt_build():
+ result = '<Unknown build of Qt>'
+ try:
+ from PySide6.QtCore import QLibraryInfo
+ result = QLibraryInfo.build()
+ except:
+ pass
+ return result
+
+
+script_dir = get_script_dir()
+history_dir = os.path.join(script_dir, 'build_history')
+
+# Find out if we have the build dir, already. Then use it.
+look_for = os.path.join("pyside6", "tests", "pysidetest")
+have_build_dir = [x for x in sys.path if x.endswith(look_for)]
+if have_build_dir:
+ all_build_dir = os.path.normpath(os.path.join(have_build_dir[0], "..", "..", ".."))
+elif os.path.exists(history_dir):
+ # Using the last build to find the build dir.
+ # Note: This is not reliable when building in parallel!
+ last_build = max(x for x in os.listdir(history_dir) if x.startswith("20"))
+ fpath = os.path.join(history_dir, last_build, "build_dir.txt")
+ if os.path.exists(fpath):
+ with open(fpath) as f:
+ f_contents = f.read().strip()
+ f_contents_split = f_contents.splitlines()
+ try:
+ all_build_dir = f_contents_split[0]
+ except IndexError:
+ print(f"Error: can't find the build dir in the given file '{fpath}'")
+ sys.exit(1)
+else:
+ print(dedent("""
+ Can't find the build dir in the history.
+ Compile again and don't forget to specify "--build-tests".
+ """))
+ sys.exit(1)
+
+if not os.path.exists(os.path.join(all_build_dir, look_for)):
+ print(dedent("""
+ PySide has not been built with tests enabled.
+ Compile again and don't forget to specify "--build-tests".
+ """))
+ sys.exit(1)
+
+pyside_build_dir = os.path.join(all_build_dir, "pyside6")
+shiboken_build_dir = os.path.join(all_build_dir, "shiboken6")
+
+# now we compute all paths:
+
+
+def set_ospaths(build_dir):
+ ps = os.pathsep
+ ospath_var = "PATH" if sys.platform == "win32" else "LD_LIBRARY_PATH"
+ old_val = os.environ.get(ospath_var, "")
+ lib_path = [os.path.join(build_dir, "pyside6", "tests", "pysidetest"),]
+ ospath = ps.join(lib_path + old_val.split(ps))
+ os.environ[ospath_var] = ospath
+
+
+set_ospaths(all_build_dir)
+
+import PySide6
+
+all_modules = list("PySide6." + _ for _ in PySide6.__all__)
+
+# now we should be able to do all imports:
+if not have_build_dir:
+ sys.path.insert(0, os.path.join(pyside_build_dir, "tests", "pysidetest"))
+import testbinding
+all_modules.append("testbinding")
+
+from shiboken6 import Shiboken
+all_modules.append("shiboken6.Shiboken")
+
+from shibokensupport.signature.lib.enum_sig import SimplifyingEnumerator
+
+# Make sure not to get .pyc in Python2.
+sourcepath = os.path.splitext(__file__)[0] + ".py"
+
+
+class Formatter(object):
+ """
+ Formatter is formatting the signature listing of an enumerator.
+
+ It is written as context managers in order to avoid many callbacks.
+ The separation in formatter and enumerator is done to keep the
+ unrelated tasks of enumeration and formatting apart.
+ """
+ def __init__(self, outfile):
+ self.outfile = outfile
+ self.last_level = 0
+
+ def print(self, *args, **kw):
+ print(*args, file=self.outfile, **kw) if self.outfile else None
+
+ @contextmanager
+ def module(self, mod_name):
+ self.print(f"")
+ self.print(f"# Module {mod_name}")
+ self.print(f"sig_dict.update({{")
+ yield
+ self.print(f' }}) if "{mod_name}" in sys.modules else None')
+
+ @contextmanager
+ def klass(self, class_name, class_str):
+ self.print()
+ self.print(f"# class {self.mod_name}.{class_name}:")
+ yield
+
+ @contextmanager
+ def function(self, func_name, signature):
+ if self.last_level > self.level:
+ self.print()
+ self.last_level = self.level
+ class_name = self.class_name
+ if class_name is None:
+ key = viskey = f"{self.mod_name}.{func_name}"
+ else:
+ key = viskey = f"{self.mod_name}.{class_name}.{func_name}"
+ if key.endswith("lY"):
+ # Some classes like PySide6.QtGui.QContextMenuEvent have functions
+ # globalX and the same with Y. The gerrit robot thinks that this
+ # is a badly written "globally". Convince it by hiding this word.
+ viskey = viskey[:-1] + '""Y'
+ self.print(f' "{viskey}": {signature},')
+ yield key
+
+
+def enum_all():
+ fmt = Formatter(None)
+ enu = SimplifyingEnumerator(fmt)
+ ret = enu.result_type()
+ for mod_name in all_modules:
+ ret.update(enu.module(mod_name))
+ return ret
+
+
+LICENSE_TEXT = """
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+"""
+
+
+def generate_all():
+ refPath = get_refpath()
+ module = os.path.basename(os.path.splitext(refPath)[0])
+ with open(refPath, "w") as outfile, open(sourcepath) as f:
+ fmt = Formatter(outfile)
+ enu = SimplifyingEnumerator(fmt)
+ lines = f.readlines()
+ license_line = next((lno for lno, line in enumerate(lines)
+ if "$QT_END_LICENSE$" in line))
+ fmt.print("#recreate # uncomment this to enforce generation")
+ fmt.print(LICENSE_TEXT)
+ version = sys.version.replace('\n', ' ')
+ build = qt_build()
+ fmt.print(dedent(f'''\
+ """
+ This file contains the simplified signatures for all functions in PySide
+ for module '{module}' using
+ Python {version}
+ {build}
+
+ There are no default values, no variable names and no self
+ parameter. Only types are present after simplification. The
+ functions 'next' resp. '__next__' are removed to make the output
+ identical for Python 2 and 3. '__div__' is also removed,
+ since it exists in Python 2, only.
+ """
+ '''))
+ fmt.print("import sys")
+ fmt.print("")
+ fmt.print("sig_dict = {}")
+ for mod_name in all_modules:
+ enu.module(mod_name)
+ fmt.print("# eof")
+
+
+def __main__():
+ print(f"+++ generating {get_refpath()}. You should probably check this file in.")
+ generate_all()
+
+
+if __name__ == "__main__":
+ __main__()
diff --git a/sources/pyside6/tests/registry/scrape_testresults.py b/sources/pyside6/tests/registry/scrape_testresults.py
new file mode 100644
index 000000000..b7b6b58aa
--- /dev/null
+++ b/sources/pyside6/tests/registry/scrape_testresults.py
@@ -0,0 +1,338 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+scrape_testresults.py
+
+Read the testresults website of COIN and find the pages that contain an
+embedded exists_{platform}_{version}_ci.py .
+
+The found pages will then be sorted by date/time and put into the registry.
+
+This program utilizes the multiprocessing package for speedy access to
+the web pages. The program works well in typically less than half an hour.
+
+After the cache has been created, the runtime is substantially smaller.
+
+"""
+
+import sys
+if sys.version_info[:2] < (3, 6):
+ print("This program is written for Python 3.6 or higher.")
+ sys.exit(1)
+
+DEMO_URL = ("https://testresults.qt.io/coin/api/results/pyside/pyside-setup/"
+ # The above URL part is fixed.
+ "30c1193ec56a86b8d0920c325185b9870f96941e/"
+ "MacOSMacOS_10_12x86_64MacOSMacOS_10_12x86_64Clangqtci-macos-"
+ "10.12-x86_64-8-425364DebugAndRelease_Release/"
+ "d80c5d4547ea2b3d74188bd458955aae39cb32b4/"
+ "test_1535865484/"
+ "log.txt.gz")
+
+from bs4 import BeautifulSoup
+from datetime import datetime
+from multiprocessing import Pool
+from textwrap import dedent
+import requests
+import os
+import time
+import re
+import json
+import argparse
+
+my_name = __file__ if __file__.endswith(".py") else __file__[:-1]
+test_path = os.path.join(os.path.dirname(__file__), "testresults", "embedded")
+if not os.path.exists(test_path):
+ os.makedirs(test_path)
+cache_path = os.path.dirname(test_path)
+target_path = os.path.dirname(__file__)
+start_time = time.time()
+
+
+def get_name(url):
+ """
+ Return the last piece of an url, including trailing slash.
+
+ In effect, this undoes the accumulation of URL pieces.
+ """
+ name = url.rstrip("/").rsplit("/", 1)[-1]
+ if url.endswith("/"):
+ name += "/"
+ return name
+
+
+def rel_url(url):
+ """
+ throw the top URL away
+ """
+ return url[len(top_url):]
+
+
+stop_all = False
+
+
+def find_all_links(text, url, ignore=()):
+ """
+ Find all links in a page.
+
+ Only simple links are allowed. That means safe characters and
+ at most one "/" at the end for directories.
+ """
+ global stop_all
+ soup = BeautifulSoup(text, "html.parser")
+ lis = soup.find_all("a")
+ names = list(row["href"] for row in lis)
+ names = list(name for name in names if name not in ignore)
+ for name in names:
+ if not re.match(r"^[A-Za-z0-9_\-.]+/?$", name):
+ print("Unexpected character in link:", name)
+ # Not clear how to terminate the pool quick and clean.
+ # We crash badly in handle_suburl_tup, ugly but works.
+ stop_all = True
+ return []
+ urls = list(url + name for name in names)
+ return urls
+
+
+def read_url(url):
+ # We intentionally let things fail, because we re-run things on failure.
+ try:
+ response = requests.get(url)
+ except requests.exceptions.ContentDecodingError as e:
+ # This is a permanent error which is in the data. We ignore that.
+ print(os.getpid(), "Decoding Error:", e)
+ print(os.getpid(), "Cannot fix this, ignored.")
+ return None
+ except requests.exceptions.RequestException as e:
+ print("Read error:", e)
+ raise
+ else:
+ return response
+
+
+def get_timestamp(text):
+ # agent:2018/06/29 15:02:15
+ global stop_all
+ prefix = "\nagent:"
+ try:
+ startpos = text.index(prefix)
+ except ValueError:
+ print("this is not the usual format of COIN log files")
+ stop_all = True
+ raise
+ startpos += len(prefix)
+ text = text[startpos : startpos + 80]
+ ts = text[:19]
+ ts = re.sub(r'[^0-9]', '_', ts)
+ # check that it is a valid time stamp
+ try:
+ datetime.strptime(ts, "%Y_%m_%d_%H_%M_%S")
+ except ValueError as e:
+ print("Unexpected time stamp", e)
+ stop_all = True
+ raise
+ return ts
+
+
+def write_data(name, text):
+ try:
+ ts = get_timestamp(text)
+ except ValueError:
+ print()
+ print(name)
+ print()
+ print(text)
+ raise
+ lines = text.split("\n")
+ for idx, line in enumerate(lines):
+ if "BEGIN_FILE" in line:
+ start = idx + 1
+ offset = line.index("BEGIN_FILE")
+ if "END_FILE" in line:
+ stop = idx
+ lines = lines[start : stop]
+ if offset:
+ lines = list(line[offset:] for line in lines)
+ # fix the lines - the original has no empty line after "# eof"
+ while lines[-1] == "":
+ lines.pop()
+ text = "\n".join(lines) + "\n"
+ modname = re.search(r"'(..*?)'", text).group(1)
+ fn = os.path.join(test_path, f"{ts}-{name}-{modname}.py")
+ if os.path.exists(fn):
+ # do not change the file, we want to skip it
+ return
+ with open(fn, "w") as f:
+ f.write(text)
+
+
+def eval_data(force=False):
+ """
+ Read all found files, sort them and keep the latest version.
+ """
+ files = []
+ for entry in os.scandir(test_path):
+ if "exists_" in entry.name and entry.name.endswith(".py"):
+ if force or os.path.getmtime(entry.path) >= start_time:
+ # this file is newly created
+ files.append(entry.path)
+ files.sort()
+ # read the files and update in chronological order
+ results = {}
+ for fn in files:
+ with open(fn) as f:
+ text = f.read()
+ modname = re.search("'(..*?)'", text).group(1)
+ results[modname] = text
+ for fn in results:
+ name = os.path.join(target_path, fn + ".py")
+ with open(name, "w") as f:
+ f.write(results[fn])
+ print("+++ generated:", name)
+ return len(results)
+
+
+def handle_suburl(idx, n, url, level):
+ if level == 1:
+ print(os.getpid(), "Reading", idx + 1, "of", n, rel_url(url))
+ response = read_url(url)
+ urls = find_all_links(response.text, url)
+ for sub_url in urls:
+ name = get_name(sub_url)
+ if name.endswith("/"):
+ if name.startswith("build_"):
+ continue
+ if name == "tasks/":
+ continue
+ handle_suburl(0, 0, sub_url, level + 1)
+ else:
+ if name.startswith("log.txt"):
+ test_name = sub_url.split("/")[-2]
+ print(os.getpid(), test_name)
+ response = read_url(sub_url)
+ txt = response.text if response else ''
+ if "BEGIN_FILE" in txt and "'BEGIN_FILE'" not in txt:
+ # find the text, but not a traceback with that text
+ print(os.getpid(), test_name, "FOUND!")
+ write_data(test_name, response.text)
+ else:
+ print(os.getpid(), test_name)
+
+
+def handle_suburl_tup(idx_n_url_level):
+ if stop_all:
+ return # bad solution, but it stops fast
+ idx, n, url, level = idx_n_url_level
+ try:
+ ret = handle_suburl(idx, n, url, level)
+ return url, None
+ except requests.exceptions.RequestException as e:
+ return url, e
+
+
+def handle_batch(urls, level):
+ n = len(urls)
+ args = ((idx, n, url, level) for (idx, url) in enumerate(urls))
+ with Pool(10) as p:
+ records = list(p.imap_unordered(handle_suburl_tup, args))
+ # re-read the failed ones
+ runs = [n]
+ for idx in range(10):
+ urls = list(x[0] for x in records if x[-1])
+ if not urls:
+ break
+ print("Pausing 5 seconds")
+ time.sleep(5)
+ n = len(urls)
+ runs.append(n)
+ args = ((idx, n, url, level) for (idx, url) in enumerate(urls))
+ with Pool(10) as p:
+ records = list(p.imap_unordered(handle_suburl_tup, args))
+ # Return success when the remaining URLs are empty.
+ print("Runs:", ", ".join(map(str, runs)))
+ return not urls
+
+
+def handle_topurl(url):
+ """
+ Find all links to directories.
+
+ We maintain a cache of these links. The cache is only updated
+ when all URLs have been successfully processed.
+ """
+ try:
+ response = requests.get(url)
+ except requests.exceptions.RequestException as e:
+ print("Skipped", e)
+ return
+ global top_url
+ top_url = url
+ urls = find_all_links(response.text, url, ignore=("tasks/",))
+ work_urls = set(urls)
+ cache_file = os.path.join(cache_path, "known_urls.json")
+ if os.path.exists(cache_file):
+ with open(cache_file, 'r') as fp:
+ known_urls = json.load(fp)
+ work_urls -= set(known_urls)
+ level = 1
+ for sub_url in work_urls:
+ name = get_name(sub_url)
+ if name.endswith("/"):
+ if name.startswith("build_"):
+ continue
+ work_urls.add(sub_url)
+ success = handle_batch(work_urls, 1)
+ if success:
+ with open(cache_file, 'w') as fp:
+ json.dump(urls, fp, sort_keys=True, indent=4)
+ return success
+
+
+def get_test_results(starturl):
+ ok = handle_topurl(starturl)
+ stop_time = time.time()
+ runtime = stop_time - start_time
+ hours, remainder = divmod(runtime, 3600)
+ minutes, seconds = divmod(remainder, 60)
+
+ runtime_formatted = f'{hours}:{minutes:%02d}:{seconds:%06.3f}'
+ print(f"Run time: {runtime_formatted}s")
+ if ok:
+ found = eval_data()
+ print(f"Successful scan, {found} new files.")
+ if found:
+ print("Please check if a git push is necessary.")
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ usage=dedent(f"""\
+ {os.path.basename(my_name)} [-h] scan
+
+ Scan the COIN testresults website for embedded exists_{{platf}}_{{version}}_ci.py files.
+
+ Warning: On the first call, this script may take almost 30 minutes to run.
+ Subsequent calls are *much* faster due to caching.
+
+ {os.path.basename(my_name)} [-h] eval
+
+ Enforces evaluation when a scan did not complete yet.
+
+ For more information, see the file
+ sources/shiboken6/libshiboken/signature_doc.rst
+ """))
+ subparsers = parser.add_subparsers(dest="command", metavar="", title="required argument")
+ # create the parser for the "scan" command
+ parser_scan = subparsers.add_parser("scan", help="run the scan")
+ parser_eval = subparsers.add_parser("eval", help="force evaluation")
+ args = parser.parse_args()
+ if not args.command:
+ parser.print_usage()
+ exit(1)
+ if args.command == "scan":
+ # Using this from the intranet require an internal URL
+ get_test_results("https://testresults.qt.io/coin/api/results/pyside/pyside-setup/")
+ elif args.command == "eval":
+ eval_data(force=True)
diff --git a/sources/pyside6/tests/registry/util.py b/sources/pyside6/tests/registry/util.py
new file mode 100644
index 000000000..5d81926a1
--- /dev/null
+++ b/sources/pyside6/tests/registry/util.py
@@ -0,0 +1,149 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+Supporting isolation of warnings
+
+Warnings in unittests are not isolated.
+We sometimes use warnings to conveniently accumulate error messages
+and eventually report them afterwards as error.
+"""
+
+import sys
+import os
+import warnings
+import re
+from contextlib import contextmanager
+
+warn_name = "__warningregistry__"
+ignore_re = 'Not importing directory .*'
+
+
+@contextmanager
+def isolate_warnings():
+ save_warnings = {}
+ for name, mod in sys.modules.items():
+ if mod and hasattr(mod, warn_name):
+ save_warnings[name] = mod.__dict__[warn_name]
+ delattr(mod, warn_name)
+ yield
+ for name, warn in save_warnings.items():
+ mod = sys.modules[name]
+ if mod:
+ setattr(mod, warn_name, warn)
+ if warn is None:
+ delattr(mod, warn_name)
+
+
+@contextmanager
+def suppress_warnings():
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore")
+ yield
+
+
+def check_warnings():
+ for name, mod in sys.modules.items():
+ if mod:
+ reg = getattr(mod, warn_name, None)
+ if reg:
+ # XXX We need to filter warnings for Python 2.
+ # This should be avoided by renaming the duplicate folders.
+ for k in reg:
+ if type(k) is tuple and re.match(ignore_re, k[0]):
+ continue
+ return True
+ return False
+
+
+def warn(message, category=None, stacklevel=2):
+ """Issue a warning with the default 'RuntimeWarning'"""
+ if category is None:
+ category = UserWarning
+ warnings.warn(message, category, stacklevel)
+
+
+def linux_distribution():
+ """Returns the Linux distribution"""
+ # We have to be more specific because we had differences between
+ # RHEL 6.6 and RHEL 7.4 .
+ # Note: The platform module is deprecated. We need to switch to the
+ # distro package, ASAP! The distro has been extracted from Python,
+ # because it changes more often than the Python version.
+ distribution = []
+ import distro
+ distribution = distro.linux_distribution()
+ if distribution:
+ return "".join(distribution[:2]).lower()
+ warnings.warn('Cannot determine Linux distribution, please install distro',
+ UserWarning)
+ return ""
+
+
+# Python2 legacy: Correct 'linux2' to 'linux', recommended way.
+if sys.platform.startswith('linux'):
+ platform_name = linux_distribution()
+ # this currently happens on opensuse in 5.14:
+ if not platform_name:
+ # We intentionally crash when that last resort is also absent:
+ platform_name = os.environ["MACHTYPE"]
+ platform_name = re.sub('[^0-9a-z]', '_', platform_name)
+else:
+ platform_name = sys.platform
+# In the linux case, we need more information.
+
+is_py3 = sys.version_info[0] == 3
+is_ci = os.environ.get("QTEST_ENVIRONMENT", "") == "ci"
+
+
+def get_script_dir():
+ script_dir = os.path.normpath(os.path.dirname(__file__))
+ while "sources" not in os.listdir(script_dir):
+ script_dir = os.path.dirname(script_dir)
+ return script_dir
+
+
+def qt_version():
+ from PySide6.QtCore import __version__
+ return tuple(map(int, __version__.split(".")))
+
+# Format a registry file name for version.
+
+
+def _registry_filename(version, use_ci_module):
+ ext_ci = "_ci" if use_ci_module else ""
+ name = f"exists_{platform_name}_{version[0]}_{version[1]}_{version[2]}{ext_ci}.py"
+ return os.path.join(os.path.dirname(__file__), name)
+
+# Return the expected registry file name.
+
+
+def get_refpath(use_ci_module=is_ci):
+ return _registry_filename(qt_version(), use_ci_module)
+
+# Return the registry file name, either that of the current
+# version or fall back to a previous patch release.
+
+
+def get_effective_refpath(use_ci_module=is_ci):
+ refpath = get_refpath(use_ci_module)
+ if os.path.exists(refpath):
+ return refpath
+ version = qt_version()
+ major, minor, patch = version[:3]
+ while patch >= 0:
+ file = _registry_filename((major, minor, patch), use_ci_module)
+ if os.path.exists(file):
+ return file
+ patch -= 1
+ return refpath
+
+# Import the CI version of the platform module
+
+
+def import_refmodule(use_ci_module=is_ci):
+ refpath = get_effective_refpath(use_ci_module)
+ modname = os.path.basename(os.path.splitext(refpath)[0])
+ return __import__(modname)
+
+# eof
diff --git a/sources/pyside6/tests/run_test.sh b/sources/pyside6/tests/run_test.sh
new file mode 100755
index 000000000..2cb3efa69
--- /dev/null
+++ b/sources/pyside6/tests/run_test.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# This is a nasty workaround of a CTest limitation
+# of setting the environment variables for the test.
+
+# $1: LD_LIBRARY_PATH
+# $2: $PYTHONPATH
+# $3: python executable
+# $4: test file
+
+export LD_LIBRARY_PATH=$1:$LD_LIBRARY_PATH
+export PYTHONPATH=$2:$PYTHONPATH
+$3 $4
diff --git a/sources/pyside6/tests/signals/CMakeLists.txt b/sources/pyside6/tests/signals/CMakeLists.txt
new file mode 100644
index 000000000..ff342adc7
--- /dev/null
+++ b/sources/pyside6/tests/signals/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+PYSIDE_TEST(args_dont_match_test.py)
+PYSIDE_TEST(bug_79.py)
+PYSIDE_TEST(bug_189.py)
+PYSIDE_TEST(bug_311.py)
+PYSIDE_TEST(bug_312.py)
+PYSIDE_TEST(bug_319.py)
+PYSIDE_TEST(decorators_test.py)
+PYSIDE_TEST(disconnect_test.py)
+PYSIDE_TEST(invalid_callback_test.py)
+PYSIDE_TEST(lambda_gui_test.py)
+PYSIDE_TEST(lambda_test.py)
+PYSIDE_TEST(leaking_signal_test.py)
+PYSIDE_TEST(multiple_connections_gui_test.py)
+PYSIDE_TEST(multiple_connections_test.py)
+PYSIDE_TEST(pysignal_test.py)
+PYSIDE_TEST(qobject_callable_connect_test.py)
+PYSIDE_TEST(qobject_destroyed_test.py)
+PYSIDE_TEST(qobject_receivers_test.py)
+PYSIDE_TEST(qobject_sender_test.py)
+PYSIDE_TEST(ref01_test.py)
+PYSIDE_TEST(ref02_test.py)
+PYSIDE_TEST(ref03_test.py)
+PYSIDE_TEST(ref04_test.py)
+PYSIDE_TEST(ref05_test.py)
+PYSIDE_TEST(ref06_test.py)
+PYSIDE_TEST(segfault_proxyparent_test.py)
+PYSIDE_TEST(self_connect_test.py)
+PYSIDE_TEST(short_circuit_test.py)
+PYSIDE_TEST(signal2signal_connect_test.py)
+PYSIDE_TEST(signal_across_threads.py)
+PYSIDE_TEST(signal_autoconnect_test.py)
+PYSIDE_TEST(signal_connectiontype_support_test.py)
+PYSIDE_TEST(signal_emission_gui_test.py)
+PYSIDE_TEST(signal_emission_test.py)
+PYSIDE_TEST(signal_enum_test.py)
+PYSIDE_TEST(signal_func_test.py)
+PYSIDE_TEST(signal_manager_refcount_test.py)
+PYSIDE_TEST(signal_newenum_test.py)
+PYSIDE_TEST(signal_number_limit_test.py)
+PYSIDE_TEST(signal_object_test.py)
+PYSIDE_TEST(signal_signature_test.py)
+PYSIDE_TEST(signal_with_primitive_type_test.py)
+PYSIDE_TEST(slot_reference_count_test.py)
+PYSIDE_TEST(static_metaobject_test.py)
diff --git a/sources/pyside6/tests/signals/anonymous_slot_leak_test.py b/sources/pyside6/tests/signals/anonymous_slot_leak_test.py
new file mode 100644
index 000000000..560a08659
--- /dev/null
+++ b/sources/pyside6/tests/signals/anonymous_slot_leak_test.py
@@ -0,0 +1,55 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from functools import partial
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QWidget
+from helper.usesqapplication import UsesQApplication
+
+
+have_debug = hasattr(sys, "gettotalrefcount")
+
+
+class LeakerLambda():
+ def __init__(self, widget):
+ widget.windowIconChanged.connect(lambda *args: None)
+
+
+class LeakerFunctoolsPartial():
+ def __init__(self, widget):
+ widget.windowIconChanged.connect(partial(int, 0))
+
+
+class TestBugPYSIDE2299(UsesQApplication):
+ def leak(self, leaker):
+ widget = QWidget()
+
+ # Warm-up
+ leaker(widget)
+
+ refs_before = sys.gettotalrefcount()
+ for _ in range(1000):
+ leaker(widget)
+ refs_after = sys.gettotalrefcount()
+
+ self.assertAlmostEqual(refs_after - refs_before, 0, delta=10)
+
+ @unittest.skipUnless(have_debug, "You need a debug build")
+ def test_lambda(self):
+ self.leak(LeakerLambda)
+
+ @unittest.skipUnless(have_debug, "You need a debug build")
+ def test_functools_partial(self):
+ self.leak(LeakerFunctoolsPartial)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/args_dont_match_test.py b/sources/pyside6/tests/signals/args_dont_match_test.py
new file mode 100644
index 000000000..4f56be348
--- /dev/null
+++ b/sources/pyside6/tests/signals/args_dont_match_test.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class Sender(QObject):
+ the_signal = Signal(int, int, int)
+
+
+class ArgsDontMatch(unittest.TestCase):
+
+ def callback(self, arg1):
+ self.ok = True
+
+ def testConnectSignalToSlotWithLessArgs(self):
+ self.ok = False
+ obj1 = Sender()
+ obj1.the_signal.connect(self.callback)
+ obj1.the_signal.emit(1, 2, 3)
+
+ self.assertTrue(self.ok)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/bug_189.py b/sources/pyside6/tests/signals/bug_189.py
new file mode 100644
index 000000000..1c013ddea
--- /dev/null
+++ b/sources/pyside6/tests/signals/bug_189.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QSlider
+from helper.usesqapplication import UsesQApplication
+
+
+class TestBugPYSIDE189(UsesQApplication):
+
+ def testDisconnect(self):
+ # Disconnecting from a signal owned by a destroyed object
+ # should raise an exception, not segfault.
+ def onValueChanged(self, value):
+ pass
+
+ sld = QSlider()
+ sld.valueChanged.connect(onValueChanged)
+
+ sld.deleteLater()
+
+ QTimer.singleShot(0, self.app.quit)
+ self.app.exec()
+
+ self.assertRaises(RuntimeError, sld.valueChanged.disconnect, onValueChanged)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/bug_311.py b/sources/pyside6/tests/signals/bug_311.py
new file mode 100644
index 000000000..e27476172
--- /dev/null
+++ b/sources/pyside6/tests/signals/bug_311.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QDate, QObject, Signal
+from helper.usesqapplication import UsesQApplication
+
+
+class DerivedDate(QDate):
+ def __init__(self, y, m, d):
+ super().__init__(y, m, d)
+
+
+class Emitter(QObject):
+ dateSignal1 = Signal(QDate)
+ dateSignal2 = Signal(DerivedDate)
+ tupleSignal = Signal(tuple)
+
+
+class SignaltoSignalTest(UsesQApplication):
+ def myCb(self, dt):
+ self._dt = dt
+
+ def testBug(self):
+ e = Emitter()
+ d = DerivedDate(2010, 8, 24)
+ self._dt = None
+ e.dateSignal1.connect(self.myCb)
+ e.dateSignal1.emit(d)
+ self.assertEqual(self._dt, d)
+
+ self._dt = None
+ e.dateSignal2.connect(self.myCb)
+ e.dateSignal2.emit(d)
+ self.assertEqual(self._dt, d)
+
+ myTuple = (5, 6, 7)
+ self._dt = None
+ e.tupleSignal.connect(self.myCb)
+ e.tupleSignal.emit(myTuple)
+ self.assertEqual(myTuple, self._dt)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/bug_312.py b/sources/pyside6/tests/signals/bug_312.py
new file mode 100644
index 000000000..80d56a020
--- /dev/null
+++ b/sources/pyside6/tests/signals/bug_312.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+MAX_LOOPS = 5
+MAX_OBJECTS = 200
+
+
+class Sender(QObject):
+ fire = Signal()
+
+
+class MultipleSlots(unittest.TestCase):
+ def myCB(self):
+ self._count += 1
+
+ def testDisconnectCleanup(self):
+ for c in range(MAX_LOOPS):
+ self._count = 0
+ self._senders = []
+ for i in range(MAX_OBJECTS):
+ o = Sender()
+ o.fire.connect(lambda: self.myCB())
+ self._senders.append(o)
+ o.fire.emit()
+
+ self.assertEqual(self._count, MAX_OBJECTS)
+
+ # delete all senders will disconnect the signals
+ self._senders = []
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/bug_319.py b/sources/pyside6/tests/signals/bug_319.py
new file mode 100644
index 000000000..657733afb
--- /dev/null
+++ b/sources/pyside6/tests/signals/bug_319.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Slot
+from helper.usesqapplication import UsesQApplication
+
+
+class Listener(QObject):
+ def __init__(self):
+ super().__init__(None)
+ self._phrase = []
+
+ @Slot(tuple)
+ def listen(self, words):
+ for w in words:
+ self._phrase.append(w)
+
+
+class Communicate(QObject):
+ # create a new signal on the fly and name it 'speak'
+ speak = Signal(tuple)
+
+
+class SignaltoSignalTest(UsesQApplication):
+ def testBug(self):
+ someone = Communicate()
+ someone2 = Listener()
+ # connect signal and slot
+ someone.speak.connect(someone2.listen)
+ # emit 'speak' signal
+ talk = ("one", "two", "three")
+ someone.speak.emit(talk)
+ self.assertEqual(someone2._phrase, list(talk))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/bug_79.py b/sources/pyside6/tests/signals/bug_79.py
new file mode 100644
index 000000000..77ac621d5
--- /dev/null
+++ b/sources/pyside6/tests/signals/bug_79.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import gc
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtGui import QStandardItemModel
+from PySide6.QtWidgets import QApplication, QTreeView
+
+
+try:
+ from sys import gettotalrefcount
+ skiptest = False
+except ImportError:
+ skiptest = True
+
+
+class ConnectTest(unittest.TestCase):
+
+ def callback(self, o):
+ print("callback")
+ self._called = o
+
+ def testNoLeaks_ConnectAndDisconnect(self):
+ self._called = None
+ app = QApplication([]) # noqa: F841
+ o = QTreeView()
+ o.setModel(QStandardItemModel())
+ o.selectionModel().destroyed.connect(self.callback)
+ o.selectionModel().destroyed.disconnect(self.callback)
+ gc.collect()
+ # if this is no debug build, then we check at least that
+ # we do not crash any longer.
+ for idx in range(200):
+ # PYSIDE-2230: Warm-up is necessary before measuring, because
+ # the code changes the constant parts after some time.
+ o.selectionModel().destroyed.connect(self.callback)
+ o.selectionModel().destroyed.disconnect(self.callback)
+ if not skiptest:
+ total = gettotalrefcount()
+ for idx in range(1000):
+ o.selectionModel().destroyed.connect(self.callback)
+ o.selectionModel().destroyed.disconnect(self.callback)
+ gc.collect()
+ if not skiptest:
+ delta = gettotalrefcount() - total
+ print("delta total refcount =", delta)
+ self.assertTrue(abs(delta) < 10)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/decorators_test.py b/sources/pyside6/tests/signals/decorators_test.py
new file mode 100644
index 000000000..b29339ee4
--- /dev/null
+++ b/sources/pyside6/tests/signals/decorators_test.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Slot, Signal
+
+
+class Sender(QObject):
+ mySignal = Signal()
+
+
+class MyObject(QObject):
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+ self._slotCalledCount = 0
+
+ @Slot()
+ def mySlot(self):
+ self._slotCalledCount = self._slotCalledCount + 1
+
+ @Slot(int)
+ @Slot('QString')
+ def mySlot2(self, arg0):
+ self._slotCalledCount = self._slotCalledCount + 1
+
+ @Slot(name='mySlot3')
+ def foo(self):
+ self._slotCalledCount = self._slotCalledCount + 1
+
+ @Slot(str, int)
+ def mySlot4(self, a, b):
+ self._slotCalledCount = self._slotCalledCount + 1
+
+ @Slot(result=int)
+ def mySlot5(self):
+ self._slotCalledCount = self._slotCalledCount + 1
+
+ @Slot(result=QObject)
+ def mySlot6(self):
+ self._slotCalledCount = self._slotCalledCount + 1
+
+
+class StaticMetaObjectTest(unittest.TestCase):
+
+ def testSignalPropagation(self):
+ o = MyObject()
+ m = o.metaObject()
+ self.assertTrue(m.indexOfSlot('mySlot()') > 0)
+ self.assertTrue(m.indexOfSlot('mySlot2(int)') > 0)
+ self.assertTrue(m.indexOfSlot('mySlot2(QString)') > 0)
+ self.assertTrue(m.indexOfSlot('mySlot3()') > 0)
+ self.assertTrue(m.indexOfSlot('mySlot4(QString,int)') > 0)
+
+ def testEmission(self):
+ sender = Sender()
+ o = MyObject()
+ sender.mySignal.connect(o.mySlot)
+ sender.mySignal.emit()
+ self.assertTrue(o._slotCalledCount == 1)
+
+ def testResult(self):
+ o = MyObject()
+ mo = o.metaObject()
+ i = mo.indexOfSlot('mySlot5()')
+ m = mo.method(i)
+ self.assertEqual(m.typeName(), "int")
+
+ def testResultObject(self):
+ o = MyObject()
+ mo = o.metaObject()
+ i = mo.indexOfSlot('mySlot6()')
+ m = mo.method(i)
+ self.assertEqual(m.typeName(), "QObject*")
+
+
+class SlotWithoutArgs(unittest.TestCase):
+
+ def testError(self):
+ # It should be an error to call the slot without the
+ # arguments, as just @Slot would end up in a slot
+ # accepting argument functions
+ self.assertRaises(TypeError, Slot, lambda: 3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/disconnect_test.py b/sources/pyside6/tests/signals/disconnect_test.py
new file mode 100644
index 000000000..ea3782a91
--- /dev/null
+++ b/sources/pyside6/tests/signals/disconnect_test.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(True)
+
+from PySide6.QtCore import QObject, Signal
+from testbinding import TestObject
+
+
+class Foo(QObject):
+ bar = Signal()
+
+
+class TestDisconnect(unittest.TestCase):
+ def theSlot1(self):
+ self.called1 = True
+
+ def theSlot2(self):
+ self.called2 = True
+
+ def testIt(self):
+ self.called1 = False
+ self.called2 = False
+ f = Foo()
+ f.bar.connect(self.theSlot1)
+ f.bar.connect(self.theSlot2)
+ f.bar.emit()
+ self.assertTrue(self.called1)
+ self.assertTrue(self.called2)
+
+ self.called1 = False
+ self.called2 = False
+ f.bar.disconnect()
+ f.bar.emit()
+ self.assertFalse(self.called1)
+ self.assertFalse(self.called2)
+
+ def testDuringCallback(self):
+ """ Test to see if the C++ object for a connection is accessed after the
+ method returns. This causes a segfault if the memory that was used by the
+ C++ object has been reused. """
+
+ self.called = False
+ obj = TestObject(0)
+
+ def callback():
+ obj.signalWithDefaultValue.disconnect(callback)
+
+ # Connect more callbacks to try to overwrite memory
+ for i in range(1000):
+ obj.signalWithDefaultValue.connect(lambda: None)
+
+ self.called = True
+
+ # A non-None return value is needed
+ return True
+ obj.signalWithDefaultValue.connect(callback)
+ obj.signalWithDefaultValue.emit()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/invalid_callback_test.py b/sources/pyside6/tests/signals/invalid_callback_test.py
new file mode 100644
index 000000000..2788c1d1a
--- /dev/null
+++ b/sources/pyside6/tests/signals/invalid_callback_test.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for passing invalid callbacks to QObject.connect'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class InvalidCallback(unittest.TestCase):
+ '''Test case for passing an invalid callback to QObject.connect'''
+
+ def setUp(self):
+ # Acquire resources
+ self.obj = QObject()
+
+ def tearDown(self):
+ # Release resources
+ try:
+ del self.obj
+ except AttributeError:
+ pass
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testIntegerCb(self):
+ # Test passing an int as callback to QObject.connect
+ self.assertRaises(TypeError, self.obj.destroyed.connect, 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/lambda_gui_test.py b/sources/pyside6/tests/signals/lambda_gui_test.py
new file mode 100644
index 000000000..2123e7206
--- /dev/null
+++ b/sources/pyside6/tests/signals/lambda_gui_test.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Connecting lambda to gui signals'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QSpinBox, QPushButton
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Control:
+ def __init__(self):
+ self.arg = False
+
+
+class QtWidgetsSigLambda(UsesQApplication):
+
+ def testButton(self):
+ # Connecting a lambda to a QPushButton.clicked()
+ obj = QPushButton('label')
+ ctr = Control()
+ func = lambda: setattr(ctr, 'arg', True) # noqa: E731
+ obj.clicked.connect(func)
+ obj.click()
+ self.assertTrue(ctr.arg)
+ self.assertTrue(obj.clicked.disconnect(func))
+
+ def testSpinButton(self):
+ # Connecting a lambda to a QPushButton.clicked()
+ obj = QSpinBox()
+ ctr = Control()
+ arg = 444
+ func = lambda x: setattr(ctr, 'arg', 444) # noqa: E731
+ obj.valueChanged.connect(func)
+ obj.setValue(444)
+ self.assertEqual(ctr.arg, arg)
+ self.assertTrue(obj.valueChanged.disconnect(func))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/lambda_test.py b/sources/pyside6/tests/signals/lambda_test.py
new file mode 100644
index 000000000..23fcdf5fa
--- /dev/null
+++ b/sources/pyside6/tests/signals/lambda_test.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Connecting lambda to signals'''
+
+import os
+import sys
+import unittest
+import weakref
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QObject, Signal, SIGNAL, QProcess
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Sender(QObject):
+ void_signal = Signal()
+ int_signal = Signal(int)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._delayed_int = 0
+
+ def emit_void(self):
+ self.void_signal.emit()
+
+ def emit_int(self, v):
+ self.int_signal.emit(v)
+
+
+class Receiver(QObject):
+
+ def __init__(self, *args):
+ super().__init__(*args)
+
+
+class BasicCase(unittest.TestCase):
+
+ def testSimplePythonSignalNoArgs(self):
+ # Connecting a lambda to a simple python signal without arguments
+ receiver = Receiver()
+ sender = Sender()
+ sender.void_signal.connect(lambda: setattr(receiver, 'called', True))
+ sender.emit_void()
+ self.assertTrue(receiver.called)
+
+ def testSimplePythonSignal(self):
+ # Connecting a lambda to a simple python signal witharguments
+ receiver = Receiver()
+ sender = Sender()
+ arg = 42
+ sender.int_signal.connect(lambda x: setattr(receiver, 'arg', arg))
+ sender.emit_int(arg)
+ self.assertEqual(receiver.arg, arg)
+
+ def testSimplePythonSignalNoArgsString(self):
+ # Connecting a lambda to a simple python signal without arguments
+ receiver = Receiver()
+ sender = Sender()
+ QObject.connect(sender, SIGNAL('void_signal()'),
+ lambda: setattr(receiver, 'called', True))
+ sender.emit_void()
+ self.assertTrue(receiver.called)
+
+ def testSimplePythonSignalString(self):
+ # Connecting a lambda to a simple python signal witharguments
+ receiver = Receiver()
+ sender = Sender()
+ arg = 42
+ QObject.connect(sender, SIGNAL('int_signal(int)'),
+ lambda x: setattr(receiver, 'arg', arg))
+ sender.emit_int(arg)
+ self.assertEqual(receiver.arg, arg)
+
+
+class QtSigLambda(UsesQApplication):
+
+ qapplication = True
+
+ def testWithArgs(self):
+ '''Connecting a lambda to a signal with and without arguments'''
+ proc = QProcess()
+ dummy = Receiver()
+ proc.started.connect(lambda: setattr(dummy, 'called', True))
+ proc.finished.connect(lambda x: setattr(dummy, 'exit_code', x))
+
+ proc.start(sys.executable, ['-c', '""'])
+ self.assertTrue(proc.waitForStarted())
+ self.assertTrue(proc.waitForFinished())
+
+ self.assertTrue(dummy.called)
+ self.assertEqual(dummy.exit_code, proc.exitCode())
+
+ def testRelease(self):
+ """PYSIDE-2646: Test whether main thread target slot lambda/methods
+ (and their captured objects) are released by the signal manager
+ after a while."""
+
+ def do_connect(sender):
+ receiver = Receiver()
+ sender.void_signal.connect(lambda: setattr(receiver, 'called', True))
+ return receiver
+
+ sender = Sender()
+ receiver = weakref.ref(do_connect(sender))
+ sender.emit_void()
+ self.assertTrue(receiver().called)
+ del sender
+ for i in range(3):
+ if not receiver():
+ break
+ QCoreApplication.processEvents()
+ self.assertFalse(receiver())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/leaking_signal_test.py b/sources/pyside6/tests/signals/leaking_signal_test.py
new file mode 100644
index 000000000..666ae7a13
--- /dev/null
+++ b/sources/pyside6/tests/signals/leaking_signal_test.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class LeakingSignal(unittest.TestCase):
+
+ def testLeakingSignal(self):
+ # Was segfaulting when the signal was garbage collected.
+ class Emitter(QObject):
+ my_signal = Signal(object)
+
+ emitter = Emitter() # noqa: F841
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/multiple_connections_gui_test.py b/sources/pyside6/tests/signals/multiple_connections_gui_test.py
new file mode 100644
index 000000000..295369b7d
--- /dev/null
+++ b/sources/pyside6/tests/signals/multiple_connections_gui_test.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QPushButton, QSpinBox
+
+from helper.basicpyslotcase import BasicPySlotCase
+from helper.usesqapplication import UsesQApplication
+
+
+class QtGuiMultipleSlots(UsesQApplication):
+ '''Multiple connections to QtGui signals'''
+
+ def run_many(self, signal, emitter, receivers, args=None):
+ """Utility method to connect a list of receivers to a signal.
+ sender - QObject that will emit the signal
+ signal - string with the signal signature
+ emitter - the callable that will trigger the signal
+ receivers - list of BasicPySlotCase instances
+ args - tuple with the arguments to be sent.
+ """
+
+ if args is None:
+ args = tuple()
+
+ for rec in receivers:
+ rec.setUp()
+ signal.connect(rec.cb)
+ rec.args = tuple(args)
+
+ emitter(*args)
+
+ for rec in receivers:
+ self.assertTrue(rec.called)
+
+ def testButtonClick(self):
+ """Multiple connections to QPushButton.clicked()"""
+ sender = QPushButton('button')
+ receivers = [BasicPySlotCase() for x in range(30)]
+ self.run_many(sender.clicked, sender.click, receivers)
+
+ def testSpinBoxValueChanged(self):
+ """Multiple connections to QSpinBox.valueChanged(int)"""
+ sender = QSpinBox()
+ # FIXME if number of receivers if higher than 50, segfaults
+ receivers = [BasicPySlotCase() for x in range(10)]
+ self.run_many(sender.valueChanged, sender.setValue,
+ receivers, (1,))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/multiple_connections_test.py b/sources/pyside6/tests/signals/multiple_connections_test.py
new file mode 100644
index 000000000..233851797
--- /dev/null
+++ b/sources/pyside6/tests/signals/multiple_connections_test.py
@@ -0,0 +1,90 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+from functools import partial
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, QProcess
+
+from helper.basicpyslotcase import BasicPySlotCase
+from helper.usesqapplication import UsesQApplication
+
+
+class MultipleSignalConnections(unittest.TestCase):
+ '''Base class for multiple signal connection testing'''
+
+ def run_many(self, signal, emitter, receivers, args=None):
+ """Utility method to connect a list of receivers to a signal.
+ sender - QObject that will emit the signal
+ signal - string with the signal signature
+ emitter - the callable that will trigger the signal
+ receivers - list of BasicPySlotCase instances
+ args - tuple with the arguments to be sent.
+ """
+
+ if args is None:
+ args = tuple()
+ for rec in receivers:
+ rec.setUp()
+ self.assertTrue(signal.connect(rec.cb))
+ rec.args = tuple(args)
+
+ emitter(*args)
+
+ for rec in receivers:
+ self.assertTrue(rec.called)
+
+
+class PythonMultipleSlots(UsesQApplication, MultipleSignalConnections):
+ '''Multiple connections to python signals'''
+
+ def testPythonSignal(self):
+ """Multiple connections to a python signal (short-circuit)"""
+
+ class Sender(QObject):
+
+ foobar = Signal(int)
+
+ sender = Sender()
+ receivers = [BasicPySlotCase() for x in range(10)]
+ self.run_many(sender.foobar, partial(sender.foobar.emit),
+ receivers, (0, ))
+
+
+class QProcessMultipleSlots(UsesQApplication, MultipleSignalConnections):
+ '''Multiple connections to QProcess signals'''
+
+ def testQProcessStarted(self):
+ '''Multiple connections to QProcess.started()'''
+ sender = QProcess()
+ receivers = [BasicPySlotCase() for x in range(10)]
+
+ def start_proc(*args):
+ sender.start(sys.executable, ['-c', '""'])
+ self.assertTrue(sender.waitForStarted())
+ self.assertTrue(sender.waitForFinished())
+
+ self.run_many(sender.started, start_proc, receivers)
+
+ def testQProcessFinished(self):
+ '''Multiple connections to QProcess.finished(int)'''
+ sender = QProcess()
+ receivers = [BasicPySlotCase() for x in range(10)]
+
+ def start_proc(*args):
+ sender.start(sys.executable, ['-c', '""'])
+ self.assertTrue(sender.waitForStarted())
+ self.assertTrue(sender.waitForFinished())
+
+ self.run_many(sender.finished, start_proc, receivers, (0, QProcess.ExitStatus.NormalExit))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/pysignal_test.py b/sources/pyside6/tests/signals/pysignal_test.py
new file mode 100644
index 000000000..d6f44edf8
--- /dev/null
+++ b/sources/pyside6/tests/signals/pysignal_test.py
@@ -0,0 +1,203 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Qt
+from PySide6.QtWidgets import QSpinBox, QApplication, QWidget # noqa: F401
+
+from helper.usesqapplication import UsesQApplication
+
+
+TEST_LIST = ["item1", "item2", "item3"]
+
+
+class Sender(QObject):
+ """Sender class used in this test."""
+
+ foo = Signal()
+ foo_int = Signal(int)
+ dummy = Signal(str)
+ dummy2 = Signal(str, list)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def callDummy(self):
+ self.dummy.emit("PyObject")
+
+ def callDummy2(self):
+ self.dummy2.emit("PyObject0", TEST_LIST)
+
+
+class PyObjectType(UsesQApplication):
+ def mySlot(self, arg):
+ self.assertEqual(arg, "PyObject")
+ self.called = True
+ self.callCount += 1
+
+ def mySlot2(self, arg0, arg1):
+ self.assertEqual(arg0, "PyObject0")
+ self.assertEqual(arg1, TEST_LIST)
+ self.callCount += 1
+ if self.running:
+ self.app.quit()
+
+ def setUp(self):
+ super().setUp()
+ self.callCount = 0
+ self.running = False
+
+ def testWithOneArg(self):
+ o = Sender()
+ o.dummy.connect(self.mySlot)
+ o.callDummy()
+ self.assertEqual(self.callCount, 1)
+
+ def testWithTwoArg(self):
+ o = Sender()
+ o.dummy2.connect(self.mySlot2)
+ o.callDummy2()
+ self.assertEqual(self.callCount, 1)
+
+ def testAsyncSignal(self):
+ self.called = False
+ self.running = True
+ o = Sender()
+ o.dummy2.connect(self.mySlot2, Qt.QueuedConnection)
+ o.callDummy2()
+ self.app.exec()
+ self.assertEqual(self.callCount, 1)
+
+ def testTwice(self):
+ self.called = False
+ self.running = True
+ o = Sender()
+ o.dummy2.connect(self.mySlot2, Qt.QueuedConnection)
+ o.callDummy2()
+ o.callDummy2()
+ self.app.exec()
+ self.assertEqual(self.callCount, 2)
+
+
+class PythonSigSlot(unittest.TestCase):
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except: # noqa: E722
+ pass
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testNoArgs(self):
+ """Python signal and slots without arguments"""
+ obj1 = Sender()
+
+ obj1.foo.connect(self.callback)
+ self.args = tuple()
+ obj1.foo.emit(*self.args)
+
+ self.assertTrue(self.called)
+
+ def testWithArgs(self):
+ """Python signal and slots with integer arguments"""
+ obj1 = Sender()
+
+ obj1.foo_int.connect(self.callback)
+ self.args = (42,)
+ obj1.foo_int.emit(*self.args)
+
+ self.assertTrue(self.called)
+
+ def testDisconnect(self):
+ obj1 = Sender()
+
+ obj1.foo_int.connect(self.callback)
+ self.assertTrue(obj1.foo_int.disconnect(self.callback))
+
+ self.args = (42, )
+ obj1.foo_int.emit(*self.args)
+
+ self.assertTrue(not self.called)
+
+
+class SpinBoxPySignal(UsesQApplication):
+ """Tests the connection of python signals to QSpinBox qt slots."""
+
+ def setUp(self):
+ super().setUp()
+ self.obj = Sender()
+ self.spin = QSpinBox()
+ self.spin.setValue(0)
+
+ def tearDown(self):
+ super().tearDown()
+ del self.obj
+ del self.spin
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testValueChanged(self):
+ """Emission of a python signal to QSpinBox setValue(int)"""
+
+ self.obj.foo_int.connect(self.spin.setValue)
+ self.assertEqual(self.spin.value(), 0)
+
+ self.obj.foo_int.emit(4)
+ self.assertEqual(self.spin.value(), 4)
+
+ def testValueChangedMultiple(self):
+ """Multiple emissions of a python signal to QSpinBox setValue(int)"""
+ self.obj.foo_int.connect(self.spin.setValue)
+ self.assertEqual(self.spin.value(), 0)
+
+ self.obj.foo_int.emit(4)
+ self.assertEqual(self.spin.value(), 4)
+
+ self.obj.foo_int.emit(77)
+ self.assertEqual(self.spin.value(), 77)
+
+
+class WidgetPySignal(UsesQApplication):
+ """Tests the connection of python signals to QWidget qt slots."""
+
+ def setUp(self):
+ super(WidgetPySignal, self).setUp()
+ self.obj = Sender()
+ self.widget = QWidget()
+
+ def tearDown(self):
+ super(WidgetPySignal, self).tearDown()
+ del self.obj
+ del self.widget
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testShow(self):
+ """Emission of a python signal to QWidget slot show()"""
+ self.widget.hide()
+
+ self.obj.foo.connect(self.widget.show)
+ self.assertTrue(not self.widget.isVisible())
+
+ self.obj.foo.emit()
+ self.assertTrue(self.widget.isVisible())
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/qobject_callable_connect_test.py b/sources/pyside6/tests/signals/qobject_callable_connect_test.py
new file mode 100644
index 000000000..a7a26d6f5
--- /dev/null
+++ b/sources/pyside6/tests/signals/qobject_callable_connect_test.py
@@ -0,0 +1,45 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class Emitter(QObject):
+ sig = Signal(int)
+
+
+class CallableObject(QObject):
+ called = False
+ x = 0
+
+ def __call__(self, x: int):
+ self.called = True
+ self.x = x
+
+
+class QObjectCallableConnectTest(unittest.TestCase):
+ '''Test case for QObject.connect() when the callable is also a QObject.'''
+
+ def testCallableConnect(self):
+ emitter = Emitter()
+ obj = CallableObject()
+ x = 1
+
+ emitter.sig.connect(obj)
+ emitter.sig.emit(x)
+
+ self.assertTrue(obj.called)
+ self.assertEqual(obj.x, x)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/qobject_destroyed_test.py b/sources/pyside6/tests/signals/qobject_destroyed_test.py
new file mode 100644
index 000000000..a21762b41
--- /dev/null
+++ b/sources/pyside6/tests/signals/qobject_destroyed_test.py
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class QObjectDestroyed(unittest.TestCase):
+ """Very simple test case for the destroyed() signal of QObject"""
+
+ def setUp(self):
+ self.called = False
+
+ def destroyed_cb(self):
+ self.called = True
+
+ def testDestroyed(self):
+ """Emission of QObject.destroyed() to a python slot"""
+ obj = QObject()
+ obj.destroyed.connect(self.destroyed_cb)
+ del obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/qobject_receivers_test.py b/sources/pyside6/tests/signals/qobject_receivers_test.py
new file mode 100644
index 000000000..9839255ac
--- /dev/null
+++ b/sources/pyside6/tests/signals/qobject_receivers_test.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test case for QObject.receivers()'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, SIGNAL, SLOT
+
+
+def cute_slot():
+ pass
+
+
+class TestQObjectReceivers(unittest.TestCase):
+ '''Test case for QObject::receivers'''
+
+ def testBasic(self):
+ sender = QObject()
+ receiver1 = QObject()
+ receiver2 = QObject()
+ self.assertEqual(sender.receivers(SIGNAL("")), 0)
+ sender.destroyed.connect(receiver1.deleteLater)
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 1)
+ sender.destroyed.connect(receiver2.deleteLater)
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 2)
+ sender.disconnect(sender, SIGNAL("destroyed()"), receiver2, SLOT("deleteLater()"))
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 1)
+ del receiver2
+ del receiver1
+ del sender
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testPySlots(self):
+ sender = QObject()
+ receiver = QObject()
+ sender.destroyed.connect(cute_slot)
+ self.assertEqual(sender.receivers(SIGNAL("destroyed( )")), 1)
+ sender.destroyed.connect(receiver.deleteLater)
+ self.assertEqual(sender.receivers(SIGNAL("destroyed()")), 2)
+ del sender
+ del receiver
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testPySignals(self):
+ sender = QObject()
+ receiver = QObject()
+ sender.connect(sender, SIGNAL("some_dynamic_signal()"), cute_slot)
+ self.assertEqual(sender.receivers(SIGNAL("some_dynamic_signal( )")), 1)
+ sender.connect(sender, SIGNAL("some_dynamic_signal()"), receiver, SLOT("deleteLater()"))
+ self.assertEqual(sender.receivers(SIGNAL("some_dynamic_signal( )")), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/qobject_sender_test.py b/sources/pyside6/tests/signals/qobject_sender_test.py
new file mode 100644
index 000000000..9c1121eb8
--- /dev/null
+++ b/sources/pyside6/tests/signals/qobject_sender_test.py
@@ -0,0 +1,117 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for QObject.sender()'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QObject, QTimer, Signal
+from helper.usesqapplication import UsesQApplication
+
+
+class ExtQTimer(QTimer):
+ def __init__(self):
+ super().__init__()
+
+
+class Sender(QObject):
+ foo = Signal()
+
+
+class Receiver(QObject):
+ def __init__(self):
+ super().__init__()
+ self.the_sender = None
+
+ def callback(self):
+ self.the_sender = self.sender()
+ if QCoreApplication.instance():
+ QCoreApplication.instance().exit()
+
+
+class ObjectSenderTest(unittest.TestCase):
+ '''Test case for QObject.sender() method.'''
+
+ def testSenderPythonSignal(self):
+ sender = Sender()
+ recv = Receiver()
+ sender.foo.connect(recv.callback)
+ sender.foo.emit()
+ self.assertEqual(sender, recv.the_sender)
+
+
+class ObjectSenderCheckOnReceiverTest(unittest.TestCase):
+ '''Test case for QObject.sender() method, this one tests the equality on the Receiver object.'''
+
+ def testSenderPythonSignal(self):
+ sender = Sender()
+ recv = Receiver()
+ sender.foo.connect(recv.callback)
+ sender.foo.emit()
+ self.assertEqual(sender, recv.the_sender)
+
+
+class ObjectSenderWithQAppTest(UsesQApplication):
+ '''Test case for QObject.sender() method with QApplication.'''
+
+ def testSenderCppSignal(self):
+ sender = QTimer()
+ sender.setObjectName('foo')
+ recv = Receiver()
+ sender.timeout.connect(recv.callback)
+ sender.start(10)
+ self.app.exec()
+ self.assertEqual(sender, recv.the_sender)
+
+ def testSenderCppSignalSingleShotTimer(self):
+ recv = Receiver()
+ QTimer.singleShot(10, recv.callback)
+ self.app.exec()
+ self.assertTrue(isinstance(recv.the_sender, QObject))
+
+ def testSenderCppSignalSingleShotTimerWithContext(self):
+ recv = Receiver()
+ QTimer.singleShot(10, recv, recv.callback)
+ self.app.exec()
+ self.assertTrue(isinstance(recv.the_sender, QObject))
+
+ def testSenderCppSignalWithPythonExtendedClass(self):
+ sender = ExtQTimer()
+ recv = Receiver()
+ sender.timeout.connect(recv.callback)
+ sender.start(10)
+ self.app.exec()
+ self.assertEqual(sender, recv.the_sender)
+
+
+class ObjectSenderWithQAppCheckOnReceiverTest(UsesQApplication):
+ '''Test case for QObject.sender() method with QApplication.'''
+
+ def testSenderCppSignal(self):
+ sender = QTimer()
+ sender.setObjectName('foo')
+ recv = Receiver()
+ sender.timeout.connect(recv.callback)
+ sender.start(10)
+ self.app.exec()
+ self.assertEqual(sender, recv.the_sender)
+
+ def testSenderCppSignalWithPythonExtendedClass(self):
+ sender = ExtQTimer()
+ recv = Receiver()
+ sender.timeout.connect(recv.callback)
+ sender.start(10)
+ self.app.exec()
+ self.assertEqual(sender, recv.the_sender)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/ref01_test.py b/sources/pyside6/tests/signals/ref01_test.py
new file mode 100644
index 000000000..1a62b2218
--- /dev/null
+++ b/sources/pyside6/tests/signals/ref01_test.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class BoundAndUnboundSignalsTest(unittest.TestCase):
+
+ def setUp(self):
+ self.methods = set(('connect', 'disconnect', 'emit'))
+
+ def tearDown(self):
+ del self.methods
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testUnboundSignal(self):
+ self.assertEqual(type(QObject.destroyed), Signal)
+ self.assertFalse(self.methods.issubset(dir(QObject.destroyed)))
+
+ def testBoundSignal(self):
+ obj = QObject()
+ self.assertNotEqual(type(obj.destroyed), Signal)
+ self.assertTrue(self.methods.issubset(dir(obj.destroyed)))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/ref02_test.py b/sources/pyside6/tests/signals/ref02_test.py
new file mode 100644
index 000000000..54b6f4a52
--- /dev/null
+++ b/sources/pyside6/tests/signals/ref02_test.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimeLine
+from helper.usesqapplication import UsesQApplication
+
+
+class NativeSignalsTest(UsesQApplication):
+
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self.called = False
+ self.timeline = QTimeLine(100)
+
+ def tearDown(self):
+ del self.called
+ del self.timeline
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ def testSignalWithIntArgument(self):
+
+ def valueChangedSlot(value):
+ self.called = True
+ self.assertEqual(type(value), float)
+ self.app.quit()
+
+ self.timeline.valueChanged.connect(valueChangedSlot)
+ self.timeline.start()
+
+ self.app.exec()
+ self.assertTrue(self.called)
+
+ def testSignalWithoutArguments(self):
+
+ def finishedSlot():
+ self.called = True
+ self.app.quit()
+
+ self.timeline.finished.connect(finishedSlot)
+ self.timeline.start()
+
+ self.app.exec()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/ref03_test.py b/sources/pyside6/tests/signals/ref03_test.py
new file mode 100644
index 000000000..c43c2e549
--- /dev/null
+++ b/sources/pyside6/tests/signals/ref03_test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class DisconnectSignalsTest(unittest.TestCase):
+
+ def setUp(self):
+ self.emitter = QObject()
+
+ def tearDown(self):
+ del self.emitter
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testConnectionRefCount(self):
+
+ def destroyedSlot():
+ pass
+
+ self.assertEqual(sys.getrefcount(destroyedSlot), 2)
+ self.emitter.destroyed.connect(destroyedSlot)
+ self.assertEqual(sys.getrefcount(destroyedSlot), 3)
+ self.emitter.destroyed.disconnect(destroyedSlot)
+ self.assertEqual(sys.getrefcount(destroyedSlot), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/ref04_test.py b/sources/pyside6/tests/signals/ref04_test.py
new file mode 100644
index 000000000..fce801456
--- /dev/null
+++ b/sources/pyside6/tests/signals/ref04_test.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class ExtQObject(QObject):
+
+ mySignal = Signal()
+
+ def __init__(self):
+ super().__init__()
+
+
+class UserSignalTest(unittest.TestCase):
+
+ def setUp(self):
+ self.emitter = ExtQObject()
+ self.counter = 0
+
+ def tearDown(self):
+ del self.emitter
+ del self.counter
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def testConnectEmitDisconnect(self):
+
+ def slot():
+ self.counter += 1
+
+ self.emitter.mySignal.connect(slot)
+
+ self.assertEqual(self.counter, 0)
+ self.emitter.mySignal.emit()
+ self.assertEqual(self.counter, 1)
+ self.emitter.mySignal.emit()
+ self.assertEqual(self.counter, 2)
+
+ self.emitter.mySignal.disconnect(slot)
+
+ self.emitter.mySignal.emit()
+ self.assertEqual(self.counter, 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/ref05_test.py b/sources/pyside6/tests/signals/ref05_test.py
new file mode 100644
index 000000000..fb9debf39
--- /dev/null
+++ b/sources/pyside6/tests/signals/ref05_test.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimeLine, Slot
+from helper.usesqapplication import UsesQApplication
+
+
+class ExtQObject(QObject):
+
+ def __init__(self):
+ super().__init__()
+ self.counter = 0
+
+ @Slot('qreal')
+ def foo(self, value):
+ self.counter += 1
+
+
+class UserSlotTest(UsesQApplication):
+
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self.receiver = ExtQObject()
+ self.timeline = QTimeLine(100)
+
+ def tearDown(self):
+ del self.timeline
+ del self.receiver
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ def testUserSlot(self):
+ self.timeline.setUpdateInterval(10)
+
+ self.timeline.finished.connect(self.app.quit)
+
+ self.timeline.valueChanged.connect(self.receiver.foo)
+ self.timeline.start()
+
+ self.app.exec()
+
+ self.assertTrue(self.receiver.counter > 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/ref06_test.py b/sources/pyside6/tests/signals/ref06_test.py
new file mode 100644
index 000000000..a827131db
--- /dev/null
+++ b/sources/pyside6/tests/signals/ref06_test.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QTimeLine, Signal, Slot
+from helper.usesqapplication import UsesQApplication
+
+
+class ExtQObject(QObject):
+ signalbetween = Signal('qreal')
+
+ def __init__(self):
+ super().__init__()
+ self.counter = 0
+
+ @Slot('qreal')
+ def foo(self, value):
+ self.counter += 1
+
+
+class SignaltoSignalTest(UsesQApplication):
+
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self.receiver = ExtQObject()
+ self.timeline = QTimeLine(100)
+
+ def tearDown(self):
+ del self.timeline
+ del self.receiver
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ UsesQApplication.tearDown(self)
+
+ def testSignaltoSignal(self):
+ self.timeline.setUpdateInterval(10)
+
+ self.timeline.finished.connect(self.app.quit)
+
+ self.timeline.valueChanged.connect(self.receiver.signalbetween)
+ self.receiver.signalbetween.connect(self.receiver.foo)
+
+ self.timeline.start()
+
+ self.app.exec()
+
+ self.assertTrue(self.receiver.counter > 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/segfault_proxyparent_test.py b/sources/pyside6/tests/signals/segfault_proxyparent_test.py
new file mode 100644
index 000000000..cb0df0978
--- /dev/null
+++ b/sources/pyside6/tests/signals/segfault_proxyparent_test.py
@@ -0,0 +1,78 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+# Description of the problem
+# After creating an PyObject that inherits from QObject, connecting it,
+# deleting it and later creating another Python QObject-based object, this
+# new object will point to the same memory position as the first one.
+
+# Somehow the underlying QObject also points to the same position.
+
+
+class Sender(QObject):
+
+ bar = Signal(int)
+
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+
+class Joe(QObject):
+
+ bar = Signal(int)
+
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+
+class SegfaultCase(unittest.TestCase):
+ """Test case for the segfault happening when parent() is called inside
+ ProxyObject"""
+
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except: # noqa: E722
+ pass
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testSegfault(self):
+ """Regression: Segfault for qobjects in the same memory position."""
+ obj = Sender()
+ obj.bar.connect(self.callback)
+ self.args = (33,)
+ obj.bar.emit(self.args[0])
+ self.assertTrue(self.called)
+ del obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ obj = Joe()
+ obj.bar.connect(self.callback)
+ self.args = (33,)
+ obj.bar.emit(self.args[0])
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/self_connect_test.py b/sources/pyside6/tests/signals/self_connect_test.py
new file mode 100644
index 000000000..08ca725f8
--- /dev/null
+++ b/sources/pyside6/tests/signals/self_connect_test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Using self.connect(signal, method)'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Slot
+from PySide6.QtWidgets import QPushButton, QWidget
+
+from helper.usesqapplication import UsesQApplication
+
+
+class Receiver(QObject):
+ def __init__(self, p=None):
+ super().__init__(p)
+ self.triggered = False
+
+ @Slot(bool, int)
+ def default_parameter_slot(self, bool_value, int_value=0):
+ self.triggered = True
+
+
+class SelfConnect(UsesQApplication):
+
+ def testButtonClickClose(self):
+ button = QPushButton()
+ button.clicked.connect(button.close)
+
+ button.show()
+ self.assertTrue(button.isVisible())
+ button.click()
+ self.assertTrue(not button.isVisible())
+
+ def testWindowButtonClickClose(self):
+ button = QPushButton()
+ window = QWidget()
+ button.clicked.connect(window.close)
+
+ window.show()
+ self.assertTrue(window.isVisible())
+ button.click()
+ self.assertTrue(not window.isVisible())
+
+ def testDefaultParameters(self):
+ button = QPushButton()
+ receiver = Receiver(button)
+ button.clicked.connect(receiver.default_parameter_slot)
+ button.clicked.connect(button.close)
+ button.show()
+ button.click()
+ self.assertTrue(receiver.triggered)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/short_circuit_test.py b/sources/pyside6/tests/signals/short_circuit_test.py
new file mode 100644
index 000000000..1ad4bc24c
--- /dev/null
+++ b/sources/pyside6/tests/signals/short_circuit_test.py
@@ -0,0 +1,85 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class Sender(QObject):
+ """Sender class used in this test."""
+
+ foo = Signal()
+ foo_int = Signal(int)
+ foo_int_int_string = Signal(int, int, str)
+ foo_int_qobject = Signal(int, QObject)
+
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+
+class ShortCircuitSignals(unittest.TestCase):
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except: # noqa: E722
+ pass
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testNoArgs(self):
+ """Short circuit signal without arguments"""
+ obj1 = Sender()
+ obj1.foo.connect(self.callback)
+ self.args = tuple()
+ obj1.foo.emit(*self.args)
+ self.assertTrue(self.called)
+
+ def testWithArgs(self):
+ """Short circuit signal with integer arguments"""
+ obj1 = Sender()
+
+ obj1.foo_int.connect(self.callback)
+ self.args = (42,)
+ obj1.foo_int.emit(*self.args)
+
+ self.assertTrue(self.called)
+
+ def testMultipleArgs(self):
+ """Short circuit signal with multiple arguments"""
+ obj1 = Sender()
+
+ obj1.foo_int_int_string.connect(self.callback)
+ self.args = (42, 33, 'char')
+ obj1.foo_int_int_string.emit(*self.args)
+
+ self.assertTrue(self.called)
+
+ def testComplexArgs(self):
+ """Short circuit signal with complex arguments"""
+ obj1 = Sender()
+
+ obj1.foo_int_qobject.connect(self.callback)
+ self.args = (42, obj1)
+
+ obj1.foo_int_qobject.emit(*self.args)
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal2signal_connect_test.py b/sources/pyside6/tests/signals/signal2signal_connect_test.py
new file mode 100644
index 000000000..31129f7a1
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal2signal_connect_test.py
@@ -0,0 +1,121 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Test case for signal to signal connections.'''
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class Sender(QObject):
+
+ mysignal_int = Signal(int)
+ mysignal_int_int = Signal(int, int)
+ mysignal_string = Signal(str)
+
+
+class Forwarder(Sender):
+
+ forward = Signal()
+ forward_qobject = Signal(QObject)
+
+
+def cute_slot():
+ pass
+
+
+class TestSignal2SignalConnect(unittest.TestCase):
+ '''Test case for signal to signal connections'''
+
+ def setUp(self):
+ # Set up the basic resources needed
+ self.sender = Sender()
+ self.forwarder = Forwarder()
+ self.args = None
+ self.called = False
+
+ def tearDown(self):
+ # Delete used resources
+ try:
+ del self.sender
+ except: # noqa: E722
+ pass
+ try:
+ del self.forwarder
+ except: # noqa: E722
+ pass
+ del self.args
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def callback_noargs(self):
+ # Default callback without arguments
+ self.called = True
+
+ def callback_args(self, *args):
+ # Default callback with arguments
+ if args == self.args:
+ self.called = True
+ else:
+ raise TypeError("Invalid arguments")
+
+ def callback_qobject(self, *args):
+ # Default callback for QObject as argument
+ if args[0].objectName() == self.args[0]:
+ self.called = True
+ else:
+ raise TypeError("Invalid arguments")
+
+ def testSignalWithoutArguments(self):
+ self.sender.destroyed.connect(self.forwarder.forward)
+ self.forwarder.forward.connect(self.callback_noargs)
+ del self.sender
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self.called)
+
+ def testSignalWithOnePrimitiveTypeArgument(self):
+ self.sender.mysignal_int.connect(self.forwarder.mysignal_int)
+ self.forwarder.mysignal_int.connect(self.callback_args)
+ self.args = (19,)
+ self.sender.mysignal_int.emit(*self.args)
+ self.assertTrue(self.called)
+
+ def testSignalWithMultiplePrimitiveTypeArguments(self):
+ self.sender.mysignal_int_int.connect(self.forwarder.mysignal_int_int)
+ self.forwarder.mysignal_int_int.connect(self.callback_args)
+ self.args = (23, 29)
+ self.sender.mysignal_int_int.emit(*self.args)
+ self.assertTrue(self.called)
+
+ def testSignalWithOneStringArgument(self):
+ self.sender.mysignal_string.connect(self.forwarder.mysignal_string)
+ self.forwarder.mysignal_string.connect(self.callback_args)
+ self.args = ('myargument',)
+ self.sender.mysignal_string.emit(*self.args)
+ self.assertTrue(self.called)
+
+ def testSignalWithOneQObjectArgument(self):
+ self.sender.destroyed.connect(self.forwarder.forward_qobject)
+ self.forwarder.forward_qobject.connect(self.callback_qobject)
+
+ obj_name = 'sender'
+ self.sender.setObjectName(obj_name)
+ self.args = (obj_name, )
+ del self.sender
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_across_threads.py b/sources/pyside6/tests/signals/signal_across_threads.py
new file mode 100644
index 000000000..91b1ca986
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_across_threads.py
@@ -0,0 +1,82 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for PYSIDE-1354: Ensure that slots are invoked from the receiver's
+thread context when using derived classes (and thus, a global receiver).'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, QThread, QTimer, Slot
+from helper.usesqapplication import UsesQApplication
+
+
+class ReceiverBase(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.senderThread = None
+
+ @Slot()
+ def slot_function(self):
+ self.senderThread = QThread.currentThread()
+
+
+class Receiver(ReceiverBase):
+ pass
+
+
+class TestThread(QThread):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def run(self):
+ pass
+
+
+class SignalAcrossThreads(UsesQApplication):
+ def setUp(self):
+ UsesQApplication.setUp(self)
+ self._timer_tick = 0
+ self._timer = QTimer()
+ self._timer.setInterval(20)
+ self._timer.timeout.connect(self._control_test)
+ self._worker_thread = TestThread()
+
+ def tearDown(self):
+ UsesQApplication.tearDown(self)
+
+ @Slot()
+ def _control_test(self):
+ if self._timer_tick == 0:
+ self._worker_thread.start()
+ elif self._timer_tick == 1:
+ self._worker_thread.wait()
+ else:
+ self._timer.stop()
+ self.app.quit()
+ self._timer_tick += 1
+
+ def test(self):
+ worker_thread_receiver = Receiver()
+ worker_thread_receiver.moveToThread(self._worker_thread)
+ self._worker_thread.started.connect(worker_thread_receiver.slot_function)
+
+ main_thread = QThread.currentThread()
+ main_thread_receiver = Receiver()
+ self._worker_thread.started.connect(main_thread_receiver.slot_function)
+
+ self._timer.start()
+ self.app.exec()
+
+ self.assertEqual(worker_thread_receiver.senderThread, self._worker_thread)
+ self.assertEqual(main_thread_receiver.senderThread, main_thread)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_autoconnect_test.py b/sources/pyside6/tests/signals/signal_autoconnect_test.py
new file mode 100644
index 000000000..51d1cea3a
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_autoconnect_test.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QMetaObject, Slot
+from PySide6.QtWidgets import QApplication, QPushButton, QWidget
+
+
+class MyObject(QWidget):
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent)
+ self._method_called = False
+
+ @Slot()
+ def on_button_clicked(self):
+ self._method_called = True
+
+
+class AutoConnectionTest(unittest.TestCase):
+
+ def testConnection(self):
+ app = QApplication([]) # noqa: F841
+
+ win = MyObject()
+ btn = QPushButton("click", win)
+ btn.setObjectName("button")
+ QMetaObject.connectSlotsByName(win)
+ btn.click()
+ self.assertTrue(win._method_called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_connectiontype_support_test.py b/sources/pyside6/tests/signals/signal_connectiontype_support_test.py
new file mode 100644
index 000000000..0a69c1e02
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_connectiontype_support_test.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Qt
+
+
+class Sender(QObject):
+ """Dummy class used in this test."""
+
+ foo = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+class TestConnectionTypeSupport(unittest.TestCase):
+ def callback(self, *args):
+ if tuple(self.args) == args:
+ self.called = True
+
+ def testNoArgs(self):
+ """Connect signal using a Qt.ConnectionType as argument"""
+ obj1 = Sender()
+
+ obj1.foo.connect(self.callback, Qt.DirectConnection)
+ self.args = tuple()
+ obj1.foo.emit(*self.args)
+
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_emission_gui_test.py b/sources/pyside6/tests/signals/signal_emission_gui_test.py
new file mode 100644
index 000000000..5a49b9d12
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_emission_gui_test.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""Tests covering signal emission and receiving to python slots"""
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtWidgets import QSpinBox, QPushButton
+
+from helper.basicpyslotcase import BasicPySlotCase
+from helper.usesqapplication import UsesQApplication
+
+
+class ButtonPySlot(UsesQApplication, BasicPySlotCase):
+ """Tests the connection of python slots to QPushButton signals"""
+
+ def testButtonClicked(self):
+ """Connection of a python slot to QPushButton.clicked()"""
+ button = QPushButton('Mylabel')
+ button.clicked.connect(self.cb)
+ self.args = tuple()
+ button.clicked.emit()
+ self.assertTrue(self.called)
+
+ def testButtonClick(self):
+ """Indirect qt signal emission using the QPushButton.click() method """
+ button = QPushButton('label')
+ button.clicked.connect(self.cb)
+ self.args = tuple()
+ button.click()
+ self.assertTrue(self.called)
+
+
+class SpinBoxPySlot(UsesQApplication, BasicPySlotCase):
+ """Tests the connection of python slots to QSpinBox signals"""
+
+ def setUp(self):
+ super(SpinBoxPySlot, self).setUp()
+ self.spin = QSpinBox()
+
+ def tearDown(self):
+ del self.spin
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super(SpinBoxPySlot, self).tearDown()
+
+ def testSpinBoxValueChanged(self):
+ """Connection of a python slot to QSpinBox.valueChanged(int)"""
+ self.spin.valueChanged.connect(self.cb)
+ self.args = [3]
+ self.spin.valueChanged.emit(*self.args)
+ self.assertTrue(self.called)
+
+ def testSpinBoxValueChangedImplicit(self):
+ """Indirect qt signal emission using QSpinBox.setValue(int)"""
+ self.spin.valueChanged.connect(self.cb)
+ self.args = [42]
+ self.spin.setValue(self.args[0])
+ self.assertTrue(self.called)
+
+ def atestSpinBoxValueChangedFewArgs(self):
+ """Emission of signals with fewer arguments than needed"""
+ self.spin.valueChanged.connect(self.cb)
+ self.args = (554,)
+ self.assertRaises(TypeError, self.spin.valueChanged.emit)
+
+
+class QSpinBoxQtSlots(UsesQApplication):
+ """Tests the connection to QSpinBox qt slots"""
+
+ qapplication = True
+
+ def testSetValueIndirect(self):
+ """Indirect signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
+ spinSend = QSpinBox()
+ spinRec = QSpinBox()
+
+ spinRec.setValue(5)
+
+ spinSend.valueChanged.connect(spinRec.setValue)
+ self.assertEqual(spinRec.value(), 5)
+ spinSend.setValue(3)
+ self.assertEqual(spinRec.value(), 3)
+ self.assertEqual(spinSend.value(), 3)
+
+ def testSetValue(self):
+ """Direct signal emission: QSpinBox using valueChanged(int)/setValue(int)"""
+ spinSend = QSpinBox()
+ spinRec = QSpinBox()
+
+ spinRec.setValue(5)
+ spinSend.setValue(42)
+
+ spinSend.valueChanged.connect(spinRec.setValue)
+ self.assertEqual(spinRec.value(), 5)
+ self.assertEqual(spinSend.value(), 42)
+ spinSend.valueChanged.emit(3)
+
+ self.assertEqual(spinRec.value(), 3)
+ # Direct emission shouldn't change the value of the emitter
+ self.assertEqual(spinSend.value(), 42)
+
+ spinSend.valueChanged.emit(66)
+ self.assertEqual(spinRec.value(), 66)
+ self.assertEqual(spinSend.value(), 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_emission_test.py b/sources/pyside6/tests/signals/signal_emission_test.py
new file mode 100644
index 000000000..b31d89c2f
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_emission_test.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""Tests covering signal emission and receiving to python slots"""
+
+import functools
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, SIGNAL, QProcess, QTimeLine
+
+from helper.usesqapplication import UsesQApplication
+
+
+class ArgsOnEmptySignal(UsesQApplication):
+ '''Trying to emit a signal without arguments passing some arguments'''
+
+ def testArgsToNoArgsSignal(self):
+ '''Passing arguments to a signal without arguments'''
+ process = QProcess()
+ self.assertRaises(TypeError, process.started.emit, 42)
+
+
+class MoreArgsOnEmit(UsesQApplication):
+ '''Trying to pass more args than needed to emit (signals with args)'''
+
+ def testMoreArgs(self):
+ '''Passing more arguments than needed'''
+ process = QProcess()
+ self.assertRaises(TypeError, process.finished.emit, 55, QProcess.ExitStatus.NormalExit, 42)
+
+
+class Sender(QObject):
+ '''Sender class'''
+
+ dummy = Signal()
+ dummy_int = Signal(int)
+
+
+class PythonSignalToCppSlots(UsesQApplication):
+ '''Connect python signals to C++ slots'''
+
+ def testWithoutArgs(self):
+ '''Connect python signal to QTimeLine.toggleDirection()'''
+ timeline = QTimeLine()
+ sender = Sender()
+ sender.dummy.connect(timeline.toggleDirection)
+
+ orig_dir = timeline.direction()
+ sender.dummy.emit()
+ new_dir = timeline.direction()
+
+ if orig_dir == QTimeLine.Forward:
+ self.assertEqual(new_dir, QTimeLine.Backward)
+ else:
+ self.assertEqual(new_dir, QTimeLine.Forward)
+
+ def testWithArgs(self):
+ '''Connect python signals to QTimeLine.setCurrentTime(int)'''
+ timeline = QTimeLine()
+ sender = Sender()
+
+ sender.dummy_int.connect(timeline.setCurrentTime)
+
+ current = timeline.currentTime()
+ sender.dummy_int.emit(current + 42)
+ self.assertEqual(timeline.currentTime(), current + 42)
+
+
+class CppSignalsToCppSlots(UsesQApplication):
+ '''Connection between C++ slots and signals'''
+
+ def testWithoutArgs(self):
+ '''Connect QProcess.started() to QTimeLine.togglePaused()'''
+ process = QProcess()
+ timeline = QTimeLine()
+
+ process.finished.connect(timeline.toggleDirection)
+
+ orig_dir = timeline.direction()
+
+ process.start(sys.executable, ['-c', '"print 42"'])
+ self.assertTrue(process.waitForStarted())
+ self.assertTrue(process.waitForFinished())
+
+ new_dir = timeline.direction()
+
+ if orig_dir == QTimeLine.Forward:
+ self.assertEqual(new_dir, QTimeLine.Backward)
+ else:
+ self.assertEqual(new_dir, QTimeLine.Forward)
+
+
+called = False
+
+
+def someSlot(args=None):
+ global called
+ called = True
+
+
+class DynamicSignalsToFuncPartial(UsesQApplication):
+
+ def testIt(self):
+ global called
+ called = False
+ o = Sender()
+ o.dummy.connect(functools.partial(someSlot, "partial .."))
+ o.dummy.emit()
+ self.assertTrue(called)
+
+
+class EmitUnknownType(UsesQApplication):
+ def testIt(self):
+ a = QObject()
+ a.connect(SIGNAL('foobar(Dummy)'), lambda x: 42) # Just connect with an unknown type
+ self.assertRaises(TypeError, a.emit, SIGNAL('foobar(Dummy)'), 22)
+
+
+class EmitEnum(UsesQApplication):
+ """Test emission of enum arguments"""
+
+ def slot(self, arg):
+ self.arg = arg
+
+ def testIt(self):
+ self.arg = None
+ p = QProcess()
+ p.stateChanged.connect(self.slot)
+ p.stateChanged.emit(QProcess.NotRunning)
+ self.assertEqual(self.arg, QProcess.NotRunning)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_enum_test.py b/sources/pyside6/tests/signals/signal_enum_test.py
new file mode 100644
index 000000000..a792e9b0c
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_enum_test.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+from enum import Enum
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Slot
+
+
+class Colors(Enum):
+ red = 1
+ green = 2
+ blue = 3
+
+
+class Obj(QObject):
+ enum_signal = Signal(Colors)
+ object_signal = Signal(object)
+
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+ self.enum_signal.connect(self.get_result)
+ self.object_signal.connect(self.get_result)
+ self.value = -1
+
+ @Slot()
+ def get_result(self, i):
+ self.value = i
+
+
+class SignalEnumTests(unittest.TestCase):
+ '''Test Signal with enum.Enum'''
+
+ def testSignal(self):
+ o = Obj()
+ # Default value
+ self.assertEqual(o.value, -1)
+
+ # Enum Signal
+ o.enum_signal.emit(Colors.green)
+ self.assertEqual(o.value, Colors.green)
+
+ # object Signal
+ o.object_signal.emit(Colors.red)
+ self.assertEqual(o.value, Colors.red)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_func_test.py b/sources/pyside6/tests/signals/signal_func_test.py
new file mode 100644
index 000000000..d441d4de9
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_func_test.py
@@ -0,0 +1,31 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import SIGNAL, SLOT
+
+
+class SIGNALSLOTTests(unittest.TestCase):
+ '''Test the output of SIGNAL and SLOT.'''
+
+ def testSIGNAL(self):
+ # SIGNAL function
+ a = "foobar"
+ self.assertEqual(str(SIGNAL(a)), "2foobar")
+
+ def testSLOT(self):
+ # SLOT function
+ a = "foobar"
+ self.assertEqual(str(SLOT(a)), "1foobar")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_manager_refcount_test.py b/sources/pyside6/tests/signals/signal_manager_refcount_test.py
new file mode 100644
index 000000000..955d5b65b
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_manager_refcount_test.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class SignalManagerRefCount(unittest.TestCase):
+ """Simple test case to check if the signal_manager is erroneously incrementing the
+ object refcounter."""
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testObjectRefcount(self):
+ """Emission of QObject.destroyed() to a python slot"""
+ def callback():
+ pass
+ obj = QObject()
+ refcount = sys.getrefcount(obj)
+ obj.destroyed.connect(callback)
+ self.assertEqual(refcount, sys.getrefcount(obj))
+ obj.destroyed.disconnect(callback)
+ self.assertEqual(refcount, sys.getrefcount(obj))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_newenum_test.py b/sources/pyside6/tests/signals/signal_newenum_test.py
new file mode 100644
index 000000000..5fbb875af
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_newenum_test.py
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Qt, Slot, Signal
+
+
+class Receiver(QObject):
+ def __init__(self):
+ super().__init__()
+ self.result = 0
+
+ @Slot(Qt.Alignment, str)
+ def handler(self, e, s):
+ print('handler', e, "type=", type(e).__name__, s)
+ self.result += 1
+
+
+class Sender(QObject):
+ test_sig = Signal(Qt.AlignmentFlag, str)
+
+ def __init__(self):
+ super().__init__()
+
+ def emit_test_sig(self):
+ self.test_sig.emit(Qt.AlignLeft, "bla")
+
+
+class TestSignalNewEnum(unittest.TestCase):
+ """Test for PYSIDE-2095, signals with new enums in Python 3.11."""
+
+ def testIt(self):
+ sender = Sender()
+ receiver = Receiver()
+ sender.test_sig.connect(receiver.handler)
+
+ sender.emit_test_sig()
+ self.assertEqual(receiver.result, 1)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_number_limit_test.py b/sources/pyside6/tests/signals/signal_number_limit_test.py
new file mode 100644
index 000000000..29825fe50
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_number_limit_test.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class Emitter(QObject):
+ s1 = Signal()
+ s2 = Signal()
+ s3 = Signal()
+ s4 = Signal()
+ s5 = Signal()
+ s6 = Signal()
+ s7 = Signal()
+ s8 = Signal()
+ s9 = Signal()
+ s10 = Signal()
+ s11 = Signal()
+ s12 = Signal()
+ s13 = Signal()
+ s14 = Signal()
+
+
+class SignalNumberLimitTest(unittest.TestCase):
+ def myCb(self):
+ self._count += 1
+
+ def testBug(self):
+ e = Emitter()
+ e.s1.connect(self.myCb)
+ e.s2.connect(self.myCb)
+ e.s3.connect(self.myCb)
+ e.s4.connect(self.myCb)
+ e.s5.connect(self.myCb)
+ e.s6.connect(self.myCb)
+ e.s7.connect(self.myCb)
+ e.s8.connect(self.myCb)
+ e.s9.connect(self.myCb)
+ e.s10.connect(self.myCb)
+ e.s11.connect(self.myCb)
+ e.s12.connect(self.myCb)
+ e.s13.connect(self.myCb)
+ e.s14.connect(self.myCb)
+
+ self._count = 0
+ e.s1.emit()
+ e.s2.emit()
+ e.s3.emit()
+ e.s4.emit()
+ e.s5.emit()
+ e.s6.emit()
+ e.s7.emit()
+ e.s8.emit()
+ e.s9.emit()
+ e.s10.emit()
+ e.s11.emit()
+ e.s12.emit()
+ e.s13.emit()
+ e.s14.emit()
+ self.assertEqual(self._count, 14)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_object_test.py b/sources/pyside6/tests/signals/signal_object_test.py
new file mode 100644
index 000000000..607f51813
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_object_test.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QTimer, Signal, QObject, Slot, Qt
+from helper.usesqapplication import UsesQApplication
+
+
+class MyObject(QTimer):
+ sig1 = Signal()
+ sig2 = Signal(int, name='rangeChanged')
+ sig3 = Signal(int)
+ sig4 = Signal((int,), (str,))
+ sig5 = Signal((str,), (int,))
+ sig6 = Signal(QObject)
+
+ @Slot(int)
+ def myRange(self, r):
+ self._range = r
+
+ def slot1(self):
+ self._called = True
+
+ def slotString(self, s):
+ self._s = s
+
+ def slotObject(self, o):
+ self._o = o
+
+
+class SignalObjectTest(UsesQApplication):
+ def cb(self):
+ self._cb_called = True
+ self.app.exit()
+
+ def testsingleConnect(self):
+ o = MyObject()
+ o.sig1.connect(o.slot1)
+ o.sig1.emit()
+ self.assertTrue(o._called)
+
+ def testSignalWithArgs(self):
+ o = MyObject()
+ o.sig3.connect(o.myRange)
+ o.sig3.emit(10)
+ self.assertEqual(o._range, 10)
+
+ def testSignatureParse(self):
+ o = MyObject()
+ o.sig2.connect(o.myRange)
+ o.sig2.emit(10)
+
+ def testDictOperator(self):
+ o = MyObject()
+ o.sig4[str].connect(o.slotString)
+ o.sig4[str].emit("PySide")
+ self.assertEqual(o._s, "PySide")
+
+ def testGeneretedSignal(self):
+ o = MyObject()
+ o.timeout.connect(self.cb)
+ o.start(100)
+ self.app.exec()
+ self.assertTrue(self._cb_called)
+
+ def testConnectionType(self):
+ o = MyObject()
+ o.timeout.connect(self.cb, type=Qt.DirectConnection)
+ o.start(100)
+ self.app.exec()
+ self.assertTrue(self._cb_called)
+
+ def testSignalWithSignal(self):
+ o = MyObject()
+ o.sig2.connect(o.myRange)
+ o.sig5.connect(o.sig2)
+ o.sig5[int].emit(10)
+ self.assertEqual(o._range, 10)
+
+ def testSignalWithObject(self):
+ o = MyObject()
+ o.sig6.connect(o.slotObject)
+ arg = QObject()
+ o.sig6.emit(arg)
+ self.assertEqual(arg, o._o)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_signature_test.py b/sources/pyside6/tests/signals/signal_signature_test.py
new file mode 100644
index 000000000..e8f08b2d9
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_signature_test.py
@@ -0,0 +1,105 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test case for signal signature received by QObject::connectNotify().'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, SIGNAL, SLOT
+from helper.usesqapplication import UsesQApplication
+
+
+called = False
+name = "Old"
+
+
+class Sender(QObject):
+ dummySignal = Signal()
+
+
+class Obj(QObject):
+ dummySignalArgs = Signal(str)
+ numberSignal = Signal(int)
+
+ def __init__(self):
+ super().__init__()
+ self.signal = ''
+
+ def connectNotify(self, signal):
+ self.signal = signal
+
+ @staticmethod
+ def static_method():
+ global called
+ called = True
+
+ @staticmethod
+ def static_method_args(arg="default"):
+ global name
+ name = arg
+
+
+def callback(arg=None):
+ pass
+
+
+def callback_empty():
+ pass
+
+
+class TestConnectNotifyWithNewStyleSignals(UsesQApplication):
+ '''Test case for signal signature received by QObject::connectNotify().'''
+
+ def testOldStyle(self):
+ sender = Obj()
+ receiver = QObject()
+ sender.connect(SIGNAL('destroyed()'), receiver, SLOT('deleteLater()'))
+ # When connecting to a regular slot, and not a python callback function, QObject::connect
+ # will use the non-cloned method signature, so connectinc to destroyed() will actually
+ # connect to destroyed(QObject*).
+ self.assertEqual(sender.signal.methodSignature(), 'destroyed(QObject*)')
+
+ def testOldStyleWithPythonCallback(self):
+ sender = Obj()
+ sender.connect(SIGNAL('destroyed()'), callback)
+ self.assertEqual(sender.signal.methodSignature(), 'destroyed()')
+
+ def testNewStyle(self):
+ sender = Obj()
+
+ sender.destroyed.connect(callback_empty)
+ self.assertEqual(sender.signal.methodSignature(), 'destroyed()')
+
+ sender.destroyed[QObject].connect(callback)
+ self.assertEqual(sender.signal.methodSignature(), 'destroyed(QObject*)')
+
+ def testStaticSlot(self):
+ global called
+ sender = Sender()
+ sender.dummySignal.connect(Obj.static_method)
+ sender.dummySignal.emit()
+ self.assertTrue(called)
+
+ def testStaticSlotArgs(self):
+ global name
+ sender = Obj()
+ sender.dummySignalArgs.connect(Obj.static_method_args)
+ sender.dummySignalArgs[str].emit("New")
+ self.assertEqual(name, "New")
+
+ def testLambdaSlot(self):
+ sender = Obj()
+ sender.numberSignal[int].connect(lambda x: 42)
+ with self.assertRaises(IndexError):
+ sender.numberSignal[str].emit("test")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signal_with_primitive_type_test.py b/sources/pyside6/tests/signals/signal_with_primitive_type_test.py
new file mode 100644
index 000000000..01492b333
--- /dev/null
+++ b/sources/pyside6/tests/signals/signal_with_primitive_type_test.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QCoreApplication, QTimeLine
+
+
+class SignalPrimitiveTypeTest(unittest.TestCase):
+
+ def signalValueChanged(self, v):
+ self.called = True
+ self._app.quit()
+
+ def createTimeLine(self):
+ self.called = False
+ tl = QTimeLine(10000)
+ tl.valueChanged.connect(self.signalValueChanged)
+ return tl
+
+ def testTimeLine(self):
+ self._valueChangedCount = 0
+ self._app = QCoreApplication([])
+ tl = self.createTimeLine()
+ tl.start()
+ self._app.exec()
+ self.assertTrue(self.called)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/signals.pyproject b/sources/pyside6/tests/signals/signals.pyproject
new file mode 100644
index 000000000..b63724eaf
--- /dev/null
+++ b/sources/pyside6/tests/signals/signals.pyproject
@@ -0,0 +1,19 @@
+{
+ "files": ["anonymous_slot_leak_test.py", "args_dont_match_test.py",
+ "bug_189.py", "bug_311.py", "bug_312.py", "bug_319.py", "bug_79.py",
+ "decorators_test.py", "disconnect_test.py", "invalid_callback_test.py",
+ "lambda_gui_test.py", "lambda_test.py", "leaking_signal_test.py",
+ "multiple_connections_gui_test.py", "multiple_connections_test.py",
+ "pysignal_test.py", "qobject_callable_connect_test.py", "qobject_destroyed_test.py",
+ "qobject_receivers_test.py", "qobject_sender_test.py", "ref01_test.py",
+ "ref02_test.py", "ref03_test.py", "ref04_test.py", "ref05_test.py",
+ "ref06_test.py", "segfault_proxyparent_test.py",
+ "self_connect_test.py", "short_circuit_test.py",
+ "signal2signal_connect_test.py", "signal_across_threads.py",
+ "signal_autoconnect_test.py", "signal_connectiontype_support_test.py",
+ "signal_emission_gui_test.py", "signal_emission_test.py",
+ "signal_enum_test.py", "signal_func_test.py", "signal_manager_refcount_test.py",
+ "signal_newenum_test.py", "signal_number_limit_test.py",
+ "signal_object_test.py", "signal_signature_test.py", "signal_with_primitive_type_test.py",
+ "slot_reference_count_test.py", "static_metaobject_test.py"]
+}
diff --git a/sources/pyside6/tests/signals/slot_reference_count_test.py b/sources/pyside6/tests/signals/slot_reference_count_test.py
new file mode 100644
index 000000000..9d5c73652
--- /dev/null
+++ b/sources/pyside6/tests/signals/slot_reference_count_test.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+''' Forced disconnection: Delete one end of the signal connection'''
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal
+
+
+class Dummy(QObject):
+ foo = Signal()
+
+ def dispatch(self):
+ self.foo.emit()
+
+
+class PythonSignalRefCount(unittest.TestCase):
+
+ def setUp(self):
+ self.emitter = Dummy()
+
+ def tearDown(self):
+ self.emitter
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCount(self):
+ def cb(*args):
+ pass
+
+ self.assertEqual(sys.getrefcount(cb), 2)
+
+ self.emitter.foo.connect(cb)
+ self.assertEqual(sys.getrefcount(cb), 3)
+
+ self.emitter.foo.disconnect(cb)
+ self.assertEqual(sys.getrefcount(cb), 2)
+
+
+class CppSignalRefCount(unittest.TestCase):
+
+ def setUp(self):
+ self.emitter = QObject()
+
+ def tearDown(self):
+ self.emitter
+
+ @unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
+ def testRefCount(self):
+ def cb(*args):
+ pass
+
+ self.assertEqual(sys.getrefcount(cb), 2)
+
+ self.emitter.destroyed.connect(cb)
+ self.assertEqual(sys.getrefcount(cb), 3)
+
+ self.emitter.destroyed.disconnect(cb)
+ self.assertEqual(sys.getrefcount(cb), 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/signals/static_metaobject_test.py b/sources/pyside6/tests/signals/static_metaobject_test.py
new file mode 100644
index 000000000..d7bf73e44
--- /dev/null
+++ b/sources/pyside6/tests/signals/static_metaobject_test.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""Tests covering signal emission and receiving to python slots"""
+
+import gc
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject, Signal, Slot, SIGNAL
+from helper.usesqapplication import UsesQApplication
+
+
+class Sender(QObject):
+
+ foo = Signal()
+ foo2 = Signal()
+
+
+class MyObject(QObject):
+
+ foo2 = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._slotCalledCount = 0
+
+ # this '@Slot()' is needed to get the right sort order in testSharedSignalEmission.
+ # For some reason, it also makes the tests actually work!
+ @Slot()
+ def mySlot(self):
+ self._slotCalledCount = self._slotCalledCount + 1
+
+
+class StaticMetaObjectTest(UsesQApplication):
+
+ def testSignalPropagation(self):
+ """Old style, dynamic signal creation."""
+ o = QObject()
+ o2 = MyObject()
+
+ # SIGNAL foo not created yet
+ self.assertEqual(o.metaObject().indexOfSignal("foo()"), -1)
+
+ o.connect(SIGNAL("foo()"), o2.mySlot)
+ # SIGNAL foo create after connect
+ self.assertTrue(o.metaObject().indexOfSignal("foo()") > 0)
+
+ # SIGNAL does not propagate to others objects of the same type
+ self.assertEqual(o2.metaObject().indexOfSignal("foo()"), -1)
+
+ del o
+ del o2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ o = MyObject()
+ # The SIGNAL was destroyed with old objects
+ self.assertEqual(o.metaObject().indexOfSignal("foo()"), -1)
+
+ def testSharedSignalEmission(self):
+ o = Sender()
+ m = MyObject()
+
+ o.foo2.connect(m.mySlot)
+ m.foo2.connect(m.mySlot)
+ o.foo2.emit()
+ self.assertEqual(m._slotCalledCount, 1)
+ del o
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ m.foo2.emit()
+ self.assertEqual(m._slotCalledCount, 2)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/support/CMakeLists.txt b/sources/pyside6/tests/support/CMakeLists.txt
new file mode 100644
index 000000000..1f18ecf23
--- /dev/null
+++ b/sources/pyside6/tests/support/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(voidptr_test.py)
diff --git a/sources/pyside6/tests/support/voidptr_test.py b/sources/pyside6/tests/support/voidptr_test.py
new file mode 100644
index 000000000..d9ea57a61
--- /dev/null
+++ b/sources/pyside6/tests/support/voidptr_test.py
@@ -0,0 +1,49 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from shiboken6 import Shiboken
+from PySide6.support import VoidPtr
+from PySide6.QtCore import QByteArray
+
+
+class PySide6Support(unittest.TestCase):
+
+ def testVoidPtr(self):
+ # Creating a VoidPtr object requires an address of
+ # a C++ object, a wrapped Shiboken Object type,
+ # an object implementing the Python Buffer interface,
+ # or another VoidPtr object.
+
+ # Original content
+ b = b"Hello world"
+ ba = QByteArray(b)
+ vp = VoidPtr(ba, ba.size())
+ self.assertIsInstance(vp, Shiboken.VoidPtr)
+
+ # Create QByteArray from voidptr byte interpretation
+ nba = QByteArray(vp.toBytes())
+ # Compare original bytes to toBytes()
+ self.assertTrue(b, vp.toBytes())
+ # Compare original with new QByteArray data
+ self.assertTrue(b, nba.data())
+ # Convert original and new to str
+ self.assertTrue(str(b), str(nba))
+
+ # Modify nba through a memoryview of vp
+ mv = memoryview(vp)
+ self.assertFalse(mv.readonly)
+ mv[6:11] = b'void*'
+ self.assertEqual(str(ba), str(b"Hello void*"))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/tools/__init__.py b/sources/pyside6/tests/tools/__init__.py
new file mode 100644
index 000000000..31f792369
--- /dev/null
+++ b/sources/pyside6/tests/tools/__init__.py
@@ -0,0 +1 @@
+from init_paths import init_test_paths
diff --git a/sources/pyside6/tests/tools/list-class-hierarchy.py b/sources/pyside6/tests/tools/list-class-hierarchy.py
new file mode 100644
index 000000000..b773b7c58
--- /dev/null
+++ b/sources/pyside6/tests/tools/list-class-hierarchy.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# This is a small script printing out Qt binding class hierarchies
+# for comparison purposes.
+#
+# Usage:
+#
+# ./list-class-hierarchy.py PySide6 > pyside6.list
+# ./list-class-hierarchy.py PyQt5 > pyqt5.list
+#
+# meld pyside.list pyqt5.list
+
+import sys
+import pdb
+from inspect import isclass
+
+ignore = ["staticMetaObject",
+ "pyqtConfigure",
+ "registerUserData",
+ "thread"]
+
+
+def recurse_into(el, obj):
+ #s = el.split('.')[-1]
+ #pdb.set_trace()
+ symbols = []
+ for item in sorted(dir(obj)):
+ if item[0] == '_':
+ continue
+ mel = el + '.' + item
+ try:
+ mobj = eval(mel)
+ except Exception:
+ continue
+
+ if item in ignore:
+ continue
+ else:
+ symbols.append(mel)
+
+ if isclass(mobj):
+ symbols += recurse_into(mel, mobj)
+
+ return symbols
+
+
+if __name__ == '__main__':
+ modules = [ 'QtCore',
+ 'QtGui',
+ 'QtHelp',
+ #'QtMultimedia',
+ 'QtNetwork',
+ #'QtOpenGL',
+ 'QtScript',
+ 'QtScriptTools',
+ 'QtSql',
+ 'QtSvg',
+ 'QtTest',
+ #'QtUiTools',
+ 'QtXml',
+ 'QtXmlPatterns' ]
+
+ libraries = ["PySide6", "PyQt5"]
+ librarySymbols = {}
+ for l in libraries:
+ dictionary = []
+ if l == "PyQt5":
+ import sip
+ sip.setapi('QDate', 2)
+ sip.setapi('QDateTime', 2)
+ sip.setapi('QString', 2)
+ sip.setapi('QTextStream', 2)
+ sip.setapi('QTime', 2)
+ sip.setapi('QUrl', 2)
+ sip.setapi('QVariant', 2)
+
+ for m in modules:
+ exec(f"from {l} import {m}", globals(), locals())
+ dictionary += recurse_into(m, eval(m))
+ librarySymbols[l] = dictionary
+
+ print("PyQt5: ", len(librarySymbols["PyQt5"]), " PySide6: ", len(librarySymbols["PySide6"]))
+
+ for symbol in librarySymbols["PyQt5"]:
+ if not (symbol in librarySymbols["PySide6"]):
+ print("Symbol not found in PySide6:", symbol)
diff --git a/sources/pyside6/tests/tools/metaobjectdump/CMakeLists.txt b/sources/pyside6/tests/tools/metaobjectdump/CMakeLists.txt
new file mode 100644
index 000000000..f1ad6ab16
--- /dev/null
+++ b/sources/pyside6/tests/tools/metaobjectdump/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(test_metaobjectdump.py)
diff --git a/sources/pyside6/tests/tools/metaobjectdump/baseline_default_birthdayparty.json b/sources/pyside6/tests/tools/metaobjectdump/baseline_default_birthdayparty.json
new file mode 100644
index 000000000..6a695dd5c
--- /dev/null
+++ b/sources/pyside6/tests/tools/metaobjectdump/baseline_default_birthdayparty.json
@@ -0,0 +1 @@
+[{"classes": [{"className": "BirthdayParty", "qualifiedClassName": "BirthdayParty", "object": true, "superClasses": [{"access": "public", "name": "QObject"}], "classInfos": [{"name": "QML.Element", "value": "auto"}, {"name": "DefaultProperty", "value": "guests"}], "properties": [{"name": "host", "type": "Person", "index": 0, "read": "host", "notify": "host_changed", "write": "host"}, {"name": "guests", "type": "QQmlListProperty<Person>", "index": 1}], "signals": [{"access": "public", "name": "host_changed", "arguments": [], "returnType": "void"}, {"access": "public", "name": "guests_changed", "arguments": [], "returnType": "void"}]}], "outputRevision": 68, "QML_IMPORT_NAME": "People", "QML_IMPORT_MAJOR_VERSION": 1, "QML_IMPORT_MINOR_VERSION": 0, "QT_MODULES": ["QtCore", "QtQml"]}] \ No newline at end of file
diff --git a/sources/pyside6/tests/tools/metaobjectdump/baseline_default_person.json b/sources/pyside6/tests/tools/metaobjectdump/baseline_default_person.json
new file mode 100644
index 000000000..571056c2a
--- /dev/null
+++ b/sources/pyside6/tests/tools/metaobjectdump/baseline_default_person.json
@@ -0,0 +1 @@
+[{"classes": [{"className": "Person", "qualifiedClassName": "Person", "object": true, "superClasses": [{"access": "public", "name": "QObject"}], "classInfos": [{"name": "QML.Element", "value": "anonymous"}], "properties": [{"name": "name", "type": "QString", "index": 0, "read": "name", "notify": "name_changed", "write": "name"}, {"name": "shoe_size", "type": "int", "index": 1, "read": "shoe_size", "notify": "shoe_size_changed", "write": "shoe_size"}], "signals": [{"access": "public", "name": "name_changed", "arguments": [], "returnType": "void"}, {"access": "public", "name": "shoe_size_changed", "arguments": [], "returnType": "void"}]}, {"className": "Boy", "qualifiedClassName": "Boy", "object": true, "superClasses": [{"access": "public", "name": "Person"}], "classInfos": [{"name": "QML.Element", "value": "auto"}]}, {"className": "Girl", "qualifiedClassName": "Girl", "object": true, "superClasses": [{"access": "public", "name": "Person"}], "classInfos": [{"name": "QML.Element", "value": "auto"}]}], "outputRevision": 68, "QML_IMPORT_NAME": "People", "QML_IMPORT_MAJOR_VERSION": 1, "QML_IMPORT_MINOR_VERSION": 0, "QT_MODULES": ["QtCore", "QtQml"]}] \ No newline at end of file
diff --git a/sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_birthdayparty.json b/sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_birthdayparty.json
new file mode 100644
index 000000000..0491e41cc
--- /dev/null
+++ b/sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_birthdayparty.json
@@ -0,0 +1 @@
+[{"classes": [{"className": "BirthdayParty", "qualifiedClassName": "BirthdayParty", "object": true, "superClasses": [{"access": "public", "name": "QObject"}], "classInfos": [{"name": "QML.Element", "value": "auto"}], "properties": [{"name": "host", "type": "Person", "index": 0, "read": "host", "notify": "host_changed", "write": "host"}, {"name": "guests", "type": "QQmlListProperty<Person>", "index": 1}], "signals": [{"access": "public", "name": "host_changed", "arguments": [], "returnType": "void"}, {"access": "public", "name": "guests_changed", "arguments": [], "returnType": "void"}]}], "outputRevision": 68, "QML_IMPORT_NAME": "People", "QML_IMPORT_MAJOR_VERSION": 1, "QML_IMPORT_MINOR_VERSION": 0, "QT_MODULES": ["QtCore", "QtQml"]}] \ No newline at end of file
diff --git a/sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_person.json b/sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_person.json
new file mode 100644
index 000000000..82021ee0a
--- /dev/null
+++ b/sources/pyside6/tests/tools/metaobjectdump/baseline_inheritance_person.json
@@ -0,0 +1 @@
+[{"classes": [{"className": "Person", "qualifiedClassName": "Person", "object": true, "superClasses": [{"access": "public", "name": "QObject"}], "classInfos": [{"name": "QML.Element", "value": "auto"}, {"name": "QML.Creatable", "value": "false"}, {"name": "QML.UncreatableReason", "value": "Person is an abstract base class."}], "properties": [{"name": "name", "type": "QString", "index": 0, "read": "name", "notify": "name_changed", "write": "name"}, {"name": "shoe_size", "type": "int", "index": 1, "read": "shoe_size", "notify": "shoe_size_changed", "write": "shoe_size"}], "signals": [{"access": "public", "name": "name_changed", "arguments": [], "returnType": "void"}, {"access": "public", "name": "shoe_size_changed", "arguments": [], "returnType": "void"}]}, {"className": "Boy", "qualifiedClassName": "Boy", "object": true, "superClasses": [{"access": "public", "name": "Person"}], "classInfos": [{"name": "QML.Element", "value": "auto"}]}, {"className": "Girl", "qualifiedClassName": "Girl", "object": true, "superClasses": [{"access": "public", "name": "Person"}], "classInfos": [{"name": "QML.Element", "value": "auto"}]}], "outputRevision": 68, "QML_IMPORT_NAME": "People", "QML_IMPORT_MAJOR_VERSION": 1, "QML_IMPORT_MINOR_VERSION": 0, "QT_MODULES": ["QtCore", "QtQml"]}] \ No newline at end of file
diff --git a/sources/pyside6/tests/tools/metaobjectdump/baseline_property_happybirthdaysong.json b/sources/pyside6/tests/tools/metaobjectdump/baseline_property_happybirthdaysong.json
new file mode 100644
index 000000000..c009111b7
--- /dev/null
+++ b/sources/pyside6/tests/tools/metaobjectdump/baseline_property_happybirthdaysong.json
@@ -0,0 +1 @@
+[{"classes": [{"className": "HappyBirthdaySong", "qualifiedClassName": "HappyBirthdaySong", "object": false, "superClasses": [{"access": "public", "name": "QPyQmlPropertyValueSource"}], "classInfos": [{"name": "QML.Element", "value": "auto"}], "properties": [{"name": "name", "type": "QString", "index": 0, "read": "name", "notify": "name_changed", "write": "name"}], "signals": [{"access": "public", "name": "name_changed", "arguments": [], "returnType": "void"}], "slots": [{"access": "public", "name": "advance", "arguments": [], "returnType": "void"}]}], "outputRevision": 68, "QML_IMPORT_NAME": "People", "QML_IMPORT_MAJOR_VERSION": 1, "QML_IMPORT_MINOR_VERSION": 0, "QT_MODULES": ["QtCore", "QtQml"]}] \ No newline at end of file
diff --git a/sources/pyside6/tests/tools/metaobjectdump/test_metaobjectdump.py b/sources/pyside6/tests/tools/metaobjectdump/test_metaobjectdump.py
new file mode 100644
index 000000000..5e7412bf5
--- /dev/null
+++ b/sources/pyside6/tests/tools/metaobjectdump/test_metaobjectdump.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import subprocess
+import unittest
+
+from pathlib import Path
+
+"""Test for pyside6-metaobjectdump.
+
+The test prints commands to regenerate the base line."""
+
+
+def msg_regenerate(cmd, baseline):
+ cmd_str = " ".join(cmd)
+ return (f"# Regenerate {baseline}\n"
+ f"{cmd_str} > {baseline}")
+
+
+@unittest.skipIf(sys.version_info < (3, 8), "Needs a recent ast module")
+class TestMetaObjectDump(unittest.TestCase):
+ """Test for the metaobjectdump tool. Compares the output of metaobjectdump.py for some
+ example files in compact format."""
+
+ def setUp(self):
+ super().setUp()
+ self._dir = Path(__file__).parent.resolve()
+ pyside_root = self._dir.parents[4]
+ self._metaobjectdump_tool = pyside_root / "sources" / "pyside-tools" / "metaobjectdump.py"
+ self._examples_dir = (pyside_root / "examples" /
+ "qml" / "tutorials" / "extending-qml-advanced")
+
+ # Compile a list of examples (tuple [file, base line, command])
+ examples = []
+ for d in ["advanced2-Inheritance-and-coercion", "advanced3-Default-properties"]:
+ example_dir = self._examples_dir / d
+ examples.append(example_dir / "birthdayparty.py")
+ examples.append(example_dir / "person.py")
+ # Example with slot
+ examples.append(self._examples_dir / "advanced6-Property-value-source"
+ / "happybirthdaysong.py")
+
+ metaobjectdump_cmd_root = [sys.executable, os.fspath(self._metaobjectdump_tool), "-c", "-s"]
+ self._examples = []
+ for example in examples:
+ name = example.parent.name
+ # Simplify "advanced2-Inheritance-and-coercion" -> "inheritance"
+ short_name = name.split("-")[1].lower()
+ baseline_name = f"baseline_{short_name}_{example.stem}.json"
+ baseline_path = self._dir / baseline_name
+ cmd = metaobjectdump_cmd_root + [os.fspath(example)]
+ self._examples.append((example, baseline_path, cmd))
+ print(msg_regenerate(cmd, baseline_path))
+
+ def testMetaObjectDump(self):
+ self.assertTrue(self._examples_dir.is_dir())
+ self.assertTrue(self._metaobjectdump_tool.is_file())
+
+ for example, baseline, cmd in self._examples:
+ self.assertTrue(example.is_file())
+ self.assertTrue(baseline.is_file())
+ baseline_data = baseline.read_text()
+
+ popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ actual = popen.communicate()[0].decode("UTF-8")
+ self.assertEqual(popen.returncode, 0)
+ self.assertEqual(baseline_data, actual)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/tools/pyside6-android-deploy/CMakeLists.txt b/sources/pyside6/tests/tools/pyside6-android-deploy/CMakeLists.txt
new file mode 100644
index 000000000..c32d636ed
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-android-deploy/CMakeLists.txt
@@ -0,0 +1,3 @@
+if(CMAKE_HOST_UNIX)
+ PYSIDE_TEST(test_pyside6_android_deploy.py)
+endif()
diff --git a/sources/pyside6/tests/tools/pyside6-android-deploy/extensive_android_deploy_test.py b/sources/pyside6/tests/tools/pyside6-android-deploy/extensive_android_deploy_test.py
new file mode 100644
index 000000000..271f8eebd
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-android-deploy/extensive_android_deploy_test.py
@@ -0,0 +1,88 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+ Extensive manual test of pyside6-android-deploy
+
+ Note: Not to be added into the CI
+"""
+
+import logging
+import unittest
+import tempfile
+import shutil
+import sys
+import os
+import importlib
+from pathlib import Path
+
+
+class TestPySide6Deploy(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.pyside_root = Path(__file__).parents[5].resolve()
+ example_root = cls.pyside_root / "examples"
+ example_application = example_root / "gui" / "analogclock"
+ cls.temp_dir = tempfile.mkdtemp()
+ cls.temp_example = Path(
+ shutil.copytree(example_application, Path(cls.temp_dir) / "analogclock")
+ ).resolve()
+ cls.current_dir = Path.cwd()
+
+ sys.path.append(str(cls.pyside_root / "sources" / "pyside-tools"))
+ cls.deploy_lib = importlib.import_module("deploy_lib")
+ cls.android_deploy = importlib.import_module("android_deploy")
+ sys.modules["android_deploy"] = cls.android_deploy
+
+ if os.environ.get("WHEEL_PYSIDE") is not None:
+ cls.pyside_wheel = Path(os.environ.get("WHEEL_PYSIDE")).resolve()
+ else:
+ raise Exception("Environment variable WHEEL_PYSIDE does not exist")
+
+ if os.environ.get("WHEEL_SHIBOKEN") is not None:
+ cls.shiboken_wheel = Path(os.environ.get("WHEEL_SHIBOKEN")).resolve()
+ else:
+ raise Exception("Environment variable WHEEL_SHIBOKEN does not exist")
+
+ def setUp(self):
+ os.chdir(self.temp_example)
+ self.config_file = self.temp_example / "pysidedeploy.spec"
+
+ def testDeployment(self):
+ self.android_deploy.main(name="android_app", shiboken_wheel=self.shiboken_wheel,
+ pyside_wheel=self.pyside_wheel, keep_deployment_files=True,
+ loglevel=logging.INFO, force=True)
+
+ print("Testing with config file")
+ self.android_deploy.main(name="android_app", config_file=self.config_file,
+ loglevel=logging.INFO, force=True)
+
+ def testWithNdkSdk(self):
+ if os.environ.get("ANDROID_SDK_ROOT") is not None:
+ android_sdk_root = Path(os.environ.get("ANDROID_SDK_ROOT")).resolve()
+ else:
+ raise Exception("Environment variable ANDROID_SDK_ROOT does not exist")
+
+ if os.environ.get("ANDROID_NDK_ROOT") is not None:
+ android_ndk_root = Path(os.environ.get("ANDROID_NDK_ROOT")).resolve()
+ else:
+ raise Exception("Environment variable ANDROID_NDK_ROOT does not exist")
+
+ self.android_deploy.main(name="android_app", shiboken_wheel=self.shiboken_wheel,
+ pyside_wheel=self.pyside_wheel,
+ ndk_path=android_ndk_root,
+ sdk_path=android_sdk_root,
+ keep_deployment_files=True,
+ loglevel=logging.INFO, force=True)
+
+ def tearDown(self) -> None:
+ super().tearDown()
+ os.chdir(self.current_dir)
+
+ @classmethod
+ def tearDownClass(cls) -> None:
+ shutil.rmtree(Path(cls.temp_dir))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/tools/pyside6-android-deploy/test_pyside6_android_deploy.py b/sources/pyside6/tests/tools/pyside6-android-deploy/test_pyside6_android_deploy.py
new file mode 100644
index 000000000..ec575e923
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-android-deploy/test_pyside6_android_deploy.py
@@ -0,0 +1,274 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import importlib
+import os
+import re
+import shutil
+import sys
+import tempfile
+import unittest
+import subprocess
+from pathlib import Path
+from unittest import mock
+from unittest.mock import patch
+
+sys.path.append(os.fspath(Path(__file__).resolve().parents[2]))
+from init_paths import init_test_paths # noqa: E402
+init_test_paths(False)
+
+
+class DeployTestBase(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.pyside_root = Path(__file__).parents[5].resolve()
+ cls.example_root = cls.pyside_root / "examples"
+ cls.temp_dir = tempfile.mkdtemp()
+ cls.current_dir = Path.cwd()
+ cls.pyside_wheel = Path("/tmp/PySide6-6.5.0a1-6.5.0-cp37-abi3-android_x86_64.whl")
+ cls.shiboken_wheel = Path("/tmp/shiboken6-6.5.0a1-6.5.0-cp37-abi3-android_x86_64.whl")
+ cls.ndk_path = Path("/tmp/android_sdk/ndk/25.2.9519653")
+ cls.sdk_path = Path("/tmp/android_sdk")
+ pyside_tools = cls.pyside_root / "sources" / "pyside-tools"
+
+ # install extra python dependencies
+ android_requirements_file = pyside_tools / "requirements-android.txt"
+ with open(android_requirements_file, 'r', encoding='UTF-8') as file:
+ while line := file.readline():
+ dependent_package = line.rstrip()
+ if not bool(importlib.util.find_spec(dependent_package)):
+ command = [sys.executable, "-m", "pip", "install", dependent_package]
+ subprocess.run(command)
+
+ sys.path.append(str(pyside_tools))
+ cls.deploy_lib = importlib.import_module("deploy_lib")
+ cls.android_deploy = importlib.import_module("android_deploy")
+ sys.modules["android_deploy"] = cls.android_deploy
+
+ # required for comparing long strings
+ cls.maxDiff = None
+
+ # print no outputs to stdout
+ sys.stdout = mock.MagicMock()
+
+ def tearDown(self) -> None:
+ super().tearDown()
+ os.chdir(self.current_dir)
+
+ @classmethod
+ def tearDownClass(cls) -> None:
+ shutil.rmtree(Path(cls.temp_dir))
+
+
+@patch("deploy_lib.android.android_config.extract_and_copy_jar")
+class TestPySide6AndroidDeployWidgets(DeployTestBase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ example_widget_application = cls.example_root / "gui" / "analogclock"
+ cls.temp_example = Path(
+ shutil.copytree(example_widget_application, Path(cls.temp_dir) / "analogclock")
+ ).resolve()
+
+ def setUp(self):
+ os.chdir(self.temp_example)
+ self.config_file = self.temp_example / "pysidedeploy.spec"
+ self.buildozer_config = self.temp_example / "buildozer.spec"
+
+ @patch("deploy_lib.android.android_config.AndroidConfig._find_local_libs")
+ @patch("deploy_lib.android.android_config.AndroidConfig._find_dependent_qt_modules")
+ @patch("deploy_lib.android.android_config.find_qtlibs_in_wheel")
+ def test_dry_run(self, mock_qtlibs, mock_extraqtmodules, mock_local_libs, mock_extract_jar):
+ mock_qtlibs.return_value = self.pyside_wheel / "PySide6/Qt/lib"
+ mock_extraqtmodules.return_value = []
+ dependent_plugins = ["platforms_qtforandroid",
+ "platforminputcontexts_qtvirtualkeyboardplugin",
+ "iconengines_qsvgicon"]
+ mock_local_libs.return_value = [], dependent_plugins
+ self.android_deploy.main(name="android_app", shiboken_wheel=self.shiboken_wheel,
+ pyside_wheel=self.pyside_wheel, ndk_path=self.ndk_path,
+ dry_run=True, force=True)
+
+ self.assertEqual(mock_extract_jar.call_count, 0)
+ self.assertEqual(mock_qtlibs.call_count, 1)
+ self.assertEqual(mock_extraqtmodules.call_count, 1)
+ self.assertEqual(mock_local_libs.call_count, 1)
+
+ @patch("deploy_lib.android.buildozer.BuildozerConfig._BuildozerConfig__find_jars")
+ @patch("deploy_lib.android.android_config.AndroidConfig.recipes_exist")
+ @patch("deploy_lib.android.android_config.AndroidConfig._find_dependent_qt_modules")
+ @patch("deploy_lib.android.android_config.find_qtlibs_in_wheel")
+ def test_config(self, mock_qtlibs, mock_extraqtmodules, mock_recipes_exist, mock_find_jars,
+ mock_extract_jar):
+ jar_dir = "tmp/jar/PySide6/jar"
+ mock_extract_jar.return_value = Path(jar_dir)
+ mock_qtlibs.return_value = self.pyside_wheel / "PySide6/Qt/lib"
+ mock_extraqtmodules.return_value = []
+ mock_recipes_exist.return_value = True
+ jars, init_classes = ["/tmp/jar/PySide6/jar/Qt6Android.jar",
+ "/tmp/jar/PySide6/jar/Qt6AndroidBindings.jar"], []
+ mock_find_jars.return_value = jars, init_classes
+
+ self.android_deploy.main(name="android_app", shiboken_wheel=self.shiboken_wheel,
+ pyside_wheel=self.pyside_wheel, ndk_path=self.ndk_path,
+ init=True, force=True, keep_deployment_files=True)
+
+ self.assertEqual(mock_extract_jar.call_count, 1)
+ self.assertEqual(mock_qtlibs.call_count, 1)
+ self.assertEqual(mock_extraqtmodules.call_count, 1)
+ self.assertEqual(mock_recipes_exist.call_count, 1)
+ self.assertEqual(mock_find_jars.call_count, 1)
+ self.assertTrue(self.config_file.exists())
+ self.assertTrue(self.buildozer_config.exists())
+
+ # test config file contents
+ config_obj = self.deploy_lib.BaseConfig(config_file=self.config_file)
+ self.assertEqual(config_obj.get_value("app", "input_file"), "main.py")
+ self.assertEqual(config_obj.get_value("python", "android_packages"),
+ "buildozer==1.5.0,cython==0.29.33")
+ self.assertEqual(config_obj.get_value("android", "wheel_pyside"),
+ str(self.pyside_wheel.resolve()))
+ self.assertEqual(config_obj.get_value("android", "wheel_shiboken"),
+ str(self.shiboken_wheel.resolve()))
+ self.assertEqual(config_obj.get_value("buildozer", "mode"), "debug")
+ self.assertEqual(config_obj.get_value("buildozer", "recipe_dir"),
+ '')
+ self.assertEqual(config_obj.get_value("buildozer", "jars_dir"),
+ str(self.temp_example / jar_dir))
+ self.assertIn(str(self.ndk_path), config_obj.get_value("buildozer", "ndk_path"))
+ self.assertEqual(config_obj.get_value("buildozer", "sdk_path"), '')
+ expected_modules = {"Core", "Gui"}
+ obtained_modules = set(config_obj.get_value("qt", "modules").split(","))
+ self.assertEqual(obtained_modules, expected_modules)
+ expected_local_libs = ""
+ self.assertEqual(config_obj.get_value("buildozer", "local_libs"),
+ expected_local_libs)
+ self.assertEqual(config_obj.get_value("buildozer", "arch"), "x86_64")
+
+ # test buildozer config file contents
+ buildozer_config_obj = self.deploy_lib.BaseConfig(config_file=self.buildozer_config)
+ obtained_jars = set(buildozer_config_obj.get_value("app", "android.add_jars").split(','))
+ expected_jars = set(jars)
+ self.assertEqual(obtained_jars, expected_jars)
+ obtained_extra_args = buildozer_config_obj.get_value("app", "p4a.extra_args")
+ extra_args_patrn = re.compile("--qt-libs=(?P<modules>.*) --load-local-libs="
+ "(?P<local_libs>.*) --init-classes=(?P<init_classes>.*)")
+ match = extra_args_patrn.search(obtained_extra_args)
+ obtained_modules = match.group("modules").split(',')
+ obtained_local_libs = match.group("local_libs")
+ obtained_init_classes = match.group("init_classes")
+ self.assertEqual(set(obtained_modules), expected_modules)
+ self.assertEqual(obtained_local_libs, expected_local_libs)
+ self.assertEqual(obtained_init_classes, '')
+ expected_include_exts = "py,png,jpg,kv,atlas,qml,js"
+ obtained_include_exts = buildozer_config_obj.get_value("app", "source.include_exts")
+ self.assertEqual(expected_include_exts, obtained_include_exts)
+
+ self.config_file.unlink()
+ self.buildozer_config.unlink()
+
+ def test_errors(self, mock_extract_jar):
+ # test if error raises for non existing NDK
+ with self.assertRaises(FileNotFoundError) as context:
+ self.android_deploy.main(name="android_app", shiboken_wheel=self.shiboken_wheel,
+ pyside_wheel=self.pyside_wheel, force=True)
+ self.assertTrue("Unable to find Android NDK" in str(context.exception))
+
+ # test when cwd() is not project_dir
+ os.chdir(self.current_dir)
+ with self.assertRaises(RuntimeError) as context:
+ self.android_deploy.main(name="android_app", shiboken_wheel=self.shiboken_wheel,
+ pyside_wheel=self.pyside_wheel, init=True, force=True)
+ self.assertTrue("For Android deployment to work" in str(context.exception))
+
+
+@patch("deploy_lib.config.run_qmlimportscanner")
+@patch("deploy_lib.android.android_config.extract_and_copy_jar")
+class TestPySide6AndroidDeployQml(DeployTestBase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ # setting up example
+ example_qml_application = cls.example_root / "quick" / "models" / "stringlistmodel"
+ cls.temp_qml_example = Path(
+ shutil.copytree(example_qml_application, Path(cls.temp_dir) / "stringlistmodel")
+ ).resolve()
+
+ def setUp(self):
+ os.chdir(self.temp_qml_example)
+ self.config_file = self.temp_qml_example / "pysidedeploy.spec"
+ self.buildozer_config_file = self.temp_qml_example / "buildozer.spec"
+ (self.temp_qml_example / "stringlistmodel.py").rename(self.temp_qml_example / "main.py")
+ (self.temp_qml_example / "stringlistmodel.pyproject").unlink()
+
+ @patch("deploy_lib.android.android_config.AndroidConfig._find_local_libs")
+ @patch("deploy_lib.android.buildozer.BuildozerConfig._BuildozerConfig__find_jars")
+ @patch("deploy_lib.android.android_config.AndroidConfig.recipes_exist")
+ @patch("deploy_lib.android.android_config.AndroidConfig._find_dependent_qt_modules")
+ @patch("deploy_lib.android.android_config.find_qtlibs_in_wheel")
+ def test_config_with_Qml(self, mock_qtlibs, mock_extraqtmodules, mock_recipes_exist,
+ mock_find_jars, mock_local_libs, mock_extract_jar,
+ mock_qmlimportscanner):
+ # setting up mocks
+ jar_dir = "tmp/jar/PySide6/jar"
+ mock_extract_jar.return_value = Path(jar_dir)
+ mock_qtlibs.return_value = self.pyside_wheel / "PySide6/Qt/lib"
+ mock_extraqtmodules.return_value = ['Qml', 'Network', 'QmlModels', 'OpenGL']
+ mock_recipes_exist.return_value = True
+ jars, init_classes = ["/tmp/jar/PySide6/jar/Qt6Android.jar",
+ "/tmp/jar/PySide6/jar/Qt6AndroidBindings.jar",
+ "/tmp/jar/PySide6/jar/Qt6AndroidNetworkInformationBackend.jar",
+ "/tmp/jar/PySide6/jar/Qt6AndroidNetwork.jar"], []
+ mock_find_jars.return_value = jars, init_classes
+ dependent_plugins = ["platforms_qtforandroid",
+ "platforminputcontexts_qtvirtualkeyboardplugin",
+ "iconengines_qsvgicon"]
+ mock_local_libs.return_value = [], dependent_plugins
+ mock_qmlimportscanner.return_value = ["QtQuick"]
+
+ self.android_deploy.main(name="android_app", shiboken_wheel=self.shiboken_wheel,
+ pyside_wheel=self.pyside_wheel, ndk_path=self.ndk_path,
+ init=True, force=True, keep_deployment_files=True)
+
+ self.assertEqual(mock_extract_jar.call_count, 1)
+ self.assertEqual(mock_qtlibs.call_count, 1)
+ self.assertEqual(mock_extraqtmodules.call_count, 1)
+ self.assertEqual(mock_recipes_exist.call_count, 1)
+ self.assertEqual(mock_find_jars.call_count, 1)
+ self.assertEqual(mock_qmlimportscanner.call_count, 1)
+ self.assertTrue(self.config_file.exists())
+ self.assertTrue(self.buildozer_config_file.exists())
+
+ config_obj = self.deploy_lib.BaseConfig(config_file=self.config_file)
+ expected_modules = {"Quick", "Core", "Gui", "Network", "Qml", "QmlModels", "OpenGL"}
+ obtained_modules = set(config_obj.get_value("qt", "modules").split(","))
+ self.assertEqual(obtained_modules, expected_modules)
+ expected_local_libs = ""
+ self.assertEqual(config_obj.get_value("buildozer", "local_libs"),
+ expected_local_libs)
+ expected_qt_plugins = set(dependent_plugins)
+ obtained_qt_plugins = set(config_obj.get_value("android", "plugins").split(","))
+ self.assertEqual(expected_qt_plugins, obtained_qt_plugins)
+
+ # test buildozer config file contents
+ buildozer_config_obj = self.deploy_lib.BaseConfig(config_file=self.buildozer_config_file)
+ obtained_jars = set(buildozer_config_obj.get_value("app", "android.add_jars").split(','))
+ expected_jars = set(jars)
+ self.assertEqual(obtained_jars, expected_jars)
+ obtained_extra_args = buildozer_config_obj.get_value("app", "p4a.extra_args")
+ extra_args_patrn = re.compile("--qt-libs=(?P<modules>.*) --load-local-libs="
+ "(?P<local_libs>.*) --init-classes=(?P<init_classes>.*)")
+ match = extra_args_patrn.search(obtained_extra_args)
+ obtained_modules = match.group("modules").split(',')
+ obtained_local_libs = match.group("local_libs")
+ obtained_init_classes = match.group("init_classes")
+ self.assertEqual(set(obtained_modules), expected_modules)
+ self.assertEqual(obtained_local_libs, expected_local_libs)
+ self.assertEqual(obtained_init_classes, '')
+
+ self.config_file.unlink()
+ self.buildozer_config_file.unlink()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/tools/pyside6-deploy/CMakeLists.txt b/sources/pyside6/tests/tools/pyside6-deploy/CMakeLists.txt
new file mode 100644
index 000000000..7f010fbd6
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-deploy/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(test_pyside6_deploy.py)
diff --git a/sources/pyside6/tests/tools/pyside6-deploy/extensive_deploy_test.py b/sources/pyside6/tests/tools/pyside6-deploy/extensive_deploy_test.py
new file mode 100644
index 000000000..40afc7f5c
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-deploy/extensive_deploy_test.py
@@ -0,0 +1,88 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""
+ Extensive manual test of pyside6-deploy
+
+ Note: Not to be added into the CI
+"""
+
+import logging
+import unittest
+import tempfile
+import shutil
+import sys
+import os
+import importlib
+from pathlib import Path
+
+
+class TestPySide6Deploy(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.pyside_root = Path(__file__).parents[5].resolve()
+ example_root = cls.pyside_root / "examples"
+ example_widgets = example_root / "widgets" / "widgets" / "tetrix"
+ example_qml = example_root / "qml" / "editingmodel"
+ example_webenginequick = example_root / "webenginequick" / "nanobrowser"
+ cls.temp_dir = tempfile.mkdtemp()
+ cls.temp_example_widgets = Path(
+ shutil.copytree(example_widgets, Path(cls.temp_dir) / "tetrix")
+ ).resolve()
+ cls.temp_example_qml = Path(
+ shutil.copytree(example_qml, Path(cls.temp_dir) / "editingmodel")
+ ).resolve()
+ cls.temp_example_webenginequick = Path(
+ shutil.copytree(example_webenginequick, Path(cls.temp_dir) / "nanobrowser")
+ ).resolve()
+ cls.current_dir = Path.cwd()
+ cls.linux_onefile_icon = (
+ cls.pyside_root / "sources" / "pyside-tools" / "deploy_lib" / "pyside_icon.jpg"
+ )
+
+ sys.path.append(str(cls.pyside_root / "sources" / "pyside-tools"))
+ cls.deploy_lib = importlib.import_module("deploy_lib")
+ cls.deploy = importlib.import_module("deploy")
+ sys.modules["deploy"] = cls.deploy
+
+ def setUpWidgets(self):
+ os.chdir(self.temp_example_widgets)
+ self.main_file = self.temp_example_widgets / "tetrix.py"
+ self.config_file = self.temp_example_widgets / "pysidedeploy.spec"
+
+ def testWidget(self):
+ self.setUpWidgets()
+ self.deploy.main(self.main_file, name="widget_app", loglevel=logging.INFO,
+ keep_deployment_files=True, force=True)
+
+ print("Now testing Widget with config file")
+ self.deploy.main(self.main_file, config_file=self.config_file, loglevel=logging.INFO,
+ force=True)
+
+ def setUpQml(self):
+ os.chdir(self.temp_example_qml)
+ self.main_file = self.temp_example_qml / "main.py"
+ self.config_file = self.temp_example_qml / "pysidedeploy.spec"
+
+ def testQml(self):
+ self.setUpQml()
+ self.deploy.main(self.main_file, name="qml_app", loglevel=logging.INFO,
+ keep_deployment_files=True, force=True)
+
+ def testWebEngineQuickDryRun(self):
+ os.chdir(self.temp_example_webenginequick)
+ main_file = self.temp_example_webenginequick / "quicknanobrowser.py"
+ self.deploy.main(main_file, name="qml_app", keep_deployment_files=True,
+ loglevel=logging.INFO, force=True)
+
+ def tearDown(self) -> None:
+ super().tearDown()
+ os.chdir(self.current_dir)
+
+ @classmethod
+ def tearDownClass(cls) -> None:
+ shutil.rmtree(Path(cls.temp_dir))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/tools/pyside6-deploy/test_pyside6_deploy.py b/sources/pyside6/tests/tools/pyside6-deploy/test_pyside6_deploy.py
new file mode 100644
index 000000000..db60c8c3f
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-deploy/test_pyside6_deploy.py
@@ -0,0 +1,400 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import unittest
+import tempfile
+import shutil
+import sys
+import os
+import importlib
+import platform
+from pathlib import Path
+from unittest.mock import patch
+from unittest import mock
+
+sys.path.append(os.fspath(Path(__file__).resolve().parents[2]))
+from init_paths import init_test_paths, _get_qt_lib_dir # noqa: E402
+init_test_paths(False)
+
+
+def is_pyenv_python():
+ pyenv_root = os.environ.get("PYENV_ROOT")
+
+ if pyenv_root and (resolved_exe := str(Path(sys.executable).resolve())):
+ return resolved_exe.startswith(pyenv_root)
+ return False
+
+
+class LongSortedOptionTest(unittest.TestCase):
+ @staticmethod
+ def _option_prepare(s):
+ """
+ Take a string and return a list obtained by text.split().
+ Options starting with "--" are also sorted."
+ """
+ items = s.split()
+ for idx in range(len(items)):
+ if items[idx].startswith("--"):
+ return items[:idx] + sorted(items[idx:])
+ return items
+
+ def assertEqual(self, text_a, text_b):
+ if (not isinstance(text_a, str) or not isinstance(text_b, str)
+ or (len(text_a) < 50 and len(text_b) < 50)):
+ return super().assertEqual(text_a, text_b)
+ sort_a = self._option_prepare(text_a)
+ sort_b = self._option_prepare(text_b)
+ return super().assertEqual(sort_a, sort_b)
+
+
+class DeployTestBase(LongSortedOptionTest):
+ @classmethod
+ def setUpClass(cls):
+ cls.pyside_root = Path(__file__).parents[5].resolve()
+ cls.example_root = cls.pyside_root / "examples"
+ cls.temp_dir = tempfile.mkdtemp()
+ cls.current_dir = Path.cwd()
+ tools_path = cls.pyside_root / "sources" / "pyside-tools"
+ cls.win_icon = tools_path / "deploy_lib" / "pyside_icon.ico"
+ cls.linux_icon = tools_path / "deploy_lib" / "pyside_icon.jpg"
+ cls.macos_icon = tools_path / "deploy_lib" / "pyside_icon.icns"
+ if tools_path not in sys.path:
+ sys.path.append(str(cls.pyside_root / "sources" / "pyside-tools"))
+ cls.deploy_lib = importlib.import_module("deploy_lib")
+ cls.deploy = importlib.import_module("deploy")
+ sys.modules["deploy"] = cls.deploy
+ files_to_ignore = [".cpp.o", ".qsb", ".webp"]
+ cls.dlls_ignore_nuitka = " ".join([f"--noinclude-dlls=*{file}"
+ for file in files_to_ignore])
+
+ # required for comparing long strings
+ cls.maxDiff = None
+
+ # print no outputs to stdout
+ sys.stdout = mock.MagicMock()
+
+ @classmethod
+ def tearDownClass(cls) -> None:
+ shutil.rmtree(Path(cls.temp_dir))
+
+ def tearDown(self) -> None:
+ super().tearDown()
+ os.chdir(self.current_dir)
+
+
+@unittest.skipIf(sys.platform == "darwin" and int(platform.mac_ver()[0].split('.')[0]) <= 11,
+ "Test only works on macOS version 12+")
+@patch("deploy_lib.config.QtDependencyReader.find_plugin_dependencies")
+class TestPySide6DeployWidgets(DeployTestBase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ example_widgets = cls.example_root / "widgets" / "widgets" / "tetrix"
+ cls.temp_example_widgets = Path(
+ shutil.copytree(example_widgets, Path(cls.temp_dir) / "tetrix")
+ ).resolve()
+
+ def setUp(self):
+ os.chdir(self.temp_example_widgets)
+ self.main_file = self.temp_example_widgets / "tetrix.py"
+ self.deployment_files = self.temp_example_widgets / "deployment"
+ # All the plugins included. This is different from plugins_nuitka, because Nuitka bundles
+ # some plugins by default
+ self.all_plugins = ["accessiblebridge", "egldeviceintegrations", "generic", "iconengines",
+ "imageformats", "platforminputcontexts", "platforms",
+ "platforms/darwin", "platformthemes", "styles", "xcbglintegrations"]
+ # Plugins that needs to be passed to Nuitka
+ plugins_nuitka = ("accessiblebridge,platforminputcontexts,platforms/darwin")
+ self.expected_run_cmd = (
+ f"{sys.executable} -m nuitka {str(self.main_file)} --follow-imports"
+ f" --enable-plugin=pyside6 --output-dir={str(self.deployment_files)} --quiet"
+ f" --noinclude-qt-translations"
+ f" --include-qt-plugins={plugins_nuitka}"
+ f" {self.dlls_ignore_nuitka}"
+ )
+ if sys.platform.startswith("linux"):
+ self.expected_run_cmd += f" --linux-icon={str(self.linux_icon)} --onefile"
+ elif sys.platform == "darwin":
+ self.expected_run_cmd += (f" --macos-app-icon={str(self.macos_icon)}"
+ " --macos-create-app-bundle --standalone")
+ elif sys.platform == "win32":
+ self.expected_run_cmd += f" --windows-icon-from-ico={str(self.win_icon)} --onefile"
+
+ if is_pyenv_python():
+ self.expected_run_cmd += " --static-libpython=no"
+ self.config_file = self.temp_example_widgets / "pysidedeploy.spec"
+
+ def testWidgetDryRun(self, mock_plugins):
+ mock_plugins.return_value = self.all_plugins
+ # Checking for dry run commands is equivalent to mocking the
+ # subprocess.check_call() in commands.py as the the dry run command
+ # is the command being run.
+ original_output = self.deploy.main(self.main_file, dry_run=True, force=True)
+ self.assertEqual(original_output, self.expected_run_cmd)
+
+ @patch("deploy_lib.dependency_util.QtDependencyReader.get_qt_libs_dir")
+ def testWidgetConfigFile(self, mock_sitepackages, mock_plugins):
+ mock_sitepackages.return_value = Path(_get_qt_lib_dir())
+ mock_plugins.return_value = self.all_plugins
+ # includes both dry run and config_file tests
+ # init
+ init_result = self.deploy.main(self.main_file, init=True, force=True)
+ self.assertEqual(init_result, None)
+
+ # test with config
+ original_output = self.deploy.main(config_file=self.config_file, dry_run=True, force=True)
+ self.assertEqual(original_output, self.expected_run_cmd)
+
+ # # test config file contents
+ config_obj = self.deploy_lib.BaseConfig(config_file=self.config_file)
+ self.assertEqual(config_obj.get_value("app", "input_file"), "tetrix.py")
+ self.assertEqual(config_obj.get_value("app", "project_dir"), ".")
+ self.assertEqual(config_obj.get_value("app", "exec_directory"), ".")
+ self.assertEqual(config_obj.get_value("python", "packages"),
+ "Nuitka==2.1")
+ self.assertEqual(config_obj.get_value("qt", "qml_files"), "")
+ equ_base = "--quiet --noinclude-qt-translations"
+ equ_value = equ_base + " --static-libpython=no" if is_pyenv_python() else equ_base
+ self.assertEqual(config_obj.get_value("nuitka", "extra_args"), equ_value)
+ self.assertEqual(config_obj.get_value("qt", "excluded_qml_plugins"), "")
+ expected_modules = {"Core", "Gui", "Widgets"}
+ if sys.platform != "win32":
+ expected_modules.add("DBus")
+ obtained_modules = set(config_obj.get_value("qt", "modules").split(","))
+ self.assertEqual(obtained_modules, expected_modules)
+ obtained_qt_plugins = config_obj.get_value("qt", "plugins").split(",")
+ self.assertEqual(obtained_qt_plugins.sort(), self.all_plugins.sort())
+ self.config_file.unlink()
+
+ def testErrorReturns(self, mock_plugins):
+ mock_plugins.return_value = self.all_plugins
+ # main file and config file does not exists
+ fake_main_file = self.main_file.parent / "main.py"
+ with self.assertRaises(RuntimeError) as context:
+ self.deploy.main(main_file=fake_main_file, config_file=self.config_file)
+ self.assertTrue("Directory does not contain main.py file." in str(context.exception))
+
+
+@unittest.skipIf(sys.platform == "darwin" and int(platform.mac_ver()[0].split('.')[0]) <= 11,
+ "Test only works on macOS version 12+")
+@patch("deploy_lib.config.QtDependencyReader.find_plugin_dependencies")
+class TestPySide6DeployQml(DeployTestBase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ example_qml = cls.example_root / "qml" / "editingmodel"
+ cls.temp_example_qml = Path(
+ shutil.copytree(example_qml, Path(cls.temp_dir) / "editingmodel")
+ ).resolve()
+
+ def setUp(self):
+ os.chdir(self.temp_example_qml)
+ self.main_file = self.temp_example_qml / "main.py"
+ self.deployment_files = self.temp_example_qml / "deployment"
+ self.first_qml_file = "main.qml"
+ self.second_qml_file = "MovingRectangle.qml"
+
+ # All the plugins included. This is different from plugins_nuitka, because Nuitka bundles
+ # some plugins by default
+ self.all_plugins = ["accessiblebridge", "egldeviceintegrations", "generic", "iconengines",
+ "imageformats", "networkaccess", "networkinformation",
+ "platforminputcontexts", "platforms", "platforms/darwin",
+ "platformthemes", "qmltooling", "scenegraph", "tls",
+ "xcbglintegrations"]
+ # Plugins that needs to be passed to Nuitka
+ plugins_nuitka = ("accessiblebridge,networkaccess,networkinformation,platforminputcontexts,"
+ "platforms/darwin,qml,qmltooling,scenegraph")
+ self.expected_run_cmd = (
+ f"{sys.executable} -m nuitka {str(self.main_file)} --follow-imports"
+ f" --enable-plugin=pyside6 --output-dir={str(self.deployment_files)} --quiet"
+ f" --noinclude-qt-translations"
+ f" {self.dlls_ignore_nuitka}"
+ " --noinclude-dlls=*/qml/QtQuickEffectMaker/*"
+ f" --include-qt-plugins={plugins_nuitka}"
+ f" --include-data-files={str(self.temp_example_qml / self.first_qml_file)}="
+ f"./main.qml --include-data-files="
+ f"{str(self.temp_example_qml / self.second_qml_file)}=./MovingRectangle.qml"
+ )
+
+ if sys.platform != "win32":
+ self.expected_run_cmd += (
+ " --noinclude-dlls=libQt6Charts*"
+ " --noinclude-dlls=libQt6Quick3D* --noinclude-dlls=libQt6Sensors*"
+ " --noinclude-dlls=libQt6Test* --noinclude-dlls=libQt6WebEngine*"
+ )
+ else:
+ self.expected_run_cmd += (
+ " --noinclude-dlls=Qt6Charts*"
+ " --noinclude-dlls=Qt6Quick3D* --noinclude-dlls=Qt6Sensors*"
+ " --noinclude-dlls=Qt6Test* --noinclude-dlls=Qt6WebEngine*"
+ )
+
+ if sys.platform.startswith("linux"):
+ self.expected_run_cmd += f" --linux-icon={str(self.linux_icon)} --onefile"
+ elif sys.platform == "darwin":
+ self.expected_run_cmd += (f" --macos-app-icon={str(self.macos_icon)}"
+ " --macos-create-app-bundle --standalone")
+ elif sys.platform == "win32":
+ self.expected_run_cmd += f" --windows-icon-from-ico={str(self.win_icon)} --onefile"
+
+ if is_pyenv_python():
+ self.expected_run_cmd += " --static-libpython=no"
+ self.config_file = self.temp_example_qml / "pysidedeploy.spec"
+
+ @patch("deploy_lib.dependency_util.QtDependencyReader.get_qt_libs_dir")
+ def testQmlConfigFile(self, mock_sitepackages, mock_plugins):
+ mock_sitepackages.return_value = Path(_get_qt_lib_dir())
+ mock_plugins.return_value = self.all_plugins
+ # create config file
+ with patch("deploy_lib.config.run_qmlimportscanner") as mock_qmlimportscanner:
+ mock_qmlimportscanner.return_value = ["QtQuick"]
+ init_result = self.deploy.main(self.main_file, init=True, force=True)
+ self.assertEqual(init_result, None)
+
+ # test config file contents
+ config_obj = self.deploy_lib.BaseConfig(config_file=self.config_file)
+ self.assertEqual(config_obj.get_value("app", "input_file"), "main.py")
+ self.assertEqual(config_obj.get_value("app", "project_dir"), ".")
+ self.assertEqual(config_obj.get_value("app", "exec_directory"), ".")
+ self.assertEqual(config_obj.get_value("python", "packages"),
+ "Nuitka==2.1")
+ self.assertEqual(config_obj.get_value("qt", "qml_files"), "main.qml,MovingRectangle.qml")
+ equ_base = "--quiet --noinclude-qt-translations"
+ equ_value = equ_base + " --static-libpython=no" if is_pyenv_python() else equ_base
+ self.assertEqual(config_obj.get_value("nuitka", "extra_args"), equ_value)
+ self.assertEqual(
+ config_obj.get_value("qt", "excluded_qml_plugins"),
+ "QtCharts,QtQuick3D,QtSensors,QtTest,QtWebEngine",
+ )
+ expected_modules = {"Core", "Gui", "Qml", "Quick", "Network", "OpenGL", "QmlModels"}
+ if sys.platform != "win32":
+ expected_modules.add("DBus")
+ obtained_modules = set(config_obj.get_value("qt", "modules").split(","))
+ self.assertEqual(obtained_modules, expected_modules)
+ obtained_qt_plugins = config_obj.get_value("qt", "plugins").split(",")
+ self.assertEqual(obtained_qt_plugins.sort(), self.all_plugins.sort())
+ self.config_file.unlink()
+
+ def testQmlDryRun(self, mock_plugins):
+ mock_plugins.return_value = self.all_plugins
+ with patch("deploy_lib.config.run_qmlimportscanner") as mock_qmlimportscanner:
+ mock_qmlimportscanner.return_value = ["QtQuick"]
+ original_output = self.deploy.main(self.main_file, dry_run=True, force=True)
+ self.assertEqual(original_output, self.expected_run_cmd)
+ self.assertEqual(mock_qmlimportscanner.call_count, 1)
+
+ def testMainFileDryRun(self, mock_plugins):
+ mock_plugins.return_value = self.all_plugins
+ with patch("deploy_lib.config.run_qmlimportscanner") as mock_qmlimportscanner:
+ mock_qmlimportscanner.return_value = ["QtQuick"]
+ original_output = self.deploy.main(Path.cwd() / "main.py", dry_run=True, force=True)
+ self.assertEqual(original_output, self.expected_run_cmd)
+ self.assertEqual(mock_qmlimportscanner.call_count, 1)
+
+
+@unittest.skipIf(sys.platform == "darwin" and int(platform.mac_ver()[0].split('.')[0]) <= 11,
+ "Test only works on macOS version 12+")
+class TestPySide6DeployWebEngine(DeployTestBase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ example_webenginequick = cls.example_root / "webenginequick" / "nanobrowser"
+ cls.temp_example_webenginequick = Path(
+ shutil.copytree(example_webenginequick, Path(cls.temp_dir) / "nanobrowser")
+ ).resolve()
+
+ @patch("deploy_lib.config.QtDependencyReader.find_plugin_dependencies")
+ @patch("deploy_lib.dependency_util.QtDependencyReader.get_qt_libs_dir")
+ def testWebEngineQuickDryRun(self, mock_sitepackages, mock_plugins):
+ mock_sitepackages.return_value = Path(_get_qt_lib_dir())
+ all_plugins = ["accessiblebridge", "egldeviceintegrations", "generic", "iconengines",
+ "imageformats", "networkaccess", "networkinformation",
+ "platforminputcontexts", "platforms", "platforms/darwin",
+ "platformthemes", "qmltooling", "scenegraph", "tls",
+ "xcbglintegrations"]
+ mock_plugins.return_value = all_plugins
+ # this test case retains the QtWebEngine dlls
+ # setup
+ os.chdir(self.temp_example_webenginequick)
+ main_file = self.temp_example_webenginequick / "quicknanobrowser.py"
+ deployment_files = self.temp_example_webenginequick / "deployment"
+ # Plugins that needs to be passed to Nuitka
+ plugins_nuitka = ("accessiblebridge,networkaccess,networkinformation,platforminputcontexts,"
+ "platforms/darwin,qml,qmltooling,scenegraph")
+ qml_files = [
+ "ApplicationRoot.qml",
+ "BrowserDialog.qml",
+ "BrowserWindow.qml",
+ "DownloadView.qml",
+ "FindBar.qml",
+ "FullScreenNotification.qml",
+ ]
+ data_files_cmd = " ".join(
+ [
+ f"--include-data-files={str(self.temp_example_webenginequick / file)}=./{file}"
+ for file in qml_files
+ ]
+ )
+ expected_run_cmd = (
+ f"{sys.executable} -m nuitka {str(main_file)} --follow-imports"
+ f" --enable-plugin=pyside6 --output-dir={str(deployment_files)} --quiet"
+ f" --noinclude-qt-translations --include-qt-plugins=all"
+ f" {data_files_cmd}"
+ f" --include-qt-plugins={plugins_nuitka}"
+ f" {self.dlls_ignore_nuitka}"
+ " --noinclude-dlls=*/qml/QtQuickEffectMaker/*"
+ )
+
+ if sys.platform != "win32":
+ expected_run_cmd += (
+ " --noinclude-dlls=libQt6Charts*"
+ " --noinclude-dlls=libQt6Quick3D* --noinclude-dlls=libQt6Sensors*"
+ " --noinclude-dlls=libQt6Test*"
+ )
+ else:
+ expected_run_cmd += (
+ " --noinclude-dlls=Qt6Charts*"
+ " --noinclude-dlls=Qt6Quick3D* --noinclude-dlls=Qt6Sensors*"
+ " --noinclude-dlls=Qt6Test*"
+ )
+
+ if sys.platform.startswith("linux"):
+ expected_run_cmd += f" --linux-icon={str(self.linux_icon)} --onefile"
+ elif sys.platform == "darwin":
+ expected_run_cmd += (f" --macos-app-icon={str(self.macos_icon)}"
+ " --macos-create-app-bundle --standalone")
+ elif sys.platform == "win32":
+ expected_run_cmd += f" --windows-icon-from-ico={str(self.win_icon)} --onefile"
+
+ config_file = self.temp_example_webenginequick / "pysidedeploy.spec"
+
+ # create config file
+ with patch("deploy_lib.config.run_qmlimportscanner") as mock_qmlimportscanner:
+ mock_qmlimportscanner.return_value = ["QtQuick", "QtWebEngine"]
+ init_result = self.deploy.main(main_file, init=True, force=True)
+ self.assertEqual(init_result, None)
+
+ # run dry_run
+ original_output = self.deploy.main(main_file, dry_run=True, force=True)
+ self.assertTrue(original_output, expected_run_cmd)
+ self.assertEqual(mock_qmlimportscanner.call_count, 2)
+
+ # test config file contents
+ config_obj = self.deploy_lib.BaseConfig(config_file=config_file)
+ self.assertEqual(config_obj.get_value("app", "input_file"), "quicknanobrowser.py")
+ self.assertEqual(config_obj.get_value("qt", "qml_files"), ",".join(qml_files))
+ self.assertEqual(
+ config_obj.get_value("qt", "excluded_qml_plugins"),
+ "QtCharts,QtQuick3D,QtSensors,QtTest",
+ )
+ expected_modules = {"Core", "Gui", "Quick", "Qml", "WebEngineQuick", "Network", "OpenGL",
+ "Positioning", "WebEngineCore", "WebChannel", "WebChannelQuick",
+ "QmlModels"}
+ if sys.platform != "win32":
+ expected_modules.add("DBus")
+ obtained_modules = set(config_obj.get_value("qt", "modules").split(","))
+ self.assertEqual(obtained_modules, expected_modules)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/pyside6/tests/tools/pyside6-qml/CMakeLists.txt b/sources/pyside6/tests/tools/pyside6-qml/CMakeLists.txt
new file mode 100644
index 000000000..4d801264a
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-qml/CMakeLists.txt
@@ -0,0 +1 @@
+PYSIDE_TEST(test_pyside6_qml.py)
diff --git a/sources/pyside6/tests/tools/pyside6-qml/test_pyside6_qml.py b/sources/pyside6/tests/tools/pyside6-qml/test_pyside6_qml.py
new file mode 100644
index 000000000..fdaf3d471
--- /dev/null
+++ b/sources/pyside6/tests/tools/pyside6-qml/test_pyside6_qml.py
@@ -0,0 +1,75 @@
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+"""Test for pyside6-qml
+
+The tests does a unittest and some integration tests for pyside6-qml."""
+
+from asyncio.subprocess import PIPE
+import os
+import sys
+import unittest
+import subprocess
+import importlib.util
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[2]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+
+class TestPySide6QmlUnit(unittest.TestCase):
+ def setUp(self) -> None:
+ super().setUp()
+ self._dir = Path(__file__).parent.resolve()
+ self.pyside_root = self._dir.parents[4]
+
+ self.pyqml_path = self.pyside_root / "sources" / "pyside-tools" / "qml.py"
+ self.core_qml_path = (self.pyside_root / "examples" / "qml" /
+ "tutorials" / "extending-qml-advanced" / "adding")
+
+ self.pyqml_run_cmd = [sys.executable, os.fspath(self.pyqml_path)]
+
+ # self.pyqml_path will not abe able to find pyside and other related binaries, if not added
+ # to path explicitly. The following lines does that.
+ self.test_env = os.environ.copy()
+ self.test_env["PYTHONPATH"] = os.pathsep + os.pathsep.join(sys.path)
+
+ def testImportQmlModules(self):
+
+ # because pyside-tools has a hyphen, a normal 'from pyside-tools import qml' cannot be done
+ spec = importlib.util.spec_from_file_location("qml", self.pyqml_path)
+ pyqml = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(pyqml)
+ pyqml.import_qml_modules(self.core_qml_path)
+
+ # path added to sys.path
+ self.assertIn(str(self.core_qml_path), sys.path)
+
+ # module is imported
+ self.assertIn("person", sys.modules.keys())
+
+ # remove the imported modules
+ sys.path.remove(str(self.core_qml_path))
+ del sys.modules["person"]
+
+ # test with module_paths - dir
+ self.person_path = self.core_qml_path / "person.py"
+ pyqml.import_qml_modules(self.core_qml_path, module_paths=[self.core_qml_path])
+ self.assertIn(str(self.core_qml_path), sys.path)
+ self.assertIn("person", sys.modules.keys())
+
+ # test with module_paths - file - in testCoreApplication(self)
+
+ def testCoreApplication(self):
+ self.pyqml_run_cmd.extend(["--apptype", "core"])
+ self.pyqml_run_cmd.append(str(self.core_qml_path / "People" / "Main.qml"))
+ self.pyqml_run_cmd.extend(["-I", str(self.core_qml_path / "person.py")])
+
+ result = subprocess.run(self.pyqml_run_cmd, stdout=PIPE, env=self.test_env)
+ self.assertEqual(result.returncode, 0)
+ self.assertEqual(result.stdout.rstrip(), b"{'_name': 'Bob Jones', '_shoe_size': 12}")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/util/color.py b/sources/pyside6/tests/util/color.py
new file mode 100644
index 000000000..e85be28f3
--- /dev/null
+++ b/sources/pyside6/tests/util/color.py
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Function to print a colored line to terminal'''
+
+
+def print_colored(message):
+ print(f'\033[0;31m{message}\033[m') # red
+
+
+if __name__ == '__main__':
+ print('42 - the answer')
+ print_colored("But what's the question?")
+ print('Hum?')
diff --git a/sources/pyside6/tests/util/helper/__init__.py b/sources/pyside6/tests/util/helper/__init__.py
new file mode 100644
index 000000000..218d8921e
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/__init__.py
@@ -0,0 +1 @@
+# This file intentionally left blank.
diff --git a/sources/pyside6/tests/util/helper/basicpyslotcase.py b/sources/pyside6/tests/util/helper/basicpyslotcase.py
new file mode 100644
index 000000000..500735c3a
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/basicpyslotcase.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import gc
+
+
+class BasicPySlotCase(object):
+ '''Base class that tests python slots and signal emissions.
+
+ Python slots are defined as any callable passed to QObject.connect().
+ '''
+ def setUp(self):
+ self.called = False
+
+ def tearDown(self):
+ try:
+ del self.args
+ except:
+ pass
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+
+ def cb(self, *args):
+ '''Simple callback with arbitrary arguments.
+
+ The test function must setup the 'args' attribute with a sequence
+ containing the arguments expected to be received by this slot.
+ Currently only a single connection is supported.
+ '''
+ if tuple(self.args) == args:
+ self.called = True
+ else:
+ raise ValueError('Invalid arguments for callback')
diff --git a/sources/pyside6/tests/util/helper/docmodifier.py b/sources/pyside6/tests/util/helper/docmodifier.py
new file mode 100644
index 000000000..cfb665640
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/docmodifier.py
@@ -0,0 +1,91 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Helper metaclass do 'decorate' docstrings from base test case classes'''
+
+import types
+
+
+def copy_func(func):
+ '''Helper function to copy a function object (except docstring)'''
+ return types.FunctionType(func.func_code, func.func_globals, func.func_name,
+ func.func_defaults, func.func_closure)
+
+
+class DocModifier(type):
+ '''Metaclass for modifiying method documentation.
+
+ It allows the managed class to modify the method documentation, adding
+ prefixes and suffixes to a given set of methods.
+
+ For example, you have some unittest.TestCases that run on different set
+ of data. These methods could be written once in a base class and the
+ inheriting class just setup different setUp/tearDown methods with the
+ proper data. To differentiate the methods when using docstrings, you
+ can add a suffix or prefix to the docstring.
+
+ Variables in the implementing class:
+
+ doc_prefix - The prefix to the docstring
+ doc_suffix - The suffix to the docstring
+ doc_filter - The function to filter the methods. If not provided, this
+ no docstrings are changed.'''
+
+ def __new__(mcs, name, bases, dct):
+
+ # FIXME currently we have to define doc_filter on each subclass
+ filter_function = dct.get('doc_filter')
+ if not filter_function:
+ filter_function = lambda x: False
+
+ for base in bases:
+ for attr in [x for x in base.__dict__ if filter_function(x)]:
+ original = getattr(base, attr)
+
+ if original.__doc__:
+ copy = copy_func(original)
+ copy.__doc__ = (dct.get('doc_prefix', '') +
+ original.__doc__ +
+ dct.get('doc_suffix', ''))
+ dct[attr] = copy
+
+ return type.__new__(mcs, name, bases, dct)
+
+ def __init__(mcs, name, bases, dct):
+ super(DocModifier, mcs).__init__(name, bases, dct)
+
+
+if __name__ == '__main__':
+
+ # tests
+ class BaseTest(object):
+ __metaclass__ = DocModifier
+
+ def testBase(self):
+ '''base'''
+
+ def testWithoutDoc(self):
+ pass
+
+ class Implementing(BaseTest):
+
+ doc_filter = lambda x: x.startswith('test')
+ doc_prefix = 'prefix'
+ doc_suffix = 'suffix'
+
+ class OnlyPrefix(BaseTest):
+
+ doc_filter = lambda x: x.startswith('test')
+ doc_prefix = 'prefix'
+
+ class OnlySuffix(BaseTest):
+
+ doc_filter = lambda x: x.startswith('test')
+ doc_suffix = 'suffix'
+
+ assert (Implementing.testBase.__doc__ == 'prefixbasesuffix')
+ assert (Implementing.testWithoutDoc.__doc__ == None)
+ assert (OnlySuffix.testBase.__doc__ == 'basesuffix')
+ assert (OnlySuffix.testWithoutDoc.__doc__ == None)
+ assert (OnlyPrefix.testBase.__doc__ == 'prefixbase')
+ assert (OnlyPrefix.testWithoutDoc.__doc__ == None)
diff --git a/sources/pyside6/tests/util/helper/helper.py b/sources/pyside6/tests/util/helper/helper.py
new file mode 100644
index 000000000..f80753f1f
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/helper.py
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Helper classes and functions'''
+
+import os
+from random import randint
+
+
+def adjust_filename(filename, orig_mod_filename):
+ dirpath = os.path.dirname(os.path.abspath(orig_mod_filename))
+ return os.path.join(dirpath, filename)
+
+
+def _join_qml_errors(errors):
+ '''Return an error string from a list of QQmlError'''
+ result = ''
+ for i, error in enumerate(errors):
+ if i:
+ result += ', '
+ result += error.toString()
+ return result
+
+
+def quickview_errorstring(quickview):
+ '''Return an error string from a QQuickView'''
+ return _join_qml_errors(quickview.errors())
+
+
+def qmlcomponent_errorstring(component):
+ '''Return an error string from a QQmlComponent'''
+ return _join_qml_errors(component.errors())
+
+
+def random_string(size=5):
+ '''Generate random string with the given size'''
+ return ''.join(map(chr, [randint(33, 126) for x in range(size)]))
diff --git a/sources/pyside6/tests/util/helper/helper.pyproject b/sources/pyside6/tests/util/helper/helper.pyproject
new file mode 100644
index 000000000..dc23d87a5
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/helper.pyproject
@@ -0,0 +1,5 @@
+{
+ "files": ["basicpyslotcase.py", "docmodifier.py", "helper.py",
+ "timedqapplication.py", "usesqapplication.py", "usesqcoreapplication.py",
+ "usesqguiapplication.py" ]
+}
diff --git a/sources/pyside6/tests/util/helper/timedqapplication.py b/sources/pyside6/tests/util/helper/timedqapplication.py
new file mode 100644
index 000000000..d9250a9e0
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/timedqapplication.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Helper classes and functions'''
+
+import gc
+import unittest
+
+from PySide6.QtCore import QTimer
+from PySide6.QtWidgets import QApplication
+
+
+class TimedQApplication(unittest.TestCase):
+ '''Helper class with timed QApplication exec loop'''
+
+ def setUp(self, timeout=100):
+ '''Setups this Application.
+
+ timeout - timeout in milisseconds'''
+ self.app = QApplication.instance() or QApplication([])
+ QTimer.singleShot(timeout, self.app.quit)
+
+ def tearDown(self):
+ '''Delete resources'''
+ del self.app
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
diff --git a/sources/pyside6/tests/util/helper/timedqguiapplication.py b/sources/pyside6/tests/util/helper/timedqguiapplication.py
new file mode 100644
index 000000000..3d9a4217c
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/timedqguiapplication.py
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Helper classes and functions'''
+
+import gc
+import unittest
+
+from PySide6.QtCore import QTimer
+from PySide6.QtGui import QGuiApplication
+
+
+class TimedQGuiApplication(unittest.TestCase):
+ '''Helper class with timed QGuiApplication exec loop'''
+
+ def setUp(self, timeout=100):
+ '''Sets up this Application.
+
+ timeout - timeout in millisseconds'''
+ self.app = QGuiApplication.instance() or QGuiApplication([])
+ QTimer.singleShot(timeout, self.app.quit)
+
+ def tearDown(self):
+ '''Delete resources'''
+ del self.app
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
diff --git a/sources/pyside6/tests/util/helper/usesqapplication.py b/sources/pyside6/tests/util/helper/usesqapplication.py
new file mode 100644
index 000000000..f62e320f4
--- /dev/null
+++ b/sources/pyside6/tests/util/helper/usesqapplication.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Helper classes and functions'''
+
+import gc
+import sys
+import unittest
+
+# This version avoids explicit import in order to adapt to the
+# import decision of the main module.
+# This should work with every compatible library.
+# Replaces the QtGui and QtCore versions as well.
+
+
+class UsesQApplication(unittest.TestCase):
+ '''Helper class to provide Q(Core|Gui|)Application instances
+ Just connect or call self.exit_app_cb. When called, will ask
+ self.app to exit.
+ '''
+
+ def setUp(self):
+ '''Creates the QApplication instance'''
+ module = sys.modules[sorted(_ for _ in sys.modules
+ if _.endswith((".QtCore", ".QtGui", ".QtWidgets")))[-1]]
+ found = module.__name__.rsplit(".")[-1]
+ cls = getattr(module, {"QtWidgets": "QApplication",
+ "QtGui": "QGuiApplication",
+ "QtCore": "QCoreApplication"}[found])
+ # Simple way of making instance a singleton
+ super().setUp()
+ self.app = cls.instance() or cls([])
+
+ def tearDown(self):
+ '''Deletes the reference owned by self'''
+ del self.app
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ super().tearDown()
+
+ def exit_app_cb(self):
+ '''Quits the application'''
+ self.app.exit(0)
diff --git a/sources/pyside6/tests/util/httpd.py b/sources/pyside6/tests/util/httpd.py
new file mode 100644
index 000000000..4e6be4881
--- /dev/null
+++ b/sources/pyside6/tests/util/httpd.py
@@ -0,0 +1,153 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import http.server as BaseHTTPServer
+import os
+import random
+import select
+import sys
+import socketserver as SocketServer
+import tempfile
+import threading
+
+sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "util"))
+
+
+class TestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ DATA = b"PySide Server"
+ allow_reuse_address = True
+
+ def do_GET(self):
+ self.send_head()
+ self.wfile.write(TestHandler.DATA)
+
+ def do_HEAD(self):
+ self.send_head()
+
+ def send_head(self):
+ self.send_response(200)
+ self.send_header("Content-type", "text/plain")
+ self.send_header("Content-Length", str(len(TestHandler.DATA)))
+ self.end_headers()
+
+
+class TestSecureHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ DATA = "PySide"
+ allow_reuse_address = True
+
+ def do_GET(self):
+ self.send_head()
+ self.wfile.write(py3k.b(TestHandler.DATA))
+
+ def do_HEAD(self):
+ self.send_head()
+
+ def send_head(self):
+ try:
+ handler = self.marshall_handler()
+ handler.do_request(self)
+ except:
+ self.send_response(401)
+ self.send_header("WWW-Authenticate", "Basic realm='Secure Area'")
+ self.send_header("Content-type", "text/plain")
+ self.send_header("Content-Length", str(len(TestHandler.DATA)))
+ self.end_headers()
+
+# Workaround for the missing shutdown method in python2.5
+
+
+class CompatTCPServer(SocketServer.TCPServer):
+ def __init__(self, server_address, RequestHandlerClass):
+ SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
+
+ self.isPy25 = sys.version_info[0] == 2 and sys.version_info[1] == 5
+ if self.isPy25:
+ self.__is_shut_down = threading.Event()
+ self.__serving = False
+
+ def serve_forever(self, poll_interval=0.5):
+ """Handle one request at a time until shutdown.
+
+ Polls for shutdown every poll_interval seconds. Ignores
+ self.timeout. If you need to do periodic tasks, do them in
+ another thread.
+ """
+ if self.isPy25:
+ self.__serving = True
+ self.__is_shut_down.clear()
+ while self.__serving:
+ # XXX: Consider using another file descriptor or
+ # connecting to the socket to wake this up instead of
+ # polling. Polling reduces our responsiveness to a
+ # shutdown request and wastes cpu at all other times.
+ r, w, e = select.select([self], [], [], poll_interval)
+ if r:
+ self.py25_handle_request_noblock()
+ self.__is_shut_down.set()
+ else:
+ SocketServer.TCPServer.serve_forever(self, poll_interval)
+
+ def py25_handle_request_noblock(self):
+ """Handle one request, without blocking.
+
+ I assume that select.select has returned that the socket is
+ readable before this function was called, so there should be
+ no risk of blocking in get_request().
+ """
+ if self.isPy25:
+ try:
+ request, client_address = self.get_request()
+ except socket.error:
+ return
+ if self.verify_request(request, client_address):
+ try:
+ self.process_request(request, client_address)
+ except:
+ self.handle_error(request, client_address)
+ self.close_request(request)
+
+ def shutdown(self):
+ """Stops the serve_forever loop.
+
+ Blocks until the loop has finished. This must be called while
+ serve_forever() is running in another thread, or it will
+ deadlock.
+ """
+ if self.isPy25:
+ self.__serving = False
+ if not self.__is_shut_down:
+ self.__is_shut_down.wait()
+ else:
+ SocketServer.TCPServer.shutdown(self)
+
+
+class TestServer(threading.Thread):
+
+ def __init__(self, secure=False):
+ threading.Thread.__init__(self)
+
+ self._port = int(os.getenv("PYSIDE_TESTSERVER_PORT") or 12321)
+ self.keep_running = True
+
+ if secure:
+ handle = TestSecureHandler
+ else:
+ handle = TestHandler
+
+ while True:
+ try:
+ self.httpd = CompatTCPServer(('', self._port), handle)
+ break
+ except:
+ self._port = self._port + random.randint(1, 100)
+
+ def port(self):
+ return self._port
+
+ def run(self):
+ self.httpd.serve_forever()
+
+ def shutdown(self):
+ self.httpd.shutdown()
+ self.join()
+
diff --git a/sources/pyside6/tests/util/processtimer.py b/sources/pyside6/tests/util/processtimer.py
new file mode 100644
index 000000000..e471cf167
--- /dev/null
+++ b/sources/pyside6/tests/util/processtimer.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import time
+
+
+class TimeoutException(Exception):
+ def __init__(self, msg):
+ self.msg = msg
+
+ def __str__(self):
+ return repr(self.msg)
+
+
+class ProcessTimer(object):
+ '''Timeout function for controlling a subprocess.Popen instance.
+
+ Naive implementation using busy loop, see later other means
+ of doing this.
+ '''
+
+ def __init__(self, proc, timeout):
+ self.proc = proc
+ self.timeout = timeout
+
+ def waitfor(self):
+ time_passed = 0
+ while (self.proc.poll() is None and time_passed < self.timeout):
+ time_passed = time_passed + 1
+ time.sleep(1)
+
+ if time_passed >= self.timeout:
+ raise TimeoutException("Timeout expired, possible deadlock")
+
+
+if __name__ == "__main__":
+ # simple example
+
+ from subprocess import Popen
+
+ proc = Popen(['sleep', '10'])
+ t = ProcessTimer(proc, 5)
+ try:
+ t.waitfor()
+ except TimeoutException:
+ print(f"timeout - PID: {t.proc.pid}")
+ #TODO: detect SO and kill accordingly
+ #Linux
+ os.kill(t.proc.pid, 9)
+ #Windows (not tested)
+ #subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True)
+ print(f"exit code: {t.proc.poll()}")
diff --git a/sources/pyside6/tests/util/rename_imports.sh b/sources/pyside6/tests/util/rename_imports.sh
new file mode 100755
index 000000000..1ec900cb3
--- /dev/null
+++ b/sources/pyside6/tests/util/rename_imports.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+# Rename import statements from .py script to use a specific module name
+set -e
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 <old_name> <new_name> <directories...>"
+ exit 1
+fi
+
+old_name=$1; shift
+new_name=$1; shift
+
+find "$@" -name "*.py" -exec sed -ri "s/(import|from) $old_name/\1 $new_name/" '{}' \;
diff --git a/sources/pyside6/tests/util/test_processtimer.py b/sources/pyside6/tests/util/test_processtimer.py
new file mode 100644
index 000000000..cee6aa14d
--- /dev/null
+++ b/sources/pyside6/tests/util/test_processtimer.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'Tests for processtimer.py'
+
+import unittest
+import os
+
+from subprocess import Popen, PIPE
+from processtimer import TimeoutException, ProcessTimer
+
+
+class TimeoutTest(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+
+ def testRaise(self):
+ self.proc = Popen(['python2.5', '-c', 'while True: pass'], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 1)
+ self.assertRaises(TimeoutException, timer.waitfor)
+
+
+class SimpleTest(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+
+ def testSimple(self):
+ self.proc = Popen(['python2.5', '-c', '"print"'], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 10)
+ timer.waitfor()
+
+
+class TestEchoOutput(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+
+ def testOutput(self):
+ self.proc = Popen(['python2.5', '-c', 'print 1',], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 1)
+ timer.waitfor()
+ self.assertEqual(self.proc.stdout.read().strip(), '1')
+
+
+class TestRetCode(unittest.TestCase):
+
+ def tearDown(self):
+ try:
+ os.kill(self.proc.pid, 9)
+ except OSError:
+ pass
+
+ def testSimple(self):
+ self.proc = Popen(['python2.5', '-c', 'print 1'], stdout=PIPE, stderr=PIPE)
+ timer = ProcessTimer(self.proc, 10)
+ timer.waitfor()
+
+ self.assertEqual(self.proc.poll(), 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside6/tests/util/valgrind-python.supp b/sources/pyside6/tests/util/valgrind-python.supp
new file mode 100644
index 000000000..a54b451b3
--- /dev/null
+++ b/sources/pyside6/tests/util/valgrind-python.supp
@@ -0,0 +1,349 @@
+#
+# This is a valgrind suppression file that should be used when using valgrind.
+#
+# Here's an example of running valgrind:
+#
+# cd python/dist/src
+# valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \
+# ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network
+#
+# You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER
+# to use the preferred suppressions with Py_ADDRESS_IN_RANGE.
+#
+# If you do not want to recompile Python, you can uncomment
+# suppressions for PyObject_Free and PyObject_Realloc.
+#
+# See Misc/README.valgrind for more information.
+
+# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64)
+ Memcheck:Value8
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:Py_ADDRESS_IN_RANGE
+}
+
+#
+# Leaks (including possible leaks)
+# Hmmm, I wonder if this masks some real leaks. I think it does.
+# Will need to fix that.
+#
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:realloc
+ fun:_PyObject_GC_Resize
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:malloc
+ fun:_PyObject_GC_New
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:malloc
+ fun:_PyObject_GC_NewVar
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+#
+# Non-python specific leaks
+#
+
+{
+ Handle pthread issue (possibly leaked)
+ Memcheck:Leak
+ fun:calloc
+ fun:allocate_dtv
+ fun:_dl_allocate_tls_storage
+ fun:_dl_allocate_tls
+}
+
+{
+ Handle pthread issue (possibly leaked)
+ Memcheck:Leak
+ fun:memalign
+ fun:_dl_allocate_tls_storage
+ fun:_dl_allocate_tls
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:PyObject_Realloc
+}
+
+###
+### All the suppressions below are for errors that occur within libraries
+### that Python uses. The problems to not appear to be related to Python's
+### use of the libraries.
+###
+
+{
+ Generic gentoo ld problems
+ Memcheck:Cond
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Param
+ write(buf)
+ fun:write
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_close
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Value8
+ fun:memmove
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Cond
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Cond
+ fun:memmove
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ GDBM problems, see test_gdbm
+ Memcheck:Param
+ write(buf)
+ fun:write
+ fun:gdbm_open
+
+}
+
+{
+ ZLIB problems, see test_gzip
+ Memcheck:Cond
+ obj:/lib/libz.so.1.2.3
+ obj:/lib/libz.so.1.2.3
+ fun:deflate
+}
+
+{
+ Avoid problems w/readline doing a putenv and leaking on exit
+ Memcheck:Leak
+ fun:malloc
+ fun:xmalloc
+ fun:sh_set_lines_and_columns
+ fun:_rl_get_screen_size
+ fun:_rl_init_terminal_io
+ obj:/lib/libreadline.so.4.3
+ fun:rl_initialize
+}
+
+###
+### These occur from somewhere within the SSL, when running
+### test_socket_sll. They are too general to leave on by default.
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Cond
+### fun:memset
+###}
+###{
+### somewhere in SSL stuff
+### Memcheck:Value4
+### fun:memset
+###}
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Cond
+### fun:MD5_Update
+###}
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Value4
+### fun:MD5_Update
+###}
+
+#
+# All of these problems come from using test_socket_ssl
+#
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_bin2bn
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_num_bits_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:BN_num_bits_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_mod_exp_mont_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_mod_exp_mont
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Param
+ write(buf)
+ fun:write
+ obj:/usr/lib/libcrypto.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:RSA_verify
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:RSA_verify
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:DES_set_key_unchecked
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:DES_encrypt2
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BUF_MEM_grow_clean
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:memcpy
+ fun:ssl3_read_bytes
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:SHA1_Update
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:SHA1_Update
+}
+
+