aboutsummaryrefslogtreecommitdiffstats
path: root/examples/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets')
-rw-r--r--examples/widgets/animation/animatedtiles/animatedtiles.py4
-rw-r--r--examples/widgets/animation/appchooser/appchooser.py2
-rw-r--r--examples/widgets/animation/easing/easing.py31
-rw-r--r--examples/widgets/animation/easing/form.ui105
-rw-r--r--examples/widgets/animation/easing/ui_form.py61
-rw-r--r--examples/widgets/animation/states/states.py2
-rw-r--r--examples/widgets/codeeditor/codeeditor.py4
-rw-r--r--examples/widgets/desktop/screenshot/screenshot.py6
-rw-r--r--examples/widgets/desktop/systray/images/bad.png (renamed from examples/widgets/systray/images/bad.png)bin2496 -> 2496 bytes
-rw-r--r--examples/widgets/desktop/systray/images/heart.png (renamed from examples/widgets/systray/images/heart.png)bin25780 -> 25780 bytes
-rw-r--r--examples/widgets/desktop/systray/images/trash.png (renamed from examples/widgets/systray/images/trash.png)bin12128 -> 12128 bytes
-rw-r--r--examples/widgets/desktop/systray/main.py (renamed from examples/widgets/systray/main.py)0
-rw-r--r--examples/widgets/desktop/systray/rc_systray.py (renamed from examples/widgets/systray/rc_systray.py)0
-rw-r--r--examples/widgets/desktop/systray/systray.pyproject (renamed from examples/widgets/systray/systray.pyproject)0
-rw-r--r--examples/widgets/desktop/systray/systray.qrc (renamed from examples/widgets/systray/systray.qrc)0
-rw-r--r--examples/widgets/desktop/systray/window.py (renamed from examples/widgets/systray/window.py)0
-rw-r--r--examples/widgets/dialogs/classwizard/classwizard.py14
-rw-r--r--examples/widgets/dialogs/classwizard/listchooser.py7
-rw-r--r--examples/widgets/dialogs/findfiles/findfiles.py4
-rw-r--r--examples/widgets/dialogs/standarddialogs/standarddialogs.py20
-rw-r--r--examples/widgets/dialogs/trivialwizard/trivialwizard.py2
-rw-r--r--examples/widgets/draganddrop/dropsite/doc/dropsite.rst8
-rw-r--r--examples/widgets/draganddrop/dropsite/droparea.py67
-rw-r--r--examples/widgets/draganddrop/dropsite/dropsite.pyproject3
-rw-r--r--examples/widgets/draganddrop/dropsite/dropsitewindow.py115
-rw-r--r--examples/widgets/draganddrop/dropsite/main.py15
-rw-r--r--examples/widgets/effects/lighting/lighting.py2
-rw-r--r--examples/widgets/gettext/main.py4
-rw-r--r--examples/widgets/graphicsview/anchorlayout/anchorlayout.py2
-rw-r--r--examples/widgets/graphicsview/diagramscene/diagramscene.py29
-rw-r--r--examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py2
-rw-r--r--examples/widgets/graphicsview/elasticnodes/elasticnodes.py6
-rw-r--r--examples/widgets/imageviewer/imageviewer.py12
-rw-r--r--examples/widgets/itemviews/address_book/address_book.py3
-rw-r--r--examples/widgets/itemviews/address_book/addresswidget.py5
-rw-r--r--examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py5
-rw-r--r--examples/widgets/itemviews/dirview/dirview.py60
-rw-r--r--examples/widgets/itemviews/dirview/dirview.pyproject3
-rw-r--r--examples/widgets/itemviews/dirview/doc/dirview.rst5
-rw-r--r--examples/widgets/itemviews/editabletreemodel/treemodel.py9
-rw-r--r--examples/widgets/itemviews/fetchmore/fetchmore.py5
-rw-r--r--examples/widgets/itemviews/spinboxdelegate/doc/spinboxdelegate.rst5
-rw-r--r--examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.py78
-rw-r--r--examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.pyproject3
-rw-r--r--examples/widgets/itemviews/spreadsheet/doc/spreadsheet.pngbin0 -> 40187 bytes
-rw-r--r--examples/widgets/itemviews/spreadsheet/doc/spreadsheet.rst10
-rw-r--r--examples/widgets/itemviews/spreadsheet/main.py19
-rw-r--r--examples/widgets/itemviews/spreadsheet/spreadsheet.py544
-rw-r--r--examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.py67
-rw-r--r--examples/widgets/itemviews/spreadsheet/spreadsheetitem.py122
-rw-r--r--examples/widgets/layouts/basiclayouts/basiclayouts.py3
-rw-r--r--examples/widgets/layouts/dynamiclayouts/dynamiclayouts.py2
-rw-r--r--examples/widgets/linguist/main.py7
-rw-r--r--examples/widgets/mainwindows/application/application.py10
-rw-r--r--examples/widgets/mainwindows/dockwidgets/dockwidgets.py2
-rw-r--r--examples/widgets/mainwindows/mdi/mdi.py17
-rw-r--r--examples/widgets/painting/painter/painter.py15
-rw-r--r--examples/widgets/painting/plot/plot.py5
-rw-r--r--examples/widgets/richtext/orderform/orderform.py7
-rw-r--r--examples/widgets/richtext/textedit/main.py1
-rw-r--r--examples/widgets/richtext/textedit/textedit.py14
-rw-r--r--examples/widgets/richtext/textobject/textobject.py6
-rw-r--r--examples/widgets/state-machine/eventtrans/eventtrans.py57
-rw-r--r--examples/widgets/state-machine/eventtrans/eventtrans.pyproject3
-rw-r--r--examples/widgets/state-machine/factstates/factstates.py89
-rw-r--r--examples/widgets/state-machine/factstates/factstates.pyproject3
-rw-r--r--examples/widgets/state-machine/ping_pong/ping_pong.py70
-rw-r--r--examples/widgets/state-machine/ping_pong/ping_pong.pyproject3
-rw-r--r--examples/widgets/state-machine/rogue/rogue.py179
-rw-r--r--examples/widgets/state-machine/rogue/rogue.pyproject3
-rw-r--r--examples/widgets/state-machine/trafficlight/doc/trafficlight.pngbin79 -> 0 bytes
-rw-r--r--examples/widgets/state-machine/trafficlight/doc/trafficlight.rst10
-rw-r--r--examples/widgets/state-machine/trafficlight/trafficlight.py117
-rw-r--r--examples/widgets/state-machine/trafficlight/trafficlight.pyproject3
-rw-r--r--examples/widgets/state-machine/twowaybutton/twowaybutton.py33
-rw-r--r--examples/widgets/state-machine/twowaybutton/twowaybutton.pyproject3
-rw-r--r--examples/widgets/tools/regularexpression/regularexpression.py2
-rw-r--r--examples/widgets/tools/regularexpression/regularexpressiondialog.py11
-rw-r--r--examples/widgets/tutorials/addressbook/part2.py6
-rw-r--r--examples/widgets/tutorials/addressbook/part3.py8
-rw-r--r--examples/widgets/tutorials/addressbook/part4.py11
-rw-r--r--examples/widgets/tutorials/addressbook/part5.py10
-rw-r--r--examples/widgets/tutorials/addressbook/part6.py9
-rw-r--r--examples/widgets/tutorials/addressbook/part7.py9
-rw-r--r--examples/widgets/tutorials/cannon/t10.py2
-rw-r--r--examples/widgets/tutorials/cannon/t11.py2
-rw-r--r--examples/widgets/tutorials/cannon/t12.py2
-rw-r--r--examples/widgets/tutorials/cannon/t13.py4
-rw-r--r--examples/widgets/tutorials/cannon/t14.py8
-rw-r--r--examples/widgets/tutorials/cannon/t2.py3
-rw-r--r--examples/widgets/tutorials/cannon/t8.py2
-rw-r--r--examples/widgets/tutorials/cannon/t9.py2
-rw-r--r--examples/widgets/tutorials/modelview/1_readonly.py38
-rw-r--r--examples/widgets/tutorials/modelview/2_formatting.py65
-rw-r--r--examples/widgets/tutorials/modelview/3_changingmodel.py52
-rw-r--r--examples/widgets/tutorials/modelview/4_headers.py43
-rw-r--r--examples/widgets/tutorials/modelview/5_edit.py73
-rw-r--r--examples/widgets/tutorials/modelview/6_treeview.py41
-rw-r--r--examples/widgets/tutorials/modelview/7_selections.py70
-rw-r--r--examples/widgets/tutorials/modelview/doc/modelview.rst4
-rw-r--r--examples/widgets/tutorials/modelview/modelview.pyproject9
-rw-r--r--examples/widgets/widgets/charactermap/charactermap.pyproject4
-rw-r--r--examples/widgets/widgets/charactermap/characterwidget.py133
-rw-r--r--examples/widgets/widgets/charactermap/doc/charactermap.rst8
-rw-r--r--examples/widgets/widgets/charactermap/fontinfodialog.py47
-rw-r--r--examples/widgets/widgets/charactermap/main.py17
-rw-r--r--examples/widgets/widgets/charactermap/mainwindow.py167
-rw-r--r--examples/widgets/widgets/digitalclock/digitalclock.py41
-rw-r--r--examples/widgets/widgets/digitalclock/digitalclock.pyproject3
-rw-r--r--examples/widgets/widgets/digitalclock/doc/digitalclock-screenshot.pngbin0 -> 726 bytes
-rw-r--r--examples/widgets/widgets/digitalclock/doc/digitalclock.rst12
-rw-r--r--examples/widgets/widgets/tetrix/doc/tetrix-screenshot.png (renamed from examples/widgets/tetrix/doc/tetrix-screenshot.png)bin5396 -> 5396 bytes
-rw-r--r--examples/widgets/widgets/tetrix/doc/tetrix.rst (renamed from examples/widgets/tetrix/doc/tetrix.rst)0
-rw-r--r--examples/widgets/widgets/tetrix/tetrix.py (renamed from examples/widgets/tetrix/tetrix.py)6
-rw-r--r--examples/widgets/widgets/tetrix/tetrix.pyproject (renamed from examples/widgets/tetrix/tetrix.pyproject)0
-rw-r--r--examples/widgets/widgetsgallery/main.py2
-rw-r--r--examples/widgets/widgetsgallery/widgetgallery.py10
117 files changed, 2308 insertions, 760 deletions
diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.py b/examples/widgets/animation/animatedtiles/animatedtiles.py
index 6ef62c2fd..b621ec117 100644
--- a/examples/widgets/animation/animatedtiles/animatedtiles.py
+++ b/examples/widgets/animation/animatedtiles/animatedtiles.py
@@ -8,11 +8,11 @@ import math
from PySide6.QtCore import (QEasingCurve, QObject, QParallelAnimationGroup,
QPointF, QPropertyAnimation, QRandomGenerator,
QRectF, QTimer, Qt, Property, Signal)
-from PySide6.QtGui import (QBrush, QColor, QLinearGradient, QPainter,
+from PySide6.QtGui import (QBrush, QLinearGradient, QPainter,
QPainterPath, QPixmap, QTransform)
from PySide6.QtWidgets import (QApplication, QGraphicsItem, QGraphicsPixmapItem,
QGraphicsRectItem, QGraphicsScene, QGraphicsView,
- QGraphicsWidget, QStyle, QWidget)
+ QGraphicsWidget, QStyle)
from PySide6.QtStateMachine import QState, QStateMachine
import animatedtiles_rc
diff --git a/examples/widgets/animation/appchooser/appchooser.py b/examples/widgets/animation/appchooser/appchooser.py
index 5421c8c2f..e49f37dec 100644
--- a/examples/widgets/animation/appchooser/appchooser.py
+++ b/examples/widgets/animation/appchooser/appchooser.py
@@ -8,7 +8,7 @@ from PySide6.QtCore import (QPointF, QPropertyAnimation, QRect, QRectF, Qt,
Signal)
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import (QApplication, QGraphicsScene, QGraphicsView,
- QGraphicsWidget, QWidget)
+ QGraphicsWidget)
from PySide6.QtStateMachine import QState, QStateMachine
import appchooser_rc
diff --git a/examples/widgets/animation/easing/easing.py b/examples/widgets/animation/easing/easing.py
index 58341c0cf..f8cba0060 100644
--- a/examples/widgets/animation/easing/easing.py
+++ b/examples/widgets/animation/easing/easing.py
@@ -8,10 +8,10 @@ import sys
from PySide6.QtCore import (Property, QEasingCurve, QObject, QPropertyAnimation,
QPoint, QPointF, QRect, QRectF, QSize, Qt)
from PySide6.QtGui import (QBrush, QColor, QIcon, QLinearGradient, QPainter,
- QPainterPath, QPen, QPixmap)
+ QPainterPath, QPixmap)
from PySide6.QtWidgets import (QApplication, QGraphicsPixmapItem,
- QGraphicsItem, QGraphicsScene, QGraphicsView,
- QListWidget, QListWidgetItem, QWidget)
+ QGraphicsItem, QGraphicsScene,
+ QListWidgetItem, QWidget)
from ui_form import Ui_Form
@@ -110,7 +110,7 @@ class Window(QWidget):
self._anim = Animation(self._item, b'pos')
self._anim.setEasingCurve(QEasingCurve.OutBounce)
- self._ui.easingCurvePicker.setCurrentRow(int(QEasingCurve.OutBounce))
+ self._ui.easingCurvePicker.setCurrentRow(0)
self.start_animation()
@@ -123,15 +123,8 @@ class Window(QWidget):
brush = QBrush(gradient)
- # The original C++ code uses undocumented calls to get the names of the
- # different curve types. We do the Python equivalant (but without
- # cheating)
- curve_types = [(n, c) for n, c in QEasingCurve.__dict__.items()
- if (isinstance(c, QEasingCurve.Type)
- and c != QEasingCurve.Custom
- and c != QEasingCurve.NCurveTypes
- and c != QEasingCurve.TCBSpline)]
- curve_types.sort(key=lambda ct: ct[1])
+ curve_types = [(f"QEasingCurve.{e.name}", e) for e in QEasingCurve.Type if e.value <= 40]
+
with QPainter(pix) as painter:
@@ -191,15 +184,15 @@ class Window(QWidget):
self._anim.setEasingCurve(curve_type)
self._anim.setCurrentTime(0)
- is_elastic = (curve_type >= QEasingCurve.InElastic
- and curve_type <= QEasingCurve.OutInElastic)
- is_bounce = (curve_type >= QEasingCurve.InBounce
- and curve_type <= QEasingCurve.OutInBounce)
+ is_elastic = (curve_type.value >= QEasingCurve.InElastic.value
+ and curve_type.value <= QEasingCurve.OutInElastic.value)
+ is_bounce = (curve_type.value >= QEasingCurve.InBounce.value
+ and curve_type.value <= QEasingCurve.OutInBounce.value)
self._ui.periodSpinBox.setEnabled(is_elastic)
self._ui.amplitudeSpinBox.setEnabled(is_elastic or is_bounce)
- self._ui.overshootSpinBox.setEnabled(curve_type >= QEasingCurve.InBack
- and curve_type <= QEasingCurve.OutInBack)
+ self._ui.overshootSpinBox.setEnabled(curve_type.value >= QEasingCurve.InBack.value
+ and curve_type.value <= QEasingCurve.OutInBack.value)
def path_changed(self, index):
self._anim.set_path_type(index)
diff --git a/examples/widgets/animation/easing/form.ui b/examples/widgets/animation/easing/form.ui
index 2397b1787..364aebeda 100644
--- a/examples/widgets/animation/easing/form.ui
+++ b/examples/widgets/animation/easing/form.ui
@@ -49,12 +49,27 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox_2">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
<property name="title">
<string>Path type</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
<widget class="QRadioButton" name="lineRadio">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>40</height>
+ </size>
+ </property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
<property name="text">
<string>Line</string>
</property>
@@ -62,17 +77,23 @@
<bool>true</bool>
</property>
<attribute name="buttonGroup">
- <string notr="true">buttonGroup</string>
+ <string>buttonGroup</string>
</attribute>
</widget>
</item>
- <item>
+ <item row="1" column="0">
<widget class="QRadioButton" name="circleRadio">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>40</height>
+ </size>
+ </property>
<property name="text">
<string>Circle</string>
</property>
<attribute name="buttonGroup">
- <string notr="true">buttonGroup</string>
+ <string>buttonGroup</string>
</attribute>
</widget>
</item>
@@ -96,6 +117,18 @@
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
<property name="text">
<string>Period</string>
</property>
@@ -106,6 +139,18 @@
<property name="enabled">
<bool>false</bool>
</property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
<property name="minimum">
<double>-1.000000000000000</double>
</property>
@@ -117,18 +162,17 @@
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Amplitude</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
+ <item row="2" column="1">
<widget class="QDoubleSpinBox" name="amplitudeSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
<property name="minimum">
<double>-1.000000000000000</double>
</property>
@@ -140,18 +184,30 @@
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="4" column="0">
<widget class="QLabel" name="label_3">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
<property name="text">
<string>Overshoot</string>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="4" column="1">
<widget class="QDoubleSpinBox" name="overshootSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
<property name="minimum">
<double>-1.000000000000000</double>
</property>
@@ -163,6 +219,19 @@
</property>
</widget>
</item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Amplitude</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -196,10 +265,6 @@
<resources/>
<connections/>
<buttongroups>
- <buttongroup name="buttonGroup">
- <property name="exclusive">
- <bool>true</bool>
- </property>
- </buttongroup>
+ <buttongroup name="buttonGroup"/>
</buttongroups>
</ui>
diff --git a/examples/widgets/animation/easing/ui_form.py b/examples/widgets/animation/easing/ui_form.py
index 07bfa8fb3..0ff7a1547 100644
--- a/examples/widgets/animation/easing/ui_form.py
+++ b/examples/widgets/animation/easing/ui_form.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
################################################################################
-## Form generated from reading UI file 'form.ui'
+## Form generated from reading UI file 'form2.ui'
##
-## Created by: Qt User Interface Compiler version 6.2.3
+## Created by: Qt User Interface Compiler version 6.4.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
@@ -47,23 +47,26 @@ class Ui_Form(object):
self.verticalLayout.setObjectName(u"verticalLayout")
self.groupBox_2 = QGroupBox(Form)
self.groupBox_2.setObjectName(u"groupBox_2")
- self.verticalLayout_2 = QVBoxLayout(self.groupBox_2)
- self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.groupBox_2.setMaximumSize(QSize(16777215, 16777215))
+ self.gridLayout_2 = QGridLayout(self.groupBox_2)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
self.lineRadio = QRadioButton(self.groupBox_2)
self.buttonGroup = QButtonGroup(Form)
self.buttonGroup.setObjectName(u"buttonGroup")
- self.buttonGroup.setExclusive(True)
self.buttonGroup.addButton(self.lineRadio)
self.lineRadio.setObjectName(u"lineRadio")
+ self.lineRadio.setMaximumSize(QSize(16777215, 40))
+ self.lineRadio.setLayoutDirection(Qt.LeftToRight)
self.lineRadio.setChecked(True)
- self.verticalLayout_2.addWidget(self.lineRadio)
+ self.gridLayout_2.addWidget(self.lineRadio, 0, 0, 1, 1)
self.circleRadio = QRadioButton(self.groupBox_2)
self.buttonGroup.addButton(self.circleRadio)
self.circleRadio.setObjectName(u"circleRadio")
+ self.circleRadio.setMaximumSize(QSize(16777215, 40))
- self.verticalLayout_2.addWidget(self.circleRadio)
+ self.gridLayout_2.addWidget(self.circleRadio, 1, 0, 1, 1)
self.verticalLayout.addWidget(self.groupBox_2)
@@ -80,45 +83,61 @@ class Ui_Form(object):
self.formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
self.label = QLabel(self.groupBox)
self.label.setObjectName(u"label")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ sizePolicy2.setHorizontalStretch(0)
+ sizePolicy2.setVerticalStretch(0)
+ sizePolicy2.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
+ self.label.setSizePolicy(sizePolicy2)
+ self.label.setMinimumSize(QSize(0, 30))
self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label)
self.periodSpinBox = QDoubleSpinBox(self.groupBox)
self.periodSpinBox.setObjectName(u"periodSpinBox")
self.periodSpinBox.setEnabled(False)
+ sizePolicy3 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.periodSpinBox.sizePolicy().hasHeightForWidth())
+ self.periodSpinBox.setSizePolicy(sizePolicy3)
+ self.periodSpinBox.setMinimumSize(QSize(0, 30))
self.periodSpinBox.setMinimum(-1.000000000000000)
self.periodSpinBox.setSingleStep(0.100000000000000)
self.periodSpinBox.setValue(-1.000000000000000)
self.formLayout.setWidget(0, QFormLayout.FieldRole, self.periodSpinBox)
- self.label_2 = QLabel(self.groupBox)
- self.label_2.setObjectName(u"label_2")
-
- self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2)
-
self.amplitudeSpinBox = QDoubleSpinBox(self.groupBox)
self.amplitudeSpinBox.setObjectName(u"amplitudeSpinBox")
self.amplitudeSpinBox.setEnabled(False)
+ self.amplitudeSpinBox.setMinimumSize(QSize(0, 30))
self.amplitudeSpinBox.setMinimum(-1.000000000000000)
self.amplitudeSpinBox.setSingleStep(0.100000000000000)
self.amplitudeSpinBox.setValue(-1.000000000000000)
- self.formLayout.setWidget(1, QFormLayout.FieldRole, self.amplitudeSpinBox)
+ self.formLayout.setWidget(2, QFormLayout.FieldRole, self.amplitudeSpinBox)
self.label_3 = QLabel(self.groupBox)
self.label_3.setObjectName(u"label_3")
+ self.label_3.setMinimumSize(QSize(0, 30))
- self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_3)
+ self.formLayout.setWidget(4, QFormLayout.LabelRole, self.label_3)
self.overshootSpinBox = QDoubleSpinBox(self.groupBox)
self.overshootSpinBox.setObjectName(u"overshootSpinBox")
self.overshootSpinBox.setEnabled(False)
+ self.overshootSpinBox.setMinimumSize(QSize(0, 30))
self.overshootSpinBox.setMinimum(-1.000000000000000)
self.overshootSpinBox.setSingleStep(0.100000000000000)
self.overshootSpinBox.setValue(-1.000000000000000)
- self.formLayout.setWidget(2, QFormLayout.FieldRole, self.overshootSpinBox)
+ self.formLayout.setWidget(4, QFormLayout.FieldRole, self.overshootSpinBox)
+
+ self.label_2 = QLabel(self.groupBox)
+ self.label_2.setObjectName(u"label_2")
+ self.label_2.setMinimumSize(QSize(0, 30))
+
+ self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_2)
self.verticalLayout.addWidget(self.groupBox)
@@ -132,11 +151,11 @@ class Ui_Form(object):
self.graphicsView = QGraphicsView(Form)
self.graphicsView.setObjectName(u"graphicsView")
- sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- sizePolicy2.setHorizontalStretch(0)
- sizePolicy2.setVerticalStretch(0)
- sizePolicy2.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth())
- self.graphicsView.setSizePolicy(sizePolicy2)
+ sizePolicy4 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth())
+ self.graphicsView.setSizePolicy(sizePolicy4)
self.gridLayout.addWidget(self.graphicsView, 1, 1, 1, 1)
@@ -153,7 +172,7 @@ class Ui_Form(object):
self.circleRadio.setText(QCoreApplication.translate("Form", u"Circle", None))
self.groupBox.setTitle(QCoreApplication.translate("Form", u"Properties", None))
self.label.setText(QCoreApplication.translate("Form", u"Period", None))
- self.label_2.setText(QCoreApplication.translate("Form", u"Amplitude", None))
self.label_3.setText(QCoreApplication.translate("Form", u"Overshoot", None))
+ self.label_2.setText(QCoreApplication.translate("Form", u"Amplitude", None))
# retranslateUi
diff --git a/examples/widgets/animation/states/states.py b/examples/widgets/animation/states/states.py
index fa37c7b09..9b85e8373 100644
--- a/examples/widgets/animation/states/states.py
+++ b/examples/widgets/animation/states/states.py
@@ -12,7 +12,7 @@ from PySide6.QtWidgets import (QApplication, QGraphicsLinearLayout,
QGraphicsObject, QGraphicsProxyWidget,
QGraphicsWidget, QGraphicsScene, QGraphicsView,
QGroupBox, QPushButton, QRadioButton,
- QTextEdit, QVBoxLayout, QWidget)
+ QTextEdit, QVBoxLayout)
from PySide6.QtStateMachine import QState, QStateMachine
diff --git a/examples/widgets/codeeditor/codeeditor.py b/examples/widgets/codeeditor/codeeditor.py
index 635dcb7a8..22f0b685b 100644
--- a/examples/widgets/codeeditor/codeeditor.py
+++ b/examples/widgets/codeeditor/codeeditor.py
@@ -69,11 +69,11 @@ class CodeEditor(QPlainTextEdit):
bottom = top + self.blockBoundingRect(block).height()
block_number += 1
- @Slot()
+ @Slot(int)
def update_line_number_area_width(self, newBlockCount):
self.setViewportMargins(self.line_number_area_width(), 0, 0, 0)
- @Slot()
+ @Slot(QRect, int)
def update_line_number_area(self, rect, dy):
if dy:
self.line_number_area.scroll(0, dy)
diff --git a/examples/widgets/desktop/screenshot/screenshot.py b/examples/widgets/desktop/screenshot/screenshot.py
index c818984dd..a5688da7a 100644
--- a/examples/widgets/desktop/screenshot/screenshot.py
+++ b/examples/widgets/desktop/screenshot/screenshot.py
@@ -5,7 +5,8 @@
import sys
-from PySide6.QtCore import QDir, QPoint, QRect, QStandardPaths, Qt, QTimer
+from PySide6.QtCore import (QDir, QPoint, QRect, QStandardPaths, Qt, QTimer,
+ Slot)
from PySide6.QtGui import QGuiApplication, QImageWriter
from PySide6.QtWidgets import (QApplication, QCheckBox, QDialog, QFileDialog,
QGridLayout, QGroupBox, QHBoxLayout, QLabel,
@@ -72,6 +73,7 @@ class Screenshot(QWidget):
if scaled_size != self.screenshot_label.pixmap().size():
self.update_screenshot_label()
+ @Slot()
def new_screenshot(self):
if self.hide_this_window_checkbox.isChecked():
self.hide()
@@ -79,6 +81,7 @@ class Screenshot(QWidget):
QTimer.singleShot(self.delay_spinbox.value() * 1000, self.shoot_screen)
+ @Slot()
def save_screenshot(self):
fmt = "png" # In order to avoid shadowing built-in format
initial_path = QStandardPaths.writableLocation(QStandardPaths.PicturesLocation)
@@ -127,6 +130,7 @@ class Screenshot(QWidget):
if self.hide_this_window_checkbox.isChecked():
self.show()
+ @Slot()
def update_checkbox(self):
if self.delay_spinbox.value() == 0:
self.hide_this_window_checkbox.setDisabled(True)
diff --git a/examples/widgets/systray/images/bad.png b/examples/widgets/desktop/systray/images/bad.png
index c8701a241..c8701a241 100644
--- a/examples/widgets/systray/images/bad.png
+++ b/examples/widgets/desktop/systray/images/bad.png
Binary files differ
diff --git a/examples/widgets/systray/images/heart.png b/examples/widgets/desktop/systray/images/heart.png
index cee1302b7..cee1302b7 100644
--- a/examples/widgets/systray/images/heart.png
+++ b/examples/widgets/desktop/systray/images/heart.png
Binary files differ
diff --git a/examples/widgets/systray/images/trash.png b/examples/widgets/desktop/systray/images/trash.png
index 4c24db926..4c24db926 100644
--- a/examples/widgets/systray/images/trash.png
+++ b/examples/widgets/desktop/systray/images/trash.png
Binary files differ
diff --git a/examples/widgets/systray/main.py b/examples/widgets/desktop/systray/main.py
index c52c51387..c52c51387 100644
--- a/examples/widgets/systray/main.py
+++ b/examples/widgets/desktop/systray/main.py
diff --git a/examples/widgets/systray/rc_systray.py b/examples/widgets/desktop/systray/rc_systray.py
index 9a6dec317..9a6dec317 100644
--- a/examples/widgets/systray/rc_systray.py
+++ b/examples/widgets/desktop/systray/rc_systray.py
diff --git a/examples/widgets/systray/systray.pyproject b/examples/widgets/desktop/systray/systray.pyproject
index eadfb0d7a..eadfb0d7a 100644
--- a/examples/widgets/systray/systray.pyproject
+++ b/examples/widgets/desktop/systray/systray.pyproject
diff --git a/examples/widgets/systray/systray.qrc b/examples/widgets/desktop/systray/systray.qrc
index a8b653584..a8b653584 100644
--- a/examples/widgets/systray/systray.qrc
+++ b/examples/widgets/desktop/systray/systray.qrc
diff --git a/examples/widgets/systray/window.py b/examples/widgets/desktop/systray/window.py
index c04a33e3a..c04a33e3a 100644
--- a/examples/widgets/systray/window.py
+++ b/examples/widgets/desktop/systray/window.py
diff --git a/examples/widgets/dialogs/classwizard/classwizard.py b/examples/widgets/dialogs/classwizard/classwizard.py
index d76eaa754..b657308e0 100644
--- a/examples/widgets/dialogs/classwizard/classwizard.py
+++ b/examples/widgets/dialogs/classwizard/classwizard.py
@@ -6,14 +6,12 @@ import os
from pathlib import Path
import sys
-from PySide6.QtCore import (QByteArray, QDir, QFile, QFileInfo,
- QRegularExpression, Qt, QUrl, Slot)
+from PySide6.QtCore import QDir, QFileInfo, QUrl, Slot
from PySide6.QtGui import QDesktopServices, QPixmap
from PySide6.QtWidgets import (QApplication, QComboBox, QCheckBox, QFormLayout,
- QFileDialog, QGroupBox, QGridLayout,
- QHBoxLayout, QLabel, QLineEdit, QMessageBox,
- QPushButton, QRadioButton, QToolButton,
- QVBoxLayout, QWizard, QWizardPage)
+ QFileDialog, QHBoxLayout, QLabel, QLineEdit,
+ QMessageBox, QToolButton, QVBoxLayout, QWizard,
+ QWizardPage)
from listchooser import ListChooser, PropertyChooser, SignalChooser
@@ -77,7 +75,7 @@ class ClassWizard(QWizard):
"""Overrides QWizard.nextId() to insert the property/signal
page in case the class is a QObject."""
idx = self.currentId()
- if self.currentId() == self._class_info_index:
+ if idx == self._class_info_index:
qobject = self.field('qobject')
return self._qobject_index if qobject else self._output_index
return super(ClassWizard, self).nextId()
@@ -177,7 +175,7 @@ class ClassWizard(QWizard):
block += '):\n'
if base_class:
- block += f' super().__init__('
+ block += ' super().__init__('
if qobject:
block += 'parent'
block += ')\n'
diff --git a/examples/widgets/dialogs/classwizard/listchooser.py b/examples/widgets/dialogs/classwizard/listchooser.py
index a51c963c4..bf15be88c 100644
--- a/examples/widgets/dialogs/classwizard/listchooser.py
+++ b/examples/widgets/dialogs/classwizard/listchooser.py
@@ -1,14 +1,13 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-from PySide6.QtCore import (QCoreApplication, QDir, QRegularExpression, Qt,
- Property, Slot)
+from PySide6.QtCore import QRegularExpression, Property, Slot
from PySide6.QtGui import QRegularExpressionValidator
from PySide6.QtWidgets import (QComboBox, QDialog, QDialogButtonBox,
QFormLayout, QGroupBox, QHBoxLayout,
- QInputDialog, QLineEdit, QListWidget,
+ QLineEdit, QListWidget,
QListWidgetItem, QPushButton, QVBoxLayout,
- QWidget)
+ )
DEFAULT_TYPES = ['int', 'str', 'PySide6.QtCore.QPoint', 'PySide6.QtCore.QRect',
diff --git a/examples/widgets/dialogs/findfiles/findfiles.py b/examples/widgets/dialogs/findfiles/findfiles.py
index 188888eee..7f2093c42 100644
--- a/examples/widgets/dialogs/findfiles/findfiles.py
+++ b/examples/widgets/dialogs/findfiles/findfiles.py
@@ -11,9 +11,9 @@ from PySide6.QtCore import (QCoreApplication, QDir, QFile, QFileInfo,
from PySide6.QtGui import QDesktopServices
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QComboBox,
QDialog, QFileDialog, QGridLayout, QHBoxLayout,
- QHeaderView, QLabel, QLineEdit, QProgressDialog,
+ QHeaderView, QLabel, QProgressDialog,
QPushButton, QSizePolicy, QTableWidget,
- QTableWidgetItem, QVBoxLayout, QWidget)
+ QTableWidgetItem)
class Window(QDialog):
diff --git a/examples/widgets/dialogs/standarddialogs/standarddialogs.py b/examples/widgets/dialogs/standarddialogs/standarddialogs.py
index 22f4b9eb6..94a5eec52 100644
--- a/examples/widgets/dialogs/standarddialogs/standarddialogs.py
+++ b/examples/widgets/dialogs/standarddialogs/standarddialogs.py
@@ -5,8 +5,8 @@
"""PySide6 port of the widgets/dialogs/standarddialogs example from Qt v5.x"""
import sys
-from PySide6.QtCore import QDir, QRect, Qt
-from PySide6.QtGui import QFont, QPalette, QScreen
+from PySide6.QtCore import QDir, Qt, Slot
+from PySide6.QtGui import QFont, QPalette
from PySide6.QtWidgets import (QApplication, QColorDialog, QCheckBox, QDialog,
QErrorMessage, QFontDialog, QFileDialog, QFrame,
QGridLayout, QGroupBox, QInputDialog, QLabel,
@@ -237,18 +237,21 @@ class Dialog(QDialog):
self.setWindowTitle("Standard Dialogs")
+ @Slot()
def set_integer(self):
i, ok = QInputDialog.getInt(self,
"QInputDialog.getInteger()", "Percentage:", 25, 0, 100, 1)
if ok:
self._integer_label.setText(f"{i}%")
+ @Slot()
def set_double(self):
d, ok = QInputDialog.getDouble(self, "QInputDialog.getDouble()",
"Amount:", 37.56, -10000, 10000, 2)
if ok:
self._double_label.setText(f"${d:g}")
+ @Slot()
def set_item(self):
items = ("Spring", "Summer", "Fall", "Winter")
@@ -257,6 +260,7 @@ class Dialog(QDialog):
if ok and item:
self._item_label.setText(item)
+ @Slot()
def set_text(self):
text, ok = QInputDialog.getText(self, "QInputDialog.getText()",
"User name:", QLineEdit.Normal,
@@ -264,12 +268,14 @@ class Dialog(QDialog):
if ok and text != '':
self._text_label.setText(text)
+ @Slot()
def set_multiline_text(self):
text, ok = QInputDialog.getMultiLineText(self, "QInputDialog::getMultiLineText()",
"Address:", "John Doe\nFreedom Street")
if ok and text != '':
self._multiline_text_label.setText(text)
+ @Slot()
def set_color(self):
options_value = self._color_options.value()
options = QColorDialog.ColorDialogOptions(options_value)
@@ -280,6 +286,7 @@ class Dialog(QDialog):
self._color_label.setPalette(QPalette(color))
self._color_label.setAutoFillBackground(True)
+ @Slot()
def set_font(self):
options_value = self._font_options.value()
options = QFontDialog.FontDialogOptions(options_value)
@@ -294,6 +301,7 @@ class Dialog(QDialog):
self._font_label.setText(font.key())
self._font_label.setFont(font)
+ @Slot()
def set_existing_directory(self):
options_value = self._file_options.value()
options = QFileDialog.Options(options_value) | QFileDialog.ShowDirsOnly
@@ -304,6 +312,7 @@ class Dialog(QDialog):
if directory:
self._directory_label.setText(directory)
+ @Slot()
def set_open_file_name(self):
options_value = self._file_options.value()
options = QFileDialog.Options(options_value)
@@ -315,6 +324,7 @@ class Dialog(QDialog):
if fileName:
self._open_file_name_label.setText(fileName)
+ @Slot()
def set_open_file_names(self):
options_value = self._file_options.value()
options = QFileDialog.Options(options_value)
@@ -327,6 +337,7 @@ class Dialog(QDialog):
file_list = ', '.join(files)
self._open_file_names_label.setText(f"[{file_list}]")
+ @Slot()
def set_save_file_name(self):
options_value = self._file_options.value()
options = QFileDialog.Options(options_value)
@@ -338,6 +349,7 @@ class Dialog(QDialog):
if fileName:
self._save_file_name_label.setText(fileName)
+ @Slot()
def critical_message(self):
reply = QMessageBox.critical(self, "QMessageBox.critical()",
Dialog.MESSAGE,
@@ -349,6 +361,7 @@ class Dialog(QDialog):
else:
self._critical_label.setText("Ignore")
+ @Slot()
def information_message(self):
reply = QMessageBox.information(self,
"QMessageBox.information()", Dialog.MESSAGE)
@@ -357,6 +370,7 @@ class Dialog(QDialog):
else:
self._information_label.setText("Escape")
+ @Slot()
def question_message(self):
reply = QMessageBox.question(self, "QMessageBox.question()",
Dialog.MESSAGE,
@@ -368,6 +382,7 @@ class Dialog(QDialog):
else:
self._question_label.setText("Cancel")
+ @Slot()
def warning_message(self):
msg_box = QMessageBox(QMessageBox.Warning,
"QMessageBox.warning()", Dialog.MESSAGE,
@@ -379,6 +394,7 @@ class Dialog(QDialog):
else:
self._warning_label.setText("Continue")
+ @Slot()
def error_message(self):
self._error_message_dialog.showMessage("This dialog shows and remembers "
"error messages. If the checkbox is checked (as it is by "
diff --git a/examples/widgets/dialogs/trivialwizard/trivialwizard.py b/examples/widgets/dialogs/trivialwizard/trivialwizard.py
index a0baa6ba4..0eb9fb567 100644
--- a/examples/widgets/dialogs/trivialwizard/trivialwizard.py
+++ b/examples/widgets/dialogs/trivialwizard/trivialwizard.py
@@ -7,7 +7,7 @@
import sys
from PySide6.QtWidgets import (QApplication, QFormLayout, QLabel, QLineEdit,
- QVBoxLayout, QWidget, QWizardPage, QWizard)
+ QVBoxLayout, QWizardPage, QWizard)
def create_intro_page():
diff --git a/examples/widgets/draganddrop/dropsite/doc/dropsite.rst b/examples/widgets/draganddrop/dropsite/doc/dropsite.rst
new file mode 100644
index 000000000..8d6c42bc8
--- /dev/null
+++ b/examples/widgets/draganddrop/dropsite/doc/dropsite.rst
@@ -0,0 +1,8 @@
+Drop Site Example
+=================
+
+The Drop Site example shows how to distinguish the various MIME formats
+available in a drag and drop operation.
+
+It accepts drops from other applications and displays the MIME formats
+provided by the drag object.
diff --git a/examples/widgets/draganddrop/dropsite/droparea.py b/examples/widgets/draganddrop/dropsite/droparea.py
new file mode 100644
index 000000000..efc4614f0
--- /dev/null
+++ b/examples/widgets/draganddrop/dropsite/droparea.py
@@ -0,0 +1,67 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QMimeData, Qt, Slot, Signal
+from PySide6.QtGui import QPalette, QPixmap
+from PySide6.QtWidgets import QFrame, QLabel
+
+
+class DropArea(QLabel):
+
+ changed = Signal(QMimeData)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setMinimumSize(200, 200)
+ self.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel)
+ self.setAlignment(Qt.AlignCenter)
+ self.setAcceptDrops(True)
+ self.setAutoFillBackground(True)
+ self.clear()
+
+ def dragEnterEvent(self, event):
+ self.setText("<drop content>")
+ self.setBackgroundRole(QPalette.Highlight)
+
+ event.acceptProposedAction()
+ self.changed.emit(event.mimeData())
+
+ def dragMoveEvent(self, event):
+ event.acceptProposedAction()
+
+ def dropEvent(self, event):
+ mime_data = event.mimeData()
+
+ if mime_data.hasImage():
+ self.setPixmap(QPixmap(mime_data.imageData()))
+ elif mime_data.hasFormat("text/markdown"):
+ self.setText(mime_data.data("text/markdown"))
+ self.setTextFormat(Qt.MarkdownText)
+ elif mime_data.hasHtml():
+ self.setText(mime_data.html())
+ self.setTextFormat(Qt.RichText)
+ elif mime_data.hasText():
+ self.setText(mime_data.text())
+ self.setTextFormat(Qt.PlainText)
+ elif mime_data.hasUrls():
+ url_list = mime_data.urls()
+ text = ""
+ for i in range(0, min(len(url_list), 32)):
+ text += url_list[i].path() + "\n"
+ self.setText(text)
+ else:
+ self.setText("Cannot display data")
+
+ self.setBackgroundRole(QPalette.Dark)
+ event.acceptProposedAction()
+
+ def dragLeaveEvent(self, event):
+ self.clear()
+ event.accept()
+
+ @Slot()
+ def clear(self):
+ self.setText("<drop content>")
+ self.setBackgroundRole(QPalette.Dark)
+
+ self.changed.emit(None)
diff --git a/examples/widgets/draganddrop/dropsite/dropsite.pyproject b/examples/widgets/draganddrop/dropsite/dropsite.pyproject
new file mode 100644
index 000000000..0173d5cb9
--- /dev/null
+++ b/examples/widgets/draganddrop/dropsite/dropsite.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "droparea.py", "dropsitewindow.py"]
+}
diff --git a/examples/widgets/draganddrop/dropsite/dropsitewindow.py b/examples/widgets/draganddrop/dropsite/dropsitewindow.py
new file mode 100644
index 000000000..5427d520d
--- /dev/null
+++ b/examples/widgets/draganddrop/dropsite/dropsitewindow.py
@@ -0,0 +1,115 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import re
+from PySide6.QtCore import QMimeData, Qt, Slot
+from PySide6.QtGui import QGuiApplication
+from PySide6.QtWidgets import (QAbstractItemView, QPushButton,
+ QDialogButtonBox, QLabel,
+ QTableWidget, QTableWidgetItem,
+ QVBoxLayout, QWidget)
+
+from droparea import DropArea
+
+DESCRIPTION = """This example accepts drags from other applications and
+displays the MIME types provided by the drag object."""
+
+
+_WHITESPACE_PATTERN = re.compile(r"\s+")
+
+
+def simplify_whitespace(s):
+ return _WHITESPACE_PATTERN.sub(" ", s).strip()
+
+
+class DropSiteWindow(QWidget):
+
+ def __init__(self):
+ super().__init__()
+ drop_area = DropArea()
+ abstract_label = QLabel()
+ self._formats_table = QTableWidget()
+
+ button_box = QDialogButtonBox()
+ abstract_label = QLabel(DESCRIPTION)
+ abstract_label.setWordWrap(True)
+ abstract_label.adjustSize()
+
+ drop_area = DropArea()
+ drop_area.changed.connect(self.update_formats_table)
+
+ self._formats_table = QTableWidget()
+ self._formats_table.setColumnCount(2)
+ self._formats_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
+ self._formats_table.setHorizontalHeaderLabels(["Format", "Content"])
+ self._formats_table.horizontalHeader().setStretchLastSection(True)
+
+ clear_button = QPushButton("Clear")
+ self._copy_button = QPushButton("Copy")
+ quit_button = QPushButton("Quit")
+
+ button_box = QDialogButtonBox()
+ button_box.addButton(clear_button, QDialogButtonBox.ActionRole)
+ button_box.addButton(self._copy_button, QDialogButtonBox.ActionRole)
+ self._copy_button.setVisible(False)
+
+ button_box.addButton(quit_button, QDialogButtonBox.RejectRole)
+
+ quit_button.clicked.connect(self.close)
+ clear_button.clicked.connect(drop_area.clear)
+ self._copy_button.clicked.connect(self.copy)
+
+ main_layout = QVBoxLayout(self)
+ main_layout.addWidget(abstract_label)
+ main_layout.addWidget(drop_area)
+ main_layout.addWidget(self._formats_table)
+ main_layout.addWidget(button_box)
+
+ self.setWindowTitle("Drop Site")
+ self.resize(700, 500)
+
+ @Slot(QMimeData)
+ def update_formats_table(self, mime_data):
+ self._formats_table.setRowCount(0)
+ self._copy_button.setEnabled(False)
+ if not mime_data:
+ return
+
+ for format in mime_data.formats():
+ format_item = QTableWidgetItem(format)
+ format_item.setFlags(Qt.ItemIsEnabled)
+ format_item.setTextAlignment(Qt.AlignTop | Qt.AlignLeft)
+
+ if format == "text/plain":
+ text = simplify_whitespace(mime_data.text())
+ elif format == "text/markdown":
+ text = mime_data.data("text/markdown").data().decode("utf8")
+ elif format == "text/html":
+ text = simplify_whitespace(mime_data.html())
+ elif format == "text/uri-list":
+ url_list = mime_data.urls()
+ text = ""
+ for i in range(0, min(len(url_list), 32)):
+ text += url_list[i].toString() + " "
+ else:
+ data = mime_data.data(format)
+ if data.size() > 32:
+ data.truncate(32)
+ text = data.toHex(" ").data().decode("utf8").upper()
+
+ row = self._formats_table.rowCount()
+ self._formats_table.insertRow(row)
+ self._formats_table.setItem(row, 0, QTableWidgetItem(format))
+ self._formats_table.setItem(row, 1, QTableWidgetItem(text))
+
+ self._formats_table.resizeColumnToContents(0)
+ self._copy_button.setEnabled(self._formats_table.rowCount() > 0)
+
+ @Slot()
+ def copy(self):
+ text = ""
+ for row in range(0, self._formats_table.rowCount()):
+ c1 = self._formats_table.item(row, 0).text()
+ c2 = self._formats_table.item(row, 1).text()
+ text += f"{c1}: {c2}\n"
+ QGuiApplication.clipboard().setText(text)
diff --git a/examples/widgets/draganddrop/dropsite/main.py b/examples/widgets/draganddrop/dropsite/main.py
new file mode 100644
index 000000000..bce476a61
--- /dev/null
+++ b/examples/widgets/draganddrop/dropsite/main.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 dropsitewindow import DropSiteWindow
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = DropSiteWindow()
+ window.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/effects/lighting/lighting.py b/examples/widgets/effects/lighting/lighting.py
index 5328058fe..fe200357d 100644
--- a/examples/widgets/effects/lighting/lighting.py
+++ b/examples/widgets/effects/lighting/lighting.py
@@ -10,7 +10,7 @@ from PySide6.QtGui import (QBrush, QColor, QLinearGradient, QPainter, QPen,
QPixmap, QRadialGradient)
from PySide6.QtWidgets import (QApplication, QFrame, QGraphicsDropShadowEffect,
QGraphicsEllipseItem, QGraphicsRectItem,
- QGraphicsScene, QGraphicsView, QWidget)
+ QGraphicsScene, QGraphicsView)
class Lighting(QGraphicsView):
diff --git a/examples/widgets/gettext/main.py b/examples/widgets/gettext/main.py
index 2e402d49c..85695728d 100644
--- a/examples/widgets/gettext/main.py
+++ b/examples/widgets/gettext/main.py
@@ -5,9 +5,9 @@ from pathlib import Path
import gettext
import sys
-from PySide6.QtCore import QItemSelection, QLocale, Qt, Slot
+from PySide6.QtCore import QItemSelection, Slot
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QListWidget,
- QMainWindow, QWidget)
+ QMainWindow)
_ = None
diff --git a/examples/widgets/graphicsview/anchorlayout/anchorlayout.py b/examples/widgets/graphicsview/anchorlayout/anchorlayout.py
index 0fbc801ae..d6e8e57b2 100644
--- a/examples/widgets/graphicsview/anchorlayout/anchorlayout.py
+++ b/examples/widgets/graphicsview/anchorlayout/anchorlayout.py
@@ -8,7 +8,7 @@ from PySide6.QtCore import QSizeF, Qt
from PySide6.QtWidgets import (QApplication, QGraphicsAnchorLayout,
QGraphicsProxyWidget, QGraphicsScene,
QGraphicsView, QGraphicsWidget,
- QPushButton, QSizePolicy, QWidget)
+ QPushButton, QSizePolicy)
def create_item(minimum, preferred, maximum, name):
diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene.py b/examples/widgets/graphicsview/diagramscene/diagramscene.py
index e653285c4..ea39cf938 100644
--- a/examples/widgets/graphicsview/diagramscene/diagramscene.py
+++ b/examples/widgets/graphicsview/diagramscene/diagramscene.py
@@ -6,12 +6,11 @@ import math
import sys
from PySide6.QtCore import (QLineF, QPointF, QRect, QRectF, QSize, QSizeF, Qt,
- Signal)
-from PySide6.QtGui import (QAction, QColor, QFont, QIcon, QIntValidator,
+ Signal, Slot)
+from PySide6.QtGui import (QAction, QBrush, QColor, QFont, QIcon, QIntValidator,
QPainter, QPainterPath, QPen, QPixmap, QPolygonF)
-from PySide6.QtWidgets import (QApplication, QButtonGroup, QComboBox,
- QFontComboBox, QGraphicsAnchorLayout,
- QGraphicsItem, QGraphicsLineItem,
+from PySide6.QtWidgets import (QAbstractButton, QApplication, QButtonGroup,
+ QComboBox, QFontComboBox, QGraphicsItem, QGraphicsLineItem,
QGraphicsPolygonItem, QGraphicsTextItem,
QGraphicsScene, QGraphicsView, QGridLayout,
QHBoxLayout, QLabel, QMainWindow, QMenu,
@@ -382,6 +381,7 @@ class MainWindow(QMainWindow):
self.setCentralWidget(self.widget)
self.setWindowTitle("Diagramscene")
+ @Slot(QAbstractButton)
def background_button_group_clicked(self, button):
buttons = self._background_button_group.buttons()
for myButton in buttons:
@@ -401,6 +401,7 @@ class MainWindow(QMainWindow):
self.scene.update()
self.view.update()
+ @Slot(int)
def button_group_clicked(self, idx):
buttons = self._button_group.buttons()
for button in buttons:
@@ -413,15 +414,18 @@ class MainWindow(QMainWindow):
self.scene.set_item_type(idx)
self.scene.set_mode(DiagramScene.InsertItem)
+ @Slot()
def delete_item(self):
for item in self.scene.selectedItems():
if isinstance(item, DiagramItem):
item.remove_arrows()
self.scene.removeItem(item)
+ @Slot(int)
def pointer_group_clicked(self, i):
self.scene.set_mode(self._pointer_type_group.checkedId())
+ @Slot()
def bring_to_front(self):
if not self.scene.selectedItems():
return
@@ -435,6 +439,7 @@ class MainWindow(QMainWindow):
z_value = item.zValue() + 0.1
selected_item.setZValue(z_value)
+ @Slot()
def send_to_back(self):
if not self.scene.selectedItems():
return
@@ -448,21 +453,26 @@ class MainWindow(QMainWindow):
z_value = item.zValue() - 0.1
selected_item.setZValue(z_value)
+ @Slot(QGraphicsPolygonItem)
def item_inserted(self, item):
self._pointer_type_group.button(DiagramScene.MoveItem).setChecked(True)
self.scene.set_mode(self._pointer_type_group.checkedId())
self._button_group.button(item.diagram_type).setChecked(False)
+ @Slot(QGraphicsTextItem)
def text_inserted(self, item):
self._button_group.button(self.insert_text_button).setChecked(False)
self.scene.set_mode(self._pointer_type_group.checkedId())
+ @Slot(QFont)
def current_font_changed(self, font):
self.handle_font_change()
+ @Slot(int)
def font_size_changed(self, font):
self.handle_font_change()
+ @Slot(str)
def scene_scale_changed(self, scale):
new_scale = int(scale[:-1]) / 100.0
old_matrix = self.view.transform()
@@ -470,6 +480,7 @@ class MainWindow(QMainWindow):
self.view.translate(old_matrix.dx(), old_matrix.dy())
self.view.scale(new_scale, new_scale)
+ @Slot()
def text_color_changed(self):
self._text_action = self.sender()
self._font_color_tool_button.setIcon(self.create_color_tool_button_icon(
@@ -477,6 +488,7 @@ class MainWindow(QMainWindow):
QColor(self._text_action.data())))
self.text_button_triggered()
+ @Slot()
def item_color_changed(self):
self._fill_action = self.sender()
self._fill_color_tool_button.setIcon(self.create_color_tool_button_icon(
@@ -484,6 +496,7 @@ class MainWindow(QMainWindow):
QColor(self._fill_action.data())))
self.fill_button_triggered()
+ @Slot()
def line_color_changed(self):
self._line_action = self.sender()
self._line_color_tool_button.setIcon(self.create_color_tool_button_icon(
@@ -491,15 +504,19 @@ class MainWindow(QMainWindow):
QColor(self._line_action.data())))
self.line_button_triggered()
+ @Slot()
def text_button_triggered(self):
self.scene.set_text_color(QColor(self._text_action.data()))
+ @Slot()
def fill_button_triggered(self):
self.scene.set_item_color(QColor(self._fill_action.data()))
+ @Slot()
def line_button_triggered(self):
self.scene.set_line_color(QColor(self._line_action.data()))
+ @Slot()
def handle_font_change(self):
font = self._font_combo.currentFont()
font.setPointSize(int(self._font_size_combo.currentText()))
@@ -512,6 +529,7 @@ class MainWindow(QMainWindow):
self.scene.set_font(font)
+ @Slot(QGraphicsItem)
def item_selected(self, item):
font = item.font()
color = item.defaultTextColor()
@@ -521,6 +539,7 @@ class MainWindow(QMainWindow):
self._italic_action.setChecked(font.italic())
self._underline_action.setChecked(font.underline())
+ @Slot()
def about(self):
QMessageBox.about(self, "About Diagram Scene",
"The <b>Diagram Scene</b> example shows use of the graphics framework.")
diff --git a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py
index 6eba05acc..0bfd3e0db 100644
--- a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py
+++ b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py
@@ -11,7 +11,7 @@ from PySide6.QtGui import (QBrush, QColor, QDrag, QImage, QPainter, QPixmap,
QPen, QTransform)
from PySide6.QtWidgets import (QApplication, QGraphicsItem,
QGraphicsItemAnimation, QGraphicsScene,
- QGraphicsView, QWidget)
+ QGraphicsView)
import dragdroprobot_rc
diff --git a/examples/widgets/graphicsview/elasticnodes/elasticnodes.py b/examples/widgets/graphicsview/elasticnodes/elasticnodes.py
index b2f9eb067..58d9d4a90 100644
--- a/examples/widgets/graphicsview/elasticnodes/elasticnodes.py
+++ b/examples/widgets/graphicsview/elasticnodes/elasticnodes.py
@@ -8,10 +8,10 @@ import math
from PySide6.QtCore import (QLineF, QPointF, QRandomGenerator, QRectF, QSizeF,
Qt, qAbs)
-from PySide6.QtGui import (QColor, QBrush, QPainter, QPainterPath, QPen,
+from PySide6.QtGui import (QColor, QBrush, QLinearGradient, QPainter, QPainterPath, QPen,
QPolygonF, QRadialGradient)
from PySide6.QtWidgets import (QApplication, QGraphicsItem, QGraphicsScene,
- QGraphicsView, QStyle, QWidget)
+ QGraphicsView, QStyle)
def random(boundary):
@@ -129,7 +129,7 @@ class Node(QGraphicsItem):
self._new_pos = QPointF()
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
- self.setCacheMode(self.DeviceCoordinateCache)
+ self.setCacheMode(QGraphicsItem.DeviceCoordinateCache)
self.setZValue(-1)
def item_type(self):
diff --git a/examples/widgets/imageviewer/imageviewer.py b/examples/widgets/imageviewer/imageviewer.py
index 1afe0b416..ded7f246a 100644
--- a/examples/widgets/imageviewer/imageviewer.py
+++ b/examples/widgets/imageviewer/imageviewer.py
@@ -3,12 +3,12 @@
from PySide6.QtPrintSupport import QPrintDialog, QPrinter
from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog, QLabel,
- QMainWindow, QMenuBar, QMessageBox, QScrollArea,
- QScrollBar, QSizePolicy, QStatusBar)
-from PySide6.QtGui import (QAction, QClipboard, QColorSpace, QGuiApplication,
- QImage, QImageReader, QImageWriter, QKeySequence,
- QPalette, QPainter, QPixmap, QScreen)
-from PySide6.QtCore import QDir, QMimeData, QStandardPaths, Qt, Slot
+ QMainWindow, QMessageBox, QScrollArea,
+ QSizePolicy)
+from PySide6.QtGui import (QColorSpace, QGuiApplication,
+ QImageReader, QImageWriter, QKeySequence,
+ QPalette, QPainter, QPixmap)
+from PySide6.QtCore import QDir, QStandardPaths, Qt, Slot
ABOUT = """<p>The <b>Image Viewer</b> example shows how to combine QLabel
diff --git a/examples/widgets/itemviews/address_book/address_book.py b/examples/widgets/itemviews/address_book/address_book.py
index 2121f2783..2e1f6b9b0 100644
--- a/examples/widgets/itemviews/address_book/address_book.py
+++ b/examples/widgets/itemviews/address_book/address_book.py
@@ -2,6 +2,7 @@
# 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
from PySide6.QtWidgets import (QMainWindow, QFileDialog, QApplication)
@@ -60,11 +61,13 @@ class MainWindow(QMainWindow):
#
# In PySide6, these functions return a tuple: (filename, filter)
+ @Slot()
def open_file(self):
filename, _ = QFileDialog.getOpenFileName(self)
if filename:
self._address_widget.read_from_file(filename)
+ @Slot()
def save_file(self):
filename, _ = QFileDialog.getSaveFileName(self)
if filename:
diff --git a/examples/widgets/itemviews/address_book/addresswidget.py b/examples/widgets/itemviews/address_book/addresswidget.py
index 7987ae3cd..ab1330e48 100644
--- a/examples/widgets/itemviews/address_book/addresswidget.py
+++ b/examples/widgets/itemviews/address_book/addresswidget.py
@@ -7,7 +7,7 @@ try:
except ImportError:
import pickle
-from PySide6.QtCore import (Qt, Signal, QRegularExpression, QModelIndex,
+from PySide6.QtCore import (Qt, Signal, Slot, QRegularExpression, QModelIndex,
QItemSelection, QSortFilterProxyModel)
from PySide6.QtWidgets import QTabWidget, QMessageBox, QTableView, QAbstractItemView
@@ -35,6 +35,7 @@ class AddressWidget(QTabWidget):
self.setup_tabs()
+ @Slot()
def add_entry(self, name=None, address=None):
""" Add an entry to the addressbook. """
if name is None and address is None:
@@ -83,6 +84,7 @@ class AddressWidget(QTabWidget):
table_view = self.currentWidget()
table_view.resizeRowToContents(ix.row())
+ @Slot()
def edit_entry(self):
""" Edit an entry in the addressbook. """
table_view = self.currentWidget()
@@ -115,6 +117,7 @@ class AddressWidget(QTabWidget):
ix = self._table_model.index(row, 1, QModelIndex())
self._table_model.setData(ix, new_address, Qt.EditRole)
+ @Slot()
def remove_entry(self):
""" Remove an entry from the addressbook. """
table_view = self.currentWidget()
diff --git a/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py b/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py
index a61a76cb8..834237404 100644
--- a/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py
+++ b/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py
@@ -4,7 +4,7 @@
import sys
from PySide6.QtCore import (QDate, QDateTime, QRegularExpression,
- QSortFilterProxyModel, QTime, Qt)
+ QSortFilterProxyModel, QTime, Qt, Slot)
from PySide6.QtGui import QStandardItemModel
from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QGridLayout,
QGroupBox, QHBoxLayout, QLabel, QLineEdit,
@@ -102,6 +102,7 @@ class Window(QWidget):
self._proxy_model.setSourceModel(model)
self._source_view.setModel(model)
+ @Slot()
def filter_reg_exp_changed(self):
syntax_nr = self._filter_syntax_combo_box.currentData()
pattern = self._filter_pattern_line_edit.text()
@@ -117,9 +118,11 @@ class Window(QWidget):
reg_exp.setPatternOptions(options)
self._proxy_model.setFilterRegularExpression(reg_exp)
+ @Slot()
def filter_column_changed(self):
self._proxy_model.setFilterKeyColumn(self._filter_column_combo_box.currentIndex())
+ @Slot()
def sort_changed(self):
if self._sort_case_sensitivity_check_box.isChecked():
case_sensitivity = Qt.CaseSensitive
diff --git a/examples/widgets/itemviews/dirview/dirview.py b/examples/widgets/itemviews/dirview/dirview.py
new file mode 100644
index 000000000..aa1e62185
--- /dev/null
+++ b/examples/widgets/itemviews/dirview/dirview.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2020 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+from PySide6.QtWidgets import (QApplication, QFileSystemModel,
+ QFileIconProvider, QScroller, QTreeView)
+from PySide6.QtCore import QDir
+
+"""PySide6 port of the widgets/itemviews/dirview example from Qt v6.x"""
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ name = "Dir View"
+ argument_parser = ArgumentParser(description=name,
+ formatter_class=RawTextHelpFormatter)
+ argument_parser.add_argument("--no-custom", "-c", action="store_true",
+ help="Set QFileSystemModel.DontUseCustomDirectoryIcons")
+ argument_parser.add_argument("--no-watch", "-w", action="store_true",
+ help="Set QFileSystemModel.DontWatch")
+ argument_parser.add_argument("directory",
+ help="The directory to start in.",
+ nargs='?', type=str)
+ options = argument_parser.parse_args()
+ root_path = options.directory
+
+ model = QFileSystemModel()
+ icon_provider = QFileIconProvider()
+ model.setIconProvider(icon_provider)
+ model.setRootPath("")
+ if options.no_custom:
+ model.setOption(QFileSystemModel.DontUseCustomDirectoryIcons)
+ if options.no_watch:
+ model.setOption(QFileSystemModel.DontWatchForChanges)
+ tree = QTreeView()
+ tree.setModel(model)
+ if root_path:
+ root_index = model.index(QDir.cleanPath(root_path))
+ if root_index.isValid():
+ tree.setRootIndex(root_index)
+
+ # Demonstrating look and feel features
+ tree.setAnimated(False)
+ tree.setIndentation(20)
+ tree.setSortingEnabled(True)
+ availableSize = tree.screen().availableGeometry().size()
+ tree.resize(availableSize / 2)
+ tree.setColumnWidth(0, tree.width() / 3)
+
+ # Make it flickable on touchscreens
+ QScroller.grabGesture(tree, QScroller.ScrollerGestureType.TouchGesture)
+
+ tree.setWindowTitle(name)
+ tree.show()
+
+ sys.exit(app.exec())
+
diff --git a/examples/widgets/itemviews/dirview/dirview.pyproject b/examples/widgets/itemviews/dirview/dirview.pyproject
new file mode 100644
index 000000000..9470083c9
--- /dev/null
+++ b/examples/widgets/itemviews/dirview/dirview.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["dirview.py"]
+}
diff --git a/examples/widgets/itemviews/dirview/doc/dirview.rst b/examples/widgets/itemviews/dirview/doc/dirview.rst
new file mode 100644
index 000000000..7044fdf58
--- /dev/null
+++ b/examples/widgets/itemviews/dirview/doc/dirview.rst
@@ -0,0 +1,5 @@
+Dir View Example
+================
+
+The Dir View example shows a tree view of the local file system. It uses the
+QFileSystemModel class to provide file and directory information.
diff --git a/examples/widgets/itemviews/editabletreemodel/treemodel.py b/examples/widgets/itemviews/editabletreemodel/treemodel.py
index 58e405c12..a58572fca 100644
--- a/examples/widgets/itemviews/editabletreemodel/treemodel.py
+++ b/examples/widgets/itemviews/editabletreemodel/treemodel.py
@@ -2,14 +2,11 @@
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-from PySide6.QtCore import QModelIndex, Qt, QAbstractItemModel, Signal
+from PySide6.QtCore import QModelIndex, Qt, QAbstractItemModel
from treeitem import TreeItem
class TreeModel(QAbstractItemModel):
- # Define signals
- dataChanged = Signal(QModelIndex, QModelIndex, object)
- headerDataChanged = Signal(Qt.Orientation, int, int)
def __init__(self, headers: list, data: str, parent=None):
super().__init__(parent)
@@ -154,9 +151,7 @@ class TreeModel(QAbstractItemModel):
result: bool = self.root_item.set_data(section, value)
if result:
- # todo: Check if emit headerDataChanged signal is correct
- # emit headerDataChanged(orientation, section, section)
- self.headerDataChanged(orientation, section, section)
+ self.headerDataChanged.emit(orientation, section, section)
return result
diff --git a/examples/widgets/itemviews/fetchmore/fetchmore.py b/examples/widgets/itemviews/fetchmore/fetchmore.py
index 08617edad..ecee86e38 100644
--- a/examples/widgets/itemviews/fetchmore/fetchmore.py
+++ b/examples/widgets/itemviews/fetchmore/fetchmore.py
@@ -11,9 +11,8 @@ down the list to see the model being populated on demand.
import sys
-from PySide6.QtCore import (QAbstractListModel, QDir, QFileInfo, QLibraryInfo,
+from PySide6.QtCore import (QAbstractListModel, QDir,
QModelIndex, Qt, Signal, Slot)
-from PySide6.QtGui import QPalette
from PySide6.QtWidgets import (QApplication, QFileIconProvider, QListView,
QPlainTextEdit, QSizePolicy, QVBoxLayout,
QWidget)
@@ -113,7 +112,7 @@ class Window(QWidget):
self.setWindowTitle("Fetch More Example")
- @Slot(str, int, int)
+ @Slot(str,int,int,int)
def update_log(self, path, start, number, total):
native_path = QDir.toNativeSeparators(path)
last = start + number - 1
diff --git a/examples/widgets/itemviews/spinboxdelegate/doc/spinboxdelegate.rst b/examples/widgets/itemviews/spinboxdelegate/doc/spinboxdelegate.rst
new file mode 100644
index 000000000..12e505207
--- /dev/null
+++ b/examples/widgets/itemviews/spinboxdelegate/doc/spinboxdelegate.rst
@@ -0,0 +1,5 @@
+SpinBox Delegate Example
+=========================
+
+A simple example that shows how a view can use a custom delegate to edit
+data obtained from a model.
diff --git a/examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.py b/examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.py
new file mode 100644
index 000000000..266b8c1e1
--- /dev/null
+++ b/examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.py
@@ -0,0 +1,78 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtWidgets import (QApplication, QStyledItemDelegate, QSpinBox,
+ QTableView)
+from PySide6.QtGui import QStandardItemModel, Qt
+from PySide6.QtCore import QModelIndex
+
+"""PySide6 port of the widgets/itemviews/spinboxdelegate from Qt v6.x"""
+
+#! [0]
+class SpinBoxDelegate(QStyledItemDelegate):
+ """A delegate that allows the user to change integer values from the model
+ using a spin box widget. """
+
+#! [0]
+ def __init__(self, parent=None):
+ super().__init__(parent)
+#! [0]
+
+#! [1]
+ def createEditor(self, parent, option, index):
+ editor = QSpinBox(parent)
+ editor.setFrame(False)
+ editor.setMinimum(0)
+ editor.setMaximum(100)
+ return editor
+#! [1]
+
+#! [2]
+ def setEditorData(self, editor, index):
+ value = index.model().data(index, Qt.EditRole)
+ editor.setValue(value)
+#! [2]
+
+#! [3]
+ def setModelData(self, editor, model, index):
+ editor.interpretText()
+ value = editor.value()
+ model.setData(index, value, Qt.EditRole)
+#! [3]
+
+#! [4]
+ def updateEditorGeometry(self, editor, option, index):
+ editor.setGeometry(option.rect)
+#! [4]
+
+
+#! [main0]
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ model= QStandardItemModel(4, 2)
+ tableView = QTableView()
+ tableView.setModel(model)
+
+ delegate = SpinBoxDelegate()
+ tableView.setItemDelegate(delegate)
+#! [main0]
+
+ tableView.horizontalHeader().setStretchLastSection(True)
+
+#! [main1]
+ for row in range(4):
+ for column in range(2):
+ index = model.index(row, column, QModelIndex())
+ value = (row + 1) * (column + 1)
+ model.setData(index, value)
+#! [main1] //# [main2]
+#! [main2]
+
+#! [main3]
+ tableView.setWindowTitle("Spin Box Delegate")
+ tableView.show()
+ sys.exit(app.exec())
+#! [main3]
diff --git a/examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.pyproject b/examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.pyproject
new file mode 100644
index 000000000..70616905c
--- /dev/null
+++ b/examples/widgets/itemviews/spinboxdelegate/spinboxdelegate.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["spinboxdelegate.py"]
+}
diff --git a/examples/widgets/itemviews/spreadsheet/doc/spreadsheet.png b/examples/widgets/itemviews/spreadsheet/doc/spreadsheet.png
new file mode 100644
index 000000000..ae7dde24b
--- /dev/null
+++ b/examples/widgets/itemviews/spreadsheet/doc/spreadsheet.png
Binary files differ
diff --git a/examples/widgets/itemviews/spreadsheet/doc/spreadsheet.rst b/examples/widgets/itemviews/spreadsheet/doc/spreadsheet.rst
new file mode 100644
index 000000000..c0839b232
--- /dev/null
+++ b/examples/widgets/itemviews/spreadsheet/doc/spreadsheet.rst
@@ -0,0 +1,10 @@
+Spreadsheet example
+===================
+
+The Spreadsheet example shows how a table view can be used to create a simple
+spreadsheet application. Custom delegates are used to render different types of
+data in distinctive colors.
+
+.. image:: spreadsheet.png
+ :width: 400
+ :alt: Spreadsheet screenshot
diff --git a/examples/widgets/itemviews/spreadsheet/main.py b/examples/widgets/itemviews/spreadsheet/main.py
new file mode 100644
index 000000000..0ecc5ec23
--- /dev/null
+++ b/examples/widgets/itemviews/spreadsheet/main.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QApplication, QLayout
+
+from spreadsheet import SpreadSheet
+
+if __name__ == "__main__":
+ app = QApplication()
+
+ sheet = SpreadSheet(10, 6)
+ sheet.setWindowIcon(QPixmap(":/images/interview.png"))
+ sheet.show()
+ sheet.layout().setSizeConstraint(QLayout.SetFixedSize)
+
+ sys.exit(app.exec())
diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.py b/examples/widgets/itemviews/spreadsheet/spreadsheet.py
new file mode 100644
index 000000000..82ebe5ebb
--- /dev/null
+++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.py
@@ -0,0 +1,544 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QPoint, Qt, QCoreApplication, Slot
+from PySide6.QtGui import QAction, QBrush, QPixmap, QColor, QPainter
+from PySide6.QtWidgets import (QColorDialog, QComboBox, QDialog, QFontDialog,
+ QGroupBox, QHBoxLayout, QMainWindow, QLabel,
+ QLineEdit, QMessageBox, QPushButton, QToolBar,
+ QTableWidgetItem, QTableWidget, QVBoxLayout, QWidget)
+
+from spreadsheetdelegate import SpreadSheetDelegate
+from spreadsheetitem import SpreadSheetItem
+
+from typing import Optional
+from numbers import Number
+
+
+class SpreadSheet(QMainWindow):
+ def __init__(self, rows: Number, cols: Number, parent: Optional[QWidget] = None) -> None:
+ super().__init__(parent)
+
+ self._tool_bar = QToolBar(self)
+ self._color_action = QAction()
+ self._font_action = QAction()
+ self._first_separator = QAction()
+ self._cell_sum_action = QAction()
+ self._cell_add_action = QAction()
+ self._cell_sub_action = QAction()
+ self._cell_mul_action = QAction()
+ self._cell_div_action = QAction()
+ self._second_separator = QAction()
+ self._clear_action = QAction()
+ self._about_spreadsheet = QAction()
+ self._exit_action = QAction()
+
+ # self._print_action = QAction()
+
+ self._cell_label = QLabel(self._tool_bar)
+ self._table = QTableWidget(rows, cols, self)
+ self._formula_input = QLineEdit(self)
+
+ self.addToolBar(self._tool_bar)
+
+ self._cell_label.setMinimumSize(80, 0)
+
+ self._tool_bar.addWidget(self._cell_label)
+ self._tool_bar.addWidget(self._formula_input)
+
+ self._table.setSizeAdjustPolicy(QTableWidget.SizeAdjustPolicy.AdjustToContents)
+ for c in range(cols):
+ character = chr(ord('A') + c)
+ self._table.setHorizontalHeaderItem(c, QTableWidgetItem(character))
+
+ self._table.setItemPrototype(self._table.item(rows - 1, cols - 1))
+ self._table.setItemDelegate(SpreadSheetDelegate())
+
+ self.create_actions()
+ self.update_color(None)
+ self.setup_menu_bar()
+ self.setup_contents()
+ self.setup_context_menu()
+ self.setCentralWidget(self._table)
+
+ self.statusBar()
+ self._table.currentItemChanged.connect(self.update_status)
+ self._table.currentItemChanged.connect(self.update_color)
+ self._table.currentItemChanged.connect(self.update_line_edit)
+ self._table.itemChanged.connect(self.update_status)
+ self._formula_input.returnPressed.connect(self.return_pressed)
+ self._table.itemChanged.connect(self.update_line_edit)
+
+ self.setWindowTitle("Spreadsheet")
+
+ def create_actions(self) -> None:
+ self._cell_sum_action = QAction("Sum", self)
+ self._cell_sum_action.triggered.connect(self.action_sum)
+
+ self._cell_add_action = QAction("&Add", self)
+ self._cell_add_action.setShortcut(Qt.CTRL | Qt.Key_Plus)
+ self._cell_add_action.triggered.connect(self.action_add)
+
+ self._cell_sub_action = QAction("&Subtract", self)
+ self._cell_sub_action.setShortcut(Qt.CTRL | Qt.Key_Minus)
+ self._cell_sub_action.triggered.connect(self.action_subtract)
+
+ self._cell_mul_action = QAction("&Multiply", self)
+ self._cell_mul_action.setShortcut(Qt.CTRL | Qt.Key_multiply)
+ self._cell_mul_action.triggered.connect(self.action_multiply)
+
+ self._cell_div_action = QAction("&Divide", self)
+ self._cell_div_action.setShortcut(Qt.CTRL | Qt.Key_division)
+ self._cell_div_action.triggered.connect(self.action_divide)
+
+ self._font_action = QAction("Font...", self)
+ self._font_action.setShortcut(Qt.CTRL | Qt.Key_F)
+ self._font_action.triggered.connect(self.select_font)
+
+ self._color_action = QAction(QPixmap(16, 16), "Background &Color...", self)
+ self._color_action.triggered.connect(self.select_color)
+
+ self._clear_action = QAction("Clear", self)
+ self._clear_action.setShortcut(Qt.Key_Delete)
+ self._clear_action.triggered.connect(self.clear)
+
+ self._about_spreadsheet = QAction("About Spreadsheet", self)
+ self._about_spreadsheet.triggered.connect(self.show_about)
+
+ self._exit_action = QAction("E&xit", self)
+ self._exit_action.triggered.connect(QCoreApplication.quit)
+
+ self._first_separator = QAction(self)
+ self._first_separator.setSeparator(True)
+
+ self._second_separator = QAction(self)
+ self._second_separator.setSeparator(True)
+
+ def setup_menu_bar(self) -> None:
+ file_menu = self.menuBar().addMenu("&File")
+ # file_menu.addAction(self._print_action)
+ file_menu.addAction(self._exit_action)
+
+ cell_menu = self.menuBar().addMenu("&Cell")
+ cell_menu.addAction(self._cell_add_action)
+ cell_menu.addAction(self._cell_sub_action)
+ cell_menu.addAction(self._cell_mul_action)
+ cell_menu.addAction(self._cell_div_action)
+ cell_menu.addAction(self._cell_sum_action)
+ cell_menu.addSeparator()
+ cell_menu.addAction(self._color_action)
+ cell_menu.addAction(self._font_action)
+
+ self.menuBar().addSeparator()
+
+ about_menu = self.menuBar().addMenu("&Help")
+ about_menu.addAction(self._about_spreadsheet)
+
+ @Slot(QTableWidgetItem)
+ def update_status(self, item: QTableWidgetItem) -> None:
+ if item and item == self._table.currentItem():
+ self.statusBar().showMessage(str(item.data(Qt.StatusTipRole)), 1000)
+ self._cell_label.setText(
+ "Cell: ({})".format(
+ SpreadSheetItem.encode_pos(self._table.row(item), self._table.column(item))
+ )
+ )
+
+ @Slot(QTableWidgetItem)
+ def update_color(self, item: QTableWidgetItem) -> None:
+ pix = QPixmap(16, 16)
+ col = QColor()
+ if item:
+ col = item.background().color()
+ if not col.isValid():
+ col = self.palette().base().color()
+
+ pt = QPainter(pix)
+ pt.fillRect(0, 0, 16, 16, col)
+
+ lighter = col.lighter()
+ pt.setPen(lighter)
+ light_frame = [QPoint(0, 15), QPoint(0, 0), QPoint(15, 0)]
+ pt.drawPolyline(light_frame)
+
+ pt.setPen(col.darker())
+ darkFrame = [QPoint(1, 15), QPoint(15, 15), QPoint(15, 1)]
+ pt.drawPolyline(darkFrame)
+
+ pt.end()
+
+ self._color_action.setIcon(pix)
+
+ @Slot(QTableWidgetItem)
+ def update_line_edit(self, item: QTableWidgetItem) -> None:
+ if item != self._table.currentItem():
+ return
+ if item:
+ self._formula_input.setText(str(item.data(Qt.EditRole)))
+ else:
+ self._formula_input.clear()
+
+ @Slot()
+ def return_pressed(self) -> None:
+ text = self._formula_input.text()
+ row = self._table.currentRow()
+ col = self._table.currentColumn()
+ item = self._table.item(row, col)
+ if not item:
+ self._table.setItem(row, col, SpreadSheetItem(text))
+ else:
+ item.setData(Qt.EditRole, text)
+ self._table.viewport().update()
+
+ @Slot()
+ def select_color(self) -> None:
+ item = self._table.currentItem()
+ col = item.background().color() if item else self._table.palette().base().color()
+ col = QColorDialog.getColor(col, self)
+ if not col.isValid():
+ return
+
+ selected = self._table.selectedItems()
+ if not selected:
+ return
+
+ for i in selected:
+ if i:
+ i.setBackground(col)
+
+ self.update_color(self._table.currentItem())
+
+ @Slot()
+ def select_font(self) -> None:
+ selected = self._table.selectedItems()
+ if not selected:
+ return
+
+ ok = False
+ fnt = QFontDialog.getFont(ok, self.font(), self)
+
+ if not ok:
+ return
+ for i in selected:
+ if i:
+ i.setFont(fnt)
+
+ def run_input_dialog(self, title: str, c1Text: str, c2Text: str, opText: str,
+ outText: str, cell1: str, cell2: str, outCell: str) -> bool:
+ rows, cols = [], []
+ for c in range(self._table.columnCount()):
+ cols.append(chr(ord('A') + c))
+ for r in range(self._table.rowCount()):
+ rows.append(str(1 + r))
+
+ add_dialog = QDialog(self)
+ add_dialog.setWindowTitle(title)
+
+ group = QGroupBox(title, add_dialog)
+ group.setMinimumSize(250, 100)
+
+ cell1_label = QLabel(c1Text, group)
+ cell1_row_input = QComboBox(group)
+ c1_row, c1_col = SpreadSheetItem.decode_pos(cell1)
+ cell1_row_input.addItems(rows)
+ cell1_row_input.setCurrentIndex(c1_row)
+
+ cell1_col_input = QComboBox(group)
+ cell1_col_input.addItems(cols)
+ cell1_col_input.setCurrentIndex(c1_col)
+
+ operator_label = QLabel(opText, group)
+ operator_label.setAlignment(Qt.AlignHCenter)
+
+ cell2_label = QLabel(c2Text, group)
+ cell2_row_input = QComboBox(group)
+ c2_row, c2_col = SpreadSheetItem.decode_pos(cell2)
+ cell2_row_input.addItems(rows)
+ cell2_row_input.setCurrentIndex(c2_row)
+ cell2_col_input = QComboBox(group)
+ cell2_col_input.addItems(cols)
+ cell2_col_input.setCurrentIndex(c2_col)
+
+ equals_label = QLabel("=", group)
+ equals_label.setAlignment(Qt.AlignHCenter)
+
+ out_label = QLabel(outText, group)
+ out_row_input = QComboBox(group)
+ out_row, out_col = SpreadSheetItem.decode_pos(outCell)
+ out_row_input.addItems(rows)
+ out_row_input.setCurrentIndex(out_row)
+ out_col_input = QComboBox(group)
+ out_col_input.addItems(cols)
+ out_col_input.setCurrentIndex(out_col)
+
+ cancel_button = QPushButton("Cancel", add_dialog)
+ cancel_button.clicked.connect(add_dialog.reject)
+
+ ok_button = QPushButton("OK", add_dialog)
+ ok_button.setDefault(True)
+ ok_button.clicked.connect(add_dialog.accept)
+
+ buttons_layout = QHBoxLayout()
+ buttons_layout.addStretch(1)
+ buttons_layout.addWidget(ok_button)
+ buttons_layout.addSpacing(10)
+ buttons_layout.addWidget(cancel_button)
+
+ dialog_layout = QVBoxLayout(add_dialog)
+ dialog_layout.addWidget(group)
+ dialog_layout.addStretch(1)
+ dialog_layout.addItem(buttons_layout)
+
+ cell1_layout = QHBoxLayout()
+ cell1_layout.addWidget(cell1_label)
+ cell1_layout.addSpacing(10)
+ cell1_layout.addWidget(cell1_col_input)
+ cell1_layout.addSpacing(10)
+ cell1_layout.addWidget(cell1_row_input)
+
+ cell2_layout = QHBoxLayout()
+ cell2_layout.addWidget(cell2_label)
+ cell2_layout.addSpacing(10)
+ cell2_layout.addWidget(cell2_col_input)
+ cell2_layout.addSpacing(10)
+ cell2_layout.addWidget(cell2_row_input)
+
+ out_layout = QHBoxLayout()
+ out_layout.addWidget(out_label)
+ out_layout.addSpacing(10)
+ out_layout.addWidget(out_col_input)
+ out_layout.addSpacing(10)
+ out_layout.addWidget(out_row_input)
+
+ v_layout = QVBoxLayout(group)
+ v_layout.addItem(cell1_layout)
+ v_layout.addWidget(operator_label)
+ v_layout.addItem(cell2_layout)
+ v_layout.addWidget(equals_label)
+ v_layout.addStretch(1)
+ v_layout.addItem(out_layout)
+
+ if add_dialog.exec():
+ cell1 = cell1_col_input.currentText() + cell1_row_input.currentText()
+ cell2 = cell2_col_input.currentText() + cell2_row_input.currentText()
+ outCell = out_col_input.currentText() + out_row_input.currentText()
+ return True
+
+ return False
+
+ @Slot()
+ def action_sum(self) -> None:
+ row_first = row_last = row_cur = 0
+ col_first = col_last = col_cur = 0
+
+ selected = self._table.selectedItems()
+
+ if selected is not None:
+ first = selected[0]
+ last = selected[-1]
+ row_first = self._table.row(first)
+ row_last = self._table.row(last)
+ col_first = self._table.column(first)
+ col_last = self._table.column(last)
+
+ current = self._table.currentItem()
+
+ if current:
+ row_cur = self._table.row(current)
+ col_cur = self._table.column(current)
+
+ cell1 = SpreadSheetItem.encode_pos(row_first, col_first)
+ cell2 = SpreadSheetItem.encode_pos(row_last, col_last)
+ out = SpreadSheetItem.encode_pos(row_cur, col_cur)
+
+ if self.run_input_dialog(
+ "Sum cells", "First cell:", "Last cell:",
+ f"{(chr(0x03a3))}", "Output to:",
+ cell1, cell2, out
+ ):
+ row, col = SpreadSheetItem.decode_pos(out)
+ self._table.item(row, col).setText(f"sum {cell1} {cell2}")
+
+ def action_math_helper(self, title: str, op: str) -> None:
+ cell1 = "C1"
+ cell2 = "C2"
+ out = "C3"
+
+ current = self._table.currentItem()
+ if current:
+ out = SpreadSheetItem.encode_pos(self._table.currentRow(), self._table.currentColumn())
+
+ if self.run_input_dialog(title, "Cell 1", "Cell 2", op, "Output to:", cell1, cell2, out):
+ row, col = SpreadSheetItem.decode_pos(out)
+ self._table.item(row, col).setText(f"{op} {cell1} {cell2}")
+
+ @Slot()
+ def action_add(self) -> None:
+ self.action_math_helper("Addition", "+")
+
+ @Slot()
+ def action_subtract(self) -> None:
+ self.action_math_helper("Subtraction", "-")
+
+ @Slot()
+ def action_multiply(self) -> None:
+ self.action_math_helper("Multiplication", "*")
+
+ @Slot()
+ def action_divide(self) -> None:
+ self.action_math_helper("Division", "/")
+
+ @Slot()
+ def clear(self) -> None:
+ selected_items = self._table.selectedItems()
+ for item in selected_items:
+ item.setText("")
+
+ def setup_context_menu(self) -> None:
+ self.addAction(self._cell_add_action)
+ self.addAction(self._cell_sub_action)
+ self.addAction(self._cell_mul_action)
+ self.addAction(self._cell_div_action)
+ self.addAction(self._cell_sum_action)
+ self.addAction(self._first_separator)
+ self.addAction(self._color_action)
+ self.addAction(self._font_action)
+ self.addAction(self._second_separator)
+ self.addAction(self._clear_action)
+ self.setContextMenuPolicy(Qt.ActionsContextMenu)
+
+ def setup_contents(self) -> None:
+ title_background = QBrush(Qt.lightGray)
+ title_font = self._table.font()
+ title_font.setBold(True)
+
+ # column 0
+ self._table.setItem(0, 0, SpreadSheetItem("Item"))
+ self._table.item(0, 0).setBackground(title_background)
+ self._table.item(0, 0).setToolTip(
+ "This column shows the purchased item/service"
+ )
+ self._table.item(0, 0).setFont(title_font)
+
+ self._table.setItem(1, 0, SpreadSheetItem("AirportBus"))
+ self._table.setItem(2, 0, SpreadSheetItem("Flight (Munich)"))
+ self._table.setItem(3, 0, SpreadSheetItem("Lunch"))
+ self._table.setItem(4, 0, SpreadSheetItem("Flight (LA)"))
+ self._table.setItem(5, 0, SpreadSheetItem("Taxi"))
+ self._table.setItem(6, 0, SpreadSheetItem("Dinner"))
+ self._table.setItem(7, 0, SpreadSheetItem("Hotel"))
+ self._table.setItem(8, 0, SpreadSheetItem("Flight (Oslo)"))
+ self._table.setItem(9, 0, SpreadSheetItem("Total:"))
+
+ self._table.item(9, 0).setFont(title_font)
+ self._table.item(9, 0).setBackground(title_background)
+
+ # column 1
+ self._table.setItem(0, 1, SpreadSheetItem("Date"))
+ self._table.item(0, 1).setBackground(title_background)
+ self._table.item(0, 1).setToolTip(
+ "This column shows the purchase date, double click to change"
+ )
+ self._table.item(0, 1).setFont(title_font)
+
+ self._table.setItem(1, 1, SpreadSheetItem("15/6/2006"))
+ self._table.setItem(2, 1, SpreadSheetItem("15/6/2006"))
+ self._table.setItem(3, 1, SpreadSheetItem("15/6/2006"))
+ self._table.setItem(4, 1, SpreadSheetItem("21/5/2006"))
+ self._table.setItem(5, 1, SpreadSheetItem("16/6/2006"))
+ self._table.setItem(6, 1, SpreadSheetItem("16/6/2006"))
+ self._table.setItem(7, 1, SpreadSheetItem("16/6/2006"))
+ self._table.setItem(8, 1, SpreadSheetItem("18/6/2006"))
+
+ self._table.setItem(9, 1, SpreadSheetItem())
+ self._table.item(9, 1).setBackground(title_background)
+
+ # column 2
+ self._table.setItem(0, 2, SpreadSheetItem("Price"))
+ self._table.item(0, 2).setBackground(title_background)
+ self._table.item(0, 2).setToolTip("This column shows the price of the purchase")
+ self._table.item(0, 2).setFont(title_font)
+
+ self._table.setItem(1, 2, SpreadSheetItem("150"))
+ self._table.setItem(2, 2, SpreadSheetItem("2350"))
+ self._table.setItem(3, 2, SpreadSheetItem("-14"))
+ self._table.setItem(4, 2, SpreadSheetItem("980"))
+ self._table.setItem(5, 2, SpreadSheetItem("5"))
+ self._table.setItem(6, 2, SpreadSheetItem("120"))
+ self._table.setItem(7, 2, SpreadSheetItem("300"))
+ self._table.setItem(8, 2, SpreadSheetItem("1240"))
+
+ self._table.setItem(9, 2, SpreadSheetItem())
+ self._table.item(9, 2).setBackground(Qt.lightGray)
+
+ # column 3
+ self._table.setItem(0, 3, SpreadSheetItem("Currency"))
+ self._table.item(0, 3).setBackground(title_background)
+ self._table.item(0, 3).setToolTip("This column shows the currency")
+ self._table.item(0, 3).setFont(title_font)
+
+ self._table.setItem(1, 3, SpreadSheetItem("NOK"))
+ self._table.setItem(2, 3, SpreadSheetItem("NOK"))
+ self._table.setItem(3, 3, SpreadSheetItem("EUR"))
+ self._table.setItem(4, 3, SpreadSheetItem("EUR"))
+ self._table.setItem(5, 3, SpreadSheetItem("USD"))
+ self._table.setItem(6, 3, SpreadSheetItem("USD"))
+ self._table.setItem(7, 3, SpreadSheetItem("USD"))
+ self._table.setItem(8, 3, SpreadSheetItem("USD"))
+
+ self._table.setItem(9, 3, SpreadSheetItem())
+ self._table.item(9, 3).setBackground(Qt.lightGray)
+
+ # column 4
+ self._table.setItem(0, 4, SpreadSheetItem("Ex. Rate"))
+ self._table.item(0, 4).setBackground(title_background)
+ self._table.item(0, 4).setToolTip("This column shows the exchange rate to NOK")
+ self._table.item(0, 4).setFont(title_font)
+
+ self._table.setItem(1, 4, SpreadSheetItem("1"))
+ self._table.setItem(2, 4, SpreadSheetItem("1"))
+ self._table.setItem(3, 4, SpreadSheetItem("8"))
+ self._table.setItem(4, 4, SpreadSheetItem("8"))
+ self._table.setItem(5, 4, SpreadSheetItem("7"))
+ self._table.setItem(6, 4, SpreadSheetItem("7"))
+ self._table.setItem(7, 4, SpreadSheetItem("7"))
+ self._table.setItem(8, 4, SpreadSheetItem("7"))
+
+ self._table.setItem(9, 4, SpreadSheetItem())
+ self._table.item(9, 4).setBackground(title_background)
+
+ # column 5
+ self._table.setItem(0, 5, SpreadSheetItem("NOK"))
+ self._table.item(0, 5).setBackground(title_background)
+ self._table.item(0, 5).setToolTip("This column shows the expenses in NOK")
+ self._table.item(0, 5).setFont(title_font)
+
+ self._table.setItem(1, 5, SpreadSheetItem("* C2 E2"))
+ self._table.setItem(2, 5, SpreadSheetItem("* C3 E3"))
+ self._table.setItem(3, 5, SpreadSheetItem("* C4 E4"))
+ self._table.setItem(4, 5, SpreadSheetItem("* C5 E5"))
+ self._table.setItem(5, 5, SpreadSheetItem("* C6 E6"))
+ self._table.setItem(6, 5, SpreadSheetItem("* C7 E7"))
+ self._table.setItem(7, 5, SpreadSheetItem("* C8 E8"))
+ self._table.setItem(8, 5, SpreadSheetItem("* C9 E9"))
+
+ self._table.setItem(9, 5, SpreadSheetItem("sum F2 F9"))
+ self._table.item(9, 5).setBackground(title_background)
+
+ @Slot()
+ def show_about(self) -> None:
+ html_text = (
+ "<HTML>"
+ "<p><b>This demo shows use of <c>QTableWidget</c> with custom handling for"
+ " individual cells.</b></p>"
+ "<p>Using a customized table item we make it possible to have dynamic"
+ " output in different cells. The content that is implemented for this"
+ " particular demo is:"
+ "<ul>"
+ "<li>Adding two cells.</li>"
+ "<li>Subtracting one cell from another.</li>"
+ "<li>Multiplying two cells.</li>"
+ "<li>Dividing one cell with another.</li>"
+ "<li>Summing the contents of an arbitrary number of cells.</li>"
+ "</HTML>")
+ QMessageBox.about(self, "About Spreadsheet", html_text)
diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.py b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.py
new file mode 100644
index 000000000..57aba6f47
--- /dev/null
+++ b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.py
@@ -0,0 +1,67 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import (QAbstractItemModel, QDate, QModelIndex, QObject,
+ QStringListModel, Qt, Slot)
+from PySide6.QtWidgets import (QCompleter, QDateTimeEdit, QLineEdit,
+ QStyleOptionViewItem, QStyledItemDelegate, QWidget)
+
+from typing import Optional
+
+
+class SpreadSheetDelegate(QStyledItemDelegate):
+ def __init__(self, parent: Optional[QObject] = None) -> None:
+ super().__init__(parent)
+
+ def create_editor(self, parent: QWidget,
+ option: QStyleOptionViewItem,
+ index: QModelIndex) -> QWidget:
+ if index.column() == 1:
+ editor = QDateTimeEdit(parent)
+ editor.setDisplayFormat("dd/M/yyyy")
+ editor.setCalendarPopup(True)
+ return editor
+
+ editor = QLineEdit(parent)
+
+ # create a completer with the strings in the column as model
+ allStrings = QStringListModel()
+ for i in range(1, index.model().rowCount()):
+ strItem = str(index.model().data(index.sibling(i, index.column()), Qt.EditRole))
+
+ if not allStrings.contains(strItem):
+ allStrings.append(strItem)
+
+ autoComplete = QCompleter(allStrings)
+ editor.setCompleter(autoComplete)
+ editor.editingFinished.connect(SpreadSheetDelegate.commit_and_close_editor)
+ return editor
+
+ @Slot()
+ def commit_and_close_editor(self) -> None:
+ editor = self.sender()
+ self.commitData.emit(editor)
+ self.closeEditor.emit(editor)
+
+ def set_editor_data(self, editor: QWidget, index: QModelIndex) -> None:
+ edit = QLineEdit(editor)
+ if edit:
+ edit.setText(str(index.model().data(index, Qt.EditRole)))
+ return
+
+ dateEditor = QDateTimeEdit(editor)
+ if dateEditor:
+ dateEditor.setDate(
+ QDate.fromString(
+ str(index.model().data(index, Qt.EditRole)), "d/M/yyyy"))
+
+ def set_model_data(self, editor: QWidget,
+ model: QAbstractItemModel, index: QModelIndex) -> None:
+ edit = QLineEdit(editor)
+ if edit:
+ model.setData(index, edit.text())
+ return
+
+ dateEditor = QDateTimeEdit(editor)
+ if dateEditor:
+ model.setData(index, dateEditor.date().toString("dd/M/yyyy"))
diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetitem.py b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.py
new file mode 100644
index 000000000..dc70da883
--- /dev/null
+++ b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.py
@@ -0,0 +1,122 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from typing import Any, Tuple
+from PySide6.QtCore import QMetaType, Qt
+from PySide6.QtWidgets import QTableWidget, QTableWidgetItem
+
+
+class SpreadSheetItem(QTableWidgetItem):
+ is_resolving = False
+
+ def __init_subclass__(cls) -> None:
+ return super().__init_subclass__()
+
+ def data(self, role: int) -> Any:
+ if role == Qt.EditRole or role == Qt.StatusTipRole:
+ return self.formula()
+
+ if role == Qt.DisplayRole:
+ return self.display()
+
+ t = str(self.display())
+
+ if role == Qt.ForegroundRole:
+ try:
+ number = int(t)
+ color = Qt.red if number < 0 else Qt.blue
+ except ValueError:
+ color = Qt.black
+ return color
+
+ if role == Qt.TextAlignmentRole:
+ if t and (t[0].isdigit() or t[0] == '-'):
+ return int(Qt.AlignRight | Qt.AlignVCenter)
+
+ return super().data(role)
+
+ def setData(self, role: int, value: Any) -> None:
+ super().setData(role, value)
+ if self.tableWidget():
+ self.tableWidget().viewport().update()
+
+ def display(self) -> QMetaType.Type.QVariant:
+ # avoid circular dependencies
+ if self.is_resolving:
+ return QMetaType.Type.QVariant
+
+ self.is_resolving = True
+ result = self.compute_formula(self.formula(), self.tableWidget(), self)
+ self.is_resolving = False
+ return result
+
+ def formula(self) -> None:
+ return str(super().data(Qt.DisplayRole))
+
+ def compute_formula(self, formula: str, widget: QTableWidget, this) -> QMetaType.Type.QVariant:
+ # check if the string is actually a formula or not
+ list_ = formula.split(' ')
+ if not list_ or not widget:
+ return formula # it is a normal string
+
+ op = list_[0].lower() if list_[0] else ""
+
+ first_row = -1
+ first_col = -1
+ second_row = -1
+ second_col = -1
+
+ if len(list_) > 1:
+ SpreadSheetItem.decode_pos(list_[1])
+
+ if len(list_) > 2:
+ SpreadSheetItem.decode_pos(list_[2])
+
+ start = widget.item(first_row, first_col)
+ end = widget.item(second_row, second_col)
+
+ first_val = int(start.text()) if start else 0
+ second_val = int(end.text()) if start else 0
+
+ if op == "sum":
+ sum = 0
+ for r in range(first_row, second_row + 1):
+ for c in range(first_col, second_col + 1):
+ table_item = widget.item(r, c)
+ if table_item and table_item != this:
+ sum += int(table_item.text())
+
+ result = sum
+ elif op == "+":
+ result = first_val + second_val
+ elif op == "-":
+ result = first_val - second_val
+ elif op == "*":
+ result = first_val * second_val
+ elif op == "/":
+ if second_val == 0:
+ result = "nan"
+ else:
+ result = first_val / second_val
+ elif op == "=":
+ if start:
+ result = start.text()
+ else:
+ result = formula
+
+ return result
+
+ def decode_pos(pos: str) -> Tuple[int, int]:
+ if (not pos):
+ col = -1
+ row = -1
+ else:
+ col = ord(pos[0].encode("latin1")) - ord('A')
+ try:
+ row = int(pos[1:]) - 1
+ except ValueError:
+ row = -1
+ return row, col
+
+ def encode_pos(row: int, col: int) -> str:
+ return str(chr(col + ord('A'))) + str(row + 1)
diff --git a/examples/widgets/layouts/basiclayouts/basiclayouts.py b/examples/widgets/layouts/basiclayouts/basiclayouts.py
index ab8e77311..a2d29e71f 100644
--- a/examples/widgets/layouts/basiclayouts/basiclayouts.py
+++ b/examples/widgets/layouts/basiclayouts/basiclayouts.py
@@ -6,12 +6,11 @@
import sys
-from PySide6.QtCore import Qt
from PySide6.QtWidgets import (QApplication, QComboBox, QDialog,
QDialogButtonBox, QGridLayout, QGroupBox,
QFormLayout, QHBoxLayout, QLabel, QLineEdit,
QMenu, QMenuBar, QPushButton, QSpinBox,
- QTextEdit, QVBoxLayout, QWidget)
+ QTextEdit, QVBoxLayout)
class Dialog(QDialog):
diff --git a/examples/widgets/layouts/dynamiclayouts/dynamiclayouts.py b/examples/widgets/layouts/dynamiclayouts/dynamiclayouts.py
index a9eec159a..4e3791519 100644
--- a/examples/widgets/layouts/dynamiclayouts/dynamiclayouts.py
+++ b/examples/widgets/layouts/dynamiclayouts/dynamiclayouts.py
@@ -50,7 +50,7 @@ class Dialog(QDialog):
self._main_layout.setSizeConstraint(QLayout.SetNoConstraint)
self.setMinimumSize(0, 0)
- orientation = Qt.Orientation(int(self._buttons_orientation_combo_box.itemData(index)))
+ orientation = Qt.Orientation(self._buttons_orientation_combo_box.itemData(index))
if orientation == self._button_box.orientation():
return
diff --git a/examples/widgets/linguist/main.py b/examples/widgets/linguist/main.py
index e71779f77..16655432c 100644
--- a/examples/widgets/linguist/main.py
+++ b/examples/widgets/linguist/main.py
@@ -1,13 +1,12 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-from pathlib import Path
import sys
from PySide6.QtCore import (QItemSelection, QLibraryInfo, QLocale, QTranslator,
- Qt, Slot)
+ Slot)
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QListWidget,
- QMainWindow, QWidget)
+ QMainWindow)
import linguist_rc
@@ -42,7 +41,7 @@ class Window(QMainWindow):
if __name__ == '__main__':
app = QApplication(sys.argv)
- path = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
+ path = QLibraryInfo.path(QLibraryInfo.TranslationsPath)
translator = QTranslator(app)
if translator.load(QLocale.system(), 'qtbase', '_', path):
app.installTranslator(translator)
diff --git a/examples/widgets/mainwindows/application/application.py b/examples/widgets/mainwindows/application/application.py
index 79c3b0f03..320c421a6 100644
--- a/examples/widgets/mainwindows/application/application.py
+++ b/examples/widgets/mainwindows/application/application.py
@@ -6,10 +6,10 @@ from argparse import ArgumentParser, RawTextHelpFormatter
import sys
from PySide6.QtCore import (QByteArray, QFile, QFileInfo, QSaveFile, QSettings,
- QTextStream, Qt)
+ QTextStream, Qt, Slot)
from PySide6.QtGui import QAction, QIcon, QKeySequence
from PySide6.QtWidgets import (QApplication, QFileDialog, QMainWindow,
- QMessageBox, QTextEdit, QWidget)
+ QMessageBox, QTextEdit)
import application_rc
@@ -42,23 +42,27 @@ class MainWindow(QMainWindow):
else:
event.ignore()
+ @Slot()
def new_file(self):
if self.maybe_save():
self._text_edit.clear()
self.set_current_file('')
+ @Slot()
def open(self):
if self.maybe_save():
fileName, filtr = QFileDialog.getOpenFileName(self)
if fileName:
self.load_file(fileName)
+ @Slot()
def save(self):
if self._cur_file:
return self.save_file(self._cur_file)
return self.save_as()
+ @Slot()
def save_as(self):
fileName, filtr = QFileDialog.getSaveFileName(self)
if fileName:
@@ -66,12 +70,14 @@ class MainWindow(QMainWindow):
return False
+ @Slot()
def about(self):
QMessageBox.about(self, "About Application",
"The <b>Application</b> example demonstrates how to write "
"modern GUI applications using Qt, with a menu bar, "
"toolbars, and a status bar.")
+ @Slot()
def document_was_modified(self):
self.setWindowModified(self._text_edit.document().isModified())
diff --git a/examples/widgets/mainwindows/dockwidgets/dockwidgets.py b/examples/widgets/mainwindows/dockwidgets/dockwidgets.py
index f8d5ffe26..6d0e95a81 100644
--- a/examples/widgets/mainwindows/dockwidgets/dockwidgets.py
+++ b/examples/widgets/mainwindows/dockwidgets/dockwidgets.py
@@ -103,7 +103,7 @@ class MainWindow(QMainWindow):
if not file.open(QFile.WriteOnly | QFile.Text):
reason = file.errorString()
QMessageBox.warning(self, "Dock Widgets",
- "Cannot write file {filename}:\n{reason}.")
+ f"Cannot write file {filename}:\n{reason}.")
return
out = QTextStream(file)
diff --git a/examples/widgets/mainwindows/mdi/mdi.py b/examples/widgets/mainwindows/mdi/mdi.py
index af402ffe8..597479981 100644
--- a/examples/widgets/mainwindows/mdi/mdi.py
+++ b/examples/widgets/mainwindows/mdi/mdi.py
@@ -8,11 +8,11 @@ from argparse import ArgumentParser, RawTextHelpFormatter
from functools import partial
import sys
-from PySide6.QtCore import (QByteArray, QFile, QFileInfo, QPoint, QSettings,
- QSaveFile, QSize, QTextStream, Qt)
+from PySide6.QtCore import (QByteArray, QFile, QFileInfo, QSettings,
+ QSaveFile, QTextStream, Qt, Slot)
from PySide6.QtGui import QAction, QIcon, QKeySequence
from PySide6.QtWidgets import (QApplication, QFileDialog, QMainWindow,
- QMdiArea, QMessageBox, QTextEdit, QWidget)
+ QMdiArea, QMessageBox, QTextEdit)
import mdi_rc
@@ -156,11 +156,13 @@ class MainWindow(QMainWindow):
self.write_settings()
event.accept()
+ @Slot()
def new_file(self):
child = self.create_mdi_child()
child.new_file()
child.show()
+ @Slot()
def open(self):
file_name, _ = QFileDialog.getOpenFileName(self)
if file_name:
@@ -178,31 +180,38 @@ class MainWindow(QMainWindow):
else:
child.close()
+ @Slot()
def save(self):
if self.active_mdi_child() and self.active_mdi_child().save():
self.statusBar().showMessage("File saved", 2000)
+ @Slot()
def save_as(self):
if self.active_mdi_child() and self.active_mdi_child().save_as():
self.statusBar().showMessage("File saved", 2000)
+ @Slot()
def cut(self):
if self.active_mdi_child():
self.active_mdi_child().cut()
+ @Slot()
def copy(self):
if self.active_mdi_child():
self.active_mdi_child().copy()
+ @Slot()
def paste(self):
if self.active_mdi_child():
self.active_mdi_child().paste()
+ @Slot()
def about(self):
QMessageBox.about(self, "About MDI",
"The <b>MDI</b> example demonstrates how to write multiple "
"document interface applications using Qt.")
+ @Slot()
def update_menus(self):
has_mdi_child = (self.active_mdi_child() is not None)
self._save_act.setEnabled(has_mdi_child)
@@ -221,6 +230,7 @@ class MainWindow(QMainWindow):
self._cut_act.setEnabled(has_selection)
self._copy_act.setEnabled(has_selection)
+ @Slot()
def update_window_menu(self):
self._window_menu.clear()
self._window_menu.addAction(self._close_act)
@@ -402,6 +412,7 @@ class MainWindow(QMainWindow):
return window
return None
+ @Slot()
def switch_layout_direction(self):
if self.layoutDirection() == Qt.LeftToRight:
QApplication.setLayoutDirection(Qt.RightToLeft)
diff --git a/examples/widgets/painting/painter/painter.py b/examples/widgets/painting/painter/painter.py
index 49036ae00..58584baff 100644
--- a/examples/widgets/painting/painter/painter.py
+++ b/examples/widgets/painting/painter/painter.py
@@ -9,7 +9,7 @@ from PySide6.QtWidgets import (
QStyle,
QColorDialog,
)
-from PySide6.QtCore import QPoint, Qt, QDir, Slot, QStandardPaths
+from PySide6.QtCore import Qt, Slot, QStandardPaths
from PySide6.QtGui import (
QMouseEvent,
QPaintEvent,
@@ -136,7 +136,8 @@ class MainWindow(QMainWindow):
self.setCentralWidget(self.painter_widget)
- self.set_color(Qt.black)
+ self.color = Qt.black
+ self.set_color(self.color)
self.mime_type_filters = ["image/png", "image/jpeg"]
@@ -175,19 +176,21 @@ class MainWindow(QMainWindow):
@Slot()
def on_color_clicked(self):
- color = QColorDialog.getColor(Qt.black, self)
+ color = QColorDialog.getColor(self.color, self)
+
if color:
self.set_color(color)
def set_color(self, color: QColor = Qt.black):
+ self.color = color
# Create color icon
pix_icon = QPixmap(32, 32)
- pix_icon.fill(color)
+ pix_icon.fill(self.color)
self.color_action.setIcon(QIcon(pix_icon))
- self.painter_widget.pen.setColor(color)
- self.color_action.setText(QColor(color).name())
+ self.painter_widget.pen.setColor(self.color)
+ self.color_action.setText(QColor(self.color).name())
if __name__ == "__main__":
diff --git a/examples/widgets/painting/plot/plot.py b/examples/widgets/painting/plot/plot.py
index 9d0dd016b..fd7ff9937 100644
--- a/examples/widgets/painting/plot/plot.py
+++ b/examples/widgets/painting/plot/plot.py
@@ -5,9 +5,8 @@ import math
import sys
from PySide6.QtWidgets import QWidget, QApplication
-from PySide6.QtCore import QPoint, QRect, QTimer, Qt, Slot
-from PySide6.QtGui import (QColor, QPainter, QPaintEvent, QPen, QPointList,
- QTransform)
+from PySide6.QtCore import QPoint, QRect, QTimer, Qt
+from PySide6.QtGui import QPainter, QPointList
WIDTH = 680
diff --git a/examples/widgets/richtext/orderform/orderform.py b/examples/widgets/richtext/orderform/orderform.py
index 9f16c40a2..fd0be01fe 100644
--- a/examples/widgets/richtext/orderform/orderform.py
+++ b/examples/widgets/richtext/orderform/orderform.py
@@ -6,14 +6,14 @@
import sys
-from PySide6.QtCore import QDate, Qt, Signal, Slot
+from PySide6.QtCore import QDate, Qt, Slot
from PySide6.QtGui import (QFont, QTextCharFormat, QTextCursor,
QTextFrameFormat, QTextLength, QTextTableFormat)
from PySide6.QtWidgets import (QApplication, QCheckBox, QDialog,
QDialogButtonBox, QGridLayout, QLabel,
QLineEdit, QMainWindow, QMenu, QMessageBox,
QTableWidget, QTableWidgetItem, QTabWidget,
- QTextEdit, QWidget)
+ QTextEdit)
from PySide6.QtPrintSupport import QAbstractPrintDialog, QPrintDialog, QPrinter
@@ -156,6 +156,7 @@ class MainWindow(QMainWindow):
'12 High Street\nSmall Town\nThis country',
dialog.order_items(), True)
+ @Slot()
def open_dialog(self):
dialog = DetailsDialog("Enter Customer Details", self)
@@ -163,6 +164,7 @@ class MainWindow(QMainWindow):
self.create_letter(dialog.sender_name(), dialog.sender_address(),
dialog.order_items(), dialog.send_offers())
+ @Slot()
def print_file(self):
editor = self.letters.currentWidget()
printer = QPrinter()
@@ -241,6 +243,7 @@ class DetailsDialog(QDialog):
def send_offers(self):
return self._offers_check_box.isChecked()
+ @Slot()
def verify(self):
if self._name_edit.text() and self._address_edit.toPlainText():
self.accept()
diff --git a/examples/widgets/richtext/textedit/main.py b/examples/widgets/richtext/textedit/main.py
index a51a4d34f..88b679edc 100644
--- a/examples/widgets/richtext/textedit/main.py
+++ b/examples/widgets/richtext/textedit/main.py
@@ -7,7 +7,6 @@ import sys
from argparse import ArgumentParser, RawTextHelpFormatter
from PySide6.QtCore import QCoreApplication, qVersion
-from PySide6.QtGui import QScreen
from PySide6.QtWidgets import QApplication
from textedit import TextEdit
diff --git a/examples/widgets/richtext/textedit/textedit.py b/examples/widgets/richtext/textedit/textedit.py
index 12eddc6c5..4f4146d34 100644
--- a/examples/widgets/richtext/textedit/textedit.py
+++ b/examples/widgets/richtext/textedit/textedit.py
@@ -2,16 +2,16 @@
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import sys
-from PySide6.QtCore import (QCoreApplication, QDir, QFile, QFileInfo, QMimeData,
+from PySide6.QtCore import (QCoreApplication, QDir, QFile, QFileInfo,
QMimeDatabase, QUrl, Qt, Slot)
-from PySide6.QtGui import (QAction, QActionGroup, QColor, QGuiApplication, QClipboard,
- QCloseEvent, QFont, QFontDatabase, QFontInfo, QIcon,
+from PySide6.QtGui import (QAction, QActionGroup, QColor, QGuiApplication,
+ QFont, QFontDatabase, QFontInfo, QIcon,
QKeySequence, QPalette, QPixmap, QTextBlockFormat,
QTextCharFormat, QTextCursor, QTextDocumentWriter,
- QTextFormat, QTextList, QTextListFormat)
+ QTextFormat, QTextListFormat)
from PySide6.QtWidgets import (QApplication, QMainWindow, QColorDialog, QComboBox,
- QDialog, QFileDialog, QFontComboBox, QStatusBar,
- QTextEdit, QToolBar, QMenu, QMenuBar, QMessageBox)
+ QDialog, QFileDialog, QFontComboBox,
+ QTextEdit, QMessageBox)
from PySide6.QtPrintSupport import (QAbstractPrintDialog, QPrinter,
QPrintDialog, QPrintPreviewDialog)
@@ -406,7 +406,7 @@ class TextEdit(QMainWindow):
@Slot()
def file_save(self):
if not self._file_name or self._file_name.startswith(":/"):
- return fileSaveAs()
+ return self.file_save_as()
writer = QTextDocumentWriter(self._file_name)
document = self._text_edit.document()
diff --git a/examples/widgets/richtext/textobject/textobject.py b/examples/widgets/richtext/textobject/textobject.py
index 3bc5f4bd2..9ab7bf8ae 100644
--- a/examples/widgets/richtext/textobject/textobject.py
+++ b/examples/widgets/richtext/textobject/textobject.py
@@ -8,9 +8,8 @@ import os
from pathlib import Path
import sys
-from PySide6.QtCore import QFile, QIODevice, QObject, QSizeF, Qt
-from PySide6.QtGui import (QTextCharFormat, QTextFormat, QTextObjectInterface,
- QPyTextObject)
+from PySide6.QtCore import QFile, QIODevice, QSizeF, Slot
+from PySide6.QtGui import (QTextCharFormat, QTextFormat, QPyTextObject)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
QVBoxLayout, QWidget)
@@ -51,6 +50,7 @@ class Window(QWidget):
self.setWindowTitle(self.tr("Text Object Example"))
+ @Slot()
def insert_text_object(self):
file_name = self._file_name_line_edit.text()
file = QFile(file_name)
diff --git a/examples/widgets/state-machine/eventtrans/eventtrans.py b/examples/widgets/state-machine/eventtrans/eventtrans.py
deleted file mode 100644
index b1c74a21f..000000000
--- a/examples/widgets/state-machine/eventtrans/eventtrans.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import sys
-
-from PySide6.QtCore import QEvent, QRect, Qt
-from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton
-from PySide6.QtStateMachine import QEventTransition, QState, QStateMachine
-
-
-class MainWindow(QMainWindow):
- def __init__(self):
- super().__init__()
- button = QPushButton(self)
- button.setGeometry(QRect(100, 100, 100, 100))
-
- machine = QStateMachine(self)
- s1 = QState()
- s1.assignProperty(button, 'text', 'Outside')
- s2 = QState()
- s2.assignProperty(button, 'text', 'Inside')
-
- enter_transition = QEventTransition(button, QEvent.Enter)
- enter_transition.setTargetState(s2)
- s1.addTransition(enter_transition)
-
- leave_transition = QEventTransition(button, QEvent.Leave)
- leave_transition.setTargetState(s1)
- s2.addTransition(leave_transition)
-
- s3 = QState()
- s3.assignProperty(button, 'text', 'Pressing...')
-
- press_transition = QEventTransition(button, QEvent.MouseButtonPress)
- press_transition.setTargetState(s3)
- s2.addTransition(press_transition)
-
- release_transition = QEventTransition(button, QEvent.MouseButtonRelease)
- release_transition.setTargetState(s2)
- s3.addTransition(release_transition)
-
- machine.addState(s1)
- machine.addState(s2)
- machine.addState(s3)
-
- machine.setInitialState(s1)
- machine.start()
-
- self.setCentralWidget(button)
- self.show()
-
-
-if __name__ == '__main__':
- app = QApplication(sys.argv)
- main_win = MainWindow()
- sys.exit(app.exec())
diff --git a/examples/widgets/state-machine/eventtrans/eventtrans.pyproject b/examples/widgets/state-machine/eventtrans/eventtrans.pyproject
deleted file mode 100644
index b2f660a8f..000000000
--- a/examples/widgets/state-machine/eventtrans/eventtrans.pyproject
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["eventtrans.py"]
-}
diff --git a/examples/widgets/state-machine/factstates/factstates.py b/examples/widgets/state-machine/factstates/factstates.py
deleted file mode 100644
index aacf8f19b..000000000
--- a/examples/widgets/state-machine/factstates/factstates.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import sys
-
-from PySide6.QtCore import QCoreApplication, QObject, Qt, Property, Signal
-from PySide6.QtStateMachine import (QFinalState, QSignalTransition, QState,
- QStateMachine)
-
-
-class Factorial(QObject):
- x_changed = Signal(int)
-
- def __init__(self):
- super().__init__()
- self.xval = -1
- self.facval = 1
-
- def get_x(self):
- return self.xval
-
- def set_x(self, x):
- if self.xval == x:
- return
- self.xval = x
- self.x_changed.emit(x)
- x = Property(int, get_x, set_x)
-
- def get_fact(self):
- return self.facval
-
- def set_fact(self, fac):
- self.facval = fac
-
- fac = Property(int, get_fact, set_fact)
-
-
-class FactorialLoopTransition(QSignalTransition):
- def __init__(self, fact):
- super().__init__(fact.x_changed)
- self.fact = fact
-
- def eventTest(self, e):
- if not super(FactorialLoopTransition, self).eventTest(e):
- return False
- return e.arguments()[0] > 1
-
- def onTransition(self, e):
- x = e.arguments()[0]
- fac = self.fact.fac
- self.fact.fac = x * fac
- self.fact.x = x - 1
-
-
-class FactorialDoneTransition(QSignalTransition):
- def __init__(self, fact):
- super().__init__(fact.x_changed)
- self.fact = fact
-
- def eventTest(self, e):
- if not super(FactorialDoneTransition, self).eventTest(e):
- return False
- return e.arguments()[0] <= 1
-
- def onTransition(self, e):
- print(self.fact.fac)
-
-
-if __name__ == '__main__':
- app = QCoreApplication(sys.argv)
- factorial = Factorial()
- machine = QStateMachine()
-
- compute = QState(machine)
- compute.assignProperty(factorial, 'fac', 1)
- compute.assignProperty(factorial, 'x', 6)
- compute.addTransition(FactorialLoopTransition(factorial))
-
- done = QFinalState(machine)
- done_transition = FactorialDoneTransition(factorial)
- done_transition.setTargetState(done)
- compute.addTransition(done_transition)
-
- machine.setInitialState(compute)
- machine.finished.connect(app.quit)
- machine.start()
-
- sys.exit(app.exec())
diff --git a/examples/widgets/state-machine/factstates/factstates.pyproject b/examples/widgets/state-machine/factstates/factstates.pyproject
deleted file mode 100644
index 751a5005b..000000000
--- a/examples/widgets/state-machine/factstates/factstates.pyproject
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["factstates.py"]
-}
diff --git a/examples/widgets/state-machine/ping_pong/ping_pong.py b/examples/widgets/state-machine/ping_pong/ping_pong.py
deleted file mode 100644
index d5c18eb28..000000000
--- a/examples/widgets/state-machine/ping_pong/ping_pong.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import sys
-
-from PySide6.QtCore import QCoreApplication, QEvent
-from PySide6.QtStateMachine import QAbstractTransition, QState, QStateMachine
-
-
-class PingEvent(QEvent):
- def __init__(self):
- super().__init__(QEvent.Type(QEvent.User + 2))
-
-
-class PongEvent(QEvent):
- def __init__(self):
- super().__init__(QEvent.Type(QEvent.User + 3))
-
-
-class Pinger(QState):
- def __init__(self, parent):
- super().__init__(parent)
-
- def onEntry(self, e):
- self.p = PingEvent()
- self.machine().postEvent(self.p)
- print('ping?')
-
-
-class PongTransition(QAbstractTransition):
- def eventTest(self, e):
- return e.type() == QEvent.User + 3
-
- def onTransition(self, e):
- self.p = PingEvent()
- machine.postDelayedEvent(self.p, 500)
- print('ping?')
-
-
-class PingTransition(QAbstractTransition):
- def eventTest(self, e):
- return e.type() == QEvent.User + 2
-
- def onTransition(self, e):
- self.p = PongEvent()
- machine.postDelayedEvent(self.p, 500)
- print('pong!')
-
-
-if __name__ == '__main__':
- app = QCoreApplication(sys.argv)
-
- machine = QStateMachine()
- group = QState(QState.ParallelStates)
- group.setObjectName('group')
-
- pinger = Pinger(group)
- pinger.setObjectName('pinger')
- pinger.addTransition(PongTransition())
-
- ponger = QState(group)
- ponger.setObjectName('ponger')
- ponger.addTransition(PingTransition())
-
- machine.addState(group)
- machine.setInitialState(group)
- machine.start()
-
- sys.exit(app.exec())
diff --git a/examples/widgets/state-machine/ping_pong/ping_pong.pyproject b/examples/widgets/state-machine/ping_pong/ping_pong.pyproject
deleted file mode 100644
index 7fb430352..000000000
--- a/examples/widgets/state-machine/ping_pong/ping_pong.pyproject
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["ping_pong.py"]
-}
diff --git a/examples/widgets/state-machine/rogue/rogue.py b/examples/widgets/state-machine/rogue/rogue.py
deleted file mode 100644
index a43d4d1bc..000000000
--- a/examples/widgets/state-machine/rogue/rogue.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import sys
-
-from PySide6.QtCore import (QEvent, QPoint, QRandomGenerator, QSize, Qt,
- Property)
-from PySide6.QtGui import QFont, QFontMetrics, QFontDatabase, QPainter
-from PySide6.QtWidgets import QApplication, QMainWindow
-from PySide6.QtStateMachine import (QEventTransition, QFinalState,
- QKeyEventTransition, QState, QStateMachine)
-
-
-class MovementTransition(QEventTransition):
- def __init__(self, window):
- super().__init__(window, QEvent.KeyPress)
- self.window = window
-
- def eventTest(self, event):
- if (event.type() == QEvent.StateMachineWrapped and
- event.event().type() == QEvent.KeyPress):
- key = event.event().key()
- return (key == Qt.Key_2 or key == Qt.Key_8 or
- key == Qt.Key_6 or key == Qt.Key_4)
- return False
-
- def onTransition(self, event):
- key = event.event().key()
- if key == Qt.Key_4:
- self.window.move_player(self.window.left)
- if key == Qt.Key_8:
- self.window.move_player(self.window.Up)
- if key == Qt.Key_6:
- self.window.move_player(self.window.right)
- if key == Qt.Key_2:
- self.window.move_player(self.window.down)
-
-
-class Custom(QState):
- def __init__(self, parent, mw):
- super().__init__(parent)
- self.mw = mw
-
- def onEntry(self, e):
- print(self.mw.status)
-
-
-class MainWindow(QMainWindow):
- def __init__(self):
- super().__init__()
- self.pX = 5
- self.pY = 5
- self.width = 35
- self.height = 20
- self._status_str = ''
-
- font = QFont()
- if 'Monospace' in QFontDatabase.families():
- font = QFont('Monospace', 12)
- else:
- for family in QFontDatabase.families():
- if QFontDatabase.isFixedPitch(family):
- font = QFont(family, 12)
- self.setFont(font)
-
- self.setup_map()
- self.build_machine()
- self.show()
-
- def setup_map(self):
- self.map = []
- 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 generator.bounded(0, 40) == 0):
- column.append('#')
- else:
- column.append('.')
- self.map.append(column)
-
- def build_machine(self):
- machine = QStateMachine(self)
-
- input_state = Custom(machine, self)
- # this line sets the status
- self.status = 'hello!'
- # however this line does not
- input_state.assignProperty(self, 'status', 'Move the rogue with 2, 4, 6, and 8')
-
- machine.setInitialState(input_state)
- machine.start()
-
- transition = MovementTransition(self)
- input_state.addTransition(transition)
-
- quit_state = QState(machine)
- quit_state.assignProperty(self, 'status', 'Really quit(y/n)?')
-
- yes_transition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Y)
- self._final_state = QFinalState(machine)
- yes_transition.setTargetState(self._final_state)
- quit_state.addTransition(yes_transition)
-
- no_transition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_N)
- no_transition.setTargetState(input_state)
- quit_state.addTransition(no_transition)
-
- quit_transition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Q)
- quit_transition.setTargetState(quit_state)
- input_state.addTransition(quit_transition)
-
- machine.setInitialState(input_state)
- machine.finished.connect(qApp.quit)
- machine.start()
-
- def sizeHint(self):
- metrics = QFontMetrics(self.font())
- return QSize(metrics.horizontalAdvance('X') * self.width,
- metrics.height() * (self.height + 1))
-
- def paintEvent(self, event):
- metrics = QFontMetrics(self.font())
- with QPainter(self) as painter:
- font_height = metrics.height()
- font_width = metrics.horizontalAdvance('X')
-
- painter.fillRect(self.rect(), Qt.black)
- painter.setPen(Qt.white)
-
- y_pos = font_height
- painter.drawText(QPoint(0, y_pos), self.status)
- for y in range(self.height):
- y_pos += font_height
- x_pos = 0
- for x in range(self.width):
- if y == self.pY and x == self.pX:
- x_pos += font_width
- continue
- painter.drawText(QPoint(x_pos, y_pos), self.map[x][y])
- x_pos += font_width
- painter.drawText(QPoint(self.pX * font_width, (self.pY + 2) * font_height), '@')
-
- def move_player(self, direction):
- if direction == self.left:
- if self.map[self.pX - 1][self.pY] != '#':
- self.pX -= 1
- elif direction == self.right:
- if self.map[self.pX + 1][self.pY] != '#':
- self.pX += 1
- elif direction == self.Up:
- if self.map[self.pX][self.pY - 1] != '#':
- self.pY -= 1
- elif direction == self.down:
- if self.map[self.pX][self.pY + 1] != '#':
- self.pY += 1
- self.repaint()
-
- def get_status(self):
- return self._status_str
-
- def set_status(self, status):
- self._status_str = status
- self.repaint()
- status = Property(str, get_status, set_status)
- Up = 0
- down = 1
- left = 2
- right = 3
- width = 35
- height = 20
-
-
-if __name__ == '__main__':
- app = QApplication(sys.argv)
- main_win = MainWindow()
- sys.exit(app.exec())
diff --git a/examples/widgets/state-machine/rogue/rogue.pyproject b/examples/widgets/state-machine/rogue/rogue.pyproject
deleted file mode 100644
index b8baf9802..000000000
--- a/examples/widgets/state-machine/rogue/rogue.pyproject
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["rogue.py"]
-}
diff --git a/examples/widgets/state-machine/trafficlight/doc/trafficlight.png b/examples/widgets/state-machine/trafficlight/doc/trafficlight.png
deleted file mode 100644
index ec88a8e8b..000000000
--- a/examples/widgets/state-machine/trafficlight/doc/trafficlight.png
+++ /dev/null
Binary files differ
diff --git a/examples/widgets/state-machine/trafficlight/doc/trafficlight.rst b/examples/widgets/state-machine/trafficlight/doc/trafficlight.rst
deleted file mode 100644
index 57d369465..000000000
--- a/examples/widgets/state-machine/trafficlight/doc/trafficlight.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Traffic Light Example
-=====================
-
-The Traffic Light example shows how to use The State Machine Framework to
-implement the control flow of a traffic light.
-
-
-.. image:: trafficlight.png
- :width: 400
- :alt: Traffic Light Screenshot
diff --git a/examples/widgets/state-machine/trafficlight/trafficlight.py b/examples/widgets/state-machine/trafficlight/trafficlight.py
deleted file mode 100644
index 1e58384f9..000000000
--- a/examples/widgets/state-machine/trafficlight/trafficlight.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import sys
-
-from PySide6.QtCore import QTimer, Qt, Property, Slot
-from PySide6.QtGui import QPainter, QPalette
-from PySide6.QtWidgets import QApplication, QVBoxLayout, QWidget
-from PySide6.QtStateMachine import QFinalState, QState, QStateMachine
-
-
-class LightWidget(QWidget):
- def __init__(self, color):
- super().__init__()
- self.color = color
- self._on_val = False
-
- def is_on(self):
- return self._on_val
-
- def set_on(self, on):
- if self._on_val == on:
- return
- self._on_val = on
- self.update()
-
- @Slot()
- def turn_off(self):
- self.set_on(False)
-
- @Slot()
- def turn_on(self):
- self.set_on(True)
-
- def paintEvent(self, e):
- if not self._on_val:
- return
- with QPainter(self) as painter:
- painter.setRenderHint(QPainter.Antialiasing)
- painter.setBrush(self.color)
- painter.drawEllipse(0, 0, self.width(), self.height())
-
- on = Property(bool, is_on, set_on)
-
-
-class TrafficLightWidget(QWidget):
- def __init__(self):
- super().__init__()
- vbox = QVBoxLayout(self)
- self._red_light = LightWidget(Qt.red)
- vbox.addWidget(self._red_light)
- self._yellow_light = LightWidget(Qt.yellow)
- vbox.addWidget(self._yellow_light)
- self._green_light = LightWidget(Qt.green)
- vbox.addWidget(self._green_light)
- pal = QPalette()
- pal.setColor(QPalette.Window, Qt.black)
- self.setPalette(pal)
- self.setAutoFillBackground(True)
-
-
-def create_light_state(light, duration, parent=None):
- light_state = QState(parent)
- timer = QTimer(light_state)
- timer.setInterval(duration)
- timer.setSingleShot(True)
- timing = QState(light_state)
- timing.entered.connect(light.turn_on)
- timing.entered.connect(timer.start)
- timing.exited.connect(light.turn_off)
- done = QFinalState(light_state)
- timing.addTransition(timer.timeout, done)
- light_state.setInitialState(timing)
- return light_state
-
-
-class TrafficLight(QWidget):
- def __init__(self):
- super().__init__()
- vbox = QVBoxLayout(self)
- widget = TrafficLightWidget()
- vbox.addWidget(widget)
- vbox.setContentsMargins(0, 0, 0, 0)
-
- machine = QStateMachine(self)
- red_going_yellow = create_light_state(widget._red_light, 1000)
- red_going_yellow.setObjectName('redGoingYellow')
- yellow_going_green = create_light_state(widget._red_light, 1000)
- yellow_going_green.setObjectName('yellowGoingGreen')
- red_going_yellow.addTransition(red_going_yellow.finished,
- yellow_going_green)
- green_going_yellow = create_light_state(widget._yellow_light, 3000)
- green_going_yellow.setObjectName('greenGoingYellow')
- yellow_going_green.addTransition(yellow_going_green.finished,
- green_going_yellow)
- yellow_going_red = create_light_state(widget._green_light, 1000)
- yellow_going_red.setObjectName('yellowGoingRed')
- green_going_yellow.addTransition(green_going_yellow.finished,
- yellow_going_red)
- yellow_going_red.addTransition(yellow_going_red.finished,
- red_going_yellow)
-
- machine.addState(red_going_yellow)
- machine.addState(yellow_going_green)
- machine.addState(green_going_yellow)
- machine.addState(yellow_going_red)
- machine.setInitialState(red_going_yellow)
- machine.start()
-
-
-if __name__ == '__main__':
- app = QApplication(sys.argv)
- widget = TrafficLight()
- widget.resize(110, 300)
- widget.show()
- sys.exit(app.exec())
diff --git a/examples/widgets/state-machine/trafficlight/trafficlight.pyproject b/examples/widgets/state-machine/trafficlight/trafficlight.pyproject
deleted file mode 100644
index 912472693..000000000
--- a/examples/widgets/state-machine/trafficlight/trafficlight.pyproject
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["trafficlight.py"]
-}
diff --git a/examples/widgets/state-machine/twowaybutton/twowaybutton.py b/examples/widgets/state-machine/twowaybutton/twowaybutton.py
deleted file mode 100644
index 35a582f93..000000000
--- a/examples/widgets/state-machine/twowaybutton/twowaybutton.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2010 velociraptor Genjix <aphidia@hotmail.com>
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-import sys
-
-from PySide6.QtWidgets import QApplication, QPushButton
-from PySide6.QtStateMachine import QState, QStateMachine
-
-
-if __name__ == '__main__':
- app = QApplication(sys.argv)
- button = QPushButton()
- machine = QStateMachine()
-
- off = QState()
- off.assignProperty(button, 'text', 'Off')
- off.setObjectName('off')
-
- on = QState()
- on.setObjectName('on')
- on.assignProperty(button, 'text', 'On')
-
- off.addTransition(button.clicked, on)
- on.addTransition(button.clicked, off)
-
- machine.addState(off)
- machine.addState(on)
- machine.setInitialState(off)
- machine.start()
- button.resize(100, 50)
- button.show()
- sys.exit(app.exec())
diff --git a/examples/widgets/state-machine/twowaybutton/twowaybutton.pyproject b/examples/widgets/state-machine/twowaybutton/twowaybutton.pyproject
deleted file mode 100644
index 223a51e32..000000000
--- a/examples/widgets/state-machine/twowaybutton/twowaybutton.pyproject
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "files": ["twowaybutton.py"]
-}
diff --git a/examples/widgets/tools/regularexpression/regularexpression.py b/examples/widgets/tools/regularexpression/regularexpression.py
index fca24f617..261e26196 100644
--- a/examples/widgets/tools/regularexpression/regularexpression.py
+++ b/examples/widgets/tools/regularexpression/regularexpression.py
@@ -12,8 +12,6 @@ from regularexpressiondialog import RegularExpressionDialog
from PySide6.QtWidgets import QApplication
-import re
-
if __name__ == "__main__":
app = QApplication(sys.argv)
diff --git a/examples/widgets/tools/regularexpression/regularexpressiondialog.py b/examples/widgets/tools/regularexpression/regularexpressiondialog.py
index 9ebf8a65d..4fc9c62a2 100644
--- a/examples/widgets/tools/regularexpression/regularexpressiondialog.py
+++ b/examples/widgets/tools/regularexpression/regularexpressiondialog.py
@@ -12,7 +12,6 @@ from PySide6.QtWidgets import (QCheckBox, QComboBox, QDialog, QFormLayout,
QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QPlainTextEdit,
QSpinBox, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget,)
-from PySide6.QtGui import QClipboard
def rawStringLiteral(pattern: str) -> str:
pattern = 'r"' + pattern
@@ -21,8 +20,8 @@ def rawStringLiteral(pattern: str) -> str:
def patternToCode(pattern: str) -> str:
- pattern = pattern.replace(f"\\", f"\\\\")
- pattern = pattern.replace(f'"', f'\\"')
+ pattern = pattern.replace("\\", "\\\\")
+ pattern = pattern.replace('"', '\\"')
pattern = '"' + pattern
pattern = pattern + '"'
return pattern
@@ -31,7 +30,7 @@ def patternToCode(pattern: str) -> str:
def codeToPattern(code: str) -> str:
try:
- new_code = code[0]
+ _ = code[0]
except IndexError:
logging.warning("code is empty")
return code
@@ -76,6 +75,7 @@ class PatternLineEdit(QLineEdit):
self.copyToCodeAction.triggered.connect(self.copyToCode)
self.pasteFromCodeAction.triggered.connect(self.pasteFromCode)
+ @Slot()
def escapeSelection(self):
selection = self.selectedText()
selection_start = self.selectionStart()
@@ -89,9 +89,11 @@ class PatternLineEdit(QLineEdit):
)
self.setText(t)
+ @Slot()
def copyToCode(self):
QGuiApplication.clipboard().setText(patternToCode(self.text()))
+ @Slot()
def pasteFromCode(self):
self.setText(codeToPattern(QGuiApplication.clipboard().text()))
@@ -165,6 +167,7 @@ class RegularExpressionDialog(QDialog):
self.palette.setColor(QPalette.Text, color)
widget.setPalette(self.palette)
+ @Slot()
def refresh(self):
self.setUpdatesEnabled(False)
self.pattern = self.patternLineEdit.text()
diff --git a/examples/widgets/tutorials/addressbook/part2.py b/examples/widgets/tutorials/addressbook/part2.py
index ccc6139ab..89c813006 100644
--- a/examples/widgets/tutorials/addressbook/part2.py
+++ b/examples/widgets/tutorials/addressbook/part2.py
@@ -4,9 +4,9 @@
import sys
-from PySide6.QtCore import Qt, Signal, Slot
-from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
- QHBoxLayout, QLabel, QLineEdit,
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import (QApplication, QGridLayout,
+ QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
QVBoxLayout, QWidget)
diff --git a/examples/widgets/tutorials/addressbook/part3.py b/examples/widgets/tutorials/addressbook/part3.py
index 5365c1ae0..571a96a48 100644
--- a/examples/widgets/tutorials/addressbook/part3.py
+++ b/examples/widgets/tutorials/addressbook/part3.py
@@ -4,8 +4,8 @@
import sys
-from PySide6.QtCore import Qt, Signal, Slot
-from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtWidgets import (QApplication, QGridLayout,
QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
QVBoxLayout, QWidget)
@@ -110,6 +110,7 @@ class AddressBook(QWidget):
self._submit_button.show()
self._cancel_button.show()
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -143,6 +144,7 @@ class AddressBook(QWidget):
self._submit_button.hide()
self._cancel_button.hide()
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
@@ -162,6 +164,7 @@ class AddressBook(QWidget):
self._submit_button.hide()
self._cancel_button.hide()
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -179,6 +182,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
diff --git a/examples/widgets/tutorials/addressbook/part4.py b/examples/widgets/tutorials/addressbook/part4.py
index 0b1edb054..505fe4db9 100644
--- a/examples/widgets/tutorials/addressbook/part4.py
+++ b/examples/widgets/tutorials/addressbook/part4.py
@@ -4,8 +4,8 @@
import sys
-from PySide6.QtCore import Qt, Signal, Slot
-from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtWidgets import (QApplication, QGridLayout,
QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
QVBoxLayout, QWidget)
@@ -105,6 +105,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -114,12 +115,14 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -157,11 +160,13 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -180,6 +185,7 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -197,6 +203,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
diff --git a/examples/widgets/tutorials/addressbook/part5.py b/examples/widgets/tutorials/addressbook/part5.py
index 48404c95d..72245703f 100644
--- a/examples/widgets/tutorials/addressbook/part5.py
+++ b/examples/widgets/tutorials/addressbook/part5.py
@@ -2,10 +2,9 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import pickle
import sys
-from PySide6.QtCore import Qt, Signal, Slot
+from PySide6.QtCore import Qt, Slot
from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
@@ -112,6 +111,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -121,12 +121,14 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -164,11 +166,13 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -187,6 +191,7 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -204,6 +209,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
diff --git a/examples/widgets/tutorials/addressbook/part6.py b/examples/widgets/tutorials/addressbook/part6.py
index 9070a34da..f75fbf44f 100644
--- a/examples/widgets/tutorials/addressbook/part6.py
+++ b/examples/widgets/tutorials/addressbook/part6.py
@@ -5,7 +5,7 @@
import pickle
import sys
-from PySide6.QtCore import QFile, QIODevice, QTextStream, Qt, Signal, Slot
+from PySide6.QtCore import Qt, Slot
from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog,
QGridLayout, QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
@@ -122,6 +122,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -131,12 +132,14 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -174,11 +177,13 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -197,6 +202,7 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -214,6 +220,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
diff --git a/examples/widgets/tutorials/addressbook/part7.py b/examples/widgets/tutorials/addressbook/part7.py
index 2fc7a8d1c..2f874f9bd 100644
--- a/examples/widgets/tutorials/addressbook/part7.py
+++ b/examples/widgets/tutorials/addressbook/part7.py
@@ -5,7 +5,7 @@
import pickle
import sys
-from PySide6.QtCore import QFile, QIODevice, QTextStream, Qt, Signal, Slot
+from PySide6.QtCore import QFile, QIODevice, QTextStream, Qt, Slot
from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog,
QGridLayout, QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
@@ -128,6 +128,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -137,12 +138,14 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -180,11 +183,13 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
@@ -203,6 +208,7 @@ class AddressBook(QWidget):
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -220,6 +226,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
diff --git a/examples/widgets/tutorials/cannon/t10.py b/examples/widgets/tutorials/cannon/t10.py
index db080f050..c9c3fa7f6 100644
--- a/examples/widgets/tutorials/cannon/t10.py
+++ b/examples/widgets/tutorials/cannon/t10.py
@@ -6,7 +6,7 @@
import sys
-from PySide6.QtCore import QRect, Qt, Signal, Slot
+from PySide6.QtCore import QRect, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette
from PySide6.QtWidgets import (QApplication, QGridLayout, QLCDNumber,
QPushButton, QSlider, QVBoxLayout, QWidget)
diff --git a/examples/widgets/tutorials/cannon/t11.py b/examples/widgets/tutorials/cannon/t11.py
index c7a4ffbd4..997eecbd1 100644
--- a/examples/widgets/tutorials/cannon/t11.py
+++ b/examples/widgets/tutorials/cannon/t11.py
@@ -7,7 +7,7 @@
import sys
import math
-from PySide6.QtCore import QPoint, QRect, QTimer, Qt, Signal, Slot
+from PySide6.QtCore import QPoint, QRect, QTimer, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette, QRegion
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout,
QLCDNumber, QPushButton, QSlider,
diff --git a/examples/widgets/tutorials/cannon/t12.py b/examples/widgets/tutorials/cannon/t12.py
index 3887bbf2e..8847b2208 100644
--- a/examples/widgets/tutorials/cannon/t12.py
+++ b/examples/widgets/tutorials/cannon/t12.py
@@ -8,7 +8,7 @@ import sys
import math
import random
-from PySide6.QtCore import QPoint, QRect, QTime, QTimer, Qt, Signal, Slot
+from PySide6.QtCore import QPoint, QRect, QTime, QTimer, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette, QRegion
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout,
QLabel, QLCDNumber, QPushButton, QSlider,
diff --git a/examples/widgets/tutorials/cannon/t13.py b/examples/widgets/tutorials/cannon/t13.py
index ddd5341da..4eb45a374 100644
--- a/examples/widgets/tutorials/cannon/t13.py
+++ b/examples/widgets/tutorials/cannon/t13.py
@@ -8,8 +8,8 @@ import sys
import math
import random
-from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, Qt, SIGNAL, SLOT,
- Signal, Slot)
+from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, Qt,
+ Signal, Slot, qWarning)
from PySide6.QtGui import QColor, QFont, QPainter, QPalette, QRegion
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout, QLabel,
QLCDNumber, QPushButton, QSizePolicy, QSlider,
diff --git a/examples/widgets/tutorials/cannon/t14.py b/examples/widgets/tutorials/cannon/t14.py
index aa0f8876b..e4f1c350d 100644
--- a/examples/widgets/tutorials/cannon/t14.py
+++ b/examples/widgets/tutorials/cannon/t14.py
@@ -8,10 +8,10 @@ import sys
import math
import random
-from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, QSize, Qt, SIGNAL,
- SLOT, Signal, Slot)
+from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, QSize, Qt,
+ Signal, Slot, qWarning)
from PySide6.QtGui import (QColor, QFont, QKeySequence, QPainter, QPalette,
- QShortcut, QRegion)
+ QShortcut, QRegion, QTransform)
from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QHBoxLayout,
QLabel, QLCDNumber, QPushButton, QSizePolicy,
QSlider, QVBoxLayout, QWidget)
@@ -341,7 +341,7 @@ class GameBoard(QWidget):
QShortcut(QKeySequence(Qt.Key_Enter), self, self.fire)
QShortcut(QKeySequence(Qt.Key_Return), self, self.fire)
- QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q), self, self.close)
+ QShortcut(QKeySequence(Qt.CTRL | Qt.Key_Q), self, self.close)
top_layout = QHBoxLayout()
top_layout.addWidget(shoot)
diff --git a/examples/widgets/tutorials/cannon/t2.py b/examples/widgets/tutorials/cannon/t2.py
index 57326ac37..d3adba396 100644
--- a/examples/widgets/tutorials/cannon/t2.py
+++ b/examples/widgets/tutorials/cannon/t2.py
@@ -6,9 +6,8 @@
import sys
-from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, Qt)
from PySide6.QtGui import QFont
-from PySide6.QtWidgets import (QApplication, QPushButton)
+from PySide6.QtWidgets import QApplication, QPushButton
if __name__ == '__main__':
diff --git a/examples/widgets/tutorials/cannon/t8.py b/examples/widgets/tutorials/cannon/t8.py
index c887a36a6..b82e24a01 100644
--- a/examples/widgets/tutorials/cannon/t8.py
+++ b/examples/widgets/tutorials/cannon/t8.py
@@ -6,7 +6,7 @@
import sys
-from PySide6.QtCore import Signal, Slot, Qt
+from PySide6.QtCore import Signal, Slot, Qt, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette
from PySide6.QtWidgets import (QApplication, QGridLayout, QLCDNumber,
QPushButton, QSlider, QVBoxLayout, QWidget)
diff --git a/examples/widgets/tutorials/cannon/t9.py b/examples/widgets/tutorials/cannon/t9.py
index 2526d1573..297e98e50 100644
--- a/examples/widgets/tutorials/cannon/t9.py
+++ b/examples/widgets/tutorials/cannon/t9.py
@@ -6,7 +6,7 @@
import sys
-from PySide6.QtCore import QRect, Qt, Signal, Slot
+from PySide6.QtCore import QRect, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette
from PySide6.QtWidgets import (QApplication, QGridLayout, QLCDNumber,
QPushButton, QSlider, QVBoxLayout, QWidget)
diff --git a/examples/widgets/tutorials/modelview/1_readonly.py b/examples/widgets/tutorials/modelview/1_readonly.py
new file mode 100644
index 000000000..9dc923260
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/1_readonly.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/1_readonly example from Qt v6.x"""
+
+
+#! [1]
+class MyModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ row = index.row() + 1
+ column = index.column() + 1
+ return f"Row{row}, Column{column}"
+ return None
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/2_formatting.py b/examples/widgets/tutorials/modelview/2_formatting.py
new file mode 100644
index 000000000..73c993e5f
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/2_formatting.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtGui import QBrush, QFont
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/2_formatting example from Qt v6.x"""
+
+
+class MyModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+#! [1]
+ def data(self, index, role=Qt.DisplayRole):
+ row = index.row()
+ col = index.column()
+ # generate a log message when this method gets called
+ print(f"row {row}, col{col}, role {role}")
+
+ if role == Qt.DisplayRole:
+ if row == 0 and col == 1:
+ return "<--left"
+ if row == 1 and col == 1:
+ return "right-->"
+ return f"Row{row}, Column{col+1}"
+
+ elif role == Qt.FontRole:
+ if row == 0 and col == 0: # change font only for cell(0,0)
+ bold_font = QFont()
+ bold_font.setBold(True)
+ return bold_font
+
+ elif role == Qt.BackgroundRole:
+ if row == 1 and col == 2: # change background only for cell(1,2)
+ return QBrush(Qt.red)
+
+ elif role == Qt.TextAlignmentRole:
+ if row == 1 and col == 1: # change text alignment only for cell(1,1)
+ return Qt.AlignRight | Qt.AlignVCenter
+
+ elif role == Qt.CheckStateRole:
+ if row == 1 and col == 0: # add a checkbox to cell(1,0)
+ return Qt.Checked
+
+ return None
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/3_changingmodel.py b/examples/widgets/tutorials/modelview/3_changingmodel.py
new file mode 100644
index 000000000..e277dd1e8
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/3_changingmodel.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, QTime, QTimer, Qt, Slot
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/3_changingmodel example from Qt v6.x"""
+
+
+class MyModel(QAbstractTableModel):
+#! [1]
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._timer = QTimer(self)
+ self._timer.setInterval(1000)
+ self._timer.timeout.connect(self.timer_hit)
+ self._timer.start()
+#! [1]
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+#! [2]
+ def data(self, index, role=Qt.DisplayRole):
+ row = index.row()
+ col = index.column()
+ if role == Qt.DisplayRole and row == 0 and col == 0:
+ return QTime.currentTime().toString()
+ return None
+#! [2]
+
+#! [3]
+ @Slot()
+ def timer_hit(self):
+ # we identify the top left cell
+ top_left = self.createIndex(0, 0)
+ # emit a signal to make the view reread identified data
+ self.dataChanged.emit(top_left, top_left, [Qt.DisplayRole])
+#! [3]
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/4_headers.py b/examples/widgets/tutorials/modelview/4_headers.py
new file mode 100644
index 000000000..3feef17bf
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/4_headers.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/4_headers example from Qt v6.x"""
+
+
+class MyModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ row = index.row() + 1
+ column = index.column() + 1
+ return f"Row{row}, Column{column}"
+ return None
+
+#! [1]
+ def headerData(self, section, orientation, role):
+ if role == Qt.DisplayRole and orientation == Qt.Horizontal:
+ return ["first", "second", "third"][section]
+ return None
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/5_edit.py b/examples/widgets/tutorials/modelview/5_edit.py
new file mode 100644
index 000000000..1a4481fc9
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/5_edit.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from itertools import chain
+
+from PySide6.QtCore import QAbstractTableModel, Qt, Signal, Slot
+from PySide6.QtWidgets import QApplication, QMainWindow, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/5_edit example from Qt v6.x"""
+
+
+COLS = 3
+ROWS = 2
+
+
+class MyModel(QAbstractTableModel):
+
+ editCompleted = Signal(str)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._grid_data = [["" for y in range(COLS)] for x in range(ROWS)]
+
+ def rowCount(self, parent=None):
+ return ROWS
+
+ def columnCount(self, parent=None):
+ return COLS
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole and self.checkIndex(index):
+ return self._grid_data[index.row()][index.column()]
+ return None
+
+#! [1]
+ def setData(self, index, value, role):
+ if role != Qt.EditRole or not self.checkIndex(index):
+ return False
+ # save value from editor to member m_gridData
+ self._grid_data[index.row()][index.column()] = value
+ # for presentation purposes only: build and emit a joined string
+ result = " ".join(chain(*self._grid_data))
+ self.editCompleted.emit(result)
+ return True
+#! [1]
+
+#! [2]
+ def flags(self, index):
+ return Qt.ItemIsEditable | super().flags(index)
+#! [2]
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._table_view = QTableView(self)
+ self.setCentralWidget(self._table_view)
+ my_model = MyModel(self)
+ self._table_view.setModel(my_model)
+ # transfer changes to the model to the window title
+ my_model.editCompleted.connect(self.show_window_title)
+
+ @Slot(str)
+ def show_window_title(self, title):
+ self.setWindowTitle(title)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/6_treeview.py b/examples/widgets/tutorials/modelview/6_treeview.py
new file mode 100644
index 000000000..09300560c
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/6_treeview.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+from PySide6.QtWidgets import QApplication, QMainWindow, QTreeView
+
+"""PySide6 port of the widgets/tutorials/modelview/6_treeview example from Qt v6.x"""
+
+#! [1]
+class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._standard_model = QStandardItemModel(self)
+ self._tree_view = QTreeView(self)
+ self.setCentralWidget(self._tree_view)
+
+ prepared_row = self.prepare_row("first", "second", "third")
+ item = self._standard_model.invisibleRootItem()
+ # adding a row to the invisible root item produces a root element
+ item.appendRow(prepared_row)
+
+ second_row = self.prepare_row("111", "222", "333")
+ # adding a row to an item starts a subtree
+ prepared_row[0].appendRow(second_row)
+
+ self._tree_view.setModel(self._standard_model)
+ self._tree_view.expandAll()
+
+ def prepare_row(self, first, second, third):
+ return [QStandardItem(first), QStandardItem(second),
+ QStandardItem(third)]
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/7_selections.py b/examples/widgets/tutorials/modelview/7_selections.py
new file mode 100644
index 000000000..6c519c865
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/7_selections.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QItemSelection, Qt, Slot
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+from PySide6.QtWidgets import QApplication, QMainWindow, QTreeView
+
+"""PySide6 port of the widgets/tutorials/modelview/7_selections example from Qt v6.x"""
+
+#! [1]
+class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._standard_model = QStandardItemModel(self)
+ self._tree_view = QTreeView(self)
+ self.setCentralWidget(self._tree_view)
+
+ # defining a couple of items
+ root_node = self._standard_model.invisibleRootItem()
+
+ america_item = QStandardItem("America")
+ mexico_item = QStandardItem("Canada")
+ usa_item = QStandardItem("USA")
+ boston_item = QStandardItem("Boston")
+ europe_item = QStandardItem("Europe")
+ italy_item = QStandardItem("Italy")
+ rome_item = QStandardItem("Rome")
+ verona_item = QStandardItem("Verona")
+
+ # building up the hierarchy
+ root_node.appendRow(america_item)
+ root_node.appendRow(europe_item)
+ america_item.appendRow(mexico_item)
+ america_item.appendRow(usa_item)
+ usa_item.appendRow(boston_item)
+ europe_item.appendRow(italy_item)
+ italy_item.appendRow(rome_item)
+ italy_item.appendRow(verona_item)
+
+ self._tree_view.setModel(self._standard_model)
+ self._tree_view.expandAll()
+
+ # selection changes shall trigger a slot
+ selection_model = self._tree_view.selectionModel()
+ selection_model.selectionChanged.connect(self.selection_changed_slot)
+#! [1]
+
+#! [2]
+ @Slot(QItemSelection, QItemSelection)
+ def selection_changed_slot(self, new_selection, old_selection):
+ # get the text of the selected item
+ index = self._tree_view.selectionModel().currentIndex()
+ selected_text = index.data(Qt.DisplayRole)
+ # find out the hierarchy level of the selected item
+ hierarchy_level = 1
+ seek_root = index
+ while seek_root.parent().isValid():
+ seek_root = seek_root.parent()
+ hierarchy_level += 1
+ self.setWindowTitle(f"{selected_text}, Level {hierarchy_level}")
+#! [2]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/doc/modelview.rst b/examples/widgets/tutorials/modelview/doc/modelview.rst
new file mode 100644
index 000000000..017f78de1
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/doc/modelview.rst
@@ -0,0 +1,4 @@
+Model View Tutorial Examples
+============================
+
+Example code for the Model View Tutorial.
diff --git a/examples/widgets/tutorials/modelview/modelview.pyproject b/examples/widgets/tutorials/modelview/modelview.pyproject
new file mode 100644
index 000000000..3bbe9d47a
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/modelview.pyproject
@@ -0,0 +1,9 @@
+{
+ "files": ["1_readonly.py",
+ "2_formatting.py",
+ "3_changingmodel.py",
+ "4_headers.py",
+ "5_edit.py",
+ "6_treeview.py",
+ "7_selections.py"]
+}
diff --git a/examples/widgets/widgets/charactermap/charactermap.pyproject b/examples/widgets/widgets/charactermap/charactermap.pyproject
new file mode 100644
index 000000000..c2b2c2068
--- /dev/null
+++ b/examples/widgets/widgets/charactermap/charactermap.pyproject
@@ -0,0 +1,4 @@
+{
+ "files": ["main.py", "characterwidget.py", "fontinfodialog.py",
+ "mainwindow.py"]
+}
diff --git a/examples/widgets/widgets/charactermap/characterwidget.py b/examples/widgets/widgets/charactermap/characterwidget.py
new file mode 100644
index 000000000..1df2a3b74
--- /dev/null
+++ b/examples/widgets/widgets/charactermap/characterwidget.py
@@ -0,0 +1,133 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from textwrap import dedent
+
+from PySide6.QtCore import QSize, Qt, Slot, Signal
+from PySide6.QtGui import (QBrush, QFont, QFontDatabase, QFontMetrics,
+ QPainter, QPen)
+from PySide6.QtWidgets import QToolTip, QWidget
+
+COLUMNS = 16
+
+
+class CharacterWidget(QWidget):
+
+ character_selected = Signal(str)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self._display_font = QFont()
+ self._last_key = -1
+ self._square_size = int(0)
+
+ self.calculate_square_size()
+ self.setMouseTracking(True)
+
+ @Slot(QFont)
+ def update_font(self, font):
+ self._display_font.setFamily(font.family())
+ self.calculate_square_size()
+ self.adjustSize()
+ self.update()
+
+ @Slot(str)
+ def update_size(self, fontSize):
+ self._display_font.setPointSize(int(fontSize))
+ self.calculate_square_size()
+ self.adjustSize()
+ self.update()
+
+ @Slot(str)
+ def update_style(self, fontStyle):
+ old_strategy = self._display_font.styleStrategy()
+ self._display_font = QFontDatabase.font(self._display_font.family(),
+ fontStyle,
+ self._display_font.pointSize())
+ self._display_font.setStyleStrategy(old_strategy)
+ self.calculate_square_size()
+ self.adjustSize()
+ self.update()
+
+ @Slot(bool)
+ def update_font_merging(self, enable):
+ if enable:
+ self._display_font.setStyleStrategy(QFont.PreferDefault)
+ else:
+ self._display_font.setStyleStrategy(QFont.NoFontMerging)
+ self.adjustSize()
+ self.update()
+
+ def calculate_square_size(self):
+ h = QFontMetrics(self._display_font, self).height()
+ self._square_size = max(16, 4 + h)
+
+ def sizeHint(self):
+ return QSize(COLUMNS * self._square_size,
+ (65536 / COLUMNS) * self._square_size)
+
+ def _unicode_from_pos(self, point):
+ row = int(point.y() / self._square_size)
+ return row * COLUMNS + int(point.x() / self._square_size)
+
+ def mouseMoveEvent(self, event):
+ widget_position = self.mapFromGlobal(event.globalPosition().toPoint())
+ key = self._unicode_from_pos(widget_position)
+ c = chr(key)
+ family = self._display_font.family()
+ text = dedent(f'''
+ <p>Character: <span style="font-size: 24pt; font-family: {family}">
+ {c}</span><p>Value: 0x{key:x}
+ ''')
+ QToolTip.showText(event.globalPosition().toPoint(), text, self)
+
+ def mousePressEvent(self, event):
+ if event.button() == Qt.LeftButton:
+ self._last_key = self._unicode_from_pos(event.position().toPoint())
+ if self._last_key != -1:
+ c = chr(self._last_key)
+ self.character_selected.emit(f"{c}")
+ self.update()
+ else:
+ super().mousePressEvent(event)
+
+ def paintEvent(self, event):
+ with QPainter(self) as painter:
+ self.render(event, painter)
+
+ def render(self, event, painter):
+ painter = QPainter(self)
+ painter.fillRect(event.rect(), QBrush(Qt.white))
+ painter.setFont(self._display_font)
+ redraw_rect = event.rect()
+ begin_row = int(redraw_rect.top() / self._square_size)
+ end_row = int(redraw_rect.bottom() / self._square_size)
+ begin_column = int(redraw_rect.left() / self._square_size)
+ end_column = int(redraw_rect.right() / self._square_size)
+ painter.setPen(QPen(Qt.gray))
+ for row in range(begin_row, end_row + 1):
+ for column in range(begin_column, end_column + 1):
+ x = int(column * self._square_size)
+ y = int(row * self._square_size)
+ painter.drawRect(x, y, self._square_size, self._square_size)
+
+ font_metrics = QFontMetrics(self._display_font)
+ painter.setPen(QPen(Qt.black))
+ for row in range(begin_row, end_row + 1):
+ for column in range(begin_column, end_column + 1):
+ key = int(row * COLUMNS + column)
+ painter.setClipRect(column * self._square_size,
+ row * self._square_size,
+ self._square_size, self._square_size)
+
+ if key == self._last_key:
+ painter.fillRect(column * self._square_size + 1,
+ row * self._square_size + 1,
+ self._square_size, self._square_size, QBrush(Qt.red))
+
+ text = chr(key)
+ painter.drawText(column * self._square_size + (self._square_size / 2) -
+ font_metrics.horizontalAdvance(text) / 2,
+ row * self._square_size + 4 + font_metrics.ascent(),
+ text)
diff --git a/examples/widgets/widgets/charactermap/doc/charactermap.rst b/examples/widgets/widgets/charactermap/doc/charactermap.rst
new file mode 100644
index 000000000..1a38615c4
--- /dev/null
+++ b/examples/widgets/widgets/charactermap/doc/charactermap.rst
@@ -0,0 +1,8 @@
+Character Map Example
+=====================
+
+The example displays an array of characters which the user can click on
+to enter text in a line edit. The contents of the line edit can then be
+copied into the clipboard, and pasted into other applications. The
+purpose behind this sort of tool is to allow users to enter characters
+that may be unavailable or difficult to locate on their keyboards.
diff --git a/examples/widgets/widgets/charactermap/fontinfodialog.py b/examples/widgets/widgets/charactermap/fontinfodialog.py
new file mode 100644
index 000000000..aa874884f
--- /dev/null
+++ b/examples/widgets/widgets/charactermap/fontinfodialog.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Qt, qVersion, qFuzzyCompare
+from PySide6.QtGui import QGuiApplication, QFontDatabase
+from PySide6.QtWidgets import (QDialog, QDialogButtonBox,
+ QPlainTextEdit, QVBoxLayout)
+
+
+def _format_font(font):
+ family = font.family()
+ size = font.pointSizeF()
+ return f"{family}, {size}pt"
+
+
+class FontInfoDialog(QDialog):
+
+ def __init__(self, parent):
+ super().__init__(parent)
+ self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
+ main_layout = QVBoxLayout(self)
+ text_edit = QPlainTextEdit(self.text(), self)
+ text_edit.setReadOnly(True)
+ text_edit.setFont(QFontDatabase.systemFont(QFontDatabase.FixedFont))
+ main_layout.addWidget(text_edit)
+ button_box = QDialogButtonBox(QDialogButtonBox.Close, self)
+ button_box.rejected.connect(self.reject)
+ main_layout.addWidget(button_box)
+
+ def text(self):
+ default_font = QFontDatabase.systemFont(QFontDatabase.GeneralFont)
+ fixed_font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
+ title_font = QFontDatabase.systemFont(QFontDatabase.TitleFont)
+ smallest_readable_font = QFontDatabase.systemFont(QFontDatabase.SmallestReadableFont)
+
+ v = qVersion()
+ platform = QGuiApplication.platformName()
+ dpi = self.logicalDpiX()
+ dpr = self.devicePixelRatio()
+ text = f"Qt {v} on {platform}, {dpi}DPI"
+ if not qFuzzyCompare(dpr, float(1)):
+ text += f", device pixel ratio: {dpr}"
+ text += ("\n\nDefault font : " + _format_font(default_font)
+ + "\nFixed font : " + _format_font(fixed_font)
+ + "\nTitle font : " + _format_font(title_font)
+ + "\nSmallest font: " + _format_font(smallest_readable_font))
+ return text
diff --git a/examples/widgets/widgets/charactermap/main.py b/examples/widgets/widgets/charactermap/main.py
new file mode 100644
index 000000000..e84a1d8af
--- /dev/null
+++ b/examples/widgets/widgets/charactermap/main.py
@@ -0,0 +1,17 @@
+# 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 mainwindow import MainWindow
+
+"""PySide6 port of the widgets/widgets/ charactermap example from Qt6"""
+
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ window = MainWindow()
+ window.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/widgets/charactermap/mainwindow.py b/examples/widgets/widgets/charactermap/mainwindow.py
new file mode 100644
index 000000000..5f0e2bce4
--- /dev/null
+++ b/examples/widgets/widgets/charactermap/mainwindow.py
@@ -0,0 +1,167 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import Qt, QSignalBlocker, Slot
+from PySide6.QtGui import QGuiApplication, QClipboard, QFont, QFontDatabase
+from PySide6.QtWidgets import (QCheckBox, QComboBox, QFontComboBox,
+ QHBoxLayout, QLabel, QLineEdit, QMainWindow,
+ QPushButton, QScrollArea,
+ QVBoxLayout, QWidget)
+
+from characterwidget import CharacterWidget
+from fontinfodialog import FontInfoDialog
+
+
+class MainWindow(QMainWindow):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self._character_widget = CharacterWidget()
+ self._filter_combo = QComboBox()
+ self._style_combo = QComboBox()
+ self._size_combo = QComboBox()
+ self._font_combo = QFontComboBox()
+ self._line_edit = QLineEdit()
+ self._scroll_area = QScrollArea()
+ self._font_merging = QCheckBox()
+
+ file_menu = self.menuBar().addMenu("File")
+ file_menu.addAction("Quit", self.close)
+ help_menu = self.menuBar().addMenu("Help")
+ help_menu.addAction("Show Font Info", self.show_info)
+ help_menu.addAction("About &Qt", qApp.aboutQt)
+
+ central_widget = QWidget()
+
+ self._filter_label = QLabel("Filter:")
+ self._filter_combo = QComboBox()
+ self._filter_combo.addItem("All", int(QFontComboBox.AllFonts.value))
+ self._filter_combo.addItem("Scalable", int(QFontComboBox.ScalableFonts.value))
+ self._filter_combo.addItem("Monospaced", int(QFontComboBox.MonospacedFonts.value))
+ self._filter_combo.addItem("Proportional", int(QFontComboBox.ProportionalFonts.value))
+ self._filter_combo.setCurrentIndex(0)
+ self._filter_combo.currentIndexChanged.connect(self.filter_changed)
+
+ self._font_label = QLabel("Font:")
+ self._font_combo = QFontComboBox()
+ self._size_label = QLabel("Size:")
+ self._size_combo = QComboBox()
+ self._style_label = QLabel("Style:")
+ self._style_combo = QComboBox()
+ self._font_merging_label = QLabel("Automatic Font Merging:")
+ self._font_merging = QCheckBox()
+ self._font_merging.setChecked(True)
+
+ self._scroll_area = QScrollArea()
+ self._character_widget = CharacterWidget()
+ self._scroll_area.setWidget(self._character_widget)
+ self.find_styles(self._font_combo.currentFont())
+ self.find_sizes(self._font_combo.currentFont())
+
+ self._line_edit = QLineEdit()
+ self._line_edit.setClearButtonEnabled(True)
+ self._clipboard_button = QPushButton("To clipboard")
+ self._font_combo.currentFontChanged.connect(self.find_styles)
+ self._font_combo.currentFontChanged.connect(self.find_sizes)
+ self._font_combo.currentFontChanged.connect(self._character_widget.update_font)
+ self._size_combo.currentTextChanged.connect(self._character_widget.update_size)
+ self._style_combo.currentTextChanged.connect(self._character_widget.update_style)
+ self._character_widget.character_selected.connect(self.insert_character)
+
+ self._clipboard_button.clicked.connect(self.update_clipboard)
+ self._font_merging.toggled.connect(self._character_widget.update_font_merging)
+
+ controls_layout = QHBoxLayout()
+ controls_layout.addWidget(self._filter_label)
+ controls_layout.addWidget(self._filter_combo, 1)
+ controls_layout.addWidget(self._font_label)
+ controls_layout.addWidget(self._font_combo, 1)
+ controls_layout.addWidget(self._size_label)
+ controls_layout.addWidget(self._size_combo, 1)
+ controls_layout.addWidget(self._style_label)
+ controls_layout.addWidget(self._style_combo, 1)
+ controls_layout.addWidget(self._font_merging_label)
+ controls_layout.addWidget(self._font_merging, 1)
+ controls_layout.addStretch(1)
+
+ line_layout = QHBoxLayout()
+ line_layout.addWidget(self._line_edit, 1)
+ line_layout.addSpacing(12)
+ line_layout.addWidget(self._clipboard_button)
+
+ central_layout = QVBoxLayout(central_widget)
+ central_layout.addLayout(controls_layout)
+ central_layout.addWidget(self._scroll_area, 1)
+ central_layout.addSpacing(4)
+ central_layout.addLayout(line_layout)
+
+ self.setCentralWidget(central_widget)
+ self.setWindowTitle("Character Map")
+
+ @Slot(QFont)
+ def find_styles(self, font):
+ current_item = self._style_combo.currentText()
+ self._style_combo.clear()
+ styles = QFontDatabase.styles(font.family())
+ for style in styles:
+ self._style_combo.addItem(style)
+
+ style_index = self._style_combo.findText(current_item)
+
+ if style_index == -1:
+ self._style_combo.setCurrentIndex(0)
+ else:
+ self._style_combo.setCurrentIndex(style_index)
+
+ @Slot(int)
+ def filter_changed(self, f):
+ filter = QFontComboBox.FontFilter(self._filter_combo.itemData(f))
+ self._font_combo.setFontFilters(filter)
+ count = self._font_combo.count()
+ self.statusBar().showMessage(f"{count} font(s) found")
+
+ @Slot(QFont)
+ def find_sizes(self, font):
+ current_size = self._size_combo.currentText()
+ with QSignalBlocker(self._size_combo):
+ # sizeCombo signals are now blocked until end of scope
+ self._size_combo.clear()
+
+ style = QFontDatabase.styleString(font)
+ if QFontDatabase.isSmoothlyScalable(font.family(), style):
+ sizes = QFontDatabase.standardSizes()
+ for size in sizes:
+ self._size_combo.addItem(f"{size}")
+ self._size_combo.setEditable(True)
+ else:
+ sizes = QFontDatabase.smoothSizes(font.family(), style)
+ for size in sizes:
+ self._size_combo.addItem(f"{size}")
+ self._size_combo.setEditable(False)
+
+ size_index = self._size_combo.findText(current_size)
+
+ if size_index == -1:
+ self._size_combo.setCurrentIndex(max(0, self._size_combo.count() / 3))
+ else:
+ self._size_combo.setCurrentIndex(size_index)
+
+ @Slot(str)
+ def insert_character(self, character):
+ self._line_edit.insert(character)
+
+ @Slot()
+ def update_clipboard(self):
+ clipboard = QGuiApplication.clipboard()
+ clipboard.setText(self._line_edit.text(), QClipboard.Clipboard)
+ clipboard.setText(self._line_edit.text(), QClipboard.Selection)
+
+ @Slot()
+ def show_info(self):
+ screen_geometry = self.screen().geometry()
+ dialog = FontInfoDialog(self)
+ dialog.setWindowTitle("Fonts")
+ dialog.setAttribute(Qt.WA_DeleteOnClose)
+ dialog.resize(screen_geometry.width() / 4, screen_geometry.height() / 4)
+ dialog.show()
diff --git a/examples/widgets/widgets/digitalclock/digitalclock.py b/examples/widgets/widgets/digitalclock/digitalclock.py
new file mode 100644
index 000000000..f0030b356
--- /dev/null
+++ b/examples/widgets/widgets/digitalclock/digitalclock.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import sys
+
+from PySide6.QtCore import QTime, QTimer, Slot
+from PySide6.QtWidgets import QApplication, QLCDNumber
+
+
+class DigitalClock(QLCDNumber):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setSegmentStyle(QLCDNumber.Filled)
+ self.setDigitCount(8)
+
+ self.timer = QTimer(self)
+ self.timer.timeout.connect(self.show_time)
+ self.timer.start(1000)
+
+ self.show_time()
+
+ self.setWindowTitle("Digital Clock")
+ self.resize(250, 60)
+
+ @Slot()
+ def show_time(self):
+ time = QTime.currentTime()
+ text = time.toString("hh:mm:ss")
+
+ # Blinking effect
+ if (time.second() % 2) == 0:
+ text = text.replace(":", " ")
+
+ self.display(text)
+
+
+if __name__ == "__main__":
+
+ app = QApplication(sys.argv)
+ clock = DigitalClock()
+ clock.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/widgets/digitalclock/digitalclock.pyproject b/examples/widgets/widgets/digitalclock/digitalclock.pyproject
new file mode 100644
index 000000000..03c3b6bb7
--- /dev/null
+++ b/examples/widgets/widgets/digitalclock/digitalclock.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["digitalclock.py"]
+}
diff --git a/examples/widgets/widgets/digitalclock/doc/digitalclock-screenshot.png b/examples/widgets/widgets/digitalclock/doc/digitalclock-screenshot.png
new file mode 100644
index 000000000..2234d7665
--- /dev/null
+++ b/examples/widgets/widgets/digitalclock/doc/digitalclock-screenshot.png
Binary files differ
diff --git a/examples/widgets/widgets/digitalclock/doc/digitalclock.rst b/examples/widgets/widgets/digitalclock/doc/digitalclock.rst
new file mode 100644
index 000000000..ef800d9c0
--- /dev/null
+++ b/examples/widgets/widgets/digitalclock/doc/digitalclock.rst
@@ -0,0 +1,12 @@
+Digital Clock Example
+=====================
+
+The Digital Clock example shows how to use QLCDNumber to display a number with
+LCD-like digits.
+
+.. image:: digitalclock-screenshot.png
+ :width: 400
+ :alt: Digital Clock Screenshot
+
+This example also demonstrates how QTimer can be used to update a widget at
+regular intervals.
diff --git a/examples/widgets/tetrix/doc/tetrix-screenshot.png b/examples/widgets/widgets/tetrix/doc/tetrix-screenshot.png
index 2c3dade39..2c3dade39 100644
--- a/examples/widgets/tetrix/doc/tetrix-screenshot.png
+++ b/examples/widgets/widgets/tetrix/doc/tetrix-screenshot.png
Binary files differ
diff --git a/examples/widgets/tetrix/doc/tetrix.rst b/examples/widgets/widgets/tetrix/doc/tetrix.rst
index 0749de9de..0749de9de 100644
--- a/examples/widgets/tetrix/doc/tetrix.rst
+++ b/examples/widgets/widgets/tetrix/doc/tetrix.rst
diff --git a/examples/widgets/tetrix/tetrix.py b/examples/widgets/widgets/tetrix/tetrix.py
index 49fd7c4ff..3accd557a 100644
--- a/examples/widgets/tetrix/tetrix.py
+++ b/examples/widgets/widgets/tetrix/tetrix.py
@@ -9,7 +9,7 @@ import random
import sys
from PySide6.QtCore import QBasicTimer, QSize, Qt, Signal, Slot
-from PySide6.QtGui import QColor, QPainter
+from PySide6.QtGui import QColor, QPainter, QPixmap
from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QLabel,
QLCDNumber, QPushButton, QWidget)
@@ -140,6 +140,7 @@ class TetrixBoard(QFrame):
return QSize(TetrixBoard.board_width * 5 + self.frameWidth() * 2,
TetrixBoard.board_height * 5 + self.frameWidth() * 2)
+ @Slot()
def start(self):
if self._is_paused:
return
@@ -159,6 +160,7 @@ class TetrixBoard(QFrame):
self.new_piece()
self.timer.start(self.timeout_time(), self)
+ @Slot()
def pause(self):
if not self._is_started:
return
@@ -322,7 +324,7 @@ class TetrixBoard(QFrame):
with QPainter(pixmap) as painter:
painter.fillRect(pixmap.rect(), self.nextPieceLabel.palette().background())
- for int in range(4):
+ for i in range(4):
x = self._next_piece.x(i) - self._next_piece.min_x()
y = self._next_piece.y(i) - self._next_piece.min_y()
self.draw_square(painter, x * self.square_width(),
diff --git a/examples/widgets/tetrix/tetrix.pyproject b/examples/widgets/widgets/tetrix/tetrix.pyproject
index 75121ea64..75121ea64 100644
--- a/examples/widgets/tetrix/tetrix.pyproject
+++ b/examples/widgets/widgets/tetrix/tetrix.pyproject
diff --git a/examples/widgets/widgetsgallery/main.py b/examples/widgets/widgetsgallery/main.py
index 1b034d323..dadd1a91a 100644
--- a/examples/widgets/widgetsgallery/main.py
+++ b/examples/widgets/widgetsgallery/main.py
@@ -11,8 +11,6 @@ from widgetgallery import WidgetGallery
if __name__ == '__main__':
- QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
- QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication()
gallery = WidgetGallery()
gallery.show()
diff --git a/examples/widgets/widgetsgallery/widgetgallery.py b/examples/widgets/widgetsgallery/widgetgallery.py
index d96241106..6178ee0d7 100644
--- a/examples/widgets/widgetsgallery/widgetgallery.py
+++ b/examples/widgets/widgetsgallery/widgetgallery.py
@@ -6,9 +6,9 @@ import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import (QCursor, QDesktopServices, QGuiApplication, QIcon,
QKeySequence, QShortcut, QStandardItem,
- QStandardItemModel, QScreen, QWindow)
-from PySide6.QtCore import (QDateTime, QDir, QLibraryInfo, QMetaObject,
- QSysInfo, QTextStream, QTimer, Qt, qVersion)
+ QStandardItemModel)
+from PySide6.QtCore import (QDateTime, QDir, QLibraryInfo,
+ QSysInfo, QTimer, Qt, qVersion, Slot)
POEM = """Twinkle, twinkle, little star,
@@ -180,9 +180,11 @@ class WidgetGallery(QDialog):
self.windowHandle().screenChanged.connect(self.update_systeminfo)
self.update_systeminfo()
+ @Slot(str)
def change_style(self, style_name):
QApplication.setStyle(QStyleFactory.create(style_name))
+ @Slot()
def advance_progressbar(self):
cur_val = self._progress_bar.value()
max_val = self._progress_bar.maximum()
@@ -379,6 +381,7 @@ class WidgetGallery(QDialog):
timer.start(1000)
return result
+ @Slot()
def update_systeminfo(self):
"""Display system information"""
system_info = SYSTEMINFO.format(sys.version,
@@ -387,6 +390,7 @@ class WidgetGallery(QDialog):
screen_info(self))
self._systeminfo_textbrowser.setHtml(system_info)
+ @Slot()
def help_on_current_widget(self):
"""Display help on widget under mouse"""
w = QApplication.widgetAt(QCursor.pos(self.screen()))