aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/doc
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside2/doc')
-rw-r--r--sources/pyside2/doc/CMakeLists.txt28
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs/static/pyside.css236
-rw-r--r--sources/pyside2/doc/additionaldocs.lst12
-rw-r--r--sources/pyside2/doc/api.rst67
-rw-r--r--sources/pyside2/doc/conf.py.in2
-rw-r--r--sources/pyside2/doc/considerations.rst85
-rw-r--r--sources/pyside2/doc/contents.rst10
-rw-r--r--sources/pyside2/doc/deployment-fbs.rst16
-rw-r--r--sources/pyside2/doc/deployment-pyinstaller.rst127
-rw-r--r--sources/pyside2/doc/deployment.rst87
-rw-r--r--sources/pyside2/doc/examples/images/tabbedbrowser.png (renamed from sources/pyside2/doc/tutorials/examples/images/tabbedbrowser.png)bin37147 -> 37147 bytes
-rw-r--r--sources/pyside2/doc/examples/index.rst14
-rw-r--r--sources/pyside2/doc/examples/tabbedbrowser.rst (renamed from sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtCore.ClassInfo.rst (renamed from sources/pyside2/doc/extras/PySide.QtCore.ClassInfo.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtCore.Signal.rst (renamed from sources/pyside2/doc/extras/PySide.QtCore.Signal.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtCore.Slot.rst (renamed from sources/pyside2/doc/extras/PySide.QtCore.Slot.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtCore.rst (renamed from sources/pyside2/doc/extras/PySide.QtCore.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtGui.rst (renamed from sources/pyside2/doc/extras/PySide.QtGui.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtHelp.rst (renamed from sources/pyside2/doc/extras/PySide.QtHelp.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtMultimedia.rst (renamed from sources/pyside2/doc/extras/PySide.QtMultimedia.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtNetwork.rst (renamed from sources/pyside2/doc/extras/PySide.QtNetwork.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtOpenGL.rst (renamed from sources/pyside2/doc/extras/PySide.QtOpenGL.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtScript.rst (renamed from sources/pyside2/doc/extras/PySide.QtScript.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtScriptTools.rst (renamed from sources/pyside2/doc/extras/PySide.QtScriptTools.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtSql.rst (renamed from sources/pyside2/doc/extras/PySide.QtSql.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtSvg.rst (renamed from sources/pyside2/doc/extras/PySide.QtSvg.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtTest.rst (renamed from sources/pyside2/doc/extras/PySide.QtTest.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtUiTools.rst (renamed from sources/pyside2/doc/extras/PySide.QtUiTools.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtWebKit.rst (renamed from sources/pyside2/doc/extras/PySide.QtWebKit.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtXml.rst (renamed from sources/pyside2/doc/extras/PySide.QtXml.rst)0
-rw-r--r--sources/pyside2/doc/extras/QtXmlPatterns.rst (renamed from sources/pyside2/doc/extras/PySide.QtXmlPatterns.rst)0
-rw-r--r--sources/pyside2/doc/faq.rst49
-rw-r--r--sources/pyside2/doc/gettingstarted-linux.rst94
-rw-r--r--sources/pyside2/doc/gettingstarted-macOS.rst93
-rw-r--r--sources/pyside2/doc/gettingstarted-windows.rst104
-rw-r--r--sources/pyside2/doc/gettingstarted.rst144
-rw-r--r--sources/pyside2/doc/index.rst127
-rw-r--r--sources/pyside2/doc/modules.rst87
-rw-r--r--sources/pyside2/doc/overview.rst42
-rw-r--r--sources/pyside2/doc/pyhtml2devhelp.py256
-rw-r--r--sources/pyside2/doc/pyside-examples/examples.qdoc32
-rw-r--r--sources/pyside2/doc/pyside-examples/images/pyside2example-classwizard.pngbin0 -> 57931 bytes
-rw-r--r--sources/pyside2/doc/pyside-examples/images/pyside2example-stardelegate.pngbin0 -> 22482 bytes
-rw-r--r--sources/pyside2/doc/pyside-examples/images/screenshot_hello.pngbin0 -> 21193 bytes
-rw-r--r--sources/pyside2/doc/pyside-examples/pyside2-classwizard.qdoc39
-rw-r--r--sources/pyside2/doc/pyside-examples/pyside2-stardelegate.qdoc39
-rw-r--r--sources/pyside2/doc/pysideapi2.rst84
-rw-r--r--sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in12
-rw-r--r--sources/pyside2/doc/quickstart.rst107
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/qml.rst8
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/uifiles.rst31
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/widgets.rst12
-rw-r--r--sources/pyside2/doc/tutorials/datavisualize/add_chart.rst2
-rw-r--r--sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst2
-rw-r--r--sources/pyside2/doc/tutorials/datavisualize/filter_data.rst1
-rw-r--r--sources/pyside2/doc/tutorials/expenses/expenses.rst141
-rw-r--r--sources/pyside2/doc/tutorials/index.rst17
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter1/chapter1.rst89
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter1/createdb.py131
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter1/images/chapter1_books.pngbin0 -> 25391 bytes
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h160
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter1/main.py59
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp143
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h83
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py134
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst93
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py131
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books.pngbin0 -> 34658 bytes
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.pngbin0 -> 44122 bytes
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/images/star.pngbin0 -> 782 bytes
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter2/main.py63
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate-old.py134
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py133
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc5
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp171
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py137
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui149
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst121
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py131
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/images/chapter3-books.pngbin0 -> 34624 bytes
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/images/star.pngbin0 -> 782 bytes
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/main-old.py52
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/chapter3/main.py53
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/hello_world_ex.py76
-rw-r--r--sources/pyside2/doc/tutorials/portingguide/index.rst196
-rw-r--r--sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst16
-rw-r--r--sources/pyside2/doc/videos.rst28
87 files changed, 3814 insertions, 881 deletions
diff --git a/sources/pyside2/doc/CMakeLists.txt b/sources/pyside2/doc/CMakeLists.txt
index 36f770367..8eb4eca06 100644
--- a/sources/pyside2/doc/CMakeLists.txt
+++ b/sources/pyside2/doc/CMakeLists.txt
@@ -70,6 +70,11 @@ foreach(moduleIn ${all_module_shortnames})
endif()
endforeach()
+#Appending the additional qdocconf that describes the pyside-examples
+#doc project.
+configure_file("qtmodules/pyside-examples.qdocconf.in" "${CMAKE_CURRENT_LIST_DIR}/qtmodules/pyside-examples.qdocconf" @ONLY)
+file(APPEND "pyside.qdocconf.in" "\@CMAKE_CURRENT_LIST_DIR\@/qtmodules/pyside-examples.qdocconf\n")
+
set(typeSystemDocXmlContents "${typeSystemDocXmlContents}\n</typesystem>\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/typesystem_doc.xml" "${typeSystemDocXmlContents}")
@@ -82,13 +87,15 @@ set(QDOC_TYPESYSTEM_PATH "${pyside2_SOURCE_DIR}${PATH_SEP}${pyside2_BINARY_DIR}"
add_custom_target(qdoc
# Use dummy Qt version information, QDoc needs it but has no effect on WebXML output
- COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${CMAKE_CURRENT_LIST_DIR}/src QT_INSTALL_DOCS=${QT_SRC_DIR}/doc QT_VERSION=1.0.0 QT_VER=1.0 QT_VERSION_TAG=100
+ COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${CMAKE_CURRENT_LIST_DIR}/src QT_INSTALL_DOCS=${QT_SRC_DIR}/doc
+ QT_VERSION=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}
+ QT_VER=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}
+ QT_VERSION_TAG=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}
qdoc pyside.qdocconf -single-exec -installdir ${DOC_DATA_DIR} -outputdir ${DOC_DATA_DIR}
COMMENT "Running qdoc against Qt source code..."
SOURCE "pyside.qdocconf")
add_custom_target(apidoc
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst
COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b html ${CMAKE_CURRENT_BINARY_DIR}/rst html
#copying shiboken2 (including ApiExtractor) doc htmls
COMMENT "Copying over the Shiboken2 doc HTMLs..."
@@ -102,6 +109,7 @@ add_custom_target(apidoc
configure_file("conf.py.in" "rst/conf.py" @ONLY)
add_custom_target("docrsts"
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst
COMMAND Shiboken2::shiboken2 --generator-set=qtdoc ${docHeader}
--include-paths="${QT_INCLUDE_DIR}${PATH_SEP}${pyside2_SOURCE_DIR}${PATH_SEP}${TS_ROOT}"
--api-version=${SUPPORTED_QT_VERSION}
@@ -109,9 +117,9 @@ add_custom_target("docrsts"
--library-source-dir=${QT_SRC_DIR}
--documentation-data-dir=${DOC_DATA_DIR}/webxml
--output-directory=${CMAKE_CURRENT_BINARY_DIR}/rst
- --documentation-code-snippets-dir=${CMAKE_CURRENT_SOURCE_DIR}/codesnippets/doc/src/snippets${PATH_SEP}${CMAKE_CURRENT_SOURCE_DIR}/codesnippets/examples
- --documentation-extra-sections-dir=${CMAKE_CURRENT_SOURCE_DIR}/extras
- --additional-documentation=${CMAKE_CURRENT_LIST_DIR}/additionaldocs.lst
+ --documentation-code-snippets-dir=${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets/doc/src/snippets${PATH_SEP}${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets/examples
+ --documentation-extra-sections-dir=${CMAKE_CURRENT_BINARY_DIR}/rst/extras
+ --additional-documentation=${CMAKE_CURRENT_BINARY_DIR}/rst/additionaldocs.lst
${CMAKE_CURRENT_BINARY_DIR}/typesystem_doc.xml
WORKING_DIRECTORY ${${module}_SOURCE_DIR}
COMMENT "Running generator to generate documentation..."
@@ -129,19 +137,9 @@ add_dependencies(apidoc docrsts licensedocrsts)
add_dependencies(licensedocrsts docrsts)
add_dependencies(docrsts qdoc)
-# #create devhelp file
-# add_custom_target(apidevhelp
-# COMMAND python;${CMAKE_CURRENT_SOURCE_DIR}/pyhtml2devhelp.py;${CMAKE_BINARY_DIR}/apidoc/html;index.html >
-# ${CMAKE_BINARY_DIR}/apidoc/html/PySide.devhelp;${BINDING_API_VERSION}&&;
-# gzip;-9v;-f;${CMAKE_BINARY_DIR}/apidoc/html/PySide.devhelp
-# COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_INSTALL_PREFIX}/share/devhelp/books"
-# COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_INSTALL_PREFIX}/share/doc/${BINDING_NAME}/html" "${CMAKE_INSTALL_PREFIX}/share/devhelp/books/${BINDING_NAME}"
-# )
#install files
add_custom_target(apidocinstall
COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/share/doc/PySide2-${BINDING_API_VERSION} && cp -rv ${CMAKE_CURRENT_BINARY_DIR}/html/* ${CMAKE_INSTALL_PREFIX}/share/doc/PySide-${BINDING_API_VERSION}
)
add_dependencies(apidocinstall apidoc)
-# add_dependencies(apidocinstall apidevhelp)
-
diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css
index 956e3113b..19275b545 100644
--- a/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css
+++ b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css
@@ -3,8 +3,8 @@
/* -- admonitions -- */
div.admonition {
- margin: 1em 0 1em;
- padding: 7px;
+ margin: 1.5em 0 1.5em;
+ padding: 0;
}
div.admonition dt {
@@ -19,6 +19,23 @@ p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
+
+div.admonition code {
+ font-family: inherit;
+}
+
+p.admonition-title + p {
+ padding-left: 1em;
+}
+
+div.admonition a:after {
+ content: ', ';
+}
+
+div.admonition a:last-child:after {
+ content: '';
+}
+
.body {
width: 100%
}
@@ -35,18 +52,21 @@ div.body p.centered {
margin-top: 25px;
}
+div.warning, div.seealso, div.note {
+ padding: 6px 0px 6px 10px;
+ border: none;
+}
+
div.warning {
background-color: #ffe4e4;
- border: 1px solid #f66;
}
div.seealso {
- background-color: #ffffcc;
- border: 1px solid #ffff66;
+ background-color: #fff2d6;
}
div.note {
- border: 1px solid #e3e3e3;
+ background-color: #f3f3f4;
}
table.docutils {
@@ -91,7 +111,7 @@ h2 em {
.body blockquote {
border: none;
padding-left: 0;
- margin-bottom: 2em;
+ margin-bottom: 1.5em;
}
.sphinxsidebar {
@@ -146,11 +166,8 @@ h2 em {
display: block;
padding: 5px;
margin: 0 10px 10px 0;
- border: 1px solid #ddd;
- background-color: #f4f4f4;
- -moz-border-radius:6px;
- -webkit-border-radius:6px;
- -khtml-border-radius:6px;
+ border: none;
+ background-color: #e2e2e2;
}
.section .docutils.container td {
@@ -290,14 +307,23 @@ tt.descname {
}
#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul {
- list-style: none;
- margin: 0px;
- padding: 10px;
+ margin: 0;
+ padding: 6px;
border: 1px solid #ddd;
- background-color: #f4f4f4;
- -moz-border-radius:10px;
- -webkit-border-radius:10px;
- -khtml-border-radius:10px;
+ border-radius: 0;
+ background-color: #e2e2e2;
+}
+
+#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p {
+ margin: 0;
+ padding: 0;
+}
+
+#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li {
+ list-style: none;
+ margin: 5px;
+ padding: 0;
+ font-size: 90%;
}
#synopsis span.pre {
@@ -312,11 +338,94 @@ tt.descname {
margin: 0px;
margin-bottom: 10px;
padding: 10px;
- border: 1px solid #ddd;
- background-color: #f4f4f4;
- -moz-border-radius:10px;
- -webkit-border-radius:10px;
- -khtml-border-radius:10px;
+ font-weight: bold;
+ background-color: #e2e2e2;
+ border: none;
+ border-radius: 0;
+}
+
+#detailed-description dd > blockquote,
+#detailed-description dd > .field-list {
+ font-family: 'Droid Sans Mono';
+ font-size: small;
+ border-left: 10px solid #e2e2e2;
+ padding-left: 10px;
+ margin-bottom: 1.5em;
+}
+
+#detailed-description dd > blockquote blockquote {
+ border: none;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd,
+#detailed-description .method .field-odd,
+#detailed-description .staticmethod .field-odd,
+#detailed-description .attribute .field-odd {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+
+}
+
+#detailed-description .class .field-even,
+#detailed-description .method .field-even,
+#detailed-description .staticmethod .field-even,
+#detailed-description .attribute .field-even {
+ margin: 0;
+ padding: 1px 0 0 0;
+ background-color: #ffffff;
+}
+
+#detailed-description .class .field-odd li,
+#detailed-description .method .field-odd li,
+#detailed-description .staticmethod .field-odd li,
+#detailed-description .attribute .field-odd li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+}
+
+#detailed-description .class .field-even li,
+#detailed-description .method .field-even li,
+#detailed-description .staticmethod .field-even li,
+#detailed-description .attribute .field-even li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd p,
+#detailed-description .method .field-odd p,
+#detailed-description .staticmethod .field-odd p,
+#detailed-description .attribute .field-odd p{
+ margin: 0;
+ margin-left: 20px;
+
+}
+
+#detailed-description .class .field-even p,
+#detailed-description .method .field-even p,
+#detailed-description .staticmethod .field-even p,
+#detailed-description .attribute .field-even p{
+ margin: 0;
+ margin-left: 20px;
+}
+
+#detailed-description .class .field-odd p:last-child,
+#detailed-description .method .field-odd p:last-child,
+#detailed-description .staticmethod .field-odd p:last-child,
+#detailed-description .attribute .field-odd p:last-child {
+ margin-bottom: 10px;
+
+}
+
+#detailed-description .class .field-even p:last-child,
+#detailed-description .method .field-even p:last-child,
+#detailed-description .staticmethod .field-even p:last-child,
+#detailed-description .attribute .field-even p:last-child{
+ margin-bottom: 10px;
}
.document dl.attribute,
@@ -333,6 +442,10 @@ tt.descname {
padding-left: 1em;
}
+#detailed-description .attribute td:nth-child(1) {
+ font-family: 'Droid Sans Mono';
+}
+
/* Qt theme */
#navbar {
position:fixed;
@@ -907,7 +1020,8 @@ body {
color:#404244;
}
ol,ul {
- list-style:none
+ list-style-type: square;
+ color: #17a81a;
}
.body ol,.body ul {
margin-top:0.75em;
@@ -1056,9 +1170,15 @@ div.multi-column div {
}
.col-2 h2,.toc h3,.sidebar-content h2,
.sidebar-content h3,.sectionlist h2,
+.sphinxsidebar {
+ position: fixed;
+ overflow: scroll;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
.sphinxsidebar h3 {
- font-weight:400;
- margin-bottom:1em
+ font-weight: bold;
+ margin-bottom:1em;
}
.toc h3 a {
color:#404244
@@ -1344,7 +1464,7 @@ div.pre {
height:auto
}
pre, .LegaleseLeft {
- background-color:#3a4055;
+ background-color:#222840;
color:#fff;
display:block;
font-family:"Droid Sans Mono";
@@ -1425,6 +1545,13 @@ pre span.wrap {
margin:4px;
opacity:0.65
}
+
+span.pre {
+ color: #09102d;
+ background-color: #e4e4e4;
+ padding: 3px;
+}
+
span.wrap:hover {
opacity:1
}
@@ -1450,6 +1577,10 @@ span.wrap:active {
code,.codelike {
font-family:"Droid Sans Mono"
}
+#detailed-description .function dt > code,
+#detailed-description .function dt > em {
+ font-weight:bold
+}
h3.fn code {
font-size:0.75em;
float:right;
@@ -1890,3 +2021,52 @@ a.plink, a.headerlink {
a.plink::before {
content:'\00B6'
}
+
+table.special {
+ border: 3px;
+ padding: 0px;
+ border-collapse: separate;
+ border-spacing: 20px;
+ line-height: 1.5em;
+}
+
+.special p {
+ text-align: center;
+ color: #3a4055;
+}
+
+.special a {
+ display: block;
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special a:hover {
+ border-bottom: 0;
+ text-decoration: none;
+}
+
+.special strong {
+ color: #17a81a;
+ font-size: 110%;
+ font-weight: normal;
+}
+
+table.special th,
+table.special td {
+ border: 1px solid #888;
+ padding-top: 14px;
+ padding-bottom: 14px;
+ padding-left: 6px;
+ padding-right: 5px;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -khtml-border-radius: 5px;
+}
+
+.special td:hover {
+ padding-top: 2px;
+ padding-bottom: 2px;
+ border-bottom: 4px solid #41cd52;
+}
diff --git a/sources/pyside2/doc/additionaldocs.lst b/sources/pyside2/doc/additionaldocs.lst
index 037cb60f7..44c562424 100644
--- a/sources/pyside2/doc/additionaldocs.lst
+++ b/sources/pyside2/doc/additionaldocs.lst
@@ -51,6 +51,18 @@
# fi
# done
# A line enclosed in [] denotes a (relative) target directory
+[pyside-examples]
+all-pyside-examples.webxml
+pyside2examples-widgets-dialogs-classwizard-classwizard-pyproject.webxml
+pyside2examples-widgets-dialogs-classwizard-classwizard-py.webxml
+pyside2examples-widgets-dialogs-classwizard-classwizard-qrc.webxml
+pyside2examples-widgets-dialogs-classwizard-classwizard-rc-py.webxml
+pyside2examples-widgets-dialogs-classwizard-example.webxml
+pyside2examples-widgets-itemviews-stardelegate-example.webxml
+pyside2examples-widgets-itemviews-stardelegate-stardelegate-pyproject.webxml
+pyside2examples-widgets-itemviews-stardelegate-stardelegate-py.webxml
+pyside2examples-widgets-itemviews-stardelegate-stareditor-py.webxml
+pyside2examples-widgets-itemviews-stardelegate-starrating-py.webxml
[overviews]
animation-overview.webxml
diff --git a/sources/pyside2/doc/api.rst b/sources/pyside2/doc/api.rst
new file mode 100644
index 000000000..34d065f49
--- /dev/null
+++ b/sources/pyside2/doc/api.rst
@@ -0,0 +1,67 @@
+.. _pyside-api:
+|project| Modules
+=================
+
+Basic modules
+-------------
+ These are the main modules that will help you build a Widget based UI.
+
+ :mod:`Qt Core <PySide2.QtCore>`
+ Provides core non-GUI functionality, like signal and slots, properties, base classes of item models, serialization, etc.
+ :mod:`Qt GUI <PySide2.QtGui>`
+ Extends QtCore with GUI functionality: Events, windows and screens, OpenGL and raster-based 2D painting, images.
+ :mod:`Qt Widgets <PySide2.QtWidgets>`
+ Ready to use Widgets for your application, including also graphical elements for your UI.
+
+QML and Qt Quick
+----------------
+ If you want to use the `QML Language <https://doc.qt.io/qt-5.qmlapplications>`, these
+ modules will help you interact with it from Python.
+
+ :mod:`Qt QML <PySide2.QtQml>`
+ Base Python API to interact with the QML module.
+ :mod:`Qt Quick <PySide2.QtQuick>`
+ Provides classes for embedding Qt Quick in Qt applications.
+ :mod:`Qt QuickWidgets <PySide2.QtQuickWidgets>`
+ Provides the QQuickWidget class for embedding Qt Quick in widget-based applications.
+
+Data visualization
+------------------
+
+ Charts and diagrams: these modules provide a large amount
+ of classes that can help you include these elements in your UI.
+
+ :mod:`Qt Charts <PySide2.QtCharts>`
+ Provides a set of easy to use chart components.
+ :mod:`Qt DataVisualization <PySide2.QtDataVisualization>`
+ Provides a way to visualize data in 3D as bar, scatter, and surface graphs.
+
+Multimedia
+-----------
+
+ Audio, video, and hardware interaction: check these modules if you are
+ looking for multimedia solutions.
+
+ :mod:`Qt Multimedia <PySide2.QtMultimedia>`
+ Provides low-level multimedia functionality.
+ :mod:`Qt MultimediaWidgets <PySide2.QtMultimediaWidgets>`
+ Provides the widget-based multimedia API.
+
+WebEngine
+---------
+
+ If your project is based on a browser or the features around web
+ based applications, these modules will help you to interact with them.
+
+ :mod:`Qt WebEngineWidgets <PySide2.QtWebEngineWidgets>`
+ Provides widgets that can handle web content.
+ :mod:`Qt WebChannel <PySide2.QtWebChannel>`
+ Enables peer-to-peer communication between a server and a client
+ (HTML/JavaScript or QML application).
+
+All the modules
+---------------
+
+ Here is a complete list of modules supported by |pymodname|.
+
+ :doc:`Modules <modules>`
diff --git a/sources/pyside2/doc/conf.py.in b/sources/pyside2/doc/conf.py.in
index 33f408354..e197b1ac7 100644
--- a/sources/pyside2/doc/conf.py.in
+++ b/sources/pyside2/doc/conf.py.in
@@ -75,7 +75,7 @@ release = '@BINDING_API_VERSION_FULL@'
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
-exclude_trees = ['_build', 'extras']
+exclude_patterns = ['_build', 'extras']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
diff --git a/sources/pyside2/doc/considerations.rst b/sources/pyside2/doc/considerations.rst
new file mode 100644
index 000000000..cf08947af
--- /dev/null
+++ b/sources/pyside2/doc/considerations.rst
@@ -0,0 +1,85 @@
+.. _pysideapi2:
+
+|project| Considerations
+=========================
+
+API Changes
+-----------
+
+One of the goals of |pymodname| is to be API compatible with PyQt5,
+with certain exceptions.
+
+The latest considerations and known issues will be also reported
+in the `wiki <https://wiki.qt.io/Qt_for_Python/Considerations>`_.
+
+__hash__() function return value
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The hash value returned for the classes :class:`PySide2.QtCore.QDate`,
+:class:`PySide2.QtCore.QDateTime`, :class:`PySide2.QtCore.QTime`, :class:`PySide2.QtCore.QUrl`
+will be based on their string representations, thus objects with the same value will produce the
+same hash.
+
+
+QString
+~~~~~~~~
+
+Methods and functions that change the contents of a QString argument were modified to receive an
+immutable Python Unicode (or str) and return another Python Unicode/str as the modified string.
+
+The following methods had their return types modified this way:
+
+**Classes:** QAbstractSpinBox, QDateTimeEdit, QDoubleSpinBox, QSpinBox, QValidator
+
+* ``fixup(string): string``
+* ``validate(string, int): [QValidator.State, string, int]``
+
+**Classes:** QDoubleValidator, QIntValidator, QRegExpValidator
+
+* ``validate(string, int): [QValidator.State, string, int]``
+
+**Class:** QClipboard
+
+* ``text(string, QClipboard.Mode mode=QClipboard.Clipboard): [string, string]``
+
+**Class:** QFileDialog
+
+Instead of ``getOpenFileNameAndFilter()``, ``getOpenFileNamesAndFilter()`` and
+``getSaveFileNameAndFilter()`` like PyQt does, PySide has modified the original methods to return
+a tuple.
+
+* ``getOpenFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [string, filter]``
+* ``getOpenFileNames(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [list(string), filter]``
+* ``getSaveFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [string, filter]``
+
+**Class:** QWebPage
+
+* ``javaScriptPrompt(QWebFrame, string, string): [bool, string]``
+
+**Classes:** QFontMetrics and QFontMetricsF
+
+They had two new methods added. Both take a string of one character and convert to a QChar
+(to call the C++ counterpart):
+
+* ``widthChar(string)``
+* ``boundingRectChar(string)``
+
+
+QTextStream
+~~~~~~~~~~~
+
+Inside this class some renames were applied to avoid clashes with native Python functions.
+They are: ``bin_()``, ``hex_()`` and ``oct_()``.
+The only modification was the addition of '_' character.
+
+
+QVariant
+~~~~~~~~
+
+As ``QVariant`` was removed, any function expecting it can receive any Python object (``None`` is
+an invalid ``QVariant``).
+The same rule is valid when returning something: the returned ``QVariant`` will be converted to
+the its original Python object type.
+
+When a method expects a ``QVariant::Type`` the programmer can use a string (the type name) or the
+type itself.
diff --git a/sources/pyside2/doc/contents.rst b/sources/pyside2/doc/contents.rst
index 675a5b73a..2a6f08266 100644
--- a/sources/pyside2/doc/contents.rst
+++ b/sources/pyside2/doc/contents.rst
@@ -4,13 +4,15 @@
.. toctree::
:maxdepth: 2
- overview.rst
- faq.rst
+ quickstart.rst
gettingstarted.rst
+ api.rst
tutorials/index.rst
+ examples/index.rst
+ videos.rst
deployment.rst
- pysideapi2.rst
- licenses.rst
+ considerations.rst
+ shiboken2/index.rst
Module Index
============
diff --git a/sources/pyside2/doc/deployment-fbs.rst b/sources/pyside2/doc/deployment-fbs.rst
index 6375da61e..311c78ac7 100644
--- a/sources/pyside2/doc/deployment-fbs.rst
+++ b/sources/pyside2/doc/deployment-fbs.rst
@@ -1,15 +1,17 @@
-===============
|project| & fbs
-===============
+####################
-`fbs <https://build-system.fman.io>`_ provides a powerful environment for packaging,
+`fbs`_ provides a powerful environment for packaging,
creating installers, and signing your application. It also lets you manage updates to
your application. As it is based on PyInstaller, it supports Linux, macOS, and Windows.
-You can read the `official tutorial <https://github.com/mherrmann/fbs-tutorial>`_ for more
-details on how to use `fbs`, or check the
-`documentation <https://build-system.fman.io/manual/>`_ for a complete set of features and
-options.
+You can read the `fbs tutorial`_ for more details about how to use
+`fbs`, or check out the `fbs manual`_ for a complete set of features
+and options.
+
+.. _fbs tutorial: https://github.com/mherrmann/fbs-tutorial
+
+.. _fbs manual: https://build-system.fman.io/manual/
Preparation
===========
diff --git a/sources/pyside2/doc/deployment-pyinstaller.rst b/sources/pyside2/doc/deployment-pyinstaller.rst
index 7a720f558..e7ed643f6 100644
--- a/sources/pyside2/doc/deployment-pyinstaller.rst
+++ b/sources/pyside2/doc/deployment-pyinstaller.rst
@@ -1,56 +1,49 @@
-=======================
|project| & PyInstaller
-=======================
+#######################
-`PyInstaller <https://www.pyinstaller.org/>`_ lets you freeze your python
-application into a stand-alone executable.
-The supported platforms are Linux, macOS, Windows, FreeBSD, and others.
+`PyInstaller <https://www.pyinstaller.org/>`_ lets you freeze your python application into a
+stand-alone executable. This installer supports Linux, macOS, Windows, and more; and is also
+compatible with 3rd-party Python modules, such as |pymodname|.
-One of the main goals of `PyInstaller` is to be compatible with 3rd-party
-Python modules, for example: |pymodname|.
-
-You can read the `official documentation <https://www.pyinstaller.org/documentation.html>`_
-to clarify any further question, and remember to contribute to
-`the project <https://github.com/pyinstaller/pyinstaller>`_
-by filing issues if you find any, or contributing to their development.
+For more details, see the `official documentation <https://www.pyinstaller.org/documentation.html>`_.
Preparation
===========
-Installing `PyInstaller` can be done using **pip**::
+Install the `PyInstaller` via **pip** with the following command::
pip install pyinstaller
-If you are using a virtual environment, remember to activate it before
-installing `PyInstaller` into it.
+If you're using a virtual environment, remember to activate it before installing `PyInstaller`.
-After the installation, the `pyinstaller` binary will be located in the `bin/`
-directory of your virtual environment, or where your Python executable is located.
-If that directory is not in your `PATH`, include the whole path when executing `pyinstaller`.
+After installation, the `pyinstaller` binary is located in your virtual environment's `bin/`
+directory, or where your Python executable is located. If that directory isn't in your `PATH`,
+include the whole path when you run `pyinstaller`.
.. warning:: If you already have a PySide2 or Shiboken2 version installed in your
- system path, PyInstaller will pick them instead of your virtual environment
- version.
+ system path, PyInstaller uses them instead of your virtual environment version.
-Freezing an application
+Freeze an application
=======================
-`PyInstaller` has many options that you can use.
-To learn more about them you can just run `pyinstaller -h`.
+`PyInstaller` has many options that you can use. To list them all, run `pyinstaller -h`.
-Two main features are the option to package the whole project
-(including the shared libraries) into one executable file (`--onefile`),
-and to place it in a directory containing the libraries.
+There are two main features:
-Additionally, for Windows you can enable opening a console during the
-execution with the option, `-c` (or equivalent `--console` or `--nowindowed`).
-Further, you can specify to not open such console window
-on macOS and Windows with the option, `-w` (or equivalent `--windowed` or `--noconsole`).
+ * the option to package the whole project (including shared libraries) into one executable file
+ (`--onefile`)
+ * the option to place it in a directory containing the libraries
-Creating an example
--------------------
+Additionally, on Windows when the command is running, you can open a console with the `-c` option
+(or `--console` or `--nowindowed` equivalent).
-Now, consider the following simple script, named `hello.py`::
+Otherwise, you can specify to not open such a console window on macOS and Windows with the `-w`
+option (or `--windowed` or `--noconsole` equivalent).
+
+Create an example
+-----------------
+
+Now, consider the following script, named `hello.py`::
import sys
import random
@@ -91,68 +84,58 @@ Now, consider the following simple script, named `hello.py`::
sys.exit(app.exec_())
-As it has a UI, you will use the `--windowed` option.
+Since it has a UI, you use the `--windowed` option.
The command line to proceed looks like this::
pyinstaller --name="MyApplication" --windowed hello.py
-This process creates a `dist/` and `build/` directory.
-The application executable and the required shared libraries are
-placed in `dist/MyApplication`.
+This process creates two directories: `dist/` and `build/`. The application executable and the
+required shared libraries are placed in `dist/MyApplication`.
-To run the application you can go to `dist/MyApplication` and
-execute the program::
+To run the application, go to `dist/MyApplication` and run the program::
cd dist/MyApplication/
./MyApplication
-.. note:: The directory inside `dist/` and the executable will have
-the same name.
+.. note:: The directory inside `dist/` and the executable have the same name.
-If you prefer to have everything bundled into one executable,
-without the shared libraries next to it, you can use the option
-`--onefile`::
+Use the `--onefile` option if you prefer to have everything bundled into one executable, without
+the shared libraries next to it::
pyinstaller --name="MyApplication" --windowed --onefile hello.py
-This process takes a bit longer, but in the end you will have one
-executable in the `dist/` directory::
+This process takes a bit longer, but in the end you have one executable in the `dist/` directory::
cd dist/
./MyApplication
-Current Caveats To Be Aware Of
-==============================
+Some Caveats
+============
-PyInstaller Problem
--------------------
+PyInstaller Issue
+-----------------
-As already mentioned, `PyInstaller` will pick a system installation
-of PySide2 or Shiboken2 instead of your virtualenv version without
-notice, if it exists. This may not be a problem if those two
-versions are the same.
+As mentioned before, if available, `PyInstaller` picks a system installation of PySide2 or
+Shiboken2 instead of your `virtualenv` version without notice. This is negligible if those
+two versions are the same.
-If you are working with different versions, this can result in
-frustrating debugging sessions. You could think you are testing the
-latest version, but `PyInstaller` could be working with an older
+If you're working with different versions, this can result in frustrating debugging sessions
+when you think you are testing the latest version, but `PyInstaller` is working with an older
version.
-Problem with numpy in Python 2.7.16
------------------------------------
+Issue with numpy in Python 2.7.16
+---------------------------------
-A recent problem of PyInstaller is the appearance of Python 2.7.16.
-This Python version creates a problem that is known from Python 3
-as a `Tcl/Tk` problem. This does rarely show up in Python 3 because
-`Tcl/Tk` is seldom used with `PyInstaller.
+A recent issue with PyInstaller is the appearance of Python 2.7.16. This Python version creates
+an issue that is known from Python 3 as a `Tcl/Tk` problem. This rarely shows up in Python 3
+because `Tcl/Tk` is seldom used with `PyInstaller`.
-On Python 2.7.16, this problem is very much visible, as many are
-using numpy. For some reason, installing `numpy` creates a
-dependency to `Tcl/Tk`, which can be circumvented only by explicitly
-excluding `Tcl/Tk` related things by adding this line to the analysis
-section of the spec-file::
+On Python 2.7.16, this problem is common, as many developers use numpy. For some reason,
+installing `numpy` creates a dependency to `Tcl/Tk`, which can be circumvented only by explicitly
+excluding `Tcl/Tk` by adding this line to spec-file's analysis section::
excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'],
@@ -160,16 +143,16 @@ section of the spec-file::
Safety Instructions
-------------------
-o When using `PyInstaller` with `virtualenv`, make sure that there is no system
+- When using `PyInstaller` with `virtualenv`, make sure that there is no system
installation of PySide2 or shiboken2.
-o Before compiling, use `pip -uninstall pyside2 shiboken2 -y` multiple times, until
+- Before compiling, use `pip -uninstall pyside2 shiboken2 -y` multiple times, until
none of the programs are found anymore.
-o Pip is usually a good tool. But to be 100 % sure, you should directly remove
+- Pip is usually a good tool. But to be 100 % sure, you should directly remove
the PySide2 and shiboken2 folders from site-packages.
-o Be sure to use the right version of pip. The safest way to really run the right
+- Be sure to use the right version of pip. The safest way to really run the right
pip, is to use the Python that you mean: Instead of the pip command, better use::
<path/to/your/>python -m pip
diff --git a/sources/pyside2/doc/deployment.rst b/sources/pyside2/doc/deployment.rst
index eb8d77b0d..f33e3cac0 100644
--- a/sources/pyside2/doc/deployment.rst
+++ b/sources/pyside2/doc/deployment.rst
@@ -1,6 +1,5 @@
-==========
-Deployment
-==========
+|project| Deployment
+====================
Deploying or freezing an application is a crucial part of many Python projects.
Most large projects are not based on a single Python file, so
@@ -12,11 +11,17 @@ Here are a few distribution options that you could use:
3. Freezing the application into a single binary file or a directory.
If you choose the **third** option, consider using one of these tools:
- * `fbs <https://build-system.fman.io/>`_,
- * `PyInstaller <https://www.pyinstaller.org/>`_,
- * `cx_Freeze <https://anthony-tuininga.github.io/cx_Freeze/>`_,
- * `py2exe <http://www.py2exe.org/>`_,
- * `py2app <https://py2app.readthedocs.io/en/latest/>`_,
+ * `fbs`_
+ * `PyInstaller`_
+ * `cx_Freeze`_
+ * `py2exe`_
+ * `py2app`_
+
+.. _fbs: https://build-system.fman.io/
+.. _PyInstaller: https://www.pyinstaller.org/
+.. _cx_Freeze: https://anthony-tuininga.github.io/cx_Freeze/
+.. _py2exe: http://www.py2exe.org/
+.. _py2app: https://py2app.readthedocs.io/en/latest/
|project| is a cross-platform framework,
so we would like to focus on solutions that work on the three
@@ -24,15 +29,56 @@ major platforms supported by Qt: Linux, macOS, and Windows.
The following table summarizes the platform support for those packaging
tools:
-=========== ======= ===== ===== =======
-Name License Linux macOS Windows
-=========== ======= ===== ===== =======
-fbs GPL yes yes yes
-PyInstaller GPL yes yes yes
-cx_Freeze MIT yes yes yes
-py2exe MIT no no yes
-py2app MIT no yes no
-=========== ======= ===== ===== =======
+.. raw:: html
+
+ <table class="docutils align-default">
+ <thead>
+ <tr>
+ <th class="head">Name</th>
+ <th class="head">License</th>
+ <th class="head">Linux</th>
+ <th class="head">macOS</th>
+ <th class="head">Windows</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><p>fbs</p></td>
+ <td><p>GPL</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>PyInstaller</p></td>
+ <td><p>GPL</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>cx_Freeze</p></td>
+ <td><p>MIT</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>py2exe</p></td>
+ <td><p>MIT</p></td>
+ <td><p style="color: red;">no</p></td>
+ <td><p style="color: red;">no</p></td>
+ <td><p style="color: green;">yes</p></td>
+ </tr>
+ <tr>
+ <td><p>py2app</p></td>
+ <td><p>MIT</p></td>
+ <td><p style="color: red;">no</p></td>
+ <td><p style="color: green;">yes</p></td>
+ <td><p style="color: red;">no</p></td>
+ </tr>
+ </tbody>
+ </table>
According to this table, only *fbs*, *cx_Freeze*, and *PyInstaller*
meets our cross-platform requirement.
@@ -47,14 +93,15 @@ to update your application packages.
To create update packages, use the `PyUpdater <https://www.pyupdater.org/>`_,
which is built around PyInstaller.
-The `fbs <https://build-system.fman.io>`_ tool offers a nice UI
+The `fbs`_ tool offers a nice UI
that allows the user to install the application step-by-step.
Here you can find a set of tutorials on how to use the previously
described tools.
-.. note:: Deployment is supported only from Qt for Python 5.12.2 and
-later.
+.. note::
+
+ Deployment is supported only from Qt for Python 5.12.2 and later.
.. toctree::
:name: mastertoc
diff --git a/sources/pyside2/doc/tutorials/examples/images/tabbedbrowser.png b/sources/pyside2/doc/examples/images/tabbedbrowser.png
index 27c3daa09..27c3daa09 100644
--- a/sources/pyside2/doc/tutorials/examples/images/tabbedbrowser.png
+++ b/sources/pyside2/doc/examples/images/tabbedbrowser.png
Binary files differ
diff --git a/sources/pyside2/doc/examples/index.rst b/sources/pyside2/doc/examples/index.rst
new file mode 100644
index 000000000..6d2b56dca
--- /dev/null
+++ b/sources/pyside2/doc/examples/index.rst
@@ -0,0 +1,14 @@
+|project| Examples
+===================
+
+A collection of examples are provided with |project| to help new users
+to understand different use cases of the module.
+You can find all the examples inside the ``pyside-setup`` on the ``examples``
+directory, or you can access them after installing |pymodname| from ``pip``
+inside the ``site-packages/PySide2/examples`` directory.
+
+.. toctree::
+ :maxdepth: 1
+
+ tabbedbrowser.rst
+ ../pyside-examples/all-pyside-examples.rst
diff --git a/sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst b/sources/pyside2/doc/examples/tabbedbrowser.rst
index c34c50647..c34c50647 100644
--- a/sources/pyside2/doc/tutorials/examples/tabbedbrowser.rst
+++ b/sources/pyside2/doc/examples/tabbedbrowser.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtCore.ClassInfo.rst b/sources/pyside2/doc/extras/QtCore.ClassInfo.rst
index d2267be9c..d2267be9c 100644
--- a/sources/pyside2/doc/extras/PySide.QtCore.ClassInfo.rst
+++ b/sources/pyside2/doc/extras/QtCore.ClassInfo.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtCore.Signal.rst b/sources/pyside2/doc/extras/QtCore.Signal.rst
index 16c640831..16c640831 100644
--- a/sources/pyside2/doc/extras/PySide.QtCore.Signal.rst
+++ b/sources/pyside2/doc/extras/QtCore.Signal.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtCore.Slot.rst b/sources/pyside2/doc/extras/QtCore.Slot.rst
index 3bc64c03a..3bc64c03a 100644
--- a/sources/pyside2/doc/extras/PySide.QtCore.Slot.rst
+++ b/sources/pyside2/doc/extras/QtCore.Slot.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtCore.rst b/sources/pyside2/doc/extras/QtCore.rst
index d3277a418..d3277a418 100644
--- a/sources/pyside2/doc/extras/PySide.QtCore.rst
+++ b/sources/pyside2/doc/extras/QtCore.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtGui.rst b/sources/pyside2/doc/extras/QtGui.rst
index e16329c38..e16329c38 100644
--- a/sources/pyside2/doc/extras/PySide.QtGui.rst
+++ b/sources/pyside2/doc/extras/QtGui.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtHelp.rst b/sources/pyside2/doc/extras/QtHelp.rst
index 239f4faa6..239f4faa6 100644
--- a/sources/pyside2/doc/extras/PySide.QtHelp.rst
+++ b/sources/pyside2/doc/extras/QtHelp.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtMultimedia.rst b/sources/pyside2/doc/extras/QtMultimedia.rst
index 5088db4d0..5088db4d0 100644
--- a/sources/pyside2/doc/extras/PySide.QtMultimedia.rst
+++ b/sources/pyside2/doc/extras/QtMultimedia.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtNetwork.rst b/sources/pyside2/doc/extras/QtNetwork.rst
index 07303b157..07303b157 100644
--- a/sources/pyside2/doc/extras/PySide.QtNetwork.rst
+++ b/sources/pyside2/doc/extras/QtNetwork.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtOpenGL.rst b/sources/pyside2/doc/extras/QtOpenGL.rst
index 38783d9fd..38783d9fd 100644
--- a/sources/pyside2/doc/extras/PySide.QtOpenGL.rst
+++ b/sources/pyside2/doc/extras/QtOpenGL.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtScript.rst b/sources/pyside2/doc/extras/QtScript.rst
index 8ce7681ec..8ce7681ec 100644
--- a/sources/pyside2/doc/extras/PySide.QtScript.rst
+++ b/sources/pyside2/doc/extras/QtScript.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtScriptTools.rst b/sources/pyside2/doc/extras/QtScriptTools.rst
index a54ed914b..a54ed914b 100644
--- a/sources/pyside2/doc/extras/PySide.QtScriptTools.rst
+++ b/sources/pyside2/doc/extras/QtScriptTools.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtSql.rst b/sources/pyside2/doc/extras/QtSql.rst
index fcdd6ba02..fcdd6ba02 100644
--- a/sources/pyside2/doc/extras/PySide.QtSql.rst
+++ b/sources/pyside2/doc/extras/QtSql.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtSvg.rst b/sources/pyside2/doc/extras/QtSvg.rst
index 7817e532f..7817e532f 100644
--- a/sources/pyside2/doc/extras/PySide.QtSvg.rst
+++ b/sources/pyside2/doc/extras/QtSvg.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtTest.rst b/sources/pyside2/doc/extras/QtTest.rst
index 0b89a22d4..0b89a22d4 100644
--- a/sources/pyside2/doc/extras/PySide.QtTest.rst
+++ b/sources/pyside2/doc/extras/QtTest.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtUiTools.rst b/sources/pyside2/doc/extras/QtUiTools.rst
index 553224527..553224527 100644
--- a/sources/pyside2/doc/extras/PySide.QtUiTools.rst
+++ b/sources/pyside2/doc/extras/QtUiTools.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtWebKit.rst b/sources/pyside2/doc/extras/QtWebKit.rst
index 58f9230a7..58f9230a7 100644
--- a/sources/pyside2/doc/extras/PySide.QtWebKit.rst
+++ b/sources/pyside2/doc/extras/QtWebKit.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtXml.rst b/sources/pyside2/doc/extras/QtXml.rst
index 4b48ef21e..4b48ef21e 100644
--- a/sources/pyside2/doc/extras/PySide.QtXml.rst
+++ b/sources/pyside2/doc/extras/QtXml.rst
diff --git a/sources/pyside2/doc/extras/PySide.QtXmlPatterns.rst b/sources/pyside2/doc/extras/QtXmlPatterns.rst
index 99254ad62..99254ad62 100644
--- a/sources/pyside2/doc/extras/PySide.QtXmlPatterns.rst
+++ b/sources/pyside2/doc/extras/QtXmlPatterns.rst
diff --git a/sources/pyside2/doc/faq.rst b/sources/pyside2/doc/faq.rst
deleted file mode 100644
index aabd017e9..000000000
--- a/sources/pyside2/doc/faq.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-Frequently Asked Questions
-==========================
-
-**When was PySide2 adopted by The Qt Company?**
- During April 2016 `The Qt Company <https://qt.io>`_ decided to properly support the port
- (`see details <https://groups.google.com/forum/#!topic/pyside-dev/pqwzngAGLWE>`_).
-
-**PySide? Qt for Python? what is the name?**
- The name of the project is Qt for Python and the name of the module is PySide2.
-
-**Why PySide2 and not just PySide?**
- Since PySide was developed for Qt4, when the port was made to support Qt5,
- the name is changed to PySide2 to imply that it was a newer version.
-
-**Where I can find information about the old PySide project?**
- The old wiki page of the project is available on PySide, but the project is deprecated
- and there is no official support for it. We highly recommend not to use it.
-
-**My project is using PySide, how hard would it be to adapt it to PySide2?**
- The changes are the same as between Qt4 and Qt5, and for PySide users it mostly means
- adapting the import statements since many classes were moved from QtGui to QtWidgets.
- Qt 5 is highly compatible with Qt 4. It is possible for developers of Qt 4 applications to
- seamlessly move to Qt 5 with their current functionality and gradually develop new things,
- leveraging all the great items Qt 5 makes possible.
-
-**Does PySide2 support Android and iOS development / deployment?**
- At the moment there is no support for mobile platforms.
-
-**Does PySide2 have support for embedded Linux (Raspberry Pi, i.MX6 etc)?**
- Not at the moment.
-
-**There are three wheels (pyside2, shiboken2, and shiboken2_generator), what is the different between them?**
-
- Before the official release, everything was in one big wheel, but it made sense to split
- the projects in three different wheels:
-
- * **pyside2**: contains all the PySide2 modules to use the Qt framework.
- Also depends on the shiboken2 module.
- * **shiboken2**: contains the shiboken2 module with helper functions for PySide2.
- * **shiboken2_generator**: contains the generator binary that can work with a C++ project
- and a typesystem to generate Python bindings.
- Take into account that if you want to generate bindings for a Qt/C++ project,
- the linking to the Qt shared libraries will be missing, and you will need to do this by hand.
- We recommend to build PySide2 from scratch to have everything properly linked.
-
-**Why shiboken2_generator is not installed automatically?**
- It's not necessary to install it to use PySide2.
- The package is the result of the wheel splitting process.
- To use the generator, it's recommended to build it from scratch to have the proper Qt-linking.
diff --git a/sources/pyside2/doc/gettingstarted-linux.rst b/sources/pyside2/doc/gettingstarted-linux.rst
new file mode 100644
index 000000000..fd5b83223
--- /dev/null
+++ b/sources/pyside2/doc/gettingstarted-linux.rst
@@ -0,0 +1,94 @@
+Getting Started on Linux
+==========================
+
+Requirements
+------------
+
+ * Qt package from `here`_ or a custom build of Qt (preferably Qt 5.12 or greater)
+ * A Python interpreter (version Python 3.5+ or Python 2.7).
+
+ * You can use the one provided by your OS, or you can get python from the `official website`_.
+ * GCC,
+ * `CMake`_ version 3.1 or greater
+ * Git version 2 or greater
+ * `libclang_` from your system or from the `precompiled Qt packages`_ is recommended.
+ * ``virtualenv`` is strongly recommended, but optional.
+ * ``sphinx`` package for the documentation (optional).
+ * Depending on your OS, other dependencies packages might be required:
+
+ * ``libgl-dev, python-dev, python-distutils, and python-setuptools``.
+
+.. _here: https://qt.io/download
+.. _official website: https://www.python.org/downloads/
+.. _CMake: https://cmake.org/download/
+.. _libclang: http://download.qt.io/development_releases/prebuilt/libclang/
+
+
+Building from source
+--------------------
+
+Creating a virtual environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``virtualenv`` allows you to create a local, user-writeable copy of a python environment into
+which arbitrary modules can be installed and which can be removed after use::
+
+ virtualenv testenv
+ source testenv/bin/activate
+ pip install sphinx # optional: documentation
+ pip install numpy PyOpenGL # optional: for examples
+
+will create and use a new virtual environment, which is indicated by the command prompt changing.
+
+Setting up CLANG
+~~~~~~~~~~~~~~~~
+
+If you don't have libclang already in your system, you can download from the Qt servers::
+
+ wget https://download.qt.io/development_releases/prebuilt/libclang/libclang-release_60-linux-Rhel7.2-gcc5.3-x86_64-clazy.7z
+
+Extract the files, and leave it on any desired path, and then set these two required
+environment variables::
+
+ 7z x libclang-release_60-linux-Rhel7.2-gcc5.3-x86_64-clazy.7z
+ export CLANG_INSTALL_DIR=$PWD/libclang
+
+Getting PySide2
+~~~~~~~~~~~~~~~
+
+Cloning the official repository can be done by::
+
+ git clone --recursive https://code.qt.io/pyside/pyside-setup
+
+Checking out the version that we want to build, e.g. 5.14::
+
+ cd pyside-setup && git checkout 5.14
+
+.. note:: Keep in mind you need to use the same version as your Qt installation.
+ Additionally, ``git checkout -b 5.14 --track origin/5.14`` could be a better option
+ in case you want to work on it.
+
+Building PySide2
+~~~~~~~~~~~~~~~~
+
+Check your Qt installation path, to specifically use that version of qmake to build PySide2.
+e.g. ``/opt/Qt/5.14.0/gcc_64/bin/qmake``.
+
+Build can take a few minutes, so it is recommended to use more than one CPU core::
+
+ python setup.py build --qmake=/opt/Qt/5.14.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8
+
+Installing PySide2
+~~~~~~~~~~~~~~~~~~
+
+To install on the current directory, just run::
+
+ python setup.py install --qmake=/opt/Qt/5.14.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8
+
+Test installation
+~~~~~~~~~~~~~~~~~
+
+You can execute one of the examples to verify the process is properly working.
+Remember to properly set the environment variables for Qt and PySide2::
+
+ python examples/widgets/widgets/tetrix.py
diff --git a/sources/pyside2/doc/gettingstarted-macOS.rst b/sources/pyside2/doc/gettingstarted-macOS.rst
new file mode 100644
index 000000000..11305247f
--- /dev/null
+++ b/sources/pyside2/doc/gettingstarted-macOS.rst
@@ -0,0 +1,93 @@
+Getting Started on macOS
+========================
+
+Requirements
+------------
+
+ * Qt package from `here`_ or a custom build of Qt (preferably Qt 5.12 or greater)
+ * A Python interpreter (version Python 3.5+ or Python 2.7).
+
+ * You can use the one provided by HomeBrew, or you can get python from the `official website`_.
+ * `XCode`_ 8.2 (macOS 10.11), 8.3.3 (macOS 10.12), 9 (macOS 10.13), 10.1 (macOS 10.14)
+ * `CMake`_ version 3.1 or greater
+ * Git version 2 or greater
+ * `libclang_` from your system or from the `precompiled Qt packages`_ is recommended.
+ * ``virtualenv`` is strongly recommended, but optional.
+ * ``sphinx`` package for the documentation (optional).
+ * Depending on your OS, other dependencies packages might be required:
+
+ * ``libgl-dev, python-dev, python-distutils, and python-setuptools``.
+
+.. _XCode: https://developer.apple.com/xcode/
+.. _here: https://qt.io/download
+.. _official website: https://www.python.org/downloads/
+.. _CMake: https://cmake.org/download/
+.. _libclang: http://download.qt.io/development_releases/prebuilt/libclang/
+
+
+Building from source
+--------------------
+
+Creating a virtual environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``virtualenv`` allows you to create a local, user-writeable copy of a python environment into
+which arbitrary modules can be installed and which can be removed after use::
+
+ virtualenv testenv
+ source testenv/bin/activate
+ pip install sphinx # optional: documentation
+ pip install numpy PyOpenGL # optional: for examples
+
+will create and use a new virtual environment, which is indicated by the command prompt changing.
+
+Setting up CLANG
+~~~~~~~~~~~~~~~~
+
+If you don't have libclang already in your system, you can download from the Qt servers::
+
+ wget https://download.qt.io/development_releases/prebuilt/libclang/libclang-release_60-mac-clazy.7z
+
+Extract the files, and leave it on any desired path, and then set these two required
+environment variables::
+
+ 7z x libclang-release_60-linux-Rhel7.2-gcc5.3-x86_64-clazy.7z
+ export CLANG_INSTALL_DIR=$PWD/libclang
+
+Getting PySide2
+~~~~~~~~~~~~~~~
+
+Cloning the official repository can be done by::
+
+ git clone --recursive https://code.qt.io/pyside/pyside-setup
+
+Checking out the version that we want to build, e.g. 5.14::
+
+ cd pyside-setup && git checkout 5.14
+
+.. note:: Keep in mind you need to use the same version as your Qt installation
+
+Building PySide2
+~~~~~~~~~~~~~~~~
+
+Check your Qt installation path, to specifically use that version of qmake to build PySide2.
+e.g. ``/opt/Qt/5.14.0/gcc_64/bin/qmake``.
+
+Build can take a few minutes, so it is recommended to use more than one CPU core::
+
+ python setup.py build --qmake=/opt/Qt/5.14.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8
+
+Installing PySide2
+~~~~~~~~~~~~~~~~~~
+
+To install on the current directory, just run::
+
+ python setup.py install --qmake=/opt/Qt/5.14.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8
+
+Test installation
+~~~~~~~~~~~~~~~~~
+
+You can execute one of the examples to verify the process is properly working.
+Remember to properly set the environment variables for Qt and PySide2::
+
+ python examples/widgets/widgets/tetrix.py
diff --git a/sources/pyside2/doc/gettingstarted-windows.rst b/sources/pyside2/doc/gettingstarted-windows.rst
new file mode 100644
index 000000000..dea781545
--- /dev/null
+++ b/sources/pyside2/doc/gettingstarted-windows.rst
@@ -0,0 +1,104 @@
+Getting Started on Windows
+==========================
+
+The Qt library has to be built with the same version of MSVC as Python and PySide2, this can be
+selected when using the online installer.
+
+Requirements
+------------
+
+ * Qt package from `here`_ or a custom build of Qt (preferably Qt 5.12 or greater)
+ * A Python interpreter (version Python 3.5+).
+
+ * Preferably get python from the `official website`_.
+
+ .. note:: Python 2.7 interpreter is not supported.
+ The official Python 2.7 binary package which can be downloaded at
+ https://www.python.org/downloads/ is built using MSVC 2007, while
+ the Qt libraries are built using MSVC 2015/2017.
+ Note that if you build your own custom Python2.7 interpreter with
+ an MSVC version equivalent to the one that Qt was built with,
+ you can safely build and use Qt for Python against that interpreter.
+
+ * `MSVC2017`_ (or MSVC2019) for Python 3 on Windows,
+ * `CMake`_ version 3.1 or greater
+ * `Git`_ version 2 or greater
+ * `libclang_` from the `precompiled Qt packages`_ is recommended.
+ * `OpenSSL`_ (optional for SSL support, Qt must have been configured using the same SSL library)
+ * ``virtualenv`` is strongly recommended, but optional.
+ * ``sphinx`` package for the documentation (optional).
+
+.. _here: https://qt.io/download
+.. _official website: https://www.python.org/downloads/
+.. _MSVC2017: https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools
+.. _CMake: https://cmake.org/download/
+.. _Git: https://git-scm.com/download/win
+.. _libclang: http://download.qt.io/development_releases/prebuilt/libclang/
+.. _OpenSSL: https://sourceforge.net/projects/openssl/
+
+
+Building from source on Windows 10
+----------------------------------
+
+Creating a virtual environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``virtualenv`` allows you to create a local, user-writeable copy of a python environment into
+which arbitrary modules can be installed and which can be removed after use::
+
+ virtualenv testenv
+ call testenv\scripts\activate
+ pip install sphinx # optional: documentation
+ pip install numpy PyOpenGL # optional: for examples
+
+will create and use a new virtual environment, which is indicated by the command prompt changing.
+
+Setting up CLANG
+~~~~~~~~~~~~~~~~
+
+If you don't have libclang already in your system, you can download from the Qt servers,
+e.g. ``libclang-release_60-windows-vs2015_64-clazy.7z``.
+
+Extract the files, and leave it on any desired path, e.g ``c:\``, and then set these two required
+environment variables::
+
+ set LLVM_INSTALL_DIR=c:\libclang
+ set PATH=C:\libclang\bin;%PATH%
+
+Getting PySide2
+~~~~~~~~~~~~~~~
+
+Cloning the official repository can be done by::
+
+ git clone --recursive https://code.qt.io/pyside/pyside-setup
+
+Checking out the version that we want to build, e.g. 5.14::
+
+ cd pyside-setup && git checkout 5.14
+
+.. note:: Keep in mind you need to use the same version as your Qt installation
+
+Building PySide2
+~~~~~~~~~~~~~~~~
+
+Check your Qt installation path, to specifically use that version of qmake to build PySide2.
+e.g. ``E:\Qt\5.12.0\msvc2015_64\bin\qmake.exe``.
+
+Build can take a few minutes, so it is recommended to use more than one CPU core::
+
+ python setup.py build --qmake=c:\path\to\qmake.exe --openssl=c:\path\to\openssl\bin --build-tests --ignore-git --parallel=8
+
+Installing PySide2
+~~~~~~~~~~~~~~~~~~
+
+To install on the current directory, just run::
+
+ python setup.py install --qmake=c:\path\to\qmake.exe --openssl=c:\path\to\openssl\bin --build-tests --ignore-git --parallel=8
+
+Test installation
+~~~~~~~~~~~~~~~~~
+
+You can execute one of the examples to verify the process is properly working.
+Remember to properly set the environment variables for Qt and PySide2::
+
+ python examples/widgets/widgets/tetrix.py
diff --git a/sources/pyside2/doc/gettingstarted.rst b/sources/pyside2/doc/gettingstarted.rst
index cc915a5cb..5d3ea3c31 100644
--- a/sources/pyside2/doc/gettingstarted.rst
+++ b/sources/pyside2/doc/gettingstarted.rst
@@ -1,101 +1,111 @@
-===============
-Getting Started
-===============
+|project| Getting Started
+==========================
-To develop with |project|, you must install Python, Clang, and |project|.
+This page is focused on building |project| from source, if you just want to install |pymodname|
+with ``pip`` you need to run::
-Preparing for the Installation
-==============================
+ pip install pyside2
-Before you can install |project|, you must install the following software:
+for more details, refer to our `Quick Start`_ guide.
-* Python 3.5+ or 2.7
-* libclang 5.0+ (for Qt 5.11) or 6.0+ (for Qt 5.12)
-* Recommended: a virtual environment, such as `venv <https://docs.python.org/3/library/venv.html>`_ or `virtualenv <https://virtualenv.pypa.io/en/stable/installation>`_
+.. _Quick Start: quickstart.html
-Installing |project|
-====================
+General Requirements
+--------------------
-After you have installed the required software, you are ready to install the |project|
-packages using the pip wheel. Run the following command from your command
-prompt to install::
+ * **Python**: 3.5+ and 2.7
+ * **Qt:** 5.12+ is recommended
+ * **libclang:** The libclang library, recommended: version 6 for PySide2 5.12.
+ Prebuilt versions of it can be `downloaded here`_.
+ * **CMake:** 3.1+ is needed.
- pip install PySide2 # For the latest version on PyPi
+.. _downloaded here: http://download.qt.io/development_releases/prebuilt/libclang/
-or::
+Guides per platform
+-------------------
- pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.12/latest pyside2 --trusted-host download.qt.io
+You can refer to the following pages for platform specific instructions:
-Testing the Installation
-========================
+ * `Windows`_,
+ * `macOS`_,
+ * `Linux`_,
+ * Mobile platforms (iOS/Android) **(no support)**
+ * Embedded platforms **(no official support)**
-Now that you have |project| installed, you can test your setup by running the following Python
-constructs to print version information:
+ .. note:: Most Linux-based embedded OS provide PySide2 with their official
+ package manager (e.g. `Raspbian`_ and `ArchlinuxARM`_).
-.. include:: pysideversion.rst
- :start-line: 5
- :end-line: 32
+.. _Windows: gettingstarted-windows.html
+.. _macOS: gettingstarted-macOS.html
+.. _Linux: gettingstarted-linux.html
+.. _Raspbian: https://www.raspbian.org/
+.. _ArchlinuxARM: https://archlinuxarm.org/
-Creating a Simple Application
-=============================
+A normal building command will look like this::
-Your |project| setup is ready, so try exploring it further by developing a simple application
-that prints "Hello World" in several languages. The following instructions will
-guide you through the development process:
+ python setup.py install --qmake=/path/to/qmake \
+ --ignore-git \
+ --debug \
+ --build-tests \
+ --parallel=8 \
+ --make-spec=ninja \
+ --verbose-build \
+ --module-subset=Core,Gui,Widgets
-* Create a new file named :code:`hello_world.py`, and add the following imports to it.
+Which will build and install the project with **debug** symbols, including the **tests**,
+using **ninja** (instead of make), and considering only the **module subset** of QtCore, QtGUI
+and QtWidgets.
- ::
+Other important options to consider are:
+ * ``--cmake``, to specify the path to the cmake binary,
+ * ``--reuse-build``, to rebuild only the modified files,
+ * ``--openssl=/path/to/openssl/bin``, to use a different path for OpenSSL,
+ * ``--standalone``, to copy over the Qt libraries into the final package
+ to make it work on other machines.
- import sys
- import random
- from PySide2 import QtCore, QtWidgets, QtGui
+Testing the installation
+-------------------------
- The |pymodname| Python module provides access to the Qt APIs as its submodule.
- In this case, you are importing the :code:`QtCore`, :code:`QtWidgets`, and :code:`QtGui` submodules.
+Once the installation finishes, you will be able to execute any of our examples::
-* Define a class named :code:`MyWidget`, which extends QWidget and includes a QPushButton and QLabel.
+ python examples/widgets/widgets/tetrix.py
- ::
+Running Tests
+--------------
- class MyWidget(QtWidgets.QWidget):
- def __init__(self):
- super().__init__()
+Using the ``--build-tests`` option will enable us to run all the auto tests inside the project::
- self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]
+ python testrunner.py test > testlog.txt
- self.button = QtWidgets.QPushButton("Click me!")
- self.text = QtWidgets.QLabel("Hello World")
- self.text.setAlignment(QtCore.Qt.AlignCenter)
+.. note:: On Windows, don't forget to have qmake in your path
+ (``set PATH=E:\Path\to\Qt\5.14\msvc2017_64\bin;%PATH%``)
- self.layout = QtWidgets.QVBoxLayout()
- self.layout.addWidget(self.text)
- self.layout.addWidget(self.button)
- self.setLayout(self.layout)
+You can also run a specific test (for example ``qpainter_test``) by running::
- self.button.clicked.connect(self.magic)
+ ctest -R qpainter_test --verbose
+Building the documentation
+---------------------------
- def magic(self):
- self.text.setText(random.choice(self.hello))
+The documentation is being generated using **qdoc** to get the API information, and also **sphinx**
+for the local Python related notes.
- The MyWidget class has the :code:`magic` member function that
- randomly chooses an item from the list :code:`hello`. This function
- is called when you click the button.
+The system required ``libxml2`` and `libxslt``, also on the Python environment, ``sphinx`` and
+``graphviz`` need to be installed before running the installation process::
-* Now, add a main function where you instantiate :code:`MyWidget` and
- :code:`show` it.
+ pip install graphviz sphinx
- ::
+After installing ``graphviz`, the ``dot`` command needs to be in PATH, otherwise,
+the process will fail. Installing ``graphviz`` system-wide is also an option.
- if __name__ == "__main__":
- app = QtWidgets.QApplication([])
+Since the process rely on a Qt installation, you need to specify where the ``qtbase`` directory
+you will use with your ``qmake`` is located::
- widget = MyWidget()
- widget.resize(800, 600)
- widget.show()
+ export QT_SRC_DIR=/path/to/qtbase
- sys.exit(app.exec_())
+Once the build process finishes, you can go to the generated ``*_build/*_release/pyside2``
+directory, and run::
-Your example is ready to be run. Try clicking the button at the bottom
-and see which greeting you get.
+ make apidoc
+
+Finally, you will get a ``html`` directory containing all the generated documentation.
diff --git a/sources/pyside2/doc/index.rst b/sources/pyside2/doc/index.rst
index b0bb1d19c..5ffe405a5 100644
--- a/sources/pyside2/doc/index.rst
+++ b/sources/pyside2/doc/index.rst
@@ -1,87 +1,42 @@
|project|
-*************
-
-|project| offers Python bindings for Qt, enabling the use of Qt5 APIs in Python
-applications. It lets Python developers utilize the full potential of Qt, using
-the |pymodname| module.
-
-The |pymodname| module provides access to the individual
-Qt modules such as QtCore, QtGui, and so on. |project| also comes with the
-:doc:`Shiboken2 <shiboken2:index>` CPython binding code generator, which can be
-used to generate Python bindings for your C or C++ code.
-
-.. toctree::
- :name: mastertoc
- :maxdepth: 2
-
- contents.rst
- Known issues <https://wiki.qt.io/Qt_for_Python/Considerations>
-
-Qt Modules
-===========
-
-Basic modules
--------------
- These are the main modules that will help you build a Widget based UI.
-
- `Qt Core <PySide2/QtCore/index.html>`_
- Provides core non-GUI functionality, like signal and slots, properties, base classes of item models, serialization, etc.
- `Qt Gui <PySide2/QtGui/index.html>`_
- Extends QtCore with GUI functionality: Events, windows and screens, OpenGL and raster-based 2D painting, images.
- `Qt Widgets <PySide2/QtWidgets/index.html>`_
- Ready to use Widgets for your application, including also graphical elements for your UI.
-
-QML and Qt Quick
-----------------
- If you want to use the `Qml Language <https://doc.qt.io/qt-5/qmlapplications.html>`, these
- modules will help you interact with it from Python.
-
- `Qt Qml <PySide2/QtQml/index.html>`_
- Base Python API to interact with the QML module.
- `Qt Quick <PySide2/QtQuick/index.html>`_
- Provides classes for embedding Qt Quick in Qt applications.
- `Qt QuickWidgets <PySide2/QtQuickWidgets/index.html>`_
- Provides the QQuickWidget class for embedding Qt Quick in widget-based applications.
-
-Data visualization
-------------------
-
- Charts, diagrams, animations: these modules provide a large amount
- of classes that can help you include these elements in your UI.
-
- `Qt Charts <PySide2/QtCharts/index.html>`_
- Provides a set of easy to use chart components.
- `Qt DataVisualization <PySide2/QtDataVisualization/index.html>`_
- Provides a way to visualize data in 3D as bar, scatter, and surface graphs.
-
-Multimedia
------------
-
- Audio, video, and hardware interaction: check these modules if you are
- looking for multimedia solutions.
-
- `Qt Multimedia <PySide2/QtMultimedia/index.html>`_
- Provides low-level multimedia functionality.
- `Qt MultimediaWidgets <PySide2/QtMultimediaWidgets/index.html>`_
- Provides the widget-based multimedia API.
-
-WebEngine
----------
-
- If your project is based on a browser or the features around web
- based applications, these modules will help you to interact with them.
-
- `Qt WebEngineWidgets <PySide2/QtWebEngineWidgets/index.html>`_
- Provides widgets that can handle web content.
- `Qt WebChannel <PySide2/QtWebChannel/index.html>`_
- Enables peer-to-peer communication between a server and a client
- (HTML/JavaScript or QML application).
-
-All the modules
----------------
-
- There are many other modules currently supported by |pymodname|,
- here you can find a complete list of them.
-
- `Check all the modules <modules.html>`_
- Display a table with all the currently supported Qt modules.
+*********
+
+**Qt for Python** offers the official Python bindings for `Qt`_ (`PySide2`_),
+enabling the use of its APIs in Python applications, and a binding generator tool (`Shiboken2`_)
+which can be used to expose C++ projects into Python.
+
+|project| is available under the LGPLv3/GPLv3 and the Qt commercial license.
+
+.. _Qt: https://doc.qt.io
+.. _PySide2: quickstart.html
+.. _Shiboken2: shiboken2/index.html
+
+Documentation
+=============
+
+.. raw:: html
+
+ <table class="special">
+ <colgroup>
+ <col style="width: 33%" />
+ <col style="width: 33%" />
+ <col style="width: 33%" />
+ </colgroup>
+ <tr>
+ <td><a href="quickstart.html"><p><strong>Check It Out!</strong><br/>Write your first Qt app.</p></a></td>
+ <td><a href="gettingstarted.html"><p><strong>Getting Started</strong><br/>Install and build from source.</p></a></td>
+ <td><a href="api.html"><p><strong>API Docs</strong><br/>Qt for Python API reference.</p></a></td>
+ </tr>
+
+ <tr>
+ <td><a href="tutorials/index.html"><p><strong>Tutorials</strong><br/>Learn with step-by-step guides.</p></a></td>
+ <td><a href="examples/index.html"><p><strong>Examples</strong><br/>Check all the available examples.</p></a></td>
+ <td><a href="videos.html"><p><strong>Videos</strong><br/>Watch webinars, Talks, and more.</p></a></td>
+ </tr>
+
+ <tr>
+ <td><a href="deployment.html" style="display: block;"><p><strong>Deployment</strong><br/>Learn to deploy your apps.</p></a></td>
+ <td><a href="considerations.html" style="display: block;"><p><strong>Considerations</strong><br/>API differences and known issues.</p></a></td>
+ <td><a href="shiboken2/index.html" style="display: block;"><p><strong>Shiboken</strong><br/>Generate C++ to Python binding.</p></a></td>
+ </tr>
+ </table>
diff --git a/sources/pyside2/doc/modules.rst b/sources/pyside2/doc/modules.rst
index 1d6564300..d9accd664 100644
--- a/sources/pyside2/doc/modules.rst
+++ b/sources/pyside2/doc/modules.rst
@@ -1,94 +1,101 @@
Qt Modules
===========
+.. toctree::
+ :hidden:
+ :glob:
+
+ PySide2/Qt*/*
+
.. list-table::
:widths: 150, 150
:align: left
- * - `Qt Core <PySide2/QtCore/index.html>`_
+ * - :mod:`Qt Core <PySide2.QtCore>`
Provides core non-GUI functionality.
- - `Qt 3D Animation <PySide2/Qt3DAnimation/index.html>`_
+ - :mod:`Qt 3D Animation <PySide2.Qt3DAnimation>`
Provides basic elements required to animate 3D objects.
- * - `Qt Gui <PySide2/QtGui/index.html>`_
+ * - :mod:`Qt Gui <PySide2.QtGui>`
Extends QtCore with GUI functionality.
- - `Qt Help <PySide2/QtHelp/index.html>`_
+ - :mod:`Qt Help <PySide2.QtHelp>`
Provides classes for integrating online documentation in applications.
- * - `Qt Network <PySide2/QtNetwork/index.html>`_
+ * - :mod:`Qt Network <PySide2.QtNetwork>`
Offers classes that let you to write TCP/IP clients and servers.
- - `Qt OpenGL <PySide2/QtOpenGL/index.html>`_
+ - :mod:`Qt OpenGL <PySide2.QtOpenGL>`
Offers classes that make it easy to use OpenGL in Qt applications.
- * - `Qt PrintSupport <PySide2/QtPrintSupport/index.html>`_
+ * - :mod:`Qt PrintSupport <PySide2.QtPrintSupport>`
Provides extensive cross-platform support for printing.
- - `Qt Qml <PySide2/QtQml/index.html>`_
+ - :mod:`Qt Qml <PySide2.QtQml>`
Python API for Qt QML.
- * - `Qt Charts <PySide2/QtCharts/index.html>`_
+ * - :mod:`Qt Charts <PySide2.QtCharts>`
Provides a set of easy to use chart components.
- - `Qt Quick <PySide2/QtQuick/index.html>`_
+ - :mod:`Qt Quick <PySide2.QtQuick>`
Provides classes for embedding Qt Quick in Qt applications.
- * - `Qt DataVisualization <PySide2/QtDataVisualization/index.html>`_
+ * - :mod:`Qt DataVisualization <PySide2.QtDataVisualization>`
Provides a way to visualize data in 3D as bar, scatter, and surface graphs.
- - `Qt QuickWidgets <PySide2/QtQuickWidgets/index.html>`_
+ - :mod:`Qt QuickWidgets <PySide2.QtQuickWidgets>`
Provides the QQuickWidget class for embedding Qt Quick in widget-based applications.
- * - `Qt TextToSpeech <PySide2/QtTextToSpeech/index.html>`_
+ * - :mod:`Qt TextToSpeech <PySide2.QtTextToSpeech>`
Provides API to access text-to-speech engines.
- - `Qt Sql <PySide2/QtSql/index.html>`_
+ - :mod:`Qt Sql <PySide2.QtSql>`
Helps you provide seamless database integration to your Qt applications.
- * - `Qt Multimedia <PySide2/QtMultimedia/index.html>`_
+ * - :mod:`Qt Multimedia <PySide2.QtMultimedia>`
Provides low-level multimedia functionality.
- - `Qt MultimediaWidgets <PySide2/QtMultimediaWidgets/index.html>`_
+ - :mod:`Qt MultimediaWidgets <PySide2.QtMultimediaWidgets>`
Provides the widget-based multimedia API.
- * - `Qt MacExtras <PySide2/QtMacExtras/index.html>`_
+ * - :mod:`Qt MacExtras <PySide2.QtMacExtras>`
Provides classes and functions specific to
macOS and iOS operating systems.
- - `Qt Svg <PySide2/QtSvg/index.html>`_
+ - :mod:`Qt Svg <PySide2.QtSvg>`
Provides classes for displaying the contents of SVG files.
- * - `Qt UiTools <PySide2/QtUiTools/index.html>`_
+ * - :mod:`Qt UiTools <PySide2.QtUiTools>`
Provides classes to handle forms created with Qt Designer.
- - `Qt Test <PySide2/QtTest/index.html>`_
+ - :mod:`Qt Test <PySide2.QtTest>`
Provides classes for unit testing Qt applications and libraries.
- * - `Qt Concurrent <PySide2/QtConcurrent/index.html>`_
+ * - :mod:`Qt Concurrent <PySide2.QtConcurrent>`
Provides high-level APIs that make it possible
to write multi-threaded programs without using low-level threading
primitives such as mutexes, read-write locks, wait conditions, or semaphores.
- - `Qt AxContainer <PySide2/QtAxContainer/index.html>`_
+ - :mod:`Qt AxContainer <PySide2.QtAxContainer>`
Provides QAxObject and QAxWidget which act as
containers for COM objects and ActiveX controls.
- * - `Qt WebEngineCore <PySide2/QtWebEngineCore/index.html>`_
+ * - :mod:`Qt WebEngineCore <PySide2.QtWebEngineCore>`
Provides the core functionality to integrate web content.
- - `Qt WebEngineWidgets <PySide2/QtWebEngineWidgets/index.html>`_
+ - :mod:`Qt WebEngineWidgets <PySide2.QtWebEngineWidgets>`
Provides widgets that can handle web content.
- * - `Qt WebChannel <PySide2/QtWebChannel/index.html>`_
+ * - :mod:`Qt WebChannel <PySide2.QtWebChannel>`
Enables peer-to-peer communication between a server and a client
(HTML/JavaScript or QML application).
- - `Qt WebSockets <PySide2/QtWebSockets/index.html>`_
+ - :mod:`Qt WebSockets <PySide2.QtWebSockets>`
Provides interfaces that enable Qt applications
to act as a server that can process WebSocket requests, or a client that
can consume data received from the server, or both.
- * - `Qt Widgets <PySide2/QtWidgets/index.html>`_
+ * - :mod:`Qt Widgets <PySide2.QtWidgets>`
Extends Qt GUI with C++ widget functionality.
- - `Qt WinExtras <PySide2/QtWinExtras/index.html>`_
+ - :mod:`Qt WinExtras <PySide2.QtWinExtras>`
Provides classes and functions for using some Windows APIs in a Qt way.
- * - `Qt X11Extras <PySide2/QtX11Extras/index.html>`_
+ * - :mod:`Qt X11Extras <PySide2.QtX11Extras>`
Provides information about the X display configuration.
- - `Qt Xml <PySide2/QtXml/index.html>`_
+ - :mod:`Qt Xml <PySide2.QtXml>`
Provides C++ implementations of SAX and DOM.
- * - `Qt XmlPatterns <PySide2/QtXmlPatterns/index.html>`_
+ * - :mod:`Qt XmlPatterns <PySide2.QtXmlPatterns>`
Provides support for XPath, XQuery, XSLTi, and XML Schema validation.
- - `Qt 3D Core <PySide2/Qt3DCore/index.html>`_
+ - :mod:`Qt 3D Core <PySide2.Qt3DCore>`
Contains functionality to support near-realtime simulation systems.
- * - `Qt 3D Extras <PySide2/Qt3DExtras/index.html>`_
+ * - :mod:`Qt 3D Extras <PySide2.Qt3DExtras>`
Provides a set of prebuilt elements to help you get started with Qt 3D.
- - `Qt 3D Input <PySide2/Qt3DInput/index.html>`_
+ - :mod:`Qt 3D Input <PySide2.Qt3DInput>`
Provides classes for handling user input in applications using Qt 3D.
- * - `Qt 3D Logic <PySide2/Qt3DLogic/index.html>`_
+ * - :mod:`Qt 3D Logic <PySide2.Qt3DLogic>`
Enables synchronizing frames with the Qt 3D backend.
- - `Qt 3D Render <PySide2/Qt3DRender/index.html>`_
+ - :mod:`Qt 3D Render <PySide2.Qt3DRender>`
Contains functionality to support 2D and 3D rendering using Qt 3D.
- * - `Qt Positioning <PySide2/QtPositioning/index.html>`_
+ * - :mod:`Qt Positioning <PySide2.QtPositioning>`
Provides positioning information via QML and Python interfaces.
- - `Qt Location <PySide2/QtLocation/index.html>`_
+ - :mod:`Qt Location <PySide2.QtLocation>`
Helps you create viable mapping solutions using the data available from some of the popular location services.
- * - `Qt Sensors <PySide2/QtSensors/index.html>`_
+ * - :mod:`Qt Sensors <PySide2.QtSensors>`
Provides access to sensor hardware via QML and Python interfaces and a motion gesture recognition API for devices.
- - `Qt Scxml <PySide2/QtScxml/index.html>`_
+ - :mod:`Qt Scxml <PySide2.QtScxml>`
Provides classes to create and use state machines from SCXML files.
+
diff --git a/sources/pyside2/doc/overview.rst b/sources/pyside2/doc/overview.rst
deleted file mode 100644
index e8a8ace00..000000000
--- a/sources/pyside2/doc/overview.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-Overview
-=========
-
-The |project| project aims to provide a complete port of the PySide module to Qt 5.
-The development started on GitHub in May 2015. The project managed to port Pyside to
-Qt 5.3, 5. 4 & 5.5.
-
-The `PySide2` module was released mid June 2018 as a Technical Preview (supporting Qt 5.11),
-and it has been fully supported since Qt 5.12.
-
-|project| is available under LGPLv3/GPLv2 and commercial license for the following platforms:
-
-+-------------+--------+--------+--------+--------+---------+---------+
-| | Linux | macOS | Windows |
-+=============+========+========+========+========+=========+=========+
-| | 32bit | 64bit | 32bit | 64bit | 32bit | 64bit |
-+-------------+--------+--------+--------+--------+---------+---------+
-| Python 2.7 | No (*) | Yes | No (*) | Yes | No (**) | No (**) |
-+-------------+--------+--------+--------+--------+---------+---------+
-| Python 3.5+ | No (*) | Yes | No (*) | Yes | Yes | Yes |
-+-------------+--------+--------+--------+--------+---------+---------+
-
- * (*): `No Qt release <https://wiki.qt.io/Qt_5.12_Tools_and_Versions#Software_configurations_for_Qt_5.12.0>`_
- * (**): `MSVC issue with Python 2.7 and Qt <https://wiki.qt.io/Qt_for_Python/Considerations#Missing_Windows_.2F_Python_2.7_release>`_
-
-
-What does PySide2 look like?
-----------------------------
-
-A simple Hello World example in PySide2 looks like this:
-
-::
-
- import sys
- from PySide2.QtWidgets import QApplication, QLabel
-
-
- if __name__ == "__main__":
- app = QApplication(sys.argv)
- label = QLabel("Hello World")
- label.show()
- sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/pyhtml2devhelp.py b/sources/pyside2/doc/pyhtml2devhelp.py
deleted file mode 100644
index aa39036d3..000000000
--- a/sources/pyside2/doc/pyhtml2devhelp.py
+++ /dev/null
@@ -1,256 +0,0 @@
-#! /usr/bin/python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Copyright (C) 2009 Matthias Klose <doko@debian.org>
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python tools.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-"""
- This script is based on Python2.6 Ubuntu package script
-"""
-
-import formatter, htmllib
-import os, sys, re
-
-class PyHTMLParser(htmllib.HTMLParser):
- pages_to_include = set(('index.html', 'PySide/QtHelp/index.html', 'PySide/QtSvg/index.html',
- 'PySide/QtGui/index.html', 'PySide/QtNetwork/index.html', 'PySide/QtWebKit/index.html',
- 'PySide/QtUiTools/index.html', 'PySide/QtXml/index.html', 'PySide/QtCore/index.html',
- 'PySide/QtScriptTools/index.html', 'PySide/QtOpenGL/index.html', 'PySide/QtScript/index.html',
- 'PySide/QtSql/index.html', 'howto-build/index.html'))
-
- def __init__(self, formatter, basedir, fn, indent, parents=set()):
- htmllib.HTMLParser.__init__(self, formatter)
- self.basedir = basedir
- self.dir, self.fn = os.path.split(fn)
- self.data = ''
- self.parents = parents
- self.link = {}
- self.indent = indent
- self.last_indent = indent - 1
- self.sub_indent = 0
- self.sub_count = 0
- self.next_link = False
-
- def process_link(self):
- new_href = os.path.join(self.dir, self.link['href'])
- text = self.link['text']
- indent = self.indent + self.sub_indent
- if self.last_indent == indent:
- print '%s</sub>' % (' ' * self.last_indent)
- self.sub_count -= 1
- print '%s<sub link="%s" name="%s">' % (' ' * indent, new_href, text)
- self.sub_count += 1
- self.last_indent = self.indent + self.sub_indent
-
- def start_li(self, attrs):
- self.sub_indent += 1
- self.next_link = True
-
- def end_li(self):
- indent = self.indent + self.sub_indent
- if self.sub_count > 0:
- print '%s</sub>' % (' ' * self.last_indent)
- self.sub_count -= 1
- self.last_indent -= 1
- self.sub_indent -= 1
-
- def start_a(self, attrs):
- self.link = {}
- for attr in attrs:
- self.link[attr[0]] = attr[1]
- self.data = ''
-
- def end_a(self):
- process = False
- text = self.data.replace('\t', '').replace('\n', ' ').replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
- self.link['text'] = text
- # handle a tag without href attribute
- try:
- href = self.link['href']
- except KeyError:
- return
-
- abs_href = os.path.join(self.basedir, href)
- if abs_href in self.parents:
- return
- if href.startswith('..') or href.startswith('http:') \
- or href.startswith('mailto:') or href.startswith('news:'):
- return
- if href in ('', 'about.html', 'modindex.html', 'genindex.html', 'glossary.html',
- 'search.html', 'contents.html', 'download.html', 'bugs.html',
- 'license.html', 'copyright.html'):
- return
-
- if self.link.has_key('class'):
- if self.link['class'] in ('biglink'):
- process = True
- if self.link['class'] in ('reference external'):
- if self.next_link:
- process = True
- next_link = False
-
- if process == True:
- self.process_link()
- if href in self.pages_to_include:
- self.parse_file(os.path.join(self.dir, href))
-
- def finish(self):
- if self.sub_count > 0:
- print '%s</sub>' % (' ' * self.last_indent)
-
- def handle_data(self, data):
- self.data += data
-
- def parse_file(self, href):
- # TODO basedir bestimmen
- parent = os.path.join(self.basedir, self.fn)
- self.parents.add(parent)
- parser = PyHTMLParser(formatter.NullFormatter(),
- self.basedir, href, self.indent + 1,
- self.parents)
- text = file(self.basedir + '/' + href).read()
- parser.feed(text)
- parser.finish()
- parser.close()
- if parent in self.parents:
- self.parents.remove(parent)
-
-class PyIdxHTMLParser(htmllib.HTMLParser):
- def __init__(self, formatter, basedir, fn, indent):
- htmllib.HTMLParser.__init__(self, formatter)
- self.basedir = basedir
- self.dir, self.fn = os.path.split(fn)
- self.data = ''
- self.link = {}
- self.indent = indent
- self.active = False
- self.indented = False
- self.nolink = False
- self.header = ''
- self.last_letter = 'Z'
- self.last_text = ''
-
- def process_link(self):
- new_href = os.path.join(self.dir, self.link['href'])
- text = self.link['text']
- if not self.active:
- return
- if text.startswith('['):
- return
- if self.link.get('rel', None) in ('prev', 'parent', 'next', 'contents', 'index'):
- return
- if self.indented:
- text = self.last_text + ' ' + text
- else:
- # Save it in case we need it again
- self.last_text = re.sub(' \([\w\-\.\s]+\)', '', text)
- indent = self.indent
- print '%s<function link="%s" name="%s"/>' % (' ' * indent, new_href, text)
-
- def start_dl(self, attrs):
- if self.last_text:
- # Looks like we found the second part to a command
- self.indented = True
-
- def end_dl(self):
- self.indented = False
-
- def start_dt(self, attrs):
- self.data = ''
- self.nolink = True
-
- def end_dt(self):
- if not self.active:
- return
- if self.nolink == True:
- # Looks like we found the first part to a command
- self.last_text = re.sub(' \([\w\-\.\s]+\)', '', self.data)
- self.nolink = False
-
- def start_h2(self, attrs):
- for k, v in attrs:
- if k == 'id':
- self.header = v
- if v == '_':
- self.active = True
-
- def start_td(self, attrs):
- self.indented = False
- self.last_text = ''
-
- def start_table(self, attrs):
- pass
-
- def end_table(self):
- if self.header == self.last_letter:
- self.active = False
-
- def start_a(self, attrs):
- self.nolink = False
- self.link = {}
- for attr in attrs:
- self.link[attr[0]] = attr[1]
- self.data = ''
-
- def end_a(self):
- text = self.data.replace('\t', '').replace('\n', ' ').replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
- self.link['text'] = text
- # handle a tag without href attribute
- try:
- href = self.link['href']
- except KeyError:
- return
- self.process_link()
-
- def handle_data(self, data):
- self.data += data
-
-def main():
- base = sys.argv[1]
- fn = sys.argv[2]
-
- parser = PyHTMLParser(formatter.NullFormatter(), base, fn, indent=0)
- print '<?xml version="1.0" encoding="iso-8859-1"?>'
- print '<book title="PySide %s Documentation" name="PySide" version="%s" link="index.html">' % (sys.argv[3], sys.argv[3])
- print '<chapters>'
- parser.parse_file(fn)
- print '</chapters>'
-
- print '<functions>'
-
- fn = 'genindex.html'
- parser = PyIdxHTMLParser(formatter.NullFormatter(), base, fn, indent=1)
- text = file(base + '/' + fn).read()
- parser.feed(text)
- parser.close()
-
- print '</functions>'
- print '</book>'
-
-main()
-
diff --git a/sources/pyside2/doc/pyside-examples/examples.qdoc b/sources/pyside2/doc/pyside-examples/examples.qdoc
new file mode 100644
index 000000000..d82b33cf7
--- /dev/null
+++ b/sources/pyside2/doc/pyside-examples/examples.qdoc
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \group all-pyside-examples
+ \title All Qt for Python Examples
+ \brief A list of all the examples that are available with the Qt for Python package.
+*/
diff --git a/sources/pyside2/doc/pyside-examples/images/pyside2example-classwizard.png b/sources/pyside2/doc/pyside-examples/images/pyside2example-classwizard.png
new file mode 100644
index 000000000..1706772d8
--- /dev/null
+++ b/sources/pyside2/doc/pyside-examples/images/pyside2example-classwizard.png
Binary files differ
diff --git a/sources/pyside2/doc/pyside-examples/images/pyside2example-stardelegate.png b/sources/pyside2/doc/pyside-examples/images/pyside2example-stardelegate.png
new file mode 100644
index 000000000..343416397
--- /dev/null
+++ b/sources/pyside2/doc/pyside-examples/images/pyside2example-stardelegate.png
Binary files differ
diff --git a/sources/pyside2/doc/pyside-examples/images/screenshot_hello.png b/sources/pyside2/doc/pyside-examples/images/screenshot_hello.png
new file mode 100644
index 000000000..41ebbf01b
--- /dev/null
+++ b/sources/pyside2/doc/pyside-examples/images/screenshot_hello.png
Binary files differ
diff --git a/sources/pyside2/doc/pyside-examples/pyside2-classwizard.qdoc b/sources/pyside2/doc/pyside-examples/pyside2-classwizard.qdoc
new file mode 100644
index 000000000..02560889b
--- /dev/null
+++ b/sources/pyside2/doc/pyside-examples/pyside2-classwizard.qdoc
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example widgets/dialogs/classwizard
+ \title PySide2.QtWidgets - Classwizard Example
+ \ingroup all-pyside-examples
+ \brief Demonstrates the use of QDialog in a wizard application
+
+ This example demonstrates the use a custom QDialog in a wizard,
+ which generates necessary C++ class template code.
+
+ \image pyside2example-classwizard.png
+
+*/
diff --git a/sources/pyside2/doc/pyside-examples/pyside2-stardelegate.qdoc b/sources/pyside2/doc/pyside-examples/pyside2-stardelegate.qdoc
new file mode 100644
index 000000000..9df718335
--- /dev/null
+++ b/sources/pyside2/doc/pyside-examples/pyside2-stardelegate.qdoc
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example widgets/itemviews/stardelegate
+ \title PySide2.QtWidgets - Star Delegate Example
+ \ingroup all-pyside-examples
+ \brief Demonstrates Qt's itemview architecture
+
+ This example demonstrates the itemview architecture, which
+ is unique to Qt.
+
+ \image pyside2example-stardelegate.png
+*/
+
diff --git a/sources/pyside2/doc/pysideapi2.rst b/sources/pyside2/doc/pysideapi2.rst
deleted file mode 100644
index e552bf21d..000000000
--- a/sources/pyside2/doc/pysideapi2.rst
+++ /dev/null
@@ -1,84 +0,0 @@
-.. _pysideapi2:
-
-Qt for Python API
-*******************
-
-One of the goals of |pymodname| is to be API compatible with PyQt5,
-with certain exceptions. For example, |pymodname| will not export C++ components
-that are marked as deprecated by Qt.
-
-The latest considerations and known issues will be also reported
-in the `wiki <https://wiki.qt.io/Qt_for_Python/Considerations>`_.
-
-__hash__() function return value
-================================
-
-The hash value returned for the classes :class:`PySide2.QtCore.QDate`, :class:`PySide2.QtCore.QDateTime`, :class:`PySide2.QtCore.QTime`, :class:`PySide2.QtCore.QUrl` will be
-based on their string representations, thus objects with the same value will
-produce the same hash.
-
-
-QString
-=======
-
-Methods that change QString arguments
--------------------------------------
-
-Methods and functions that change the contents of a QString argument were
-modified to receive an immutable Python unicode (or str) and return another
-Python unicode/str as the modified string.
-
-The following methods had their return types modified this way:
-
-**Classes:** QAbstractSpinBox, QDateTimeEdit, QDoubleSpinBox, QSpinBox, QValidator
-
-- *fixup(string)*: string
-- *validate(string, int)*: [QValidator.State, string, int]
-
-
-**Classes:** QDoubleValidator, QIntValidator, QRegExpValidator
-
-- *validate(string, int)*: [QValidator.State, string, int]
-
-**Class:** QClipboard
-
-- *text(string, QClipboard.Mode mode=QClipboard.Clipboard)*: [string, string]
-
-
-**Class:** QFileDialog
-
-Instead of *getOpenFileNameAndFilter()*, *getOpenFileNamesAndFilter()* and *getSaveFileNameAndFilter()* like PyQt4 does,
-PySide has modified the original methods to return a tuple.
-
-- *getOpenFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0)*: [string, filter]
-- *getOpenFileNames(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0)*: [list(string), filter]
-- *getSaveFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0)*: [string, filter]
-
-**Class:** QWebPage
-
-- *javaScriptPrompt(QWebFrame, string, string)*: [bool, string]
-
-Other QString related changes
------------------------------
-
-**Classes:** QFontMetrics and QFontMetricsF
-
-They had two new methods added. Both take a string of one character and convert to a QChar (to call the C++ counterpart):
-
-- widthChar(string)
-- boundingRectChar(string)
-
-
-QTextStream
-===========
-
-Inside this class some renames were applied to avoid clashes with native Python functions. They are: *bin_()*, *hex_()* and *oct_()*.
-The only modification was the addition of '_' character.
-
-
-QVariant
-========
-
-As QVariant was removed, any function expecting it can receive any Python object (None is an invalid QVariant). The same rule is valid when returning something: the returned QVariant will be converted to the its original Python object type.
-
-When a method expects a *QVariant::Type* the programmer can use a string (the type name) or the type itself.
diff --git a/sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in
new file mode 100644
index 000000000..14808f218
--- /dev/null
+++ b/sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in
@@ -0,0 +1,12 @@
+include(@QT_SRC_DIR@/doc/global/qt-module-defaults.qdocconf)
+
+project = Pyside2Examples
+description = Qt for Python Examples
+version = $QT_VERSION
+
+sourcedirs += @CMAKE_CURRENT_SOURCE_DIR@/pyside-examples
+exampledirs = @CMAKE_CURRENT_SOURCE_DIR@/../../../examples
+examples.fileextensions += *.py *.pyproject
+imagedirs += @CMAKE_CURRENT_SOURCE_DIR@/pyside-examples/images
+url.examples = "https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/\1?h=$QT_VER"
+include(../pyside-config.qdocconf)
diff --git a/sources/pyside2/doc/quickstart.rst b/sources/pyside2/doc/quickstart.rst
new file mode 100644
index 000000000..5d8ddfe2d
--- /dev/null
+++ b/sources/pyside2/doc/quickstart.rst
@@ -0,0 +1,107 @@
+|project| Quick start
+======================
+
+Requirements
+------------
+
+Before you can install |project|, first you must install the following software:
+
+ * Python 2.7 or 3.5+,
+ * We recommend using a virtual environment, such as
+ `venv <https://docs.python.org/3/library/venv.html>`_ or
+ `virtualenv <https://virtualenv.pypa.io/en/stable/installation>`_
+
+Installation
+------------
+
+Now you are ready to install the |project| packages using ``pip``.
+From the terminal, run the following command::
+
+ pip install PySide2 # For the latest version on PyPi
+
+or::
+
+ pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.14/latest pyside2 --trusted-host download.qt.io
+
+Test your Installation
+----------------------
+
+Now that you have |project| installed, you can test your setup by running the following Python
+constructs to print version information::
+
+ import PySide2.QtCore
+
+ # Prints PySide2 version
+ # e.g. 5.11.1a1
+ print(PySide2.__version__)
+
+ # Gets a tuple with each version component
+ # e.g. (5, 11, 1, 'a', 1)
+ print(PySide2.__version_info__)
+
+ # Prints the Qt version used to compile PySide2
+ # e.g. "5.11.2"
+ print(PySide2.QtCore.__version__)
+
+ # Gets a tuple with each version components of Qt used to compile PySide2
+ # e.g. (5, 11, 2)
+ print(PySide2.QtCore.__version_info__)
+
+Create a Simple Application
+---------------------------
+
+Your |project| setup is ready. You can explore it further by developing a simple application
+that prints "Hello World" in several languages. The following instructions will
+guide you through the development process:
+
+1. Create a new file named :code:`hello_world.py`, and add the following imports to it.::
+
+ import sys
+ import random
+ from PySide2 import QtCore, QtWidgets, QtGui
+
+ The |pymodname| Python module provides access to the Qt APIs as its submodule.
+ In this case, you are importing the :code:`QtCore`, :code:`QtWidgets`, and :code:`QtGui` submodules.
+
+2. Define a class named :code:`MyWidget`, which extends QWidget and includes a QPushButton and
+ QLabel.::
+
+ class MyWidget(QtWidgets.QWidget):
+ def __init__(self):
+ super().__init__()
+
+ self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]
+
+ self.button = QtWidgets.QPushButton("Click me!")
+ self.text = QtWidgets.QLabel("Hello World")
+ self.text.setAlignment(QtCore.Qt.AlignCenter)
+
+ self.layout = QtWidgets.QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ self.button.clicked.connect(self.magic)
+
+
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+ The MyWidget class has the :code:`magic` member function that randomly chooses an item from the
+ :code:`hello` list. When you click the button, the :code:`magic` function is called.
+
+3. Now, add a main function where you instantiate :code:`MyWidget` and :code:`show` it.::
+
+ if __name__ == "__main__":
+ app = QtWidgets.QApplication([])
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec_())
+
+Run your example. Try clicking the button at the bottom to see which greeting you get.
+
+.. image:: pyside-examples/images/screenshot_hello.png
+ :alt: Hello World application
diff --git a/sources/pyside2/doc/tutorials/basictutorial/qml.rst b/sources/pyside2/doc/tutorials/basictutorial/qml.rst
index 81583096b..fb168410a 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/qml.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/qml.rst
@@ -14,7 +14,9 @@ that loads the QML file. To make things easier, let's save both files in
the same directory.
Here is a simple QML file called `view.qml`:
-::
+
+.. code-block:: javascript
+
import QtQuick 2.0
Rectangle {
@@ -39,7 +41,9 @@ is the Rectangle in this case.
Now, let's see how the code looks on the PySide2.
Let's call it `main.py`:
-::
+
+.. code-block:: python
+
from PySide2.QtWidgets import QApplication
from PySide2.QtQuick import QQuickView
from PySide2.QtCore import QUrl
diff --git a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
index b00437bcb..a45bfc18c 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
@@ -78,14 +78,12 @@ Generating a Python class
Another option to interact with a **UI file** is to generate a Python
class from it. This is possible thanks to the `pyside2-uic` tool.
-To use this tool, you need to run the following command on a console:
-::
+To use this tool, you need to run the following command on a console::
pyside2-uic mainwindow.ui > ui_mainwindow.py
We redirect all the output of the command to a file called `ui_mainwindow.py`,
-which will be imported directly:
-::
+which will be imported directly::
from ui_mainwindow import Ui_MainWindow
@@ -93,7 +91,8 @@ Now to use it, we should create a personalized class for our widget
to **setup** this generated design.
To understand the idea, let's take a look at the whole code:
-::
+
+.. code-block:: python
import sys
from PySide2.QtWidgets import QApplication, QMainWindow
@@ -118,26 +117,32 @@ What is inside the *if* statement is already known from the previous
examples, and our new basic class contains only two new lines
that are in charge of loading the generated python class from the UI
file:
-::
+
+.. code-block:: python
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
-.. note:: You must run `pyside2-uic` again every time you make changes
-to the **UI file**.
+.. note::
+
+ You must run `pyside2-uic` again every time you make changes
+ to the **UI file**.
Loading it directly
====================
To load the UI file directly, we will need a class from the **QtUiTools**
module:
-::
+
+.. code-block:: python
from PySide2.QtUiTools import QUiLoader
The `QUiLoader` lets us load the **ui file** dynamically
and use it right away:
-::
+
+.. code-block:: python
+
ui_file = QFile("mainwindow.ui")
ui_file.open(QFile.ReadOnly)
@@ -146,7 +151,8 @@ and use it right away:
window.show()
The complete code of this example looks like this:
-::
+
+.. code-block:: python
# File: main.py
import sys
@@ -169,6 +175,7 @@ The complete code of this example looks like this:
Then to execute it we just need to run the following on a
command prompt:
-::
+
+.. code-block:: python
python main.py
diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgets.rst b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst
index c864e3d47..41e474227 100644
--- a/sources/pyside2/doc/tutorials/basictutorial/widgets.rst
+++ b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst
@@ -5,7 +5,9 @@ As with any other programming framework,
you start with the traditional "Hello World" program.
Here is a simple example of a Hello World application in PySide2:
-::
+
+.. code-block:: python
+
import sys
from PySide2.QtWidgets import QApplication, QLabel
@@ -22,13 +24,17 @@ After the imports, you create a `QApplication` instance. As Qt can
receive arguments from command line, you may pass any argument to
the QApplication object. Usually, you don't need to pass any
arguments so you can leave it as is, or use the following approach:
-::
+
+.. code-block:: python
+
app = QApplication([])
After the creation of the application object, we have created a
`QLabel` object. A `QLabel` is a widget that can present text
(simple or rich, like html), and images:
-::
+
+.. code-block:: python
+
# This HTML approach will be valid too!
label = QLabel("<font color=red size=40>Hello World!</font>")
diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst b/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst
index 0c9803269..95b2092b3 100644
--- a/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst
+++ b/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst
@@ -15,6 +15,6 @@ previous chapter to add a QChartView:
.. literalinclude:: datavisualize5/main_widget.py
:linenos:
:lines: 40-
- :emphasize-lines: 2-3,6,22-37,48-51
+ :emphasize-lines: 2-3,6,22-36,48-50
diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst b/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst
index bbf27f2da..720918008 100644
--- a/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst
+++ b/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst
@@ -59,10 +59,12 @@ In the following snippets you'll see those changes highlighted:
.. literalinclude:: datavisualize4/main_window.py
:language: python
:linenos:
+ :lines: 40-
:emphasize-lines: 8,11
.. literalinclude:: datavisualize4/main.py
:language: python
:linenos:
+ :lines: 40-
:emphasize-lines: 46-47
diff --git a/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst b/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst
index f54ba217c..b06b2fa15 100644
--- a/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst
+++ b/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst
@@ -23,7 +23,6 @@ The following script filters and formats the CSV data as described earlier:
.. literalinclude:: datavisualize2/main.py
:language: python
:linenos:
- :emphasize-lines: 44,47-69
:lines: 40-
Now that you have a tuple of QDateTime and float data, try improving the
diff --git a/sources/pyside2/doc/tutorials/expenses/expenses.rst b/sources/pyside2/doc/tutorials/expenses/expenses.rst
index c34d18669..a19cec5c3 100644
--- a/sources/pyside2/doc/tutorials/expenses/expenses.rst
+++ b/sources/pyside2/doc/tutorials/expenses/expenses.rst
@@ -31,7 +31,8 @@ Empty window
The base structure for a `QApplication` is located inside the `if __name__ == "__main__":`
code block.
- .. code::
+.. code-block:: python
+ :dedent: 4
if __name__ == "__main__":
app = QApplication([])
@@ -41,17 +42,17 @@ code block.
Now, to start the development, create an empty window called `MainWindow`.
You could do that by defining a class that inherits from `QMainWindow`.
- .. literalinclude:: steps/01-expenses.py
- :linenos:
- :lines: 45-59
- :emphasize-lines: 45-48
+.. literalinclude:: steps/01-expenses.py
+ :linenos:
+ :lines: 45-59
+ :emphasize-lines: 1-4
Now that our class is defined, create an instance of it and call `show()`.
- .. literalinclude:: steps/01-expenses.py
- :linenos:
- :lines: 45-59
- :emphasize-lines: 54-56
+.. literalinclude:: steps/01-expenses.py
+ :linenos:
+ :lines: 45-59
+ :emphasize-lines: 10-12
Menu bar
--------
@@ -59,10 +60,10 @@ Menu bar
Using a `QMainWindow` gives some features for free, among them a *menu bar*. To use it, you need
to call the method `menuBar()` and populate it inside the `MainWindow` class.
- .. literalinclude:: steps/02-expenses.py
- :linenos:
- :lines: 46-58
- :emphasize-lines: 51
+.. literalinclude:: steps/02-expenses.py
+ :linenos:
+ :lines: 46-58
+ :emphasize-lines: 6
Notice that the code snippet adds a *File* menu with the *Exit* option only.
@@ -72,14 +73,14 @@ First signal/slot connection
The *Exit* option must be connected to a slot that triggers the application to exit. The main
idea to achieve this, is the following:
- .. code::
+.. code-block:: python
element.signal_name.connect(slot_name)
All the interface's elements could be connected through signals to certain slots,
in the case of a `QAction`, the signal `triggered` can be used:
- .. code::
+.. code-block:: python
exit_action.triggered.connect(slot_name)
@@ -87,10 +88,10 @@ in the case of a `QAction`, the signal `triggered` can be used:
`QApplication.quit()`. If we put all these concepts together you will end up with the
following code:
- .. literalinclude:: steps/03-expenses.py
- :linenos:
- :lines: 56-65
- :emphasize-lines: 59, 63-65
+.. literalinclude:: steps/03-expenses.py
+ :linenos:
+ :lines: 56-65
+ :emphasize-lines: 4, 8-10
Notice that the decorator `@Slot()` is required for each slot you declare to properly
register them. Slots are normal functions, but the main difference is that they
@@ -105,15 +106,15 @@ This central widget could be another class derived from `QWidget`.
Additionally, you will define example data to visualize later.
- .. literalinclude:: steps/04-expenses.py
- :linenos:
- :lines: 46-53
+.. literalinclude:: steps/04-expenses.py
+ :linenos:
+ :lines: 46-53
With the `Widget` class in place, modify `MainWindow`'s initialization code
- .. literalinclude:: steps/04-expenses.py
- :linenos:
- :lines: 80-84
+.. literalinclude:: steps/04-expenses.py
+ :linenos:
+ :lines: 80-84
Window layout
-------------
@@ -124,13 +125,13 @@ goal of creating an expenses application.
After declaring the example data, you can visualize it on a simple `QTableWidget`. To do so, you
will add this procedure to the `Widget` constructor.
- .. warning:: Only for the example purpose a QTableWidget will be used,
- but for more performance-critical applications the combination
- of a model and a QTableView is encouraged.
+.. warning:: Only for the example purpose a QTableWidget will be used,
+ but for more performance-critical applications the combination
+ of a model and a QTableView is encouraged.
- .. literalinclude:: steps/05-expenses.py
- :linenos:
- :lines: 48-73
+.. literalinclude:: steps/05-expenses.py
+ :linenos:
+ :lines: 48-73
As you can see, the code also includes a `QHBoxLayout` that provides the container to place widgets
horizontally.
@@ -141,9 +142,9 @@ columns that will be used, and to *stretch* the content to use the whole `Widget
The last line of code refers to *filling the table**, and the code to perform that task is
displayed below.
- .. literalinclude:: steps/05-expenses.py
- :linenos:
- :lines: 75-81
+.. literalinclude:: steps/05-expenses.py
+ :linenos:
+ :lines: 75-81
Having this process on a separate method is a good practice to leave the constructor more readable,
and to split the main functions of the class in independent processes.
@@ -159,17 +160,17 @@ application.
To distribute these input lines and buttons, you will use a `QVBoxLayout` that allows you to place
elements vertically inside a layout.
- .. literalinclude:: steps/06-expenses.py
- :linenos:
- :lines: 64-80
+.. literalinclude:: steps/06-expenses.py
+ :linenos:
+ :lines: 64-80
Leaving the table on the left side and these newly included widgets to the right side
will be just a matter to add a layout to our main `QHBoxLayout` as you saw in the previous
example:
- .. literalinclude:: steps/06-expenses.py
- :linenos:
- :lines: 42-47
+.. literalinclude:: steps/06-expenses.py
+ :linenos:
+ :lines: 42-47
The next step will be connecting those new buttons to slots.
@@ -181,19 +182,19 @@ Each `QPushButton` have a signal called *clicked*, that is emitted when you clic
This will be more than enough for this example, but you can see other signals in the `official
documentation <https://doc.qt.io/qtforpython/PySide2/QtWidgets/QAbstractButton.html#signals>`_.
- .. literalinclude:: steps/07-expenses.py
- :linenos:
- :lines: 92-95
+.. literalinclude:: steps/07-expenses.py
+ :linenos:
+ :lines: 92-95
As you can see on the previous lines, we are connecting each *clicked* signal to different slots.
In this example slots are normal class methods in charge of perform a determined task associated
with our buttons. It is really important to decorate each method declaration with a `@Slot()`, in
that way PySide2 knows internally how to register them into Qt.
- .. literalinclude:: steps/07-expenses.py
- :linenos:
- :lines: 1000-129
- :emphasize-lines: 101,115,127
+.. literalinclude:: steps/07-expenses.py
+ :linenos:
+ :lines: 100-129
+ :emphasize-lines: 2,16,28
Since these slots are methods, we can access the class variables, like our `QTableWidget` to
interact with it.
@@ -225,15 +226,15 @@ the current content of the `QLineEdit`.
You can connect two different object's signal to the same slot, and this will be the case
for your current application:
- .. literalinclude:: steps/08-expenses.py
- :linenos:
- :lines: 99-100
+.. literalinclude:: steps/08-expenses.py
+ :linenos:
+ :lines: 99-100
The content of the *check_disable* slot will be really simple:
- .. literalinclude:: steps/08-expenses.py
- :linenos:
- :lines: 119-124
+.. literalinclude:: steps/08-expenses.py
+ :linenos:
+ :lines: 119-124
You have two options, write a verification based on the current value
of the string you retrieve, or manually get the whole content of both
@@ -253,17 +254,17 @@ OK, but you can accomplish more by representing the data graphically.
First you will include an empty `QChartView` placeholder into the right
side of your application.
- .. literalinclude:: steps/09-expenses.py
- :linenos:
- :lines: 66-68
+.. literalinclude:: steps/09-expenses.py
+ :linenos:
+ :lines: 66-68
Additionally the order of how you include widgets to the right
`QVBoxLayout` will also change.
- .. literalinclude:: steps/09-expenses.py
- :linenos:
- :lines: 81-91
- :emphasize-lines: 89
+.. literalinclude:: steps/09-expenses.py
+ :linenos:
+ :lines: 81-91
+ :emphasize-lines: 9
Notice that before we had a line with `self.right.addStretch()`
to fill up the vertical space between the *Add* and the *Clear* buttons,
@@ -277,18 +278,18 @@ Full application
For the final step, you will need to connect the *Plot* button
to a slot that creates a chart and includes it into your `QChartView`.
- .. literalinclude:: steps/10-expenses.py
- :linenos:
- :lines: 103-109
- :emphasize-lines: 106
+.. literalinclude:: steps/10-expenses.py
+ :linenos:
+ :lines: 103-109
+ :emphasize-lines: 6
That is nothing new, since you already did it for the other buttons,
but now take a look at how to create a chart and include it into
your `QChartView`.
- .. literalinclude:: steps/10-expenses.py
- :linenos:
- :lines: 139-151
+.. literalinclude:: steps/10-expenses.py
+ :linenos:
+ :lines: 139-151
The following steps show how to fill a `QPieSeries`:
@@ -305,9 +306,9 @@ your newly created chart to the `QChartView`.
The application will look like this:
- .. image:: expenses_tool.png
+.. image:: expenses_tool.png
And now you can see the whole code:
- .. literalinclude:: main.py
- :linenos:
+.. literalinclude:: main.py
+ :linenos:
diff --git a/sources/pyside2/doc/tutorials/index.rst b/sources/pyside2/doc/tutorials/index.rst
index 5a97aecb9..7486554f9 100644
--- a/sources/pyside2/doc/tutorials/index.rst
+++ b/sources/pyside2/doc/tutorials/index.rst
@@ -1,22 +1,12 @@
-Qt for Python examples and tutorials
-*************************************
+|project| Tutorials
+====================
-A collection of examples and tutorials with "walkthrough" guides are
+A collection of tutorials with "walkthrough" guides are
provided with |project| to help new users get started. These
documents were ported from C++ to Python and cover a range of topics,
from basic use of widgets to step-by-step tutorials that show how an
application is put together.
-Examples and demos
-===================
-
-.. toctree::
- :maxdepth: 1
-
- examples/tabbedbrowser.rst
-
-Tutorials
-==========
.. toctree::
:maxdepth: 2
@@ -30,3 +20,4 @@ Tutorials
expenses/expenses.rst
qmlapp/qmlapplication.rst
qmlintegration/qmlintegration.rst
+ portingguide/index.rst
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter1/chapter1.rst b/sources/pyside2/doc/tutorials/portingguide/chapter1/chapter1.rst
new file mode 100644
index 000000000..20b11065a
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter1/chapter1.rst
@@ -0,0 +1,89 @@
+Chapter 1: ``initDb.h`` to ``createDb.py``
+*******************************************
+
+To begin with, port the C++ code that creates an SQLite
+database and tables, and adds data to them. In this case,
+all C++ code related to this lives in ``initdb.h``. The
+code in this header file is divided into following parts:
+
+* ``initDb`` - Creates a db and the necessary tables
+* ``addBooks`` - Adds data to the **books** table.
+* ``addAuthor`` - Adds data to the **authors** table.
+* ``addGenre`` - Adds data to the **genres** table.
+
+To start with, add these following ``import`` statements at
+the beginning of ``createdb.py``:
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 40-44
+
+The ``initDb`` function does most of the work needed to
+set up the database, but it depends on the ``addAuthor``,
+``addGenre``, and ``addBook`` helper functions to populate
+the tables. Port these helper functions first. Here is how
+the C++ and Python versions of these functions look like:
+
+C++ version
+------------
+
+.. literalinclude:: initdb.h
+ :language: c++
+ :linenos:
+ :lines: 55-81
+
+Python version
+---------------
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 44-65
+
+Now that the helper functions are in place, port ``initDb``.
+Here is how the C++ and Python versions of this function
+looks like:
+
+C++ version
+------------
+
+.. literalinclude:: initdb.h
+ :language: c++
+ :linenos:
+ :lines: 81-159
+
+Python version
+---------------
+
+.. literalinclude:: createdb.py
+ :language: python
+ :linenos:
+ :lines: 65-
+
+.. note:: The Python version uses the ``check`` function to
+ execute the SQL statements instead of the ``if...else``
+ block like in the C++ version. Although both are valid
+ approaches, the earlier one produces code that looks
+ cleaner and shorter.
+
+Your Python code to set up the database is ready now. To
+test it, add the following code to ``main.py`` and run it:
+
+.. literalinclude:: main.py
+ :language: python
+ :linenos:
+ :lines: 40-
+
+Use the following command from the prompt to run:
+
+.. code-block::
+
+ python main.py
+
+Your table will look like this:
+
+.. image:: images/chapter1_books.png
+
+Try modifying the SQL statment in ``main.py`` to get data
+from the ``genres`` or ``authors`` table.
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter1/createdb.py b/sources/pyside2/doc/tutorials/portingguide/chapter1/createdb.py
new file mode 100644
index 000000000..8fb20cda1
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter1/createdb.py
@@ -0,0 +1,131 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from PySide2.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from datetime import date
+
+
+def add_book(q, title, year, authorId, genreId, rating):
+ q.addBindValue(title)
+ q.addBindValue(year)
+ q.addBindValue(authorId)
+ q.addBindValue(genreId)
+ q.addBindValue(rating)
+ q.exec_()
+
+
+def add_genre(q, name):
+ q.addBindValue(name)
+ q.exec_()
+ return q.lastInsertId()
+
+
+def add_author(q, name, birthdate):
+ q.addBindValue(name)
+ q.addBindValue(str(birthdate))
+ q.exec_()
+ return q.lastInsertId()
+
+BOOKS_SQL = """
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ """
+AUTHORS_SQL = """
+ create table authors(id integer primary key, name varchar, birthdate text)
+ """
+GENRES_SQL = """
+ create table genres(id integer primary key, name varchar)
+ """
+INSERT_AUTHOR_SQL = """
+ insert into authors(name, birthdate) values(?, ?)
+ """
+INSERT_GENRE_SQL = """
+ insert into genres(name) values(?)
+ """
+INSERT_BOOK_SQL = """
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ """
+
+def init_db():
+ """
+ init_db()
+ Initializes the database.
+ If tables "books" and "authors" are already in the database, do nothing.
+ Return value: None or raises ValueError
+ The error value is the QtSql error instance.
+ """
+ def check(func, *args):
+ if not func(*args):
+ raise ValueError(func.__self__.lastError())
+ db = QSqlDatabase.addDatabase("QSQLITE")
+ db.setDatabaseName(":memory:")
+
+ check(db.open)
+
+ q = QSqlQuery()
+ check(q.exec_, BOOKS_SQL)
+ check(q.exec_, AUTHORS_SQL)
+ check(q.exec_, GENRES_SQL)
+ check(q.prepare, INSERT_AUTHOR_SQL)
+
+ asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1))
+ greeneId = add_author(q, "Graham Greene", date(1904, 10, 2))
+ pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28))
+
+ check(q.prepare,INSERT_GENRE_SQL)
+ sfiction = add_genre(q, "Science Fiction")
+ fiction = add_genre(q, "Fiction")
+ fantasy = add_genre(q, "Fantasy")
+
+ check(q.prepare,INSERT_BOOK_SQL)
+ add_book(q, "Foundation", 1951, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4)
+ add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3)
+ add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4)
+ add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3)
+ add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3)
+ add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4)
+ add_book(q, "The Third Man", 1950, greeneId, fiction, 5)
+ add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4)
+ add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3)
+ add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3)
+ add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3)
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter1/images/chapter1_books.png b/sources/pyside2/doc/tutorials/portingguide/chapter1/images/chapter1_books.png
new file mode 100644
index 000000000..164674220
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter1/images/chapter1_books.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h b/sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h
new file mode 100644
index 000000000..773e3fb74
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef INITDB_H
+#define INITDB_H
+
+#include <QtSql>
+
+void addBook(QSqlQuery &q, const QString &title, int year, const QVariant &authorId,
+ const QVariant &genreId, int rating)
+{
+ q.addBindValue(title);
+ q.addBindValue(year);
+ q.addBindValue(authorId);
+ q.addBindValue(genreId);
+ q.addBindValue(rating);
+ q.exec();
+}
+
+QVariant addGenre(QSqlQuery &q, const QString &name)
+{
+ q.addBindValue(name);
+ q.exec();
+ return q.lastInsertId();
+}
+
+QVariant addAuthor(QSqlQuery &q, const QString &name, const QDate &birthdate)
+{
+ q.addBindValue(name);
+ q.addBindValue(birthdate);
+ q.exec();
+ return q.lastInsertId();
+}
+
+const auto BOOKS_SQL = QLatin1String(R"(
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ )");
+
+const auto AUTHORS_SQL = QLatin1String(R"(
+ create table authors(id integer primary key, name varchar, birthdate date)
+ )");
+
+const auto GENRES_SQL = QLatin1String(R"(
+ create table genres(id integer primary key, name varchar)
+ )");
+
+const auto INSERT_AUTHOR_SQL = QLatin1String(R"(
+ insert into authors(name, birthdate) values(?, ?)
+ )");
+
+const auto INSERT_BOOK_SQL = QLatin1String(R"(
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ )");
+
+const auto INSERT_GENRE_SQL = QLatin1String(R"(
+ insert into genres(name) values(?)
+ )");
+
+QSqlError initDb()
+{
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+ db.setDatabaseName(":memory:");
+
+ if (!db.open())
+ return db.lastError();
+
+ QStringList tables = db.tables();
+ if (tables.contains("books", Qt::CaseInsensitive)
+ && tables.contains("authors", Qt::CaseInsensitive))
+ return QSqlError();
+
+ QSqlQuery q;
+ if (!q.exec(BOOKS_SQL))
+ return q.lastError();
+ if (!q.exec(AUTHORS_SQL))
+ return q.lastError();
+ if (!q.exec(GENRES_SQL))
+ return q.lastError();
+
+ if (!q.prepare(INSERT_AUTHOR_SQL))
+ return q.lastError();
+ QVariant asimovId = addAuthor(q, QLatin1String("Isaac Asimov"), QDate(1920, 2, 1));
+ QVariant greeneId = addAuthor(q, QLatin1String("Graham Greene"), QDate(1904, 10, 2));
+ QVariant pratchettId = addAuthor(q, QLatin1String("Terry Pratchett"), QDate(1948, 4, 28));
+
+ if (!q.prepare(INSERT_GENRE_SQL))
+ return q.lastError();
+ QVariant sfiction = addGenre(q, QLatin1String("Science Fiction"));
+ QVariant fiction = addGenre(q, QLatin1String("Fiction"));
+ QVariant fantasy = addGenre(q, QLatin1String("Fantasy"));
+
+ if (!q.prepare(INSERT_BOOK_SQL))
+ return q.lastError();
+ addBook(q, QLatin1String("Foundation"), 1951, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Empire"), 1952, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Second Foundation"), 1953, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation's Edge"), 1982, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Foundation and Earth"), 1986, asimovId, sfiction, 4);
+ addBook(q, QLatin1String("Prelude to Foundation"), 1988, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("Forward the Foundation"), 1993, asimovId, sfiction, 3);
+ addBook(q, QLatin1String("The Power and the Glory"), 1940, greeneId, fiction, 4);
+ addBook(q, QLatin1String("The Third Man"), 1950, greeneId, fiction, 5);
+ addBook(q, QLatin1String("Our Man in Havana"), 1958, greeneId, fiction, 4);
+ addBook(q, QLatin1String("Guards! Guards!"), 1989, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Night Watch"), 2002, pratchettId, fantasy, 3);
+ addBook(q, QLatin1String("Going Postal"), 2004, pratchettId, fantasy, 3);
+
+ return QSqlError();
+}
+
+#endif
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter1/main.py b/sources/pyside2/doc/tutorials/portingguide/chapter1/main.py
new file mode 100644
index 000000000..7e94e4c14
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter1/main.py
@@ -0,0 +1,59 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+
+from PySide2.QtSql import QSqlQueryModel
+from PySide2.QtWidgets import QTableView, QApplication
+
+import createdb
+
+if __name__ == "__main__":
+ app = QApplication()
+ createdb.init_db()
+
+ model = QSqlQueryModel()
+ model.setQuery("select * from books")
+
+ table_view = QTableView()
+ table_view.setModel(model)
+ table_view.resize(800, 600)
+ table_view.show()
+ sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp
new file mode 100644
index 000000000..4115f80cf
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bookdelegate.h"
+
+#include <QtWidgets>
+
+BookDelegate::BookDelegate(QObject *parent)
+ : QSqlRelationalDelegate(parent), star(QPixmap(":images/star.png"))
+{
+}
+
+void BookDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() != 5) {
+ QStyleOptionViewItem opt = option;
+ // Since we draw the grid ourselves:
+ opt.rect.adjust(0, 0, -1, -1);
+ QSqlRelationalDelegate::paint(painter, opt, index);
+ } else {
+ const QAbstractItemModel *model = index.model();
+ QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ?
+ (option.state & QStyle::State_Active) ?
+ QPalette::Normal :
+ QPalette::Inactive :
+ QPalette::Disabled;
+
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(
+ option.rect,
+ option.palette.color(cg, QPalette::Highlight));
+
+ int rating = model->data(index, Qt::DisplayRole).toInt();
+ int width = star.width();
+ int height = star.height();
+ int x = option.rect.x();
+ int y = option.rect.y() + (option.rect.height() / 2) - (height / 2);
+ for (int i = 0; i < rating; ++i) {
+ painter->drawPixmap(x, y, star);
+ x += width;
+ }
+ // Since we draw the grid ourselves:
+ drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1));
+ }
+
+ QPen pen = painter->pen();
+ painter->setPen(option.palette.color(QPalette::Mid));
+ painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
+ painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
+ painter->setPen(pen);
+}
+
+QSize BookDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() == 5)
+ return QSize(5 * star.width(), star.height()) + QSize(1, 1);
+ // Since we draw the grid ourselves:
+ return QSqlRelationalDelegate::sizeHint(option, index) + QSize(1, 1);
+}
+
+bool BookDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index)
+{
+ if (index.column() != 5)
+ return QSqlRelationalDelegate::editorEvent(event, model, option, index);
+
+ if (event->type() == QEvent::MouseButtonPress) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+ int stars = qBound(0, int(0.7 + qreal(mouseEvent->pos().x()
+ - option.rect.x()) / star.width()), 5);
+ model->setData(index, QVariant(stars));
+ // So that the selection can change:
+ return false;
+ }
+
+ return true;
+}
+
+QWidget *BookDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if (index.column() != 4)
+ return QSqlRelationalDelegate::createEditor(parent, option, index);
+
+ // For editing the year, return a spinbox with a range from -1000 to 2100.
+ QSpinBox *sb = new QSpinBox(parent);
+ sb->setFrame(false);
+ sb->setMaximum(2100);
+ sb->setMinimum(-1000);
+
+ return sb;
+}
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h
new file mode 100644
index 000000000..f1b432699
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOOKDELEGATE_H
+#define BOOKDELEGATE_H
+
+#include <QModelIndex>
+#include <QPixmap>
+#include <QSize>
+#include <QSqlRelationalDelegate>
+
+QT_FORWARD_DECLARE_CLASS(QPainter)
+
+class BookDelegate : public QSqlRelationalDelegate
+{
+public:
+ BookDelegate(QObject *parent);
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+ bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) override;
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+private:
+ QPixmap star;
+};
+
+#endif
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py
new file mode 100644
index 000000000..57d8f0f73
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py
@@ -0,0 +1,134 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import copy, os
+from PySide2.QtSql import QSqlRelationalDelegate
+from PySide2.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate,
+ QStyle, QStyleOptionViewItem)
+from PySide2.QtGui import QMouseEvent, QPixmap, QPalette, QImage
+from PySide2.QtCore import QEvent, QSize, Qt, QUrl
+
+class BookDelegate(QSqlRelationalDelegate):
+ """Books delegate to rate the books"""
+
+ def __init__(self, parent=None):
+ QSqlRelationalDelegate.__init__(self, parent)
+ star_png = os.path.dirname(__file__) + "\images\star.png"
+ self.star = QPixmap(star_png)
+
+ def paint(self, painter, option, index):
+ """ Paint the items in the table.
+
+ If the item referred to by <index> is a StarRating, we
+ handle the painting ourselves. For the other items, we
+ let the base class handle the painting as usual.
+
+ In a polished application, we'd use a better check than
+ the column number to find out if we needed to paint the
+ stars, but it works for the purposes of this example.
+ """
+ if index.column() != 5:
+ # Since we draw the grid ourselves:
+ opt = copy.copy(option)
+ opt.rect = option.rect.adjusted(0, 0, -1, -1)
+ QSqlRelationalDelegate.paint(self, painter, opt, index)
+ else:
+ model = index.model()
+ if option.state & QStyle.State_Enabled:
+ if option.state & QStyle.State_Active:
+ color_group = QPalette.Normal
+ else:
+ color_group = QPalette.Inactive
+ else:
+ color_group = QPalette.Disabled
+
+ if option.state & QStyle.State_Selected:
+ painter.fillRect(option.rect,
+ option.palette.color(color_group, QPalette.Highlight))
+ rating = model.data(index, Qt.DisplayRole)
+ width = self.star.width()
+ height = self.star.height()
+ x = option.rect.x()
+ y = option.rect.y() + (option.rect.height() / 2) - (height / 2)
+ for i in range(rating):
+ painter.drawPixmap(x, y, self.star)
+ x += width
+
+ # Since we draw the grid ourselves:
+ self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1))
+
+ pen = painter.pen()
+ painter.setPen(option.palette.color(QPalette.Mid))
+ painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
+ painter.drawLine(option.rect.topRight(), option.rect.bottomRight())
+ painter.setPen(pen)
+
+ def sizeHint(self, option, index):
+ """ Returns the size needed to display the item in a QSize object. """
+ if index.column() == 5:
+ size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1)
+ return size_hint
+ # Since we draw the grid ourselves:
+ return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1)
+
+ def editorEvent(self, event, model, option, index):
+ if index.column() != 5:
+ return False
+
+ if event.type() == QEvent.MouseButtonPress:
+ mouse_pos = event.pos()
+ new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width())
+ stars = max(0, min(new_stars, 5))
+ model.setData(index, stars)
+ # So that the selection can change
+ return False
+
+ return True
+
+ def createEditor(self, parent, option, index):
+ if index.column() != 4:
+ return QSqlRelationalDelegate.createEditor(self, parent, option, index)
+
+ # For editing the year, return a spinbox with a range from -1000 to 2100.
+ spinbox = QSpinBox(parent)
+ spinbox.setFrame(False)
+ spinbox.setMaximum(2100)
+ spinbox.setMinimum(-1000)
+ return spinbox
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst b/sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst
new file mode 100644
index 000000000..a574218fd
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst
@@ -0,0 +1,93 @@
+Chapter 2: ``bookdelegate.cpp`` to ``bookdelegate.py``
+*******************************************************
+
+Now that your database is in place, port the C++ code for the
+``BookDelegate`` class. This class offers a delegate to present
+and edit the data in a ``QTableView``. It inherits
+``QSqlRelationalDelegate`` interface, which offers features
+specific for handling relational databases, such as a combobox
+editor for foreign key fields. To begin with, create
+``bookdelegate.py`` and add the following imports to it:
+
+.. literalinclude:: bookdelegate.py
+ :language: python
+ :linenos:
+ :lines: 40-47
+
+After the necessary ``import`` statements, port the
+constructor code for the ``BookDelegate`` class. Both
+the C++ and Python versions of this code initialize a
+``QSqlRelationalDelegate`` and ``QPixmap`` instance.
+Here is how they look:
+
+C++ version
+-------------
+
+.. literalinclude:: bookdelegate.cpp
+ :language: c++
+ :linenos:
+ :lines: 54-59
+
+Python version
+---------------
+
+.. literalinclude:: bookdelegate.py
+ :language: python
+ :linenos:
+ :lines: 47-54
+
+.. note:: The Python version loads the ``QPixmap`` using
+ the absolute path of ``star.png`` in the local
+ filesystem.
+
+As the default functionality offered by the
+``QSqlRelationalDelegate`` is not enough to present
+the books data, you must reimplement a few functions.
+For example, painting stars to represent the rating for
+each book in the table. Here is how the reimplemented
+code looks like:
+
+C++ version
+------------
+
+.. literalinclude:: bookdelegate.cpp
+ :language: c++
+ :linenos:
+ :lines: 59-
+
+Python version
+---------------
+
+.. literalinclude:: bookdelegate.py
+ :language: python
+ :linenos:
+ :lines: 55-
+
+Now that the delegate is in place, run the following
+``main.py`` to see how the data is presented:
+
+.. literalinclude:: main.py
+ :language: python
+ :linenos:
+ :lines: 40-
+
+Here is how the application will look when you run it:
+
+.. image:: images/chapter2_books.png
+ :alt: Books table data
+
+The only difference you'll notice now in comparison to
+:doc:`chapter 1 <../chapter1/chapter1>` is that the
+``rating`` column looks different.
+
+Try improving the table even further by adding these
+features:
+
+* Title for each column
+* SQL relation for the ``author_id`` and ``genre_id`` columns
+* Set a title to the window
+
+With these features, this is how your table will look like:
+
+.. image:: images/chapter2_books_with_relation.png
+ :alt: Books table with SQL relation
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py b/sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py
new file mode 100644
index 000000000..8fb20cda1
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py
@@ -0,0 +1,131 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from PySide2.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from datetime import date
+
+
+def add_book(q, title, year, authorId, genreId, rating):
+ q.addBindValue(title)
+ q.addBindValue(year)
+ q.addBindValue(authorId)
+ q.addBindValue(genreId)
+ q.addBindValue(rating)
+ q.exec_()
+
+
+def add_genre(q, name):
+ q.addBindValue(name)
+ q.exec_()
+ return q.lastInsertId()
+
+
+def add_author(q, name, birthdate):
+ q.addBindValue(name)
+ q.addBindValue(str(birthdate))
+ q.exec_()
+ return q.lastInsertId()
+
+BOOKS_SQL = """
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ """
+AUTHORS_SQL = """
+ create table authors(id integer primary key, name varchar, birthdate text)
+ """
+GENRES_SQL = """
+ create table genres(id integer primary key, name varchar)
+ """
+INSERT_AUTHOR_SQL = """
+ insert into authors(name, birthdate) values(?, ?)
+ """
+INSERT_GENRE_SQL = """
+ insert into genres(name) values(?)
+ """
+INSERT_BOOK_SQL = """
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ """
+
+def init_db():
+ """
+ init_db()
+ Initializes the database.
+ If tables "books" and "authors" are already in the database, do nothing.
+ Return value: None or raises ValueError
+ The error value is the QtSql error instance.
+ """
+ def check(func, *args):
+ if not func(*args):
+ raise ValueError(func.__self__.lastError())
+ db = QSqlDatabase.addDatabase("QSQLITE")
+ db.setDatabaseName(":memory:")
+
+ check(db.open)
+
+ q = QSqlQuery()
+ check(q.exec_, BOOKS_SQL)
+ check(q.exec_, AUTHORS_SQL)
+ check(q.exec_, GENRES_SQL)
+ check(q.prepare, INSERT_AUTHOR_SQL)
+
+ asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1))
+ greeneId = add_author(q, "Graham Greene", date(1904, 10, 2))
+ pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28))
+
+ check(q.prepare,INSERT_GENRE_SQL)
+ sfiction = add_genre(q, "Science Fiction")
+ fiction = add_genre(q, "Fiction")
+ fantasy = add_genre(q, "Fantasy")
+
+ check(q.prepare,INSERT_BOOK_SQL)
+ add_book(q, "Foundation", 1951, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4)
+ add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3)
+ add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4)
+ add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3)
+ add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3)
+ add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4)
+ add_book(q, "The Third Man", 1950, greeneId, fiction, 5)
+ add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4)
+ add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3)
+ add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3)
+ add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3)
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books.png b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books.png
new file mode 100644
index 000000000..e456b7d8f
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png
new file mode 100644
index 000000000..82a5f449c
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/images/star.png b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/star.png
new file mode 100644
index 000000000..87f4464bd
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/star.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/main.py b/sources/pyside2/doc/tutorials/portingguide/chapter2/main.py
new file mode 100644
index 000000000..639ee2ca0
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/main.py
@@ -0,0 +1,63 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+
+from PySide2.QtCore import Qt
+from PySide2.QtSql import QSqlQueryModel
+from PySide2.QtWidgets import QTableView, QApplication
+
+import createdb
+from bookdelegate import BookDelegate
+
+if __name__ == "__main__":
+ app = QApplication()
+ createdb.init_db()
+
+ model = QSqlQueryModel()
+ model.setQuery("select title, author, genre, year, rating from books")
+
+ table = QTableView()
+ table.setModel(model)
+ table.setItemDelegate(BookDelegate())
+ table.resize(800, 600)
+ table.show()
+
+ sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate-old.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate-old.py
new file mode 100644
index 000000000..2e8670448
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate-old.py
@@ -0,0 +1,134 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import copy, os
+from PySide2.QtSql import QSqlRelationalDelegate
+from PySide2.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate,
+ QStyle, QStyleOptionViewItem)
+from PySide2.QtGui import QMouseEvent, QPixmap, QPalette, QImage
+from PySide2.QtCore import QEvent, QSize, Qt, QUrl
+
+class BookDelegate(QSqlRelationalDelegate):
+ """Books delegate to rate the books"""
+
+ def __init__(self, star_png, parent=None):
+ QSqlRelationalDelegate.__init__(self, parent)
+ star_png = os.path.dirname(__file__) + "\images\star.png"
+ self.star = QPixmap(star_png)
+
+ def paint(self, painter, option, index):
+ """ Paint the items in the table.
+
+ If the item referred to by <index> is a StarRating, we
+ handle the painting ourselves. For the other items, we
+ let the base class handle the painting as usual.
+
+ In a polished application, we'd use a better check than
+ the column number to find out if we needed to paint the
+ stars, but it works for the purposes of this example.
+ """
+ if index.column() != 5:
+ # Since we draw the grid ourselves:
+ opt = copy.copy(option)
+ opt.rect = option.rect.adjusted(0, 0, -1, -1)
+ QSqlRelationalDelegate.paint(self, painter, opt, index)
+ else:
+ model = index.model()
+ if option.state & QStyle.State_Enabled:
+ if option.state & QStyle.State_Active:
+ color_group = QPalette.Normal
+ else:
+ color_group = QPalette.Inactive
+ else:
+ color_group = QPalette.Disabled
+
+ if option.state & QStyle.State_Selected:
+ painter.fillRect(option.rect,
+ option.palette.color(color_group, QPalette.Highlight))
+ rating = model.data(index, Qt.DisplayRole)
+ width = self.star.width()
+ height = self.star.height()
+ x = option.rect.x()
+ y = option.rect.y() + (option.rect.height() / 2) - (height / 2)
+ for i in range(rating):
+ painter.drawPixmap(x, y, self.star)
+ x += width
+
+ # Since we draw the grid ourselves:
+ self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1))
+
+ pen = painter.pen()
+ painter.setPen(option.palette.color(QPalette.Mid))
+ painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
+ painter.drawLine(option.rect.topRight(), option.rect.bottomRight())
+ painter.setPen(pen)
+
+ def sizeHint(self, option, index):
+ """ Returns the size needed to display the item in a QSize object. """
+ if index.column() == 5:
+ size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1)
+ return size_hint
+ # Since we draw the grid ourselves:
+ return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1)
+
+ def editorEvent(self, event, model, option, index):
+ if index.column() != 5:
+ return False
+
+ if event.type() == QEvent.MouseButtonPress:
+ mouse_pos = event.pos()
+ new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width())
+ stars = max(0, min(new_stars, 5))
+ model.setData(index, stars)
+ # So that the selection can change
+ return False
+
+ return True
+
+ def createEditor(self, parent, option, index):
+ if index.column() != 4:
+ return QSqlRelationalDelegate.createEditor(self, parent, option, index)
+
+ # For editing the year, return a spinbox with a range from -1000 to 2100.
+ spinbox = QSpinBox(parent)
+ spinbox.setFrame(False)
+ spinbox.setMaximum(2100)
+ spinbox.setMinimum(-1000)
+ return spinbox
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py
new file mode 100644
index 000000000..087b0c262
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py
@@ -0,0 +1,133 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import copy, os
+from PySide2.QtSql import QSqlRelationalDelegate
+from PySide2.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate,
+ QStyle, QStyleOptionViewItem)
+from PySide2.QtGui import QMouseEvent, QPixmap, QPalette, QImage
+from PySide2.QtCore import QEvent, QSize, Qt, QUrl
+
+class BookDelegate(QSqlRelationalDelegate):
+ """Books delegate to rate the books"""
+
+ def __init__(self, star_png, parent=None):
+ QSqlRelationalDelegate.__init__(self, parent)
+ self.star = QPixmap(":/images/star.png")
+
+ def paint(self, painter, option, index):
+ """ Paint the items in the table.
+
+ If the item referred to by <index> is a StarRating, we
+ handle the painting ourselves. For the other items, we
+ let the base class handle the painting as usual.
+
+ In a polished application, we'd use a better check than
+ the column number to find out if we needed to paint the
+ stars, but it works for the purposes of this example.
+ """
+ if index.column() != 5:
+ # Since we draw the grid ourselves:
+ opt = copy.copy(option)
+ opt.rect = option.rect.adjusted(0, 0, -1, -1)
+ QSqlRelationalDelegate.paint(self, painter, opt, index)
+ else:
+ model = index.model()
+ if option.state & QStyle.State_Enabled:
+ if option.state & QStyle.State_Active:
+ color_group = QPalette.Normal
+ else:
+ color_group = QPalette.Inactive
+ else:
+ color_group = QPalette.Disabled
+
+ if option.state & QStyle.State_Selected:
+ painter.fillRect(option.rect,
+ option.palette.color(color_group, QPalette.Highlight))
+ rating = model.data(index, Qt.DisplayRole)
+ width = self.star.width()
+ height = self.star.height()
+ x = option.rect.x()
+ y = option.rect.y() + (option.rect.height() / 2) - (height / 2)
+ for i in range(rating):
+ painter.drawPixmap(x, y, self.star)
+ x += width
+
+ # Since we draw the grid ourselves:
+ self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1))
+
+ pen = painter.pen()
+ painter.setPen(option.palette.color(QPalette.Mid))
+ painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
+ painter.drawLine(option.rect.topRight(), option.rect.bottomRight())
+ painter.setPen(pen)
+
+ def sizeHint(self, option, index):
+ """ Returns the size needed to display the item in a QSize object. """
+ if index.column() == 5:
+ size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1)
+ return size_hint
+ # Since we draw the grid ourselves:
+ return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1)
+
+ def editorEvent(self, event, model, option, index):
+ if index.column() != 5:
+ return False
+
+ if event.type() == QEvent.MouseButtonPress:
+ mouse_pos = event.pos()
+ new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width())
+ stars = max(0, min(new_stars, 5))
+ model.setData(index, stars)
+ # So that the selection can change
+ return False
+
+ return True
+
+ def createEditor(self, parent, option, index):
+ if index.column() != 4:
+ return QSqlRelationalDelegate.createEditor(self, parent, option, index)
+
+ # For editing the year, return a spinbox with a range from -1000 to 2100.
+ spinbox = QSpinBox(parent)
+ spinbox.setFrame(False)
+ spinbox.setMaximum(2100)
+ spinbox.setMinimum(-1000)
+ return spinbox
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc b/sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc
new file mode 100644
index 000000000..d6ad21337
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/star.png</file>
+</qresource>
+</RCC>
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp
new file mode 100644
index 000000000..76f3c9da8
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bookwindow.h"
+#include "bookdelegate.h"
+#include "initdb.h"
+
+#include <QtSql>
+
+BookWindow::BookWindow()
+{
+ ui.setupUi(this);
+
+ if (!QSqlDatabase::drivers().contains("QSQLITE"))
+ QMessageBox::critical(
+ this,
+ "Unable to load database",
+ "This demo needs the SQLITE driver"
+ );
+
+ // Initialize the database:
+ QSqlError err = initDb();
+ if (err.type() != QSqlError::NoError) {
+ showError(err);
+ return;
+ }
+
+ // Create the data model:
+ model = new QSqlRelationalTableModel(ui.bookTable);
+ model->setEditStrategy(QSqlTableModel::OnManualSubmit);
+ model->setTable("books");
+
+ // Remember the indexes of the columns:
+ authorIdx = model->fieldIndex("author");
+ genreIdx = model->fieldIndex("genre");
+
+ // Set the relations to the other database tables:
+ model->setRelation(authorIdx, QSqlRelation("authors", "id", "name"));
+ model->setRelation(genreIdx, QSqlRelation("genres", "id", "name"));
+
+ // Set the localized header captions:
+ model->setHeaderData(authorIdx, Qt::Horizontal, tr("Author Name"));
+ model->setHeaderData(genreIdx, Qt::Horizontal, tr("Genre"));
+ model->setHeaderData(model->fieldIndex("title"),
+ Qt::Horizontal, tr("Title"));
+ model->setHeaderData(model->fieldIndex("year"), Qt::Horizontal, tr("Year"));
+ model->setHeaderData(model->fieldIndex("rating"),
+ Qt::Horizontal, tr("Rating"));
+
+ // Populate the model:
+ if (!model->select()) {
+ showError(model->lastError());
+ return;
+ }
+
+ // Set the model and hide the ID column:
+ ui.bookTable->setModel(model);
+ ui.bookTable->setItemDelegate(new BookDelegate(ui.bookTable));
+ ui.bookTable->setColumnHidden(model->fieldIndex("id"), true);
+ ui.bookTable->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ // Initialize the Author combo box:
+ ui.authorEdit->setModel(model->relationModel(authorIdx));
+ ui.authorEdit->setModelColumn(
+ model->relationModel(authorIdx)->fieldIndex("name"));
+
+ ui.genreEdit->setModel(model->relationModel(genreIdx));
+ ui.genreEdit->setModelColumn(
+ model->relationModel(genreIdx)->fieldIndex("name"));
+
+ // Lock and prohibit resizing of the width of the rating column:
+ ui.bookTable->horizontalHeader()->setSectionResizeMode(
+ model->fieldIndex("rating"),
+ QHeaderView::ResizeToContents);
+
+ QDataWidgetMapper *mapper = new QDataWidgetMapper(this);
+ mapper->setModel(model);
+ mapper->setItemDelegate(new BookDelegate(this));
+ mapper->addMapping(ui.titleEdit, model->fieldIndex("title"));
+ mapper->addMapping(ui.yearEdit, model->fieldIndex("year"));
+ mapper->addMapping(ui.authorEdit, authorIdx);
+ mapper->addMapping(ui.genreEdit, genreIdx);
+ mapper->addMapping(ui.ratingEdit, model->fieldIndex("rating"));
+
+ connect(ui.bookTable->selectionModel(),
+ &QItemSelectionModel::currentRowChanged,
+ mapper,
+ &QDataWidgetMapper::setCurrentModelIndex
+ );
+
+ ui.bookTable->setCurrentIndex(model->index(0, 0));
+ createMenuBar();
+}
+
+void BookWindow::showError(const QSqlError &err)
+{
+ QMessageBox::critical(this, "Unable to initialize Database",
+ "Error initializing database: " + err.text());
+}
+
+void BookWindow::createMenuBar()
+{
+ QAction *quitAction = new QAction(tr("&Quit"), this);
+ QAction *aboutAction = new QAction(tr("&About"), this);
+ QAction *aboutQtAction = new QAction(tr("&About Qt"), this);
+
+ QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+ fileMenu->addAction(quitAction);
+
+ QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+ helpMenu->addAction(aboutAction);
+ helpMenu->addAction(aboutQtAction);
+
+ connect(quitAction, &QAction::triggered, this, &BookWindow::close);
+ connect(aboutAction, &QAction::triggered, this, &BookWindow::about);
+ connect(aboutQtAction, &QAction::triggered, qApp, &QApplication::aboutQt);
+}
+
+void BookWindow::about()
+{
+ QMessageBox::about(this, tr("About Books"),
+ tr("<p>The <b>Books</b> example shows how to use Qt SQL classes "
+ "with a model/view framework."));
+}
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py
new file mode 100644
index 000000000..4bc4cf48b
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py
@@ -0,0 +1,137 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+from PySide2.QtWidgets import (QAction, QAbstractItemView, qApp, QDataWidgetMapper,
+ QHeaderView, QMainWindow, QMessageBox)
+from PySide2.QtGui import QKeySequence
+from PySide2.QtSql import (QSqlRelation, QSqlRelationalTableModel, QSqlTableModel,
+ QSqlError)
+from PySide2.QtCore import QAbstractItemModel, QObject, QSize, Qt, Slot
+import createdb
+from ui_bookwindow import Ui_BookWindow
+from bookdelegate import BookDelegate
+
+
+class BookWindow(QMainWindow, Ui_BookWindow):
+ # """A window to show the books available"""
+
+ def __init__(self):
+ QMainWindow.__init__(self)
+ self.setupUi(self)
+
+ #Initialize db
+ createdb.init_db()
+
+ model = QSqlRelationalTableModel(self.bookTable)
+ model.setEditStrategy(QSqlTableModel.OnManualSubmit)
+ model.setTable("books")
+
+ # Remember the indexes of the columns:
+ author_idx = model.fieldIndex("author")
+ genre_idx = model.fieldIndex("genre")
+
+ # Set the relations to the other database tables:
+ model.setRelation(author_idx, QSqlRelation("authors", "id", "name"))
+ model.setRelation(genre_idx, QSqlRelation("genres", "id", "name"))
+
+ # Set the localized header captions:
+ model.setHeaderData(author_idx, Qt.Horizontal, self.tr("Author Name"))
+ model.setHeaderData(genre_idx, Qt.Horizontal, self.tr("Genre"))
+ model.setHeaderData(model.fieldIndex("title"), Qt.Horizontal, self.tr("Title"))
+ model.setHeaderData(model.fieldIndex("year"), Qt.Horizontal, self.tr("Year"))
+ model.setHeaderData(model.fieldIndex("rating"), Qt.Horizontal, self.tr("Rating"))
+
+ if not model.select():
+ print(model.lastError())
+
+ # Set the model and hide the ID column:
+ self.bookTable.setModel(model)
+ self.bookTable.setItemDelegate(BookDelegate(self.bookTable))
+ self.bookTable.setColumnHidden(model.fieldIndex("id"), True)
+ self.bookTable.setSelectionMode(QAbstractItemView.SingleSelection)
+
+ # Initialize the Author combo box:
+ self.authorEdit.setModel(model.relationModel(author_idx))
+ self.authorEdit.setModelColumn(model.relationModel(author_idx).fieldIndex("name"))
+
+ self.genreEdit.setModel(model.relationModel(genre_idx))
+ self.genreEdit.setModelColumn(model.relationModel(genre_idx).fieldIndex("name"))
+
+ # Lock and prohibit resizing of the width of the rating column:
+ self.bookTable.horizontalHeader().setSectionResizeMode(model.fieldIndex("rating"),
+ QHeaderView.ResizeToContents)
+
+ mapper = QDataWidgetMapper(self)
+ mapper.setModel(model)
+ mapper.setItemDelegate(BookDelegate(self))
+ mapper.addMapping(self.titleEdit, model.fieldIndex("title"))
+ mapper.addMapping(self.yearEdit, model.fieldIndex("year"))
+ mapper.addMapping(self.authorEdit, author_idx)
+ mapper.addMapping(self.genreEdit, genre_idx)
+ mapper.addMapping(self.ratingEdit, model.fieldIndex("rating"))
+
+ selection_model = self.bookTable.selectionModel()
+ selection_model.currentRowChanged.connect(mapper.setCurrentModelIndex)
+
+ self.bookTable.setCurrentIndex(model.index(0, 0))
+ self.create_menubar()
+
+ def showError(err):
+ QMessageBox.critical(self, "Unable to initialize Database",
+ "Error initializing database: " + err.text())
+
+ def create_menubar(self):
+ file_menu = self.menuBar().addMenu(self.tr("&File"))
+ quit_action = file_menu.addAction(self.tr("&Quit"))
+ quit_action.triggered.connect(qApp.quit)
+
+ help_menu = self.menuBar().addMenu(self.tr("&Help"))
+ about_action = help_menu.addAction(self.tr("&About"))
+ about_action.setShortcut(QKeySequence.HelpContents)
+ about_action.triggered.connect(self.about)
+ aboutQt_action = help_menu.addAction("&About Qt")
+ aboutQt_action.triggered.connect(qApp.aboutQt)
+
+ def about(self):
+ QMessageBox.about(self, self.tr("About Books"),
+ self.tr("<p>The <b>Books</b> example shows how to use Qt SQL classes "
+ "with a model/view framework."))
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui
new file mode 100644
index 000000000..e1668288f
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui
@@ -0,0 +1,149 @@
+<ui version="4.0" >
+ <author></author>
+ <comment></comment>
+ <exportmacro></exportmacro>
+ <class>BookWindow</class>
+ <widget class="QMainWindow" name="BookWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>601</width>
+ <height>420</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Books</string>
+ </property>
+ <widget class="QWidget" name="centralWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Books</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTableView" name="bookTable" >
+ <property name="selectionBehavior" >
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Details</string>
+ </property>
+ <layout class="QFormLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>&lt;b>Title:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="titleEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2_2_2_2" >
+ <property name="text" >
+ <string>&lt;b>Author: &lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="authorEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>&lt;b>Genre:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QComboBox" name="genreEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>&lt;b>Year:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QSpinBox" name="yearEdit" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="prefix" >
+ <string/>
+ </property>
+ <property name="maximum" >
+ <number>2100</number>
+ </property>
+ <property name="minimum" >
+ <number>-1000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>&lt;b>Rating:&lt;/b></string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" >
+ <widget class="QSpinBox" name="ratingEdit" >
+ <property name="maximum" >
+ <number>5</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <pixmapfunction></pixmapfunction>
+ <tabstops>
+ <tabstop>bookTable</tabstop>
+ <tabstop>titleEdit</tabstop>
+ <tabstop>authorEdit</tabstop>
+ <tabstop>genreEdit</tabstop>
+ <tabstop>yearEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst b/sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst
new file mode 100644
index 000000000..71b254811
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst
@@ -0,0 +1,121 @@
+Chapter 3: Port ``bookdwindow.cpp`` to ``bookwindow.py``
+*********************************************************
+
+After the bookdelegate, port the C++ code for the
+``BookWindow`` class. It offers a QMainWindow, containing a
+``QTableView`` to present the books data, and a **Details**
+section with a set of input fields to edit the selected row
+in the table. To begin with, create the ``bookwindow.py``
+and add the following imports to it:
+
+.. literalinclude:: bookwindow.py
+ :language: python
+ :linenos:
+ :lines: 40-53
+
+.. note:: The imports include the ``BookDelegate`` you
+ ported earlier and the ``Ui_BookWindow``. The pyside-uic
+ tool generates the ``ui_bookwindow`` Python code based
+ on the ``bookwindow.ui`` XML file.
+
+To generate this Python code, run the following command on the
+prompt:
+
+.. code-block::
+
+ pyside2-uic bookwindow.ui > ui_bookwindow.py
+
+Try porting the remaining code now. To begin with, here is
+how both the versions of the constructor code looks:
+
+C++ version
+------------
+
+.. literalinclude:: bookwindow.cpp
+ :language: c++
+ :linenos:
+ :lines: 47-115
+
+Python version
+---------------
+
+.. literalinclude:: bookwindow.py
+ :language: python
+ :linenos:
+ :lines: 53-116
+
+.. note:: The Python version of the ``BookWindow`` class
+ definition inherits from both ``QMainWindow`` and
+ ``Ui_BookWindow``, which is defined in the
+ ``ui_bookwindow.py`` file that you generated earlier.
+
+Here is how the rest of the code looks like:
+
+C++ version
+------------
+
+.. literalinclude:: bookwindow.cpp
+ :language: c++
+ :linenos:
+ :lines: 115-
+
+Python version
+---------------
+
+.. literalinclude:: bookwindow.py
+ :language: python
+ :linenos:
+ :lines: 117-
+
+Now that all the necessary pieces are in place, try to put
+them together in ``main.py``.
+
+.. literalinclude:: main.py
+ :language: python
+ :linenos:
+ :lines: 40-
+
+Try running this to see if you get the following output:
+
+.. image:: images/chapter3-books.png
+ :alt: BookWindow with a QTableView and a few input fields
+
+Now, if you look back at :doc:`chapter2 <../chapter2/chapter2>`,
+you'll notice that the ``bookdelegate.py`` loads the
+``star.png`` from the filesytem. Instead, you could add it
+to a ``qrc`` file, and load from it. The later approach is
+rececommended if your application is targeted for
+different platforms, as most of the popular platforms
+employ stricter file access policy these days.
+
+To add the ``star.png`` to a ``.qrc``, create a file called
+``books.qrc`` and the following XML content to it:
+
+.. literalinclude:: books.qrc
+ :linenos:
+
+This is a simple XML file defining a list all resources that
+your application needs. In this case, it is the ``star.png``
+image only.
+
+Now, run the ``pyside2-rcc`` tool on the ``books.qrc`` file
+to generate ``rc_books.py``.
+
+.. code-block::
+
+ pyside2-rcc books.qrc > rc_books.py
+
+Once you have the Python script generated, make the
+following changes to ``bookdelegate.py`` and ``main.py``:
+
+.. literalinclude:: bookdelegate.py
+ :diff: ../chapter2/bookdelegate.py
+
+.. literalinclude:: main.py
+ :diff: main-old.py
+
+Although there will be no noticeable difference in the UI
+after these changes, using a ``.qrc`` is a better approach.
+
+Now that you have successfully ported the SQL Books example,
+you know how easy it is. Try porting another C++ application.
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py
new file mode 100644
index 000000000..8fb20cda1
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py
@@ -0,0 +1,131 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from PySide2.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from datetime import date
+
+
+def add_book(q, title, year, authorId, genreId, rating):
+ q.addBindValue(title)
+ q.addBindValue(year)
+ q.addBindValue(authorId)
+ q.addBindValue(genreId)
+ q.addBindValue(rating)
+ q.exec_()
+
+
+def add_genre(q, name):
+ q.addBindValue(name)
+ q.exec_()
+ return q.lastInsertId()
+
+
+def add_author(q, name, birthdate):
+ q.addBindValue(name)
+ q.addBindValue(str(birthdate))
+ q.exec_()
+ return q.lastInsertId()
+
+BOOKS_SQL = """
+ create table books(id integer primary key, title varchar, author integer,
+ genre integer, year integer, rating integer)
+ """
+AUTHORS_SQL = """
+ create table authors(id integer primary key, name varchar, birthdate text)
+ """
+GENRES_SQL = """
+ create table genres(id integer primary key, name varchar)
+ """
+INSERT_AUTHOR_SQL = """
+ insert into authors(name, birthdate) values(?, ?)
+ """
+INSERT_GENRE_SQL = """
+ insert into genres(name) values(?)
+ """
+INSERT_BOOK_SQL = """
+ insert into books(title, year, author, genre, rating)
+ values(?, ?, ?, ?, ?)
+ """
+
+def init_db():
+ """
+ init_db()
+ Initializes the database.
+ If tables "books" and "authors" are already in the database, do nothing.
+ Return value: None or raises ValueError
+ The error value is the QtSql error instance.
+ """
+ def check(func, *args):
+ if not func(*args):
+ raise ValueError(func.__self__.lastError())
+ db = QSqlDatabase.addDatabase("QSQLITE")
+ db.setDatabaseName(":memory:")
+
+ check(db.open)
+
+ q = QSqlQuery()
+ check(q.exec_, BOOKS_SQL)
+ check(q.exec_, AUTHORS_SQL)
+ check(q.exec_, GENRES_SQL)
+ check(q.prepare, INSERT_AUTHOR_SQL)
+
+ asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1))
+ greeneId = add_author(q, "Graham Greene", date(1904, 10, 2))
+ pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28))
+
+ check(q.prepare,INSERT_GENRE_SQL)
+ sfiction = add_genre(q, "Science Fiction")
+ fiction = add_genre(q, "Fiction")
+ fantasy = add_genre(q, "Fantasy")
+
+ check(q.prepare,INSERT_BOOK_SQL)
+ add_book(q, "Foundation", 1951, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4)
+ add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3)
+ add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3)
+ add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4)
+ add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3)
+ add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3)
+ add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4)
+ add_book(q, "The Third Man", 1950, greeneId, fiction, 5)
+ add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4)
+ add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3)
+ add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3)
+ add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3)
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/images/chapter3-books.png b/sources/pyside2/doc/tutorials/portingguide/chapter3/images/chapter3-books.png
new file mode 100644
index 000000000..952cb14e8
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/images/chapter3-books.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/images/star.png b/sources/pyside2/doc/tutorials/portingguide/chapter3/images/star.png
new file mode 100644
index 000000000..87f4464bd
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/images/star.png
Binary files differ
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/main-old.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/main-old.py
new file mode 100644
index 000000000..4a8743c37
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/main-old.py
@@ -0,0 +1,52 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+from PySide2.QtWidgets import QApplication
+from bookwindow import BookWindow
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ window = BookWindow()
+ window.resize(800, 600)
+ window.show()
+
+ sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/main.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/main.py
new file mode 100644
index 000000000..50d2c0d6b
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/main.py
@@ -0,0 +1,53 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+from PySide2.QtWidgets import QApplication
+from bookwindow import BookWindow
+import rc_books
+
+if __name__ == "__main__":
+ app = QApplication([])
+
+ window = BookWindow()
+ window.resize(800, 600)
+ window.show()
+
+ sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/tutorials/portingguide/hello_world_ex.py b/sources/pyside2/doc/tutorials/portingguide/hello_world_ex.py
new file mode 100644
index 000000000..c83dda55c
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/hello_world_ex.py
@@ -0,0 +1,76 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+import random
+
+from PySide2.QtWidgets import (QApplication, QLabel,
+ QPushButton, QVBoxLayout, QWidget)
+from PySide2.QtCore import Qt, Slot
+
+class MyWidget(QWidget):
+ def __init__(self):
+ super().__init__()
+
+ self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]
+
+ self.button = QPushButton("Click me!")
+ self.text = QLabel("Hello World")
+ self.text.setAlignment(Qt.AlignCenter)
+
+ self.layout = QVBoxLayout()
+ self.layout.addWidget(self.text)
+ self.layout.addWidget(self.button)
+ self.setLayout(self.layout)
+
+ self.button.clicked.connect(self.magic)
+
+ @Slot()
+ def magic(self):
+ self.text.setText(random.choice(self.hello))
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ widget = MyWidget()
+ widget.resize(800, 600)
+ widget.show()
+
+ sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/tutorials/portingguide/index.rst b/sources/pyside2/doc/tutorials/portingguide/index.rst
new file mode 100644
index 000000000..aabf4b19f
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/portingguide/index.rst
@@ -0,0 +1,196 @@
+Porting a C++ Application to Python
+*************************************
+
+Qt for Python lets you use Qt APIs in a Python application.
+So the next question is: What does it take to port an
+existing C++ application? Try porting a Qt C++ application
+to Python to understand this.
+
+Before you start, ensure that all the prerequisites for
+Qt for Python are met. See
+:doc:`Getting Started <../../gettingstarted>` for more
+information. In addition, familiarize yourself with the
+basic differences between Qt in C++ and in Python.
+
+Basic differences
+==================
+
+This section highlights some of the basic differences
+between C++ and Python, and how Qt differs between these
+two contexts.
+
+C++ vs Python
+--------------
+
+* In the interest of code reuse, both C++ and Python
+ provide ways for one file of code to use facilities
+ provided by another. In C++, this is done using the
+ ``#include`` directive to access the API definition of
+ the reused code. The Python equivalent is an ``import``
+ statement.
+* The constructor of a C++ class shares the name of its
+ class and automatically calls the constructor of any
+ base-classes (in a predefined order) before it runs.
+ In Python, the ``__init__()`` method is the constructor
+ of the class, and it can explicitly call base-class
+ constructors in any order.
+* C++ uses the keyword, ``this``, to implicitly refer to
+ the current object. In python, you need to explicitly
+ mention the current object as the first parameter
+ to each instance method of the class; it is conventionally
+ named ``self``.
+* And more importantly, forget about curly braces, {}, and
+ semi-colon, ;.
+* Precede variable definitions with the ``global`` keyword,
+ only if they need global scope.
+
+.. code:: python
+
+ var = None
+ def func(key, value = None):
+ """Does stuff with a key and an optional value.
+
+ If value is omitted or None, the value from func()'s
+ last call is reused.
+ """
+ global var
+ if value is None:
+ if var is None:
+ raise ValueError("Must pass a value on first call", key, value)
+ value = var
+ else:
+ var = value
+ doStuff(key, value)
+
+In this example, ``func()`` would treat ``var`` as a local
+name without the ``global`` statement. This would lead to
+a ``NameError`` in the ``value is None`` handling, on
+accessing ``var``. For more information about this, see
+`Python refernce documentation <python refdoc>`_.
+
+.. _python refdoc: https://docs.python.org/3/reference/simple_stmts.html#the-global-statement
+
+.. tip:: Python being an interpreted language, most often
+ the easiest way is to try your idea in the interperter.
+ You could call the ``help()`` function in the
+ interpreter on any built-in function or keyword in
+ Python. For example, a call to ``help(import)`` should
+ provide documentation about the ``import`` statment
+
+Last but not the least, try out a few examples to
+familiarize yourself with the Python coding style and
+follow the guidelines outlined in the
+`PEP8 - Style Guide <pep8>`_.
+
+.. _pep8: <https://www.python.org/dev/peps/pep-0008/#naming-conventions>
+
+.. code-block:: python
+
+ import sys
+
+ from PySide2.QtWidgets import QApplication, QLabel
+
+ app = QApplication(sys.argv)
+ label = QLabel("Hello World")
+ label.show()
+ sys.exit(app.exec_())
+
+.. note:: Qt provides classes that are meant to manage
+ the application-specific requirements depending on
+ whether the application is console-only
+ (QCoreApplication), GUI with QtWidgets (QApplication),
+ or GUI without QtWidgets (QGuiApplication). These
+ classes load necessary plugins, such as the GUI
+ libraries required by an application. In this case, it is
+ QApplication that is initialized first as the application
+ has a GUI with QtWidgets.
+
+Qt in the C++ and Python context
+---------------------------------
+
+Qt behaves the same irrespective of whether it is used
+in a C++ or a Python application. Considering that C++
+and Python use different language semantics, some
+differences between the two variants of Qt are inevitable.
+Here are a few important ones that you must be aware of:
+
+* **Qt Properties**: ``Q_PROPERTY`` macros are used in C++ to add a
+ public member variable with getter and setter functions. Python's
+ alternative for this is the ``@property`` decorator before the
+ getter and setter function definitions.
+* **Qt Signals and Slots**: Qt offers a unique callback mechanism,
+ where a signal is emitted to notify the occurrence of an event, so
+ that slots connected to this signal can react to it. In C++,
+ the class definition must define the slots under the
+ ``public Q_SLOTS:`` and signals under ``Q_SIGNALS:``
+ access specifier. You connect these two using one of the
+ several variants of the QObject::connect() function. Python's
+ equivalent for this is the `@Slot`` decorator just before the
+ function definition. This is necessary to register the slots
+ with the QtMetaObject.
+* **QString, QVariant, and other types**
+
+ - Qt for Python does not provide access to QString and
+ QVariant. You must use Python's native types instead.
+ - QChar and QStringRef are represented as Python strings,
+ and QStringList is converted to a list of strings.
+ - QDate, QDateTime, QTime, and QUrl's __hash__() methods
+ return a string representation so that identical dates
+ (and identical date/times or times or URLs) have
+ identical hash values.
+ - QTextStream's bin(), hex(), and oct() functions are
+ renamed to bin_(), hex_(), and oct_() respectively. This
+ should avoid name conflicts with Python's built-in
+ functions.
+
+* **QByteArray**: A QByteArray is treated as a list of
+ bytes without encoding. The equivalent type in Python
+ varies; Python 2 uses "str" type, whereas Python 3 uses
+ "bytes". To avoid confusion, a QString is represented as
+ an encoded human readable string, which means it is
+ a "unicode" object in Python 2, and a "str" in Python 3.
+
+Here is the improved version of the Hello World example,
+demonstrating some of these differences:
+
+.. literalinclude:: hello_world_ex.py
+ :linenos:
+ :lines: 40-
+
+.. note:: The ``if`` block is just a good practice when
+ developing a Python application. It lets the Python file
+ behave differently depending on whether it is imported
+ as a module in another file or run directly. The
+ ``__name__`` variable will have different values in
+ these two scenarios. It is ``__main__`` when the file is
+ run directly, and the module's file name
+ (``hello_world_ex`` in this case) when imported as a
+ module. In the later case, everything defined in the
+ module except the ``if`` block is available to the
+ importing file.
+
+Notice that the QPushButton's ``clicked`` signal is
+connected to the ``magic`` function to randomly change the
+QLabel's ``text`` property. The `@Slot`` decorator marks
+the methods that are slots and informs the QtMetaObject about
+them.
+
+Porting a Qt C++ example
+=========================
+
+Qt offers several C++ examples to showcase its features and help
+beginners learn. You can try porting one of these C++ examples to
+Python. The
+`books SQL example <https://code.qt.io/cgit/qt/qtbase.git/tree/examples/sql/books>`_
+is a good starting point as it does not require you to write UI-specific code in
+Python, but can use its ``.ui`` file instead.
+
+The following chapters guides you through the porting process:
+
+.. toctree::
+ :glob:
+ :titlesonly:
+
+ chapter1/chapter1
+ chapter2/chapter2
+ chapter3/chapter3
diff --git a/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst b/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst
index 36a12381d..62336ee81 100644
--- a/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst
+++ b/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst
@@ -31,7 +31,7 @@ application and PySide2 integration:
.. literalinclude:: main.py
:linenos:
:lines: 98-108
- :emphasize-lines: 103,107
+ :emphasize-lines: 6,9
Notice that we specify the name of the context property, **con**,
and also we explicitly load our QML file.
@@ -47,7 +47,7 @@ application and PySide2 integration:
.. literalinclude:: view.qml
:linenos:
:lines: 85-93
- :emphasize-lines: 89-91
+ :emphasize-lines: 5-7
The properties *Italic*, *Bold*, and *Underline* are mutually
exclusive, this means only one can be active at any time.
@@ -64,7 +64,7 @@ application and PySide2 integration:
.. literalinclude:: main.py
:linenos:
:lines: 79-84
- :emphasize-lines: 82,84
+ :emphasize-lines: 4,6
Returning *True* or *False* allows you to activate and deactivate
the properties of the QML UI elements.
@@ -98,14 +98,14 @@ application and PySide2 integration:
.. literalinclude:: main.py
:linenos:
:lines: 41-48
- :emphasize-lines: 48
+ :emphasize-lines: 8
- You can read more about this configuration file
- `here <https://doc.qt.io/qt-5/qtquickcontrols2-configuration.html>`_.
+ You can read more about this configuration file
+ `here <https://doc.qt.io/qt-5/qtquickcontrols2-configuration.html>`_.
The final look of your application will be:
.. image:: textproperties_material.png
-You can download `view.qml <view.qml>`_ and `main.py <main.py>`_
-to try this example.
+You can :download:`view.qml <view.qml>` and
+:download:`main.py <main.py>` to try this example.
diff --git a/sources/pyside2/doc/videos.rst b/sources/pyside2/doc/videos.rst
new file mode 100644
index 000000000..cda84f419
--- /dev/null
+++ b/sources/pyside2/doc/videos.rst
@@ -0,0 +1,28 @@
+|project| Videos
+================
+
+Webinar: Creating user interfaces with Qt for Python
+----------------------------------------------------
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/wKqLaNqxgas" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>
+
+Webinar: Develop your first Qt for Python application
+------------------------------------------------------
+
+.. raw:: html
+
+ <div style="position: relative; padding-bottom: 56.25%; height: 0;
+ overflow: hidden; max-width: 100%; height: auto;">
+ <iframe src="https://www.youtube.com/embed/HDBjmSiOBxY" frameborder="0"
+ allowfullscreen style="position: absolute; top: 0; left: 0;
+ width: 100%; height: 100%;">
+ </iframe>
+ </div>