diff options
Diffstat (limited to 'examples/corelib/settingseditor/settingseditor.py')
-rw-r--r-- | examples/corelib/settingseditor/settingseditor.py | 210 |
1 files changed, 92 insertions, 118 deletions
diff --git a/examples/corelib/settingseditor/settingseditor.py b/examples/corelib/settingseditor/settingseditor.py index 9e2a2a2d8..bd5766adb 100644 --- a/examples/corelib/settingseditor/settingseditor.py +++ b/examples/corelib/settingseditor/settingseditor.py @@ -1,59 +1,27 @@ -# -*- 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 +from __future__ import annotations """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: @@ -87,14 +55,14 @@ class TypeChecker: self.size_exp = QRegularExpression(self.point_exp) date_pattern = '([0-9]{,4})-([0-9]{,2})-([0-9]{,2})' - self.date_exp = QRegularExpression('^{}$'.format(date_pattern)) + self.date_exp = QRegularExpression(f'^{date_pattern}$') assert self.date_exp.isValid() time_pattern = '([0-9]{,2}):([0-9]{,2}):([0-9]{,2})' - self.time_exp = QRegularExpression('^{}$'.format(time_pattern)) + self.time_exp = QRegularExpression(f'^{time_pattern}$') assert self.time_exp.isValid() - pattern = '^{}T{}$'.format(date_pattern, time_pattern) + pattern = f'^{date_pattern}T{time_pattern}$' self.dateTime_exp = QRegularExpression(pattern) assert self.dateTime_exp.isValid() @@ -167,7 +135,7 @@ class TypeChecker: class MainWindow(QMainWindow): def __init__(self, parent=None): - super(MainWindow, self).__init__(parent) + super().__init__(parent) self.settings_tree = SettingsTree() self.setCentralWidget(self.settings_tree) @@ -183,11 +151,12 @@ 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) - if self.location_dialog.exec_(): + if self.location_dialog.exec(): settings = QSettings(self.location_dialog.format(), self.location_dialog.scope(), self.location_dialog.organization(), @@ -195,9 +164,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 +179,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 createActions(self): - self.openSettingsAct = QtGui.QAction("&Open Application Settings...", - self, shortcut="Ctrl+O", triggered=self.openSettings) - - self.openIniFileAct = QtGui.QAction("Open I&NI File...", self, - shortcut="Ctrl+N", triggered=self.openIniFile) - - self.openPropertyListAct = 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") @@ -315,12 +279,12 @@ class MainWindow(QMainWindow): if not settings.isWritable(): nice_name += " (read only)" - self.setWindowTitle("{} - Settings Editor".format(nice_name)) + self.setWindowTitle(f"{nice_name} - Settings Editor") class LocationDialog(QDialog): def __init__(self, parent=None): - super(LocationDialog, self).__init__(parent) + super().__init__(parent) self.format_combo = QComboBox() self.format_combo.addItem("Native") @@ -378,17 +342,17 @@ class LocationDialog(QDialog): locations_layout = QVBoxLayout(self.locations_groupbox) locations_layout.addWidget(self.locations_table) - mainLayout = QGridLayout(self) - mainLayout.addWidget(format_label, 0, 0) - mainLayout.addWidget(self.format_combo, 0, 1) - mainLayout.addWidget(scope_label, 1, 0) - mainLayout.addWidget(self.scope_cCombo, 1, 1) - mainLayout.addWidget(organization_label, 2, 0) - mainLayout.addWidget(self.organization_combo, 2, 1) - mainLayout.addWidget(application_label, 3, 0) - mainLayout.addWidget(self.application_combo, 3, 1) - mainLayout.addWidget(self.locations_groupbox, 4, 0, 1, 2) - mainLayout.addWidget(self.button_box, 5, 0, 1, 2) + main_layout = QGridLayout(self) + main_layout.addWidget(format_label, 0, 0) + main_layout.addWidget(self.format_combo, 0, 1) + main_layout.addWidget(scope_label, 1, 0) + main_layout.addWidget(self.scope_cCombo, 1, 1) + main_layout.addWidget(organization_label, 2, 0) + main_layout.addWidget(self.organization_combo, 2, 1) + main_layout.addWidget(application_label, 3, 0) + main_layout.addWidget(self.application_combo, 3, 1) + main_layout.addWidget(self.locations_groupbox, 4, 0, 1, 2) + main_layout.addWidget(self.button_box, 5, 0, 1, 2) self.update_locations() @@ -425,21 +389,21 @@ class LocationDialog(QDialog): if self.scope() == QSettings.SystemScope: continue - actualScope = QSettings.UserScope + actual_scope = QSettings.UserScope else: - actualScope = QSettings.SystemScope + actual_scope = QSettings.SystemScope for j in range(2): if j == 0: if not self.application(): continue - actualApplication = self.application() + actual_application = self.application() else: - actualApplication = '' + actual_application = '' - settings = QSettings(self.format(), actualScope, - self.organization(), actualApplication) + settings = QSettings(self.format(), actual_scope, + self.organization(), actual_application) row = self.locations_table.rowCount() self.locations_table.setRowCount(row + 1) @@ -472,7 +436,7 @@ class LocationDialog(QDialog): class SettingsTree(QTreeWidget): def __init__(self, parent=None): - super(SettingsTree, self).__init__(parent) + super().__init__(parent) self._type_checker = TypeChecker() self.setItemDelegate(VariantDelegate(self._type_checker, self)) @@ -512,6 +476,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 +487,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 +506,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 +529,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: @@ -613,7 +580,7 @@ class SettingsTree(QTreeWidget): if value_type: value = self.settings.value(key, type=value_type) child.setText(1, value.__class__.__name__) - child.setText(2, VariantDelegate.displayText(value)) + child.setText(2, VariantDelegate.display_text(value)) child.setData(2, Qt.UserRole, value) while divider_index < self.child_count(parent): @@ -666,7 +633,7 @@ class SettingsTree(QTreeWidget): class VariantDelegate(QItemDelegate): def __init__(self, type_checker, parent=None): - super(VariantDelegate, self).__init__(parent) + super().__init__(parent) self._type_checker = type_checker def paint(self, painter, option, index): @@ -711,7 +678,7 @@ class VariantDelegate(QItemDelegate): elif isinstance(editor, QSpinBox): editor.setValue(value) else: - editor.setText(self.displayText(value)) + editor.setText(self.display_text(value)) def value_from_lineedit(self, lineedit, model, index): if not lineedit.isModified(): @@ -733,9 +700,9 @@ 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.displayText(value), Qt.DisplayRole) + model.setData(index, self.display_text(value), Qt.DisplayRole) @staticmethod def is_supported_type(value): @@ -744,7 +711,7 @@ class VariantDelegate(QItemDelegate): QSize, list)) @staticmethod - def displayText(value): + def display_text(value): if isinstance(value, str): return value if isinstance(value, bool): @@ -752,23 +719,30 @@ class VariantDelegate(QItemDelegate): if isinstance(value, (int, float, QByteArray)): return str(value) if isinstance(value, QColor): - return '({},{},{},{})'.format(value.red(), value.green(), - value.blue(), value.alpha()) + (r, g, b, a) = (value.red(), value.green(), value.blue(), value.alpha()) + return f'({r},{g},{b},{a})' if isinstance(value, (QDate, QDateTime, QTime)): return value.toString(Qt.ISODate) if isinstance(value, QPoint): - return '({},{})'.format(value.x(), value.y()) + x = value.x() + y = value.y() + return f'({x},{y})' if isinstance(value, QRect): - return '({},{},{},{})'.format(value.x(), value.y(), value.width(), - value.height()) + x = value.x() + y = value.y() + w = value.width() + h = value.height() + return f'({x},{y},{w},{h})' if isinstance(value, QSize): - return '({},{})'.format(value.width(), value.height()) + w = value.width() + 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>' - return '<{}>'.format(value) + return f'<{value}>' if __name__ == '__main__': @@ -777,4 +751,4 @@ if __name__ == '__main__': if len(sys.argv) > 1: main_win.load_ini_file(sys.argv[1]) main_win.show() - sys.exit(app.exec_()) + sys.exit(app.exec()) |