aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/doc/tutorials/basictutorial
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/doc/tutorials/basictutorial')
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst6
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/dialog.rst43
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/icons.zipbin0 -> 6156 bytes
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst34
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst214
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/translations.rst168
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/treewidget.rst12
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/uifiles.rst88
-rw-r--r--sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst36
9 files changed, 326 insertions, 275 deletions
diff --git a/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst b/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst
index 2221858bc..c5464640b 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/clickablebutton.rst
@@ -60,7 +60,8 @@ signal to the `say_hello()` function:
button.clicked.connect(say_hello)
Finally, we show the button and start the Qt main loop:
-::
+
+.. code-block:: python
# Show the button
button.show()
@@ -68,9 +69,8 @@ Finally, we show the button and start the Qt main loop:
app.exec()
Here is the complete code for this example:
-::
- #!/usr/bin/python
+.. code-block:: python
import sys
from PySide6.QtWidgets import QApplication, QPushButton
diff --git a/sources/pyside6/doc/tutorials/basictutorial/dialog.rst b/sources/pyside6/doc/tutorials/basictutorial/dialog.rst
index bc06d6d9b..b7712672b 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/dialog.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/dialog.rst
@@ -3,8 +3,8 @@ Creating a Dialog Application
This tutorial shows how to build a simple dialog with some
basic widgets. The idea is to let users provide their name
-in a `QLineEdit`, and the dialog greets them on click of a
-`QPushButton`.
+in a ``QLineEdit``, and the dialog greets them on click of a
+``QPushButton``.
Let us just start with a simple stub that creates and shows
a dialog. This stub is updated during the course of this
@@ -31,24 +31,24 @@ tutorial, but you can use this stub as is if you need to:
sys.exit(app.exec())
The imports aren't new to you, the same for the creation of the
-`QApplication` and the execution of the Qt main loop.
+``QApplication`` and the execution of the Qt main loop.
The only novelty here is the **class definition**.
You can create any class that subclasses PySide6 widgets.
-In this case, we are subclassing `QDialog` to define a custom
+In this case, we are subclassing ``QDialog`` to define a custom
dialog, which we name as **Form**. We have also implemented the
-`init()` method that calls the `QDialog`'s init method with the
-parent widget, if any. Also, the new `setWindowTitle()` method
-just sets the title of the dialog window. In `main()`, you can see
+``init()`` method that calls the ``QDialog``'s init method with the
+parent widget, if any. Also, the new ``setWindowTitle()`` method
+just sets the title of the dialog window. In ``main()``, you can see
that we are creating a *Form object* and showing it to the world.
Create the Widgets
------------------
-We are going to create two widgets: a `QLineEdit` where users can
-enter their name, and a `QPushButton` that prints the contents of
-the `QLineEdit`.
-So, let's add the following code to the `init()` method of our Form:
+We are going to create two widgets: a ``QLineEdit`` where users can
+enter their name, and a ``QPushButton`` that prints the contents of
+the ``QLineEdit``.
+So, let's add the following code to the ``init()`` method of our Form:
::
# Create widgets
@@ -62,8 +62,8 @@ Create a layout to organize the Widgets
---------------------------------------
Qt comes with layout-support that helps you organize the widgets
-in your application. In this case, let's use `QVBoxLayout` to lay out
-the widgets vertically. Add the following code to the `init()` method,
+in your application. In this case, let's use ``QVBoxLayout`` to lay out
+the widgets vertically. Add the following code to the ``init()`` method,
after creating the widgets:
::
@@ -72,40 +72,41 @@ after creating the widgets:
layout.addWidget(self.edit)
layout.addWidget(self.button)
-So, we create the layout, add the widgets with `addWidget()`.
+So, we create the layout, add the widgets with ``addWidget()``.
Create the function to greet and connect the Button
---------------------------------------------------
Finally, we just have to add a function to our custom **Form**
and *connect* our button to it. Our function will be a part of
-the Form, so you have to add it after the `init()` function:
+the Form, so you have to add it after the ``init()`` function:
::
# Greets the user
def greetings(self):
print(f"Hello {self.edit.text()}")
-Our function just prints the contents of the `QLineEdit` to the
+Our function just prints the contents of the ``QLineEdit`` to the
python console. We have access to the text by means of the
-`QLineEdit.text()` method.
+``QLineEdit.text()`` method.
Now that we have everything, we just need to *connect* the
-`QPushButton` to the `Form.greetings()` method. To do so, add the
-following line to the `init()` method:
+``QPushButton`` to the ``Form.greetings()`` method. To do so, add the
+following line to the ``init()`` method:
::
# Add button signal to greetings slot
self.button.clicked.connect(self.greetings)
-Once executed, you can enter your name in the `QLineEdit` and watch
+Once executed, you can enter your name in the ``QLineEdit`` and watch
the console for greetings.
Complete code
-------------
Here is the complete code for this tutorial:
-::
+
+.. code-block:: python
import sys
from PySide6.QtWidgets import (QLineEdit, QPushButton, QApplication,
diff --git a/sources/pyside6/doc/tutorials/basictutorial/icons.zip b/sources/pyside6/doc/tutorials/basictutorial/icons.zip
new file mode 100644
index 000000000..e279e37b8
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/basictutorial/icons.zip
Binary files differ
diff --git a/sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst b/sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst
index 477c5b738..858293beb 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/qrcfiles.rst
@@ -1,7 +1,7 @@
.. _using_qrc_files:
-Using `.qrc` Files (`pyside6-rcc`)
-**********************************
+Using ``.qrc`` Files (``pyside6-rcc``)
+**************************************
The `Qt Resource System`_ is a mechanism for storing binary files
in an application.
@@ -17,7 +17,7 @@ In this tutorial you will learn how to load custom images as button icons.
For inspiration, we will try to adapt the multimedia player example
from Qt.
-As you can see on the following image, the `QPushButton` that are used
+As you can see on the following image, the ``QPushButton`` that are used
for the media actions (play, pause, stop, and so on) are using the
default icons meant for such actions.
@@ -25,29 +25,27 @@ default icons meant for such actions.
:alt: Multimedia Player Qt Example
You could make the application more attractive by designing the icons,
-but in case you don't want to design them, `download the following set`_
-and use them.
+but in case you don't want to design them, you can download and use them.
+
+:download:`Download icons <icons.zip>`
.. image:: icons.png
:alt: New Multimedia icons
-You can find more information about the `rcc` command, and `.qrc` file
+You can find more information about the ``rcc`` command, and ``.qrc`` file
format, and the resource system in general in the `Qt Resource System`_
site.
-.. _`download the following set`: icons/
-
-The `.qrc` file
-================
+The ``.qrc`` file
+=================
-Before running any command, add information about the resources to a `.qrc`
+Before running any command, add information about the resources to a ``.qrc``
file.
-In the following example, notice how the resources are listed in `icons.qrc`
+In the following example, notice how the resources are listed in ``icons.qrc``
::
- </ui>
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>icons/play.png</file>
@@ -62,15 +60,15 @@ In the following example, notice how the resources are listed in `icons.qrc`
Generating a Python file
=========================
-Now that the `icons.qrc` file is ready, use the `pyside6-rcc` tool to generate
+Now that the ``icons.qrc`` file is ready, use the ``pyside6-rcc`` tool to generate
a Python class containing the binary information about the resources
To do this, we need to run::
- pyside6-rcc icons.rc -o rc_icons.py
+ pyside6-rcc icons.qrc -o rc_icons.py
-The `-o` option lets you specify the output filename,
-which is `rc_icons.py` in this case.
+The ``-o`` option lets you specify the output filename,
+which is ``rc_icons.py`` in this case.
To use the generated file, add the following import at the top of your main Python file::
@@ -167,7 +165,7 @@ Now, the constructor of your class should look like this:
Executing the example
=====================
-Run the application by calling `python main.py` to checkout the new icon-set:
+Run the application by calling ``python main.py`` to checkout the new icon-set:
.. image:: player-new.png
:alt: New Multimedia Player Qt Example
diff --git a/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst b/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst
index 470b4ab70..0bfd9e276 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/signals_and_slots.rst
@@ -43,101 +43,104 @@ a signal directly to another signal. (This will emit the second signal
immediately whenever the first is emitted.)
Qt's widgets have many predefined signals and slots. For example,
-`QAbstractButton` (base class of buttons in Qt) has a `clicked()`
-signal and `QLineEdit` (single line input field) has a slot named
-'clear()`. So, a text input field with a button to clear the text
-could be implemented by placing a `QToolButton` to the right of the
-`QLineEdit` and connecting its `clicked()` signal to the slot
-'clear()`. This is done using the `connect()` method of the signal:
+``QAbstractButton`` (base class of buttons in Qt) has a ``clicked()``
+signal and ``QLineEdit`` (single line input field) has a slot named
+``clear()``. So, a text input field with a button to clear the text
+could be implemented by placing a ``QToolButton`` to the right of the
+``QLineEdit`` and connecting its ``clicked()`` signal to the slot
+``clear()``. This is done using the ``connect()`` method of the signal:
- .. code-block:: python
+.. code-block:: python
- button = QToolButton()
- line_edit = QLineEdit()
- button.clicked.connect(line_edit.clear)
+ button = QToolButton()
+ line_edit = QLineEdit()
+ button.clicked.connect(line_edit.clear)
-`connect()` returns a `QMetaObject.Connection` object, which can be
-used with the `disconnect()` method to sever the connection.
+``connect()`` returns a ``QMetaObject.Connection`` object, which can be
+used with the ``disconnect()`` method to sever the connection.
Signals can also be connected to free functions:
- .. code-block:: python
+.. code-block:: python
- import sys
- from PySide6.QtWidgets import QApplication, QPushButton
+ import sys
+ from PySide6.QtWidgets import QApplication, QPushButton
- def function():
- print("The 'function' has been called!")
+ def function():
+ print("The 'function' has been called!")
- app = QApplication()
- button = QPushButton("Call function")
- button.clicked.connect(func)
- button.show()
- sys.exit(app.exec())
+ app = QApplication()
+ button = QPushButton("Call function")
+ button.clicked.connect(function)
+ button.show()
+ sys.exit(app.exec())
Connections can be spelled out in code or, for widget forms,
designed in the
`Signal-Slot Editor <https://doc.qt.io/qt-6/designer-connection-mode.html>`_
-of Qt Designer.
+of *Qt Widgets Designer*.
The Signal Class
----------------
When writing classes in Python, signals are declared as class level
variables of the class ``QtCore.Signal()``. A QWidget-based button
-that emits a `clicked()` signal could look as
+that emits a ``clicked()`` signal could look as
follows:
- .. code-block:: python
+.. code-block:: python
- from PySide6.QtCore import Qt, Signal
- from PySide6.QtWidgets import QWidget
+ from PySide6.QtCore import Qt, Signal
+ from PySide6.QtWidgets import QWidget
- class Button(QWidget):
+ class Button(QWidget):
- clicked = Signal(Qt.MouseButton)
+ clicked = Signal(Qt.MouseButton)
- ...
+ ...
- def mousePressEvent(self, event):
- self.clicked.emit(event.button())
+ def mousePressEvent(self, event):
+ self.clicked.emit(event.button())
The constructor of ``Signal`` takes a tuple or a list of Python types
and C types:
- .. code-block:: python
+.. code-block:: python
- signal1 = Signal(int) # Python types
- signal2 = Signal(QUrl) # Qt Types
- signal3 = Signal(int, str, int) # more than one type
- signal4 = Signal((float,), (QDate,)) # optional types
+ signal1 = Signal(int) # Python types
+ signal2 = Signal(QUrl) # Qt Types
+ signal3 = Signal(int, str, int) # more than one type
+ signal4 = Signal((float,), (QDate,)) # optional types
In addition to that, it can receive also a named argument ``name`` that defines
the signal name. If nothing is passed, the new signal will have the same name
as the variable that it is being assigned to.
- .. code-block:: python
+.. code-block:: python
- # TODO
- signal5 = Signal(int, name='rangeChanged')
- # ...
- rangeChanged.emit(...)
+ # TODO
+ signal5 = Signal(int, name='rangeChanged')
+ # ...
+ rangeChanged.emit(...)
Another useful option of ``Signal`` is the arguments name,
useful for QML applications to refer to the emitted values by name:
- .. code-block:: python
+.. code-block:: python
- sumResult = Signal(int, arguments=['sum'])
+ sumResult = Signal(int, arguments=['sum'])
- .. code-block:: javascript
+.. code-block:: javascript
- Connections {
- target: ...
- function onSumResult(sum) {
- // do something with 'sum'
- }
+ Connections {
+ target: ...
+ function onSumResult(sum) {
+ // do something with 'sum'
+ }
+
+
+.. _slot-decorator:
The Slot Class
--------------
@@ -146,11 +149,11 @@ Slots in QObject-derived classes should be indicated by the decorator
``@QtCore.Slot()``. Again, to define a signature just pass the types
similar to the ``QtCore.Signal()`` class.
- .. code-block:: python
+.. code-block:: python
- @Slot(str)
- def slot_function(self, s):
- ...
+ @Slot(str)
+ def slot_function(self, s):
+ ...
``Slot()`` also accepts a ``name`` and a ``result`` keyword.
@@ -159,6 +162,19 @@ Python type. The ``name`` keyword behaves the same way as in ``Signal()``. If
nothing is passed as name then the new slot will have the same name as the
function that is being decorated.
+We recommend marking all methods used by signal connections with a
+``@QtCore.Slot()`` decorator. Not doing causes run-time overhead due to the
+method being added to the ``QMetaObject`` when creating the connection. This is
+particularly important for ``QObject`` classes registered with QML, where
+missing decorators can introduce bugs.
+
+Missing decorators can be diagnosed by setting activating warnings of the
+logging category ``qt.pyside.libpyside``; for example by setting the
+environment variable:
+
+.. code-block:: bash
+
+ export QT_LOGGING_RULES="qt.pyside.libpyside.warning=true"
.. _overloading-signals-and-slots:
@@ -172,62 +188,76 @@ In Qt 6, signals have distinct names for different types.
The following example uses two handlers for a Signal and a Slot to showcase
the different functionality.
- .. code-block:: python
+.. code-block:: python
- import sys
- from PySide6.QtWidgets import QApplication, QPushButton
- from PySide6.QtCore import QObject, Signal, Slot
+ import sys
+ from PySide6.QtWidgets import QApplication, QPushButton
+ from PySide6.QtCore import QObject, Signal, Slot
- class Communicate(QObject):
- # create two new signals on the fly: one will handle
- # int type, the other will handle strings
- speak = Signal((int,), (str,))
+ class Communicate(QObject):
+ # create two new signals on the fly: one will handle
+ # int type, the other will handle strings
+ speak = Signal((int,), (str,))
- def __init__(self, parent=None):
- super().__init__(self, parent)
+ def __init__(self, parent=None):
+ super().__init__(parent)
- self.speak[int].connect(self.say_something)
- self.speak[str].connect(self.say_something)
+ self.speak[int].connect(self.say_something)
+ self.speak[str].connect(self.say_something)
- # define a new slot that receives a C 'int' or a 'str'
- # and has 'say_something' as its name
- @Slot(int)
- @Slot(str)
- def say_something(self, arg):
- if isinstance(arg, int):
- print("This is a number:", arg)
- elif isinstance(arg, str):
- print("This is a string:", arg)
+ # define a new slot that receives a C 'int' or a 'str'
+ # and has 'say_something' as its name
+ @Slot(int)
+ @Slot(str)
+ def say_something(self, arg):
+ if isinstance(arg, int):
+ print("This is a number:", arg)
+ elif isinstance(arg, str):
+ print("This is a string:", arg)
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+ someone = Communicate()
- if __name__ == "__main__":
- app = QApplication(sys.argv)
- someone = Communicate()
+ # emit 'speak' signal with different arguments.
+ # we have to specify the str as int is the default
+ someone.speak.emit(10)
+ someone.speak[str].emit("Hello everybody!")
- # emit 'speak' signal with different arguments.
- # we have to specify the str as int is the default
- someone.speak.emit(10)
- someone.speak[str].emit("Hello everybody!")
+.. _signals-and-slots-strings:
Specifying Signals and Slots by Method Signature Strings
--------------------------------------------------------
Signals and slots can also be specified as C++ method signature
-strings passed through the `SIGNAL()` and/or `SLOT()` functions:
+strings passed through the ``SIGNAL()`` and/or ``SLOT()`` functions:
+
+.. code-block:: python
+
+ from PySide6.QtCore import SIGNAL, SLOT
+
+ button.connect(SIGNAL("clicked(Qt::MouseButton)"),
+ action_handler, SLOT("action1(Qt::MouseButton)"))
+
+This is not normally recommended; it is only needed
+for a few cases where signals are only accessible via ``QMetaObject``
+(``QAxObject``, ``QAxWidget``, ``QDBusInterface`` or ``QWizardPage::registerField()``):
- .. code-block:: python
+.. code-block:: python
- from PySide6.QtCore import SIGNAL, SLOT
+ wizard.registerField("text", line_edit, "text",
+ SIGNAL("textChanged(QString)"))
- button.connect(SIGNAL("clicked(Qt::MouseButton)"),
- action_handler, SLOT("action1(Qt::MouseButton)"))
+The signature strings can be found by querying ``QMetaMethod.methodSignature()``
+when introspecting ``QMetaObject``:
-This is not recommended for connecting signals, it is mostly
-used to specify signals for methods like `QWizardPage::registerField()`:
+.. code-block:: python
- .. code-block:: python
+ mo = widget.metaObject()
+ for m in range(mo.methodOffset(), mo.methodCount()):
+ print(mo.method(m).methodSignature())
- wizard.registerField("text", line_edit, "text",
- SIGNAL("textChanged(QString)"))
+Slots should be decorated using :ref:`@Slot <slot-decorator>`.
diff --git a/sources/pyside6/doc/tutorials/basictutorial/translations.rst b/sources/pyside6/doc/tutorials/basictutorial/translations.rst
index 31cd004a3..21c16cdcd 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/translations.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/translations.rst
@@ -9,10 +9,10 @@ Translating Applications
Qt Linguist
-----------
-`Qt Linguist <https://doc.qt.io/qt-6/qtlinguist-index.html>`_ and
+`Qt Linguist`_ and
its related tools can be used to provide translations for applications.
-The ``examples/widgets/linguist`` example illustrates this. The example is
+The :ref:`qt-linguist-example` example illustrates this. The example is
very simple, it has a menu and shows a list of programming languages with
multiselection.
@@ -28,18 +28,18 @@ The linguist example has a number of messages enclosed in ``self.tr()``.
The status bar message shown in response to a selection change uses
a plural form depending on a count:
- .. code-block:: python
+.. code-block:: python
- count = len(self._list_widget.selectionModel().selectedRows())
- message = self.tr("%n language(s) selected", "", count)
+ count = len(self._list_widget.selectionModel().selectedRows())
+ message = self.tr("%n language(s) selected", "", count)
The translation workflow for the example is as follows:
The translated messages are extracted using the ``lupdate`` tool,
producing XML-based ``.ts`` files:
- .. code-block:: bash
+.. code-block:: bash
- pyside6-lupdate main.py -ts example_de.ts
+ pyside6-lupdate main.py -ts example_de.ts
If ``example_de.ts`` already exists, it will be updated with the new
messages added to the code in-between.
@@ -52,15 +52,29 @@ they should be passed to the ``pyside6-lupdate`` tool as well:
pyside6-lupdate main.py main.qml form.ui -ts example_de.ts
The source files generated by ``pyside6-uic`` from the form files
-should `not` be passed.
+should **not** be passed.
+
+The ``lupdate`` mode of ``pyside6-project`` can also be used for this. It
+collects all source files and runs ``pyside6-lupdate`` when ``.ts`` file(s)
+are given in the ``.pyproject`` file:
+
+.. code-block:: bash
+
+ pyside6-project lupdate .
``.ts`` files are translated using *Qt Linguist*. Once this is complete,
the files are converted to a binary form (``.qm`` files):
- .. code-block:: bash
+.. code-block:: bash
+
+ pyside6-lrelease example_de.ts -qm example_de.qm
+
+``pyside6-project`` will build the ``.qm`` file automatically when
+``.ts`` file(s) are given in the ``.pyproject`` file:
- mkdir translations
- pyside6-lrelease example_de.ts -qm translations/example_de.qm
+.. code-block:: bash
+
+ pyside6-project build .
To avoid having to ship the ``.qm`` files, it is recommend
to put them into a Qt resource file along with icons and other
@@ -68,43 +82,45 @@ applications resources (see :ref:`using_qrc_files`).
The resource file ``linguist.qrc`` provides the ``example_de.qm``
under ``:/translations``:
- .. code-block:: xml
+.. code-block:: xml
- <!DOCTYPE RCC><RCC version="1.0">
- <qresource>
- <file>translations/example_de.qm</file>
- </qresource>
- </RCC>
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="translations">
+ <file>example_de.qm</file>
+ </qresource>
+ </RCC>
At runtime, the translations need to be loaded using the ``QTranslator`` class:
- .. code-block:: python
+.. code-block:: python
- path = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
- translator = QTranslator(app)
- if translator.load(QLocale.system(), 'qtbase', '_', path):
- app.installTranslator(translator)
- translator = QTranslator(app)
- path = ':/translations'
- if translator.load(QLocale.system(), 'example', '_', path):
- app.installTranslator(translator)
+ path = QLibraryInfo.location(QLibraryInfo.TranslationsPath)
+ translator = QTranslator(app)
+ if translator.load(QLocale.system(), 'qtbase', '_', path):
+ app.installTranslator(translator)
+ translator = QTranslator(app)
+ path = ':/translations'
+ if translator.load(QLocale.system(), 'example', '_', path):
+ app.installTranslator(translator)
The code first loads the translations shipped for Qt and then
the translations of the applications loaded from resources.
The example can then be run in German:
- .. code-block:: bash
+.. code-block:: bash
+
+ LANG=de python main.py
- LANG=de python main.py
+.. _Qt Linguist: https://doc.qt.io/qt-6/qtlinguist-index.html
GNU gettext
-----------
-The `GNU gettext <https://docs.python.org/3/library/gettext.html>`_ module
+The `GNU gettext`_ module
can be used to provide translations for applications.
-The ``examples/widgets/gettext`` example illustrates this. The example is
+The :ref:`gettext-example` example illustrates this. The example is
very simple, it has a menu and shows a list of programming languages with
multiselection.
@@ -116,29 +132,29 @@ aliased to ``ngettext``.
Those functions are defined at the top:
- .. code-block:: python
+.. code-block:: python
- import gettext
- ...
- _ = None
- ngettext = None
+ import gettext
+ # ...
+ _ = None
+ ngettext = None
and later assigned as follows:
- .. code-block:: python
-
- src_dir = Path(__file__).resolve().parent
- try:
- translation = gettext.translation('example', localedir=src_dir / 'locales')
- if translation:
- translation.install()
- _ = translation.gettext
- ngettext = translation.ngettext
- except FileNotFoundError:
- pass
- if not _:
- _ = gettext.gettext
- ngettext = gettext.ngettext
+.. code-block:: python
+
+ src_dir = Path(__file__).resolve().parent
+ try:
+ translation = gettext.translation('example', localedir=src_dir / 'locales')
+ if translation:
+ translation.install()
+ _ = translation.gettext
+ ngettext = translation.ngettext
+ except FileNotFoundError:
+ pass
+ if not _:
+ _ = gettext.gettext
+ ngettext = gettext.ngettext
This specifies that our translation file has the base name ``example`` and
will be found in the source tree under ``locales``. The code will try
@@ -146,18 +162,18 @@ to load a translation matching the current language.
Messages to be translated look like:
- .. code-block:: python
+.. code-block:: python
- file_menu = self.menuBar().addMenu(_("&File"))
+ file_menu = self.menuBar().addMenu(_("&File"))
The status bar message shown in response to a selection change uses
a plural form depending on a count:
- .. code-block:: python
+.. code-block:: python
- count = len(self._list_widget.selectionModel().selectedRows())
- message = ngettext("{0} language selected",
- "{0} languages selected", count).format(count)
+ count = len(self._list_widget.selectionModel().selectedRows())
+ message = ngettext("{0} language selected",
+ "{0} languages selected", count).format(count)
The ``ngettext()`` function takes the singular form, plural form and the count.
The returned string still contains the formatting placeholder, so it needs
@@ -172,43 +188,45 @@ is first created:
xgettext -L Python -o locales/example.pot main.py
This file has a few generic placeholders which can be replaced by the
-appropriate values. It is then copied to the ``de_DE/LC_MESSAGES`` directory.
+appropriate values. It is then copied to the ``de_DE/LC_MESSAGES`` directory.
- .. code-block:: bash
+.. code-block:: bash
- cd locales/de_DE/LC_MESSAGES/
- cp ../../example.pot .
+ cd locales/de_DE/LC_MESSAGES/
+ cp ../../example.pot .
Further adaptions need to be made to account for the German plural
form and encoding:
- .. code-block::
+.. code-block::
- "Project-Id-Version: PySide6 gettext example\n"
- "POT-Creation-Date: 2021-07-05 14:16+0200\n"
- "Language: de_DE\n"
- "MIME-Version: 1.0\n"
- "Content-Type: text/plain; charset=UTF-8\n"
- "Content-Transfer-Encoding: 8bit\n"
- "Plural-Forms: nplurals=2; plural=n != 1;\n"
+ "Project-Id-Version: PySide6 gettext example\n"
+ "POT-Creation-Date: 2021-07-05 14:16+0200\n"
+ "Language: de_DE\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
Below, the translated messages can be given:
- .. code-block::
+.. code-block::
- #: main.py:57
- msgid "&File"
- msgstr "&Datei"
+ #: main.py:57
+ msgid "&File"
+ msgstr "&Datei"
Finally, the ``.pot`` is converted to its binary form (machine object file,
``.mo``), which needs to be deployed:
- .. code-block:: bash
+.. code-block:: bash
- msgfmt -o example.mo example.pot
+ msgfmt -o example.mo example.pot
The example can then be run in German:
- .. code-block:: bash
+.. code-block:: bash
+
+ LANG=de python main.py
- LANG=de python main.py
+.. _GNU gettext: https://docs.python.org/3/library/gettext.html
diff --git a/sources/pyside6/doc/tutorials/basictutorial/treewidget.rst b/sources/pyside6/doc/tutorials/basictutorial/treewidget.rst
index b286de507..f431cb5c4 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/treewidget.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/treewidget.rst
@@ -11,14 +11,14 @@ information in trees. You can also create a data model and display it using a
further on. To know more about the Model/View architecture in Qt, refer to
its `official documentation <https://doc.qt.io/qt-6/model-view-programming.html>`_.
-1. Import ``QTreeWidget`` and ``QTreeWidgetItem`` for this application:
+#. Import ``QTreeWidget`` and ``QTreeWidgetItem`` for this application:
.. code-block:: python
import sys
from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
-2. Define a dictionary with project structures to display the information as a
+#. Define a dictionary with project structures to display the information as a
tree, with files belonging to each project:
.. code-block:: python
@@ -27,13 +27,13 @@ information in trees. You can also create a data model and display it using a
"Project B": ["file_b.csv", "photo.jpg"],
"Project C": []}
-3. Initialize the ``QApplication`` singleton:
+#. Initialize the ``QApplication`` singleton:
.. code-block:: python
app = QApplication()
-4. Configure the ``QTreeWidget`` to have two columns, one for the item name,
+#. Configure the ``QTreeWidget`` to have two columns, one for the item name,
and the other for item type information of the files in the project
directories.
You can set the column name with the ``setHeaderLabels`` as described below:
@@ -44,7 +44,7 @@ information in trees. You can also create a data model and display it using a
tree.setColumnCount(2)
tree.setHeaderLabels(["Name", "Type"])
-5. Iterate the data structure, create the ``QTreeWidgetItem`` elements, and add
+#. Iterate the data structure, create the ``QTreeWidgetItem`` elements, and add
the corresponding children to each parent.
We also extract the extension name for only the files and add them
into the second column.
@@ -64,7 +64,7 @@ information in trees. You can also create a data model and display it using a
tree.insertTopLevelItems(0, items)
-7. Show the tree and execute the ``QApplication``.
+#. Show the tree and execute the ``QApplication``.
.. code-block:: python
diff --git a/sources/pyside6/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside6/doc/tutorials/basictutorial/uifiles.rst
index cd1057c97..cb945908d 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/uifiles.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/uifiles.rst
@@ -1,27 +1,27 @@
.. _using_ui_files:
-Using `.ui` files from Designer or QtCreator with `QUiLoader` and `pyside6-uic`
-*******************************************************************************
+Using ``.ui`` files from Designer or QtCreator with ``QUiLoader`` and ``pyside6-uic``
+*************************************************************************************
This page describes the use of
-`Qt Designer <https://doc.qt.io/qt-6/qtdesigner-manual.html>`_ to create
+`Qt Widgets Designer <https://doc.qt.io/qt-6/qtdesigner-manual.html>`_ to create
graphical interfaces based on Qt Widgets for your Qt for Python project.
-**Qt Designer** is a graphical UI design tool which is available as a
+*Qt Widgets Designer* is a graphical UI design tool which is available as a
standalone binary (``pyside6-designer``) or embedded into the
-`Qt Creator IDE <https://doc.qt.io/qtcreator>`_. Its use within **Qt Creator**
+`Qt Creator IDE <https://doc.qt.io/qtcreator>`_. Its use within *Qt Creator*
is described at
-`Using Qt Designer <https://doc.qt.io/qtcreator/creator-using-qt-designer.html>`_.
+`Using Qt Widgets Designer <https://doc.qt.io/qtcreator/creator-using-qt-designer.html>`_.
.. image:: uifiles.png
:alt: Designer and the equivalent code
-The designs are stored in `.ui` files, which is an XML-based format. It will
+The designs are stored in ``.ui`` files, which is an XML-based format. It will
be converted to Python or C++ code populating a widget instance at project build
time by the `pyside6-uic <https://doc.qt.io/qt-6/uic.html>`_ tool.
-To create a new Qt Design Form in **Qt Creator**, choose
-`File/New File Or Project` and "Main Window" for template. Save it as
-`mainwindow.ui`. Add a `QPushButton` to the center of the centralwidget.
+To create a new Qt Design Form in *Qt Creator*, choose
+``File/New File Or Project`` and "Main Window" for template. Save it as
+``mainwindow.ui``. Add a ``QPushButton`` to the center of the centralwidget.
Your file ``mainwindow.ui`` should look something like this:
@@ -88,12 +88,12 @@ Option A: Generating a Python class
===================================
The standard way to interact with a **UI file** is to generate a Python
-class from it. This is possible thanks to the `pyside6-uic` tool.
+class from it. This is possible thanks to the ``pyside6-uic`` tool.
To use this tool, you need to run the following command on a console::
- pyside6-uic mainwindow.ui > ui_mainwindow.py
+ pyside6-uic mainwindow.ui -o ui_mainwindow.py
-We redirect all the output of the command to a file called `ui_mainwindow.py`,
+We redirect all the output of the command to a file called ``ui_mainwindow.py``,
which will be imported directly::
from ui_mainwindow import Ui_MainWindow
@@ -136,7 +136,7 @@ file:
.. note::
- You must run `pyside6-uic` again every time you make changes
+ You must run ``pyside6-uic`` again every time you make changes
to the **UI file**.
Option B: Loading it directly
@@ -149,7 +149,7 @@ module:
from PySide6.QtUiTools import QUiLoader
-The `QUiLoader` lets us load the **ui file** dynamically
+The ``QUiLoader`` lets us load the **ui file** dynamically
and use it right away:
.. code-block:: python
@@ -192,40 +192,41 @@ 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
+.. code-block:: bash
python main.py
.. note::
- `QUiLoader` uses connect() calls taking the function signatures as string
+ ``QUiLoader`` uses ``connect()`` calls taking the function signatures as string
arguments for signal/slot connections.
- It is thus unable to handle Python types like `str` or `list` from
+ It is thus unable to handle Python types like ``str`` or ``list`` from
custom widgets written in Python since these types are internally mapped
to different C++ types.
.. _designer_custom_widgets:
-Custom Widgets in Qt Designer
-=============================
+Custom Widgets in Qt Widgets Designer
+=====================================
-**Qt Designer** is able to use user-provided (custom) widgets. They are shown
-in the widget box and can be dragged onto the form just like Qt's widgets (see
-`Using Custom Widgets with Qt Designer <https://doc.qt.io/qt-6/designer-using-custom-widgets.html>`_
-). Normally, this requires implementing the widget as a plugin to Qt Designer
-written in C++ implementing its
-`QDesignerCustomWidgetInterface <https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html>`_ .
+*Qt Widgets Designer* is able to use user-provided (custom) widgets.
+They are shown in the widget box and can be dragged onto the form just like
+Qt's widgets (see
+`Using Custom Widgets with Qt Widgets Designer <https://doc.qt.io/qt-6/designer-using-custom-widgets.html>`_
+). Normally, this requires implementing the widget as a plugin to
+*Qt Widgets Designer* written in C++ implementing its
+`QDesignerCustomWidgetInterface`_ .
Qt for Python provides a simple interface for this which is similar to
:meth:`registerCustomWidget()<PySide6.QtUiTools.QUiLoader.registerCustomWidget>`.
The widget needs to be provided as a Python module, as shown by
-the widgetbinding example (file ``wigglywidget.py``) or
-the taskmenuextension example (file ``tictactoe.py``).
+the :ref:`widgetbinding-example` (file ``wigglywidget.py``) or
+the :ref:`task-menu-extension-example` (file ``tictactoe.py``).
-Registering this with Qt Designer is done by providing
+Registering this with *Qt Widgets Designer* is done by providing
a registration script named ``register*.py`` and pointing
-the path-type environment variable ``PYSIDE_DESIGNER_PLUGINS``
+the path-type environment variable ``PYSIDE_DESIGNER_PLUGINS``
to the directory.
The code of the registration script looks as follows:
@@ -262,20 +263,20 @@ The code of the registration script looks as follows:
QPyDesignerCustomWidgetCollection provides an implementation of
-`QDesignerCustomWidgetCollectionInterface <https://doc.qt.io/qt-6/qdesignercustomwidgetcollectioninterface.html>`_
-exposing custom widgets to **Qt Designer** with static convenience functions
-for registering types or adding instances of
-`QDesignerCustomWidgetInterface <https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html>`_ .
+`QDesignerCustomWidgetCollectionInterface`_
+exposing custom widgets to *Qt Widgets Designer* with static convenience
+functions for registering types or adding instances of
+`QDesignerCustomWidgetInterface`_ .
The function
:meth:`registerCustomWidget()<PySide6.QtDesigner.QPyDesignerCustomWidgetCollection.registerCustomWidget>`
-is used to register a widget type with **Qt Designer**. In the simple case, it
-can be used like `QUiLoader.registerCustomWidget()`. It takes the custom widget
+is used to register a widget type with *Qt Widgets Designer*. In the simple case, it
+can be used like ``QUiLoader.registerCustomWidget()``. It takes the custom widget
type and some optional keyword arguments passing values that correspond to the
getters of
-`QDesignerCustomWidgetInterface <https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html>`_ :
+`QDesignerCustomWidgetInterface`_ :
-When launching **Qt Designer** via its launcher ``pyside6-designer``,
+When launching *Qt Widgets Designer* via its launcher ``pyside6-designer``,
the custom widget should be visible in the widget box.
For advanced usage, it is also possible to pass the function an implementation
@@ -286,15 +287,18 @@ is registered for the custom widget. The example is a port of the
corresponding C++
`Task Menu Extension Example <https://doc.qt.io/qt-6/qtdesigner-taskmenuextension-example.html>`_ .
-Troubleshooting the Qt Designer Plugin
-++++++++++++++++++++++++++++++++++++++
+.. _QDesignerCustomWidgetCollectionInterface: https://doc.qt.io/qt-6/qdesignercustomwidgetcollectioninterface.html
+.. _QDesignerCustomWidgetInterface: https://doc.qt.io/qt-6/qdesignercustomwidgetinterface.html
+
+Troubleshooting the Qt Widgets Designer Plugin
+++++++++++++++++++++++++++++++++++++++++++++++
- The launcher ``pyside6-designer`` must be used. The standalone
- **Qt Designer** will not load the plugin.
+ *Qt Widgets Designer* will not load the plugin.
- The menu item **Help/About Plugin** brings up a dialog showing the plugins
found and potential load error messages.
- Check the console or Windows Debug view for further error messages.
- Due to the buffering of output by Python, error messages may appear
- only after **Qt Designer** has terminated.
+ only after *Qt Widgets Designer* has terminated.
- When building Qt for Python, be sure to set the ``--standalone`` option
for the plugin to be properly installed.
diff --git a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst
index e1af8b8a9..2fa51c0a8 100644
--- a/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst
+++ b/sources/pyside6/doc/tutorials/basictutorial/widgetstyling.rst
@@ -23,7 +23,7 @@ to each component. As an example, look at the following simple snippet:
w.show()
sys.exit(app.exec())
-When you execute this code, you will see a simple `QLabel` aligned at the
+When you execute this code, you will see a simple ``QLabel`` aligned at the
center, and with a placeholder text.
.. image:: widgetstyling-simple-no.png
@@ -32,8 +32,8 @@ center, and with a placeholder text.
You can style your application using the CSS-like syntax.
For more information, see `Qt Style Sheets Reference`_.
-A `QLabel` can be styled differently by setting some of its CSS
-properties, such as `background-color` and `font-family`,
+A ``QLabel`` can be styled differently by setting some of its CSS
+properties, such as ``background-color`` and ``font-family``,
so let's see how does the code look like with these changes:
.. code-block:: python
@@ -55,7 +55,7 @@ so let's see how does the code look like with these changes:
w.show()
sys.exit(app.exec())
-Now when you run the code, notice that the `QLabel` looks different with your
+Now when you run the code, notice that the ``QLabel`` looks different with your
custom style:
.. image:: widgetstyling-simple-yes.png
@@ -64,15 +64,15 @@ custom style:
.. note::
- If you don't have the font `Titillium` installed, you can try with any
+ If you don't have the font ``Titillium`` installed, you can try with any
other you prefer.
- Remember you can list your installed fonts using `QFontDatabase`,
- specifically the `families()` method.
+ Remember you can list your installed fonts using ``QFontDatabase``,
+ specifically the ``families()`` method.
Styling each UI element separately like you did in the previous snippet is a
lot of work. The easier alternative for this is to use Qt Style Sheets,
-which is one or more `.qss` files defining the style for the UI elements in
+which is one or more ``.qss`` files defining the style for the UI elements in
your application.
More examples can be found in the `Qt Style Sheet Examples`_ documentation
@@ -94,7 +94,7 @@ Qt Style Sheets
It's recommended to create a full new Qt style to cover all the possible
corner cases.
-A `qss` file is quite similar to a CSS file, but you need to specify the Widget
+A ``qss`` file is quite similar to a CSS file, but you need to specify the Widget
component and optionally the name of the object::
QLabel {
@@ -105,8 +105,8 @@ component and optionally the name of the object::
font-size: 20px;
}
-The first style defines a `background-color` for all `QLabel` objects in your
-application, whereas the later one styles the `title` object only.
+The first style defines a ``background-color`` for all ``QLabel`` objects in your
+application, whereas the later one styles the ``title`` object only.
.. note::
@@ -115,8 +115,8 @@ application, whereas the later one styles the `title` object only.
`label.setObjectName("title")`
-Once you have a `qss` file for your application, you can apply it by reading
-the file and using the `QApplication.setStyleSheet(str)` function:
+Once you have a ``qss`` file for your application, you can apply it by reading
+the file and using the ``QApplication.setStyleSheet(str)`` function:
.. code-block:: python
@@ -132,7 +132,7 @@ the file and using the `QApplication.setStyleSheet(str)` function:
sys.exit(app.exec())
-Having a general `qss` file allows you to decouple the styling aspects of
+Having a general ``qss`` file allows you to decouple the styling aspects of
the code, without mixing it in the middle of the general functionality, and you
can simply enable it or disable it.
@@ -142,14 +142,14 @@ Look at this new example, with more widgets components:
:linenos:
:lines: 22-44
-This displays a two column widget, with a `QListWidget` on the left and a
-`QLabel` and a `QPushButton` on the right. It looks like this when you run the
+This displays a two column widget, with a ``QListWidget`` on the left and a
+``QLabel`` and a ``QPushButton`` on the right. It looks like this when you run the
code:
.. image:: widgetstyling-no.png
:alt: Widget with no style
-If you add content to the previously described `style.qss` file, you can modify
+If you add content to the previously described ``style.qss`` file, you can modify
the look-n-feel of the previous example:
.. literalinclude:: style.qss
@@ -161,7 +161,7 @@ You can also use state-based styling on the QListWidget *items* for example, to
style them differently depending on whether they are *selected* or not.
After applying all the styling alternatives you explored in this topic, notice
-that the `QLabel` example looks a lot different now.
+that the ``QLabel`` example looks a lot different now.
Try running the code to check its new look:
.. image:: widgetstyling-yes.png