Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm having trouble with a script to add, load and remove stuff from a JSON file, I'm only being able to edit two rows of items from the JSON, only being able to add stuff after the JSON was loaded in the GUI and not removing stuff for now.
Here's the code and the JSON files:
from PyQt5 import QtCore, QtGui, QtWidgets
import json
class Ui_Dialog(object):
def botao_adicionar_clicked(self):
QtWidgets.QTreeWidgetItem(self.lista_de_itens)
with open('data.json', 'r') as file:
data = json.load(file)
for item in data['database']:
num_id = int(item["num"])
print(num_id + 1)
item_input = self.box_item.text()
valor_input = self.box_valor.text()
unidades_input = self.box_unidades.text()
item_output = str(item_input)
unidades_output = str(unidades_input)
valor_output = str(valor_input)
for item in data['database']:
self.lista_de_itens.topLevelItem(num_id + 1).setText(0, item_output)
self.lista_de_itens.topLevelItem(num_id + 1).setText(1, unidades_output)
self.lista_de_itens.topLevelItem(num_id + 1).setText(2, valor_output)
final_id = str(num_id + 1)
item_final = {"num": final_id, "item":item_output, "unidades":unidades_output, "valor":valor_input}
data["database"].append(item_final)
with open('data.json', 'w') as file:
json.dump(data, file, indent=4)
def botao_carregar_clicked(self):
QtWidgets.QTreeWidgetItem(self.lista_de_itens)
with open('data.json', 'r') as file:
data = json.load(file)
#print(data['num'].count(["num"]))
for item in data['database']:
num_id = int(item["num"])
print(num_id + 1)
for item in data['database']:
self.lista_de_itens.topLevelItem(int(item["num"])).setText(0, item["item"])
for unidades in data['database']:
self.lista_de_itens.topLevelItem(int(item["num"])).setText(1, unidades["unidades"])
for valor in data['database']:
self.lista_de_itens.topLevelItem(int(item["num"])).setText(2, valor["valor"])
def botao_remover_clicked(self):
QtWidgets.QTreeWidgetItem(self.lista_de_itens)
with open('data.json', 'r+') as file:
data = json.load(file)
item_input = self.box_item.text()
valor_input = self.box_valor.text()
unidades_input = self.box_unidades.text()
item_output = str(item_input)
unidades_output = str(unidades_input)
valor_output = str(valor_input)
if item_output in data['item']:
del item_output
elif unidades_output in data['unidades']:
del unidades_output
elif valor_output in data['valor']:
del valor_output
else:
print('Não existe no BD')
with open('data.json', 'w') as file:
#item_final = {"item":item_output,"unidades":unidades_output,"valor":valor_input}
json.dump(data, file)
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(339, 329)
Dialog.setSizeGripEnabled(False)
self.lista_de_itens = QtWidgets.QTreeWidget(Dialog)
self.lista_de_itens.setGeometry(QtCore.QRect(10, 10, 321, 191))
self.lista_de_itens.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.lista_de_itens.setFrameShadow(QtWidgets.QFrame.Sunken)
self.lista_de_itens.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.lista_de_itens.setAutoScroll(True)
self.lista_de_itens.setIndentation(1)
self.lista_de_itens.setRootIsDecorated(False)
self.lista_de_itens.setUniformRowHeights(True)
self.lista_de_itens.setItemsExpandable(False)
self.lista_de_itens.setAnimated(False)
self.lista_de_itens.setWordWrap(True)
self.lista_de_itens.setExpandsOnDoubleClick(False)
self.lista_de_itens.setObjectName("lista_de_itens")
QtWidgets.QTreeWidgetItem(self.lista_de_itens)
self.lista_de_itens.header().setVisible(True)
self.lista_de_itens.header().setCascadingSectionResizes(False)
self.lista_de_itens.header().setDefaultSectionSize(94)
self.lista_de_itens.header().setHighlightSections(False)
self.lista_de_itens.header().setMinimumSectionSize(35)
self.lista_de_itens.header().setSortIndicatorShown(False)
self.lista_de_itens.header().setStretchLastSection(False)
self.box_item = QtWidgets.QLineEdit(Dialog)
self.box_item.setGeometry(QtCore.QRect(10, 210, 321, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.box_item.setFont(font)
self.box_item.setPlaceholderText("Item")
self.box_item.setObjectName("box_item")
self.box_unidades = QtWidgets.QLineEdit(Dialog)
self.box_unidades.setGeometry(QtCore.QRect(10, 250, 151, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.box_unidades.setFont(font)
self.box_unidades.setPlaceholderText("Unidades")
self.box_unidades.setObjectName("box_unidades")
self.box_valor = QtWidgets.QLineEdit(Dialog)
self.box_valor.setGeometry(QtCore.QRect(180, 250, 151, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.box_valor.setFont(font)
self.box_valor.setPlaceholderText("Valor")
self.box_valor.setObjectName("box_valor")
self.botao_carregar = QtWidgets.QPushButton(Dialog)
self.botao_carregar.setGeometry(QtCore.QRect(121, 290, 111, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(16)
self.botao_carregar.setFont(font)
self.botao_carregar.setText("Carregar")
self.botao_carregar.setObjectName("botao_carregar")
self.botao_carregar.clicked.connect(self.botao_carregar_clicked)
self.botao_adicionar = QtWidgets.QPushButton(Dialog)
self.botao_adicionar.setGeometry(QtCore.QRect(11, 290, 101, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(16)
self.botao_adicionar.setFont(font)
self.botao_adicionar.setText("Adicionar")
self.botao_adicionar.setObjectName("botao_adicionar")
self.botao_adicionar.clicked.connect(self.botao_adicionar_clicked)
self.botao_remover = QtWidgets.QPushButton(Dialog)
self.botao_remover.setGeometry(QtCore.QRect(240, 290, 91, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(16)
self.botao_remover.setFont(font)
self.botao_remover.setText("Remover")
self.botao_remover.setObjectName("botao_remover")
self.botao_remover.clicked.connect(self.botao_remover_clicked)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.lista_de_itens.setSortingEnabled(False)
self.lista_de_itens.headerItem().setText(0, _translate("Dialog", "Item"))
self.lista_de_itens.headerItem().setText(1, _translate("Dialog", "Unidades"))
self.lista_de_itens.headerItem().setText(2, _translate("Dialog", "Valor"))
__sortingEnabled = self.lista_de_itens.isSortingEnabled()
self.lista_de_itens.setSortingEnabled(False)
self.lista_de_itens.topLevelItem(0).setText(0, _translate("Dialog", "Test"))
self.lista_de_itens.topLevelItem(0).setText(1, _translate("Dialog", "1000"))
self.lista_de_itens.topLevelItem(0).setText(2, _translate("Dialog", "2,99"))
self.lista_de_itens.setSortingEnabled(__sortingEnabled)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
JSON that at least load and can be added stuff:
"database": [
"num": "0",
"item": "Test2",
"unidades": "200",
"valor": "2,99"
"num": "1",
"item": "Test3",
"unidades": "31",
"valor": "5,99"
JSON that doesn't work:
"database": [
"num": "0",
"item": "Test2",
"unidades": "200",
"valor": "2,99"
"num": "1",
"item": "Test3",
"unidades": "31",
"valor": "5,99"
"num": "2",
"item": "Test4",
"unidades": "31",
"valor": "5,99"
Thanks in advance for any help!
Your main problem is that you are trying to access an item that does not exist so QTreeWidget will return None causing the error you have. In the first link you must order, Qt Designer does not provide a widget but a class that fills a widget so I recommend you create another class that inherits from a widget and use the previous class to fill.
Going to the problem, among the tasks you indicate you will always have to fill in the items from a file and vice versa, so it is better to create 2 methods that do it. On the other hand I created a custom QTreeWidgetItem that supports the 4 items, and so add them or remove it, with this I have been able to implement the functions of loading and saving. But the task of removing is confusing because I do not understand how you identify which row you want to eliminate, so I have proposed a new methodology: the selected row will be deleted, for this you must click on the row and then the button.
from PyQt5 import QtCore, QtGui, QtWidgets
import json
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(339, 329)
Dialog.setSizeGripEnabled(False)
self.lista_de_itens = QtWidgets.QTreeWidget(Dialog)
self.lista_de_itens.setGeometry(QtCore.QRect(10, 10, 321, 191))
self.lista_de_itens.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.lista_de_itens.setFrameShadow(QtWidgets.QFrame.Sunken)
self.lista_de_itens.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.lista_de_itens.setAutoScroll(True)
self.lista_de_itens.setIndentation(1)
self.lista_de_itens.setRootIsDecorated(False)
self.lista_de_itens.setUniformRowHeights(True)
self.lista_de_itens.setItemsExpandable(False)
self.lista_de_itens.setAnimated(False)
self.lista_de_itens.setWordWrap(True)
self.lista_de_itens.setExpandsOnDoubleClick(False)
self.lista_de_itens.setObjectName("lista_de_itens")
self.lista_de_itens.header().setVisible(True)
self.lista_de_itens.header().setCascadingSectionResizes(False)
self.lista_de_itens.header().setDefaultSectionSize(94)
self.lista_de_itens.header().setHighlightSections(False)
self.lista_de_itens.header().setMinimumSectionSize(35)
self.lista_de_itens.header().setSortIndicatorShown(False)
self.lista_de_itens.header().setStretchLastSection(False)
self.box_item = QtWidgets.QLineEdit(Dialog)
self.box_item.setGeometry(QtCore.QRect(10, 210, 321, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.box_item.setFont(font)
self.box_item.setPlaceholderText("Item")
self.box_item.setObjectName("box_item")
self.box_unidades = QtWidgets.QLineEdit(Dialog)
self.box_unidades.setGeometry(QtCore.QRect(10, 250, 151, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.box_unidades.setFont(font)
self.box_unidades.setPlaceholderText("Unidades")
self.box_unidades.setObjectName("box_unidades")
self.box_valor = QtWidgets.QLineEdit(Dialog)
self.box_valor.setGeometry(QtCore.QRect(180, 250, 151, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(14)
self.box_valor.setFont(font)
self.box_valor.setPlaceholderText("Valor")
self.box_valor.setObjectName("box_valor")
self.botao_carregar = QtWidgets.QPushButton(Dialog)
self.botao_carregar.setGeometry(QtCore.QRect(121, 290, 111, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(16)
self.botao_carregar.setFont(font)
self.botao_carregar.setObjectName("botao_carregar")
self.botao_adicionar = QtWidgets.QPushButton(Dialog)
self.botao_adicionar.setGeometry(QtCore.QRect(11, 290, 101, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(16)
self.botao_adicionar.setFont(font)
self.botao_adicionar.setObjectName("botao_adicionar")
self.botao_remover = QtWidgets.QPushButton(Dialog)
self.botao_remover.setGeometry(QtCore.QRect(240, 290, 91, 31))
font = QtGui.QFont()
font.setFamily("Arial")
font.setPointSize(16)
self.botao_remover.setFont(font)
self.botao_remover.setObjectName("botao_remover")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.lista_de_itens.setSortingEnabled(False)
self.lista_de_itens.headerItem().setText(0, _translate("Dialog", "Item"))
self.lista_de_itens.headerItem().setText(1, _translate("Dialog", "Unidades"))
self.lista_de_itens.headerItem().setText(2, _translate("Dialog", "Valor"))
__sortingEnabled = self.lista_de_itens.isSortingEnabled()
self.lista_de_itens.setSortingEnabled(False)
self.lista_de_itens.setSortingEnabled(__sortingEnabled)
self.botao_carregar.setText(_translate("Dialog", "Carregar"))
self.botao_adicionar.setText(_translate("Dialog", "Adicionar"))
self.botao_remover.setText(_translate("Dialog", "Remover"))
class TreeWidgetItem(QtWidgets.QTreeWidgetItem):
def __init__(self, num, item, unidades, valor):
super(TreeWidgetItem, self).__init__([item, unidades, valor])
self._num = num
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.setupUi(self)
self.botao_carregar.clicked.connect(self.botao_carregar_clicked)
self.botao_adicionar.clicked.connect(self.botao_adicionar_clicked)
self.botao_remover.clicked.connect(self.botao_remover_clicked)
@QtCore.pyqtSlot()
def botao_carregar_clicked(self):
# remove all items
self.lista_de_itens.clear()
# load new items from file
self.carregar_itens_do_arquivo()
@QtCore.pyqtSlot()
def botao_adicionar_clicked(self):
item_input = self.box_item.text()
valor_input = self.box_valor.text()
unidades_input = self.box_unidades.text()
if not item_input or not valor_input or not unidades_input:
print("empty fields")
return
num_input = max([self.lista_de_itens.topLevelItem(i)._num for i in range(self.lista_de_itens.topLevelItemCount())] + [-1])+1
it = TreeWidgetItem(num_input, item_input, valor_input, unidades_input)
self.lista_de_itens.addTopLevelItem(it)
self.salvar_itens_em_um_arquivo()
self.box_item.clear()
self.box_valor.clear()
self.box_unidades.clear()
@QtCore.pyqtSlot()
def botao_remover_clicked(self):
for it in reversed(self.lista_de_itens.selectedItems()):
i = self.lista_de_itens.indexOfTopLevelItem(it)
it_ = self.lista_de_itens.takeTopLevelItem(i)
del it_
self.salvar_itens_em_um_arquivo()
def carregar_itens_do_arquivo(self):
with open('data.json', 'r') as file:
data = json.load(file)
for e in data['database']:
it = TreeWidgetItem(int(e["num"]), e["item"], e["unidades"], e["valor"])
self.lista_de_itens.addTopLevelItem(it)
def salvar_itens_em_um_arquivo(self):
data = { "database": [] }
for i in range(self.lista_de_itens.topLevelItemCount()):
it = self.lista_de_itens.topLevelItem(i)
row = {"num": str(it._num), "item" : it.text(0), "unidades": it.text(1), "valor": it.text(2)}
data["database"].append(row)
with open('data.json', 'w') as file:
json.dump(data, file, indent=4)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.