def test_settings(): settings = core.Settings("1", "2") settings.set_value("test", "value") assert "test" in settings assert settings.value("test") == "value" with core.Settings("ab", "cd", settings_id="test") as s: s.set_value("test2", "xx") with settings.write_array("test"): pass with settings.read_array("test"): pass with settings.group("test"): pass settings["test2"] = "xyz" assert settings["test2"] == "xyz" settings.setdefault("test3", "abc") assert settings.get("test3") == "abc" del settings["test3"] path = pathlib.Path.cwd() settings.set_default_format("ini") with pytest.raises(ValueError): settings.set_default_format("ino") settings.set_path("native", "user", path) with pytest.raises(ValueError): settings.set_path("error", "user", path) with pytest.raises(ValueError): settings.set_path("native", "error", path) s = core.Settings.build_from_dict(dict(a="b")) repr(s)
def test_settings(qapp): settings = core.Settings("1", "2") settings.clear() settings.set_value("test", "value") assert settings.get("empty") is None assert len(settings) > 0 assert "test" in settings assert settings.get("test") == "value" with core.Settings(settings_id="test") as s: s.set_value("test2", "xx") with settings.write_array("test"): pass with settings.read_array("test"): pass with settings.edit_group("test"): pass with pytest.raises(KeyError): del settings["some value"] with pytest.raises(KeyError): settings.pop("some value2") settings["test2"] = "xyz" assert settings["test2"] == "xyz" settings.setdefault("test3", "abc") assert settings.get("test3") == "abc" del settings["test3"] path = pathlib.Path.cwd() for i in settings: pass settings["test"] = True assert settings["test"] is True settings["test"] = "test" assert settings["test"] == "test" settings["test"] = dict(a="b") assert settings["test"] == dict(a="b") settings["test"] = (1, "b") assert settings["test"] == (1, "b") settings["test"] = QtCore.QByteArray(b"test") assert settings["test"] == QtCore.QByteArray(b"test") settings["test"] = b"test" assert settings["test"] == b"test" settings.set_default_format("ini") assert settings.get_default_format() == "ini" with pytest.raises(InvalidParamError): settings.set_default_format("ino") assert settings.get_scope() == "user" settings.set_path("native", "user", path) with pytest.raises(InvalidParamError): settings.set_path("error", "user", path) with pytest.raises(InvalidParamError): settings.set_path("native", "error", path) s = core.Settings.build_from_dict(dict(a="b"))
def __init__(self, path=None, mode="open", caption="", path_id=None, parent=None): self.path_id = path_id if path_id and path is None: settings = core.Settings() path = settings.value(self.path_id, "") super().__init__(directory=path, caption=caption, parent=parent) self.set_file_mode("existing_files") self.set_accept_mode(mode)
def choose(self) -> Optional[List[pathlib.Path]]: result = super().exec_() if result != self.Accepted: return None paths = self.selected_files() folder_path = paths[0].parent if self.path_id: settings = core.Settings() settings.setValue(self.path_id, str(folder_path)) return paths
def closeEvent(self, event): """ override, gets executed when app gets closed. saves GUI settings """ settings = core.Settings() settings.set_value("mainwindow.geometry", self.saveGeometry()) settings.set_value("mainwindow.state", self.saveState()) super().closeEvent(event) event.accept()
def choose(self) -> list[pathlib.Path] | None: result = self.main_loop() if result != self.Accepted: return None paths = self.selected_files() folder_path = paths[0].parent if self.path_id: settings = core.Settings() settings.setValue(self.path_id, str(folder_path)) return paths
def load_state(self, settings: core.Settings | None = None, key: str | None = None) -> bool: settings = core.Settings() if settings is None else settings key = self.generate_header_id() if key is None else key state = settings.get(key, None) if state is not None: self.restoreState(state) return True return False
def load_window_state(self): settings = core.Settings() geom = settings.value("mainwindow.geometry", None) state = settings.value("mainwindow.state", None) if geom is not None and state is not None: try: self.restoreGeometry(geom) self.restoreState(state) except TypeError: logging.info("Wrong type for window state. Probably Qt binding switch?") pass
def store_widget_states(self, settings: MutableMapping | None = None, key: str = "states"): settings = core.Settings() if settings is None else settings result = {} for k, v in SAVE_STATES.items(): result[k] = { i.objectName(): i.saveState() for i in self.find_children(v) if i.objectName() } settings[key] = result
def restore_widget_states(self, settings: Mapping | None = None, key: str = "states"): settings = core.Settings() if settings is None else settings for category, v in SAVE_STATES.items(): items = settings[key].get(category) if items is None: continue for name, state in items.items(): w = self.find_child(v, name=name) if w is not None: w.restoreState(state)
def __init__(self, path=None, mode="open", caption="", path_id=None, extension_filter=None, parent=None): super().__init__(parent=parent) self.setDirectory(path) self.title = caption self.path_id = path_id if extension_filter: self.set_filter(extension_filter) if path_id and path is None: settings = core.Settings() path = settings.value(self.path_id, "") self.set_file_mode("existing_files") self.set_accept_mode(mode)
def _write_model_settings(self): """Write the model settings to the persistent store.""" logger.debug("Writing model settings for window: %d", self._instance_nr) new = dict( auto_refresh=self._auto_refresh, refresh_rate=self._refresh_rate, show_callable_attrs=self._proxy_tree_model.get_show_callables(), show_special_attrs=self._proxy_tree_model.get_show_special_attrs(), ) settings_id = self._settings_group_name("model") logger.debug(f"New settings: {new}") with core.Settings(settings_id=settings_id) as settings: settings.set_values(new)
def save_window_state(self, recursive: bool = False): """Save current window state as QSetting. Args: recursive (bool, optional): Description """ settings = core.Settings() name = self.get_id() logger.debug(f"Saving window state for {self.windowTitle()!r}...") settings[f"{name}.geometry"] = self.saveGeometry() settings[f"{name}.state"] = self.saveState() if recursive: for window in self.find_children(MainWindow, recursive=True): if window.get_id(): window.save_window_state()
def is_dark_mode() -> bool: if sys.platform.startswith("win"): from prettyqt import core path = ( "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" "Themes\\Personalize") settings = core.Settings(path, core.Settings.Format.NativeFormat) return settings.value("AppsUseLightTheme") == 0 elif sys.platform == "darwin": import darkdetect return darkdetect.isDark() else: return False
def load_window_state(self, recursive: bool = False) -> bool: settings = core.Settings() name = self.get_id() geom = settings.get(f"{name}.geometry") state = settings.get(f"{name}.state") restored = False if geom is not None and state is not None: try: logger.debug(f"Loading window state for {self.windowTitle()!r}...") self.restoreGeometry(geom) self.restoreState(state) restored = True except TypeError: logger.error("Wrong type for window state. Probably Qt binding switch?") if recursive: for window in self.find_children(MainWindow, recursive=True): if window.get_id(): window.load_window_state() return restored
def __init__( self, path: None | types.PathType = None, mode: AcceptModeStr = "open", caption: str | None = None, path_id: str | None = None, extension_filter: dict | None = None, file_mode: FileModeStr = "existing_files", parent: QtWidgets.QWidget | None = None, ): super().__init__(parent=parent) self.set_title(caption) self.path_id = path_id if extension_filter: self.set_extension_filter(extension_filter) if path_id is not None and path is None: settings = core.Settings() path = settings.get(path_id, "") if path is not None: self.set_directory(path) self.set_file_mode(file_mode) self.set_accept_mode(mode)
def load_state(self): settings = core.Settings() state = settings.value(f"{self.widget_name}.state", None) if state is not None: self.restoreState(state)
def __init__(self, organisation, application, qsettings=None): super().__init__() if qsettings is None: self._settings = core.Settings(organisation, application) else: self._settings = qsettings
def test_settings(): settings = core.Settings("1", "2") settings.set_value("test", "value") assert settings.contains("test") assert settings.value("test") == "value"
def __init__(self, obj, name: str = ""): super().__init__() self.set_title("Object browser") self._instance_nr = self._add_instance() self.set_icon("mdi.language-python") self._attr_cols = DEFAULT_ATTR_COLS self._attr_details = DEFAULT_ATTR_DETAILS logger.debug("Reading model settings for window: %d", self._instance_nr) with core.Settings( settings_id=self._settings_group_name("model")) as settings: self._auto_refresh = settings.get("auto_refresh", False) self._refresh_rate = settings.get("refresh_rate", 2) show_callable_attrs = settings.get("show_callable_attrs", True) show_special_attrs = settings.get("show_special_attrs", True) self._tree_model = objectbrowsertreemodel.ObjectBrowserTreeModel( obj, name, attr_cols=self._attr_cols) self._proxy_tree_model = objectbrowsertreemodel.ObjectBrowserTreeProxyModel( show_callable_attrs=show_callable_attrs, show_special_attrs=show_special_attrs, ) self._proxy_tree_model.setSourceModel(self._tree_model) # self._proxy_tree_model.setSortRole(RegistryTableModel.SORT_ROLE) self._proxy_tree_model.setDynamicSortFilter(True) # self._proxy_tree_model.setSortCaseSensitivity(Qt.CaseInsensitive) # Views self._setup_actions() self.central_splitter = widgets.Splitter( parent=self, orientation=constants.VERTICAL) self.setCentralWidget(self.central_splitter) # Tree widget self.obj_tree = widgets.TreeView() self.obj_tree.setRootIsDecorated(True) self.obj_tree.setAlternatingRowColors(True) self.obj_tree.set_model(self._proxy_tree_model) self.obj_tree.set_selection_behaviour("rows") self.obj_tree.setUniformRowHeights(True) self.obj_tree.setAnimated(True) # Stretch last column? # It doesn't play nice when columns are hidden and then shown again. self.obj_tree.h_header.set_id("table_header") self.obj_tree.h_header.setSectionsMovable(True) self.obj_tree.h_header.setStretchLastSection(False) self.central_splitter.addWidget(self.obj_tree) # Bottom pane bottom_pane_widget = widgets.Widget() bottom_pane_widget.set_layout("horizontal", spacing=0, margin=5) self.central_splitter.addWidget(bottom_pane_widget) group_box = widgets.GroupBox("Details") bottom_pane_widget.box.addWidget(group_box) group_box.set_layout("horizontal", margin=2) # Radio buttons radio_widget = widgets.Widget() radio_widget.set_layout("vertical", margin=0) self.button_group = widgets.ButtonGroup(self) for button_id, attr_detail in enumerate(self._attr_details): radio_button = widgets.RadioButton(attr_detail.name) radio_widget.box.addWidget(radio_button) self.button_group.addButton(radio_button, button_id) self.button_group.buttonClicked.connect(self._change_details_field) self.button_group.button(0).setChecked(True) radio_widget.box.addStretch(1) group_box.box.addWidget(radio_widget) # Editor widget font = gui.Font("Courier") font.setFixedPitch(True) # font.setPointSize(14) self.editor = widgets.PlainTextEdit() self.editor.setReadOnly(True) self.editor.setFont(font) group_box.box.addWidget(self.editor) # Splitter parameters self.central_splitter.setCollapsible(0, False) self.central_splitter.setCollapsible(1, True) self.central_splitter.setSizes([400, 200]) self.central_splitter.setStretchFactor(0, 10) self.central_splitter.setStretchFactor(1, 0) selection_model = self.obj_tree.selectionModel() selection_model.currentChanged.connect(self._update_details) menubar = self.menuBar() file_menu = menubar.add_menu("&File") file_menu.addAction("C&lose", self.close, "Ctrl+W") file_menu.addAction("E&xit", lambda: widgets.app().closeAllWindows(), "Ctrl+Q") view_menu = menubar.add_menu("&View") view_menu.addAction("&Refresh", self._tree_model.refresh_tree, "Ctrl+R") view_menu.addAction(self.toggle_auto_refresh_action) view_menu.addSeparator() self.show_cols_submenu = widgets.Menu("Table columns") view_menu.add_menu(self.show_cols_submenu) actions = self.obj_tree.h_header.get_header_actions() self.show_cols_submenu.add_actions(actions) view_menu.addSeparator() view_menu.addAction(self.toggle_callable_action) view_menu.addAction(self.toggle_special_attribute_action) assert self._refresh_rate > 0 self._refresh_timer = core.Timer(self) self._refresh_timer.setInterval(self._refresh_rate * 1000) self._refresh_timer.timeout.connect(self._tree_model.refresh_tree) # Update views with model self.toggle_special_attribute_action.setChecked(show_special_attrs) self.toggle_callable_action.setChecked(show_callable_attrs) self.toggle_auto_refresh_action.setChecked(self._auto_refresh) # Select first row so that a hidden root node will not be selected. first_row_index = self._proxy_tree_model.first_item_index() self.obj_tree.setCurrentIndex(first_row_index) if self._tree_model.inspected_node_is_visible: self.obj_tree.expand(first_row_index)
def save_state(self, settings: core.Settings | None = None, key: str | None = None): settings = core.Settings() if settings is None else settings key = self.generate_header_id() if key is None else key settings.set_value(key, self.saveState())
def save_state(self): settings = core.Settings() settings.setValue(f"{self.widget_name}.state", self.saveState())