Search code examples
pythonpyside2

How to fill QTableWidget from json in Python


I'm working on statistical software which takes data from Cloud Firestore database, puts it into QTableWidget and then into chart. I'm able to create offline backup of database (json below). How can I achieve to fill QTableWidget with data from it?

In my table, I've got 4 visible columns - Date, Type, Published, Sent and one hidden - ID (formatted date, e.g. 050719)

This is .json file I get from database

"{\"events\": {\"050719\": {\"Type\": \"Conference\", \"Published\": \"4\", \"Sent\": \"3\", \"Date\": \"05.07.2019\"}, \"050919\": {\"Type\": \"Conference\", \"Published\": \"23\", \"Sent\": \"35\", \"Date\": \"05.09.2019\"}, \"120719\": {\"Type\": \"Conference\", \"Published\": \"3\", \"Sent\": \"4\", \"Date\": \"12.07.2019\"}, \"150719\": {\"Type\": \"Conference\", \"Published\": \"4\", \"Date\": \"15.07.2019\", \"Sent\": \"2\"}}}"

Solution

  • There is no general method, but the basic idea is to iterate through the components as shown below:

    import json
    from PySide2 import QtWidgets
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
    
        data = "{\"events\": {\"050719\": {\"Type\": \"Conference\", \"Published\": \"4\", \"Sent\": \"3\", \"Date\": \"05.07.2019\"}, \"050919\": {\"Type\": \"Conference\", \"Published\": \"23\", \"Sent\": \"35\", \"Date\": \"05.09.2019\"}, \"120719\": {\"Type\": \"Conference\", \"Published\": \"3\", \"Sent\": \"4\", \"Date\": \"12.07.2019\"}, \"150719\": {\"Type\": \"Conference\", \"Published\": \"4\", \"Date\": \"15.07.2019\", \"Sent\": \"2\"}}}"
        # or
        # with open('/path/of/json') as f:
        #     data = json.load(f)
        d = json.loads(data)
        keys = ["Date", "Type", "Published", "Sent"]
        labels = keys + ["ID"]
    
        w = QtWidgets.QTableWidget(0, len(labels))
        w.setColumnHidden(4, True)
        w.setHorizontalHeaderLabels(labels)
    
        for i, (key, value) in enumerate(d["events"].items()):
            rows = [value[k] for k in keys] + [key]
            w.insertRow(w.rowCount())
            for j, v in enumerate(rows):
                it = QtWidgets.QTableWidgetItem(v)
                w.setItem(i, j, it)
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    Update:

    import json
    from PySide2 import QtCore, QtWidgets
    
    
    class DateTimeDelegate(QtWidgets.QStyledItemDelegate):
        def initStyleOption(self, option, index):
            super(DateTimeDelegate, self).initStyleOption(option, index)
            value = index.data()
            option.text = QtCore.QDateTime.fromMSecsSinceEpoch(value).toString("dd.MM.yyyy")
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
    
        data = # ...
        d = json.loads(data)
        keys = ["Date", "Type", "Published", "Sent"]
        labels = keys + ["ID"]
    
        w = QtWidgets.QTableWidget(0, len(labels))
        delegate = DateTimeDelegate(w)
        w.setItemDelegateForColumn(0, delegate)
        w.setColumnHidden(4, True)
        w.setHorizontalHeaderLabels(labels)
    
        for i, (key, value) in enumerate(d["events"].items()):
            rows = [
                value[k]
                if k != "Date"
                else QtCore.QDateTime.fromString(value[k], "dd.MM.yyyy").toMSecsSinceEpoch()
                for k in keys
            ] + [key]
            w.insertRow(w.rowCount())
            for j, v in enumerate(rows):
                it = QtWidgets.QTableWidgetItem()
                it.setData(QtCore.Qt.DisplayRole, v)
                w.setItem(i, j, it)
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    enter image description here