aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-01-26 08:40:30 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-01-26 11:20:26 +0100
commit019ab0d2388e30def0cb982c14e011af119d2409 (patch)
treecc34379c3114f67fcbe2477cb7c5294c17c6fa50
parentf2e3e8d8d34c93dc8e61d0efd01a59f542abd94c (diff)
PySide6: Re-add QStateMachine
The code was moved from QtCore into a separate library, QStateMachine, within the qtscxml repository. Re-add tests and fix examples. Task-number: PYSIDE-904 Task-number: PYSIDE-1482 Change-Id: I977b4835b3345fb342c369e4fdd92646118f7fda Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--examples/widgets/animation/animatedtiles/animatedtiles.py24
-rw-r--r--examples/widgets/animation/appchooser/appchooser.py14
-rw-r--r--examples/widgets/animation/states/states.py12
-rw-r--r--examples/widgets/state-machine/eventtrans.py4
-rw-r--r--examples/widgets/state-machine/factstates.py5
-rw-r--r--examples/widgets/state-machine/pingpong.py4
-rw-r--r--examples/widgets/state-machine/rogue.py14
-rw-r--r--examples/widgets/state-machine/trafficlight.py4
-rw-r--r--examples/widgets/state-machine/twowaybutton.py4
-rw-r--r--sources/cmake_helpers/helpers.cmake1
-rw-r--r--sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt41
-rw-r--r--sources/pyside6/PySide6/QtStateMachine/typesystem_statemachine.xml221
-rw-r--r--sources/pyside6/tests/QtStateMachine/CMakeLists.txt5
-rw-r--r--sources/pyside6/tests/QtStateMachine/bug_1031.py42
-rw-r--r--sources/pyside6/tests/QtStateMachine/qabstracttransition_test.py194
-rw-r--r--sources/pyside6/tests/QtStateMachine/qstate_test.py73
-rw-r--r--sources/pyside6/tests/QtStateMachine/qstatemachine_test.py93
-rw-r--r--sources/pyside6/tests/QtStateMachine/setprop_on_ctor_test.py48
18 files changed, 768 insertions, 35 deletions
diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.py b/examples/widgets/animation/animatedtiles/animatedtiles.py
index 3ec1b475b..b5a030235 100644
--- a/examples/widgets/animation/animatedtiles/animatedtiles.py
+++ b/examples/widgets/animation/animatedtiles/animatedtiles.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 Riverbank Computing Limited.
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -40,7 +40,7 @@
##
#############################################################################
-from PySide6 import QtCore, QtGui, QtWidgets
+from PySide6 import QtCore, QtGui, QtStateMachine, QtWidgets
import animatedtiles_rc
@@ -179,14 +179,16 @@ if __name__ == '__main__':
buttonParent.setZValue(65)
# States.
- rootState = QtCore.QState()
- ellipseState = QtCore.QState(rootState)
- figure8State = QtCore.QState(rootState)
- randomState = QtCore.QState(rootState)
- tiledState = QtCore.QState(rootState)
- centeredState = QtCore.QState(rootState)
+ rootState = QtStateMachine.QState()
+ ellipseState = QtStateMachine.QState(rootState)
+ figure8State = QtStateMachine.QState(rootState)
+ randomState = QtStateMachine.QState(rootState)
+ tiledState = QtStateMachine.QState(rootState)
+ centeredState = QtStateMachine.QState(rootState)
# Values.
+ generator = QtCore.QRandomGenerator.global_()
+
for i, item in enumerate(items):
# Ellipse.
ellipseState.assignProperty(item, 'pos',
@@ -200,8 +202,8 @@ if __name__ == '__main__':
# Random.
randomState.assignProperty(item, 'pos',
- QtCore.QPointF(-250 + QtCore.qrand() % 500,
- -250 + QtCore.qrand() % 500))
+ QtCore.QPointF(-250 + generator.bounded(0, 500),
+ -250 + generator.bounded(0, 500)))
# Tiled.
tiledState.assignProperty(item, 'pos',
@@ -221,7 +223,7 @@ if __name__ == '__main__':
QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform)
view.show()
- states = QtCore.QStateMachine()
+ states = QtStateMachine.QStateMachine()
states.addState(rootState)
states.setInitialState(rootState)
rootState.setInitialState(centeredState)
diff --git a/examples/widgets/animation/appchooser/appchooser.py b/examples/widgets/animation/appchooser/appchooser.py
index 55cd3c1d5..5c9e9c6c1 100644
--- a/examples/widgets/animation/appchooser/appchooser.py
+++ b/examples/widgets/animation/appchooser/appchooser.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 Riverbank Computing Limited.
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -40,7 +40,7 @@
##
#############################################################################
-from PySide6 import QtCore, QtGui, QtWidgets
+from PySide6 import QtCore, QtGui, QtStateMachine, QtWidgets
import appchooser_rc
@@ -71,7 +71,7 @@ class Pixmap(QtWidgets.QGraphicsWidget):
def createStates(objects, selectedRect, parent):
for obj in objects:
- state = QtCore.QState(parent)
+ state = QtStateMachine.QState(parent)
state.assignProperty(obj, 'geometry', selectedRect)
parent.addTransition(obj.clicked, state)
@@ -111,13 +111,13 @@ if __name__ == '__main__':
window.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
window.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
- machine = QtCore.QStateMachine()
- machine.setGlobalRestorePolicy(QtCore.QStateMachine.RestoreProperties)
+ machine = QtStateMachine.QStateMachine()
+ machine.setGlobalRestorePolicy(QtStateMachine.QStateMachine.RestoreProperties)
- group = QtCore.QState(machine)
+ group = QtStateMachine.QState(machine)
selectedRect = QtCore.QRect(86, 86, 128, 128)
- idleState = QtCore.QState(group)
+ idleState = QtStateMachine.QState(group)
group.setInitialState(idleState)
objects = [p1, p2, p3, p4]
diff --git a/examples/widgets/animation/states/states.py b/examples/widgets/animation/states/states.py
index 363b5af6c..77c76bd9e 100644
--- a/examples/widgets/animation/states/states.py
+++ b/examples/widgets/animation/states/states.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 Riverbank Computing Limited.
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -40,7 +40,7 @@
##
#############################################################################
-from PySide6 import QtCore, QtGui, QtWidgets
+from PySide6 import QtCore, QtGui, QtStateMachine, QtWidgets
import states_rc
@@ -116,10 +116,10 @@ if __name__ == '__main__':
scene.addItem(p5)
scene.addItem(p6)
- machine = QtCore.QStateMachine()
- state1 = QtCore.QState(machine)
- state2 = QtCore.QState(machine)
- state3 = QtCore.QState(machine)
+ machine = QtStateMachine.QStateMachine()
+ state1 = QtStateMachine.QState(machine)
+ state2 = QtStateMachine.QState(machine)
+ state3 = QtStateMachine.QState(machine)
machine.setInitialState(state1)
# State 1.
diff --git a/examples/widgets/state-machine/eventtrans.py b/examples/widgets/state-machine/eventtrans.py
index 3445832a0..312b4e258 100644
--- a/examples/widgets/state-machine/eventtrans.py
+++ b/examples/widgets/state-machine/eventtrans.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -42,6 +42,8 @@
from PySide6.QtWidgets import *
from PySide6.QtCore import *
+from PySide6.QtStateMachine import QEventTransition, QState, QStateMachine
+
class MainWindow(QMainWindow):
def __init__(self):
diff --git a/examples/widgets/state-machine/factstates.py b/examples/widgets/state-machine/factstates.py
index 64b9613ec..3608f2a49 100644
--- a/examples/widgets/state-machine/factstates.py
+++ b/examples/widgets/state-machine/factstates.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -42,6 +42,9 @@
from PySide6.QtWidgets import *
from PySide6.QtCore import *
+from PySide6.QtStateMachine import (QFinalState, QSignalTransition, QState,
+ QStateMachine)
+
class Factorial(QObject):
xChanged = Signal(int)
diff --git a/examples/widgets/state-machine/pingpong.py b/examples/widgets/state-machine/pingpong.py
index 6d64bebc6..f2e1f59f7 100644
--- a/examples/widgets/state-machine/pingpong.py
+++ b/examples/widgets/state-machine/pingpong.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -42,6 +42,8 @@
from PySide6.QtWidgets import *
from PySide6.QtCore import *
+from PySide6.QtStateMachine import QAbstractTransition, QState, QStateMachine
+
class PingEvent(QEvent):
def __init__(self):
diff --git a/examples/widgets/state-machine/rogue.py b/examples/widgets/state-machine/rogue.py
index af37b522b..b830d6023 100644
--- a/examples/widgets/state-machine/rogue.py
+++ b/examples/widgets/state-machine/rogue.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -43,6 +43,9 @@
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
+from PySide6.QtStateMachine import (QEventTransition, QFinalState,
+ QKeyEventTransition, QState, QStateMachine)
+
class MovementTransition(QEventTransition):
def __init__(self, window):
@@ -83,12 +86,11 @@ class MainWindow(QMainWindow):
self.height = 20
self.statusStr = ''
- database = QFontDatabase()
font = QFont()
- if 'Monospace' in database.families():
+ if 'Monospace' in QFontDatabase.families():
font = QFont('Monospace', 12)
else:
- for family in database.families():
+ for family in QFontDatabase.families():
if database.isFixedPitch(family):
font = QFont(family, 12)
self.setFont(font)
@@ -98,12 +100,12 @@ class MainWindow(QMainWindow):
self.show()
def setupMap(self):
self.map = []
- qsrand(QTime(0, 0, 0).secsTo(QTime.currentTime()))
+ generator = QRandomGenerator().global_()
for x in range(self.width):
column = []
for y in range(self.height):
if x == 0 or x == self.width - 1 or y == 0 or \
- y == self.height - 1 or qrand() % 40 == 0:
+ y == self.height - 1 or generator.bounded(0, 40) == 0:
column.append('#')
else:
column.append('.')
diff --git a/examples/widgets/state-machine/trafficlight.py b/examples/widgets/state-machine/trafficlight.py
index 4aa8d560e..3631fdbbb 100644
--- a/examples/widgets/state-machine/trafficlight.py
+++ b/examples/widgets/state-machine/trafficlight.py
@@ -43,6 +43,8 @@
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
+from PySide6.QtStateMachine import QFinalState, QState, QStateMachine
+
class LightWidget(QWidget):
def __init__(self, color):
@@ -83,7 +85,7 @@ class TrafficLightWidget(QWidget):
self.greenLight = LightWidget(Qt.green)
vbox.addWidget(self.greenLight)
pal = QPalette()
- pal.setColor(QPalette.Background, Qt.black)
+ pal.setColor(QPalette.Window, Qt.black)
self.setPalette(pal)
self.setAutoFillBackground(True)
diff --git a/examples/widgets/state-machine/twowaybutton.py b/examples/widgets/state-machine/twowaybutton.py
index 44a011d69..6b3c58359 100644
--- a/examples/widgets/state-machine/twowaybutton.py
+++ b/examples/widgets/state-machine/twowaybutton.py
@@ -2,7 +2,7 @@
#############################################################################
##
## Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -42,6 +42,8 @@
from PySide6.QtWidgets import *
from PySide6.QtCore import *
+from PySide6.QtStateMachine import QState, QStateMachine
+
if __name__ == '__main__':
import sys
diff --git a/sources/cmake_helpers/helpers.cmake b/sources/cmake_helpers/helpers.cmake
index 98a74251a..446b7940b 100644
--- a/sources/cmake_helpers/helpers.cmake
+++ b/sources/cmake_helpers/helpers.cmake
@@ -32,6 +32,7 @@ set(ALL_OPTIONAL_MODULES
Scxml
Sensors
SerialPort
+ StateMachine
TextToSpeech
Charts
Svg
diff --git a/sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt b/sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt
new file mode 100644
index 000000000..204a126b6
--- /dev/null
+++ b/sources/pyside6/PySide6/QtStateMachine/CMakeLists.txt
@@ -0,0 +1,41 @@
+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}Core_LIBRARIES}
+ ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}
+ ${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..561916d27
--- /dev/null
+++ b/sources/pyside6/PySide6/QtStateMachine/typesystem_statemachine.xml
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<typesystem package="PySide6.QtStateMachine">
+ <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/qtcore.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="addTransition(const QObject*,const char*,QAbstractState*)">
+ <modify-argument index="return">
+ <parent index="this" action="add"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.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/qtcore.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"/>
+
+ <value-type name="SignalEvent"/>
+ <value-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/qtcore.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/qtcore.cpp" snippet="qstatemachine-defaultanimations"/>
+ </add-function>
+ </object-type>
+
+</typesystem>
diff --git a/sources/pyside6/tests/QtStateMachine/CMakeLists.txt b/sources/pyside6/tests/QtStateMachine/CMakeLists.txt
new file mode 100644
index 000000000..2d41653af
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/CMakeLists.txt
@@ -0,0 +1,5 @@
+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/bug_1031.py b/sources/pyside6/tests/QtStateMachine/bug_1031.py
new file mode 100644
index 000000000..de623c419
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/bug_1031.py
@@ -0,0 +1,42 @@
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+
+sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "util"))
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+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..e5f1bc7fb
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/qabstracttransition_test.py
@@ -0,0 +1,194 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+from sys import getrefcount
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+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_()
+
+ def testRefCountOfTargetState(self):
+ transition = QEventTransition()
+ state1 = QState()
+ refcount1 = getrefcount(state1)
+
+ transition.setTargetState(state1)
+
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(getrefcount(transition.targetState()), refcount1 + 1)
+
+ state2 = QState()
+ refcount2 = getrefcount(state2)
+
+ transition.setTargetState(state2)
+
+ self.assertEqual(transition.targetState(), state2)
+ self.assertEqual(getrefcount(transition.targetState()), refcount2 + 1)
+ self.assertEqual(getrefcount(state1), refcount1)
+
+ del transition
+
+ self.assertEqual(getrefcount(state2), refcount2)
+
+ def testRefCountOfTargetStates(self):
+ transition = QEventTransition()
+ state1 = QState()
+ state2 = QState()
+ states = [state1, state2]
+ refcount1 = getrefcount(state1)
+ refcount2 = getrefcount(state2)
+
+ transition.setTargetStates(states)
+
+ self.assertEqual(transition.targetStates(), states)
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(getrefcount(transition.targetStates()[0]), refcount1 + 1)
+ self.assertEqual(getrefcount(transition.targetStates()[1]), refcount2 + 1)
+
+ del states
+ del transition
+
+ self.assertEqual(getrefcount(state1), refcount1 - 1)
+ self.assertEqual(getrefcount(state2), refcount2 - 1)
+
+ def testRefCountOfTargetStatesAfterSingleTargetState(self):
+ transition = QEventTransition()
+ state0 = QState()
+ refcount0 = getrefcount(state0)
+
+ transition.setTargetState(state0)
+
+ self.assertEqual(transition.targetState(), state0)
+ self.assertEqual(getrefcount(transition.targetState()), refcount0 + 1)
+
+ state1 = QState()
+ state2 = QState()
+ states = [state1, state2]
+ refcount1 = getrefcount(state1)
+ refcount2 = getrefcount(state2)
+
+ transition.setTargetStates(states)
+
+ self.assertEqual(getrefcount(state0), refcount0)
+ self.assertEqual(transition.targetStates(), states)
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(getrefcount(transition.targetStates()[0]), refcount1 + 1)
+ self.assertEqual(getrefcount(transition.targetStates()[1]), refcount2 + 1)
+
+ del states
+ del transition
+
+ self.assertEqual(getrefcount(state1), refcount1 - 1)
+ self.assertEqual(getrefcount(state2), refcount2 - 1)
+
+ def testRefCountOfTargetStatesBeforeSingleTargetState(self):
+ transition = QEventTransition()
+ state1 = QState()
+ state2 = QState()
+ states = [state1, state2]
+ refcount1 = getrefcount(state1)
+ refcount2 = getrefcount(state2)
+
+ transition.setTargetStates(states)
+
+ self.assertEqual(transition.targetStates(), states)
+ self.assertEqual(transition.targetState(), state1)
+ self.assertEqual(getrefcount(transition.targetStates()[0]), refcount1 + 1)
+ self.assertEqual(getrefcount(transition.targetStates()[1]), refcount2 + 1)
+
+ state3 = QState()
+ refcount3 = getrefcount(state3)
+
+ transition.setTargetState(state3)
+
+ self.assertEqual(transition.targetState(), state3)
+ self.assertEqual(getrefcount(transition.targetState()), refcount3 + 1)
+
+ del states
+
+ self.assertEqual(getrefcount(state1), refcount1 - 1)
+ self.assertEqual(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..ab9fa1abd
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/qstate_test.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+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..895b8f2cc
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/qstatemachine_test.py
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+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.usesqcoreapplication import UsesQCoreApplication
+
+
+class QStateMachineTest(UsesQCoreApplication):
+
+ def cb(self, *args):
+ self.assertEqual(self.machine.defaultAnimations(), [self.anim])
+
+ def testBasic(self):
+ self.machine = QStateMachine()
+ s1 = QState()
+ s2 = QState()
+ s3 = QFinalState()
+
+ QObject.connect(self.machine, SIGNAL("started()"), 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(UsesQCoreApplication):
+ '''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..345ec40b9
--- /dev/null
+++ b/sources/pyside6/tests/QtStateMachine/setprop_on_ctor_test.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2021 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+import unittest
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+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()