aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/doc/tutorials/expenses/expenses.rst
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/doc/tutorials/expenses/expenses.rst')
-rw-r--r--sources/pyside6/doc/tutorials/expenses/expenses.rst107
1 files changed, 39 insertions, 68 deletions
diff --git a/sources/pyside6/doc/tutorials/expenses/expenses.rst b/sources/pyside6/doc/tutorials/expenses/expenses.rst
index aa672d781..2064488ae 100644
--- a/sources/pyside6/doc/tutorials/expenses/expenses.rst
+++ b/sources/pyside6/doc/tutorials/expenses/expenses.rst
@@ -1,6 +1,5 @@
-######################
Expenses Tool Tutorial
-######################
+======================
In this tutorial you will learn the following concepts:
* creating user interfaces programatically,
@@ -21,9 +20,9 @@ The requirements:
(`QPushButton <https://doc.qt.io/qtforpython/PySide6/QtWidgets/QPushButton.html>`_).
* A verification step to avoid invalid data entry.
* A chart to visualize the expense data
- (`QChart <https://doc.qt.io/qtforpython/PySide6/QtCharts/QtCharts.QChart.html>`_) that will
+ (`QChart <https://doc.qt.io/qtforpython/PySide6/QtCharts/QChart.html>`_) that will
be embedded in a chart view
- (`QChartView <https://doc.qt.io/qtforpython/PySide6/QtCharts/QtCharts.QChartView.html>`_).
+ (`QChartView <https://doc.qt.io/qtforpython/PySide6/QtCharts/QChartView.html>`_).
Empty window
------------
@@ -34,68 +33,41 @@ code block.
.. code-block:: python
:linenos:
- if __name__ == "__main__":
- app = QApplication([])
- # ...
- sys.exit(app.exec())
+ if __name__ == "__main__":
+ app = QApplication([])
+ # ...
+ sys.exit(app.exec())
Now, to start the development, create an empty window called `MainWindow`.
You could do that by defining a class that inherits from `QMainWindow`.
.. literalinclude:: steps/01-expenses.py
:linenos:
- :lines: 45-59
+ :lines: 8-22
:emphasize-lines: 1-4
Now that our class is defined, create an instance of it and call `show()`.
.. literalinclude:: steps/01-expenses.py
:linenos:
- :lines: 45-59
+ :lines: 8-22
:emphasize-lines: 10-12
Menu bar
--------
-Using a `QMainWindow` gives some features for free, among them a *menu bar*. To use it, you need
+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: 6
+ :lines: 9-19
+ :emphasize-lines: 10
Notice that the code snippet adds a *File* menu with the *Exit* option only.
-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-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-block:: python
-
- exit_action.triggered.connect(slot_name)
-
-.. note:: Now a *slot* needs to be defined to exit the application, which can be done using
- `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: 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
-will be invokable from `Signals` of QObjects when connected.
+The *Exit* option must be connected to a slot that triggers the application to exit. We pass
+``QWidget.close()`` here. After the last window has been closed, the application exits.
Empty widget and data
---------------------
@@ -108,13 +80,13 @@ Additionally, you will define example data to visualize later.
.. literalinclude:: steps/04-expenses.py
:linenos:
- :lines: 46-53
+ :lines: 8-15
With the `Widget` class in place, modify `MainWindow`'s initialization code
.. literalinclude:: steps/04-expenses.py
:linenos:
- :lines: 80-84
+ :lines: 37-40
Window layout
-------------
@@ -122,7 +94,7 @@ Window layout
Now that the main empty window is in place, you need to start adding widgets to achieve the main
goal of creating an expenses application.
-After declaring the example data, you can visualize it on a simple `QTableWidget`. To do so, you
+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,
@@ -131,7 +103,7 @@ will add this procedure to the `Widget` constructor.
.. literalinclude:: steps/05-expenses.py
:linenos:
- :lines: 48-73
+ :lines: 11-31
As you can see, the code also includes a `QHBoxLayout` that provides the container to place widgets
horizontally.
@@ -144,7 +116,7 @@ displayed below.
.. literalinclude:: steps/05-expenses.py
:linenos:
- :lines: 75-81
+ :lines: 33-39
Having this process on a separate method is a good practice to leave the constructor more readable,
and to split the main functions of the class in independent processes.
@@ -157,12 +129,12 @@ Because the data that is being used is just an example, you are required to incl
input items to the table, and extra buttons to clear the table's content, and also quit the
application.
-To distribute these input lines and buttons, you will use a `QVBoxLayout` that allows you to place
-elements vertically inside a layout.
+For input lines along with descriptive labels, you will use a `QFormLayout`. Then,
+you will nest the form layout into a `QVBoxLayout` along with the buttons.
.. literalinclude:: steps/06-expenses.py
:linenos:
- :lines: 64-80
+ :lines: 27-43
Leaving the table on the left side and these newly included widgets to the right side
will be just a matter to add a layout to our main `QHBoxLayout` as you saw in the previous
@@ -170,7 +142,7 @@ example:
.. literalinclude:: steps/06-expenses.py
:linenos:
- :lines: 42-47
+ :lines: 45-48
The next step will be connecting those new buttons to slots.
@@ -184,17 +156,19 @@ documentation <https://doc.qt.io/qtforpython/PySide6/QtWidgets/QAbstractButton.h
.. literalinclude:: steps/07-expenses.py
:linenos:
- :lines: 92-95
+ :lines: 50-52
As you can see on the previous lines, we are connecting each *clicked* signal to different slots.
In this example slots are normal class methods in charge of perform a determined task associated
-with our buttons. It is really important to decorate each method declaration with a `@Slot()`, in
-that way PySide6 knows internally how to register them into Qt.
+with our buttons. It is really important to decorate each method declaration with a `@Slot()`,
+that way, PySide6 knows internally how to register them into Qt and they
+will be invokable from `Signals` of QObjects when connected.
+
.. literalinclude:: steps/07-expenses.py
:linenos:
- :lines: 100-129
- :emphasize-lines: 2,16,28
+ :lines: 57-82
+ :emphasize-lines: 1, 23
Since these slots are methods, we can access the class variables, like our `QTableWidget` to
interact with it.
@@ -217,24 +191,21 @@ Verification step
Adding information to the table needs to be a critical action that require a verification step
to avoid adding invalid information, for example, empty information.
-You can use a signal from `QLineEdit` called *textChanged[str]* which will be emitted every
+You can use a signal from `QLineEdit` called *textChanged* which will be emitted every
time something inside changes, i.e.: each key stroke.
-Notice that this time, there is a *[str]* section on the signal, this means that the signal
-will also emit the value of the text that was changed, which will be really useful to verify
-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
+ :lines: 57-58
The content of the *check_disable* slot will be really simple:
.. literalinclude:: steps/08-expenses.py
:linenos:
- :lines: 119-124
+ :lines: 77-80
You have two options, write a verification based on the current value
of the string you retrieve, or manually get the whole content of both
@@ -256,15 +227,15 @@ side of your application.
.. literalinclude:: steps/09-expenses.py
:linenos:
- :lines: 66-68
+ :lines: 30-32
Additionally the order of how you include widgets to the right
`QVBoxLayout` will also change.
.. literalinclude:: steps/09-expenses.py
:linenos:
- :lines: 81-91
- :emphasize-lines: 9
+ :lines: 46-54
+ :emphasize-lines: 8
Notice that before we had a line with `self.right.addStretch()`
to fill up the vertical space between the *Add* and the *Clear* buttons,
@@ -280,8 +251,8 @@ to a slot that creates a chart and includes it into your `QChartView`.
.. literalinclude:: steps/10-expenses.py
:linenos:
- :lines: 103-109
- :emphasize-lines: 6
+ :lines: 62-67
+ :emphasize-lines: 3
That is nothing new, since you already did it for the other buttons,
but now take a look at how to create a chart and include it into
@@ -289,7 +260,7 @@ your `QChartView`.
.. literalinclude:: steps/10-expenses.py
:linenos:
- :lines: 139-151
+ :lines: 95-107
The following steps show how to fill a `QPieSeries`: