From 090d4fba6a444590d850c697472e5fbcef46b0a4 Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Thu, 10 Jun 2021 20:46:25 +0200 Subject: examples: add screenshots to more modules Adding screenshots and small documentation file to the modules - corelib - datavisualization - external - opengl - quick - sql - uitools - webchannel - webenginewidgets - some widgets - xml Renaming the widgets gallery due to name conflict with the quick controls gallery, and fixing two typos from contextinfo.py and hellogl2.py. Task-number: PYSIDE-841 Pick-to: 6.1 Change-Id: I2705e5d605fa738da0dca906cf6acb4b9d5d3dcd Reviewed-by: Friedemann Kleint --- .../corelib/settingseditor/doc/settingseditor.png | Bin 0 -> 10234 bytes .../corelib/settingseditor/doc/settingseditor.rst | 10 + examples/corelib/threads/doc/threads.png | Bin 0 -> 61689 bytes examples/corelib/threads/doc/threads.rst | 10 + examples/datavisualization/bars3d/doc/bars3d.png | Bin 0 -> 31558 bytes examples/datavisualization/bars3d/doc/bars3d.rst | 8 + .../taskmenuextension/doc/taskmenuextension.png | Bin 0 -> 142848 bytes .../taskmenuextension/doc/taskmenuextension.rst | 15 + .../external/matplotlib/widget3d/doc/widget3d.png | Bin 0 -> 135383 bytes .../external/matplotlib/widget3d/doc/widget3d.rst | 9 + .../widget_gaussian/doc/widget_gaussian.png | Bin 0 -> 16198 bytes .../widget_gaussian/doc/widget_gaussian.rst | 9 + examples/external/opencv/doc/opencv.png | Bin 0 -> 132069 bytes examples/external/opencv/doc/opencv.rst | 9 + examples/external/opencv/opencv.pyproject | 3 + examples/external/pandas/doc/pandas.rst | 9 + examples/external/pandas/doc/pandas_simple.png | Bin 0 -> 37161 bytes examples/external/scikit/doc/scikit.png | Bin 0 -> 390406 bytes examples/external/scikit/doc/scikit.rst | 9 + examples/external/scikit/scikit.pyproject | 3 + examples/opengl/contextinfo/contextinfo.py | 12 +- examples/opengl/contextinfo/doc/contextinfo.png | Bin 0 -> 35022 bytes examples/opengl/contextinfo/doc/contextinfo.rst | 10 + examples/opengl/hellogl2/doc/hellogl2.png | Bin 0 -> 4143 bytes examples/opengl/hellogl2/doc/hellogl2.rst | 9 + examples/opengl/hellogl2/hellogl2.py | 2 +- examples/opengl/textures/doc/textures.png | Bin 0 -> 38108 bytes examples/opengl/textures/doc/textures.rst | 9 + examples/quick/painteditem/doc/painteditem.png | Bin 0 -> 3768 bytes examples/quick/painteditem/doc/painteditem.rst | 11 + examples/quickcontrols2/gallery/doc/gallery.png | Bin 0 -> 23828 bytes examples/sql/books/doc/books.png | Bin 0 -> 59045 bytes examples/sql/books/doc/books.rst | 11 + examples/webchannel/standalone/doc/standalone.png | Bin 0 -> 47586 bytes examples/webchannel/standalone/doc/standalone.rst | 8 + .../webenginequick/nanobrowser/doc/nanobrowser.png | Bin 0 -> 56339 bytes .../webenginequick/nanobrowser/doc/nanobrowser.rst | 8 + .../simplebrowser/doc/simplebrowser.png | Bin 0 -> 51615 bytes .../simplebrowser/doc/simplebrowser.rst | 8 + examples/widgets/gallery/gallery.pyproject | 3 - examples/widgets/gallery/main.py | 56 --- examples/widgets/gallery/widgetgallery.py | 435 --------------------- .../widgets/widgetsgallery/doc/widgetsgallery.png | Bin 0 -> 49870 bytes .../widgets/widgetsgallery/doc/widgetsgallery.rst | 16 + examples/widgets/widgetsgallery/main.py | 56 +++ examples/widgets/widgetsgallery/widgetgallery.py | 435 +++++++++++++++++++++ .../widgetsgallery/widgetsgallery.pyproject | 3 + examples/xml/dombookmarks/doc/dombookmarks.png | Bin 0 -> 35779 bytes examples/xml/dombookmarks/doc/dombookmarks.rst | 12 + 49 files changed, 697 insertions(+), 501 deletions(-) create mode 100644 examples/corelib/settingseditor/doc/settingseditor.png create mode 100644 examples/corelib/settingseditor/doc/settingseditor.rst create mode 100644 examples/corelib/threads/doc/threads.png create mode 100644 examples/corelib/threads/doc/threads.rst create mode 100644 examples/datavisualization/bars3d/doc/bars3d.png create mode 100644 examples/datavisualization/bars3d/doc/bars3d.rst create mode 100644 examples/designer/taskmenuextension/doc/taskmenuextension.png create mode 100644 examples/designer/taskmenuextension/doc/taskmenuextension.rst create mode 100644 examples/external/matplotlib/widget3d/doc/widget3d.png create mode 100644 examples/external/matplotlib/widget3d/doc/widget3d.rst create mode 100644 examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.png create mode 100644 examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.rst create mode 100644 examples/external/opencv/doc/opencv.png create mode 100644 examples/external/opencv/doc/opencv.rst create mode 100644 examples/external/opencv/opencv.pyproject create mode 100644 examples/external/pandas/doc/pandas.rst create mode 100644 examples/external/pandas/doc/pandas_simple.png create mode 100644 examples/external/scikit/doc/scikit.png create mode 100644 examples/external/scikit/doc/scikit.rst create mode 100644 examples/external/scikit/scikit.pyproject create mode 100644 examples/opengl/contextinfo/doc/contextinfo.png create mode 100644 examples/opengl/contextinfo/doc/contextinfo.rst create mode 100644 examples/opengl/hellogl2/doc/hellogl2.png create mode 100644 examples/opengl/hellogl2/doc/hellogl2.rst create mode 100644 examples/opengl/textures/doc/textures.png create mode 100644 examples/opengl/textures/doc/textures.rst create mode 100644 examples/quick/painteditem/doc/painteditem.png create mode 100644 examples/quick/painteditem/doc/painteditem.rst create mode 100644 examples/quickcontrols2/gallery/doc/gallery.png create mode 100644 examples/sql/books/doc/books.png create mode 100644 examples/sql/books/doc/books.rst create mode 100644 examples/webchannel/standalone/doc/standalone.png create mode 100644 examples/webchannel/standalone/doc/standalone.rst create mode 100644 examples/webenginequick/nanobrowser/doc/nanobrowser.png create mode 100644 examples/webenginequick/nanobrowser/doc/nanobrowser.rst create mode 100644 examples/webenginewidgets/simplebrowser/doc/simplebrowser.png create mode 100644 examples/webenginewidgets/simplebrowser/doc/simplebrowser.rst delete mode 100644 examples/widgets/gallery/gallery.pyproject delete mode 100644 examples/widgets/gallery/main.py delete mode 100644 examples/widgets/gallery/widgetgallery.py create mode 100644 examples/widgets/widgetsgallery/doc/widgetsgallery.png create mode 100644 examples/widgets/widgetsgallery/doc/widgetsgallery.rst create mode 100644 examples/widgets/widgetsgallery/main.py create mode 100644 examples/widgets/widgetsgallery/widgetgallery.py create mode 100644 examples/widgets/widgetsgallery/widgetsgallery.pyproject create mode 100644 examples/xml/dombookmarks/doc/dombookmarks.png create mode 100644 examples/xml/dombookmarks/doc/dombookmarks.rst (limited to 'examples') diff --git a/examples/corelib/settingseditor/doc/settingseditor.png b/examples/corelib/settingseditor/doc/settingseditor.png new file mode 100644 index 000000000..d281125d3 Binary files /dev/null and b/examples/corelib/settingseditor/doc/settingseditor.png differ diff --git a/examples/corelib/settingseditor/doc/settingseditor.rst b/examples/corelib/settingseditor/doc/settingseditor.rst new file mode 100644 index 000000000..4c60dbe8e --- /dev/null +++ b/examples/corelib/settingseditor/doc/settingseditor.rst @@ -0,0 +1,10 @@ +Settings Editor Example +======================= + +The Settings Editor example shows how Qt's standard settings support is used in +an application by providing an editor that enables the user to view the +settings for installed applications, and modify those that can be edited. + +.. image:: settingseditor.png + :width: 400 + :alt: Settings Editor Screenshot diff --git a/examples/corelib/threads/doc/threads.png b/examples/corelib/threads/doc/threads.png new file mode 100644 index 000000000..d022f4aff Binary files /dev/null and b/examples/corelib/threads/doc/threads.png differ diff --git a/examples/corelib/threads/doc/threads.rst b/examples/corelib/threads/doc/threads.rst new file mode 100644 index 000000000..d1bcf6fd4 --- /dev/null +++ b/examples/corelib/threads/doc/threads.rst @@ -0,0 +1,10 @@ +Mandelbrot Threads Example +========================== + +The Mandelbrot example demonstrates multi-thread programming using Qt. It shows +how to use a worker thread to perform heavy computations without blocking the +main thread's event loop. + +.. image:: threads.png + :width: 400 + :alt: Mandelbrot Threads Screenshot diff --git a/examples/datavisualization/bars3d/doc/bars3d.png b/examples/datavisualization/bars3d/doc/bars3d.png new file mode 100644 index 000000000..fc5cdc168 Binary files /dev/null and b/examples/datavisualization/bars3d/doc/bars3d.png differ diff --git a/examples/datavisualization/bars3d/doc/bars3d.rst b/examples/datavisualization/bars3d/doc/bars3d.rst new file mode 100644 index 000000000..aaa7ea158 --- /dev/null +++ b/examples/datavisualization/bars3d/doc/bars3d.rst @@ -0,0 +1,8 @@ +Bars 3D Example +=============== + +The bars example shows how to make a 3D bar graph using Q3DBars. + +.. image:: simple3d.png + :width: 400 + :alt: Bards 3D Screenshot diff --git a/examples/designer/taskmenuextension/doc/taskmenuextension.png b/examples/designer/taskmenuextension/doc/taskmenuextension.png new file mode 100644 index 000000000..a1fe22e05 Binary files /dev/null and b/examples/designer/taskmenuextension/doc/taskmenuextension.png differ diff --git a/examples/designer/taskmenuextension/doc/taskmenuextension.rst b/examples/designer/taskmenuextension/doc/taskmenuextension.rst new file mode 100644 index 000000000..a1b584fb9 --- /dev/null +++ b/examples/designer/taskmenuextension/doc/taskmenuextension.rst @@ -0,0 +1,15 @@ +Task Menu Extension (Designer) +============================== + +This example shows how to add custom widgets to Qt Designer, +which can be launched with `pyside6-designer`, and to extend +its built-in context menu. + +The main mechanism is based on the :ref:`QPyDesignerCustomWidgetCollection` +class that takes care of handling the registration. + +More information can be found in :ref:`designer_custom_widgets`. + +.. image:: taskmenuextension.png + :width: 400 + :alt: Task Menu Extension Screenshot diff --git a/examples/external/matplotlib/widget3d/doc/widget3d.png b/examples/external/matplotlib/widget3d/doc/widget3d.png new file mode 100644 index 000000000..fa2ed5043 Binary files /dev/null and b/examples/external/matplotlib/widget3d/doc/widget3d.png differ diff --git a/examples/external/matplotlib/widget3d/doc/widget3d.rst b/examples/external/matplotlib/widget3d/doc/widget3d.rst new file mode 100644 index 000000000..b5c9fd8fd --- /dev/null +++ b/examples/external/matplotlib/widget3d/doc/widget3d.rst @@ -0,0 +1,9 @@ +Matplotlib Widget 3D Example +============================ + +A Python application that demonstrates how to combine matplotlib +with Qt Widget-based functionality. + +.. image:: widget3d.png + :width: 400 + :alt: Matplotlib Widget 3D Screenshot diff --git a/examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.png b/examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.png new file mode 100644 index 000000000..e9fe16354 Binary files /dev/null and b/examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.png differ diff --git a/examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.rst b/examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.rst new file mode 100644 index 000000000..467fb42c2 --- /dev/null +++ b/examples/external/matplotlib/widget_gaussian/doc/widget_gaussian.rst @@ -0,0 +1,9 @@ +Matplotlib Widget Gaussian Example +================================== + +A Python application that demonstrates how to interact with +matplotlib and scipy, combined with Qt Widgets. + +.. image:: widget_gaussian.png + :width: 400 + :alt: Matplotlib Widget Gaussian Screenshot diff --git a/examples/external/opencv/doc/opencv.png b/examples/external/opencv/doc/opencv.png new file mode 100644 index 000000000..e3edcab47 Binary files /dev/null and b/examples/external/opencv/doc/opencv.png differ diff --git a/examples/external/opencv/doc/opencv.rst b/examples/external/opencv/doc/opencv.rst new file mode 100644 index 000000000..ff2c72501 --- /dev/null +++ b/examples/external/opencv/doc/opencv.rst @@ -0,0 +1,9 @@ +OpenCV Face Detection Example +============================= + +A Python application that demonstrates how to use OpenCV +and a trained model to detect faces detected from a webcam. + +.. image:: opencv.png + :width: 400 + :alt: OpenCV Face Detection Screenshot diff --git a/examples/external/opencv/opencv.pyproject b/examples/external/opencv/opencv.pyproject new file mode 100644 index 000000000..dd9a73e24 --- /dev/null +++ b/examples/external/opencv/opencv.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["webcam_pattern_detection.py"] +} diff --git a/examples/external/pandas/doc/pandas.rst b/examples/external/pandas/doc/pandas.rst new file mode 100644 index 000000000..8e75eead4 --- /dev/null +++ b/examples/external/pandas/doc/pandas.rst @@ -0,0 +1,9 @@ +Pandas Simple Example +===================== + +A Python application that demonstrates how to visualize +a Pandas DataFrame. + +.. image:: pandas_simple.png + :width: 400 + :alt: Pandas Simple Screenshot diff --git a/examples/external/pandas/doc/pandas_simple.png b/examples/external/pandas/doc/pandas_simple.png new file mode 100644 index 000000000..ea5d240bd Binary files /dev/null and b/examples/external/pandas/doc/pandas_simple.png differ diff --git a/examples/external/scikit/doc/scikit.png b/examples/external/scikit/doc/scikit.png new file mode 100644 index 000000000..930a1c7c9 Binary files /dev/null and b/examples/external/scikit/doc/scikit.png differ diff --git a/examples/external/scikit/doc/scikit.rst b/examples/external/scikit/doc/scikit.rst new file mode 100644 index 000000000..29ebbddbf --- /dev/null +++ b/examples/external/scikit/doc/scikit.rst @@ -0,0 +1,9 @@ +Scikit Image Example +==================== + +A Python application that demonstrates how to use Scikit Image +to apply filters to images based on a Qt Widgets. + +.. image:: scikit.png + :width: 400 + :alt: Scikit Image Screenshot diff --git a/examples/external/scikit/scikit.pyproject b/examples/external/scikit/scikit.pyproject new file mode 100644 index 000000000..5026c86e3 --- /dev/null +++ b/examples/external/scikit/scikit.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["staining_colors_separation.py"] +} diff --git a/examples/opengl/contextinfo/contextinfo.py b/examples/opengl/contextinfo/contextinfo.py index 47fd83abc..73b55df13 100644 --- a/examples/opengl/contextinfo/contextinfo.py +++ b/examples/opengl/contextinfo/contextinfo.py @@ -245,12 +245,12 @@ class RenderWindow(QWindow): context_surface_format = print_surface_format(self.context.format()) surface_format = print_surface_format(self.format()) - text = ("Vendor: {gl_vendor}\n" - "Renderer: {gl_renderer}\n" - "Version: {gl_version}\n" - "Shading language: {gl_lang_version}\n" - "Context Format: {context_surface_format}\n\n" - "Surface Format: {surface_format}") + text = (f"Vendor: {gl_vendor}\n" + f"Renderer: {gl_renderer}\n" + f"Version: {gl_version}\n" + f"Shading language: {gl_lang_version}\n" + f"Context Format: {context_surface_format}\n\n" + f"Surface Format: {surface_format}") self.context.doneCurrent() return text diff --git a/examples/opengl/contextinfo/doc/contextinfo.png b/examples/opengl/contextinfo/doc/contextinfo.png new file mode 100644 index 000000000..c7911f162 Binary files /dev/null and b/examples/opengl/contextinfo/doc/contextinfo.png differ diff --git a/examples/opengl/contextinfo/doc/contextinfo.rst b/examples/opengl/contextinfo/doc/contextinfo.rst new file mode 100644 index 000000000..1fa9eb42d --- /dev/null +++ b/examples/opengl/contextinfo/doc/contextinfo.rst @@ -0,0 +1,10 @@ +Context Info Example +==================== + +The example shows the information about the OpenGL-related graphics +configuration of the current system. This can be useful as a +diagnostic tool. + +.. image:: contextinfo.png + :width: 400 + :alt: Context Simple Screenshot diff --git a/examples/opengl/hellogl2/doc/hellogl2.png b/examples/opengl/hellogl2/doc/hellogl2.png new file mode 100644 index 000000000..674ea9fbe Binary files /dev/null and b/examples/opengl/hellogl2/doc/hellogl2.png differ diff --git a/examples/opengl/hellogl2/doc/hellogl2.rst b/examples/opengl/hellogl2/doc/hellogl2.rst new file mode 100644 index 000000000..1223e138c --- /dev/null +++ b/examples/opengl/hellogl2/doc/hellogl2.rst @@ -0,0 +1,9 @@ +Hello GL2 Example +================= + +The Hello GL2 example demonstrates the basic use of the OpenGL-related classes +provided with Qt. + +.. image:: hellogl2.png + :width: 400 + :alt: Hello GL2 Screenshot diff --git a/examples/opengl/hellogl2/hellogl2.py b/examples/opengl/hellogl2/hellogl2.py index 6dfc032ad..2f170dc90 100644 --- a/examples/opengl/hellogl2/hellogl2.py +++ b/examples/opengl/hellogl2/hellogl2.py @@ -232,7 +232,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions): def __init__(self, transparent, parent=None): QOpenGLWidget.__init__(self, parent) - super().__init__() + QOpenGLFunctions.__init__(self) self._transparent = transparent self._core = QSurfaceFormat.defaultFormat().profile() == QSurfaceFormat.CoreProfile diff --git a/examples/opengl/textures/doc/textures.png b/examples/opengl/textures/doc/textures.png new file mode 100644 index 000000000..ff80a7d8f Binary files /dev/null and b/examples/opengl/textures/doc/textures.png differ diff --git a/examples/opengl/textures/doc/textures.rst b/examples/opengl/textures/doc/textures.rst new file mode 100644 index 000000000..80bf20451 --- /dev/null +++ b/examples/opengl/textures/doc/textures.rst @@ -0,0 +1,9 @@ +Texture Example +=============== + +The Textures example demonstrates the use of Qt's image classes as textures in +applications that use both OpenGL and Qt to display graphics. + +.. image:: textures.png + :width: 400 + :alt: Textures Screenshot diff --git a/examples/quick/painteditem/doc/painteditem.png b/examples/quick/painteditem/doc/painteditem.png new file mode 100644 index 000000000..743cd11b5 Binary files /dev/null and b/examples/quick/painteditem/doc/painteditem.png differ diff --git a/examples/quick/painteditem/doc/painteditem.rst b/examples/quick/painteditem/doc/painteditem.rst new file mode 100644 index 000000000..6f12355ca --- /dev/null +++ b/examples/quick/painteditem/doc/painteditem.rst @@ -0,0 +1,11 @@ +Scene Graph Painted Item Example +================================ + +Shows how to implement QPainter-based custom scenegraph items. + +The Painted Item example shows how to use the QML Scene Graph framework to +implement custom scenegraph items using QPainter. + +.. image:: painteditem.png + :width: 400 + :alt: Painted Item Screenshot diff --git a/examples/quickcontrols2/gallery/doc/gallery.png b/examples/quickcontrols2/gallery/doc/gallery.png new file mode 100644 index 000000000..615ea9e3c Binary files /dev/null and b/examples/quickcontrols2/gallery/doc/gallery.png differ diff --git a/examples/sql/books/doc/books.png b/examples/sql/books/doc/books.png new file mode 100644 index 000000000..102395155 Binary files /dev/null and b/examples/sql/books/doc/books.png differ diff --git a/examples/sql/books/doc/books.rst b/examples/sql/books/doc/books.rst new file mode 100644 index 000000000..cb8edc2ac --- /dev/null +++ b/examples/sql/books/doc/books.rst @@ -0,0 +1,11 @@ +SQL Books Example +================= + +Shows how to use Qt SQL classes with a model/view framework. + +The Books example shows how Qt's SQL classes can be used with the model/view +framework to create rich user interfaces for information stored in a database. + +.. image:: books.png + :width: 400 + :alt: SQL Books Screenshot diff --git a/examples/webchannel/standalone/doc/standalone.png b/examples/webchannel/standalone/doc/standalone.png new file mode 100644 index 000000000..972b0fbbf Binary files /dev/null and b/examples/webchannel/standalone/doc/standalone.png differ diff --git a/examples/webchannel/standalone/doc/standalone.rst b/examples/webchannel/standalone/doc/standalone.rst new file mode 100644 index 000000000..f22f32c23 --- /dev/null +++ b/examples/webchannel/standalone/doc/standalone.rst @@ -0,0 +1,8 @@ +WebChannel Standalone Example +============================= + +A simple chat between a server and a remote client running in a browser. + +.. image:: standalone.png + :width: 400 + :alt: WebChannel Standalone Screenshot diff --git a/examples/webenginequick/nanobrowser/doc/nanobrowser.png b/examples/webenginequick/nanobrowser/doc/nanobrowser.png new file mode 100644 index 000000000..3dddb05d9 Binary files /dev/null and b/examples/webenginequick/nanobrowser/doc/nanobrowser.png differ diff --git a/examples/webenginequick/nanobrowser/doc/nanobrowser.rst b/examples/webenginequick/nanobrowser/doc/nanobrowser.rst new file mode 100644 index 000000000..850985072 --- /dev/null +++ b/examples/webenginequick/nanobrowser/doc/nanobrowser.rst @@ -0,0 +1,8 @@ +Nano Browser Example +==================== + +A web browser implemented using the WebEngineView QML type. + +.. image:: nanobrowser.png + :width: 400 + :alt: Nano Browser Screenshot diff --git a/examples/webenginewidgets/simplebrowser/doc/simplebrowser.png b/examples/webenginewidgets/simplebrowser/doc/simplebrowser.png new file mode 100644 index 000000000..3fa5a0046 Binary files /dev/null and b/examples/webenginewidgets/simplebrowser/doc/simplebrowser.png differ diff --git a/examples/webenginewidgets/simplebrowser/doc/simplebrowser.rst b/examples/webenginewidgets/simplebrowser/doc/simplebrowser.rst new file mode 100644 index 000000000..83dd109c5 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/doc/simplebrowser.rst @@ -0,0 +1,8 @@ +Simple Browser Example +====================== + +A simple browser based on Qt WebEngine Widgets. + +.. image:: simplebrowser.png + :width: 400 + :alt: Simple Browser Screenshot diff --git a/examples/widgets/gallery/gallery.pyproject b/examples/widgets/gallery/gallery.pyproject deleted file mode 100644 index 635e123b0..000000000 --- a/examples/widgets/gallery/gallery.pyproject +++ /dev/null @@ -1,3 +0,0 @@ -{ - "files": ["main.py", "widgetgallery.py"] -} diff --git a/examples/widgets/gallery/main.py b/examples/widgets/gallery/main.py deleted file mode 100644 index c3602321b..000000000 --- a/examples/widgets/gallery/main.py +++ /dev/null @@ -1,56 +0,0 @@ -############################################################################# -## -## 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$ -## -############################################################################# - -"""PySide6 port of the widgets/gallery example from Qt v5.15""" - -import sys - -from PySide6.QtCore import QCoreApplication, Qt -from PySide6.QtWidgets import QApplication -from widgetgallery import WidgetGallery - - -if __name__ == '__main__': - QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) - QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) - app = QApplication() - gallery = WidgetGallery() - gallery.show() - sys.exit(app.exec()) diff --git a/examples/widgets/gallery/widgetgallery.py b/examples/widgets/gallery/widgetgallery.py deleted file mode 100644 index f57e23992..000000000 --- a/examples/widgets/gallery/widgetgallery.py +++ /dev/null @@ -1,435 +0,0 @@ -############################################################################# -## -## 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 PySide6.QtWidgets import * -from PySide6.QtGui import (QCursor, QDesktopServices, QGuiApplication, QIcon, - QKeySequence, QShortcut, QStandardItem, - QStandardItemModel, QScreen, QWindow) -from PySide6.QtCore import (QDateTime, QDir, QLibraryInfo, QMetaObject, - QSysInfo, QTextStream, QTimer, Qt, qVersion) - - -POEM = """Twinkle, twinkle, little star, -How I wonder what you are. -Up above the world so high, -Like a diamond in the sky. -Twinkle, twinkle, little star, -How I wonder what you arenot""" - -DIR_OPEN_ICON = ":/qt-project.org/styles/commonstyle/images/diropen-128.png" - -COMPUTER_ICON = ":/qt-project.org/styles/commonstyle/images/computer-32.png" - -SYSTEMINFO = """ -

Python

{}

-

Qt Build

{}

-

Operating System

{}

-

Screens

-{} -""" - - -def class_name(o): - return o.metaObject().className() - - -def help_url(page): - """Build a Qt help URL from the page name""" - major_version = qVersion().split('.')[0] - return f"https://doc.qt.io/qt-{major_version}/{page}.html" - - -def launch_help(widget): - """Launch a widget's help page""" - url = help_url(class_name(widget).lower()) - QDesktopServices.openUrl(url) - - -def launch_module_help(): - QDesktopServices.openUrl(help_url("qtwidgets-index")) - - -def init_widget(w, name): - """Init a widget for the gallery, give it a tooltip showing the - class name""" - w.setObjectName(name) - w.setToolTip(class_name(w)) - - -def style_names(): - """Return a list of styles, default platform style first""" - default_style_name = QApplication.style().objectName().lower() - result = [] - for style in QStyleFactory.keys(): - if style.lower() == default_style_name: - result.insert(0, style) - else: - result.append(style) - return result - - -def embed_into_hbox_layout(w, margin=5): - """Embed a widget into a layout to give it a frame""" - result = QWidget() - layout = QHBoxLayout(result) - layout.setContentsMargins(margin, margin, margin, margin) - layout.addWidget(w) - return result - - -def format_geometry(rect): - """Format a geometry as a X11 geometry specification""" - w = rect.width() - h = rect.height() - x = rect.x() - y = rect.y() - return f"{w}x{h}{x:+d}{y:+d}" - - -def screen_info(widget): - """Format information on the screens""" - policy = QGuiApplication.highDpiScaleFactorRoundingPolicy() - policy_string = str(policy).split('.')[-1] - result = f"

High DPI scale factor rounding policy: {policy_string}

    " - for screen in QGuiApplication.screens(): - current = screen == widget.screen() - result += "
  1. " - if current: - result += "" - name = screen.name() - geometry = format_geometry(screen.geometry()) - dpi = int(screen.logicalDotsPerInchX()) - dpr = screen.devicePixelRatio() - result += f'"{name}" {geometry} {dpi}DPI, DPR={dpr}' - if current: - result += "" - result += "
  2. " - result += "
" - return result - - -class WidgetGallery(QDialog): - """Dialog displaying a gallery of Qt Widgets""" - - def __init__(self): - super().__init__() - - self.setWindowIcon(QIcon(':/qt-project.org/logos/pysidelogo.png')) - self._progress_bar = self.create_progress_bar() - - self._style_combobox = QComboBox() - init_widget(self._style_combobox, "styleComboBox") - self._style_combobox.addItems(style_names()) - - style_label = QLabel("Style:") - init_widget(style_label, "style_label") - style_label.setBuddy(self._style_combobox) - - help_label = QLabel("Press F1 over a widget to see Documentation") - init_widget(help_label, "help_label") - - disable_widgets_checkbox = QCheckBox("Disable widgets") - init_widget(disable_widgets_checkbox, "disable_widgets_checkbox") - - buttons_groupbox = self.create_buttons_groupbox() - itemview_tabwidget = self.create_itemview_tabwidget() - simple_input_widgets_groupbox = self.create_simple_inputwidgets_groupbox() - text_toolbox = self.create_text_toolbox() - - self._style_combobox.textActivated.connect(self.change_style) - disable_widgets_checkbox.toggled.connect(buttons_groupbox.setDisabled) - disable_widgets_checkbox.toggled.connect(text_toolbox.setDisabled) - disable_widgets_checkbox.toggled.connect(itemview_tabwidget.setDisabled) - disable_widgets_checkbox.toggled.connect(simple_input_widgets_groupbox.setDisabled) - - help_shortcut = QShortcut(self) - help_shortcut.setKey(QKeySequence.HelpContents) - help_shortcut.activated.connect(self.help_on_current_widget) - - top_layout = QHBoxLayout() - top_layout.addWidget(style_label) - top_layout.addWidget(self._style_combobox) - top_layout.addStretch(1) - top_layout.addWidget(help_label) - top_layout.addStretch(1) - top_layout.addWidget(disable_widgets_checkbox) - - dialog_buttonbox = QDialogButtonBox(QDialogButtonBox.Help | - QDialogButtonBox.Close) - init_widget(dialog_buttonbox, "dialogButtonBox") - dialog_buttonbox.helpRequested.connect(launch_module_help) - dialog_buttonbox.rejected.connect(self.reject) - - main_layout = QGridLayout(self) - main_layout.addLayout(top_layout, 0, 0, 1, 2) - main_layout.addWidget(buttons_groupbox, 1, 0) - main_layout.addWidget(simple_input_widgets_groupbox, 1, 1) - main_layout.addWidget(itemview_tabwidget, 2, 0) - main_layout.addWidget(text_toolbox, 2, 1) - main_layout.addWidget(self._progress_bar, 3, 0, 1, 2) - main_layout.addWidget(dialog_buttonbox, 4, 0, 1, 2) - - qv = qVersion() - self.setWindowTitle(f"Widget Gallery Qt {qv}") - - def setVisible(self, visible): - super(WidgetGallery, self).setVisible(visible) - if visible: - self.windowHandle().screenChanged.connect(self.update_systeminfo) - self.update_systeminfo() - - def change_style(self, style_name): - QApplication.setStyle(QStyleFactory.create(style_name)) - - def advance_progressbar(self): - cur_val = self._progress_bar.value() - max_val = self._progress_bar.maximum() - self._progress_bar.setValue(cur_val + (max_val - cur_val) / 100) - - def create_buttons_groupbox(self): - result = QGroupBox("Buttons") - init_widget(result, "buttons_groupbox") - - default_pushbutton = QPushButton("Default Push Button") - init_widget(default_pushbutton, "default_pushbutton") - default_pushbutton.setDefault(True) - - toggle_pushbutton = QPushButton("Toggle Push Button") - init_widget(toggle_pushbutton, "toggle_pushbutton") - toggle_pushbutton.setCheckable(True) - toggle_pushbutton.setChecked(True) - - flat_pushbutton = QPushButton("Flat Push Button") - init_widget(flat_pushbutton, "flat_pushbutton") - flat_pushbutton.setFlat(True) - - toolbutton = QToolButton() - init_widget(toolbutton, "toolButton") - toolbutton.setText("Tool Button") - - menu_toolbutton = QToolButton() - init_widget(menu_toolbutton, "menuButton") - menu_toolbutton.setText("Menu Button") - tool_menu = QMenu(menu_toolbutton) - menu_toolbutton.setPopupMode(QToolButton.InstantPopup) - tool_menu.addAction("Option") - tool_menu.addSeparator() - action = tool_menu.addAction("Checkable Option") - action.setCheckable(True) - menu_toolbutton.setMenu(tool_menu) - tool_layout = QHBoxLayout() - tool_layout.addWidget(toolbutton) - tool_layout.addWidget(menu_toolbutton) - - commandlinkbutton = QCommandLinkButton("Command Link Button") - init_widget(commandlinkbutton, "commandLinkButton") - commandlinkbutton.setDescription("Description") - - button_layout = QVBoxLayout() - button_layout.addWidget(default_pushbutton) - button_layout.addWidget(toggle_pushbutton) - button_layout.addWidget(flat_pushbutton) - button_layout.addLayout(tool_layout) - button_layout.addWidget(commandlinkbutton) - button_layout.addStretch(1) - - radiobutton_1 = QRadioButton("Radio button 1") - init_widget(radiobutton_1, "radioButton1") - radiobutton_2 = QRadioButton("Radio button 2") - init_widget(radiobutton_2, "radioButton2") - radiobutton_3 = QRadioButton("Radio button 3") - init_widget(radiobutton_3, "radioButton3") - radiobutton_1.setChecked(True) - - checkbox = QCheckBox("Tri-state check box") - init_widget(checkbox, "checkBox") - checkbox.setTristate(True) - checkbox.setCheckState(Qt.PartiallyChecked) - - checkable_layout = QVBoxLayout() - checkable_layout.addWidget(radiobutton_1) - checkable_layout.addWidget(radiobutton_2) - checkable_layout.addWidget(radiobutton_3) - checkable_layout.addWidget(checkbox) - checkable_layout.addStretch(1) - - main_layout = QHBoxLayout(result) - main_layout.addLayout(button_layout) - main_layout.addLayout(checkable_layout) - main_layout.addStretch() - return result - - def create_text_toolbox(self): - result = QToolBox() - init_widget(result, "toolBox") - - # Create centered/italic HTML rich text - rich_text = "" - for line in POEM.split('\n'): - rich_text += f"
{line}
" - rich_text += "
" - - text_edit = QTextEdit(rich_text) - init_widget(text_edit, "textEdit") - plain_textedit = QPlainTextEdit(POEM) - init_widget(plain_textedit, "plainTextEdit") - - self._systeminfo_textbrowser = QTextBrowser() - init_widget(self._systeminfo_textbrowser, "systemInfoTextBrowser") - - result.addItem(embed_into_hbox_layout(text_edit), "Text Edit") - result.addItem(embed_into_hbox_layout(plain_textedit), - "Plain Text Edit") - result.addItem(embed_into_hbox_layout(self._systeminfo_textbrowser), - "Text Browser") - return result - - def create_itemview_tabwidget(self): - result = QTabWidget() - init_widget(result, "bottomLeftTabWidget") - result.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored) - - tree_view = QTreeView() - init_widget(tree_view, "treeView") - filesystem_model = QFileSystemModel(tree_view) - filesystem_model.setRootPath(QDir.rootPath()) - tree_view.setModel(filesystem_model) - - table_widget = QTableWidget() - init_widget(table_widget, "tableWidget") - table_widget.setRowCount(10) - table_widget.setColumnCount(10) - - list_model = QStandardItemModel(0, 1, result) - - list_model.appendRow(QStandardItem(QIcon(DIR_OPEN_ICON), "Directory")) - list_model.appendRow(QStandardItem(QIcon(COMPUTER_ICON), "Computer")) - - list_view = QListView() - init_widget(list_view, "listView") - list_view.setModel(list_model) - - icon_mode_listview = QListView() - init_widget(icon_mode_listview, "iconModeListView") - - icon_mode_listview.setViewMode(QListView.IconMode) - icon_mode_listview.setModel(list_model) - - result.addTab(embed_into_hbox_layout(tree_view), "Tree View") - result.addTab(embed_into_hbox_layout(table_widget), "Table") - result.addTab(embed_into_hbox_layout(list_view), "List") - result.addTab(embed_into_hbox_layout(icon_mode_listview), - "Icon Mode List") - return result - - def create_simple_inputwidgets_groupbox(self): - result = QGroupBox("Simple Input Widgets") - init_widget(result, "bottomRightGroupBox") - result.setCheckable(True) - result.setChecked(True) - - lineedit = QLineEdit("s3cRe7") - init_widget(lineedit, "lineEdit") - lineedit.setClearButtonEnabled(True) - lineedit.setEchoMode(QLineEdit.Password) - - spin_box = QSpinBox() - init_widget(spin_box, "spinBox") - spin_box.setValue(50) - - date_timeedit = QDateTimeEdit() - init_widget(date_timeedit, "dateTimeEdit") - date_timeedit.setDateTime(QDateTime.currentDateTime()) - - slider = QSlider() - init_widget(slider, "slider") - slider.setOrientation(Qt.Horizontal) - slider.setValue(40) - - scrollbar = QScrollBar() - init_widget(scrollbar, "scrollBar") - scrollbar.setOrientation(Qt.Horizontal) - scrollbar.setValue(60) - - dial = QDial() - init_widget(dial, "dial") - dial.setValue(30) - dial.setNotchesVisible(True) - - layout = QGridLayout(result) - layout.addWidget(lineedit, 0, 0, 1, 2) - layout.addWidget(spin_box, 1, 0, 1, 2) - layout.addWidget(date_timeedit, 2, 0, 1, 2) - layout.addWidget(slider, 3, 0) - layout.addWidget(scrollbar, 4, 0) - layout.addWidget(dial, 3, 1, 2, 1) - layout.setRowStretch(5, 1) - return result - - def create_progress_bar(self): - result = QProgressBar() - init_widget(result, "progressBar") - result.setRange(0, 10000) - result.setValue(0) - - timer = QTimer(self) - timer.timeout.connect(self.advance_progressbar) - timer.start(1000) - return result - - def update_systeminfo(self): - """Display system information""" - system_info = SYSTEMINFO.format(sys.version, - QLibraryInfo.build(), - QSysInfo.prettyProductName(), - screen_info(self)) - self._systeminfo_textbrowser.setHtml(system_info) - - def help_on_current_widget(self): - """Display help on widget under mouse""" - w = QApplication.widgetAt(QCursor.pos(self.screen())) - while w: # Skip over internal widgets - name = w.objectName() - if name and not name.startswith("qt_"): - launch_help(w) - break - w = w.parentWidget() diff --git a/examples/widgets/widgetsgallery/doc/widgetsgallery.png b/examples/widgets/widgetsgallery/doc/widgetsgallery.png new file mode 100644 index 000000000..236296681 Binary files /dev/null and b/examples/widgets/widgetsgallery/doc/widgetsgallery.png differ diff --git a/examples/widgets/widgetsgallery/doc/widgetsgallery.rst b/examples/widgets/widgetsgallery/doc/widgetsgallery.rst new file mode 100644 index 000000000..336eb7e46 --- /dev/null +++ b/examples/widgets/widgetsgallery/doc/widgetsgallery.rst @@ -0,0 +1,16 @@ +Widgets Gallery Example +======================= + +Qt's support for widget styles and themes enables your application to fit in +with the native desktop environment. + +The widgets examples show how some of the widgets available in Qt might appear +when configured to use the a particular style. Each style is only available on +the respective platfom, and provides native look and feel by integrating to the +platform theme. Thus, the final appearance varies depending on the active +theme. + + +.. image:: widgetsgallery.png + :width: 400 + :alt: Widgets Gallery Screenshot diff --git a/examples/widgets/widgetsgallery/main.py b/examples/widgets/widgetsgallery/main.py new file mode 100644 index 000000000..c3602321b --- /dev/null +++ b/examples/widgets/widgetsgallery/main.py @@ -0,0 +1,56 @@ +############################################################################# +## +## 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$ +## +############################################################################# + +"""PySide6 port of the widgets/gallery example from Qt v5.15""" + +import sys + +from PySide6.QtCore import QCoreApplication, Qt +from PySide6.QtWidgets import QApplication +from widgetgallery import WidgetGallery + + +if __name__ == '__main__': + QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) + QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) + app = QApplication() + gallery = WidgetGallery() + gallery.show() + sys.exit(app.exec()) diff --git a/examples/widgets/widgetsgallery/widgetgallery.py b/examples/widgets/widgetsgallery/widgetgallery.py new file mode 100644 index 000000000..f57e23992 --- /dev/null +++ b/examples/widgets/widgetsgallery/widgetgallery.py @@ -0,0 +1,435 @@ +############################################################################# +## +## 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 PySide6.QtWidgets import * +from PySide6.QtGui import (QCursor, QDesktopServices, QGuiApplication, QIcon, + QKeySequence, QShortcut, QStandardItem, + QStandardItemModel, QScreen, QWindow) +from PySide6.QtCore import (QDateTime, QDir, QLibraryInfo, QMetaObject, + QSysInfo, QTextStream, QTimer, Qt, qVersion) + + +POEM = """Twinkle, twinkle, little star, +How I wonder what you are. +Up above the world so high, +Like a diamond in the sky. +Twinkle, twinkle, little star, +How I wonder what you arenot""" + +DIR_OPEN_ICON = ":/qt-project.org/styles/commonstyle/images/diropen-128.png" + +COMPUTER_ICON = ":/qt-project.org/styles/commonstyle/images/computer-32.png" + +SYSTEMINFO = """ +

Python

{}

+

Qt Build

{}

+

Operating System

{}

+

Screens

+{} +""" + + +def class_name(o): + return o.metaObject().className() + + +def help_url(page): + """Build a Qt help URL from the page name""" + major_version = qVersion().split('.')[0] + return f"https://doc.qt.io/qt-{major_version}/{page}.html" + + +def launch_help(widget): + """Launch a widget's help page""" + url = help_url(class_name(widget).lower()) + QDesktopServices.openUrl(url) + + +def launch_module_help(): + QDesktopServices.openUrl(help_url("qtwidgets-index")) + + +def init_widget(w, name): + """Init a widget for the gallery, give it a tooltip showing the + class name""" + w.setObjectName(name) + w.setToolTip(class_name(w)) + + +def style_names(): + """Return a list of styles, default platform style first""" + default_style_name = QApplication.style().objectName().lower() + result = [] + for style in QStyleFactory.keys(): + if style.lower() == default_style_name: + result.insert(0, style) + else: + result.append(style) + return result + + +def embed_into_hbox_layout(w, margin=5): + """Embed a widget into a layout to give it a frame""" + result = QWidget() + layout = QHBoxLayout(result) + layout.setContentsMargins(margin, margin, margin, margin) + layout.addWidget(w) + return result + + +def format_geometry(rect): + """Format a geometry as a X11 geometry specification""" + w = rect.width() + h = rect.height() + x = rect.x() + y = rect.y() + return f"{w}x{h}{x:+d}{y:+d}" + + +def screen_info(widget): + """Format information on the screens""" + policy = QGuiApplication.highDpiScaleFactorRoundingPolicy() + policy_string = str(policy).split('.')[-1] + result = f"

High DPI scale factor rounding policy: {policy_string}

    " + for screen in QGuiApplication.screens(): + current = screen == widget.screen() + result += "
  1. " + if current: + result += "" + name = screen.name() + geometry = format_geometry(screen.geometry()) + dpi = int(screen.logicalDotsPerInchX()) + dpr = screen.devicePixelRatio() + result += f'"{name}" {geometry} {dpi}DPI, DPR={dpr}' + if current: + result += "" + result += "
  2. " + result += "
" + return result + + +class WidgetGallery(QDialog): + """Dialog displaying a gallery of Qt Widgets""" + + def __init__(self): + super().__init__() + + self.setWindowIcon(QIcon(':/qt-project.org/logos/pysidelogo.png')) + self._progress_bar = self.create_progress_bar() + + self._style_combobox = QComboBox() + init_widget(self._style_combobox, "styleComboBox") + self._style_combobox.addItems(style_names()) + + style_label = QLabel("Style:") + init_widget(style_label, "style_label") + style_label.setBuddy(self._style_combobox) + + help_label = QLabel("Press F1 over a widget to see Documentation") + init_widget(help_label, "help_label") + + disable_widgets_checkbox = QCheckBox("Disable widgets") + init_widget(disable_widgets_checkbox, "disable_widgets_checkbox") + + buttons_groupbox = self.create_buttons_groupbox() + itemview_tabwidget = self.create_itemview_tabwidget() + simple_input_widgets_groupbox = self.create_simple_inputwidgets_groupbox() + text_toolbox = self.create_text_toolbox() + + self._style_combobox.textActivated.connect(self.change_style) + disable_widgets_checkbox.toggled.connect(buttons_groupbox.setDisabled) + disable_widgets_checkbox.toggled.connect(text_toolbox.setDisabled) + disable_widgets_checkbox.toggled.connect(itemview_tabwidget.setDisabled) + disable_widgets_checkbox.toggled.connect(simple_input_widgets_groupbox.setDisabled) + + help_shortcut = QShortcut(self) + help_shortcut.setKey(QKeySequence.HelpContents) + help_shortcut.activated.connect(self.help_on_current_widget) + + top_layout = QHBoxLayout() + top_layout.addWidget(style_label) + top_layout.addWidget(self._style_combobox) + top_layout.addStretch(1) + top_layout.addWidget(help_label) + top_layout.addStretch(1) + top_layout.addWidget(disable_widgets_checkbox) + + dialog_buttonbox = QDialogButtonBox(QDialogButtonBox.Help | + QDialogButtonBox.Close) + init_widget(dialog_buttonbox, "dialogButtonBox") + dialog_buttonbox.helpRequested.connect(launch_module_help) + dialog_buttonbox.rejected.connect(self.reject) + + main_layout = QGridLayout(self) + main_layout.addLayout(top_layout, 0, 0, 1, 2) + main_layout.addWidget(buttons_groupbox, 1, 0) + main_layout.addWidget(simple_input_widgets_groupbox, 1, 1) + main_layout.addWidget(itemview_tabwidget, 2, 0) + main_layout.addWidget(text_toolbox, 2, 1) + main_layout.addWidget(self._progress_bar, 3, 0, 1, 2) + main_layout.addWidget(dialog_buttonbox, 4, 0, 1, 2) + + qv = qVersion() + self.setWindowTitle(f"Widget Gallery Qt {qv}") + + def setVisible(self, visible): + super(WidgetGallery, self).setVisible(visible) + if visible: + self.windowHandle().screenChanged.connect(self.update_systeminfo) + self.update_systeminfo() + + def change_style(self, style_name): + QApplication.setStyle(QStyleFactory.create(style_name)) + + def advance_progressbar(self): + cur_val = self._progress_bar.value() + max_val = self._progress_bar.maximum() + self._progress_bar.setValue(cur_val + (max_val - cur_val) / 100) + + def create_buttons_groupbox(self): + result = QGroupBox("Buttons") + init_widget(result, "buttons_groupbox") + + default_pushbutton = QPushButton("Default Push Button") + init_widget(default_pushbutton, "default_pushbutton") + default_pushbutton.setDefault(True) + + toggle_pushbutton = QPushButton("Toggle Push Button") + init_widget(toggle_pushbutton, "toggle_pushbutton") + toggle_pushbutton.setCheckable(True) + toggle_pushbutton.setChecked(True) + + flat_pushbutton = QPushButton("Flat Push Button") + init_widget(flat_pushbutton, "flat_pushbutton") + flat_pushbutton.setFlat(True) + + toolbutton = QToolButton() + init_widget(toolbutton, "toolButton") + toolbutton.setText("Tool Button") + + menu_toolbutton = QToolButton() + init_widget(menu_toolbutton, "menuButton") + menu_toolbutton.setText("Menu Button") + tool_menu = QMenu(menu_toolbutton) + menu_toolbutton.setPopupMode(QToolButton.InstantPopup) + tool_menu.addAction("Option") + tool_menu.addSeparator() + action = tool_menu.addAction("Checkable Option") + action.setCheckable(True) + menu_toolbutton.setMenu(tool_menu) + tool_layout = QHBoxLayout() + tool_layout.addWidget(toolbutton) + tool_layout.addWidget(menu_toolbutton) + + commandlinkbutton = QCommandLinkButton("Command Link Button") + init_widget(commandlinkbutton, "commandLinkButton") + commandlinkbutton.setDescription("Description") + + button_layout = QVBoxLayout() + button_layout.addWidget(default_pushbutton) + button_layout.addWidget(toggle_pushbutton) + button_layout.addWidget(flat_pushbutton) + button_layout.addLayout(tool_layout) + button_layout.addWidget(commandlinkbutton) + button_layout.addStretch(1) + + radiobutton_1 = QRadioButton("Radio button 1") + init_widget(radiobutton_1, "radioButton1") + radiobutton_2 = QRadioButton("Radio button 2") + init_widget(radiobutton_2, "radioButton2") + radiobutton_3 = QRadioButton("Radio button 3") + init_widget(radiobutton_3, "radioButton3") + radiobutton_1.setChecked(True) + + checkbox = QCheckBox("Tri-state check box") + init_widget(checkbox, "checkBox") + checkbox.setTristate(True) + checkbox.setCheckState(Qt.PartiallyChecked) + + checkable_layout = QVBoxLayout() + checkable_layout.addWidget(radiobutton_1) + checkable_layout.addWidget(radiobutton_2) + checkable_layout.addWidget(radiobutton_3) + checkable_layout.addWidget(checkbox) + checkable_layout.addStretch(1) + + main_layout = QHBoxLayout(result) + main_layout.addLayout(button_layout) + main_layout.addLayout(checkable_layout) + main_layout.addStretch() + return result + + def create_text_toolbox(self): + result = QToolBox() + init_widget(result, "toolBox") + + # Create centered/italic HTML rich text + rich_text = "" + for line in POEM.split('\n'): + rich_text += f"
{line}
" + rich_text += "
" + + text_edit = QTextEdit(rich_text) + init_widget(text_edit, "textEdit") + plain_textedit = QPlainTextEdit(POEM) + init_widget(plain_textedit, "plainTextEdit") + + self._systeminfo_textbrowser = QTextBrowser() + init_widget(self._systeminfo_textbrowser, "systemInfoTextBrowser") + + result.addItem(embed_into_hbox_layout(text_edit), "Text Edit") + result.addItem(embed_into_hbox_layout(plain_textedit), + "Plain Text Edit") + result.addItem(embed_into_hbox_layout(self._systeminfo_textbrowser), + "Text Browser") + return result + + def create_itemview_tabwidget(self): + result = QTabWidget() + init_widget(result, "bottomLeftTabWidget") + result.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored) + + tree_view = QTreeView() + init_widget(tree_view, "treeView") + filesystem_model = QFileSystemModel(tree_view) + filesystem_model.setRootPath(QDir.rootPath()) + tree_view.setModel(filesystem_model) + + table_widget = QTableWidget() + init_widget(table_widget, "tableWidget") + table_widget.setRowCount(10) + table_widget.setColumnCount(10) + + list_model = QStandardItemModel(0, 1, result) + + list_model.appendRow(QStandardItem(QIcon(DIR_OPEN_ICON), "Directory")) + list_model.appendRow(QStandardItem(QIcon(COMPUTER_ICON), "Computer")) + + list_view = QListView() + init_widget(list_view, "listView") + list_view.setModel(list_model) + + icon_mode_listview = QListView() + init_widget(icon_mode_listview, "iconModeListView") + + icon_mode_listview.setViewMode(QListView.IconMode) + icon_mode_listview.setModel(list_model) + + result.addTab(embed_into_hbox_layout(tree_view), "Tree View") + result.addTab(embed_into_hbox_layout(table_widget), "Table") + result.addTab(embed_into_hbox_layout(list_view), "List") + result.addTab(embed_into_hbox_layout(icon_mode_listview), + "Icon Mode List") + return result + + def create_simple_inputwidgets_groupbox(self): + result = QGroupBox("Simple Input Widgets") + init_widget(result, "bottomRightGroupBox") + result.setCheckable(True) + result.setChecked(True) + + lineedit = QLineEdit("s3cRe7") + init_widget(lineedit, "lineEdit") + lineedit.setClearButtonEnabled(True) + lineedit.setEchoMode(QLineEdit.Password) + + spin_box = QSpinBox() + init_widget(spin_box, "spinBox") + spin_box.setValue(50) + + date_timeedit = QDateTimeEdit() + init_widget(date_timeedit, "dateTimeEdit") + date_timeedit.setDateTime(QDateTime.currentDateTime()) + + slider = QSlider() + init_widget(slider, "slider") + slider.setOrientation(Qt.Horizontal) + slider.setValue(40) + + scrollbar = QScrollBar() + init_widget(scrollbar, "scrollBar") + scrollbar.setOrientation(Qt.Horizontal) + scrollbar.setValue(60) + + dial = QDial() + init_widget(dial, "dial") + dial.setValue(30) + dial.setNotchesVisible(True) + + layout = QGridLayout(result) + layout.addWidget(lineedit, 0, 0, 1, 2) + layout.addWidget(spin_box, 1, 0, 1, 2) + layout.addWidget(date_timeedit, 2, 0, 1, 2) + layout.addWidget(slider, 3, 0) + layout.addWidget(scrollbar, 4, 0) + layout.addWidget(dial, 3, 1, 2, 1) + layout.setRowStretch(5, 1) + return result + + def create_progress_bar(self): + result = QProgressBar() + init_widget(result, "progressBar") + result.setRange(0, 10000) + result.setValue(0) + + timer = QTimer(self) + timer.timeout.connect(self.advance_progressbar) + timer.start(1000) + return result + + def update_systeminfo(self): + """Display system information""" + system_info = SYSTEMINFO.format(sys.version, + QLibraryInfo.build(), + QSysInfo.prettyProductName(), + screen_info(self)) + self._systeminfo_textbrowser.setHtml(system_info) + + def help_on_current_widget(self): + """Display help on widget under mouse""" + w = QApplication.widgetAt(QCursor.pos(self.screen())) + while w: # Skip over internal widgets + name = w.objectName() + if name and not name.startswith("qt_"): + launch_help(w) + break + w = w.parentWidget() diff --git a/examples/widgets/widgetsgallery/widgetsgallery.pyproject b/examples/widgets/widgetsgallery/widgetsgallery.pyproject new file mode 100644 index 000000000..635e123b0 --- /dev/null +++ b/examples/widgets/widgetsgallery/widgetsgallery.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "widgetgallery.py"] +} diff --git a/examples/xml/dombookmarks/doc/dombookmarks.png b/examples/xml/dombookmarks/doc/dombookmarks.png new file mode 100644 index 000000000..6a500238a Binary files /dev/null and b/examples/xml/dombookmarks/doc/dombookmarks.png differ diff --git a/examples/xml/dombookmarks/doc/dombookmarks.rst b/examples/xml/dombookmarks/doc/dombookmarks.rst new file mode 100644 index 000000000..558cd0fbb --- /dev/null +++ b/examples/xml/dombookmarks/doc/dombookmarks.rst @@ -0,0 +1,12 @@ +DOM Bookmarks Example +===================== + +Provides a reader for XML Bookmark Exchange Language files. + +The DOM Bookmarks example provides a reader for XML Bookmark Exchange Language +(XBEL) files that uses Qt's DOM-based XML API to read and parse the files. The +SAX Bookmarks example provides an alternative way to read this type of file. + +.. image:: dombookmarks.png + :width: 400 + :alt: DOM Bookmark Screenshot -- cgit v1.2.3