При добавлении виджета QTextedit и выполнении закрытия окна программа зависает

Есть GUI, программа которая сохраняет настройки/состояния/значения всех виджетов. Но когда пытаюсь добавить еще виджет QTextedit и при закрытии работающего окна gui программа зависает!

Как сохранять настройки всех виджетов

from PyQt5.Qt import *
from distutils.util import strtobool
import inspect


class MyQMainWindow(QMainWindow):
    companie_name = 'CompanieName'
    software_name = 'SoftwareName'
    settings_ui_name = 'defaultUiwidget'
    settings_ui_user_name = 'user'
    _names_to_avoid = {}

    def __init__(self, parent=None):
        super(MyQMainWindow, self).__init__(parent)
        self.settings = QSettings(self.companie_name, self.software_name)

    def closeEvent(self, e):
        self._gui_save()

    @classmethod
    def _get_handled_types(cls):
        return QSpinBox, QCheckBox, QRadioButton, QTextEdit
                                                  # ------------ > добавил сам
    @classmethod
    def _is_handled_type(cls, widget):
        return any(isinstance(widget, t) for t in cls._get_handled_types())

    def _gui_save(self):
        """ сохранить элементы управления и значения в настройках реестра """
        name_prefix = f"{self.settings_ui_name}/"
        self.settings.setValue(name_prefix + "geometry", self.saveGeometry())

        for name, obj in inspect.getmembers(self):
            if not self._is_handled_type(obj):
                continue

            name = obj.objectName()
            value = None

            if isinstance(obj, QCheckBox):
                value = obj.isChecked()
            elif isinstance(obj, QRadioButton):
                value = obj.isChecked()
            elif isinstance(obj, QSpinBox):
                value = obj.value()
            elif isinstance(obj, QTextEdit):    # ------------ > добавил сам
                value = obj.value()

            if value is not None:
                self.settings.setValue(name_prefix + name, value)

    def _gui_restore(self):
        """ восстановить элементы управления со значениями,
        хранящимися в настройках реестра
        """
        name_prefix = f"{self.settings_ui_name}/"
        geometry_value = self.settings.value(name_prefix + "geometry")
        if geometry_value:
            self.restoreGeometry(geometry_value)

        for name, obj in inspect.getmembers(self):
            if not self._is_handled_type(obj):
                continue
            if name in self._names_to_avoid:
                continue

            name = obj.objectName()
            value = None
            if not isinstance(obj, QListWidget):
                value = self.settings.value(name_prefix + name)
                if value is None:
                    continue

            if isinstance(obj, QCheckBox):
                obj.setChecked(strtobool(value))
            elif isinstance(obj, QRadioButton):
                obj.setChecked(strtobool(value))
            elif isinstance(obj, QSpinBox):
                obj.setValue(int(value))
            elif isinstance(obj, QTextEdit):    # ------------ > добавил сам
                obj.setValue(int(value))

    def _add_setting(self, name, value):
        name_prefix = f"{self.settings_ui_user_name}/"
        self.settings.setValue(name_prefix + name, value)

    def _get_setting(self, name):
        name_prefix = f"{self.settings_ui_user_name}/"
        return self.settings.value(name_prefix + name)


class MainWindow(MyQMainWindow):
    companie_name = 'Name'
    software_name = 'softName'
    _names_to_avoid = {'my_widget_name_not_to_save'}

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle(' ')
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)

        self.rb_1 = QRadioButton('RB 1')
        self.rb_1.setObjectName('rb_1')
        self.rb_2 = QRadioButton('RB 2')
        self.rb_2.setObjectName('rb_2')

        self.cb_1 = QCheckBox('Показать заголовок.')
        self.cb_1.setObjectName('cb_1')
        self.cb_1.stateChanged.connect(self.changeTitle)
        self.cb_2 = QCheckBox('CB 2')
        self.cb_2.setObjectName('cb_2')

        self.label = QLabel()
        self.spinBox = QSpinBox()
        self.spinBox.setObjectName("spinBox")
        self.spinBox.valueChanged.connect(self.label.setNum)

        self.text = QTextEdit()                 # ------------ > добавил сам
        self.text.setObjectName('text')

        self.gridLayout = QGridLayout(self.centralWidget)
        self.gridLayout.addWidget(self.rb_1, 0, 0)
        self.gridLayout.addWidget(self.rb_2, 0, 1)
        self.gridLayout.addWidget(self.cb_1, 1, 0)
        self.gridLayout.addWidget(self.cb_2, 1, 1)
        self.gridLayout.addWidget(self.label, 2, 0)
        self.gridLayout.addWidget(self.spinBox, 2, 1)
        self.gridLayout.addWidget(self.text, 3, 0)     # ------------ > добавил сам

        self._gui_restore()

    def changeTitle(self, state):
        if state == Qt.Checked:
            self.setWindowTitle('Hello QCheckBox')
        else:
            self.setWindowTitle(' ')


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    w.resize(300, 200)
    sys.exit(app.exec_())


Ответы (1 шт):

Автор решения: S. Nick

QString QTextEdit::toPlainText() const

Возвращает текст редактирования текста как обычный текст.

void QTextEdit::setPlainText(const QString &text)

Изменяет текст редактирования текста на текст строки. Любой предыдущий текст удаляется.


P.S. Чтобы получать реальную ошибку всегда запускайте свое приложение в CMD/терминале/консоли.

from PyQt5.Qt import *
from distutils.util import strtobool
import inspect


class MyQMainWindow(QMainWindow):
    companie_name = 'CompanieName'
    software_name = 'SoftwareName'
    settings_ui_name = 'defaultUiwidget'
    settings_ui_user_name = 'user'
    _names_to_avoid = {}

    def __init__(self, parent=None):
        super(MyQMainWindow, self).__init__(parent)
        self.settings = QSettings(self.companie_name, self.software_name)

    def closeEvent(self, e):
        self._gui_save()

    @classmethod
    def _get_handled_types(cls):
        return QSpinBox, QCheckBox, QRadioButton, QTextEdit                      # !!!
                                                # ^^^^^^^^^---- > добавил сам 
    @classmethod
    def _is_handled_type(cls, widget):
        return any(isinstance(widget, t) for t in cls._get_handled_types())

    def _gui_save(self):
        """ сохранить элементы управления и значения в настройках реестра """
        name_prefix = f"{self.settings_ui_name}/"
        self.settings.setValue(name_prefix + "geometry", self.saveGeometry())

        for name, obj in inspect.getmembers(self):
            if not self._is_handled_type(obj):
                continue

            name = obj.objectName()
            value = None

            if isinstance(obj, QCheckBox):
                value = obj.isChecked()
            elif isinstance(obj, QRadioButton):
                value = obj.isChecked()
            elif isinstance(obj, QSpinBox):
                value = obj.value()
            elif isinstance(obj, QTextEdit):    # < --- > добавил сам
#                value = obj.value()                                             # ---
                value = obj.toPlainText()                                        # +++

            if value is not None:
                self.settings.setValue(name_prefix + name, value)

    def _gui_restore(self):
        """ восстановить элементы управления со значениями,
        хранящимися в настройках реестра
        """
        name_prefix = f"{self.settings_ui_name}/"
        geometry_value = self.settings.value(name_prefix + "geometry")
        if geometry_value:
            self.restoreGeometry(geometry_value)

        for name, obj in inspect.getmembers(self):
            if not self._is_handled_type(obj):
                continue
            if name in self._names_to_avoid:
                continue

            name = obj.objectName()
            value = None
            if not isinstance(obj, QListWidget):
                value = self.settings.value(name_prefix + name)
                if value is None:
                    continue

            if isinstance(obj, QCheckBox):
                obj.setChecked(strtobool(value))
            elif isinstance(obj, QRadioButton):
                obj.setChecked(strtobool(value))
            elif isinstance(obj, QSpinBox):
                obj.setValue(int(value))
            elif isinstance(obj, QTextEdit):    # < ----- > добавил сам
#                obj.setValue(int(value))                                        # ---
                obj.setPlainText(value)                                          # +++

    def _add_setting(self, name, value):
        name_prefix = f"{self.settings_ui_user_name}/"
        self.settings.setValue(name_prefix + name, value)

    def _get_setting(self, name):
        name_prefix = f"{self.settings_ui_user_name}/"
        return self.settings.value(name_prefix + name)


class MainWindow(MyQMainWindow):
    companie_name = 'Name'
    software_name = 'softName'
    _names_to_avoid = {'my_widget_name_not_to_save'}

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle(' ')
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)

        self.rb_1 = QRadioButton('RB 1')
        self.rb_1.setObjectName('rb_1')
        self.rb_2 = QRadioButton('RB 2')
        self.rb_2.setObjectName('rb_2')

        self.cb_1 = QCheckBox('Показать заголовок.')
        self.cb_1.setObjectName('cb_1')
        self.cb_1.stateChanged.connect(self.changeTitle)
        self.cb_2 = QCheckBox('CB 2')
        self.cb_2.setObjectName('cb_2')

        self.label = QLabel()
        self.spinBox = QSpinBox()
        self.spinBox.setObjectName("spinBox")
        self.spinBox.valueChanged.connect(self.label.setNum)

        self.text = QTextEdit()                 # < ------------ > добавил сам
        self.text.setObjectName('text')

        self.gridLayout = QGridLayout(self.centralWidget)
        self.gridLayout.addWidget(self.rb_1, 0, 0)
        self.gridLayout.addWidget(self.rb_2, 0, 1)
        self.gridLayout.addWidget(self.cb_1, 1, 0)
        self.gridLayout.addWidget(self.cb_2, 1, 1)
        self.gridLayout.addWidget(self.label, 2, 0)
        self.gridLayout.addWidget(self.spinBox, 2, 1)
        self.gridLayout.addWidget(self.text, 3, 0, 1, 2)   # <-- > добавил сам

        self._gui_restore()

    def changeTitle(self, state):
        if state == Qt.Checked:
            self.setWindowTitle('Hello QCheckBox')
        else:
            self.setWindowTitle(' ')


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    w.resize(300, 200)
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка