ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 05.12.2023
Просмотров: 876
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
Глава 30. Взаимодействие с Windows
741 класса
QRegion
), — если этот параметр отсутствует, будет создана область с размерами по умолчанию. Работает только в Windows Vista и 7;
disableBlurBehindWindow(<Окно>)
— убирает у окна, указанного в параметре
<Окно>
, созданную ранее область размытия.
<Окно>
задается экземпляром класса
QWidget или
QWindow
. Работает только в Windows Vista и 7;
setWindowFlip3DPolicy(<Окно>, <Поведение>)
— задает для окна, указанного в парамет- ре
<Окно>
(экземпляра класса
QWidget или
QWindow
),
<Поведение>
при выводе трехмерного списка открытых окон. В качестве параметра
<Поведение>
может быть указан один из следующих атрибутов класса
QtWinExtras.QtWin
:
•
FlipDefault
—
0
— окно выводится непосредственно в списке окон (поведение по умолчанию);
•
FlipExcludeAbove
—
2
— окно выводится над списком окон, а не в нем;
•
FlipExcludeBelow
—
1
— окно выводится под списком окон, а не в нем.
Работает только в Windows Vista и 7;
windowFlip3DPolicy(<Окно>)
— выводит обозначение поведения окна, указанного в па- раметре
<Окно>
(экземпляра класса
QWidget или
QWindow
), при выводе трехмерного спи- ска окон в виде одного из указанных ранее атрибутов класса
QtWinExtras.QtWin
. Работа- ет только в Windows Vista и 7.
30.5. Получение сведений об операционной системе
Часто бывает необходимо выяснить, на какой операционной системе запущено приложение, и узнать версию этой системы. Для такого случая PyQt предоставляет класс
QSysInfo
, объ- явленный в модуле
QtCore
Этот класс поддерживает ряд статических методов (здесь приведен сокращенный список методов, полный их список можно найти на странице https://doc.qt.io/qt-5/qsysinfo.html):
productType()
— возвращает строковое наименование системы. В случае Windows воз- вращает строку windows
;
productVersion()
— возвращает строку с короткой версией системы:
>>> QtCore.QSysInfo.productVersion()
'10'
prettyProductName()
— возвращает строку с названием и короткой версией системы, заключенной в круглые скобки:
>>> QtCore.QSysInfo.prettyProductName()
'Windows 10 (10.0)'
kernelVersion()
— возвращает строку с полной версией системы:
>>> QtCore.QSysInfo.kernelVersion()
'10.0.16299'
currentCpuArchitecture()
— возвращает строковое обозначение процессорной архитек- туры компьютера, на котором запущено приложение. Могут быть возвращены следую- щие строки (приведен сокращенный список):
742
Часть II. Библиотека PyQt 5
• i386
— 32-разрядный процессор архитектуры x86;
• x86_64
— 64-разрядный процессор архитектуры x86;
• ia64
— процессор Intel Itanium;
• arm
— 32-разрядный процессор архитектуры ARM;
• arm64
— 64-разрядный процессор архитектуры ARM.
Пример:
>>> QtCore.QSysInfo.currentCpuArchitecture()
'x86_64'
machineHostName()
— возвращает сетевое имя компьютера в виде строки.
30.6. Получение путей к системным каталогам
И напоследок выясним, как средствами PyQt получить пути к некоторым системным ката- логам. А сделать это можно, вызвав один из следующих статических методов класса
QDir
, объявленного в модуле
QtCore
:
homePath()
— возвращает строковый путь к каталогу пользовательского профиля:
>>> QtCore.QDir.homePath()
'C:/Users/vlad'
rootPath()
— возвращает строковый путь к корневому каталогу системного диска:
>>> QtCore.QDir.rootPath()
'C:/'
tempPath()
— возвращает строковый путь к каталогу, предназначенному для хранения временных файлов:
>>> QtCore.QDir.tempPath()
'C:/Windows/Temp'
Пути, возвращаемые всеми этими тремя методами, включают в себя в качестве разделите- лей фрагментов прямые слэши. Чтобы преобразовать их в обратные слэши, применяемые в системе Windows, следует воспользоваться статическим методом toNativeSeparators(<Путь>)
того же класса
QDir
:
>>> path = QtCore.QDir.homePath()
>>> path
'C:/Users/vlad'
>>> QtCore.QDir.toNativeSeparators(path)
'C:\\Users\\vlad'
ГЛ А В А
31
Сохранение настроек приложений
Все профессионально выполненные приложения предусматривают возможность настройки их параметров. Эти настройки требуется где-то хранить, чтобы пользователю не пришлось задавать их при каждом запуске приложения. В этом PyQt идет навстречу разработчикам, предоставляя единое хранилище настроек, в качестве которого могут использоваться как реестр Windows (по умолчанию), так и INI-файл.
Для работы с таким хранилищем имеется удобный класс
QSettings
, объявленный в модуле
QtCore
31.1. Создание экземпляра класса QSettings
Рассмотрим все поддерживаемые форматы конструктора класса
QSettings
:
<Объект> = QSettings([parent=None])
<Объект> = QSettings(<Название организации>[, application=""][, parent=None])
<Объект> = QSettings(<Диапазон>, <Название организации>[, application=""][, parent=None])
<Объект> = QSettings(<Тип хранилища>, <Диапазон>,
<Название организации>[, application=""][, parent=None])
<Объект> = QSettings(<Путь к файлу или ключу Реестра>, <Тип хранилища>[, parent=None])
Первый формат — самый простой. Он лишь позволяет указать родителя, присвоив его не- обязательному параметру parent
. При этом настройки будут храниться на уровне текущего пользователя в реестре Windows.
Чтобы настройки успешно сохранились, понадобится задать названия организации и при- ложения, и сделать это нужно еще до создания экземпляра класса
QSettings
. В этом нам помогут следующие два статических метода класса
QCoreApplication из модуля
QtCore
:
setOrganizationName(<Название организации>)
— задает
<Название организации>
;
setApplicationName(<Название приложения>)
— задает
<Название приложения>
Пример:
QtCore.QCoreApplication.setOrganizationName("Прохоренок и Дронов")
QtCore.QCoreApplication.setApplicationName("Тестовое приложение") settings = QtCore.QSettings()
744
Часть II. Библиотека PyQt 5
Второй формат позволяет сразу задать
<Название организации>
— разработчика приложе- ния. В необязательном параметре application можно указать название приложения. На- стройки также будут храниться на уровне текущего пользователя в реестре Windows.
В третьем формате мы можем задать
<Диапазон>
хранения настроек, т. е. указать, будут ли они храниться на уровне текущего пользователя или на уровне системы (относиться ко всем зарегистрированным в системе пользователям).
<Диапазон>
указывается в виде одного из следующих атрибутов класса
QSettings
:
UserScope
—
0
— хранение настроек на уровне текущего пользователя;
SystemScope
—
1
— хранение настроек на уровне системы.
Эти настройки тоже будут храниться в реестре Windows.
Если нам нужно явно задать еще и
<Тип хранилища>
— будет ли это реестр или INI-файл, — мы воспользуемся четвертым форматом конструктора.
<Тип хранилища>
задается в виде од- ного из следующих атрибутов класса
QSettings
:
NativeFormat
—
0
— реестр Windows: его 32-разрядная копия, если приложение работа- ет под управлением 32-разрядной редакции Python, и 64-разрядная — для 64-разрядной редакции языка;
IniFormat
—
1
— INI-файл;
Registry32Format
—
2
— для 64-разрядных приложений — 32-разрядная копия реестра, для 32-разрядных приложений аналогичен атрибуту
NativeFormat
. Поддерживается, на- чиная с PyQt 5.7;
Registry64Format
—
3
— для 32-разрядных приложений, запущенных под 64-разрядной
Windows, — 64-разрядная копия реестра, для 32-разрядных приложений, работающих под 64-разрядной Windows, и 64-разрядных приложений аналогичен
NativeFormat
. Под- держивается, начиная с PyQt 5.7.
Пятый формат позволяет напрямую указать
<Путь к файлу или ключу реестра>
, где хранят- ся настройки (в частности, этот формат пригодится нам в случае, если нужно прочитать какие-либо системные настройки). В качестве параметра
<Тип хранилища>
следует указать один из следующих атрибутов класса
QSettings
:
NativeFormat
—
0
— реестр;
IniFormat
—
1
— INI-файл.
Класс
QSettings поддерживает следующие методы, позволяющие узнать значения парамет- ров, которые были заданы при создании экземпляра:
organizationName()
— возвращает название организации;
applicationName()
— возвращает название приложения;
scope()
— возвращает обозначение диапазона;
format()
— возвращает обозначение формата хранения настроек;
fileName()
— возвращает путь к ключу реестра или INI-файлу с настройками.
Глава 31. Сохранение настроек приложений
745 31.2. Запись и чтение данных
Создав экземпляр класса
QSettings
, мы можем приступить к сохранению настроек или чте- нию их.
31.2.1. Базовые средства записи и чтения данных
Для выполнения простейших операций по записи и чтению данных класс
QSettings предос- тавляет следующие методы:
setValue(<Имя значения>, <Значение>)
— записывает заданное
<Значение>
под указан- ным в виде строки параметром
<Имя значения>
<Значение>
может быть любого типа;
value(<Имя значения>[, defaultValue=None][, type=None])
— считывает значение, ука- занное параметром
<Имя значения>
, и возвращает его в качестве результата. В необяза- тельном параметре defaultValue можно указать значение, которое будет возвращено, если
<Имя значения>
не будет найдено. Если параметр не задан, возвращается значение
None
. В необязательном параметре type можно задать тип, в который должно быть пре- образовано считанное значение. Если он не указан, значение возвращается в своем изна- чальном типе;
remove(<Имя значения>)
— удаляет значение, указанное параметром
<Имя значения>
Если в качестве параметра была передана пустая строка, будут удалены все значения, что находятся в хранилище;
contains(<Имя значения>)
— возвращает
True
, если значение, указанное параметром
<Имя значения>
, существует, и
False
— в противном случае;
childKeys()
— возвращает список имен имеющихся в хранилище значений;
clear()
— удаляет все значения из хранилища;
sync()
— выполняет принудительную запись всех выполненных в хранилище измене- ний в реестр или файл.
В листинге 31.1 приведен код приложения, которое записывает в хранилище настроек (по- скольку формат хранения не задан, в качестве хранилища выступает реестр) число, строку и экземпляр класса
QSize
. Далее оно считывает все сохраненные ранее значения, выводит их на экран и проверяет, присутствует ли в хранилище настроек значение, которое заведомо там не сохранялось. Наконец, оно очищает хранилище.
Листинг 31.1. Использование базовых средств хранения настроек from PyQt5 import QtCore, QtWidgets import sys app = QtWidgets.QApplication(sys.argv) settings = QtCore.QSettings("Прохоренок и Дронов", "Тест 1") v1 = 123 v2 = "Python" v3 = QtCore.QSize(640, 480) print(v1, v2, v3, sep=" | ") print("Сохраняем настройки") settings.setValue("Значение 2", v2) settings.setValue("Значение 3", v3)
1 ... 68 69 70 71 72 73 74 75 ... 83
746
Часть II. Библиотека PyQt 5 settings.sync() print("Считываем настройки") lv1 = settings.value("Значение 1") lv2 = settings.value("Значение 2") lv3 = settings.value("Значение 3") print(lv1, lv2, lv3, sep=" | ") if settings.contains("Значение 4"): print("Значение 4 в хранилище присутствует") else: print("Значение 4 в хранилище отсутствует") print("Очищаем хранилище") settings.clear()
В консоли это приложение выведет:
123 | Python | PyQt5.QtCore.QSize(640, 480)
Сохраняем настройки
Считываем настройки
123 | Python | PyQt5.QtCore.QSize(640, 480)
Значение 4 в хранилище отсутствует
Очищаем хранилище
Теперь давайте прочитаем из реестра путь к системному каталогу Документы, для чего воспользуемся пятым форматом конструктора класса
QSettings
(см. разд. 31.1):
>>> settings = QtCore.QSettings("HKEY_CURRENT_USER\\Software\\
Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
QtCore.QSettings.NativeFormat)
>>> settings.value("Personal")
'D:\\Data\\Документы'
31.2.2. Группировка сохраняемых значений. Ключи
PyQt позволяет нам объединять сохраняемые в хранилище настроек значения по какому- либо признаку в особые группы, называемые ключами. Каждый ключ может содержать произвольное количество значений, а разные ключи могут содержать значения с одинако- выми именами. Для создания ключей можно применить два способа: простой и сложный.
Простой способ заключается в том, что в первом параметре метода setValue()
имя значе- ния предваряется именем ключа, в которое его следует поместить, и отделяется от него прямым слэшем: settings.setValue("Ключ 1/Значение 1", v1) lv1 = settings.value("Ключ 1/Значение 1")
Ключи можно вкладывать внутрь других ключей: settings.setValue("Ключ 2/Вложенный ключ 1/Значение 4", v4) lv4 = settings.value("Ключ 2/ Вложенный ключ 1/Значение 4")
Сложный способ (который на самом деле не так уж и сложен) пригодится, если нам нужно сохранить в одном ключе сразу несколько значений или же прочитать ряд значений из одного и того же ключа. Для его реализации следует выполнить следующие шаги:
Глава 31. Сохранение настроек приложений
747 1. Вызвать метод beginGroup(<Имя или путь ключа>)
класса
QSettings
. В качестве пара- метра методу передается имя ключа, к содержимому которого следует обратиться, или же целый «путь», если нужно создать вложенный ключ: settings.beginGroup("Ключ 1") settings.beginGroup("Ключ 2/Вложенный ключ 1")
2. Выполнить запись или чтение нужных значений с помощью знакомых нам методов setValue()
и value()
. В этом случае значения будут записаны в ключ, указанный в пре- дыдущем вызове метода beginGroup()
, или же прочитаны из этого ключа.
3. Вызвать метод endGroup()
класса
QSettings
Использование методов beginGroup()
и endGroup()
имеет ряд особенностей, о которых нам обязательно следует знать.
Методы remove()
, contains()
и childKeys()
, если их вызовы помещены между вызовами упомянутых ранее методов, действуют только внутри указанного в вызове метода beginGroup()
ключа. Так, метод contains()
будет искать значение с указанным именем только в текущем ключе.
Вызов метода remove()
с передачей ему в качестве параметра пустой строки удалит все значения, сохраненные в текущем ключе, не затрагивая содержимое других ключей и
«корня» хранилища.
Список, возвращаемый методом childKeys()
, будет включать не только имена значений, но и имена всех ключей, вложенных в текущий ключ.
Для проверки существования какого-либо ключа можно использовать метод contains()
, вызвав его в ключе предыдущего уровня или же в «корне» хранилища, если ключ никуда не вложен.
Для удаления ключа можно использовать метод remove()
, который в этом случае вызы- вается точно так же.
При использовании ключей для группировки записываемых в хранилище значений нам мо- гут пригодиться три следующих метода класса
QSettings
:
group()
— возвращает строку с именем или путем текущего ключа;
childGroups()
— возвращает список с именами всех ключей, что имеются в текущем;
allKeys()
— возвращает список полных путей ко всем значениям, что имеются в храни- лище, включая значения, которые сохранены в ключах.
В листинге 31.2 приведен код приложения, чье окно сохраняет свое местоположение при завершении и восстанавливает при запуске. Помимо этого, при нажатии специальной кноп- ки выполняется сохранение текста, занесенного пользователем в поле ввода. Местоположе- ние окна и введенный текст сохраняются в разных группах.
Листинг 31.2. Использование ключей from PyQt5 import QtCore, QtWidgets import sys class MyWindow(QtWidgets.QWidget): def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent, flags=QtCore.Qt.Window)
748
Часть II. Библиотека PyQt 5 self.setWindowTitle("Использование ключей") self.settings = QtCore.QSettings("Прохоренок и Дронов",
"Использование ключей") vbox = QtWidgets.QVBoxLayout() self.txtLine = QtWidgets.QLineEdit(parent=self) vbox.addWidget(self.txtLine) btnSave = QtWidgets.QPushButton("&Сохранить текст") btnSave.clicked.connect(self.saveText) vbox.addWidget(btnSave) self.setLayout(vbox) if self.settings.contains("Окно/Местоположение"): self.setGeometry(self.settings.value("Окно/Местоположение")) else: self.resize(200, 50) if self.settings.contains("Данные/Текст"): self.txtLine.setText(self.settings.value("Данные/Текст")) def closeEvent(self, evt): self.settings.beginGroup("Окно") self.settings.setValue("Местоположение", self.geometry()) self.settings.endGroup() def saveText(self): self.settings.beginGroup("Данные") self.settings.setValue("Текст", self.txtLine.text()) self.settings.endGroup() app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_())
31.2.3. Запись списков
Часто бывает необходимо записать в хранилище настроек список каких-либо значений, а потом прочитать его оттуда. Для таких случаев PyQt также предоставляет весьма удобные инструменты.
Для записи списка в хранилище настроек следует выполнить следующую последователь- ность действий:
1. Вызвать метод beginWriteArray(<Имя или путь ключа>[, size=-1])
класса
QSettings
Первым параметром методу передается
<Имя или путь ключа>
, в котором будут сохране- ны элементы списка. В необязательном параметре size можно указать размер списка — если задать значение
-1
или вообще опустить этот параметр, PyQt определит размер со- храняемого списка самостоятельно.
2. Перебрать в цикле весь сохраняемый список. Внутри цикла выполнить следующие дей- ствия:
• вызвать метод setArrayIndex(<Индекс записываемого элемента>)
класса
QSettings
, тем самым дав PyQt понять, что сейчас будет выполнена запись содержимого эле- мента списка с индексом, заданным в параметре
<Индекс записываемого элемента>
;
Глава 31. Сохранение настроек приложений
749
• собственно, записать значение элемента списка, индекс которого был передан методу setArrayIndex()
на первом шаге.
3. Закончив запись элементов списка, уже по завершении выполнения цикла, в котором выполняется его перебор, вызвать метод endArray()
класса
QSettings
. Это послужит сигналом окончания записи списка.
Прочитать список из хранилища настроек можно точно таким же образом, за единственным исключением. На шаге 1 вместо метода beginWriteArray()
следует вызвать метод beginReadArray(<Имя или путь ключа>)
того же класса
QSettings
. Метод в качестве резуль- тата возвращает размер списка, ранее сохраненный методом beginWriteArray()
. Этот размер понадобится нам для формирования цикла, который будет выполнять выборку элементов списка.
На шаге 2, после вызова метода setArrayIndex()
, можно пользоваться методами remove()
и contains()
для удаления и проверки существования значения соответственно. Эти методы будут действовать только для элемента списка с указанным в вызове метода setArrayIndex()
индексом.
При использовании описанного здесь подхода в хранилище настроек создается следующая структура ключей и значений:
ключ, чье имя (путь) было задано в вызове метода beginWriteArray()
. В этом ключе бу- дут созданы:
• значение size
— хранящее размер записанного списка. Этот размер будет возвращен методом beginReadArray()
;
• ключ, чье имя совпадает с индексом, заданным очередным вызовом метода setArrayIndex()
и увеличенным на единицу.
В этом ключе будут созданы значения, записываемые последующими вызовами метода setValue()
В качестве примера рассмотрим листинг 31.3, в котором приведен код, формирующий спи- сок строк, записывающий его в хранилище настроек, считывающий впоследствии и выво- дящий на экран.
Листинг 31.3. Запись и чтение списков from PyQt5 import QtCore, QtWidgets import sys app = QtWidgets.QApplication(sys.argv) settings = QtCore.QSettings("Прохоренок и Дронов", "Тест 2") l = ["Python", "Ruby", "PHP", "JavaScript"] print(l) print("Сохраняем список") settings.beginWriteArray("Список") for i, el in enumerate(l): settings.setArrayIndex(i) settings.setValue("Элемент", el) settings.endArray() settings.sync() print("Считываем список")