From 40b06f4998509252356c0104981685fe5cd57bc9 Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Wed, 17 Jun 2020 11:30:29 +0200 Subject: doc: Add widget styling tutorial Usage of the 'setStyleSheet' function and loading '.qss' files. Task-number: PYSIDE-841 Change-Id: I905025488c75cf379c7d77427da93d217169c604 Reviewed-by: Christian Tismer Reviewed-by: Friedemann Kleint --- .../pyside2/doc/tutorials/basictutorial/style.qss | 23 +++ .../tutorials/basictutorial/widgetstyling-no.png | Bin 0 -> 26444 bytes .../basictutorial/widgetstyling-simple-no.png | Bin 0 -> 3834 bytes .../basictutorial/widgetstyling-simple-yes.png | Bin 0 -> 4743 bytes .../tutorials/basictutorial/widgetstyling-yes.png | Bin 0 -> 32311 bytes .../doc/tutorials/basictutorial/widgetstyling.py | 95 ++++++++++++ .../doc/tutorials/basictutorial/widgetstyling.rst | 169 +++++++++++++++++++++ sources/pyside2/doc/tutorials/index.rst | 1 + 8 files changed, 288 insertions(+) create mode 100644 sources/pyside2/doc/tutorials/basictutorial/style.qss create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-no.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-no.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-yes.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-yes.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst (limited to 'sources') diff --git a/sources/pyside2/doc/tutorials/basictutorial/style.qss b/sources/pyside2/doc/tutorials/basictutorial/style.qss new file mode 100644 index 000000000..b84b98f05 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/style.qss @@ -0,0 +1,23 @@ +QListWidget { + color: #FFFFFF; + background-color: #33373B; +} + +QListWidget::item { + height: 50px; +} + +QListWidget::item:selected { + background-color: #2ABf9E; +} + +QLabel { + background-color: #FFFFFF; + qproperty-alignment: AlignCenter; +} + +QPushButton { + background-color: #2ABf9E; + padding: 20px; + font-size: 18px; +} diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-no.png b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-no.png new file mode 100644 index 000000000..c30dd621b Binary files /dev/null and b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-no.png differ diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-no.png b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-no.png new file mode 100644 index 000000000..eb90e216d Binary files /dev/null and b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-no.png differ diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-yes.png b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-yes.png new file mode 100644 index 000000000..5a714977e Binary files /dev/null and b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-yes.png differ diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-yes.png b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-yes.png new file mode 100644 index 000000000..8ba49bd26 Binary files /dev/null and b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-yes.png differ diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py new file mode 100644 index 000000000..41af464c8 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py @@ -0,0 +1,95 @@ +############################################################################# +## +## Copyright (C) 2020 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.QtWidgets import (QApplication, QHBoxLayout, QLabel, QListWidget, + QListWidgetItem, QPushButton, QVBoxLayout, + QWidget) + +_placeholder = """ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim +veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea +commodo consequat. Duis aute irure dolor in reprehenderit in voluptate +velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint +occaecat cupidatat non proident, sunt in culpa qui officia deserunt +mollit anim id est laborum +""" + + +class Widget(QWidget): + def __init__(self, parent=None): + super(Widget, self).__init__(parent) + + menu_widget = QListWidget() + for i in range(10): + item = QListWidgetItem("Item {}".format(i)) + item.setTextAlignment(Qt.AlignCenter) + menu_widget.addItem(item) + + text_widget = QLabel(_placeholder) + button = QPushButton("Something") + + content_layout = QVBoxLayout() + content_layout.addWidget(text_widget) + content_layout.addWidget(button) + main_widget = QWidget() + main_widget.setLayout(content_layout) + + layout = QHBoxLayout() + layout.addWidget(menu_widget, 1) + layout.addWidget(main_widget, 4) + self.setLayout(layout) + + +if __name__ == "__main__": + app = QApplication() + + w = Widget() + w.show() + + _style = None + with open("style.qss", "r") as f: + _style = f.read() + app.setStyleSheet(_style) + + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst new file mode 100644 index 000000000..a79f9c898 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst @@ -0,0 +1,169 @@ +Widget Styling +************** + +Qt Widgets application use a default theme depending on the platform. +In some cases, there are system-wide configurations that modify the Qt theme, +and applications are displayed differently. + +However, you can take care of your own widgets and provide a custom style +to each component. As an example, look at the following simple snippet: + +.. code-block:: python + + import sys + from PySide2.QtCore import Qt + from PySide2.QtWidgets import QApplication, QLabel + + if __name__ == "__main__": + app = QApplication() + w = QLabel("This is a placeholder text") + w.setAlignment(Qt.AlignCenter) + w.show() + sys.exit(app.exec_()) + +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 + :alt: Simple Widget with no style + +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`, +so let's see how does the code look like with these changes: + +.. code-block:: python + + import sys + from PySide2.QtCore import Qt + from PySide2.QtWidgets import QApplication, QLabel + + if __name__ == "__main__": + app = QApplication() + w = QLabel("This is a placeholder text") + w.setAlignment(Qt.AlignCenter) + w.setStyleSheet(""" + background-color: #262626; + color: #FFFFFF; + font-family: Titillium; + font-size: 18px; + """) + w.show() + sys.exit(app.exec_()) + +Now when you run the code, notice that the `QLabel` looks different with your +custom style: + +.. image:: widgetstyling-simple-yes.png + :alt: Simple Widget with Style + + +.. note:: + + 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. + + +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 +your application. + +More examples can be found in the `Qt Style Sheet Examples`_ documentation +page. + + +.. _`Qt Style Sheets Reference`: https://doc.qt.io/qt-5/stylesheet-reference.html +.. _`Qt Style Sheet Examples`: https://doc.qt.io/qt-5/stylesheet-examples.html + +Qt Style Sheets +=============== + +.. warning:: + + Before starting modifying your application, keep in mind that you will be + responsible for all the graphical details of the application. + Altering margins, and sizes might end up looking strange or incorrect, so you + need to be careful when altering the style. + 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 +component and optionally the name of the object:: + + QLabel { + background-color: red; + } + + QLabel#title { + 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. + +.. note:: + + You can set object names with the `setObjectName(str)` function to any Qt + object, for example: for a `label = QLabel("Test")`, you can write + `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: + +.. code-block:: python + + if __name__ == "__main__": + app = QApplication() + + w = Widget() + w.show() + + with open("style.qss", "r") as f: + _style = f.read() + app.setStyleSheet(_style) + + sys.exit(app.exec_()) + +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. + +Look at this new example, with more widgets components: + +.. literalinclude:: widgetstyling.py + :linenos: + :lines: 59-81 + +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 +the look-n-feel of the previous example: + +.. literalinclude:: style.qss + :linenos: + +The style changes mainly the color of the different widgets, alter the +alignment, and includes some spacing. +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. +Try running the code to check its new look: + +.. image:: widgetstyling-yes.png + :alt: Widget with style + +You have the freedom to tune your style sheets and provide a really nice +look-n-feel to all your applications. diff --git a/sources/pyside2/doc/tutorials/index.rst b/sources/pyside2/doc/tutorials/index.rst index 598b42ca1..9739eee97 100644 --- a/sources/pyside2/doc/tutorials/index.rst +++ b/sources/pyside2/doc/tutorials/index.rst @@ -19,6 +19,7 @@ Basic tutorials basictutorial/dialog.rst basictutorial/uifiles.rst basictutorial/qrcfiles.rst + basictutorial/widgetstyling.rst Real use-cases applications --------------------------- -- cgit v1.2.3