Пример #1
0
def repr_settings(settings: QSettings) -> str:
    """works on a QSettings, not a Settings"""
    msg = 'QSettings:\n'
    for key in sorted(settings.allKeys()):
        value = settings.value(key)
        msg += '    %r : %r\n' % (key, value)
    return msg
Пример #2
0
 def restore_from_defaults():
     """
     Clears all settings (except "defaults" group) and restores all settings
     from the defaults group.
     """
     settings = QSettings()
     for g in settings.childGroups():
         if g != "defaults":
             settings.remove(g)
     for k in settings.childKeys():
         settings.remove(k)
     defaults = QSettings()
     defaults.beginGroup("defaults")
     for k in defaults.allKeys():
         settings.setValue(k, defaults.value(k))
Пример #3
0
 def restore_from_defaults():
     """
     Clears all settings (except "defaults" group) and restores all settings
     from the defaults group.
     """
     settings = QSettings()
     for g in settings.childGroups():
         if g != "defaults":
             settings.remove(g)
     for k in settings.childKeys():
         settings.remove(k)
     defaults = QSettings()
     defaults.beginGroup("defaults")
     for k in defaults.allKeys():
         settings.setValue(k, defaults.value(k))
Пример #4
0
class UserConfig(object):
    """Holds user configuration option. Options are assigned a section
    and a key must only be unique within a section.

    Uses QSettings for the heavy lifting. All platforms use the Ini format
    at UserScope
    """

    # The raw QSettings instance
    qsettings = None
    defaults = None

    def __init__(self, organization, application, defaults=None):
        """

        :param organization: A string name for the organization
        :param application: A string name for the application name
        :param defaults: Default configuration values for this instance in the
        form of nested dict instances
        """
        # Loads the saved settings if found
        self.qsettings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                                   organization, application)
        self.defaults = defaults

    def all_keys(self):
        return self.qsettings.allKeys()

    @property
    def filename(self):
        return self.qsettings.fileName()

    def get(self, section, option):
        """
        Return a value for an option in a given section. If not
        specified in the saved settings then the initial
        defaults are consulted. If no option is found then
        a KeyError is raised
        :param section: A string section name
        :param option: A string option name
        :return: The value of the option
        """
        value = self.qsettings.value(self._settings_path(section, option))
        if not value:
            value = self._get_default_or_raise(section, option)

        return value

    def set(self, section, option, value):
        """
        Set a value for an option in a given section.
        :param section: A string section name
        :param option: A string option name
        :param value: The value of the setting
        """
        self.qsettings.setValue(self._settings_path(section, option), value)

    # -------------------------------------------------------------------------
    # "Private" methods
    # -------------------------------------------------------------------------

    def _check_section_option_is_valid(self, section, option):
        """
        Sanity check the section and option are strings
        """
        if not is_text_string(section):
            raise RuntimeError("section is not a text string")
        if not is_text_string(option):
            raise RuntimeError("option is not a text string")

    def _get_default_or_raise(self, section, option):
        """
        Returns the value listed in the defaults if it exists
        :param section: A string denoting the section (not checked)
        :param option: A string denoting the option name
        :return: The value of the default
        :raises KeyError: if the item does not exist
        """
        value = None
        if self.defaults and section in self.defaults:
            try:
                value = self.defaults[section][option]
            except KeyError:
                raise KeyError("Unknown config item requested: " +
                               self._settings_path(section, option))
        return value

    def _settings_path(self, section, option):
        """
        Private method to construct a path to the given option with the
        section
        :param section: The name of the section
        :param option: The name of the option
        :return: A path to the location within the QSettings instance
        """
        self._check_section_option_is_valid(section, option)
        return section + "/" + option
Пример #5
0
class UserConfig(object):
    """Holds user configuration option. Options are assigned a section
    and a key must only be unique within a section.

    Uses QSettings for the heavy lifting. All platforms use the Ini format
    at UserScope
    """

    # The raw QSettings instance
    qsettings = None

    def __init__(self, organization, application, defaults=None):
        """
        :param organization: A string name for the organization
        :param application: A string name for the application name
        :param defaults: Default configuration values for this instance in the
        form of nested dict instances
        """
        # Loads the saved settings if found
        self.qsettings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                                   organization, application)

        # convert the defaults into something that qsettings can handle
        default_settings = self._flatten_defaults(defaults)

        # put defaults into qsettings if they weren't there already
        try:
            self.set_qsettings_values(default_settings)
        # the editors/sessiontabs are pickled in config so need to remove them
        except ValueError:
            self.qsettings.remove('Editors/SessionTabs')
            self.set_qsettings_values(default_settings)

    def set_qsettings_values(self, default_settings):
        configFileKeys = self.qsettings.allKeys()
        for key in default_settings.keys():
            if key not in configFileKeys:
                self.qsettings.setValue(key, default_settings[key])

    def all_keys(self, group=None):
        if group is not None:
            self.qsettings.beginGroup(group)
            result = self.qsettings.allKeys()
            self.qsettings.endGroup()
        else:
            result = self.qsettings.allKeys()

        return result

    @property
    def filename(self):
        return self.qsettings.fileName()

    def get(self, option, second=None, type=None):
        """Return a value for an option. If two arguments are given the first
        is the group/section and the second is the option within it.
        ``config.get('main', 'window/size')`` is equivalent to
        ``config.get('main/window/size')`` If no option is found then
        a KeyError is raised
        """
        try:
            return self._get_setting(option, second, type)
        except TypeError:
            # The 'PyQt_PyObject' (1024) type is sometimes used for settings which have an unknown type.
            value = self._get_setting(option,
                                      second,
                                      type=QVariant.typeToName(1024))
            return value if isinstance(value, type) else type(*value)

    def has(self, option, second=None):
        """Return a True if the key exists in the
        settings. ``config.get('main', 'window/size')`` and
        ``config.get('main/window/size')`` are equivalent.
        """
        option = self._check_section_option_is_valid(option, second)
        return option in self.all_keys()

    def set(self, option, value, extra=None):
        """Set a value for an option in a given section. Can either supply
        the fully qualified option or add the section as an additional
        first argument. ``config.set('main', 'high_dpi_scaling',
        True)`` is equivalent to ``config.set('main/high_dpi_scaling',
        True)``
        """
        if extra is None:
            option = self._check_section_option_is_valid(option, extra)
            # value is in the right place
        else:
            option = self._check_section_option_is_valid(option, value)
            value = extra
        self.qsettings.setValue(option, value)

    def remove(self, option, second=None):
        """Removes a key from the settings. Key not existing returns without effect.
        """
        option = self._check_section_option_is_valid(option, second)
        if self.has(option):
            self.qsettings.remove(option)

    # -------------------------------------------------------------------------
    # "Private" methods
    # -------------------------------------------------------------------------

    @staticmethod
    def _flatten_defaults(input_dict):
        result = {}
        for key in input_dict:
            value = input_dict[key]
            if isinstance(value, dict):
                value = UserConfig._flatten_defaults(value)
                for key_inner in value.keys():
                    result[joinsettings(key, key_inner)] = value[key_inner]
            else:
                result[key] = value
        return result

    def _check_section_option_is_valid(self, option, second):
        """
        Sanity check the section and option are strings and return the flattened option key
        """
        if second is None:
            if not isinstance(option, str):
                raise TypeError(
                    'Found invalid type ({}) for option ({}) must be a string'.
                    format(type(option), option))
            return option
        else:  # first argument is actually the section/group
            if not isinstance(option, str):
                raise TypeError(
                    'Found invalid type ({}) for section ({}) must be a string'
                    .format(type(option), option))
            if not isinstance(second, str):
                raise TypeError(
                    'Found invalid type ({}) for option ({}) must be a string'.
                    format(type(second), second))
            return joinsettings(option, second)

    def _get_setting(self, option, second=None, type=None):
        """Return a value for an option. If two arguments are given the first
        is the group/section and the second is the option within it.
        ``config.get('main', 'window/size')`` is equivalent to
        ``config.get('main/window/size')`` If no option is found then
        a KeyError is raised
        """
        full_option = self._check_section_option_is_valid(option, second)
        if type is None:
            # Some platforms only ever store string values in QSettings so the type of stored settings can get lost
            raise ValueError(
                "Please specify the type of the setting you are retrieving.")
        if not self.has(option, second):
            # If a setting does not exist, we want to raise a KeyError
            raise KeyError(f"Unknown config item requested: '{option}'")
        return self.qsettings.value(full_option, type=type)
Пример #6
0
 def __iter__(self):
     settings = QSettings(parent=self.parent)
     settings.beginGroup(self.group)
     keys = settings.allKeys()
     for k in keys:
         yield k, settings.value(k)
Пример #7
0
class UserConfig(object):
    """Holds user configuration option. Options are assigned a section
    and a key must only be unique within a section.

    Uses QSettings for the heavy lifting. All platforms use the Ini format
    at UserScope
    """

    # The raw QSettings instance
    qsettings = None

    def __init__(self, organization, application, defaults=None):
        """
        :param organization: A string name for the organization
        :param application: A string name for the application name
        :param defaults: Default configuration values for this instance in the
        form of nested dict instances
        """
        # Loads the saved settings if found
        self.qsettings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                                   organization, application)

        # convert the defaults into something that qsettings can handle
        default_settings = self._flatten_defaults(defaults)

        # put defaults into qsettings if they weren't there already
        try:
            self.set_qsettings_values(default_settings)
        # the editors/sessiontabs are pickled in config so need to remove them
        except ValueError:
            self.qsettings.remove('Editors/SessionTabs')
            self.set_qsettings_values(default_settings)

        # fixup the values of booleans - they do not evaluate correctly when read from the config file
        for key in self.all_keys():
            try:
                value = self.get(key)
            except (KeyError, TypeError):
                continue
            if value == 'true':
                self.set(key, True)
            elif value == 'false':
                self.set(key, False)

    def set_qsettings_values(self, default_settings):
        configFileKeys = self.qsettings.allKeys()
        for key in default_settings.keys():
            if key not in configFileKeys:
                self.qsettings.setValue(key, default_settings[key])

    def all_keys(self, group=None):
        if group is not None:
            self.qsettings.beginGroup(group)
            result = self.qsettings.allKeys()
            self.qsettings.endGroup()
        else:
            result = self.qsettings.allKeys()

        return result

    @property
    def filename(self):
        return self.qsettings.fileName()

    def get(self, option, second=None, type=None):
        """Return a value for an option. If two arguments are given the first
        is the group/section and the second is the option within it.
        ``config.get('main', 'window/size')`` is equivalent to
        ``config.get('main/window/size')`` If no option is found then
        a KeyError is raised
        """
        def raise_keyerror(key):
            raise KeyError(
                'Unknown config item requested: "{}"'.format(option))

        full_option = self._check_section_option_is_valid(option, second)
        if type is None:
            # return whatever the QSettings object returns
            value = self.qsettings.value(full_option)
            if value is None:
                raise_keyerror(full_option)
            else:
                return value
        else:
            # PyQt QSettings with the type parameter tries to always return the type even if no value exists
            # We still want a KeyError if it does not exist
            if self.has(option, second):
                return self.qsettings.value(full_option, type=type)
            else:
                raise_keyerror(option)

    def has(self, option, second=None):
        """Return a True if the key exists in the
        settings. ``config.get('main', 'window/size')`` and
        ``config.get('main/window/size')`` are equivalent.
        """
        option = self._check_section_option_is_valid(option, second)
        return option in self.all_keys()

    def set(self, option, value, extra=None):
        """Set a value for an option in a given section. Can either supply
        the fully qualified option or add the section as an additional
        first argument. ``config.set('main', 'high_dpi_scaling',
        True)`` is equivalent to ``config.set('main/high_dpi_scaling',
        True)``
        """
        if extra is None:
            option = self._check_section_option_is_valid(option, extra)
            # value is in the right place
        else:
            option = self._check_section_option_is_valid(option, value)
            value = extra
        self.qsettings.setValue(option, value)

    def remove(self, option, second=None):
        """Removes a key from the settings. Key not existing returns without effect.
        """
        option = self._check_section_option_is_valid(option, second)
        if self.has(option):
            self.qsettings.remove(option)

    # -------------------------------------------------------------------------
    # "Private" methods
    # -------------------------------------------------------------------------

    @staticmethod
    def _flatten_defaults(input_dict):
        result = {}
        for key in input_dict:
            value = input_dict[key]
            if isinstance(value, dict):
                value = UserConfig._flatten_defaults(value)
                for key_inner in value.keys():
                    result[joinsettings(key, key_inner)] = value[key_inner]
            else:
                result[key] = value
        return result

    def _check_section_option_is_valid(self, option, second):
        """
        Sanity check the section and option are strings and return the flattened option key
        """
        if second is None:
            if not isinstance(option, str):
                raise TypeError(
                    'Found invalid type ({}) for option ({}) must be a string'.
                    format(type(option), option))
            return option
        else:  # first argument is actually the section/group
            if not isinstance(option, str):
                raise TypeError(
                    'Found invalid type ({}) for section ({}) must be a string'
                    .format(type(option), option))
            if not isinstance(second, str):
                raise TypeError(
                    'Found invalid type ({}) for option ({}) must be a string'.
                    format(type(second), second))
            return joinsettings(option, second)
Пример #8
0
class UserConfig(object):
    """Holds user configuration option. Options are assigned a section
    and a key must only be unique within a section.

    Uses QSettings for the heavy lifting. All platforms use the Ini format
    at UserScope
    """

    # The raw QSettings instance
    qsettings = None

    def __init__(self, organization, application, defaults=None):
        """
        :param organization: A string name for the organization
        :param application: A string name for the application name
        :param defaults: Default configuration values for this instance in the
        form of nested dict instances
        """
        # Loads the saved settings if found
        self.qsettings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                                   organization, application)

        # convert the defaults into something that qsettings can handle
        default_settings = self._flatten_defaults(defaults)

        # put defaults into qsettings if they weren't there already
        try:
            self.set_qsettings_values(default_settings)
        # the editors/sessiontabs are pickled in config so need to remove them
        except ValueError:
            self.qsettings.remove('Editors/SessionTabs')
            self.set_qsettings_values(default_settings)

        # fixup the values of booleans - they do not evaluate correctly when read from the config file
        for key in self.all_keys():
            try:
                value = self.get(key)
            except KeyError:
                continue
            if value == 'true':
                self.set(key, True)
            elif value == 'false':
                self.set(key, False)

    def set_qsettings_values(self, default_settings):
        configFileKeys = self.qsettings.allKeys()
        for key in default_settings.keys():
            if key not in configFileKeys:
                self.qsettings.setValue(key, default_settings[key])

    def all_keys(self, group=None):
        if group is not None:
            self.qsettings.beginGroup(group)
            result = self.qsettings.allKeys()
            self.qsettings.endGroup()
        else:
            result = self.qsettings.allKeys()

        return result

    @property
    def filename(self):
        return self.qsettings.fileName()

    def get(self, option, second=None):
        """Return a value for an option. If two arguments are given the first
        is the group/section and the second is the option within it.
        ``config.get('main', 'window/size')`` is equivalent to
        ``config.get('main/window/size')`` If no option is found then
        a KeyError is raised
        """
        option = self._check_section_option_is_valid(option, second)
        value = self.qsettings.value(option)

        # qsettings appears to return None if the option isn't found
        if value is None:
            raise KeyError('Unknown config item requested: "{}"'.format(option))
        else:
            return value

    def has(self, option, second=None):
        """Return a True if the key exists in the
        settings. ``config.get('main', 'window/size')`` and
        ``config.get('main/window/size')`` are equivalent.
        """
        option = self._check_section_option_is_valid(option, second)
        return option in self.all_keys()

    def set(self, option, value, extra=None):
        """Set a value for an option in a given section. Can either supply
        the fully qualified option or add the section as an additional
        first argument. ``config.set('main', 'high_dpi_scaling',
        True)`` is equivalent to ``config.set('main/high_dpi_scaling',
        True)``
        """
        if extra is None:
            option = self._check_section_option_is_valid(option, extra)
            # value is in the right place
        else:
            option = self._check_section_option_is_valid(option, value)
            value = extra
        self.qsettings.setValue(option, value)

    def remove(self, option, second=None):
        """Removes a key from the settings. Key not existing returns without effect.
        """
        option = self._check_section_option_is_valid(option, second)
        if self.has(option):
            self.qsettings.remove(option)

    # -------------------------------------------------------------------------
    # "Private" methods
    # -------------------------------------------------------------------------

    @staticmethod
    def _flatten_defaults(input_dict):
        result = {}
        for key in input_dict:
            value = input_dict[key]
            if isinstance(value, dict):
                value = UserConfig._flatten_defaults(value)
                for key_inner in value.keys():
                    result[joinsettings(key, key_inner)] = value[key_inner]
            else:
                result[key] = value
        return result

    def _check_section_option_is_valid(self, option, second):
        """
        Sanity check the section and option are strings and return the flattened option key
        """
        if second is None:
            if not is_text_string(option):
                raise TypeError('Found invalid type ({}) for option ({}) must be a string'.format(type(option), option))
            return option
        else: # fist argument is actually the section/group
            if not is_text_string(option):
                raise TypeError('Found invalid type ({}) for section ({}) must be a string'.format(type(option), option))
            if not is_text_string(second):
                raise TypeError('Found invalid type ({}) for option ({}) must be a string'.format(type(second), second))
            return joinsettings(option, second)
Пример #9
0
 def __iter__(self):
     settings = QSettings(parent=self.parent)
     settings.beginGroup(self.group)
     keys = settings.allKeys()
     for k in keys:
         yield k, settings.value(k)