QSettings - сохранять и восстанавливать данные QTableWidget

Начал учить PyQt5 и кое как написал сохранение для QTableWidget, но столкнулся с проблемой чтения данных таблицы из сохранения, буду рад помощи.

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QSize, QCoreApplication
CONFIG_FILE_NAME = 'config.ini'

class Ui_MainWindow(QtWidgets.QMainWindow):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1920, 1000)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(10, 40, 131, 20))
        self.lineEdit.setInputMask("")
        self.lineEdit.setText("")
        self.lineEdit.setPlaceholderText("Регион...")
        
        self.saveButton = QtWidgets.QPushButton(self.centralwidget)
        self.saveButton.setGeometry(QtCore.QRect(5, 940, 90, 23))
        self.saveButton.setObjectName("pushButton_save")
        self.saveButton.clicked.connect(self.slotButton_save)
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(200, 0, 1720, 1000))
        
        self.loadButton = QtWidgets.QPushButton(self.centralwidget) 
        self.loadButton.setGeometry(QtCore.QRect(100, 940, 90, 23))
        self.loadButton.setObjectName("pushButton")
        self.loadButton.clicked.connect(self.slotButton_Load)
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(200, 0, 1720, 1000))
        
        Row = 1000
        self.row = Row
        Col = 7
        self.col = Col
        self.tableWidget.setRowCount(Row)
        self.tableWidget.setColumnCount(Col)
        self.tableWidget.setObjectName("tableWidget")
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(6, item)
        self.tableWidget.horizontalHeader().setDefaultSectionSize(237)
        
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)


    def slotButton_save(self):
        setting = QtCore.QSettings("config.ini", QtCore.QSettings.IniFormat)

        setting.setValue("edit/edit",
                         self.lineEdit.text())
        countColumn = 0  
        while countColumn < self.tableWidget.columnCount():
            for i in range(self.tableWidget.rowCount()):
                try:
                    setting.setValue(f"Column{countColumn}/{i}", self.tableWidget.item(i, countColumn).text())
                except AttributeError:
                    setting.setValue(f"Column{countColumn}/{i}", "empty")
            countColumn += 1

            
    def slotButton_Load(self):
        setting = QtCore.QSettings("config.ini", QtCore.QSettings.IniFormat)

        setting.value("edit/edit"," ")
        countColumn = 0  
        while countColumn < self.tableWidget.columnCount():
            for i in range(self.tableWidget.rowCount()):
                try:
                    set.self.tableWidget(setting.setValue(f"Column{countColumn}/{i}", ))
                except AttributeError:
                    setting.setValue(f"Column{countColumn}/{i}", )
            countColumn += 1

         
    

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.saveButton.setText(_translate("MainWindow", "Сохранить"))
        self.loadButton.setText(_translate("MainWindow", "загрузить"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "Регион"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "Адрес"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "Предприятие"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "Ассортимент"))
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "Количество"))
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText(_translate("MainWindow", "Результат"))
        item = self.tableWidget.horizontalHeaderItem(6)
        item.setText(_translate("MainWindow", "Примечание"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

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

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

НИКОГДА НЕ ИЗМЕНЯЙТЕ код, сгенерированный Qt Designer, НИКОГДА.
Создайте другой класс, который наследуется от соответствующего виджета, и используйте созданный класс для его заполнения.

Как вариант, попробуйте так:

import contextlib
from PyQt5 import QtCore, QtGui, QtWidgets
# ??? from PyQt5.QtCore import QSize, QCoreApplication

CONFIG_FILE_NAME = 'config_q1428936.ini'


# ??? class Ui_MainWindow(QtWidgets.QMainWindow):
class Ui_MainWindow(object):                                         # !!! object
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1220, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(10, 40, 131, 20))
        self.lineEdit.setInputMask("")
        self.lineEdit.setText("")
        self.lineEdit.setPlaceholderText("Регион...")
        
        self.saveButton = QtWidgets.QPushButton(self.centralwidget)
        self.saveButton.setGeometry(QtCore.QRect(5, 940, 90, 23))
        self.saveButton.setObjectName("pushButton_save")
#        self.saveButton.clicked.connect(self.slotButton_save)
        
# ???        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
# ???        self.tableWidget.setGeometry(QtCore.QRect(200, 0, 1720, 1000))
        
        self.loadButton = QtWidgets.QPushButton(self.centralwidget) 
        self.loadButton.setGeometry(QtCore.QRect(100, 940, 90, 23))
        self.loadButton.setObjectName("pushButton")
#        self.loadButton.clicked.connect(self.slotButton_Load)
        
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(200, 0, 1720, 1000))
        
#        Row = 1000
#        self.row = Row
#        Col = 7
#        self.col = Col
        self.tableWidget.setRowCount(1000)
        self.tableWidget.setColumnCount(7)
        
        self.tableWidget.setObjectName("tableWidget")
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem('sfdsfsdfsdf')
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(6, item)
        
        self.tableWidget.horizontalHeader().setDefaultSectionSize(200)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.saveButton.setText(_translate("MainWindow", "Сохранить"))
        self.loadButton.setText(_translate("MainWindow", "загрузить"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "Регион"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "Адрес"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "Предприятие"))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "Ассортимент"))
        item = self.tableWidget.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "Количество"))
        item = self.tableWidget.horizontalHeaderItem(5)
        item.setText(_translate("MainWindow", "Результат"))
        item = self.tableWidget.horizontalHeaderItem(6)
        item.setText(_translate("MainWindow", "Примечание"))


class SettingsManager:
    def __init__(self, filename):
        self.m_settings = QtCore.QSettings(filename, QtCore.QSettings.IniFormat)

    @property
    def settings(self):
        return self.m_settings

    def read(self, widget):
        self.settings.beginGroup(widget.objectName())
        if isinstance(widget, QtWidgets.QAbstractItemView):
            selectionMode = self.settings.value(
                "selectionMode", type=QtWidgets.QAbstractItemView.SelectionMode
            )
            widget.setSelectionMode(selectionMode)

        if isinstance(widget, QtWidgets.QTableWidget):
            rowCount = self.settings.value("rowCount", type=int)
            columnCount = self.settings.value("columnCount", type=int)
            widget.setRowCount(rowCount)
            widget.setColumnCount(columnCount)
            items = self.settings.value("items")
            if items is None:
                self.read_defaults(widget)
            else:
                stream = QtCore.QDataStream(items, QtCore.QIODevice.ReadOnly)
                while not stream.atEnd():
                    it = QtWidgets.QTableWidgetItem()
                    i = stream.readInt()
                    j = stream.readInt()
                    stream >> it
                    widget.setItem(i, j, it)
                selecteditems = self.settings.value("selecteditems")
                stream = QtCore.QDataStream(
                    selecteditems, QtCore.QIODevice.ReadOnly
                )
                while not stream.atEnd():
                    i = stream.readInt()
                    j = stream.readInt()
                    it = widget.item(i, j)
                    if it is not None:
                        it.setSelected(True)
        self.settings.endGroup()

    def write(self, widget):
        self.settings.beginGroup(widget.objectName())
        if isinstance(widget, QtWidgets.QAbstractItemView):
            self.settings.setValue("selectionMode", widget.selectionMode())

        if isinstance(widget, QtWidgets.QTableWidget):
            self.settings.setValue("rowCount", widget.rowCount())
            self.settings.setValue("columnCount", widget.columnCount())
            items = QtCore.QByteArray()
            stream = QtCore.QDataStream(items, QtCore.QIODevice.WriteOnly)
            for i in range(widget.rowCount()):
                for j in range(widget.columnCount()):
                    it = widget.item(i, j)
                    if it is not None:
                        stream.writeInt(i)
                        stream.writeInt(j)
                        stream << it
            self.settings.setValue("items", items)
            selecteditems = QtCore.QByteArray()
            stream = QtCore.QDataStream(
                selecteditems, QtCore.QIODevice.WriteOnly
            )
            for it in widget.selectedItems():
                # print(it.row(), it.column())
                stream.writeInt(it.row())
                stream.writeInt(it.column())
            self.settings.setValue("selecteditems", selecteditems)
        self.settings.endGroup()

    def release(self):
        self.m_settings.sync()

    def read_defaults(self, widget):
        if  widget.objectName() == "tableWidget":
            widget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
            widget.setRowCount(1)
            widget.setColumnCount(7)                                              # - (5) + (4)
            for i in range(widget.rowCount()):
                for j in range(widget.columnCount()):
                    it = QtWidgets.QTableWidgetItem("{}-{}".format(i, j))
                    widget.setItem(i, j, it)


@contextlib.contextmanager
def settingsContext(filename):
    manager = SettingsManager(filename)
    try:
        yield manager
    finally:
        manager.release()


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        
        self.setupUi(self)
                                 
        self.saveButton.clicked.connect(self.slotButton_save)
        self.loadButton.clicked.connect(self.slotButton_Load)
        
        self.frame = QtWidgets.QFrame()
        self.layout = QtWidgets.QVBoxLayout(self.frame)
        self.layout.addWidget(self.lineEdit)
        self.layout.addStretch(1)
        self.layout.addWidget(self.saveButton)
        self.layout.addWidget(self.loadButton)
        
        self.mainLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.mainLayout.addWidget(self.frame, alignment=QtCore.Qt.AlignLeft)
        self.mainLayout.addWidget(self.tableWidget)

    def slotButton_Load(self):
        with settingsContext("config_q1428936.ini") as m:
            for children in self.findChildren(QtWidgets.QWidget):
                if children.objectName():
                    m.read(children)

    def slotButton_save(self):
        with settingsContext("config_q1428936.ini") as m:
            for children in self.findChildren(QtWidgets.QWidget):
                if children.objectName():
                    m.write(children)
        

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
#    MainWindow = QtWidgets.QMainWindow()
#    ui = Ui_MainWindow()
#    ui.setupUi(MainWindow)
#    MainWindow.show()
    w = MainWindow()                                      # +++
    w.show()                                              # +++
    sys.exit(app.exec_())

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

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

→ Ссылка