from pathlib import Path
from PyQt5.QtCore import QSettings
from PyQt5.QtGui import (QResizeEvent, QMoveEvent)
= Path(__file__).parent / "app_settings.ini"
settings_file = QSettings(settings_file.as_posix(), QSettings.Format.IniFormat) settings
9 Přetrvávající nastavení aplikace
Jedním nedostatkem, kterým může aplikace trpět, je že po startu se bude vždy nacházet ve výchozím stavu. Což reálně znamená, že si aplikace nepřenáší mezi jednotlivými spuštěními žádnou informaci o svém stavu. U jednoduchých aplikací to nemusí vadit, byť i zde si lze představit informace, které by si aplikace mohla přenést, např. velikost a umístění okna na obrazovce.
Pro uložení nejen těchto, ale libovolných jiných, informací applikace je možné použít třídu QSettings
, která je přímo pro tyto situace vytvořena. Tato třída má dva režimy, ve kterých může fungovat. Jednou variantou je vytvoření .ini soubor v definovaném umístění, což je textový soubor, do které se nastavení zapisují. Takovýto soubor vytvoříme následovně:
Druhou variantou je nastavení proměnných QApplication
organizace, domény a názvu aplikace, a následně vytvoření settings
bez udání dalších informací. V tomto případě Qt zvolí umístění souboru dle systému a několika dalších informací autonomně a formát nebude textový .ini soubor. Tato varianta je obecnější, ale náročnější, protože programátor nemá k přímo přístup k souboru a informacím v něm uloženým.
from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QApplication
"MySoft")
QApplication.setOrganizationName("mysoft.com")
QApplication.setOrganizationDomain("Star Runner")
QApplication.setApplicationName(
= QSettings() settings
Jakmile existuje proměnná s nastaveními, je důležité znát několik základních funkcí pro práci s nastaveními. Samotná třída QApplication
obsahuje širší funkcionalitu, ale tyto funkce jsou zásadní. Základními funkcemi je zápis a přečtení proměnné, což je realizováno funkcemi setValue()
a value()
. Obě tyto funkce mají jako první parameter název příslušného nastavení, v němž je možné použít /
jako oddělovač úrovní. Funkce value()
umožňuje jako druhý parametr definovat defaultní hodnotu nastavení, pokud zatím není nastavená a neexistuje.
"mainwindow/value", 0)
settings.value("mainwindow/value", 1) settings.setValue(
Dvě další zásadní funkce jsou vymazání proměnné (remove()
) a kontrola, zdali proměnná existuje (contains()
), obě funkce přijímají jako první parameter název nastavení.
"mainwindow/value")
settings.contains("mainwindow/value") settings.remove(
Qt umožňuje do nastavení ukládat a následně načítat i některé komplexnější objekty, např. velikost (třída QSize
) či umístění (třída QPoint
), což značně usnadňuje mnoho operací. Např. je tak možné jednoduše ukládat do nastavení velikost a umístění oken na obrazovce.
9.1 Praktická ukázka
Praktická ukázka zde zahrnuje prázdnou aplikaci, která si pamatuje svoje umístění a velikost na obrazovce. Ukázka je dostupná: empty_application_with_settings.py. V ukázce je podstatné, že velikost a umístění okna se zapisují do nastavení při každé jejich změně, a načítají se při vytvoření hlavní okna aplikace.
Tuto jednoduchou ukázku můžeme dále rozšířit o zobrazení všech existujících nastavení. Toho docílíme vytvořením jednoduchého okna odvozeného od QDialog
.
class SettingsDialog(QDialog):
def __init__(self, parent: Optional[QWidget] = None) -> None:
super().__init__(parent)
self.setWindowTitle("Settings")
self.setMinimumSize(500, 300)
self.settings = QSettings()
= QVBoxLayout()
layout self.setLayout(layout)
self.table_widget = QTableWidget(self)
self.table_widget)
layout.addWidget(
self.table_widget.setColumnCount(2)
self.table_widget.setHorizontalHeaderLabels(["Key", "Value"])
self.table_widget.verticalHeader().setVisible(False)
self.buttons = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Ok, self)
self.buttons)
layout.addWidget(
self.buttons.button(QDialogButtonBox.Cancel).setText("Close")
self.buttons.button(QDialogButtonBox.Ok).setText("Remove All Settings")
self.buttons.accepted.connect(self.accept)
self.buttons.rejected.connect(self.reject)
= self.settings.allKeys()
settings_keys self.table_widget.setRowCount(len(settings_keys))
for i, key in enumerate(settings_keys):
self.table_widget.setCellWidget(i, 0, QLabel(key))
self.table_widget.setCellWidget(i, 1, QLabel(str(self.settings.value(key, ""))))
self.table_widget.resizeColumnsToContents()
Vytvoření tohoto dialogového okna navážeme v aplikaci na nový prvek (QAction
) v menu. Výsledek je v příkladu empty_application_with_settings_dialog.py.