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_())

