diff options
author | Cristián Maureira-Fredes <Cristian.Maureira-Fredes@qt.io> | 2021-09-08 00:17:50 +0200 |
---|---|---|
committer | Cristián Maureira-Fredes <Cristian.Maureira-Fredes@qt.io> | 2021-09-17 13:30:25 +0200 |
commit | 41522805c65ab2de956e4bb636172a3b9bcfdfcb (patch) | |
tree | 944a0b3ff84fef9140ed960cb33913d1d760d2c9 | |
parent | 6392ea613c1cf93a3fd793cd61050aa348ae1c7c (diff) |
doc: update qml tutorials
- Add screenshot and updates to the 'first qml application'
- Update 'context properties' for 'python-qml interaction' tutorial
- Remove the 'Real use-cases' subsection
- Update the snippets from QML application tutorial
- Update the QML SQL integration tutorial
Change-Id: I9c6a1bedb66b130e9c28d340b236e778f7c109b8
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r-- | sources/pyside6/doc/tutorials/basictutorial/greenapplication.png | bin | 0 -> 2089 bytes | |||
-rw-r--r-- | sources/pyside6/doc/tutorials/basictutorial/qml.rst | 50 | ||||
-rw-r--r-- | sources/pyside6/doc/tutorials/index.rst | 7 | ||||
-rw-r--r-- | sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst | 12 | ||||
-rw-r--r-- | sources/pyside6/doc/tutorials/qmlintegration/main.py | 1 | ||||
-rw-r--r-- | sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst | 48 | ||||
-rw-r--r-- | sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml | 10 | ||||
-rw-r--r-- | sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst | 43 |
8 files changed, 102 insertions, 69 deletions
diff --git a/sources/pyside6/doc/tutorials/basictutorial/greenapplication.png b/sources/pyside6/doc/tutorials/basictutorial/greenapplication.png Binary files differnew file mode 100644 index 000000000..29ea0a701 --- /dev/null +++ b/sources/pyside6/doc/tutorials/basictutorial/greenapplication.png diff --git a/sources/pyside6/doc/tutorials/basictutorial/qml.rst b/sources/pyside6/doc/tutorials/basictutorial/qml.rst index 0ea346069..49cd3d94a 100644 --- a/sources/pyside6/doc/tutorials/basictutorial/qml.rst +++ b/sources/pyside6/doc/tutorials/basictutorial/qml.rst @@ -1,7 +1,7 @@ Your First QtQuick/QML Application ********************************** -QML is a declarative language that lets you develop applications +QML_ is a declarative language that lets you develop applications faster than with traditional languages. It is ideal for designing the UI of your application because of its declarative nature. In QML, a user interface is specified as a tree of objects with properties. In @@ -13,55 +13,67 @@ a file with the QML description of the user interface, and a python file that loads the QML file. To make things easier, let's save both files in the same directory. -Here is a simple QML file called `view.qml`: +Here is a simple QML file called :code:`view.qml`: .. code-block:: javascript - import QtQuick 2.0 + import QtQuick Rectangle { + id: main width: 200 height: 200 color: "green" Text { text: "Hello World" - anchors.centerIn: parent + anchors.centerIn: main } } -We start by importing `QtQuick 2.0`, which is a QML module. +We start by importing :code:`QtQuick`, which is a QML module. The rest of the QML code is pretty straightforward for those who have previously used HTML or XML files. Basically, we are creating a green rectangle with the size `200*200`, and adding a Text element -that reads "Hello World". The code `anchors.centerIn: parent` makes -the text appear centered in relation to its immediate parent, which -is the Rectangle in this case. +that reads "Hello World". The code :code:`anchors.centerIn: main` makes +the text appear centered within the object with :code:`id: main`, +which is the Rectangle in this case. Now, let's see how the code looks on the PySide6. -Let's call it `main.py`: +Let's call it :code:`main.py`: .. code-block:: python + import sys from PySide6.QtWidgets import QApplication from PySide6.QtQuick import QQuickView - from PySide6.QtCore import QUrl - app = QApplication([]) - view = QQuickView() - url = QUrl("view.qml") + if __name__ == "__main__": + app = QApplication() + view = QQuickView() - view.setSource(url) - view.show() - app.exec() + view.setSource("view.qml") + view.show() + sys.exit(app.exec()) If you are already familiar with PySide6 and have followed our tutorials, you have already seen much of this code. -The only novelties are that you must `import QtQuick` and set the -source of the `QQuickView` object to the URL of your QML file. -Then, as any Qt widget, you call `QQuickView.show()`. +The only novelties are that you must :code:`import QtQuick` and set the +source of the :code:`QQuickView` object to the URL of your QML file. +Then, similar to what you do with any Qt widget, you call +:code:`QQuickView.show()`. .. note:: If you are programming for desktop, you should consider adding `view.setResizeMode(QQuickView.SizeRootObjectToView)` before showing the view. + +When you execute the :code:`main.py` script, you will see the following +application: + + +.. image:: greenapplication.png + :alt: Simple QML and Python example + :align: center + +.. _QML: https://doc.qt.io/qt-6/qmlapplications.html diff --git a/sources/pyside6/doc/tutorials/index.rst b/sources/pyside6/doc/tutorials/index.rst index 628ab1fc3..82408ce93 100644 --- a/sources/pyside6/doc/tutorials/index.rst +++ b/sources/pyside6/doc/tutorials/index.rst @@ -169,13 +169,6 @@ Quick/QML: Basic tutorials basictutorial/qml.rst qmlintegration/qmlintegration.rst - -Real use-cases applications ---------------------------- - -.. toctree:: - :maxdepth: 1 - qmlapp/qmlapplication.rst qmlsqlintegration/qmlsqlintegration.rst .. diff --git a/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst b/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst index 082490f4b..4f444aae7 100644 --- a/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst +++ b/sources/pyside6/doc/tutorials/qmlapp/qmlapplication.rst @@ -9,7 +9,7 @@ QtQml and QtQuick modules provides the necessary infrastructure for QML-based UIs. In this tutorial, you'll also learn how to provide data from Python -as a QML context property, which is then consumed by the ListView +as a QML initial property, which is then consumed by the ListView defined in the QML file. Before you begin, install the following prerequisites: @@ -62,7 +62,7 @@ development process using Qt Creator: .. literalinclude:: main.py :linenos: :lines: 40-60 - :emphasize-lines: 12-20 + :emphasize-lines: 7-9,14-17 #. Now, set up the application window using :ref:`PySide6.QtGui.QGuiApplication<qguiapplication>`, which manages the application-wide @@ -78,13 +78,13 @@ development process using Qt Creator: Otherwise, the root item will retain its original size on resizing the window. -#. You can now expose the ``data_list`` variable as a QML context +#. You can now expose the ``data_list`` variable as a QML initial property, which will be consumed by the QML ListView item in ``view.qml``. .. literalinclude:: main.py :linenos: :lines: 40-70 - :emphasize-lines: 27-30 + :emphasize-lines: 28-31 #. Load the ``view.qml`` to the ``QQuickView`` and call ``show()`` to display the application window. @@ -92,14 +92,14 @@ development process using Qt Creator: .. literalinclude:: main.py :linenos: :lines: 40-79 - :emphasize-lines: 33-39 + :emphasize-lines: 33-40 #. Finally, execute the application to start the event loop and clean up. .. literalinclude:: main.py :linenos: :lines: 40- - :emphasize-lines: 41-43 + :emphasize-lines: 42-44 #. Your application is ready to be run now. Select **Projects** mode to choose the Python version to run it. diff --git a/sources/pyside6/doc/tutorials/qmlintegration/main.py b/sources/pyside6/doc/tutorials/qmlintegration/main.py index 0408313d3..db1a59c2e 100644 --- a/sources/pyside6/doc/tutorials/qmlintegration/main.py +++ b/sources/pyside6/doc/tutorials/qmlintegration/main.py @@ -46,6 +46,7 @@ from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine, QmlElement from PySide6.QtQuickControls2 import QQuickStyle +import style_rc # To be used on the @QmlElement decorator # (QML_IMPORT_MINOR_VERSION is optional) diff --git a/sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst b/sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst index 46b055e13..0b33a746e 100644 --- a/sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst +++ b/sources/pyside6/doc/tutorials/qmlintegration/qmlintegration.rst @@ -1,13 +1,13 @@ -Python-based context properties -=============================== +Python-QML integration +====================== This tutorial provides a quick walk-through of a python application that loads, and interacts with a QML file. QML is a declarative language that lets you design UIs faster than a traditional language, such as C++. The QtQml and QtQuick modules provides the necessary infrastructure for QML-based UIs. -In this tutorial, you will learn how to integrate Python with a QML application through a context -property. This mechanism will help us to understand how to use Python as a backend for certain +In this tutorial, you will learn how to integrate Python with a QML application. +This mechanism will help us to understand how to use Python as a backend for certain signals from the UI elements in the QML interface. Additionally, you will learn how to provide a modern look to your QML application using one of the features from Qt Quick Controls 2. @@ -29,29 +29,47 @@ application and PySide6 integration: .. literalinclude:: main.py :linenos: - :lines: 98-108 - :emphasize-lines: 6,9 + :lines: 100-113 + :emphasize-lines: 4,9 - Notice that we specify the name of the context property, **con**, - and also we explicitly load our QML file. + Notice that we only need a :code:`QQmlApplicationEngine` to + :code:`load` the QML file. -#. Define the `Bridge` class, containing all the logic for the context property: +#. Define the `Bridge` class, containing all the logic for the element + that will be register in QML: .. literalinclude:: main.py :linenos: :lines: 51-91 + :emphasize-lines: 3,4,7 + + Notice that the registration happens thanks to the :code:`QmlElement` + decorator, that underneath uses the reference to the :code:`Bridge` + class and the variables :code:`QML_IMPORT_NAME` and + :code:`QML_IMPORT_MAJOR_VERSION`. #. Now, go back to the QML file and connect the signals to the slots defined in the `Bridge` class: + .. code:: js + + Bridge { + id: bridge + } + + Inside the :code:`ApplicationWindow` we declare a component + with the same name as the Python class, and provide an :code:`id:`. + This :code:`id` will help you to get a reference to the element + that was registered from Python. + .. literalinclude:: view.qml :linenos: - :lines: 85-93 - :emphasize-lines: 5-7 + :lines: 82-92 + :emphasize-lines: 6-8 The properties *Italic*, *Bold*, and *Underline* are mutually exclusive, this means only one can be active at any time. To achieve this each time we select one of these options, we - check the three properties via the context property as you can + check the three properties via the QML element property as you can see in the above snippet. Only one of the three will return *True*, while the other two will return *False*, that is how we make sure only one is being @@ -73,7 +91,7 @@ application and PySide6 integration: .. literalinclude:: main.py :linenos: - :lines: 64-70 + :lines: 71-76 #. Now, for changing the look of our application, you have two options: @@ -96,8 +114,8 @@ application and PySide6 integration: .. literalinclude:: main.py :linenos: - :lines: 41-48 - :emphasize-lines: 8 + :lines: 41-49 + :emphasize-lines: 9 You can read more about this configuration file `here <https://doc.qt.io/qt-5/qtquickcontrols2-configuration.html>`_. diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml b/sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml index 453be1252..2a784fc3d 100644 --- a/sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml +++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/chat.qml @@ -37,10 +37,10 @@ ** ****************************************************************************/ -import QtQuick 2.12 -import QtQuick.Layouts 1.12 -import QtQuick.Controls 2.12 -import ChatModel 1.0 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import ChatModel ApplicationWindow { id: window @@ -54,7 +54,7 @@ ApplicationWindow { } ColumnLayout { - anchors.fill: parent + anchors.fill: window ListView { id: listView diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst b/sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst index b7d627282..053d0316e 100644 --- a/sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst +++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst @@ -4,7 +4,7 @@ QML, SQL and PySide Integration Tutorial This tutorial is very similar to the `Qt Chat Tutorial`_ one but it focuses on explaining how to integrate a SQL database into a PySide6 application using QML for its UI. -.. _`Qt Chat Tutorial`: https://doc.qt.io/qt-5/qtquickcontrols-chattutorial-example.html +.. _`Qt Chat Tutorial`: https://doc.qt.io/qt-6/qtquickcontrols-chattutorial-example.html sqlDialog.py ------------ @@ -16,7 +16,7 @@ The database contains a single line to mock the beginning of a conversation. .. literalinclude:: sqlDialog.py :linenos: - :lines: 40-77 + :lines: 40-79 The ``SqlConversationModel`` class offers the read-only data model required for the non-editable contacts list. It derives from the :ref:`QSqlQueryModel` class, which is the logical choice for @@ -28,14 +28,14 @@ of a chat application. .. literalinclude:: sqlDialog.py :linenos: - :lines: 80-91 + :lines: 83-95 In ``setRecipient()``, you set a filter over the returned results from the database, and emit a signal every time the recipient of the message changes. .. literalinclude:: sqlDialog.py :linenos: - :lines: 93-103 + :lines: 97-106 The ``data()`` function falls back to ``QSqlTableModel``'s implementation if the role is not a custom user role. @@ -44,7 +44,7 @@ that field, and then use that index to find the value to be returned. .. literalinclude:: sqlDialog.py :linenos: - :lines: 105-112 + :lines: 108-115 In ``roleNames()``, we return a Python dictionary with our custom role and role names as key-values @@ -55,7 +55,7 @@ and that's why we're using the ``hash`` function. .. literalinclude:: sqlDialog.py :linenos: - :lines: 114-128 + :lines: 117-131 The ``send_message()`` function uses the given recipient and message to insert a new record into the database. @@ -64,7 +64,7 @@ since all the changes will be cached in the model until you do so. .. literalinclude:: sqlDialog.py :linenos: - :lines: 130-145 + :lines: 133-152 chat.qml -------- @@ -88,7 +88,7 @@ Let's step through the ``chat.qml`` file. .. literalinclude:: chat.qml :linenos: - :lines: 44-49 + :lines: 45-50 ``ApplicationWindow`` is a Window with some added convenience for creating a header and a footer. It also provides the foundation for popups and supports some basic styling, such as the background @@ -98,6 +98,13 @@ There are three properties that are almost always set when using ApplicationWind ``height``, and ``visible``. Once we've set these, we have a properly sized, empty window ready to be filled with content. +Because we are exposing the :code:`SqlConversationModel` class to QML, we will +declare a component to access it: + + .. literalinclude:: chat.qml + :linenos: + :lines: 52-54 + There are two ways of laying out items in QML: `Item Positioners`_ and `Qt Quick Layouts`_. - Item positioners (`Row`_, `Column`_, and so on) are useful for situations where the size of items @@ -108,7 +115,11 @@ There are two ways of laying out items in QML: `Item Positioners`_ and `Qt Quick .. literalinclude:: chat.qml :linenos: - :lines: 50-53 + :lines: 56-59 + + .. literalinclude:: chat.qml + :linenos: + :lines: 108-110 Pane is basically a rectangle whose color comes from the application's style. It's similar to `Frame`_, but it has no stroke around its border. @@ -140,7 +151,7 @@ Let's look at the ``Listview`` in detail: .. literalinclude:: chat.qml :linenos: - :lines: 53-99 + :lines: 59-106 After filling the ``width`` and ``height`` of its parent, we also set some margins on the view. @@ -170,7 +181,7 @@ We use Pane to cover the area under these two items: .. literalinclude:: chat.qml :linenos: - :lines: 101-125 + :lines: 108-132 The `TextArea`_ should fill the available width of the screen. We assign some placeholder text to provide a visual cue to the contact as to where they should begin @@ -194,16 +205,14 @@ messages levels that our application will generate (errors, warnings, and inform .. literalinclude:: main.py :linenos: - :lines: 40-50 + :lines: 40-52 ``connectToDatabase()`` creates a connection with the SQLite database, creating the actual file if it doesn't already exist. .. literalinclude:: main.py :linenos: - :lines: 53-72 - - + :lines: 55-75 A few interesting things happen in the ``main`` function: @@ -212,7 +221,7 @@ A few interesting things happen in the ``main`` function: using the **QtWidgets** module. - Connecting to the database, - Declaring a :ref:`QQmlApplicationEngine`. - This allows you to access the QML context property to connect Python + This allows you to access the QML Elements to connect Python and QML from the conversation model we built on ``sqlDialog.py``. - Loading the ``.qml`` file that defines the UI. @@ -220,6 +229,6 @@ Finally, the Qt application runs, and your program starts. .. literalinclude:: main.py :linenos: - :lines: 75-85 + :lines: 78-88 .. image:: example_list_view.png |