添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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_())
                It works perfectly, had been strugling for a while with this one, and regarding the removing part, I tried some stuff to properly identify the rows but ended up giving up and tried to focus on the other 2, Thank you so much!
– user9159043
                Oct 20, 2018 at 17:23
        

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.