aboutsummaryrefslogtreecommitdiffstats
path: root/examples/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'examples/corelib')
-rw-r--r--examples/corelib/ipc/sharedmemory/dialog.py53
-rw-r--r--examples/corelib/ipc/sharedmemory/main.py51
-rw-r--r--examples/corelib/ipc/sharedmemory/ui_dialog.py4
-rw-r--r--examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.pngbin0 -> 22569 bytes
-rw-r--r--examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.rst10
-rw-r--r--examples/corelib/mimetypesbrowser/mainwindow.py161
-rw-r--r--examples/corelib/mimetypesbrowser/mimetypemodel.py136
-rw-r--r--examples/corelib/mimetypesbrowser/mimetypesbrowser.py24
-rw-r--r--examples/corelib/mimetypesbrowser/mimetypesbrowser.pyproject3
-rw-r--r--examples/corelib/settingseditor/settingseditor.py126
-rw-r--r--examples/corelib/threads/mandelbrot.py163
11 files changed, 450 insertions, 281 deletions
diff --git a/examples/corelib/ipc/sharedmemory/dialog.py b/examples/corelib/ipc/sharedmemory/dialog.py
index 8045330e2..134900047 100644
--- a/examples/corelib/ipc/sharedmemory/dialog.py
+++ b/examples/corelib/ipc/sharedmemory/dialog.py
@@ -1,52 +1,5 @@
-############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the Qt for Python examples of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:BSD$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## BSD License Usage
-## Alternatively, 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$
-##
-############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import os
from pathlib import Path
@@ -137,4 +90,4 @@ class Dialog(QDialog):
def detach(self):
if not self._shared_memory.detach():
- self.ui.label.setText(tr("Unable to detach from shared memory."))
+ self.ui.label.setText(self.tr("Unable to detach from shared memory.")) # noqa: F821
diff --git a/examples/corelib/ipc/sharedmemory/main.py b/examples/corelib/ipc/sharedmemory/main.py
index 13e8f9dff..e497c8de6 100644
--- a/examples/corelib/ipc/sharedmemory/main.py
+++ b/examples/corelib/ipc/sharedmemory/main.py
@@ -1,52 +1,5 @@
-############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the Qt for Python examples of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:BSD$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## BSD License Usage
-## Alternatively, 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$
-##
-############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""PySide6 port of the ipc/sharedmemory example from Qt v6.x"""
diff --git a/examples/corelib/ipc/sharedmemory/ui_dialog.py b/examples/corelib/ipc/sharedmemory/ui_dialog.py
index 891c7b847..2cd544f40 100644
--- a/examples/corelib/ipc/sharedmemory/ui_dialog.py
+++ b/examples/corelib/ipc/sharedmemory/ui_dialog.py
@@ -3,7 +3,7 @@
################################################################################
## Form generated from reading UI file 'dialog.ui'
##
-## Created by: Qt User Interface Compiler version 6.2.0
+## Created by: Qt User Interface Compiler version 6.7.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
@@ -16,7 +16,7 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout, QLabel,
- QPushButton, QSizePolicy)
+ QPushButton, QSizePolicy, QWidget)
class Ui_Dialog(object):
def setupUi(self, Dialog):
diff --git a/examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.png b/examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.png
new file mode 100644
index 000000000..3c4a476b3
--- /dev/null
+++ b/examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.png
Binary files differ
diff --git a/examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.rst b/examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.rst
new file mode 100644
index 000000000..e8e4d1ecd
--- /dev/null
+++ b/examples/corelib/mimetypesbrowser/doc/mimetypesbrowser.rst
@@ -0,0 +1,10 @@
+MIME Type Browser Example
+=========================
+
+A Python application that demonstrates the analogous example in C++
+`MIME Type Browser Example <https://doc.qt.io/qt-6/qtcore-mimetypes-mimetypebrowser-example.html>`_
+
+.. image:: mimetypesbrowser.png
+ :width: 400
+ :alt: mimetypebrowser screenshot
+
diff --git a/examples/corelib/mimetypesbrowser/mainwindow.py b/examples/corelib/mimetypesbrowser/mainwindow.py
new file mode 100644
index 000000000..76404eeb7
--- /dev/null
+++ b/examples/corelib/mimetypesbrowser/mainwindow.py
@@ -0,0 +1,161 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from mimetypemodel import MimeTypeModel
+from PySide6.QtCore import (QDir, QFileInfo, QMimeDatabase, QModelIndex, Qt,
+ Slot)
+from PySide6.QtGui import QAction, QKeySequence
+from PySide6.QtWidgets import (QAbstractItemView, QApplication, QDialog,
+ QFileDialog, QInputDialog, QMainWindow,
+ QMessageBox, QSplitter, QTextEdit, QTreeView,
+ QWidget)
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, parent: QWidget = None) -> None:
+ super().__init__(parent=parent)
+ self.m_find_index: int = 0
+ self.m_model = MimeTypeModel(self)
+ self.m_tree_view = QTreeView(self)
+ self.m_details_text = QTextEdit(self)
+ self.m_find_matches = []
+
+ self.setWindowTitle("Qt Mime Database Browser")
+
+ # create actions
+ self.detect_file_action = QAction(
+ "&Detect File Type...", self, shortcut="Ctrl+O", triggered=self.detect_file
+ )
+ self.exit_action = QAction("E&xit", self, shortcut="Ctrl+Q", triggered=self.close)
+ self.m_find_action = QAction("&Find...", self, shortcut="Ctrl+F", triggered=self.find)
+ self.m_find_next_action = QAction(
+ "Find &Next", self, shortcut="Ctrl+G", triggered=self.find_next
+ )
+ self.m_find_previous_action = QAction(
+ "Find &Previous",
+ self,
+ shortcut="Ctrl+Shift+G",
+ triggered=self.find_previous,
+ )
+ self.about_action = QAction(
+ "About Qt",
+ self,
+ shortcut=QKeySequence(QKeySequence.HelpContents),
+ triggered=QApplication.aboutQt,
+ )
+
+ # add action to menu
+ self.file_menu = self.menuBar().addMenu("&File")
+ self.file_menu.addAction(self.detect_file_action)
+ self.file_menu.addAction(self.exit_action)
+ self.find_menu = self.menuBar().addMenu("&Edit")
+ self.find_menu.addAction(self.m_find_action)
+ self.find_menu.addAction(self.m_find_next_action)
+ self.find_menu.addAction(self.m_find_previous_action)
+ self.about_menu = self.menuBar().addMenu("&About")
+ self.about_menu.addAction(self.about_action)
+
+ self.central_splitter = QSplitter(self)
+ self.setCentralWidget(self.central_splitter)
+
+ self.m_tree_view.setUniformRowHeights(True)
+ self.m_tree_view.setModel(self.m_model)
+
+ self.items = self.m_model.findItems(
+ "application/octet-stream",
+ Qt.MatchContains | Qt.MatchFixedString | Qt.MatchRecursive,
+ )
+
+ if self.items:
+ self.m_tree_view.expand(self.m_model.indexFromItem(self.items[0]))
+
+ self.m_tree_view.selectionModel().currentChanged.connect(self.current_changed)
+ self.central_splitter.addWidget(self.m_tree_view)
+ self.m_details_text.setReadOnly(True)
+ self.central_splitter.addWidget(self.m_details_text)
+
+ self.update_find_actions()
+
+ @Slot()
+ def detect_file(self):
+ file_name = QFileDialog.getOpenFileName(self, "Choose File")
+ if not file_name:
+ return
+
+ mime_database = QMimeDatabase()
+ fi = QFileInfo(file_name[0])
+ mime_type = mime_database.mimeTypeForFile(fi)
+ index = (
+ self.m_model.indexForMimeType(mime_type.name())
+ if mime_type.isValid()
+ else QModelIndex()
+ )
+
+ if index.isValid():
+ self.statusBar().showMessage(f'{fi.fileName()}" is of type "{mime_type.name()}"')
+ self._select_and_goto(index)
+ else:
+ QMessageBox.information(
+ self,
+ "Unknown File Type",
+ f"The type of {QDir.toNativeSeparators(file_name)} could not be determined.",
+ )
+
+ @Slot()
+ def find(self):
+ input_dialog = QInputDialog(self)
+ input_dialog.setWindowTitle("Find")
+ input_dialog.setLabelText("Text")
+ if input_dialog.exec() != QDialog.Accepted:
+ return
+
+ value = input_dialog.textValue().strip()
+ if not value:
+ return
+
+ self.m_find_matches.clear()
+ self.m_find_index = 0
+ items = self.m_model.findItems(
+ value, Qt.MatchContains | Qt.MatchFixedString | Qt.MatchRecursive
+ )
+
+ for item in items:
+ self.m_find_matches.append(self.m_model.indexFromItem(item))
+
+ self.statusBar().showMessage(f'{len(self.m_find_matches)} mime types match "{value}".')
+ self.update_find_actions()
+
+ if self.m_find_matches:
+ self._select_and_goto(self.m_find_matches[0])
+
+ @Slot()
+ def find_next(self):
+ self.m_find_index = self.m_find_index + 1
+ if self.m_find_index >= len(self.m_find_matches):
+ self.m_find_index = 0
+ if self.m_find_index < len(self.m_find_matches):
+ self._select_and_goto(self.m_find_matches[self.m_find_index])
+
+ @Slot()
+ def find_previous(self):
+ self.m_find_index = self.m_find_index - 1
+ if self.m_find_index < 0:
+ self.m_find_index = len(self.m_find_matches) - 1
+ if self.m_find_index >= 0:
+ self._select_and_goto(self.m_find_matches[self.m_find_index])
+
+ @Slot(QModelIndex)
+ def current_changed(self, index: QModelIndex):
+ if index.isValid():
+ self.m_details_text.setText(
+ MimeTypeModel.formatMimeTypeInfo(self.m_model.mimeType(index))
+ )
+
+ def update_find_actions(self):
+ self.find_next_previous_enabled = len(self.m_find_matches) > 1
+ self.m_find_next_action.setEnabled(self.find_next_previous_enabled)
+ self.m_find_previous_action.setEnabled(self.find_next_previous_enabled)
+
+ def _select_and_goto(self, index: QModelIndex):
+ self.m_tree_view.scrollTo(index, QAbstractItemView.PositionAtCenter)
+ self.m_tree_view.setCurrentIndex(index)
diff --git a/examples/corelib/mimetypesbrowser/mimetypemodel.py b/examples/corelib/mimetypesbrowser/mimetypemodel.py
new file mode 100644
index 000000000..5243f110e
--- /dev/null
+++ b/examples/corelib/mimetypesbrowser/mimetypemodel.py
@@ -0,0 +1,136 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from typing import List
+
+from PySide6.QtCore import QMimeDatabase, QMimeType, QModelIndex, QObject, Qt, qWarning
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+
+mimeTypeRole = Qt.UserRole + 1
+iconQueriedRole = Qt.UserRole + 2
+
+
+def createRow(t: QMimeType):
+ name_item = QStandardItem(t.name())
+ flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled
+ name_item.setData(t, mimeTypeRole)
+ name_item.setData(False, iconQueriedRole)
+ name_item.setFlags(flags)
+ name_item.setToolTip(t.comment())
+ return [name_item]
+
+
+class MimeTypeModel(QStandardItemModel):
+ def __init__(self, parent: QObject = None):
+ super().__init__(0, 1, parent)
+ self.setHorizontalHeaderLabels(["Name"])
+ self.m_name_index_hash = {}
+ self.populate()
+
+ def populate(self):
+ mime_database = QMimeDatabase()
+ all_types: List[QMimeType] = mime_database.allMimeTypes()
+
+ # Move top level types to rear end of list, sort this partition,
+ # create top level items and truncate the list.
+ with_parent_mimetypes, without_parent_mimetypes = [], []
+
+ for mime_type in all_types:
+ if mime_type.parentMimeTypes():
+ with_parent_mimetypes.append(mime_type)
+ else:
+ without_parent_mimetypes.append(mime_type)
+
+ without_parent_mimetypes.sort(key=lambda x: x.name())
+
+ for top_level_type in without_parent_mimetypes:
+ row = createRow(top_level_type)
+ self.appendRow(row)
+ self.m_name_index_hash[top_level_type.name()] = self.indexFromItem(row[0])
+
+ all_types = with_parent_mimetypes
+
+ while all_types:
+ # Find a type inheriting one that is already in the model.
+ name_index_value: QModelIndex = None
+ name_index_key = ""
+ for mime_type in all_types:
+ name_index_value = self.m_name_index_hash.get(
+ mime_type.parentMimeTypes()[0]
+ )
+ if name_index_value:
+ name_index_key = mime_type.parentMimeTypes()[0]
+ break
+
+ if not name_index_value:
+ orphaned_mime_types = ", ".join(
+ [mime_type.name() for mime_type in all_types]
+ )
+ qWarning(f"Orphaned mime types: {orphaned_mime_types}")
+ break
+
+ # Move types inheriting the parent type to rear end of list, sort this partition,
+ # append the items to parent and truncate the list.
+ parent_name = name_index_key
+ with_parent_name, without_parent_name = [], []
+
+ for mime_type in all_types:
+ if parent_name in mime_type.parentMimeTypes():
+ with_parent_name.append(mime_type)
+ else:
+ without_parent_name.append(mime_type)
+
+ without_parent_name.sort(key=lambda x: x.name())
+ parent_item = self.itemFromIndex(name_index_value)
+
+ for mime_type in with_parent_name:
+ row = createRow(mime_type)
+ parent_item.appendRow(row)
+ self.m_name_index_hash[mime_type.name()] = self.indexFromItem(row[0])
+
+ all_types = without_parent_name
+
+ def mimeType(self, index: QModelIndex):
+ return index.data(mimeTypeRole)
+
+ def indexForMimeType(self, name):
+ return self.m_name_index_hash[name]
+
+ @staticmethod
+ def formatMimeTypeInfo(t: QMimeType):
+ out = f"<html><head/><body><h3><center>{t.name()}</center></h3><br><table>"
+ aliases_str = ", ".join(t.aliases())
+ if aliases_str:
+ out += f"<tr><td>Aliases:</td><td> ({aliases_str})"
+
+ out += (
+ f"</td></tr><tr><td>Comment:</td><td>{t.comment()}"
+ f"</td></tr><tr><td>Icon name:</td><td>{t.iconName()}</td></tr>"
+ f"<tr><td>Generic icon name</td><td>{t.genericIconName()}</td></tr>"
+ )
+
+ filter_str = t.filterString()
+ if filter_str:
+ out += f"<tr><td>Filter:</td><td>{filter_str}</td></tr>"
+
+ patterns_str = ", ".join(t.globPatterns())
+ if patterns_str:
+ out += f"<tr><td>Glob patterns:</td><td>{patterns_str}</td></tr>"
+
+ parentMimeTypes_str = ", ".join(t.parentMimeTypes())
+ if parentMimeTypes_str:
+ out += f"<tr><td>Parent types:</td><td>{parentMimeTypes_str}</td></tr>"
+
+ suffixes = t.suffixes()
+ if suffixes:
+ out += "<tr><td>Suffixes:</td><td>"
+ preferredSuffix = t.preferredSuffix()
+ if preferredSuffix:
+ suffixes.remove(preferredSuffix)
+ out += f"<b>{preferredSuffix}</b> "
+ suffixes_str = ", ".join(suffixes)
+ out += f"{suffixes_str}</td></tr>"
+
+ out += "</table></body></html>"
+
+ return out
diff --git a/examples/corelib/mimetypesbrowser/mimetypesbrowser.py b/examples/corelib/mimetypesbrowser/mimetypesbrowser.py
new file mode 100644
index 000000000..4742a31b8
--- /dev/null
+++ b/examples/corelib/mimetypesbrowser/mimetypesbrowser.py
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the corelib/mimetypes/mimetypebrowser example from from Qt"""
+
+import argparse
+import sys
+
+from mainwindow import MainWindow
+from PySide6.QtWidgets import QApplication
+
+if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ parser = argparse.ArgumentParser(description="MimeTypesBrowser Example")
+ parser.add_argument("-v", "--version", action="version", version="%(prog)s 1.0")
+ args = parser.parse_args()
+
+ mainWindow = MainWindow()
+ availableGeometry = mainWindow.screen().availableGeometry()
+ mainWindow.resize(availableGeometry.width() / 3, availableGeometry.height() / 2)
+ mainWindow.show()
+
+ sys.exit(app.exec())
diff --git a/examples/corelib/mimetypesbrowser/mimetypesbrowser.pyproject b/examples/corelib/mimetypesbrowser/mimetypesbrowser.pyproject
new file mode 100644
index 000000000..ada4252da
--- /dev/null
+++ b/examples/corelib/mimetypesbrowser/mimetypesbrowser.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["mimetypesbrowser.py"]
+}
diff --git a/examples/corelib/settingseditor/settingseditor.py b/examples/corelib/settingseditor/settingseditor.py
index 2c6a0703b..f87a2f4b5 100644
--- a/examples/corelib/settingseditor/settingseditor.py
+++ b/examples/corelib/settingseditor/settingseditor.py
@@ -1,59 +1,26 @@
-# -*- coding: utf-8 -*-
-
-#############################################################################
-##
-## Copyright (C) 2013 Riverbank Computing Limited.
-## 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$
-##
-#############################################################################
+# Copyright (C) 2013 Riverbank Computing Limited.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""PySide6 port of the widgets/tools/settingseditor example from Qt v5.x"""
import sys
from PySide6.QtCore import (QByteArray, QDate, QDateTime, QDir, QEvent, QPoint,
- QRect, QRegularExpression, QSettings, QSize, QTime, QTimer, Qt)
+ QRect, QRegularExpression, QSettings, QSize, QTime,
+ QTimer, Qt, Slot)
from PySide6.QtGui import (QAction, QColor, QIcon, QIntValidator,
- QDoubleValidator, QRegularExpressionValidator, QValidator)
+ QDoubleValidator, QRegularExpressionValidator,
+ QValidator)
from PySide6.QtWidgets import (QAbstractItemView, QApplication,
- QCheckBox, QComboBox, QFileDialog, QDialog, QDialogButtonBox, QGridLayout,
- QGroupBox, QHeaderView, QInputDialog, QItemDelegate, QLabel, QLineEdit,
- QMainWindow, QMessageBox, QStyle, QSpinBox, QStyleOptionViewItem,
- QTableWidget, QTableWidgetItem, QTreeWidget, QTreeWidgetItem, QVBoxLayout)
+ QCheckBox, QComboBox, QFileDialog, QDialog,
+ QDialogButtonBox, QGridLayout,
+ QGroupBox, QHeaderView, QInputDialog,
+ QItemDelegate, QLabel, QLineEdit,
+ QMainWindow, QMessageBox, QStyle, QSpinBox,
+ QStyleOptionViewItem, QTableWidget,
+ QTableWidgetItem, QTreeWidget, QTreeWidgetItem,
+ QVBoxLayout)
class TypeChecker:
@@ -183,6 +150,7 @@ class MainWindow(QMainWindow):
self.setWindowTitle("Settings Editor")
self.resize(500, 600)
+ @Slot()
def open_settings(self):
if self.location_dialog is None:
self.location_dialog = LocationDialog(self)
@@ -195,9 +163,10 @@ class MainWindow(QMainWindow):
self.set_settings_object(settings)
self.fallbacks_action.setEnabled(True)
+ @Slot()
def open_inifile(self):
file_name, _ = QFileDialog.getOpenFileName(self, "Open INI File",
- '', "INI Files (*.ini *.conf)")
+ '', "INI Files (*.ini *.conf)")
if file_name:
self.load_ini_file(file_name)
@@ -209,77 +178,71 @@ class MainWindow(QMainWindow):
self.set_settings_object(settings)
self.fallbacks_action.setEnabled(False)
+ @Slot()
def open_property_list(self):
file_name, _ = QFileDialog.getOpenFileName(self,
- "Open Property List", '', "Property List Files (*.plist)")
+ "Open Property List", '',
+ "Property List Files (*.plist)")
if file_name:
settings = QSettings(file_name, QSettings.NativeFormat)
self.set_settings_object(settings)
self.fallbacks_action.setEnabled(False)
+ @Slot()
def open_registry_path(self):
path, ok = QInputDialog.getText(self, "Open Registry Path",
- "Enter the path in the Windows registry:",
- QLineEdit.Normal, 'HKEY_CURRENT_USER\\')
+ "Enter the path in the Windows registry:",
+ QLineEdit.Normal, 'HKEY_CURRENT_USER\\')
if ok and path != '':
settings = QSettings(path, QSettings.NativeFormat)
self.set_settings_object(settings)
self.fallbacks_action.setEnabled(False)
+ @Slot()
def about(self):
QMessageBox.about(self, "About Settings Editor",
- "The <b>Settings Editor</b> example shows how to access "
- "application settings using Qt.")
-
- def create_actions(self):
- self._open_settings_act = QtGui.QAction("&Open Application Settings...",
- self, shortcut="Ctrl+O", triggered=self.openSettings)
-
- self._open_ini_file_act = QtGui.QAction("Open I&NI File...", self,
- shortcut="Ctrl+N", triggered=self.openIniFile)
-
- self._open_property_list_act = QtGui.QAction("Open macOS &Property List...",
- self, shortcut="Ctrl+P", triggered=self.openPropertyList)
+ "The <b>Settings Editor</b> example shows how to access "
+ "application settings using Qt.")
def create_actions(self):
self.open_settings_action = QAction("&Open Application Settings...",
- self, shortcut="Ctrl+O", triggered=self.open_settings)
+ self, shortcut="Ctrl+O", triggered=self.open_settings)
self.open_ini_file_action = QAction("Open I&NI File...", self,
- shortcut="Ctrl+N", triggered=self.open_inifile)
+ shortcut="Ctrl+N", triggered=self.open_inifile)
- self.open_property_list_action = QAction("Open macOS &Property List...",
- self, shortcut="Ctrl+P", triggered=self.open_property_list)
+ self.open_property_list_action = QAction("Open macOS &Property List...", self,
+ shortcut="Ctrl+P",
+ triggered=self.open_property_list)
if sys.platform != 'darwin':
self.open_property_list_action.setEnabled(False)
self.open_registry_path_action = QAction(
- "Open Windows &Registry Path...", self, shortcut="Ctrl+G",
- triggered=self.open_registry_path)
+ "Open Windows &Registry Path...", self, shortcut="Ctrl+G",
+ triggered=self.open_registry_path)
if sys.platform != 'win32':
self.open_registry_path_action.setEnabled(False)
self.refresh_action = QAction("&Refresh", self, shortcut="Ctrl+R",
- enabled=False, triggered=self.settings_tree.refresh)
+ enabled=False, triggered=self.settings_tree.refresh)
- self.exit_action = QAction("E&xit", self, shortcut="Ctrl+Q",
- triggered=self.close)
+ self.exit_action = QAction("E&xit", self, shortcut="Ctrl+Q", triggered=self.close)
self.auto_refresh_action = QAction("&Auto-Refresh", self,
- shortcut="Ctrl+A", checkable=True, enabled=False)
+ shortcut="Ctrl+A", checkable=True, enabled=False)
self.auto_refresh_action.triggered[bool].connect(self.settings_tree.set_auto_refresh)
self.auto_refresh_action.triggered[bool].connect(self.refresh_action.setDisabled)
self.fallbacks_action = QAction("&Fallbacks", self,
- shortcut="Ctrl+F", checkable=True, enabled=False)
+ shortcut="Ctrl+F", checkable=True, enabled=False)
self.fallbacks_action.triggered[bool].connect(self.settings_tree.set_fallbacks_enabled)
self.about_action = QAction("&About", self, triggered=self.about)
self.about_Qt_action = QAction("About &Qt", self,
- triggered=qApp.aboutQt)
+ triggered=qApp.aboutQt) # noqa: F821
def create_menus(self):
self.file_menu = self.menuBar().addMenu("&File")
@@ -512,6 +475,7 @@ class SettingsTree(QTreeWidget):
def sizeHint(self):
return QSize(800, 600)
+ @Slot(bool)
def set_auto_refresh(self, autoRefresh):
self.auto_refresh = autoRefresh
@@ -522,15 +486,18 @@ class SettingsTree(QTreeWidget):
else:
self.refresh_timer.stop()
+ @Slot(bool)
def set_fallbacks_enabled(self, enabled):
if self.settings is not None:
self.settings.setFallbacksEnabled(enabled)
self.refresh()
+ @Slot()
def maybe_refresh(self):
if self.state() != QAbstractItemView.EditingState:
self.refresh()
+ @Slot()
def refresh(self):
if self.settings is None:
return
@@ -538,7 +505,7 @@ class SettingsTree(QTreeWidget):
# The signal might not be connected.
try:
self.itemChanged.disconnect(self.update_setting)
- except:
+ except Exception:
pass
self.settings.sync()
@@ -561,7 +528,6 @@ class SettingsTree(QTreeWidget):
key = ancestor.text(0) + '/' + key
ancestor = ancestor.parent()
- d = item.data(2, Qt.UserRole)
self.settings.setValue(key, item.data(2, Qt.UserRole))
if self.auto_refresh:
@@ -733,7 +699,7 @@ class VariantDelegate(QItemDelegate):
value = editor.value()
else:
value = self.value_from_lineedit(editor, model, index)
- if not value is None:
+ if value is not None:
model.setData(index, value, Qt.UserRole)
model.setData(index, self.display_text(value), Qt.DisplayRole)
@@ -771,7 +737,7 @@ class VariantDelegate(QItemDelegate):
h = value.height()
return f'({w},{h})'
if isinstance(value, list):
- return ','.join(value)
+ return ','.join(map(repr, value))
if value is None:
return '<Invalid>'
diff --git a/examples/corelib/threads/mandelbrot.py b/examples/corelib/threads/mandelbrot.py
index c95966119..4689813d4 100644
--- a/examples/corelib/threads/mandelbrot.py
+++ b/examples/corelib/threads/mandelbrot.py
@@ -1,44 +1,6 @@
-
-#############################################################################
-##
-## Copyright (C) 2013 Riverbank Computing Limited.
-## Copyright (C) 2016 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$
-##
-#############################################################################
+# Copyright (C) 2013 Riverbank Computing Limited.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
"""PySide6 port of the corelib/threads/mandelbrot example from Qt v5.x, originating from PyQt"""
@@ -47,7 +9,7 @@ import sys
from PySide6.QtCore import (Signal, QMutex, QElapsedTimer, QMutexLocker,
QPoint, QPointF, QSize, Qt, QThread,
- QWaitCondition)
+ QWaitCondition, Slot)
from PySide6.QtGui import QColor, QImage, QPainter, QPixmap, qRgb
from PySide6.QtWidgets import QApplication, QWidget
@@ -68,7 +30,7 @@ INFO_KEY = 'info'
HELP = ("Use mouse wheel or the '+' and '-' keys to zoom. Press and "
- "hold left mouse button to scroll.")
+ "hold left mouse button to scroll.")
class RenderThread(QThread):
@@ -91,7 +53,8 @@ class RenderThread(QThread):
self.abort = False
for i in range(RenderThread.colormap_size):
- self.colormap.append(self.rgb_from_wave_length(380.0 + (i * 400.0 / RenderThread.colormap_size)))
+ self.colormap.append(
+ self.rgb_from_wave_length(380.0 + (i * 400.0 / RenderThread.colormap_size)))
def stop(self):
self.mutex.lock()
@@ -102,18 +65,17 @@ class RenderThread(QThread):
self.wait(2000)
def render(self, centerX, centerY, scale_factor, resultSize):
- locker = QMutexLocker(self.mutex)
-
- self._center_x = centerX
- self._center_y = centerY
- self._scale_factor = scale_factor
- self._result_size = resultSize
-
- if not self.isRunning():
- self.start(QThread.LowPriority)
- else:
- self.restart = True
- self.condition.wakeOne()
+ with QMutexLocker(self.mutex):
+ self._center_x = centerX
+ self._center_y = centerY
+ self._scale_factor = scale_factor
+ self._result_size = resultSize
+
+ if not self.isRunning():
+ self.start(QThread.LowPriority)
+ else:
+ self.restart = True
+ self.condition.wakeOne()
def run(self):
timer = QElapsedTimer()
@@ -171,7 +133,8 @@ class RenderThread(QThread):
if num_iterations < max_iterations:
image.setPixel(x + half_width, y + half_height,
- self.colormap[num_iterations % RenderThread.colormap_size])
+ self.colormap[
+ num_iterations % RenderThread.colormap_size])
all_black = False
else:
image.setPixel(x + half_width, y + half_height, qRgb(0, 0, 0))
@@ -185,7 +148,8 @@ class RenderThread(QThread):
if elapsed > 2000:
elapsed /= 1000
unit = 's'
- text = f"Pass {curpass+1}/{NUM_PASSES}, max iterations: {max_iterations}, time: {elapsed}{unit}"
+ text = (f"Pass {curpass + 1}/{NUM_PASSES}, "
+ f"max iterations: {max_iterations}, time: {elapsed}{unit}")
image.setText(INFO_KEY, text)
self.rendered_image.emit(image, scale_factor)
curpass += 1
@@ -253,45 +217,45 @@ class MandelbrotWidget(QWidget):
self._info = ''
def paintEvent(self, event):
- painter = QPainter(self)
- painter.fillRect(self.rect(), Qt.black)
-
- if self.pixmap.isNull():
+ with QPainter(self) as painter:
+ painter.fillRect(self.rect(), Qt.black)
+
+ if self.pixmap.isNull():
+ painter.setPen(Qt.white)
+ painter.drawText(self.rect(), Qt.AlignCenter,
+ "Rendering initial image, please wait...")
+ return
+
+ if self._cur_scale == self._pixmap_scale:
+ painter.drawPixmap(self._pixmap_offset, self.pixmap)
+ else:
+ scale_factor = self._pixmap_scale / self._cur_scale
+ new_width = int(self.pixmap.width() * scale_factor)
+ new_height = int(self.pixmap.height() * scale_factor)
+ new_x = self._pixmap_offset.x() + (self.pixmap.width() - new_width) / 2
+ new_y = self._pixmap_offset.y() + (self.pixmap.height() - new_height) / 2
+
+ painter.save()
+ painter.translate(new_x, new_y)
+ painter.scale(scale_factor, scale_factor)
+ exposed, _ = painter.transform().inverted()
+ exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1)
+ painter.drawPixmap(exposed, self.pixmap, exposed)
+ painter.restore()
+
+ text = HELP
+ if self._info:
+ text += ' ' + self._info
+ metrics = painter.fontMetrics()
+ text_width = metrics.horizontalAdvance(text)
+
+ painter.setPen(Qt.NoPen)
+ painter.setBrush(QColor(0, 0, 0, 127))
+ painter.drawRect((self.width() - text_width) / 2 - 5, 0, text_width + 10,
+ metrics.lineSpacing() + 5)
painter.setPen(Qt.white)
- painter.drawText(self.rect(), Qt.AlignCenter,
- "Rendering initial image, please wait...")
- return
-
- if self._cur_scale == self._pixmap_scale:
- painter.drawPixmap(self._pixmap_offset, self.pixmap)
- else:
- scale_factor = self._pixmap_scale / self._cur_scale
- new_width = int(self.pixmap.width() * scale_factor)
- new_height = int(self.pixmap.height() * scale_factor)
- new_x = self._pixmap_offset.x() + (self.pixmap.width() - new_width) / 2
- new_y = self._pixmap_offset.y() + (self.pixmap.height() - new_height) / 2
-
- painter.save()
- painter.translate(new_x, new_y)
- painter.scale(scale_factor, scale_factor)
- exposed, _ = painter.transform().inverted()
- exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1)
- painter.drawPixmap(exposed, self.pixmap, exposed)
- painter.restore()
-
- text = HELP
- if self._info:
- text += ' ' + self._info
- metrics = painter.fontMetrics()
- text_width = metrics.horizontalAdvance(text)
-
- painter.setPen(Qt.NoPen)
- painter.setBrush(QColor(0, 0, 0, 127))
- painter.drawRect((self.width() - text_width) / 2 - 5, 0, text_width + 10,
- metrics.lineSpacing() + 5)
- painter.setPen(Qt.white)
- painter.drawText((self.width() - text_width) / 2,
- metrics.leading() + metrics.ascent(), text)
+ painter.drawText((self.width() - text_width) / 2,
+ metrics.leading() + metrics.ascent(), text)
def resizeEvent(self, event):
self.thread.render(self._center_x, self._center_y, self._cur_scale, self.size())
@@ -340,6 +304,7 @@ class MandelbrotWidget(QWidget):
delta_y = (self.height() - self.pixmap.height()) / 2 - self._pixmap_offset.y()
self.scroll(delta_x, delta_y)
+ @Slot(QImage, float)
def update_pixmap(self, image, scale_factor):
if not self._last_drag_pos.isNull():
return
@@ -354,15 +319,13 @@ class MandelbrotWidget(QWidget):
def zoom(self, zoomFactor):
self._cur_scale *= zoomFactor
self.update()
- self.thread.render(self._center_x, self._center_y, self._cur_scale,
- self.size())
+ self.thread.render(self._center_x, self._center_y, self._cur_scale, self.size())
def scroll(self, deltaX, deltaY):
self._center_x += deltaX * self._cur_scale
self._center_y += deltaY * self._cur_scale
self.update()
- self.thread.render(self._center_x, self._center_y, self._cur_scale,
- self.size())
+ self.thread.render(self._center_x, self._center_y, self._cur_scale, self.size())
if __name__ == '__main__':