Не могу прочитать логическое значение из INI-файла

У меня проблема с загрузкой логического ini файл в PyQt5 приложение.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
from PyQt5 import QtCore
from PyQt5.QtCore import QSettings, QVariant
from PyQt5.QtWidgets import (
    QApplication, QCheckBox, QDialog, QGridLayout,
    QLabel, QLayout, QPushButton
)


class Settings(QDialog):
    "settings GUI"

    _settings = None

    def __init__(self):
        super(Settings, self).__init__()
        self._ui()

    def _ui(self):
        self._chk_test = QCheckBox()
        self._chk_test.setText("test checkbox")

        self._settings = QSettings("settings.ini", QSettings.IniFormat)
        self._settings.setFallbacksEnabled(False)

        # load configuration
        self._chk_test.setChecked(
            self._bool(self._settings.value("test_value", True)))

        # save settings
        btn_save = QPushButton("save")
        btn_save.clicked.connect(self._save_settings)

        # setting layouts
        grid_layout = QGridLayout()
        grid_layout.addWidget(self._chk_test, 0, 0, 1, 1)
        grid_layout.addWidget(btn_save, 0, 1, 1, 1)
        grid_layout.setSizeConstraint(QLayout.SetFixedSize)
        grid_layout.setHorizontalSpacing(100)
        grid_layout.setVerticalSpacing(5)

        self.setWindowTitle("Boolean")
        self.setLayout(grid_layout)
        self.show()

    def _save_settings(self):
        self._settings.setValue("test_value", self._chk_test.isChecked())
        self.close()

    def _bool(self, str):
        if str == "true":
            return True
        else:
            return False


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Settings()
    sys.exit(app.exec_())

Когда я пытаюсь загрузить булево, используя

self._settings.value("test_value", True).toBool()

или же

QVariant(self._settings.value("test_value", True)).toBool()

Я получаю AttributeError:

'str' / 'QVariant' object has no attribute 'toBool()'. 

Я написал обычай _bool метод, но мне интересно, есть ли лучший способ решить это.

3 ответа

Решение

Они добавляют третий аргумент type= установить тип для результата. Так что вы можете использовать type=bool и получить Python True/False вместо строки "true"/"false"

a = self._settings.value("test_value", True, type=bool)
print('a:', type(a), a)

b = self._settings.value("test_value", True)
print('b:', type(b), b)

результат

a: <class 'bool'> True
b: <class 'str'> true

Найдено в Google: https://riverbankcomputing.com/pipermail/pyqt/2011-January/029032.html

  • Добавлен необязательный аргумент ключевого слова type в QSettings.value(), чтобы можно было указать тип возвращаемого значения.

Если предположить, self._settings.value("test_value", True) возвращает строку, значение которой "true"Вы могли бы сделать

self._chk_test.setChecked(
            self._settings.value("test_value", True) == "true")

Однако, если вам нужно сделать это несколько раз, я бы оставил пользовательский метод (но сделал бы его более компактным, как предложил @furas):

def _bool(self, str):
    return str == "true"

Я возился со смесью вышеперечисленных решений и обнаружил, что для экономии времени на тестировании действительно важно очистить настройки перед их установкой.

      self._settings.clear()
self._settings.setValue("test_value", False)
print(self._settings.value("test_value", type=bool)

Это решение работает для меня на macOS и Windows.

Еще одна вещь, на которую следует обратить внимание при работе с кросс-платформой, — всегда использовать один и тот же регистр и никогда не использовать регистр для различения двух слов. Файл инициализации Windows нечувствителен к регистру, а macOS чувствителен к регистру.

Другие вопросы по тегам