ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов
Скачать 7.92 Mb.
|
# Создаем первые две кнопки button1 = QtWinExtras.QWinThumbnailToolButton(parent=self) button1.setIcon(icon1) button1.setToolTip("Кнопка 1") button1.setDismissOnClick(True) button1.clicked.connect(self.button1Clicked) self.thumbnailToolbar.addButton(button1) button2 = QtWinExtras.QWinThumbnailToolButton(parent=self) button2.setIcon(icon2) button2.setToolTip("Кнопка 2") button2.setDismissOnClick(True) button2.clicked.connect(self.button2Clicked) self.thumbnailToolbar.addButton(button2) # Создаем кнопку, что сформирует свободное пространство # между второй и третьей кнопками button0 = QtWinExtras.QWinThumbnailToolButton(parent=self) button0.setInteractive(False) button0.setFlat(True) self.thumbnailToolbar.addButton(button0) # Создаем третью кнопку button3 = QtWinExtras.QWinThumbnailToolButton(parent=self) button3.setIcon(icon3) button3.setToolTip("Кнопка 3") button3.clicked.connect(self.button3Clicked) self.thumbnailToolbar.addButton(button3) # Создаем надпись, куда будут выводиться сообщения о нажатии # кнопок панели инструментов, и кнопку выхода vbox = QtWidgets.QVBoxLayout() self.lblOutput = QtWidgets.QLabel(parent=self) vbox.addWidget(self.lblOutput) btnClose = QtWidgets.QPushButton("&Выход") Глава 30. Взаимодействие с Windows 739 btnClose.clicked.connect(QtWidgets.qApp.quit) vbox.addWidget(btnClose) self.setLayout(vbox) self.resize(200, 100) # После вывода окна на экран привязываем его к панели инструментов def showEvent(self, evt): self.thumbnailToolbar.setWindow(self.windowHandle()) # Выводим в надпись сообщения о нажатии кнопок def button1Clicked(self): self.lblOutput.setText("Нажата кнопка 1") def button2Clicked(self): self.lblOutput.setText("Нажата кнопка 2") def button3Clicked(self): self.lblOutput.setText("Нажата кнопка 3") app = QtWidgets.QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_()) П РИМЕЧАНИЕ В PyQt также заявлена поддержка вывода произвольного изображения в качестве миниа- тюры, которая появляется при наведении курсора мыши на кнопку панели задач, представ- ляющую приложение, и при переключении между приложениями нажатием комбинации клавиш 30.4. Дополнительные инструменты по управлению окнами Ряд инструментов, позволяющих управлять окнами, реализован в статических методах класса QtWinExtras.QtWin : taskbarDeleteTab(<Окно>) — удаляет из панели задач кнопку, представляющую указан- ное <Окно> , которое задается экземпляром класса QWidget или QWindow : QtWinExtras.QtWin.taskbarDeleteTab(window) taskbarAddTab(<Окно>) — вновь добавляет удаленную ранее из панели задач кнопку, представляющую указанное <Окно> , которое задается экземпляром класса QWidget или QWindow ; taskbarActivateTab(<Окно>) — активизирует на панели задач кнопку, представляющую указанное <Окно> , не активизируя само окно. <Окно> должно быть указано в виде экземп- ляра класса QWidget или QWindow ; 740 Часть II. Библиотека PyQt 5 taskbarActivateTabAlt(<Окно>) — помечает на панели задач кнопку, представляющую указанное <Окно> , как активную, не активизируя ни кнопку, ни само окно. <Окно> должно быть указано в виде экземпляра класса QWidget или QWindow ; setWindowExcludedFromPeek(<Окно>, <Флаг>) — если вторым параметром передать зна- чение True , при наведении курсора мыши на миниатюру панели задач, представляющую любое другое окно, окно, указанное в параметре <Окно> , будет выводиться как есть, а не в виде тонкой рамки. Чтобы вернуть окну поведение по умолчанию (вывод в виде тон- кой рамки), следует передать вторым параметром значение False <Окно> должно быть указано в виде экземпляра класса QWidget или QWindow : QtWinExtras.QtWin.setWindowExcludedFromPeek(window, True) isWindowExcludedFromPeek(<Окно>) — возвращает True , если <Окно> при наведении кур- сора мыши на миниатюру панели задач, представляющую любое другое окно, выводится как есть, и False , если оно выводится как обычно, в виде тонкой рамки. <Окно> должно быть указано в виде экземпляра класса QWidget или QWindow ; setWindowDisallowPeek(<Окно>, <Флаг>) — если вторым параметром передать значение True , при наведении курсора мыши на миниатюру панели задач, представляющую <Окно> , все прочие окна будут выводиться как есть, а не в виде тонких рамок. Чтобы вернуть поведение по умолчанию (вывод остальных окон в виде тонких рамок), следует передать вторым параметром значение False <Окно> должно быть указано в виде экзем- пляра класса QWidget или QWindow ; isWindowPeekDisallowed(<Окно>) — возвращает True , если при наведении курсора мыши на миниатюру панели задач, представляющую <Окно> , все прочие окна выводятся как есть, и False , если они выводятся как обычно, в виде тонкой рамки. <Окно> должно быть указано в виде экземпляра класса QWidget или QWindow ; extendFrameIntoClientArea() — расширяет полупрозрачную область заголовка, указан- ного в первом параметре <Окно> на его клиентскую область. Работает только в Windows Vista и 7. Форматы метода: extendFrameIntoClientArea(<Окно>, <Слева>, <Сверху>, <Справа>, <Снизу>) extendFrameIntoClientArea(<Окно>, <Окно> должно быть указано в виде экземпляра класса QWidget или QWindow Первый формат позволяет задать величины областей, на которые должна распростра- няться область полупрозрачности, непосредственно, в виде целых чисел, в пикселах. Второй формат указывает величины этих областей в виде экземпляра класса QMargins : QtWinExtras.QtWin.extendFrameIntoClientArea(window, 0, 20, 0, 20) Если указать в качестве всех величин областей, на которые распространяется область полупрозрачности, число -1 , все окно станет полупрозрачным: QtWinExtras.QtWin.extendFrameIntoClientArea(window, -1, -1, -1, -1) resetExtendedFrame(<Окно>) — задает для окна, указанного в параметре <Окно> , область полупрозрачности по умолчанию, т. е. охватывающую только заголовок окна. <Окно> указывается в виде экземпляра класса QWidget или QWindow . Работает только в Windows Vista и 7; enableBlurBehindWindow(<Окно>[, — создает снаружи окна, указанного в параметре <Окно> , область размытия. <Окно> задается экземпляром класса QWidget или QWindow . Вторым параметром можно передать размеры области размытия (экземпляр Глава 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) |